【问题标题】:Using mako for Cisco config generation. Is it possible to use the netaddr module (or any module) in templates?使用 mako 生成 Cisco 配置。是否可以在模板中使用 netaddr 模块(或任何模块)?
【发布时间】:2018-03-20 07:10:41
【问题描述】:

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

编辑。有人告诉我尝试使用内置功能的 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 定义返回网络加上 netaddr 没有执行的子网“192.168.1.0/25”。我还没有找到任何方法让 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 几乎没有出现说明如何做这样的事情。

【问题讨论】:

  • 仍在努力,但到目前为止没有任何帮助。
  • 我可能已经走得更远了。我为模板尝试了这个: %def> !变量输入:${LAN_IP} ${get_address(LAN_IP)} 现在我得到无效的模板,请更正以下错误:模板属性错误:“测试”中预期有 4 个八位字节由于“测试”在我的模板中没有,我认为这是前端代码中的一个错误。

标签: python templates mako cisco-ios


【解决方案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"
}

【讨论】:

    猜你喜欢
    • 2014-11-17
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 2022-06-19
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多