有一个配置文件,例如/etc/network/interfaces。我只想使用 Puppet 管理该文件的特定部分。
例子:
# At the beginning at least is some dynamic content that can be different
# from machine to machine and changed by an admin manually
auto eth0
iface eth0 inet static
address 192.168.108.5
netmask 255.255.255.0
# BEGIN PUPPET WLAN0
allow-hotplug wlan0
iface wlan0 inet static
address 192.168.109.5
netmask 255.255.255.0
# END PUPPET WLAN0
# Potentially more stuff that I do not want to touch through Puppet
# But could be static if it makes it more easy. E.g. simply force sections to end of file.
stdlib file_line 资源非常接近我的需要。用于替换匹配项的正则表达式和内容。然而,不幸的是,没有办法使 file_line 匹配多行并替换为新内容。
替代方案 1:创建一个 bash 脚本:丑陋的 Exec 资源和临时文件。
替代方案 2:使用 Augeas:对于简单的搜索和替换来说似乎有点过分了。
除了 stdlib 之外,还有其他模块允许我在多行上进行正则表达式匹配和替换吗?
还有比兼顾临时 bash 脚本和 Exec 资源更好的手工解决方案吗?
答案1
您可以简单地使用单行匹配作为 a 的占位符多行值:
$wlan_address = [...]
$wlan_netmask = [...]
$wlan_string = "allow-hotplug wlan0
iface wlan0 inet static
address ${wlan_address}
netmask ${wlan_netmask}"
file_line { 'wlan0':
path => '/etc/network/interfaces',
line => $wlan_string,
match => '^# PUPPET WLAN0$',
}
答案2
管理文件的一部分是一种配置管理反模式,应尽可能避免这种模式。
您已经确定了可以执行此操作的各种工具。
- 奥吉亚斯
- 标准库/文件行
- 执行+sed
您也可以管理整个文件,并执行“onlyif”,这样文件就不会每次都被覆盖。
正如您所发现的, file_line 仅适用于单行的 init 样式配置文件。
最好的选择是使用 sed 插入对该文件执行 exec。
答案3
默认情况下,puppet 中已经安装了一个名为:puppetlabs-stdlib 的模块,并且在该模块中定义了一个名为 file_line 的类型,它可以实现这一点:) 这是我在 /manifests/node.pp 下的案例场景:
node elk.ershandc.org {
...
file_line { 'backup_authorized_key' :
ensure => 'present',
path => '/root/.ssh/authorized_keys',
line =>'ssh-rsaAAAAB3NzaC1yc2EAAAADAQABAAABAQC1ZCi/K0hlffi9ZUmveJ05l301RE6u/TzrCK+i54edzN5stR/tTjd28vFIup10HTYoZxbqBgRMrxVGDnfwtaSsCZH31g2/flZBxSZGzjySKeUqnf/YyGJP6my/IjA4xcKVcPDPx2FF/u1Sd07y7wnLizjAhtIOwq1daiCcRbXkIxfpobQt/RtJLAyDA1CwACr9NWmAezS0rnaYXRBQrmrkCBx91fMhKsarvxB3z4mTG8wVNwXvE9g2Hps6bRzff0hIXaIoVFYHwqmyIkN+4xCDGcjt3TjZp0zvTK20RR7DNOHxOGs8GBhcvitEkGY/JXgA4AJ26ncfXaspaUgEM/Rt root@devop-testbed'
}
...
}
答案4
如果你能保证其他文件内容是静态的,你可以将该文件制作成模板并保持静态部分不变。例子:
auto eth0
iface eth0 inet static
address 192.168.108.5
netmask 255.255.255.0
# BEGIN PUPPET WLAN0
allow-hotplug wlan0
iface wlan0 inet static
address <%= wlan0_address %>
netmask <%= wlan0_netmask %>
# END PUPPET WLAN0
# More stuff that I do not want to touch through Puppet
# Static content here
此示例假设您已在其他地方定义了$wlan0_address
变量$wlan0_netmask
。
然后您可以使用文件资源进行部署:
file{'interfaces':
ensure => file,
path => '/etc/network/interfaces',
content => template('/path/to/template'),
}