The queries we've looked at so far are quite powerful and useful, but what ifyour query needs to consider both resources and facts?
For instance, suppose you're configuring a load balancer, and need the IP addresses of your Apache servers. You could find those servers by using this resource query:
["and", ["=", "type", "Class"], ["=", "title", "Apache"]]
This will find all the Class[Apache]
resources, which each knows the certnameof the node it came from. Then you could put all those certnames into a factquery:
["and", ["=", "name", "ipaddress"], ["or", ["=", "certname", "a.example.com"], ["=", "certname", "b.example.com"], ["=", "certname", "c.example.com"], ["=", "certname", "d.example.com"], ["=", "certname", "e.example.com"]]]
But this query is lengthy, and it requires some logic to assemble and run thesecond query. There has to be a better way! What if we could find theClass[Apache]
servers and use the results of that query to find thecertname? We can, with this fact query:
["and", ["=", "name", "ipaddress"], ["in", "certname", ["extract", "certname", ["select_resources", ["and", ["=", "type", "Class"], ["=", "title", "Apache"]]]]
This may appear a little daunting, so we'll look at it piece by piece.
Let's start with "select_resources". This operator takes one argument, which isa resource query, and returns the results of that query in exactly the formyou would expect to see them if you did a plain resource query.
We then use an operator called "extract" to turn our list of resources intojust a list of certnames. So we now conceptually have something like:
["in", "certname", ["foo.example.com", "bar.example.com", "baz.example.com"]]
The "in" operator matches facts whose "certname" is in the supplied list. (In our case, this list is generated by a subquery. To use a literal list, you must use the the "array" syntax described in the AST array documentation.)
At this point, our query seems a lot like the one above, except we didn't have to specify exactly which certnames to use, and instead we get them in the same query.
Similarly, there are "select_facts", "select_nodes", and "select_fact_contents" operators,which will perform subqueries against the facts, nodes, and fact-contents endpoints.Any subquery operator is usable from any queryable endpoint. Subqueries may be nested,and multiple subqueries may be used in a single query. For more information seethe select_<ENTITY>
documentation.