当未定义属性时,解决Ansible map filter错误的最佳方法是什么?
我有一个带有属性的接口列表,如ip、vrf等。我最感兴趣的属性是vrf。我使用map属性来过滤这个列表,并使用减少的惟一列表创建必要的代码。如果其中一个提供的接口未定义vrf,则过滤此列表的最优雅方式是什么 变数当未定义属性时,解决Ansible map filter错误的最佳方法是什么?,ansible,jinja2,Ansible,Jinja2,我有一个带有属性的接口列表,如ip、vrf等。我最感兴趣的属性是vrf。我使用map属性来过滤这个列表,并使用减少的惟一列表创建必要的代码。如果其中一个提供的接口未定义vrf,则过滤此列表的最优雅方式是什么 变数 base: HOSTNAME: MVPS001R01 SITE_NUMBER: 20 ROUTER_NUMBER: 1 MGMT_IP: 100.64.1.1 interfaces: - intf: LOOP0 ip: 100.64.1.1
base:
HOSTNAME: MVPS001R01
SITE_NUMBER: 20
ROUTER_NUMBER: 1
MGMT_IP: 100.64.1.1
interfaces:
- intf: LOOP0
ip: 100.64.1.1
vrf: MPLS1
type: LOOP
- intf: GI0/0/0
vrf: global
ip: 192.168.0.1/24
type: eth
peering:
- intf: GI0/0/1
vrf: INET1
ip: 1.1.1.1/30
type: eth
- intf: GI0/1/0
vrf: MPLS1
ip: 172.31.0.45
vlan: 2010
type: eth
base:
HOSTNAME: MVPS001R01
SITE_NUMBER: 20
ROUTER_NUMBER: 1
MGMT_IP: 100.64.1.1
interfaces:
- intf: LOOP0
ip: 100.64.1.1
vrf: MPLS1
type: LOOP
- intf: GI0/0/0
ip: 192.168.0.1/24
type: eth
peering:
- intf: GI0/0/1
vrf: INET1
ip: 1.1.1.1/30
type: eth
- intf: GI0/1/0
vrf: MPLS1
ip: 172.31.0.45
vlan: 2010
type: eth
Jinja2代码:
{% set VRFS = base.interfaces | map(attribute='vrf') | list | unique %}
{% for transport in transports %}
{% for vrf in VRFS %}
{% if transport.name | upper == vrf | upper %}
vrf definition {{ transport.name | upper }}
rd 1:{{ transport.priority | int }}
!
address-family ipv4
exit-address-family
!
{% endif %}
{% endfor %}
{% endfor%}
当所有接口都定义了“vrf”时输出
vrf definition MPLS1
rd 1:100
!
address-family ipv4
exit-address-family
!
vrf definition INET1
rd 1:200
!
address-family ipv4
exit-address-family
其中一个接口缺少vrf时的输出
interfaces:
- intf: LOOP0
ip: 100.64.1.1
vrf: MPLS1
type: LOOP
- intf: GI0/0/0
ip: 192.168.0.1/24
type: eth
peering:
TASK [deploy-smartwan : Generate Base Configuration File] *******************************************************************************************
fatal: [router1]: FAILED! => {"changed": false, "failed": true, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'vrf'"}
可能未设置vrf属性。如何对此进行解释并有效处理?通过添加selectattr筛选器,我只能从定义vrf属性的base.interfaces中选择项目。我认为这是一种非常优雅的方法,可以将元素列表减少到生成配置所必需的程度
{% set VRFS = base.interfaces | selectattr("vrf", "defined") | map(attribute='vrf') | list | unique %}
{% for transport in transports %}
{% for vrf in VRFS %}
{% if transport.name | upper == vrf | upper %}
vrf definition {{ transport.name | upper }}
rd 1:{{ transport.priority | int }}
!
address-family ipv4
exit-address-family
!
{% endif %}
{% endfor %}
{% endfor%}
变数
我有一个带有属性的接口列表,如ip、vrf等。我最感兴趣的属性是vrf。我使用map属性来过滤这个列表,并使用减少的惟一列表创建必要的代码。如果其中一个提供的接口未定义vrf,则过滤此列表的最优雅方式是什么
变数
base:
HOSTNAME: MVPS001R01
SITE_NUMBER: 20
ROUTER_NUMBER: 1
MGMT_IP: 100.64.1.1
interfaces:
- intf: LOOP0
ip: 100.64.1.1
vrf: MPLS1
type: LOOP
- intf: GI0/0/0
vrf: global
ip: 192.168.0.1/24
type: eth
peering:
- intf: GI0/0/1
vrf: INET1
ip: 1.1.1.1/30
type: eth
- intf: GI0/1/0
vrf: MPLS1
ip: 172.31.0.45
vlan: 2010
type: eth
base:
HOSTNAME: MVPS001R01
SITE_NUMBER: 20
ROUTER_NUMBER: 1
MGMT_IP: 100.64.1.1
interfaces:
- intf: LOOP0
ip: 100.64.1.1
vrf: MPLS1
type: LOOP
- intf: GI0/0/0
ip: 192.168.0.1/24
type: eth
peering:
- intf: GI0/0/1
vrf: INET1
ip: 1.1.1.1/30
type: eth
- intf: GI0/1/0
vrf: MPLS1
ip: 172.31.0.45
vlan: 2010
type: eth
输出
vrf definition MPLS1
rd 1:100
!
address-family ipv4
exit-address-family
!
vrf definition INET1
rd 1:200
!
address-family ipv4
exit-address-family
如果其中一个提供的接口未定义vrf,则过滤此列表的最优雅方式是什么你的预期产出是多少?你要求的优雅度的评价标准是什么?谢谢你的回答。预期输出应为定义的每个VRF创建一个实例。如果接口没有VFF,则不应创建它。我认为我需要遍历接口的原始列表,找到每个定义了VRF的项,然后将该项添加到另一个列表中。定义新列表后,我可以使用map过滤器,而不会因为单个接口没有定义VRF而导致错误。