On Mar 6, 1:00 pm, Justin Lloyd <jstn...@gmail.com> wrote:
> John,
>
> I'm running into some snags of my own and your explanations have been
> helpful. However, I'd like to ask if you can comment a bit more on the
> emphasis Puppet Labs has on parameterized classes versus include. For one,
> I'm thinking of modules available via github. Take the
> puppetlabs/mcollective module, for example. It's highly parameterized and I
> have some "wrapper classes" like this:
>
>     class puppet_base ( $puppet_master = false, $mcollective_client = false
> ) {
>
>         class { 'system_base': } # basics needed by all systems
>
>         class { 'puppet':
>             master  => $puppet_master,
>             require => Class['system_base'],
>         }
>
>         class { 'mcollective_server':
>             mcollective_client => $mcollective_client,
>         }
>     }
>
>     class mcollective_server ( $mcollective_client => false ) {
>         package { 'stomp':
>             ensure   => present,
>             provider => 'gem',
>         }
>
>         if $mcollective_client {
>             class { 'activemq':
>                 require => Package['stomp'],
>                 before  => Class['mcollective'],
>             }
>         }
>
>         class { 'mcollective': # puppetlabs/mcollective module
>             client => $mcollective_client,
>         }
>     }
>
> This seemed to me like an appropriate use of parameterized classes and a
> way of keeping node definitions simple and readable, like so:
>
>     node 'regular-host' {
>         class { 'puppet_base':
>             stage => 'first'
>         }
>     }
>
>     node 'mco-admin-host': {
>         class { 'puppet_base':
>             stage => 'first',
>             mcollective_client => true,
>         }
>     }
>
>     node 'puppet-master' {
>         class { 'puppet_base':
>             stage => 'first',
>             puppet_master => true,
>         }
>     }
>
> I am running into some snags with ensuring curl and rubygems packages are
> installed prior to the puppet_base being evaluated (that's a long story),
> but that may be more of an issue with better use of stages.
>
> Can you comment on the above and how it is impacted by your explanations of
> includes (and smarter classes) vs. parameterization?


First, I think run stages are a better tool in principle than they are
in practice.  There is nothing you can do with stages that you cannot
also do with ordinary resource / class relationships, and people
sometimes get into trouble with run stages because they end up with
more implied relationships than they needed or wanted.  If people have
run stages working well for them then great, but I recommend
approaching them with caution.  If ordinary relationships can do the
job without too much trouble, then I think that's a better bet.  Above
all, do not use run stages without specific need.

Second, here are some of my design principles for classes:

1) 'include' classes wherever a class or definition has either a
logical or a functional dependency.  That is,
1a) If one class (or definition) refers to variables or resources
declared in another, then the former should directly or indirectly
'include' the latter
1b) If the configuration described by one class (or definition)
depends for client-side correctness or proper function on separate
configuration described by a different class, then the former should
directly or indirectly 'include' the latter (even if (1a) does not
apply)

2) Declare all needed resource relationships, as specifically as
possible.  In particular, prefer resource / resource relationships to
resource / class and class / class relationships.

3) Define and document modules' and classes' scope and external
interfaces.

4) Avoid use of dynamic scoping.


Regarding (1): as of 2.7.x, this principle is not usable with
parameterized classes.  That is my own biggest reason for avoiding
them.  Also, principle (1) implies that some classes will be
'include'd more than once, which is just fine.  The overall result of
applying this principle is that you can declare (via 'include' or
'require') any class in any place in your manifest without worrying
about parse-order issues or broken configurations (for lack of needed
other classes).  Not being able to rely on that result is a
significant weakness of any class that does not apply principle (1),
among them all classes that declare parameterized classes.

Regarding (2): this one wil be controversial, at least with regard to
cross-module relationships.  Looking ahead to (3), however, I consider
those resources available for cross-module relationships to be part of
modules' external interfaces, to be referenced only if documented.
Declaring relationships as precisely as possible gives Puppet the
greatest freedom to find an acceptable order of resource application.
Ideally, one module would not have to worry about the details of
application order within a different module, but it is very hard to
keep modules so self-contained without allowing them to balloon to
cover huge swaths of configuration space.


As for the specifics of your code:

A) Classes that are certain to not be subject to my principle (1) are
the least problematic when parameterized, though that does not mean
that they should not themselves apply principle (1) in their bodies.
Perhaps your wrapper classes are in that category.

B) I urge you to consider feeding data to your classes via Hiera
instead of via class parameters.  Becoming familiar with Hiera and
using it effectively will pay off.  Among other things, Hiera
integration into Telly will contribute to enabling you to apply
principle (1) to parameterized classes (or so I understand).

C) Other than generally objecting to parameterized classes, I don't
see anything awful about what you presented.


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to puppet-users@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to