On Tuesday, April 15, 2014 9:21:38 AM UTC-5, David Portabella wrote: > > Ok, I see. > > Thanks for all this discussion! > > > > No, you *never* need to use parameterized classes. > > If you are determined to avoid resource-like class declarations, > > then you can replace each parameterized class in your manifest set with > a non-parameterized version that obtains its data via direct hiera() calls. > > you mean replacing: > class tomcat ( > port = hiera('tomcat_port', 7070) > ssl_port = hiera('tomcat_port', 7071) > ) { > notice $port > notice $ssl_port > } > by: > class tomcat { > $port = hiera('tomcat_port', 7070) > $ssl_port = hiera('tomcat_port', 7071) > notice $port > notice $ssl_port > } > ? >
Yes, that's pretty much what I mean, but it is poor form to put explicit hiera calls in your parameter list, because Puppet (v3+) performs hiera lookups for class parameters automatically (using a key based on class name and parameter name; see http://docs.puppetlabs.com/puppet/3/reference/lang_classes.html#include-like-vs-resource-like). If you are going to write parameterized classes -- and that's not a bad thing in itself -- then the best form would be more like this: class tomcat ( port = 7070 ssl_port = 7071 ) { notice $port notice $ssl_port } Puppet will first attempt to resolve the parameters via hiera keys 'tomcat::port' and 'tomcat::ssl_port', and in each case it will use the declared default value if the lookup fails. Your alternative form is exactly what I meant by a way to write the same class without parameters. > for a java/scala software developer like me, this does not look a good, > because it makes it more difficult to unit test. > In a sense, the non-parameterized version is easier to unit test, because you have fewer cases (depending on how thorough you are). You have the cases for hiera-provided data either way, and for parameterized class you also have cases for DSL-declared parameter values. Before this goes too far off on a tangent, though, I reiterate that it is not parameterized classes themselves that are problematic (unless indirectly). The problem is associated with the resource-like class declaration syntax. The resource-like syntax can be used even with unparameterized classes, so it really is a separate consideration. > maybe with puppet it is easy to build and pass different hiera data for > unit testing? > > There is, for example, https://github.com/amfranz/rspec-hiera-puppet. No doubt there are others. Moreover, because Hiera supports pluggable back ends and is comparatively simple, it is likely that you could build your own without too much trouble if what's already available doesn't suit you. > > > Hiera's YAML back end is not the ultimate solution, but the Hiera > *framework* can be. > > You can plug in pretty much any kind of data lookup or computation. > > Ok. I didn't know about this neither. I'll take a look. > > > so, one specific example, > someone (not me) implemented a class tomcat with parameters port and > ssl_port. > I want to use that class, > and I want that the ssl_port is always port + 1 (I don't want this to be > configurable in hiera) > Every parameter of every class is ALWAYS configurable via Hiera (in Puppet 3+). That was one if the most significant advances in Puppet 3. You can override whatever Hiera data may be provided via a resource-like class declaration, but that opens you up to problems, as we have been discussing. > so, in my hiera data, I will specify port, and then I have my class: > class application ($port) { > class {tomcat: > port => $port > ssl_port => $port+1 > } > class {nginx: > ... > } > # configuration files... > } > > how would you do this without using resource-like class declaration? > > At the present time, I think I would need to write a custom hiera back end that served keys 'tomcat::port' and 'tomcat::ssl_port' with values having the desired relationship, and to insert that into my hiera configuration at higher priority than the YAML back end. The class 'application' then declares class 'tomcat' as "include 'tomcat'". Really, though, that's a heck of a PITA for such a small constraint. Why not just declare both parameters in the normal YAML back end, and verify the proper ports via functional testing? > > > Or you can make exactly one class responsible for performing any needed > computations and declaring the > > class for which you want to use a resource-like declaration, and any > node or other class must declare the > > wrapper class instead (using 'include' or one of its brethren). > > I see. similar to the example42 params pattern. you mean something like: > class parameters { > $port = hiera("port") > $ssl_port = $port + 1 > } > > Yuck! 1. Unless for some very special need (for which I do not presently have an example), do not use hiera() calls as parameter defaults. 2. Never set a class parameter default as a function of other class parameter values. It is not reliable. But you could do this: class parameters ($port) { $ssl_port = $port +1 } > class tomcat { > include parameters > notice $parameters::port > notice $parameters::ssl_port > } > > > And then the rest of class 'tomcat' uses $parameters::port and $parameters::ssl_port for the HTTP and HTTPS ports? Ok, but that requires you to modify the 'tomcat' class. If you're willing to do that, then why introduce a new class as a data intermediary? My comments about a wrapper class were directed more towards your class 'application' above or something very similar. The parameter $application::port should in that case be provided by Hiera (else you just move the problem up one level), and you must enforce a restriction that there is no other declaration of class 'tomcat' anywhere in your manifest set. It's that last bit that tends to be the sticking point, especially if you have a large Puppet code base or use a lot of third-party modules. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/20b06a1d-3458-4205-82aa-307e9f29e90c%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.