I am trying to create dictionary out of the servers stored in different env variables in ansible.
What i currently have is:
env_loadbalancer_vservers2: "{{ hostvars[inventory_hostname] | dict2items | selectattr('key', 'match', 'env_.*_loadbalancer_vservers(?![_.])') | list | items2dict }} "
Which will:
- get all variables in ansible for a specific host,
- change dict to items type
- as we can easily access now key value I will match only keys I want using regex
- Change it back to list
- Back to dict
problem is that output looks like this:
{
"env_decision_manager_loadbalancer_vservers": {
"decision_central": {
"ip_or_dns": "ip",
"port": "port",
"protocol": "SSL",
"ssl": true,
"timeout": 600,
}
},
"env_ftp_loadbalancer_vservers": {
"ftp_1": {
"ip_or_dns": "ip",
"port": "port",
"protocol": "FTP",
"ssl": false,
"timeout": 9010,
}
},
"env_jboss_loadbalancer_vservers": {
"jboss": {
"ip_or_dns": "ip",
"port": "port",
"protocol": "SSL",
"ssl": true,
"timeout": 600,
}
"jboss_adm": {
"ip_or_dns": "som_other_ip",
"port": "rando_number",
"protocol": "SSL",
"ssl": true,
"timeout": 86410,
}
}
While my desired output should look like:
{
"decision_central": {
"ip_or_dns": "ip",
"port": "port",
"protocol": "SSL",
"ssl": true,
"timeout": 600,
},
"ftp_1": {
"ip_or_dns": "ip",
"port": "port",
"protocol": "FTP",
"ssl": false,
"timeout": 9010,
},
"jboss": {
"ip_or_dns": "ip",
"port": "port",
"protocol": "SSL",
"ssl": true,
"timeout": 600,
},
"jboss_adm": {
"ip_or_dns": "som_other_ip",
"port": "rando_number",
"protocol": "SSL",
"ssl": true,
"timeout": 86410,
}
So practically I need to remove "Top-level key tier" and merge their values. I've spent quite a time on this solution without any good progress and I would be happy for any advice :)
PS. The solution should be "clean" without any custom modules or actual tasks, the best idea would just add some functions to the filter pipeline mentioned above that will result in the correct format of dict
Thank you :)
CodePudding user response:
Select the attribute value
regexp: 'env_.*_loadbalancer_vservers(?![_.])'
l1: "{{ hostvars[inventory_hostname]|
dict2items|
selectattr('key', 'match', regexp)|
map(attribute='value')|
list }}"
gives the list
l1:
- decision_central:
ip_or_dns: ip
port: port
protocol: SSL
ssl: true
timeout: 600
- ftp_1: null
ip_or_dns: IP
port: port
protocol: FTP
ssl: false
timeout: 9010
- jboss:
ip_or_dns: ip
port: port
protocol: SSL
ssl: true
timeout: 600
jboss_adm:
ip_or_dns: som_other_ip
port: rando_number
protocol: SSL
ssl: true
timeout: 86410
Combine the items of the list
d1: "{{ {}|combine(l1) }}"
gives the dictionary you're looking for
d1:
decision_central:
ip_or_dns: ip
port: port
protocol: SSL
ssl: true
timeout: 600
ftp_1:
ip_or_dns: ip
port: port
protocol: FTP
ssl: false
timeout: 9010
jboss:
ip_or_dns: ip
port: port
protocol: SSL
ssl: true
timeout: 600
jboss_adm:
ip_or_dns: som_other_ip
port: rando_number
protocol: SSL
ssl: true
timeout: 86410