- en
- Language: ru
- Documentation version: latest
if/elif/else
if позволяет добавлять условие в шаблон. Например, можно использовать if, чтобы добавлять какие-то части шаблона в зависимости от наличия переменных в словаре с данными.
Конструкция if также должна находиться внутри {% %}
.
Нужно явно указывать окончание условия:
{% if ospf %}
router ospf 1
router-id 10.0.0.{{ id }}
auto-cost reference-bandwidth 10000
{% endif %}
Пример шаблона templates/if.txt:
hostname {{ name }}
interface Loopback0
ip address 10.0.0.{{ id }} 255.255.255.255
{% for vlan, name in vlans.items() %}
vlan {{ vlan }}
name {{ name }}
{% endfor %}
{% if ospf %}
router ospf 1
router-id 10.0.0.{{ id }}
auto-cost reference-bandwidth 10000
{% for networks in ospf %}
network {{ networks.network }} area {{ networks.area }}
{% endfor %}
{% endif %}
Выражение if ospf
работает так же, как в Python: если переменная
существует и не пустая, результат будет True. Если переменной нет или
она пустая, результат будет False.
То есть, в этом шаблоне конфигурация OSPF генерируется только в том случае, если переменная ospf существует и не пустая.
Конфигурация будет генерироваться с двумя вариантами данных.
Сначала с файлом data_files/if.yml, в котором нет переменной ospf:
id: 3
name: R3
vlans:
10: Marketing
20: Voice
30: Management
Результат будет таким:
$ python cfg_gen.py templates/if.txt data_files/if.yml
hostname R3
interface Loopback0
ip address 10.0.0.3 255.255.255.255
vlan 10
name Marketing
vlan 20
name Voice
vlan 30
name Management
Теперь аналогичный шаблон, но с файлом data_files/if_ospf.yml:
id: 3
name: R3
vlans:
10: Marketing
20: Voice
30: Management
ospf:
- network: 10.0.1.0 0.0.0.255
area: 0
- network: 10.0.2.0 0.0.0.255
area: 2
- network: 10.1.1.0 0.0.0.255
area: 0
Теперь результат выполнения будет таким:
hostname R3
interface Loopback0
ip address 10.0.0.3 255.255.255.255
vlan 10
name Marketing
vlan 20
name Voice
vlan 30
name Management
router ospf 1
router-id 10.0.0.3
auto-cost reference-bandwidth 10000
network 10.0.1.0 0.0.0.255 area 0
network 10.0.2.0 0.0.0.255 area 2
network 10.1.1.0 0.0.0.255 area 0
Как и в Python, в Jinja можно делать ответвления в условии.
Пример шаблона templates/if_vlans.txt:
{% for intf, params in trunks.items() %}
interface {{ intf }}
{% if params.action == 'add' %}
switchport trunk allowed vlan add {{ params.vlans }}
{% elif params.action == 'delete' %}
switchport trunk allowed vlan remove {{ params.vlans }}
{% else %}
switchport trunk allowed vlan {{ params.vlans }}
{% endif %}
{% endfor %}
Файл data_files/if_vlans.yml с данными:
trunks:
Fa0/1:
action: add
vlans: 10,20
Fa0/2:
action: only
vlans: 10,30
Fa0/3:
action: delete
vlans: 10
В данном примере в зависимости от значения параметра action генерируются разные команды.
В шаблоне можно было использовать и такой вариант обращения к вложенным словарям:
{% for intf in trunks %}
interface {{ intf }}
{% if trunks[intf]['action'] == 'add' %}
switchport trunk allowed vlan add {{ trunks[intf]['vlans'] }}
{% elif trunks[intf]['action'] == 'delete' %}
switchport trunk allowed vlan remove {{ trunks[intf]['vlans'] }}
{% else %}
switchport trunk allowed vlan {{ trunks[intf]['vlans'] }}
{% endif %}
{% endfor %}
В итоге будет сгенерирована такая конфигурация:
$ python cfg_gen.py templates/if_vlans.txt data_files/if_vlans.yml
interface Fa0/1
switchport trunk allowed vlan add 10,20
interface Fa0/3
switchport trunk allowed vlan remove 10
interface Fa0/2
switchport trunk allowed vlan 10,30
Также с помощью if можно фильтровать, по каким элементам последовательности пройдется цикл for.
Пример шаблона templates/if_for.txt с фильтром в цикле for:
{% for vlan, name in vlans.items() if vlan > 15 %}
vlan {{ vlan }}
name {{ name }}
{% endfor %}
Файл с данными (data_files/if_for.yml):
vlans:
10: Marketing
20: Voice
30: Management
Результат выполнения:
$ python cfg_gen.py templates/if_for.txt data_files/if_for.yml
vlan 20
name Voice
vlan 30
name Management