---
- name: Replace dict in list example
hosts: localhost
gather_facts: false
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
fix:
net_type: 'dns'
net_ipv4_subnet: '10.3.0.0/16'
net_ipv6_subnet: 'FD03::/64'
net_id: 3
nic_ids: []
tasks:
- name: Do this if the order doesn't matter
# N.B. This assumes there is 1 provider to replace.
ansible.builtin.debug:
msg: "{{ item }}"
loop:
- "{{ [vpc.provider | selectattr('net_type', 'ne', fix.net_type)] |
sum(start=[fix]) }}"
- name: Do this if the order matters
# N.B. This will replace _all_ "dns" providers with 'fix'.
ansible.builtin.debug:
msg: "{{ item }}"
loop:
- |
{% set providers = [] %}
{% for p in vpc.provider %}
{% set _ = providers.append(p if p.net_type != fix.net_type else
fix) %}
{% endfor %}{{ providers }}
On 8/18/23 9:40 AM, jean-christophe manciot wrote:
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 replace only the whole entry indexed by "net_type: 'dns'" with:
- net_type: 'dns'
net_ipv4_subnet: '10.3.0.0/16'
net_ipv6_subnet: 'FD03::/64'
net_id: 3
nic_ids: []
so the result would look like:
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.3.0.0/16'
net_ipv6_subnet: 'FD03::/64'
net_id: 3
nic_ids: []
- net_type: 'ns'
net_ipv4_subnet: '10.2.0.0/16'
net_ipv6_subnet: 'FD02::/64'
net_id: 2
nic_ids:
- 5555555555
- 6666666666
I've tried the following task using the *combine* filter:
- name: Combining 2 <vpc> dictionaries with
combine/list_merge='replace'
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
net_id: 3
net_ipv4_subnet: '10.3.0.0/16'
net_ipv6_subnet: 'FD03::/64'
new_vpc: "{{ vpc | combine({'provider': [{'net_type':
'dns', 'net_id': net_id, 'net_ipv4_subnet': net_ipv4_subnet,
'net_ipv6_subnet': net_ipv6_subnet, 'nic_ids': []}]}, recursive=True,
list_merge='replace') }}"
debug:
msg: "{{ new_vpc }}"
which unfortunately removes the other 2 entries:
ok: [localhost] =>
msg:
provider:
- net_id: 3
net_ipv4_subnet: 10.3.0.0/16
net_ipv6_subnet: FD03::/64
net_type: dns
nic_ids: []
Same result with community.general.*lists_mergeby* filter:
- name: Combining 2 <vpc> dictionaries with
lists_mergeby/list_merge='replace'
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
seed_vpc:
provider:
- net_type: 'dns'
net_ipv4_subnet: '10.3.0.0/16'
net_ipv6_subnet: 'FD03::/64'
net_id: 3
nic_ids: []
new_vpc: "{{ [vpc.provider, seed_vpc.provider] |
community.general.lists_mergeby('net_type=dns', recursive=True,
list_merge='replace') }}"
debug:
msg: "{{ new_vpc }}"
leads to:
ok: [localhost] =>
msg:
provider:
- net_id: 3
net_ipv4_subnet: 10.3.0.0/16
net_ipv6_subnet: FD03::/64
net_type: dns
nic_ids: []
Am I missing something or is it impossible to perform with the
currently available ansible filters?
--
You received this message because you are subscribed to the Google
Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ansible-project/f77880a9-c219-41ec-ad7d-d5381594489an%40googlegroups.com
<https://groups.google.com/d/msgid/ansible-project/f77880a9-c219-41ec-ad7d-d5381594489an%40googlegroups.com?utm_medium=email&utm_source=footer>.
--
Todd
--
You received this message because you are subscribed to the Google Groups "Ansible
Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ansible-project/b259c2a4-9dfa-ee2f-a840-7ee769f7afc5%40gmail.com.