使用mako进行Cisco配置生成。是否可以在模板中使用netaddr模块(或任何模块)?

时间:2017-10-09 06:46:15

标签: python templates mako cisco-ios

我是python和mako的新手,我可能遇到基本概念的问题。我有工作模板,但如果我可以使用netaddr模块处理模板中的IP地址,我的CSV输入可以大大清理。我想做的是传递一个接口IP变量,如: LAN_IP ='192.168.1.1/24'(我这样做是从CSV)到模板然后以某种方式使用netaddr模块填写IP,子网掩码(点分十进制和反向掩码)和网络地址所以我可以在同一配置中将这一个CSV变量用于bgp网络语句,eigrp掩码和ACL等。我可以从Python shell中执行以下操作:

>>> 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

EDIT。有人告诉我试试ipaddress内置的功能。从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定义返回网络PLUS子网“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几乎没有说明如何做这样的事情。

1 个答案:

答案 0 :(得分: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"
}