{"id":3428,"date":"2016-03-18T08:40:11","date_gmt":"2016-03-18T07:40:11","guid":{"rendered":"https:\/\/www.devco.net\/?p=3428"},"modified":"2016-03-18T12:16:12","modified_gmt":"2016-03-18T11:16:12","slug":"puppet-4-type-aliases","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2016\/03\/18\/puppet-4-type-aliases.php","title":{"rendered":"Puppet 4 Type Aliases"},"content":{"rendered":"

Back when I first took a look at Puppet 4<\/a> features I explored the new Data Types and said:<\/p>\n

\nAdditionally I cannot see myself using a Struct like above in the argument list \u2013 to which Henrik says they are looking to add a typedef thing to the language so you can give complex Struc\u2019s a more convenient name and use that. This will help that a lot.\n<\/p><\/blockquote>\n

And since Puppet 4.4.0 this has now become a reality. So a quick post to look at that.<\/p>\n

The Problem<\/H2>
\nI’ve been writing a
Hiera based node classifier<\/a> both to scratch and itch and to have something fairly complex to explore the new features in Puppet 4.<\/p>\n

The classifier takes a set of classification rules and produce classifications – classes to include and parameters – from there. Here’s a sample classification:<\/p>\n

\r\nclassifier::rules:\r\n  RedHat VMs:\r\n    match: all\r\n    rules:\r\n      - fact: \"%{facts.os.family}\"\r\n        operator: ==\r\n        value: RedHat\r\n      - fact: \"%{facts.is_virtual}\"\r\n        operator: ==\r\n        value: \"true\"\r\n    data:\r\n      redhat_vm: true\r\n      centos::vm::someprop: someval\r\n    classes:\r\n      - centos::vm\r\n<\/pre>\n

This is a classification rule that has 2 rules to match against machines running RedHat like operating systems and that are virtual. In that case if both these are true it will:<\/p>\n

    \n
  • Include the class centos::vm<\/em><\/li>\n
  • Create some data redhat_vm => true<\/em> and centos::vm::someprop => someval<\/em>\n<\/ul>\n

    You can have an arbitrary amount of classifications made up of a arbitrary amount of rules. This data lives in hiera so you can have all sorts of merging, overriding and knock out fun with it.<\/p>\n

    The amazing thing is since Puppet 4.4.0 there is now no Ruby code involved in doing what I said above, all the parsing, looping, evaluating or rules and building of data structures are all done using functions written in the pure Puppet DSL.<\/p>\n

    There’s some Ruby there in the form of a custom backend for the new lookup based hiera system – but this is experimental, optional and a bit crazy. <\/p>\n

    Anyway, so here’s the problem, before Puppet 4.4.0 my main class had this in:<\/p>\n

    \r\nclass classifier (\r\n  Hash[String,\r\n    Struct[{\r\n      match    => Enum[\"all\", \"any\"],\r\n      rules    => Array[\r\n        Struct[{\r\n          fact     => String,\r\n          operator => Enum[\"==\", \"=~\", \">\", \" =>\", \"<\", \"<=\"],\r\n          value    => Data,\r\n          invert   => Optional[Boolean]\r\n        }]\r\n      ],\r\n      data     => Optional[Hash[Pattern[\/\\A[a-z0-9_][a-zA-Z0-9_]*\\Z\/], Data]],\r\n      classes  => Array[Pattern[\/\\A([a-z][a-z0-9_]*)?(::[a-z][a-z0-9_]*)*\\Z\/]]\r\n    }]\r\n  ] $rules = {}\r\n) {\r\n....\r\n}\r\n<\/pre>\n

    This describes the full valid rule as a Puppet Type. It’s pretty horrible. Worse I have a number of functions and classes all that receives the full classification or parts of it and I’d have to duplicate all this all over.<\/p>\n

    The Solution<\/H2>
    \nSo as of yesterday I can now make this a lot better:<\/p>\n
    \r\nclass classifier (\r\n  Classifier::Classifications  $rules = {},\r\n) {\r\n....\r\n}\r\n<\/pre>\n

    to do this I made a few files in the module:<\/p>\n

    \r\n# classifier\/types\/matches.pp\r\ntype Classifier::Matches = Enum[\"all\", \"any\"]\r\n<\/pre>\n
    \r\n# classifier\/types\/classname.pp\r\ntype Classifier::Classname = Pattern[\/\\A([a-z][a-z0-9_]*)?(::[a-z][a-z0-9_]*)*\\Z\/]\r\n<\/pre>\n

    and a few more, eventually ending up in:<\/p>\n

    \r\n# classifier\/types\/classification.pp\r\ntype Classifier::Classification = Struct[{\r\n  match    => Classifier::Matches,\r\n  rules    => Array[Classifier::Rule],\r\n  data     => Classifier::Data,\r\n  classes  => Array[Classifier::Classname]\r\n}]\r\n<\/pre>\n

    Which you can see solves the problem quite nicely. Now in classes and functions where I need lets say just a Rule all I do is use Classifier::Rule<\/em> instead of all the crazy.<\/p>\n

    This makes the native Puppet Data Types perfectly usable for me, well worth adopting these.<\/p>\n","protected":false},"excerpt":{"rendered":"

    Back when I first took a look at Puppet 4 features I explored the new Data Types and said: Additionally I cannot see myself using a Struct like above in the argument list \u2013 to which Henrik says they are looking to add a typedef thing to the language so you can give complex Struc\u2019s […]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","footnotes":""},"categories":[7],"tags":[85,21],"_links":{"self":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/3428"}],"collection":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/comments?post=3428"}],"version-history":[{"count":3,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/3428\/revisions"}],"predecessor-version":[{"id":3476,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/3428\/revisions\/3476"}],"wp:attachment":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/media?parent=3428"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/categories?post=3428"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/tags?post=3428"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}