{"id":3528,"date":"2016-11-01T08:26:45","date_gmt":"2016-11-01T07:26:45","guid":{"rendered":"https:\/\/www.devco.net\/?p=3528"},"modified":"2016-11-03T05:16:23","modified_gmt":"2016-11-03T04:16:23","slug":"puppet-query-language","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2016\/11\/01\/puppet-query-language.php","title":{"rendered":"Puppet Query Language"},"content":{"rendered":"
For a few releases now PuppetDB had a new query language called Puppet Query Language or PQL for short. It’s quite interesting, I thought a quick post might make a few more people aware of it.<\/p>\n
PQL Queries look more or less like this:<\/p>\n
\r\nnodes { certname ~ 'devco' }\r\n<\/pre>\nThis is your basic query it will return a bunch of nodes, something like:<\/p>\n
\r\n[\r\n {\r\n \"deactivated\": null,\r\n \"latest_report_hash\": null,\r\n \"facts_environment\": \"production\",\r\n \"cached_catalog_status\": null,\r\n \"report_environment\": null,\r\n \"latest_report_corrective_change\": null,\r\n \"catalog_environment\": \"production\",\r\n \"facts_timestamp\": \"2016-11-01T06:42:15.135Z\",\r\n \"latest_report_noop\": null,\r\n \"expired\": null,\r\n \"latest_report_noop_pending\": null,\r\n \"report_timestamp\": null,\r\n \"certname\": \"devco.net\",\r\n \"catalog_timestamp\": \"2016-11-01T06:42:16.971Z\",\r\n \"latest_report_status\": null\r\n }\r\n]\r\n<\/pre>\nThere are a bunch of in-built relationships between say a node and it’s facts and inventory, so queries can get quite complex:<\/p>\n
\r\ninventory[certname] { \r\n facts.osfamily = \"RedHat\" and\r\n facts.dc = \"linodeldn\" and\r\n resources { \r\n type = \"Package\" and\r\n title = \"java\" and\r\n parameters.ensure = \"1.7.0\" \r\n } \r\n}\r\n<\/pre>\nThis finds all the RedHat machines in a particular DC with Java 1.7.0 on them. Be aware this will also find machines that are deactivated. <\/p>\n
I won’t go into huge details of the queries, the docs are pretty good – examples<\/a>, overview<\/a>. <\/p>\nSo this is quite interesting, this finally gives us a reasonably usable DB to do queries that mcollective discovery used to be used for – but of course its not a live view nor does it have any clue what the machines are up to but as a cached data source for discovery this is interesting.<\/p>\n
Using<\/H2>
\nCLI<\/H3>
\nYou can of course query this stuff on the CLI and I suggest you familiarise yourself with JQ<\/a>.<\/p>\nFirst you’ll have to set up your account:<\/p>\n
\r\n{\r\n \"puppetdb\": {\r\n \"server_urls\": \"https:\/\/puppet:8081\",\r\n \"cacert\": \"\/home\/rip\/.puppetlabs\/etc\/puppet\/ssl\/certs\/ca.pem\",\r\n \"cert\": \"\/home\/rip\/.puppetlabs\/etc\/puppet\/ssl\/certs\/rip.mcollective.pem\",\r\n \"key\": \"\/home\/rip\/.puppetlabs\/etc\/puppet\/ssl\/private_keys\/rip.mcollective.pem\"\r\n }\r\n}\r\n<\/pre>\nThis is in ~\/.puppetlabs\/client-tools\/puppetdb.conf<\/em> which is a bit senseless to me since there clearly is a standard place for config files, but alas.<\/p>\nOnce you have this and you installed the puppet-client-tools<\/em> package you can do queries like:<\/p>\n\r\n$ puppet query \"nodes { certname ~ 'devco.net' }\"\r\n<\/pre>\nPuppet Code<\/H3>
\nYour master will have the puppetdb-termini<\/em> package on it and this brings with it Puppet functions to query PuppetDB so you do not need to use a 3rd party module anymore:<\/p>\n\r\n$nodes = puppetdb_query(\"nodes { certname ~ 'devco' }\")\r\n<\/pre>\nPuppet Job<\/H3>
\nAt the recent PuppetConf Puppet announced that their enterprise tool puppet job<\/em> supports using this as discovery, if I remember right it’s something like:<\/p>\n\r\n$ puppet job run -q 'nodes { certname ~ 'devco' }'\r\n<\/pre>\nMCollective<\/H3>
\nAt PuppetConf I integrated this into MCollective and my Choria tool, mco feature still due a release (MCO-776<\/a>, choria<\/a>):<\/p>\nRun Puppet on all the nodes matched by the query:<\/p>\n
\r\n$ puppet query \"nodes { certname ~ 'devco.net' }\"|mco rpc puppet runonce\r\n<\/pre>\nThe above is a bit limited in that the apps in question have to specifically support this kind of STDIN discovery – the rpc<\/em> app does.<\/p>\nI then also added support to the Choria CLI:<\/p>\n
\r\n$ mco puppet runonce -I \"pql:nodes[certname] { certname ~ 'devco.net' }\"\r\n<\/pre>\n