Jinja2 Network Automation - увеличение переменной (подсеть +1) - PullRequest
0 голосов
/ 05 ноября 2019

Прежде всего, я сетевой инженер, немного изучающий кодирование и пытающийся развиваться с использованием этой относительно новой технологии. Я искал в Интернете несколько часов относительно приведенного ниже вопроса, но большинство результатов поиска включают Ansible, который мне не нужен (на данный момент).

Я использую скрипт python / jinja2, который генерирует конфигурацию на основеVAR называется confplate: см. https://github.com/verbosemode/confplate - я провел некоторое тестирование, и оно отлично работает. Очень просто и быстро.

Однако я пытаюсь использовать переменную (сетевой адрес) и увеличить ее в шаблоне Jinja2 для установки IP-адреса.

См. Ниже фрагмент Jinja2:

ip dhcp pool WLAN01
network {{ vlan400_network }} 255.255.255.0
domain-name abc.xyz
default-router {{ vlan400_network + 1 }}
lease 0 1

vlan400_network = 172.29.50.0

Я хочу, чтобы default-router был 172.29.50.1 - конечно, я не могу увеличить его, используя приведенный вышефрагмент.

Нужно ли для этого использовать регулярные выражения? Это не кажется очень простым, используя исключительно Jinja2. Я предпочитаю делать это, используя только Python / Jinja2. Это возможно? Заранее спасибо!

1 Ответ

1 голос
/ 07 ноября 2019

Как вы обнаружили, вы не будете слишком далеко продвигаться в создании конфигураций для сетевых устройств, если будете просто полагаться на стандартные фильтры 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
...