使用 Puppet 仅管理配置文件的一部分(多行 file_line)

使用 Puppet 仅管理配置文件的一部分(多行 file_line)

有一个配置文件,例如/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'),
}

相关内容