Puppet 木偶解析顺序解释

Puppet 木偶解析顺序解释,puppet,Puppet,我正在基于提供的包30-stig.rules文件构建auditd audit.rules文件 stig.rules文件位于/usr/share/doc/audit-/rules/30-stig.rules。但是,事先很难知道安装了哪个版本的auditd,因此我想使用exec资源将此文件复制到标准位置: exec { 'Copy stig.rules to /tmp/stig.rules': command => 'cp $(rpm -qf auditd | grep stig.rul

我正在基于提供的包30-stig.rules文件构建auditd audit.rules文件

stig.rules文件位于/usr/share/doc/audit-/rules/30-stig.rules。但是,事先很难知道安装了哪个版本的auditd,因此我想使用exec资源将此文件复制到标准位置:

exec { 'Copy stig.rules to /tmp/stig.rules':
  command  => 'cp $(rpm -qf auditd | grep stig.rules) /tmp/stig.rules',
  unless   => 'cmp /tmp/stig.rules $(rpm -qf auditd | grep stig.rules)',
}

file { '/etc/audit/audit.rules':
  ensure  => file,
  content => template('auditd/audit.rules.erb'),
}
模板(audit.rules.erb)包含:

scope.function_file(['/tmp/stig.rules'])
我最初遇到一个错误,模板无法定位/tmp/stig.rules。因此,我补充说:

Exec['Copy stig.rules to /tmp/stig.rules'] -> File['/etc/audit/audit.rules']

即使在这个显式排序之后,我也会得到相同的错误,即找不到/tmp/stig.rules。似乎在解析文件资源的过程中,甚至在它执行“exec”之前,就已经在进行一些预验证,应该在“exec”之后对其进行排序。有人能解释这种行为吗?

如评论中所述,您遇到的问题是Puppet函数在Puppet主机上执行

通常,这个问题可以通过创建一个返回auditd版本的函数来解决

在模块中创建一个类似以下内容的文件:

# lib/facter/auditd_version.rb

Facter.add(:auditd_version) do
  confine :osfamily => 'RedHat'
  setcode do
    Facter::Core::Execution.exec('rpm -q --queryformat "%{VERSION}\n" audit')
  end
end
然后,您可以使用以下方法引用清单中的文件路径:

$file_path = "/usr/share/doc/audit-${facts['auditd_version']}/rules/30-stig.rules"
或(遗产):

您可以通过以下方式在ERB模板中访问它:

/usr/share/doc/audit-<%= @auditd_version %>/rules/30-stig.rules
然后在模板中,您现在可以通过
@stig_rules
访问该内容

如果RPM偶尔会更改该文件的内容,那么您需要更新您的Puppet清单-如果是,那就不理想了

另一种方法是简单地返回自定义事实中的整个文件内容

# lib/facter/stig_rules.rb

Facter.add(:stig_rules) do
  confine :osfamily => 'RedHat'
  setcode do
    Facter::Core::Execution.exec("cat \
      /usr/share/doc/audit-#{Facter.value(:auditd_version)}/stig.rules")
  end
end

您的傀儡资源与您的预期行为不匹配,并且似乎与您的错误无关。我不希望您指定的关系能够解决此问题,而且它似乎没有这样做。好的,谢谢。你能解释一下为什么你觉得我的资源与我的预期行为不匹配吗?该文件是由文件资源引用的模板引用的。这就是为什么我觉得奇怪,它会在文件资源运行之前解析模板(因为exec还没有运行)。好的,所以这仍然与资源顺序无关,而是这一细微差别往往会让很多傀儡新手绊倒:“函数在傀儡主机上执行。它们不在傀儡代理上执行。因此它们只能访问傀儡主机上可用的命令和数据。”这更有意义。因此,在本例中,想要使用与部署在客户机上的审计包版本相关的最新“stig.rules”文件(可能与部署到Puppet master的版本不匹配)是不可能的?实际上我就是这么做的。我创建了自定义事实,它提供了客户端auditd版本。但是,当我试图将其内容插入模板时,我仍然必须使用ERB中的“文件”功能,正如您所说,该功能仍然在服务器端执行。对整个内容执行自定义事实可能会起作用。我之前创建了一个指向stig.rules文件的自定义事实。但是,这些信息都在客户端,正如您所指出的,ERB函数会尝试在服务器端定位同一个文件,这样就不会对所有发行版都起作用,或者如果客户端和服务器之间的审核版本不同。我想您可能会误解。我相信在这种情况下,大多数人都会允许Puppet管理stig.rules文件,方法是将RPM提供的任何内容复制到Puppet模块中,然后声明该文件资源及其内容。Puppet看到已经存在的文件(由RPM交付)具有预期的内容,因此什么也不做。如果您有不同操作系统的不同文件,那么您可以基于例如
$facts['osfamily']
执行条件逻辑。尽管如此,我认为获得一个自定义事实来简单地返回文件的全部内容也应该很好。
$stig_rules = template('mymodule/stig_rules.erb')
file { "/usr/share/doc/audit-${facts['auditd_version']}/rules/30-stig.rules":
  ensure  => file,
  content => $stig_rules,
}
# lib/facter/stig_rules.rb

Facter.add(:stig_rules) do
  confine :osfamily => 'RedHat'
  setcode do
    Facter::Core::Execution.exec("cat \
      /usr/share/doc/audit-#{Facter.value(:auditd_version)}/stig.rules")
  end
end