Как вы обнаружили, вы не будете слишком далеко продвигаться в создании конфигураций для сетевых устройств, если будете просто полагаться на стандартные фильтры Jinja2.
Вы должны написать свои собственные пользовательские фильтры (в Python) ииспользуйте их в своих файлах шаблонов.
Для примера, который у вас есть, сделайте следующее:
Шаг 1: Создайте шаблон
Я собираюсьчтобы предоставить сеть vlan в качестве спецификации CIDR:
./confplate.py template.txt vlan400_network=21.22.23.0/24
Как видите, это интуитивно понятно и гибко: если вам нравится, вы можете изменить сеть на 21.22.23.192/26
, и все будет работать нормально, как мы вскоре увидим.
Шаблон для этого выглядит следующим образом:
ip dhcp pool WLAN01
network {{ vlan400_network | network_from_cidr }}
domain-name abc.xyz
default-router {{ vlan400_network | gateway_from_cidr }}
lease 0 1
, где network_from_cidr
и gateway_from_cidr
- это пользовательские фильтры Jinja2, которые мы вскоре создадим.
Идея состоит в том, что фильтр network_from_cidr
будет принимать строку типа "21.22.23.0/24" и возвращать строку "21.22.23.0 255.255.255.0". Аналогично, фильтр gateway_from_cidr
примет строку «21.22.23.0/24» и вернет «21.22.23.1» (т. Е. Первый ненулевой адрес хоста в подсети).
Шаг 2: Напишите код Python для пользовательских фильтров
Создайте файл с именем custom_filters.py
и введите следующий код:
import ipaddress
def network_from_cidr (cidr):
ipn = ipaddress.ip_network(unicode(cidr), strict=True)
return '{} {}'.format(ipn.network_address, ipn.netmask)
def gateway_from_cidr (cidr):
ipn = ipaddress.ip_network(unicode(cidr), strict=True)
# By convention, the gateway has the first non-zero address in the subnet
first_address = list(ipn.hosts())[0]
return first_address
Код использует модуль ipaddress . Как видите, мы определяем две функции, по одной для каждого из пользовательских фильтров, которые мы хотим создать. Функции принимают один аргумент, то есть строку, которая предшествует |
в шаблоне.
Шаг 3: Сообщите confplate.py о своих пользовательских фильтрах
Где-тов начале confplate.py
напишите import custom_filters
.
Затем вы должны сказать:
env = Environment(loader=FileSystemLoader(self.templatepath), undefined=StrictUndefined)
# Load our custom filters
env.filters['network_from_cidr'] = custom_filters.network_from_cidr
env.filters['gateway_from_cidr'] = custom_filters.gateway_from_cidr
в соответствующих точках кода (в confplate.py вы действительно должны это сделатьдважды, один раз в функции get_template_vars
и один раз в render_template
)
Test
./confplate.py template.txt vlan400_network=21.22.23.0/24
ip dhcp pool WLAN01
network 21.22.23.0 255.255.255.0
domain-name abc.xyz
default-router 21.22.23.1
lease 0 1
./confplate.py template.txt vlan400_network=21.22.23.192/26
ip dhcp pool WLAN01
network 21.22.23.192 255.255.255.192
domain-name abc.xyz
default-router 21.22.23.193
lease 0 1