The source nested dictionary is for instance the following:
vpc:
provider:
net_type: ‘db’
net_ipv4_subnet: ‘10.0.0.0/16 ’
net_ipv6_subnet: ‘FD00::/64’
net_id: ‘0’
nic_ids:
1111111111
2222222222
net_type: ‘dns’
net_ipv4_subnet: ‘10.1.0.0/16 ’
net_ipv6_subnet: ‘FD01::/64’
net_id: ‘1’
nic_ids:
3333333333
4444444444
net_type: ‘ns’
net_ipv4_subnet: ‘10.2.0.0/16 ’
net_ipv6_subnet: ‘FD02::/64’
net_id: ‘2’
nic_ids:
5555555555
6666666666
We need to remove the item ''4444444444 from the list <nic_ids> located inside the dictionary matched by the key/value net_id==‘1’.
Selecting the <nic_ids> list inside the right dictionary is easy with:
vpc.provider | selectattr(‘net_id’, ‘eq’, ‘1’) | map(attribute= ‘nic_ids’), but I have no idea how to remove the item from list and build the new vpc.provider?
Any suggestion?
Here is how to get the new list:
name: Removing a <nic_id> from the list inside the dictionary matching the <net_id>
vars:
vpc:
provider:
net_type: ‘db’
net_ipv4_subnet: ‘10.0.0.0/16’
net_ipv6_subnet: ‘FD00::/64’
net_id: ‘0’
nic_ids:
1111111111
2222222222
net_type: ‘dns’
net_ipv4_subnet: ‘10.1.0.0/16’
net_ipv6_subnet: ‘FD01::/64’
net_id: ‘1’
nic_ids:
3333333333
4444444444
net_type: ‘ns’
net_ipv4_subnet: ‘10.2.0.0/16’
net_ipv6_subnet: ‘FD02::/64’
net_id: ‘2’
nic_ids:
5555555555
6666666666
nic_ids_:
4444444444
new_nic_ids: “{{ vpc.provider | selectattr(‘net_id’, ‘eq’, ‘1’) | map(attribute= ‘nic_ids’) | first | difference(nic_ids_) }}”
debug:
msg: “{{ new_nic_ids }}”
But I don’t know how to get the updated .
OK, I got it, but I’m sure there is a more elegant and simpler way to achieve the same result:
name: Removing a <nic_id> from the dictionary matching the <net_id>
vars:
vpc:
provider:
net_type: ‘db’
net_ipv4_subnet: ‘10.0.0.0/16’
net_ipv6_subnet: ‘FD00::/64’
net_id: ‘0’
nic_ids:
1111111111
2222222222
net_type: ‘dns’
net_ipv4_subnet: ‘10.1.0.0/16’
net_ipv6_subnet: ‘FD01::/64’
net_id: ‘1’
nic_ids:
3333333333
4444444444
net_type: ‘ns’
net_ipv4_subnet: ‘10.2.0.0/16’
net_ipv6_subnet: ‘FD02::/64’
net_id: ‘2’
nic_ids:
5555555555
6666666666
nic_ids_:
4444444444
new_nic_ids: “{{ vpc.provider | selectattr(‘net_id’, ‘eq’, ‘1’) | map(attribute= ‘nic_ids’) | first | difference(nic_ids_) }}”
seed_vpc:
provider:
net_id: ‘1’
nic_ids: “{{ new_nic_ids }}”
new_vpc:
provider:
“{{ [vpc.provider, seed_vpc.provider] | community.general.lists_mergeby(‘net_id’, recursive=True, list_merge=‘replace’) }}”
debug:
msg: “{{ new_vpc }}”
vbotka
(Vladimir Botka)
August 25, 2023, 4:57pm
4
Put the items you want to update into a dictionary. For example,
diff:
'1': [4444444444]
Use Jinja to update the list
update: |
{% filter from_yaml %}
{% for i in vpc.provider %}
{% if i.net_id in diff %}
{% set nic_ids=i.nic_ids|difference(diff[i.net_id]) %}
- {{ i|combine({'nic_ids': nic_ids}) }}
{% else %}
- {{ i }}
{% endif %}
{% endfor %}
{% endfilter %}
Then, create the dictionary
new_vpc:
provider: "{{ update }}"