B3nny
B3nny

Reputation: 13

In Puppet, how to use defined node variables in an if clause

In a puppet class how should I test if a variable has been set in a node? I use a VM name (like server1) and a domain name (like example.org) where users can reach the page. "example.org" won't be conveyed via a fact, so I need to pass it via a class parameter. I came up with this way to define the variable in a node block and use it in my test class for my settings.

node "VM1" {
  class { 'test':
    domainname => "example.org",
  }

[...]

class test ($domainname) {
  ini_setting {
    'set_property':
      ensure  => present,
      path    => '/tmp/test.ini',
      section => 'main',
      setting => 'url',
      value   => "https://$domainname";
  }

[...]

But now I want to add a condition that if $domainname isn't set then the $hostname fact should be used in its place.

ini_setting {
    'set_property':
    ensure  => present,
    path    => '/tmp/test.ini',
    section => 'main',
    setting => 'url',
    if $domainname !~ $hostname {
      value   => "https://$domainname";
    } else {
      value   => "https://$hostname";
    }

But now I get an error like this every time:

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Syntax error at 'domainname'

What should I do instead?

Upvotes: 1

Views: 4422

Answers (1)

John Bollinger
John Bollinger

Reputation: 180201

The error message is explaining to you that if statements cannot appear inside resource declarations. There is, however, a different conditional form, called a "selector" that can appear inside resource declarations. It is Puppet's analog of the ternary ?: operator that appears in several languages.

Stylistically, though, it is usually better form to keep resource declarations as simple as possible. To that end, you should probably set a variable, conditionally, outside the resource declaration, and then use its value inside. Using your own conditional, that might look like this:

  if $domainname !~ $hostname {
    $url_value = "https://$domainname";
  } else {
    $url_value = "https://$hostname";
  }

  ini_setting {
    'set_property':
      ensure  => present,
      path    => '/tmp/test.ini',
      section => 'main',
      setting => 'url',
      value   => $url_value;
  }

Additionally, however, I note that your particular condition, repeated above, is highly suspect. In recent Puppet (version 4 and above), you should be using Puppet data types to both declare your class parameters and check them. In particular, if it is permissible to declare class test without providing a $domainname parameter, then you would declare that class like so:

# Using the Puppet v4+ type system
class test(
  Optional[String] $domainname = undef
) {
  # ...

, and would test whether a value was provided for $domainname like so:

  if $domainname =~ Undef {
    # ...
  }

You cannot use the type system in earlier Puppet, but there you can rely on undefined variables to expand to nothing when you interpolate them:

# Using the Puppet v3- behavior
class test(
  $domainname = undef
) {
  # ...

  if "$domainname" == "" {
    # ...
  }

  # ...
}

Upvotes: 1

Related Questions