How to remove a single item from a list within a nested dictionary

165 views
Skip to first unread message

jean-christophe manciot

unread,
Aug 25, 2023, 9:19:40 AM8/25/23
to Ansible Project
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?

jean-christophe manciot

unread,
Aug 25, 2023, 10:22:09 AM8/25/23
to Ansible Project
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 <vpc>.
Message has been deleted
Message has been deleted

jean-christophe manciot

unread,
Aug 25, 2023, 10:32:09 AM8/25/23
to Ansible Project
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>
                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 }}"

Vladimir Botka

unread,
Aug 25, 2023, 12:57:52 PM8/25/23
to jean-christophe manciot, ansible...@googlegroups.com
On Fri, 25 Aug 2023 06:19:39 -0700 (PDT)
jean-christophe manciot <actionm...@gmail.com> wrote:

> We need to remove the item ''4444444444 from the list <nic_ids> located
> inside the dictionary matched by the key/value net_id=='1'.

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 }}"



--
Vladimir Botka
Reply all
Reply to author
Forward
0 new messages