Reputation: 892
I have this variable :
components:
comp_one:
name: first_component
remote_server_path: "/tmp/path/one"
binaries:
- test
- test_two
comp_two:
name: second_component
remote_server_path: "/tmp/path/two"
binaries:
- ed_test
- ed_test_2
comp_three:
name: third_component
remote_server_path: "/tmp/path/three"
What I'm trying to achieve, is to only keep sub-dictionaries of components
that has key binaries
, and the filter those binaries using my group_names
. Also, D'd like to only keep dict keys binaries
and remote_server_path
.
For example, if i have this hosts.yaml :
---
all:
children:
kubernetes_dev:
children:
ed_test:
hosts:
host_one:
ansible_host: XXX.XXX.XXX.XXX
ansible_ssh_user: ansible
test_two:
hosts:
host_one:
ansible_host: XXX.XXX.XXX.XXX
ansible_ssh_user: ansible
test:
hosts:
host_one:
ansible_host: XXX.XXX.XXX.XXX
ansible_ssh_user: ansible
The expected output would be :
comp_one:
remote_server_path: "/tmp/path/one"
binaries:
- test
- test_two
comp_two:
remote_server_path: "/tmp/path/two"
binaries:
- ed_test
I've successfully filtered the comp_three
dict using this :
- name: Debug
ansible.builtin.debug:
msg: "{{ item }}"
with_items: "{{ components | dict2items | selectattr('value.binaries', 'defined') }}"
But, I can't figure out a way to only select binaries
and remote_server_path
keys while filtering with my `group_names.
Does anyone can't help me find a clean way to do this ?
Regards,
Upvotes: 1
Views: 769
Reputation: 68294
Use group_names. This is: "List of groups the current host is part of.". For the host host_one in the inventory hosts.yaml this is
group_names: [ed_test, test, test_two]
Convert the dictionary components to list and test intersect of binaries and group_names. Default to empty list if the attribute binaries is missing
- set_fact:
selected_list: "{{ selected_list|d([]) + [_item] }}"
loop: "{{ components|dict2items }}"
when: my_groups|length > 0
vars:
_item: "{{ item|combine(my_value) }}"
my_value: "{{ {'value': {'binaries': my_groups,
'remote_server_path': item.value.remote_server_path}} }}"
my_groups: "{{ item.value.binaries|d([])|intersect(group_names) }}"
gives
selected_list:
- key: comp_one
value:
binaries:
- test
- test_two
remote_server_path: /tmp/path/one
- key: comp_two
value:
binaries:
- ed_test
remote_server_path: /tmp/path/two
Conver the list into a dictionary
- set_fact:
selected_dict: "{{ selected_list|items2dict }}"
gives the expected result
selected_dict:
comp_one:
binaries:
- test
- test_two
remote_server_path: /tmp/path/one
comp_two:
binaries:
- ed_test
remote_server_path: /tmp/path/two
Example of a complete playbook
- hosts: all
vars:
components:
comp_one:
name: first_component
remote_server_path: /tmp/path/one
binaries:
- test
- test_two
comp_two:
name: second_component
remote_server_path: /tmp/path/two
binaries:
- ed_test
- ed_test_2
comp_three:
name: third_component
remote_server_path: /tmp/path/three
tasks:
- set_fact:
selected_list: "{{ selected_list|d([]) + [_item] }}"
loop: "{{ components|dict2items }}"
when: my_groups|length > 0
vars:
_item: "{{ item|combine(my_value) }}"
my_value: "{{ {'value': {'binaries': my_groups,
'remote_server_path': item.value.remote_server_path}} }}"
my_groups: "{{ item.value.binaries|d([])|intersect(group_names) }}"
- set_fact:
selected_dict: "{{ selected_list|items2dict }}"
- debug:
var: selected_dict
Upvotes: 1