使用 puppet 管理多个文件权限

问题描述

如何从 cat 命令的文件名列表中设置文件权限?

例如,下面的命令返回 3 个文件名:

$ cat /tmp/test | grep file
/etc/systemd/file_1.log
/etc/systemd/file_2.log
/etc/systemd/file_3.log

如何使用 puppet 运行命令,获取文件名,然后循环这 3 个文件名并相应地设置权限?

解决方法

文件是资源,如果你想管理一个资源,你必须知道它在那里,所以动态创建的日志文件并不容易。如果您已经知道文件名,那么您可以使用类似的方法并将数组传递给文件资源。

file { ['/etc/systemd/file_1.log','/etc/systemd/file_1.log','/etc/systemd/file_1.log'] :
    ensure => 'file',mode   => '0644',owner  => 'root',group  => 'root',}

另一种方法可能是使用 exec

exec { 'chmod 644 /etc/systemd/file_*.log':
  path => ['/usr/bin','/usr/sbin',],}

但你真的需要像 onlyifunless 这样的东西,否则这将每 30 分钟执行一次,这打破了我们尝试应用 Puppet 代码的幂等规则,只有在需要时才会改变纠正。因此,您将需要一个命令行来测试权限并向 onlyif 返回一个布尔值。 此处有更多详细信息https://puppet.com/docs/puppet/5.5/types/exec.html

另一种方法(以及我这样做的方式)是通过外部事实公开该文件的内容,该事实将文件列表传递给 Puppet 以在目录编译中使用。外部事实可以是 bash 脚本,因此我会创建一个名为 /etc/facter/facts.d/logfiles.sh 的文件,显然我会使用 Puppet 部署它。

#!/usr/bin/env bash
logfiles=($(grep file /tmp/test))
echo "logfiles=${logfiles[*]}"

然后在我的 Puppet 代码中我会有这样的东西;

$logfiles.each |String $logfile| {
  file { $logfile :
    ensure => 'file',}
}

因此,当 Puppet 运行发生时,日志文件列表将通过事实返回给 Puppet,然后将列出的每个文件定义为具有正确权限的资源。

,

如何从 cat 命令的文件名列表中设置文件权限?

有两种主要选择,但我首先注意到您的示例是 grep 的输出,而不是 cat,并且该示例中的 cat 是多余的。尽管如此,这些细节并没有改变大局——基本上相同的方法适用于任何命令的数据输出。


编写一个 custom fact 来捕获文件名(截至每个目录请求的时间)并使用该信息创建适当的 {{1} } 资源。

自定义事实并不难,但完整的细节比 SO 答案更适合。假设你有一个事实 File,它的值是一个绝对文件名的数组,你可以像这样简洁地表达整个想要的 $facts['systemd_logs'] 资源组:

File

(或您想要的任何模式)。


使用 Exec 资源来运行适当的命令会更快(也更脏)

file { $facts['systemd_logs']:
    mode => '0644',}