首页 > 解决方案 > Puppet - 如何使用不同的文件源

问题描述

我在 Puppet 中为 Nagios 代理 (NRPE) 创建了一个配置。现在,我正在尝试根据目录的存在设置不同的文件源。首先,我检查是否存在特定目录,然后设置特定文件内容。我当前的配置文件如下所示:

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"],
        }
    }

这工作正常,但我有一个问题:

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"],
        }
    }

看起来require => Exec[...]被忽略了。

我的支票定义:

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',
    }
}

我正在使用 Puppet 3.8.7。如何以正确的方式做到这一点?

标签: puppetnagios

解决方案


您所拥有的问题是您正在使用require,它仅确保指定的资源(在本例中为 each exec)在资源之前执行file。您想要的行为更接近于notify关系(创建刷新事件),但是,file资源不关心刷新事件。您可以在此处阅读有关刷新关系的更多信息:https ://puppet.com/docs/puppet/latest/lang_relationships.html#refreshing-and-notification 。

我有两种可能的方法来解决这个问题。第一个是使用exec语句来管理文件,而不是file资源。这绝对不是最优的,因为您会丢失file资源中的所有参数(我绝对不推荐这种方法,但您可以)。

另一种方法是创建一个自定义的 ruby​​ 事实来检查文件是否存在。事实看起来像这样:

Facter.add('nagios_directories') do
  confine kernel: 'Linux'

  setcode do
    paths_to_check = [
      '/usr/lib/nagios/plugins',
      '/usr/lib32/nagios/plugins',
      '/usr/lib64/nagios/plugins',
    ]
    paths_to_check.select { |d| File.directory?(d) }
  end
end

这个事实将检查数组中列出的所有目录paths_to_check,并返回一个包含确实存在的目录的数组。如果没有目录存在,它将返回一个空数组。

一旦你建立了这个事实,你就可以像这样重写你的代码:

class nagios_client::file_nrpe-cfg {
  if (member($fact['nagios_directories'], '/usr/lib/nagios/plugins')) {
    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"),
    }
  }

  if (member($fact['nagios_directories'], '/usr/lib32/nagios/plugins')) {
    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"),
    }
  }

  if (member($fact['nagios_directories'], '/usr/lib64/nagios/plugins')) {
    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"),
    }
  }
}

以下是自定义事实的一些附加文档:https ://puppet.com/docs/facter/3.9/fact_overview.html 。

最后,如果您使用的是 Puppet 6(目前是最新版本),您可以编写自定义 Ruby 函数并使用新deferred类型。这种类型允许您在目录运行时在代理上执行函数(在此版本之前,所有 Puppet 函数在编译时在 Puppet Master 上执行),这意味着您可以使用函数来检查文件是否存在。我没有机会尝试此功能,但您可以在此处查看文档:https ://puppet.com/docs/puppet/6.0/integrating_secrets_and_retrieving_agent-side_data.html 。


推荐阅读