Ansible Jinja2 выдает итерации по списку, когда имя_хоста-инвентаря является вершиной дерева переменных - PullRequest
0 голосов
/ 07 мая 2019

Я сталкиваюсь с проблемой, когда Jinja2 выполняет итерацию по списку, когда имя_инвентаря находится в верхней части дерева переменных.

Мой YAML (group_vars / all / main.yaml):

router1:
  interfaces:
  - { name: ge-0/0/0, ipv4_address: 192.168.0.11, ipv4_mask: '24' }
  - { name: ge-0/0/1, ipv4_address: 192.168.1.11, ipv4_mask: '24' }
router2:
  interfaces:
  - { name: ge-0/0/0, ipv4_address: 192.168.0.12, ipv4_mask: '24' }
  - { name: ge-0/0/1, ipv4_address: 192.168.1.12, ipv4_mask: '24' }

Следующий шаблон Jinja2 не работает:

{% for interface in [inventory_hostname].interfaces %}
interface {{ interface.name }}
   ...
!
{% endfor %}

И я не понимаю, почему?

Мне удалось заставить его работать со следующим, но выглядит уродливо:

{% for interface in hostvars[inventory_hostname][inventory_hostname].interfaces %}
interface {{ interface.name }}
   ...
!
{% endfor %}

Почему не работает первый шаблон?

Ответы [ 2 ]

0 голосов
/ 07 мая 2019

Этот синтаксис недействителен:

{% for interface in [inventory_hostname].interfaces %}

Вы используете скобки, такие как [...] ...

  • Для индексирования списка, например my_var[0] или my_var[1]
  • Для доступа к значению словаря, например my_var['name'] или my_var['size']
  • Для создания списка, например [1, 2, 3, 4, 5]

Но вы не можете их использоватькак вы пытаетесь их использовать.


Есть несколько способов решить эту проблему.Я думаю, что наиболее элегантным решением было бы перенести настройки из group_vars/all и вместо этого создать:

  • host_vars/router1.yml со следующим содержимым:

    interfaces:
    - { name: ge-0/0/0, ipv4_address: 192.168.0.11, ipv4_mask: '24' }
    - { name: ge-0/0/1, ipv4_address: 192.168.1.11, ipv4_mask: '24' }
    
  • host_vars/router2.yml со следующим содержанием:

    interfaces:
    - { name: ge-0/0/0, ipv4_address: 192.168.0.12, ipv4_mask: '24' }
    - { name: ge-0/0/1, ipv4_address: 192.168.1.12, ipv4_mask: '24' }
    

С этим, ваш шаблон просто становится:

{% for interface in interfaces %}

Ион будет использовать правильное значение для любого хоста, на который на данный момент нацелена задача.


Если вам действительно нужно сохранить текущую конфигурацию, вы можете использовать поиск vars, например:

{% for interface in lookup('vars', inventory_hostname).interfaces %}

... но я действительно думаю, что вы найдете вещи более управляемыми, если вы реструктурируете свои данные.

0 голосов
/ 07 мая 2019

Правильное решение иметь два файла параметров, по одному для каждой группы:

(group_vars / router1.yaml):

interfaces:
- { name: ge-0/0/0, ipv4_address: 192.168.0.11, ipv4_mask: '24' }
- { name: ge-0/0/1, ipv4_address: 192.168.1.11, ipv4_mask: '24' }

(group_vars / router2.yaml):

interfaces:
- { name: ge-0/0/0, ipv4_address: 192.168.0.12, ipv4_mask: '24' }
- { name: ge-0/0/1, ipv4_address: 192.168.1.12, ipv4_mask: '24' }

И использовать их, как в следующем примере в шаблонах jinja2:

{% for interface in interfaces %}
interface {{ interface.name }}
   ...
!
{% endfor %}
...