Let’s assume the following fictional list of dictionaries:
domain_definition:
- name: server11
cluster: cluster1
db_servers: - server12
- server21
port: ‘8080’ - name: server12
cluster: cluster1
db_servers: - server22
port: ‘8090’ - name: server13
cluster: cluster1
port: ‘8091’ - name: server21
cluster: cluster2
db_servers: - server12
- server22
port: ‘9080’ - name: server22
cluster: cluster2
port: ‘9090’
The goal is to list all ports of used ‘db_servers’, so the expected list is:
- ‘8090’
- ‘9080’
- ‘9090’
- ‘8090’
- ‘9090’
The constraint is to use one (some operation is performed for each item) and only one loop (the list is huge in reality).
The following does not work because selectattr expects a value, not a list of values:
- name: Extracting a list of values of a field within a list of dictionaries when a key matches another list of values
hosts: - localhost
strategy: debug
tasks: - name: Extracting a list of values of a field within a list of dictionaries when a key matches another list of values
vars:
domain_definition: - name: server11
cluster: cluster1
db_servers: - server12
- server21
port: ‘8080’ - name: server12
cluster: cluster1
db_servers: - server22
port: ‘8090’ - name: server13
cluster: cluster1
port: ‘8091’ - name: server21
cluster: cluster2
db_servers: - server12
- server22
port: ‘9080’ - name: server22
cluster: cluster2
port: ‘9090’
db_servers_names: “{{ item.db_servers |
default() |
list }}”
db_servers_used_ports: “{{ domain_definition |
selectattr(‘name’, ‘eq’, db_servers_names) |
map(attribute= ‘port’) |
list }}”
debug:
msg: - “db_servers_names: {{ db_servers_names }}”
- “db_servers_used_ports: {{ db_servers_used_ports }}”
loop: “{{ domain_definition }}”
Any suggestion?