Re: [ansible-project] Combine dictionaries based on a dictionary key value.

12 views
Skip to first unread message

Vladimir Botka

unread,
Jun 30, 2020, 2:47:19 AM6/30/20
to Adam McGill, ansible...@googlegroups.com
On Mon, 29 Jun 2020 13:22:05 -0700 (PDT)
Adam McGill <adama...@gmail.com> wrote:

> ... add the items ... based on key value of node_name.
>
> aggregate_info: [
> {
> ...
> "node_name": "TEST_NA_CLUSTER_01-01",
> ...
> },
> {
> ...
> "node_name": "TEST_NA_CLUSTER_01-02",
> ...
> }]
>
> net_interface: [
> {
> ...
> "node_name": "TEST_NA_CLUSTER_01-01",
> ...
> },
> {
> ...
> "node_name": "IQ-REG_NA_CLUSTER_01-02",
> ...
> }]

The values of "node_name" does not correspond. It would be good to test it.
For example

- fail:
msg: Values of node_name(s) do not fit
when: aggregate_info|map(attribute='node_name')|list|
difference(net_interface|map(attribute='node_name')|list)

--
Vladimir Botka

Vladimir Botka

unread,
Jun 30, 2020, 3:17:47 AM6/30/20
to Adam McGill, ansible...@googlegroups.com
On Mon, 29 Jun 2020 13:22:05 -0700 (PDT)
Adam McGill <adama...@gmail.com> wrote:

> add the items of net_interface into aggregate_info or
> create new dictionary based on key value of node_name.

Create dictionaries from the lists

- set_fact:
agg: "{{ agg|default({})|combine({item.node_name: item}) }}"
loop: "{{ aggregate_info }}"
- set_fact:
net: "{{ net|default({})|combine({item.node_name: item}) }}"
loop: "{{ net_interface }}"

Then combine the corresponding dictionaries and concatenate the results into
a new list

- set_fact:
aggregate_info2: "{{ aggregate_info2|default([]) +
[agg[item]|combine(net[item])] }}"
loop: "{{ agg.keys()|list }}"

HTH,

-vlado

--
Vladimir Botka

Felix Fontein

unread,
Jun 30, 2020, 4:00:34 AM6/30/20
to ansible...@googlegroups.com
Hi,

a new lookup plugin was proposed for community.general which would help
with this:
https://github.com/ansible-collections/community.general/pull/263

We're currently trying to evaluate whether this plugin would be useful
to the community. Feel free to comment there (or try it out!).

Cheers,
Felix




On Mon, 29 Jun 2020 13:22:05 -0700 (PDT)
Adam McGill <adama...@gmail.com> wrote:

> Hello,
> Basically want to add the items of net_interface into aggregate_info
> or create new dictionary based on key value of node_name. Looking
> for assistance on how i can achieve this please and thank you.
>
> *Dictionary called: aggregate_info*
> {
> "name": "agg_Data1_Cluster01",
> "node_name": "TEST_NA_CLUSTER_01-01",
> "percent_used_capacity": "46",
> "size_available": 8141263818752,
> "size_avaliable_80%": 5122753242726,
> "size_total": 15092552880128,
> "size_total_80%": 12074042304102,
> "size_used": 6951289061376
> },
> {
> "name": "agg_Data1_Cluster02",
> "node_name": "TEST_NA_CLUSTER_01-02",
> "percent_used_capacity": "34",
> "size_available": 5116275568640,
> "size_avaliable_80%": 3561215869747,
> "size_total": 7775298494464,
> "size_total_80%": 6220238795571,
> "size_used": 2659022925824
> }
>
> *Dictionary called: net_interface*
> {
> "address": "XX.XXX.X.XXX",
> "address4oct": "224",
> "data_protcol": "none",
> "failover_group": "Management",
> "node_name": "TEST_NA_CLUSTER_01-01",
> "role": "node_mgmt",
> "vserver": "TEST_NA_CLUSTER_01"
> },
> {
> "address": "XX.XXX.X.XXX",
> "address4oct": "226",
> "data_protcol": "none",
> "failover_group": "Management",
> "node_name": "IQ-REG_NA_CLUSTER_01-02",
> "role": "node_mgmt",
> "vserver": "TEST_NA_CLUSTER_01"
> }
>
>
> *Out Come want:*
> Dictionary called: aggregate_info (original) or new name
> {
> "name": "agg_Data1_Cluster01",
> "node_name": "TEST_NA_CLUSTER_01-01",
> "percent_used_capacity": "46",
> "size_available": 8141263818752,
> "size_avaliable_80%": 5122753242726,
> "size_total": 15092552880128,
> "size_total_80%": 12074042304102,
> "size_used": 6951289061376
> "address": "XX.XXX.X.XXX",
> "address4oct": "224",
> "data_protcol": "none",
> "failover_group": "Management",
> "role": "node_mgmt",
> "vserver": "TEST_NA_CLUSTER_01"
> },
> {
> "name": "agg_Data1_Cluster02",
> "node_name": "TEST_NA_CLUSTER_01-02",
> "percent_used_capacity": "34",
> "size_available": 5116275568640,
> "size_avaliable_80%": 3561215869747,
> "size_total": 7775298494464,
> "size_total_80%": 6220238795571,
> "size_used": 2659022925824
> "address": "XX.XXX.X.XXX",
> "address4oct": "226",
> "data_protcol": "none",
> "failover_group": "Management",
> "role": "node_mgmt",
> "vserver": "TEST_NA_CLUSTER_01"
> }
>

Vladimir Botka

unread,
Jul 1, 2020, 2:14:41 AM7/1/20
to 'Felix Fontein' via Ansible Project
On Tue, 30 Jun 2020 10:00:14 +0200
"'Felix Fontein' via Ansible Project" <ansible...@googlegroups.com>
wrote:

> a new lookup plugin was proposed for community.general which would help
> with this:
> https://github.com/ansible-collections/community.general/pull/263

I have proposed this filter plugin instead
https://github.com/ansible-collections/community.general/pull/604

shell> cat filter_plugins/list.py
from collections import defaultdict
from operator import itemgetter


def lists_mergeby(l1, l2, index):
'''Merge lists by attribute index. Example:
- debug: msg="{{ l1|lists_mergeby(l2, 'index')|list }}"
'''
d = defaultdict(dict)
for l in (l1, l2):
for elem in l:
d[elem[index]].update(elem)
return sorted(d.values(), key=itemgetter(index))


class FilterModule(object):
''' Ansible list filters '''

def filters(self):
return {
'lists_mergeby': lists_mergeby
}

Works fine also with Adam's data

- set_fact:
aggregate_info2: "{{ net_interface|
lists_mergeby(aggregate_info, 'node_name')|
list }}"
- debug:
var: aggregate_info2

give

aggregate_info2:
- address: XX.XXX.X.XXX
address4oct: '224'
data_protcol: none
failover_group: Management
name: agg_Data1_Cluster01"
node_name: TEST_NA_CLUSTER_01-01
percent_used_capacity: '46'
role: node_mgmt
size_available: 8141263818752
size_avaliable_80%: 5122753242726
size_total: 15092552880128
size_total_80%: 12074042304102
size_used: 6951289061376
vserver: TEST_NA_CLUSTER_01
- address: XX.XXX.X.XXX
address4oct: '226'
data_protcol: none
failover_group: Management
name: agg_Data1_Cluster02
node_name: TEST_NA_CLUSTER_01-02
percent_used_capacity: '34'
role: node_mgmt
size_available: 5116275568640
size_avaliable_80%: 3561215869747
size_total: 7775298494464
size_total_80%: 6220238795571
size_used: 2659022925824
vserver: TEST_NA_CLUSTER_01

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