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.

Reply via email to