当每个密钥/值对匹配时,在Ansible中合并列表
我有两个字典列表(port_info和int_trunk),当“port”键的值匹配时,我会尝试合并它们,但是并非每个端口都会在“int_trunk”中表示。在本例中,只需将“trunked_vlan”值留空即可。我使用“with_nested”来迭代列表。我似乎无法得到我想要的输出。我尝试了combine()过滤器,并手动尝试创建变量,但没有完全实现。如何将这两个列表合并当每个密钥/值对匹配时,在Ansible中合并列表,ansible,Ansible,我有两个字典列表(port_info和int_trunk),当“port”键的值匹配时,我会尝试合并它们,但是并非每个端口都会在“int_trunk”中表示。在本例中,只需将“trunked_vlan”值留空即可。我使用“with_nested”来迭代列表。我似乎无法得到我想要的输出。我尝试了combine()过滤器,并手动尝试创建变量,但没有完全实现。如何将这两个列表合并 --- - hosts: localhost connection: local gather_facts: no
---
- hosts: localhost
connection: local
gather_facts: no
vars:
trunk_ports: []
non_trunk_ports: []
new_port_info: []
port_info:
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/1"
speed: "a-1000"
status: connected
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 3
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/2"
speed: "a-1000"
status: connected
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 3
- desc: "Some Port"
duplex: auto
port: "Gi1/0/3"
speed: auto
status: notconnect
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 23
int_trunk:
- port: "Gi1/0/1"
vlans: "1-50"
- port: "Gi1/0/2"
vlans: "50-60"
其输出应为:
port_info:
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/1"
speed: "a-1000"
status: connected
trunk_vlans: "1-50"
type: "10/100/1000BaseTX"
vlan: 3
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/2"
speed: "a-1000"
status: connected
trunk_vlans: "50-60"
type: "10/100/1000BaseTX"
vlan: 3
- desc: "Some Port"
duplex: auto
port: "Gi1/0/3"
speed: auto
status: notconnect
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 23
这是我尝试过的事情之一:
---
- hosts: localhost
connection: local
gather_facts: no
vars:
trunk_ports: []
non_trunk_ports: []
new_port_info: []
port_info:
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/1"
speed: "a-1000"
status: connected
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 3
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/2"
speed: "a-1000"
status: connected
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 3
- desc: " "
duplex: auto
port: "Gi1/0/3"
speed: auto
status: notconnect
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 23
int_trunk:
- port: "Gi1/0/1"
vlans: "1-50"
- port: "Gi1/0/2"
vlans: "50-60"
tasks:
- name: Merge trunk ports
set_fact:
trunk_ports: "{{ trunk_ports + [ { 'desc': item.0.desc, 'duplex': item.0.duplex, 'port': item.0.port, 'speed': item.0.speed, 'status
': item.0.status, 'trunk_vlans': item.1.vlans, 'type': item.0.type, 'vlan': item.0.vlan } ] }}"
with_nested:
- "{{ port_info }}"
- "{{ int_trunk }}"
when: item.0.port == item.1.port
- name: Merge non-trunk ports
set_fact:
non_trunk_ports: "{{ non_trunk_ports + [ { 'desc': item.0.desc, 'duplex': item.0.duplex, 'port': item.0.port, 'speed': item.0.speed,
'status': item.0.status, 'trunk_vlans': item.0.trunk_vlans, 'type': item.0.type, 'vlan': item.0.vlan } ] }}"
with_nested:
- "{{ port_info }}"
- "{{ int_trunk }}"
when: item.0.port != item.1.port
- name: Merge all ports
set_fact:
new_port_info: "{{ new_port_info + [item.0|combine(item.1)] }}"
with_nested:
- "{{ port_info }}"
- "{{ trunk_ports }}"
when: item.0.port == item.1.port
- name: Echo
debug: var=trunk_ports
- name: Echo
debug: var=non_trunk_ports
- name: Echo
debug: var=new_port_info
我最终使用的是端口Gi1/0/1和Gi1/0/2,但不是Gi1/0/3。不确定是否有“一行”过滤可以做到这一点。以下是我的想法,首先是对流程的解释:
set\u fact
步骤填充2个列表中常见的所有端口的列表port\u info
中的元素具有与int\u trunk
中的元素相等的port属性时,我们合并这两个字典port\u info
列表,并将port\u info\u final
列表添加到int\u trunk
中没有匹配元素的所有元素port\u info\u final
列表中获得了合并元素和唯一元素
剧本:
---
- hosts: localhost
connection: local
gather_facts: false
vars:
trunk_ports: []
non_trunk_ports: []
new_port_info: []
port_info:
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/1"
speed: "a-1000"
status: connected
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 3
- desc: "*** Voice Server Port ***"
duplex: "a-full"
port: "Gi1/0/2"
speed: "a-1000"
status: connected
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 3
- desc: "Some Port"
duplex: auto
port: "Gi1/0/3"
speed: auto
status: notconnect
trunk_vlans: ""
type: "10/100/1000BaseTX"
vlan: 23
int_trunk:
- port: "Gi1/0/1"
vlans: "1-50"
- port: "Gi1/0/2"
vlans: "50-60"
port_info_final: []
tasks:
- name: get the lists of ports per list
set_fact:
portlist_1: "{{ port_info | map(attribute='port') | list }}"
portlist_2: "{{ int_trunk | map(attribute='port') | list }}"
- name: get the ports that exist in port_info but not in int_trunk
set_fact:
ports_not_in_int_trunk: "{{ portlist_1 | difference(portlist_2) }}"
- name: merge the dictionaries when the port is matched
set_fact:
port_info_final: "{{ port_info_final + [item[0] | combine(item[1])] }}"
when: item[0].port == item[1].port
loop: "{{ query('nested', int_trunk, port_info) }}"
- name: add all the port_info elements that dont have entry in int_trunk
set_fact:
port_info_final: "{{ port_info_final + [item] }}"
when: item.port in ports_not_in_int_trunk
loop: "{{ port_info }}"
- name: print results
debug:
msg: "{{ port_info_final }}"
结果:
TASK [print results] ************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
{
"desc": "*** Voice Server Port ***",
"duplex": "a-full",
"port": "Gi1/0/1",
"speed": "a-1000",
"status": "connected",
"trunk_vlans": "",
"type": "10/100/1000BaseTX",
"vlan": 3,
"vlans": "1-50"
},
{
"desc": "*** Voice Server Port ***",
"duplex": "a-full",
"port": "Gi1/0/2",
"speed": "a-1000",
"status": "connected",
"trunk_vlans": "",
"type": "10/100/1000BaseTX",
"vlan": 3,
"vlans": "50-60"
},
{
"desc": "Some Port",
"duplex": "auto",
"port": "Gi1/0/3",
"speed": "auto",
"status": "notconnect",
"trunk_vlans": "",
"type": "10/100/1000BaseTX",
"vlan": 23
}
]
}
PLAY RECAP **********************************************************************************************************************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0
希望它能有所帮助尽管由于我自己在提供的输入中的错误,我不得不做一些轻微的修改。在port_info中,我们有“集群VLAN”,它一开始没有任何值。在int_中继中,我们有“VLAN”。我希望“VLAN”与“集群VLAN”相结合,而不是创建新的k/v对。因此,我所做的是将“VLAN”重命名为“集群VLAN”,然后反转联合循环中的列表,以便int_集群键覆盖端口信息键。这似乎是我想要的。谢谢