I need to transform a simple list to a complex one.
The simple one looks like:
customers:
- customer01-node01.private.foo.it
- customer02-node01.private.foo.it
- customer04-node03.private.foo.it
- customer03-node02.private.foo.it
- customer05-node02.private.foo.it
- customer01-node04.private.foo.it
- cusotmer02-node04.private.foo.it
- customer04-node06.private.foo.it
- customer03-node05.private.foo.it
- customer05-node05.private.foo.it
I am trying to find a way to obtain a complex one, grouping nodes by customer. The final result I'm finding for is this one:
customers_list:
- customer: customer01
nodes:
- node01.private.foo.it
- node04.private.foo.it
- customer: customer02
nodes:
- node01.private.foo.it
- node04.private.foo.it
- customer: customer03
nodes:
- node02.private.foo.it
- node05.private.foo.it
- customer: customer04
nodes:
- node03.private.foo.it
- node06.private.foo.it
- customer: customer05
nodes:
- node02.private.foo.it
- node05.private.foo.it
I am unable to find a way.
CodePudding user response:
Parse the data
- set_fact:
customers_parsed: "{{ customers_parsed|d([]) [{'customer': _customer,
'node': _node}] }}"
loop: "{{ customers }}"
vars:
_customer: "{{ item.split('-')|first }}"
_node: "{{ item.split('-')|last }}"
gives
customers_parsed:
- customer: customer01
node: node01.private.foo.it
- customer: customer02
node: node01.private.foo.it
- customer: customer04
node: node03.private.foo.it
- customer: customer03
node: node02.private.foo.it
- customer: customer05
node: node02.private.foo.it
- customer: customer01
node: node04.private.foo.it
- customer: customer02
node: node04.private.foo.it
- customer: customer04
node: node06.private.foo.it
- customer: customer03
node: node05.private.foo.it
- customer: customer05
node: node05.private.foo.it
Then group the items by the attribute customer and concatenate the list
- set_fact:
customers_list: "{{ customers_list|d([]) [{'customer': item.0,
'nodes': _nodes}] }}"
loop: "{{ customers_parsed|groupby('customer') }}"
vars:
_nodes: "{{ item.1|map(attribute='node')|list }}"
gives
customers_list:
- customer: customer01
nodes:
- node01.private.foo.it
- node04.private.foo.it
- customer: customer02
nodes:
- node01.private.foo.it
- node04.private.foo.it
- customer: customer03
nodes:
- node02.private.foo.it
- node05.private.foo.it
- customer: customer04
nodes:
- node03.private.foo.it
- node06.private.foo.it
- customer: customer05
nodes:
- node02.private.foo.it
- node05.private.foo.it
CodePudding user response:
you could use a custom filter:
you create a folder filter_plugins in your playbook folder (i have named the file myfilters.py and the filter custom)
myfilters.py:
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'custom': self.custom
}
def custom(self, listvar):
result = {}
final = []
for it in listvar:
f, s = it.split('-')
if f in result:
result[f].append(s)
else:
result[f] = [s]
for k in result:
final.append({'customer':k, 'nodes': result[k]})
return final
the playbook:
---
- hosts: localhost
vars:
customers:
- customer01-node01.private.foo.it
- customer02-node01.private.foo.it
- customer04-node03.private.foo.it
- customer03-node02.private.foo.it
- customer05-node02.private.foo.it
- customer01-node04.private.foo.it
- customer02-node04.private.foo.it
- customer04-node06.private.foo.it
- customer03-node05.private.foo.it
- customer05-node05.private.foo.it
tasks:
- name: parsevar
set_fact:
customers_list: "{{ customers | custom }}"
- name: display
debug:
msg: "{{ customers_list }}"
result:
ok: [localhost] => {
"msg": [
{
"customer": "customer01",
"nodes": [
"node01.private.foo.it",
"node04.private.foo.it"
]
},
{
"customer": "customer02",
"nodes": [
"node01.private.foo.it",
"node04.private.foo.it"
]
},
{
"customer": "customer04",
"nodes": [
"node03.private.foo.it",
"node06.private.foo.it"
]
},
{
"customer": "customer03",
"nodes": [
"node02.private.foo.it",
"node05.private.foo.it"
]
},
{
"customer": "customer05",
"nodes": [
"node02.private.foo.it",
"node05.private.foo.it"
]
}
]
}
the advantage to use a custom filter: you just have only one task to transform datas