Short answer (TL;DR)
Yes, this is possible, but it is extremely cumbersome, because, at least in terms of working with JMESpath, the source dataset is poorly normalized for this kind of general-purpose query.
Context
- jmespath query language
- querying object properties for deeply nested objects
Problem
- How to construct a jmespath query with filter expressions
- The goal is to filter on objects with arbitrarily nested object properties
Solution
- This can be done with jmespath, but the operation will be cumbersome
- One problematic issue: the source dataset is poorly normalized for this kind of jmespath query
- In order to construct the jmespath query, we have to assume all the primary object keys are known in advance of creating the query
- In this specific example, we have to know that there are three and only three hostnames in advance of constructing the jmespath query ... this is not a favorable circumstance if we want the flexibility to specify any arbitrary number of hostnames
Example
The following (way-too-huge) jmespath query ...
[
{
"hostname": `oclab1n01.example.org`
,"fileexists_stat_exists": @.hostvars."oclab1n01.example.org".fileexists.stat.exists
}
,{
"hostname": `oclab1n02.example.org`
,"fileexists_stat_exists": @.hostvars."oclab1n02.example.org".fileexists.stat.exists
}
,{
"hostname": `oclab1n03.example.org`
,"fileexists_stat_exists": @.hostvars."oclab1n02.example.org".fileexists.stat.exists
}
]|[? @.fileexists_stat_exists == `true`]|[*].hostname
returns the following desired result
[
"oclab1n02.example.org",
"oclab1n03.example.org"
]
Pitfalls
- One major pitfall with this use-case is the source dataset is poorly normalized for this kind of query
- A more flattened data structure would be easier to query
- Consequently, if possible, a better approach would be to flatten the source dataset before running jmespath queries against it
Alternate example with a different original dataset
If the original data were organized as a list of objects, instead of a set of nested objects within objects, it would be easier to search, sort and filter the list without having to know in advance how many hostname entries are involved.
{"hostvars": [
{"hostname":"oclab1n01.example.org"
,"fileexists": true
,"filechanged": false
,"filefailed": false
,"filestat_exists": false
,"we_can_even_still_deeply_nest":{"however":
{"im_only_doing":"it here","to":"prove a point"}
}
}
,{"hostname":"oclab1n02.example.org"
,"fileexists": true
,"filechanged": false
,"filefailed": false
,"filestat_exists": true
}
,{"hostname":"oclab1n03.example.org"
,"fileexists": true
,"filechanged": false
,"filefailed": false
,"filestat_exists": true
}
]
}
The above re-normalized dataset can now be easily queried
hostvars|[? @.filestat_exists == `true`]|[*].hostname