Использование mako для генерации конфигурации Cisco. Можно ли использовать модуль netaddr (или любой другой модуль) в шаблонах?

Я очень новичок в python и mako, и у меня могут возникнуть проблемы с базовыми понятиями. У меня есть рабочие шаблоны, но мой ввод CSV можно было бы значительно очистить, если бы я мог использовать модуль netaddr для работы с IP-адресами в шаблоне. То, что я хотел бы сделать, это передать переменную IP интерфейса, например: LAN_IP = '192.168.1.1/24' (я делаю это из CSV) в шаблон, а затем каким-то образом использовать модуль netaddr для заполнения IP, маски подсети (в десятичном формате с точками и инверсной маске) ​​и сетевой адрес, чтобы я мог использовать эту одну переменную CSV для сетевых операторов bgp, масок eigrp, списков ACL и т. д. в той же конфигурации. Я могу сделать следующее из оболочки Python:

>>> from netaddr import *
>>> LAN_IP = '192.168.1.1/24'
>>> IP = IPNetwork(LAN_IP)
>>> print(IP.ip)
192.168.1.1
>>> print(IP.network)
192.168.1.0
>>> print(IP.netmask)
255.255.255.0
>>> print(IP.hostmask)
0.0.0.255

РЕДАКТИРОВАТЬ. Мне сказали попробовать встроенный IP-адрес. Попытка этого из командной строки Python показывает, что это может работать:

MAKO_TEMPLATE_STRING = """\
<%def name="get_netmask(ip_string)"><%
    import ipaddress
    return ipaddress.IPv4Interface(ip_string).netmask
%></%def>
<%def name="get_address(ip_string)"><%
    import ipaddress
    return ipaddress.IPv4Interface(ip_string).ip
%></%def>
<%def name="get_subnet(ip_string)"><%
    import ipaddress
    return ipaddress.IPv4Interface(ip_string).network
%></%def>
<%def name="get_hostmask(ip_string)"><%
    import ipaddress
    return ipaddress.IPv4Interface(ip_string).hostmask
%></%def>
! Variable Input: ${data}
${get_address(data)} ${get_netmask(data)} ${get_subnet(data)} ${get_hostmask(data)}
"""
print(Template(MAKO_TEMPLATE_STRING).render(data="192.168.1.1/25"))

Это дает мне следующий вывод: ! Переменный ввод: 192.168.1.1/25 192.168.1.1 255.255.255.128 192.168.1.0/25 0.0.0.127

Теперь новая проблема заключается в том, что определение ipaddress.IPv4Interface(ip_string).network возвращает сеть ПЛЮС подсеть «192.168.1.0/25», чего netaddr не делал. Я не нашел способа заставить ipaddress возвращать ТОЛЬКО часть подсети.

Итак, для сборки шаблона я продвинулся немного дальше.... Если я помещу ТОЛЬКО это в шаблон, он проверит:

<%def name="get_netmask(ip_string)"><%
    import ipaddress
    return ipaddress.IPv4Interface(ip_string).netmask
%></%def>
<%def name="get_address(ip_string)"><%
    import ipaddress
    return ipaddress.IPv4Interface(ip_string).ip
%></%def>
<%def name="get_network(ip_string)"><%
    import ipaddress
    return ipaddress.IPv4Interface(ip_string).network
%></%def>

Но когда я пробую любой тип ссылки, я получаю сообщение об ошибке.

! Variable Input: ${LAN_IP}  <--I tried with and without this line
${get_address(LAN_IP)}  <--The template does not seem to like these references.
${get_netmask(LAN_IP)}
${get_subnet(LAN_IP)}

Мне кажется, что я упускаю здесь что-то очень простое, но, возможно, я неправильно подхожу к проблеме. Любая помощь будет принята с благодарностью, поскольку документы Mako и Google мало что иллюстрируют, как сделать что-то подобное.


person Daniel Flick    schedule 09.10.2017    source источник
comment
Все еще работаю над этим, но пока ничего не помогло.   -  person Daniel Flick    schedule 17.10.2017
comment
Хотя, возможно, я продвинулся немного дальше. Я попробовал это для шаблона: ‹%! ## код на уровне модуля python import ipaddress %› ‹%def name=get_address(ip_string)› ‹% return ipaddress.IPv4Interface(ip_string).ip %› ‹/%def› ! Ввод переменной: ${LAN_IP} ${get_address(LAN_IP)}, и теперь я получаю неверный шаблон, исправьте следующую ошибку: Ошибка атрибута шаблона: ожидается 4 октета в «тесте». Поскольку «тест» отсутствует в моем шаблоне, я думаю, что это ошибка во внешнем коде.   -  person Daniel Flick    schedule 17.10.2017


Ответы (1)


Проблема была с кодом подтверждения. В разделе шаблона python класс IPv4Interface вызовет исключение из-за недопустимого значения в процессе проверки. Поэтому сервер отклоняет данные формы и шаблон не создается.

Решение. Будет работать, если вы добавите обработку ошибок в раздел шаблона python.

<%!
    ## python module-level code
    import ipaddress
%>
<%def name="get_address(ip_string)">
    <%
    try:
        return ipaddress.IPv4Interface(ip_string).ip
    except Exception:
        return "FAIL_OR_EMPTY"
    %>
</%def>
! Variable Input: ${LAN_IP}
${get_address(LAN_IP)}

Объяснение: Во время проверки HTML-формы на стороне сервера шаблон конфигурации отображается с набором фиктивных параметров для проверки синтаксиса (см. файл app/forms.py, класс ConfigTemplateForm). Ваш шаблон конфигурации проверяется со следующим набором параметров во время проверки формы:

{
    "hostname": "test",
    "LAN_IP": "test"
}
person Daniel Flick    schedule 19.10.2017