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 [email protected].
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.