我有一个定义的资源类型,如果文件不存在则将一行附加到文件,如下所示:
define appendLineToFile($file, $line, $user) {
exec { "echo \"\\n$line\" >> \"$file\"":
path => '/bin',
unless => "grep -Fx \"$line\" \"$file\"",
user => $user,
}
}
它在大多数情况下都能很好地工作,但在下面这样的情况下则不行,在这种情况下,双引号必须转义两次(这读起来非常令人困惑):
appendLineToFile { 'Add http_proxy & https_proxy to sudoers':
file => '/etc/sudoers',
line => "Defaults env_keep += \\\"http_proxy https_proxy\\\"",
user => root,
}
有没有办法改变定义的资源类型,使其不需要转义?例如
line => "Defaults env_keep += \"http_proxy https_proxy\"",
答案1
两件事情:
奥杰阿斯
Puppet 可以很好地与名为奥杰阿斯:
Augeas 是一款很棒的工具,它将配置文件(实际上可以是任何东西,但主要是配置文件)视为值树。然后,您可以根据需要修改树,并将文件写回。
对于 Augeas 能够理解的文件,可以非常轻松地进行编程更改,而不必担心注释、空格、解析或任何其他棘手的细节。此外,Augeas支持 sudoers 文件格式。
Sudoers 包括
作为须藤从版本 1.7.2 开始,它支持一个includedir
指令,允许您指定一个目录来扩展 sudoers。该目录中的文件必须包含有效 sudoers 代码片段,sudo 将读取和使用它们,就像它们包含在原始文件中一样。我在 Puppet 中使用了一个自定义资源:
define sudo-include( content ) {
file { "/etc/sudoers.d/$name":
content => $content,
mode => 0440,
user => root,
group => root,
}
}
[...]
sudo-include { "moreusers":
content => "\
joe ALL=(ALL) ALL
mike ALL=(ALL) NOPASSWD:ALL
"
}
当您使用该sudo-include
资源时,它会自动在正确的位置以正确的权限创建文件,您需要做的就是为其命名并赋予内容。
答案2
Handyman5建议使用奥杰阿斯。下面是如何实现此目的的示例:
如果您希望使用 将两个条目放在一行上+=
,您可以按以下方式使用 Augeas:
augeas { "Add http_proxy & https_proxy to sudoers":
context => "/files/etc/sudoers",
# Only if no node exists for http_proxy
onlyif => "match Defaults/env_keep/var[. = 'http_proxy'] size==0",
changes => [
# Create a new Defaults line for the two variables
"ins Defaults after Defaults[last()]",
# Make this Defaults line a += type
"clear Defaults[last()]/env_keep/append",
# assign values to the two variables
"set Defaults[last()]/env_keep/var[1] http_proxy",
"set Defaults[last()]/env_keep/var[2] https_proxy",
],
}
但是,您可能希望避免关联这两个变量,这样即使已经设置了一个变量,它仍会起作用。在这种情况下,我会将问题一分为二,仅为 http_proxy 创建一个新的 Defaults 节点,并将其(带有依赖项)重用于 https_proxy。
答案3
除非您使用的是 Debian Squeeze(它使用 dash 而不是 bash 作为默认 shell),否则您可以在参数上使用单引号echo
,并使用-e
,这会启用有限的转义字符。
另请参阅通用模块至少执行两次你正在做的事情。