我在变量中有一个 JSON:
{
"device_vlans": {
"1": {
"name": "default",
"interfaces": [
"GigabitEthernet1/1",
"GigabitEthernet1/2",
"GigabitEthernet1/3"
]
},
"20": {
"name": "VLAN20",
"interfaces": [
"GigabitEthernet1/2"
]
},
"30": {
"name": "VLAN30",
"interfaces": [
"GigabitEthernet1/3"
]
}
}
但我需要它看起来更像这样:
{
"device_vlans": {
"GigabitEthernet1/1": {
"vlans": [
"1"
]
},
"GigabitEthernet1/2": {
"vlans": [
"1",
"20"
]
},
"GigabitEthernet1/3": {
"vlans": [
"1",
"30"
]
}
}
目前,我正在循环遍历设备的所有接口,并且在循环中,我正在使用 循环遍历 device_vlans 变量中的所有项目when: item == interface
。它真的很慢,并给我带来了问题。
有没有更好的方法可以用 ansible 来实现这个效果?
我想到自定义过滤器可以解决这个问题吗?
答案1
创建设备和接口列表
- set_fact:
dev_ifc: "{{ dev_ifc|d([]) + [{'dev': item.1, 'ifc': item.0.key}] }}"
with_subelements:
- "{{ device_vlans|dict2items }}"
- value.interfaces
给出
dev_ifc:
- {dev: GigabitEthernet1/1, ifc: '1'}
- {dev: GigabitEthernet1/2, ifc: '1'}
- {dev: GigabitEthernet1/3, ifc: '1'}
- {dev: GigabitEthernet1/2, ifc: '20'}
- {dev: GigabitEthernet1/3, ifc: '30'}
然后,按设备对列表进行分组并创建字典
- set_fact:
device_vlans: "{{ dict(key|zip(val)) }}"
vars:
arr: "{{ dev_ifc|groupby('dev') }}"
key: "{{ arr|map('first')|list }}"
val: "{{ arr|map('last')|
map('json_query', '[].ifc')|
map('community.general.dict_kv', 'interfaces')|
list }}"
给出
device_vlans:
GigabitEthernet1/1:
interfaces: ['1']
GigabitEthernet1/2:
interfaces: ['1', '20']
GigabitEthernet1/3:
interfaces: ['1', '30']
可以避免在任务中进行迭代。相反,将迭代放入 Jinja2 中。例如,将以下声明放入合适的
dev_ifc_str: |-
{% for ifc in device_vlans.keys() %}
{% for dev in device_vlans[ifc]['interfaces'] %}
- {dev: {{ dev }}, ifc: {{ ifc }}}
{% endfor %}
{% endfor %}
dev_ifc: "{{ dev_ifc_str|from_yaml }}"
device_vlans2: "{{ dict(_key|zip(_val)) }}"
_arr: "{{ dev_ifc|groupby('dev') }}"
_key: "{{ _arr|map('first')|list }}"
_val: "{{ _arr|map('last')|
map('json_query', '[].ifc')|
map('community.general.dict_kv', 'interfaces')|
list }}"