0

I create configuration in Puppet for Nagios agent (NRPE). Now I'm trying to set different file source depending on existence of dirs.First I check if specific directory exists and then set specific file conntent. My current config files looks like:

class nagios_client::file_nagios-check-linux-stats {

        include nagios_client::check_location_lib-nagios

        file { '/usr/lib/nagios/plugins/check_linux_stats.pl':
        ensure  => file,
        owner   => root,
        group   => root,
        mode    => 755,
        content => template("nagios_client/check_linux_stats.pl.erb"),
        require => Exec["check_usr-lib_exists"],
        }
        file { '/usr/lib64/nagios/plugins/check_linux_stats.pl':
        ensure  => file,
        owner   => root,
        group   => root,
        mode    => 755,
        content => template("nagios_client/check_linux_stats.pl.erb"),
        require => Exec["check_usr-lib64_exists"],
        }
        file { '/usr/lib32/nagios/plugins/check_linux_stats.pl':
        ensure  => file,
        owner   => root,
        group   => root,
        mode    => 755,
        content => template("nagios_client/check_linux_stats.pl.erb"),
        require => Exec["check_usr-lib32_exists"],
        }
    }

This works fine, but I have a problem with this:

class nagios_client::file_nrpe-cfg {

    #    include nagios_client::check_location_lib-nagios

        file { '/etc/nagios/nrpe.cfg.def':
            path    => '/etc/nagios/nrpe.cfg',
            ensure  => file,
            owner   => root,
            group   => root,
            mode    => 644,
            content => template("nagios_client/nrpe-cfg.erb"),
            require => Exec["check_usr-lib_exists"],
        }

        file { '/etc/nagios/nrpe.cfg.32':
            path    => '/etc/nagios/nrpe.cfg',
            ensure  => file,
            owner   => root,
            group   => root,
            mode    => 644,
            content => template("nagios_client/nrpe-cfg-32.erb"),
            require => Exec["check_usr-lib32_exists"],
        }

        file { '/etc/nagios/nrpe.cfg.64':
            path    => '/etc/nagios/nrpe.cfg',
            ensure  => file,
            owner   => root,
            group   => root,
            mode    => 644,
            content => template("nagios_client/nrpe-cfg-64.erb"),
            require => Exec["check_usr-lib64_exists"],
        }
    }

It looks like require => Exec[...] is ignored.

My check definition:

class nagios_client::check_location_lib-nagios {

    exec { 'check_usr-lib_exists':
    command => '/bin/true',
        onlyif  => '/usr/bin/test -d /usr/lib/nagios/plugins',
    }
    exec { 'check_usr-lib32_exists':
        command => '/bin/true',
        onlyif  => '/usr/bin/test -d /usr/lib32/nagios/plugins',
        }
    exec { 'check_usr-lib64_exists':
        command => '/bin/true',
        onlyif  => '/usr/bin/test -d /usr/lib64/nagios/plugins',
    }
}

I'm using Puppet 3.8.7. How to do it in right way?

2 Answers2

1

This isn't how Puppet works. You can't use exec resources as conditional logic for other resources like this. Your require parameter is only indicating that the exec resources should be handled before the file resources, not that their "return value" should indicate whether to create the resource or not.

If you want to indicate whether those directories exist or not, you should create one or more custom facts that check for the presence of those directories. A single $nagios_plugin_dir fact would probably suffice that just returns the first directory out of the three that exists on the host, and then just use that in the path of your file resources:

file { "${nagios_plugin_dir}/check_linux_stats.pl":
  ensure  => file,
  owner   => root,
  group   => root,
  mode    => 755,
  content => template('nagios_client/check_linux_stats.pl.erb'),
}

You can then also just do this:

file { '/etc/nagios/nrpe.cfg':
  ensure  => file,
  owner   => root,
  group   => root,
  mode    => 644,
  content => template('nagios_client/nrpe-cfg.erb'),
}

And in your ERB template just use this fact to template in the same path, (I assume that's why you have three different templates in the first place?).

You're also on a really really old version of Puppet these days.

bodgit
  • 4,751
  • 16
  • 27
  • Are those directories created by a package that might not be installed yet on the host? That fact will be run prior to Puppet changing any state so if your class installs the package that creates those directories then none of them will exist when the fact runs the first time so you would reach the default condition. You're perhaps then better off utilising the various existing OS/architecture facts to construct the path programatically, i.e. Red Hat 64-bit (x86_64) uses /usr/lib64, Red Hat 32-bit (i386) uses /usr/lib, Debian uses ..., etc. Otherwise I would suggest creating another question. – bodgit Dec 04 '18 at 12:27
1

bodgit is correct in that this is best handled by a template that checks the Operating system you're on and doing it that way, or a custom fact.

BUT it is possible to run functions that check things on the agent side now! In the newest version of Puppet (Puppet 6+), functions can be deferred to run on the agent. So you could use a file_exists function, run it deferred and refer to that value in your code:

module Puppet::Parser::Functions
    newfunction(:file_exists, :type => :rvalue) do |args|
        file = File.expand_path(args[0])
        if File.exists?(file)
            return true
        else
            return false
        end
    end
end

Which you could then use in your code like this:

$lib64nagiosexists = Deferred(“file_exists”, ["/usr/lib64/nagios/plugins”])

Then put your code behind that flag

if $lib64nagiosexists {
    file { '/etc/nagios/nrpe.cfg.64':
        path    => '/etc/nagios/nrpe.cfg',
        ensure  => file,
        owner   => root,
        group   => root,
        mode    => 644,
        content => template("nagios_client/nrpe-cfg-64.erb"),
        require => Exec["check_usr-lib64_exists"],
    }
}  
Peter Souter
  • 651
  • 1
  • 4
  • 13