首页 > 解决方案 > 使用 Jinja2 模板语言从前缀/子网推断网络参数

问题描述

我正在开发一个开源项目,为使用 Salt 和 Jinja2 的小型企业网络或节点集群提供完整的堆栈。

但是,为了使堆栈与 /24、/16 和 /8 等子网不兼容,我需要从前缀/子网中推导出一些参数。

这是一个例子:

用户提供子网 10.0.0.0 和前缀 /23。我想推断:

网络掩码是 255.255.254.0,广播是 10.0.1.255

我还希望用户能够在使用 Salt 后指定其他具有相同操作的参数。

但是我今天没能找到一种方法来使用 Jinja2 模板语言来做到这一点,以便能够直接在 Salt Pillar 中呈现值。

您可以在模板设计器http://jinja.pocoo.org/docs/2.10/templates/中看到可用的数学运算是有限的。我也在考虑过滤器,但找不到。

你们中有人知道使用基本数学运算来实现此类 IP 相关运算的方法吗?(所以没有二进制文件)

我最好的问候

标签: mathjinja2salt-stack

解决方案


正如你所说,内置的 Jinja 过滤器在这方面是相当有限的。我认为您将需要调用 salt 模块。

如果您有 Salt 2016.3 或更高版本,您可以netaddress在 Jinja 模板中调用执行模块。确保 Python 模块netaddr安装在目标 minions 上。然后你可以在你的 Salt 状态中像这样调用 Jinja。

/tmp/demonstration.txt:
  file.managed:
    - contents:
      - "broadcast: {{ salt.netaddress.cidr_broadcast('10.0.0.0/23') }}"
      - "netmask: {{ salt.netaddress.cidr_netmask('10.0.0.0/23') }}"

(将字符串文字替换为10.0.0.0/23您在支柱中定义的内容。)

如果您有较早的 Salt 版本,请将文件放在您的(可能)内netaddress.py称为的目录中:_modulesfile_roots/srv/salt/state/_modules

# -*- coding: utf-8 -*- 

import netaddr  

def cidr_broadcast(str_net):
    net = netaddr.IPNetwork(str_net)
    return net.broadcast

def cidr_netmask(str_net):
    net = netaddr.IPNetwork(str_net)
    return net.netmask

执行sudo salt <target_minion> saltutil.sync_all,它应该也可以工作。

但是,我不确定您所说的“能够在 Salt Pillar 中直接呈现值”是什么意思。

如果你想在支柱中做同样的事情,你可以像这样编写支柱 SLS 文件:

{%- set example_net = '10.0.0.0/23' %}

demonstration:
  example_net:
    net: {{ example_net }}
    broadcast: {{ salt.netaddress.cidr_broadcast(example_net) }}
    netmask: {{ salt.netaddress.cidr_netmask(example_net) }}

请注意,如果您需要为柱子渲染编写自定义模块,这会有所不同,因为柱子是在主节点上渲染的。您需要extension_modules在主配置中进行设置,并将模块放置modules在这种情况下称为的目录中。

问候,德克


推荐阅读