Home > Software design >  Getting empty merged list when trying to merge two dict lists with multiple when conditions in Ansib
Getting empty merged list when trying to merge two dict lists with multiple when conditions in Ansib

Time:07-03

here are my two list -

listone -

list1": 
[
{
    "_ref": "LAB1/1/4094",
    "vlan_id": 12,
    "vlan_name": "test_vlan_1",
    "vlan_subnet": "192.168.1.0/28",
    "vlan_vrf": "vrf_1"
},
{
    "_ref": "LAB2/1/4094",
    "vlan_id": 12,
    "vlan_name": "test_vlan_1",
    "vlan_subnet": "192.168.2.0/28",
    "vlan_vrf": "vrf_1"
}
]

secondlist -

"list2":

[
{
    "_ref": "LAB1/1/4094",
    "vlan_id": "12",
    "vlan_name": "test_vlan_1",
    "vlan_ref": "vlan/ZG5zLnZsYW4kLmNvbS5pbmZvYmxveC5kbnMudmxhbl92aWV3JElORlJBTEFCLjEuNDA5NC4xMg:LAB1/test_vlan_1/12"
}
]
- name: merge lists final
  set_fact:
    merged_list: "{{ merged_list|default([])   [ item[0] | union(item[1]) ] }}"
  when: item[0]._ref == item[1]._ref and item[0].vlan_id == item[1].vlan_id and item[0].vlan_name == item[1].vlan_name
  loop: "{{ query('nested', list1, list2) }}"
- name: print results
  debug:
    var: merged_list

I get output as:

TASK [print results] ***********************************************************
ok: [localhost] => {
    "merged_list": "VARIABLE IS NOT DEFINED!"
}

desired output: in below, if you notice list2 has a match with list1 first dict item so list2 item merged with list1 first item, in the final output i want merged with a match and also unmatched item of list1 which is second one.

"merged_list":

[
{
    "_ref": "LAB1/1/4094",
    "vlan_id": 12,
    "vlan_name": "test_vlan_1",
    "vlan_subnet": "192.168.1.0/28",
    "vlan_vrf": "vrf_1",
    "vlan_ref": "vlan/ZG5zLnZsYW4kLmNvbS5pbmZvYmxveC5kbnMudmxhbl92aWV3JElORlJBTEFCLjEuNDA5NC4xMg:LAB1/test_vlan_1/12"
},
{
    "_ref": "LAB2/1/4094",
    "vlan_id": 12,
    "vlan_name": "test_vlan_1",
    "vlan_subnet": "192.168.2.0/28",
    "vlan_vrf": "vrf_1"
}
]

i believe when: item[0]._ref == item[1]._ref and item[0].vlan_id == item[1].vlan_id and item[0].vlan_name == item[1].vlan_name condition is not working as i expected. Any suggestions/clue to make this work and get merged_list as the way i am looking for.

CodePudding user response:

The items in the lists are dictionaries. You need the filter combine to merge them. For example, the playbook below (simplified for testing)

- hosts: localhost
  vars:
    list1:
      - {_ref: ZG5, name: LAB1, vlan_id: 12, vlan_name: test_vlan_1}
      - {_ref: XXX, name: LAB2, vlan_id: 12, vlan_name: test_vlan_1}
      - {_ref: YYY, name: LAB3, vlan_id: 13, vlan_name: test_vlan_1}
    list2:
      - {_ref: ZG5, vlan_id: 12, vlan_name: test_vlan_1, vlan_ref: vlan/ZG5}
  tasks:
    - set_fact:
        merged_list: "{{ merged_list|d([])   [_item] }}"
      loop: "{{ query('nested', list1, list2) }}"
      vars:
        _conditions:
          - "{{ item.0._ref == item.1._ref }}"
          - "{{ item.0.vlan_id == item.1.vlan_id }}"
          - "{{ item.0.vlan_name == item.1.vlan_name }}"
        _item: "{{ _conditions is all|ternary(item.0|combine(item.1), item.0) }}"
    - debug:
        var: merged_list

gives

merged_list:
  - {_ref: ZG5, name: LAB1, vlan_id: 12, vlan_name: test_vlan_1, vlan_ref: vlan/ZG5}
  - {_ref: XXX, name: LAB2, vlan_id: 12, vlan_name: test_vlan_1}
  - {_ref: YYY, name: LAB3, vlan_id: 13, vlan_name: test_vlan_1}
  • Related