Let’s assume the following fictional dictionary with nested lists, dictionaries, and strings, of arbitrary depth.:
domain_definition.yml
---
domain_definition:
- name: server01
cluster: cluster0
port: '8070'
- name: server11
cluster: cluster1
port: '8080'
workstations:
- name: debian1
revision: '2016-06-21'
url: http://debian1.example.com:9911/2016-06-21
- name: ubuntu1
revision: '2017-08-16'
url: http://ubuntu1.example.com:9912/2017-08-16
- name: server12
cluster: cluster2
port: '8090'
workstations:
- name: debian2
revision: '2018-04-15'
url: http://debian2.example.com:9921/2018-04-15
- name: ubuntu2
revision: '2020-01-12'
url: http://ubuntu2.example.com:9922/2020-01-12
The goal is to extract as efficiently as possible (the original file can be quite large) a workstation matching:
- a workstation os with its : for instance ubuntu1 ↔ 2017-08-16
- only a workstation os : for instance debian2
As you can see from example above, the key is not always set.
A major constraint is to avoid “json_query” as it cannot deal properly with keys containing a colon (as it may happen in my real context), last time I checked
I unsuccessfully tried different tasks, including the following:
- name: Extracting a value of a field deep within a list of complex dictionaries when some keys match other values
hosts:
- localhost
strategy: debug
tasks:
- name: Including domain_definition
include_vars: "domain_definition.yml"
- name: Extracting the OS URL when <os_revision> is known
vars:
- os_name: ubuntu1
- os_revision: 2017-08-16
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations') |
list |
selectattr('name', 'eq', os_name) |
list |
selectattr('revision', 'eq', os_revision) |
map(attribute= 'url') |
first }}"
ignore_errors: yes
- name: Extracting the OS URL when <os_revision> is known
vars:
- os_name: ubuntu1
- os_revision: 2017-08-16
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations.name', 'eq', os_name) |
list |
selectattr('workstations.revision', 'eq', os_revision) |
map(attribute= 'workstations.url') |
first }}"
ignore_errors: yes
- name: Extracting the OS URL when <os_revision> is unknown
vars:
- os_name: debian2
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations') |
list |
selectattr('name', 'eq', os_name) |
map(attribute= 'url') |
first }}"
ignore_errors: yes
- name: Extracting the OS URL when <os_revision> is unknown
vars:
- os_name: debian2
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations.name', 'eq', os_name) |
map(attribute= 'workstations.url') |
first }}"
ignore_errors: yes
I always get the error msg: ‘dict object’ has no attribute ‘workstations’.
Any suggestion?