{"id":458,"date":"2011-01-09T21:53:29","date_gmt":"2011-01-09T20:53:29","guid":{"rendered":"http:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/"},"modified":"2011-01-09T21:53:29","modified_gmt":"2011-01-09T20:53:29","slug":"puppet-external-nodes-classifier-script-in-perl","status":"publish","type":"post","link":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/","title":{"rendered":"Puppet external nodes classifier script in Perl"},"content":{"rendered":"<p>The <a href=\"\/cstrep\/blog\/2011\/01\/06\/upgrade-of-puppet-from-0-24-5-to-2-6-2-got-nil-value-for-content\" rel=\"nofollow\">upgrade to puppet 2.6.2<\/a> worked out fine. Coming from 0.24.5, I noticed a really welcome speed improvement. However, I had a tricky problem.<\/p>\n<p>While upgrading to 2.6, I also decided to switch to <a href=\"http:\/\/docs.puppetlabs.com\/guides\/external_nodes.html\" rel=\"nofollow\">external nodes classifier<\/a> script. If you don&#39;t know about it, it&#39;s a nice puppet feature that I planned to use since the start. It allows you to write a small script in any language you want, to basically tell the puppetmaster, given the hostname, what you want that machine to be.<\/p>\n<p>Puppet calls your script with one argument that is the hostname of the machine that is asking for its catalog of resources. In your script, you have to output something like the following:<\/p>\n<pre><code>---\r\nclasses:\r\n  - perl\r\n  - apache\r\n  - ntp\r\n  - munin\r\nenvironment: production\r\nparameters:\r\n  puppet_server: my.puppetmaster.com\r\n<\/code><\/pre>\n<p>You can specify all the &quot;classes&quot; of that machine, so basically what you want puppet to install (or repair) on that machine. So far so good. So my classifier script looks into some preset directories for some project-specific JSON files, and then checks if any of these JSON files contain the name of the machine that puppet is asking for. Code follows:<\/p>\n<pre>#!\/usr\/bin\/env perl\r\n#\r\n# http:\/\/docs.puppetlabs.com\/guides\/external_nodes.html\r\n#\r\n\r\nuse strict;\r\nuse warnings;\r\nuse File::Basename ();\r\nuse File::Slurp ();\r\nuse JSON::XS ();\r\nuse YAML ();\r\n\r\nour $nodes_dir = &#39;\/etc\/puppet\/manifests\/nodes&#39;;\r\n\r\nour %default_params = (\r\n    puppet_server =&gt; &#39;my.puppetmaster.com&#39;,\r\n);\r\n\r\n# ...\r\n# A few very simple subs\r\n# omitted for brevity\r\n# ...\r\n\r\n# The hostname puppet asks for\r\nmy $wanted = $ARGV[0];\r\n\r\n# The data structure found in the JSON file\r\nmy $node_info = search_into_json_files_and_find($wanted);\r\n\r\nmy $puppet_classifier_info = {\r\n    classes =&gt; $node_info-&gt;{puppet_classes},\r\n    environment =&gt; &#39;production&#39;,\r\n    parameters =&gt; %default_params,\r\n};\r\n\r\nprint YAML-&gt;Dump($puppet_classifier_info);\r\n<\/pre>\n<p>Now, I don&#39;t know if you can immediately spot the problem here, but I didn&#39;t, so I wasted a good part of an afternoon chasing a bug I didn&#39;t even know existed. The resulting YAML (puppet wants YAML) was this one:<\/p>\n<pre>--- YAML \r\n--- \r\nclasses: \r\n    - geodns::production::backend \r\nenvironment: production \r\nname: z01-06-02 \r\nparameters: \r\n    puppet_server: z01-06-02\r\n<\/pre>\n<p>The problem with this, is that it looks innocent and valid, and in fact is valid, but it&#39;s <strong>two<\/strong> YAML documents, not one. So <a href=\"http:\/\/groups.google.com\/group\/puppet-users\/browse_thread\/thread\/ae1b060fef26741b\/664e23398e47f608?show_docid=664e23398e47f608\" rel=\"nofollow\">puppet will parse the <code>---  YAML<\/code> line<\/a> since that is one single complete YAML document, and ignore the rest.<\/p>\n<p>And why is that happening in the first place? Because of the <code>YAML-&gt;Dump()<\/code> call I wrote, instead of the correct <code>YAML::Dump()<\/code>&#8230; Eh :) So the correct code is:<\/p>\n<pre>print YAML::Dump($puppet_classifier_info);\r\n<\/pre>\n<p>Never use <code>YAML-&gt;Something()<\/code> &#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The upgrade to puppet 2.6.2 worked out fine. Coming from 0.24.5, I noticed a really welcome speed improvement. However, I had a tricky problem. While upgrading to 2.6, I also decided to switch to external nodes classifier script. If you don&#39;t know about it, it&#39;s a nice puppet feature that I planned to use since [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[91,50,260,76,78,346],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Puppet external nodes classifier script in Perl - Random hacking<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Puppet external nodes classifier script in Perl - Random hacking\" \/>\n<meta property=\"og:description\" content=\"The upgrade to puppet 2.6.2 worked out fine. Coming from 0.24.5, I noticed a really welcome speed improvement. However, I had a tricky problem. While upgrading to 2.6, I also decided to switch to external nodes classifier script. If you don&#039;t know about it, it&#039;s a nice puppet feature that I planned to use since [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/\" \/>\n<meta property=\"og:site_name\" content=\"Random hacking\" \/>\n<meta property=\"article:published_time\" content=\"2011-01-09T20:53:29+00:00\" \/>\n<meta name=\"author\" content=\"cosimo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"cosimo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/\"},\"author\":{\"name\":\"cosimo\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"headline\":\"Puppet external nodes classifier script in Perl\",\"datePublished\":\"2011-01-09T20:53:29+00:00\",\"dateModified\":\"2011-01-09T20:53:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/\"},\"wordCount\":301,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"keywords\":[\"development\",\"perl\",\"puppet\",\"servers\",\"upgrade\",\"yaml\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/\",\"name\":\"Puppet external nodes classifier script in Perl - Random hacking\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\"},\"datePublished\":\"2011-01-09T20:53:29+00:00\",\"dateModified\":\"2011-01-09T20:53:29+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Puppet external nodes classifier script in Perl\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\",\"name\":\"Random hacking\",\"description\":\"Assume nothing. Code defensively. Keep it simple, stupid!\",\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\",\"name\":\"cosimo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"caption\":\"cosimo\"},\"logo\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\"},\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Puppet external nodes classifier script in Perl - Random hacking","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/","og_locale":"en_US","og_type":"article","og_title":"Puppet external nodes classifier script in Perl - Random hacking","og_description":"The upgrade to puppet 2.6.2 worked out fine. Coming from 0.24.5, I noticed a really welcome speed improvement. However, I had a tricky problem. While upgrading to 2.6, I also decided to switch to external nodes classifier script. If you don&#39;t know about it, it&#39;s a nice puppet feature that I planned to use since [&hellip;]","og_url":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/","og_site_name":"Random hacking","article_published_time":"2011-01-09T20:53:29+00:00","author":"cosimo","twitter_card":"summary_large_image","twitter_misc":{"Written by":"cosimo","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#article","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/"},"author":{"name":"cosimo","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"headline":"Puppet external nodes classifier script in Perl","datePublished":"2011-01-09T20:53:29+00:00","dateModified":"2011-01-09T20:53:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/"},"wordCount":301,"commentCount":0,"publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"keywords":["development","perl","puppet","servers","upgrade","yaml"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/","url":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/","name":"Puppet external nodes classifier script in Perl - Random hacking","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website"},"datePublished":"2011-01-09T20:53:29+00:00","dateModified":"2011-01-09T20:53:29+00:00","breadcrumb":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/01\/puppet-external-nodes-classifier-script-in-perl\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.streppone.it\/cosimo\/blog\/"},{"@type":"ListItem","position":2,"name":"Puppet external nodes classifier script in Perl"}]},{"@type":"WebSite","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website","url":"https:\/\/www.streppone.it\/cosimo\/blog\/","name":"Random hacking","description":"Assume nothing. Code defensively. Keep it simple, stupid!","publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1","name":"cosimo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","caption":"cosimo"},"logo":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/"},"url":"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/"}]}},"_links":{"self":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/458"}],"collection":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/comments?post=458"}],"version-history":[{"count":0,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/458\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/media?parent=458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/categories?post=458"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/tags?post=458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}