Ask Your Question
1

Splitting classes into multiple files ?

asked 2015-04-23 03:16:02 -0500

maduma gravatar image

Strategy pattern for puppet class ?

I Want to split my complicated class 'mess' in multiple file.
People with different skills will implentent the subclasses.
What do you think about the following pattern?

class mess
(
  $database,
  $dbuser,
  $dbpassword,
  $frequency,
  $format,
)
{
  # Select the subclass at runtime
  # can be much more complicated than this
  $subclass = $operatingsystem ? {
    'Solaris'          => 'solaris',
    'AIX'              => 'aix',
    /(Fedora|RedHat)/  => 'redhat',
    /(Darwin|FreeBSD)/ => 'bsd',
  }

  # include the subclass 
  class {"mess::$subclass":
    database   => $database,
    dbuser     => $dbuser,
    dbpassword => $dbpassword,
    $frequency => $frequency,
    format     => $format,
  }
}
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
0

answered 2015-04-23 09:05:49 -0500

JohnsonEarls gravatar image

updated 2015-04-24 11:41:57 -0500

If the only difference between the subclasses is setting parameters, then another way to do this would be to inherit a parameters base class, and have that parameters base class do the logic to set the parameters:

class mess::params
{
  # default the user parameters to `undef` - or pick an appropriate default value
  $database = undef
  $dbuser = undef
  $dbpassword = undef
  $frequency = undef
  $format = undef

  # set other parameters based on the OS family
  case $::osfamily {
    'Debian' : {
      $package = '...'
      $conffile = '...'
    }
    'RedHat' : {
      $package = '...'
      $conffile = '...'
    }
    default : {
      fail("Unknown OS family ${::osfamily}")
    }
  }
}

And your main class would then be...

class mess
(
  $database = $mess::params::database ,
  $dbuser = $mess:params::dbuser ,
  $dbpassword = $mess::params::dbpassword ,
  $frequency = $mess::params::frequency ,
  $format = $mess::params::format ,
  $package = $mess::params::package ,
  $conffile = $mess::params::conffile ,
) inherits mess::params
{
  # use os-specific $package and $conffile from params here
}

This also gives you the option of overriding the OS-specific parameters if needed.

If os-specific logic is also required, then you code that logic directly into the mess class, or you can pull in an os-specific subclass (note, the mess::params class is still required for this example):

class mess
(
  $database = $mess::params::database ,
  $dbuser = $mess:params::dbuser ,
  $dbpassword = $mess::params::dbpassword ,
  $frequency = $mess::params::frequency ,
  $format = $mess::params::format ,
  $package = $mess::params::package ,
  $conffile = $mess::params::conffile ,
) inherits mess::params
{
  # use os-specific $package and $conffile from params here
  # if os-specific logic is required, include a subclass that inherits from mess
  contain "mess::${::osfamily}"
}

and the subclass might look like:

class mess::RedHat
inherits mess
{
  # do specific stuff for RedHat
}

By using inheritance, you don't need to pass the specific values around.

edit flag offensive delete link more

Comments

Is it possible to inherit from base class with parameters for os-specific logic? The anchor stuff looks a bit cryptic

maduma gravatar imagemaduma ( 2015-04-24 03:39:24 -0500 )edit

i'm using puppet 3.6.1. Can i replace the anchor stuff with: contain "mess::${::osfamily}"

maduma gravatar imagemaduma ( 2015-04-24 06:26:31 -0500 )edit

Yes, I edited my answer to use contain instead of anchor.

JohnsonEarls gravatar imageJohnsonEarls ( 2015-04-24 07:44:33 -0500 )edit

Why does the documentation say that is not allowed to inherit from parametrized base class ? In this method mess::RedHat inherits from base class mess which have parameters.

maduma gravatar imagemaduma ( 2015-04-24 08:10:10 -0500 )edit

When the documentation refers to a "base class" in that context, they're talking about the "ultimate" base class (the one with no `inherits` clause). mess::RedHat has the superclass of mess, which has the superclass of mess::params. mess::params has no superclass, and so is the "base class".

JohnsonEarls gravatar imageJohnsonEarls ( 2015-04-24 08:54:28 -0500 )edit
0

answered 2015-04-24 13:23:59 -0500

maduma gravatar image

This is working even if mess::solaris inherits from a parametrized class. mess must have default for each parameters (or you may user hiera)

class mess
(
  $database   = undef,
  $dbuser     = undef,
  $dbpassword = undef,
  $frequency  = undef,
  $format     = undef,
)
{
  # Select the subclass at runtime
  # can be much more complicated than this
  $subclass = $::operatingsystem ? {
    'Solaris'          => 'solaris',
    'AIX'              => 'aix',
    /(Fedora|RedHat)/  => 'redhat',
    /(Darwin|FreeBSD)/ => 'bsd',
  }
  # include the subclass at runtime
  contain "mess::$subclass"
}

class mess::solaris inherits mess {
  # do os specific logic
}
edit flag offensive delete link more

Comments

I understand that this may "work". There's a difference between "it works" and "it's supported": """ Note: This version of Puppet does not support using parameterized classes for inheritable base classes. The base class must have no parameters. """

JohnsonEarls gravatar imageJohnsonEarls ( 2015-04-24 15:19:38 -0500 )edit

The rest of the discussion for class inheritance makes it clear that the intent of the "supported" statement is that all parameterized classes must inherit from a class that is evaluated before the parameterized class's parameters are evaluated.

JohnsonEarls gravatar imageJohnsonEarls ( 2015-04-24 15:21:39 -0500 )edit

@Johnson Many thanks for helping me understanding better this fabulous tool.

maduma gravatar imagemaduma ( 2015-04-24 15:52:40 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2015-04-23 03:16:02 -0500

Seen: 465 times

Last updated: Apr 24 '15