我有两个字典列表(port_info和int_trunk),当'port'键的值匹配时我试图合并但是并不是每个端口都会在'int_trunk'中表示。在这种情况下,只需将“trunked_vlans”值留空即可。我使用'with_nested'迭代列表。我似乎无法让输出做我想要的。我已经尝试过combine()过滤器以及手动尝试创建变量而不能完全获得变量。如何将这两个列表合并?
---
- 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。
答案 0 :(得分:0)
不确定是否有"一行"过滤可以做到这一点。这是我想出的东西,首先解释流程:
set_fact
步骤填充2个列表中常见的所有端口的列表。port_info
中的元素的port属性等于int_trunk
中的元素时,我们合并/合并2个词典。port_info
列表,并在port_info_final
列表中添加int_trunk
中没有匹配元素的所有元素。我们在port_info_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
希望有所帮助