- ru
- Language: en
- Documentation version: latest
Тесты
Кроме фильтров, Jinja также поддерживает тесты. Тесты позволяют проверять переменные на какое-то условие.
Jinja поддерживает большое количество встроенных тестов. Мы рассмотрим лишь несколько из них. Остальные тесты вы можете найти в документации.
Тесты, как и фильтры, можно создавать самостоятельно.
defined
Тест defined позволяет проверить, есть ли переменная в словаре данных.
Пример шаблона templates/test_defined.txt:
router ospf 1
{% if ref_bw is defined %}
auto-cost reference-bandwidth {{ ref_bw }}
{% else %}
auto-cost reference-bandwidth 10000
{% endif %}
{% for networks in ospf %}
network {{ networks.network }} area {{ networks.area }}
{% endfor %}
Этот пример более громоздкий, чем вариант с использованием фильтра default, но этот тест может быть полезен в том случае, если, в зависимости от того, определена переменная или нет, нужно выполнять разные команды.
Файл с данными (data_files/test_defined.yml):
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
Результат выполнения:
$ python cfg_gen.py templates/test_defined.txt data_files/test_defined.yml
router ospf 1
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
iterable
Тест iterable проверяет, является ли объект итератором.
Благодаря таким проверкам, можно делать ответвления в шаблоне, которые будут учитывать тип переменной.
Шаблон templates/test_iterable.txt (сделаны отступы, чтобы были понятней ответвления):
{% for intf, params in trunks | dictsort %}
interface {{ intf }}
{% if params.vlans is iterable %}
{% if params.action == 'add' %}
switchport trunk allowed vlan add {{ params.vlans | join(',') }}
{% elif params.action == 'delete' %}
switchport trunk allowed vlan remove {{ params.vlans | join(',') }}
{% else %}
switchport trunk allowed vlan {{ params.vlans | join(',') }}
{% endif %}
{% else %}
{% 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 %}
{% endif %}
{% endfor %}
Файл с данными (data_files/test_iterable.yml):
trunks:
Fa0/1:
action: add
vlans:
- 10
- 20
Fa0/2:
action: only
vlans:
- 10
- 30
Fa0/3:
action: delete
vlans: 10
Обратите внимание на последнюю строку: vlans: 10
. В данном случае 10
уже не находится в списке, и фильтр join в таком случае не работает. Но,
за счет теста is iterable
(в этом случае результат будет false), в
этом случае шаблон уходит в ветку else.
Результат выполнения:
$ python cfg_gen.py templates/test_iterable.txt data_files/test_iterable.yml
interface Fa0/1
switchport trunk allowed vlan add 10,20
interface Fa0/2
switchport trunk allowed vlan 10,30
interface Fa0/3
switchport trunk allowed vlan remove 10
Такие отступы получились из-за того, что в шаблоне используются отступы, но не установлено lstrip_blocks=True (он удаляет пробелы и табы в начале строки).