How to make a variable in a parameterized Puppet class default to the value of another parameter

puppet

I have a Puppet class that sets up a number of services and
configuration files. In most cases, there is a default server that
can be used, but it is also possible to configure explicit per-service
servers. I find myself doing this all the time:

class myclass (
  $default_server    = 'server.example.com',
  $server_for_thing1 = undef,
  $server_for_thing2 = undef,
  $server_for_thing3 = undef
) {

  if $server_for_thing1 {
    $real_server_for_thing1 = $server_for_thing1
  } else {
    $real_server_for_thing1 = $default_server
  }

  # ...and so forth...
}

As the number of possible services grows large, this syntax becomes
unwieldy. Is there a better way of doing this? I really want
something along the lines of:

$server_for_thing1 = $server_for_thing1 || $default_server

…but variables cannot be re-assigned in Puppet. Are there better
ways of doing this?

Best Answer

While not exactly what you are asking for, have you considered using an External Node Classifier to set and override the default value for specific servers? I believe the ECN is the "puppet way" of doing things in a situation like yours.

EDIT: (based on the first comment)

Second idea: you can use a custom function to at least make the multi-line repeated logic a bit more readable. Something like this, which returns the first "defined" argument, though with puppet, I am never sure what "defined" is (in this case, "undef" gets passed as an empty string to the function, which is still good enough).

module Puppet::Parser::Functions
    newfunction(:get_default, :type => :rvalue) do |args|
        value = nil
        args.each { |x|
            if ! x.nil? and x.length > 0
                value = x
                break
            end
        }
        return value
    end
end

You can then call it as many times as you want:

$real_server_for_thing1 = get_default($server_for_thing1, $default_server)
$real_server_for_thing2 = get_default($server_for_thing2, $default_server)
$real_server_for_thing3 = get_default($server_for_thing3, $default_server)
Related Topic