首先,我是一个网络工程师,学习一些编码,并尝试使用这一相对较新的技术进行进化。关于下面的问题,我已经搜索了好几个小时了,但是大多数搜索结果都包括我不想要的Ansible (目前)。
我使用的是python/jinja2 2脚本,它基于名为confplate的VAR生成一个配置:参见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 1vlan400_network = 172.29.50.0
我希望默认的路由器是172.29.50.1,当然我不能使用上面的片段来增加它。
为此我需要使用正则表达式吗?仅仅使用Jinja2似乎并不容易。我倾向于只使用Python/Jinja2 2完成这一任务。这个是可能的吗?提前感谢!
发布于 2019-11-07 04:52:06
正如您所发现的,如果您只依赖于Jinja2 2的默认过滤器,就不会在为网络设备生成配置方面走得太远。
您必须编写自己的自定义过滤器(用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.23.0 255.255.255.0“。同样,gateway_from_cidr过滤器将接受字符串"21.22.23.0/24“并返回"21.22.23.1”(即子网中的第一个非零主机地址)。
步骤2:为自定义过滤器编写代码
创建一个名为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中)
测试
./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 1https://stackoverflow.com/questions/58714289
复制相似问题