Keeping You Honest

Extending Puppet 3′s Databindings to Types

by on Feb.08, 2013, under Puppet

I know a lot of you are looking forward to Part 3 It is being worked on, but writing the modules for it is going a little slow.

I’ve been toying with some ideas, and been discussing them with various members of the community and PuppetLabs devs. So I figured I would give it a quick write up to hash out a few last details before I submit a feature One request.

One of the biggest new things to happen to Puppet was databinding. This feature allows you to automagically externalize your data just be setting the class up as a parametrized class.

class foo (
  $param1 = 'bar',
){
  ...
}

And then just add the following to the proper yaml file based on your hierarchy: foo::param1: ‘bat’

But this is limited to classes. And I started to wonder… why? Why can’t this be used with defined types? And of course, if it is used with defined types, then why not let it be used with built in types and custom types? And I can’t really see any reason why databindings shouldn’t be available across the board.

This, however, brings us to a problem.  With a class, the lookup key is class::param_name. Classes are singletons, so this is not a problem.  However, defined types and built in resources are not – they can be used over and over as long as the title/name is unique. So how then do we address the lookups?

My first thought was to use type::title::param. For example, if we have a module named apache2 and it has a define for vhosts, it would be apache2::vhosts when you reference it. Common parameters for a vhost define are documentroot, port, template etc.  These could use a key of apache2::vhosts::<$title>::documentroot or apache2::vhosts::<$title>::port. For most cases, and I believe most if not all built in types, this will work fine.

However, there are some modules that use top level defines. For example, the concat module has a define that is simply named “concat”. And there is a concat::setup class. Now, let’s say that the concat::setup class and the concat define both take a parameter called x. (this is a bit contrived, but it illustrates the point, and concat does use such a top level define). The parameter for the class would be concat::setup::x. Now, we are using the define, and we add concat { ‘setup’: } to the catalog.  Now we have a problem… this would also be referenced as concat::setup::x.

So that is one potential problem – and a big one for those cases where it pops up. Personally, I don’t know of too many “real” cases where this would be a problem, but I have been told it could happen quite often.

Another possible idea would be to put all resources into a special namespace for the key lookups.  Such as type::resource::<$title>::param. Using our example from above, the lookup key would then be type::concat::setup:x .  Of course, tthe fixed string doesn’t have to be “type” – it could be whatever is deemed reasonable. This, of course, doesn’t entirely remove the problem, just narrows the scope in which it can happen. In all honesty, I am not sure on what the best answer is. But I would really like to be able like to be able to do something like user { ‘bob’: } and have it automagically pull in the parameters.

 

I do realize that I can do something close to this using create_resources(), but you can’t chain to functions and wrapping create_resources() in anchor tags is a bit tedious, not to mention it makes the code harder to read.

If you have any thoughts or ideas on how to do this, please leave me a comment here, look me up on IRC (FriedBob in #puppet and #puppet-dev on Freenode) or twitter ( @FriedBob).

:, , , ,

1 Comment for this entry

Leave a Reply

Looking for something?
You can search for it here.

Custom Search

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!