如何在Puppet中跟踪定义资源实例化以生成NetworkManager配置
解决Puppet定义资源生成NetworkManager Dummy接口配置的IP递增问题
我来帮你搞定这个Puppet配置的需求,这里有两种实用的方案,你可以根据项目的实际情况来选:
方案一:用类收集IP + EPP模板生成配置(推荐)
这个方案的核心思路是:用一个主类统筹所有IP的收集,再通过模板循环生成带递增序号的ipaddressX行,逻辑清晰且易维护。
步骤1:定义主类和IP收集的定义资源
class site_dummy_interface ( # 可配置参数,方便复用 String $connection_id = 'dummydsr', String $interface_name = 'dummydsr', String $uuid = '50819d31-8967-4321-aa34-383f4a658789', # 建议用uuidgen生成新的唯一值 ) { # 收集所有site_dummy_interface::add_ip类型的资源,提取IP列表 $ip_list = resources('site_dummy_interface::add_ip').map |$resource| { $resource['ip'] } # 生成NetworkManager配置文件 file { '/etc/NetworkManager/system-connections/dummydsr.nmconnection': ensure => file, content => epp('site_dummy_interface/dummy_connection.epp', { connection_id => $connection_id, uuid => $uuid, interface_name => $interface_name, ip_addresses => $ip_list, }), mode => '0600', # NetworkManager要求配置文件必须是0600权限,否则不加载 notify => Service['NetworkManager'], } # 确保NetworkManager服务运行 service { 'NetworkManager': ensure => running, enable => true, } } # 定义资源:用于添加单个IP,同时做格式校验 define site_dummy_interface::add_ip(String $ip) { # 验证IP格式是否符合x.x.x.x/xx if $ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/ { fail("Invalid IP format for ${title}: ${ip} - must be in x.x.x.x/xx format") } # 这里不需要额外操作,仅作为IP的收集入口和格式校验器 }
步骤2:创建EPP模板(site_dummy_interface/dummy_connection.epp)
模板里用each_with_index循环IP列表,自动生成带递增序号的行:
[connection] id=<%= $connection_id %> uuid=<%= $uuid %> type=dummy interface-name=<%= $interface_name %> permissions= [ipv4] method=manual <% $ip_addresses.each_with_index |$ip, $index| { -%> ipaddress<%= $index + 1 %>=<%= $ip %> <% } -%> [ipv6] method=ignore
步骤3:使用方式
在你的manifest里调用定义资源添加IP,主类会自动收集并生成配置:
include site_dummy_interface # 添加第一个IP site_dummy_interface::add_ip { 'web_server_1': ip => '1.2.3.4/32', } # 添加第二个IP site_dummy_interface::add_ip { 'web_server_2': ip => '5.6.7.8/32', } # 添加第三个IP site_dummy_interface::add_ip { 'web_server_3': ip => '8.7.6.5/32', }
方案二:用concat模块逐行拼接配置
如果你不想用模板,可以借助puppetlabs-concat模块,把配置拆分成头部、IP行、尾部三个部分,逐行拼接。不过这个方案对IP序号的控制不如模板精准,适合对序号顺序要求不严格的场景(NetworkManager本身不要求ipaddressX的序号连续,只要key唯一即可)。
核心代码示例
class site_dummy_interface ( String $connection_id = 'dummydsr', String $interface_name = 'dummydsr', String $uuid = '50819d31-8967-4321-aa34-383f4a658789', ) { include concat # 初始化拼接目标文件 concat { '/etc/NetworkManager/system-connections/dummydsr.nmconnection': ensure => file, mode => '0600', notify => Service['NetworkManager'], } # 添加配置头部 concat::fragment { 'dummy_header': target => '/etc/NetworkManager/system-connections/dummydsr.nmconnection', content => @("HEADER"/L), [connection] id=${connection_id} uuid=${uuid} type=dummy interface-name=${interface_name} permissions= [ipv4] method=manual | HEADER order => '01', } # 添加配置尾部 concat::fragment { 'dummy_footer': target => '/etc/NetworkManager/system-connections/dummydsr.nmconnection', content => "[ipv6]\nmethod=ignore\n", order => '99', } service { 'NetworkManager': ensure => running, enable => true, } } # 定义资源:添加单个IP行 define site_dummy_interface::add_ip(String $ip) { if $ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/ { fail("Invalid IP format for ${title}: ${ip}") } # 用资源标题生成唯一的order值,保证IP行不会重叠 $order = sprintf('%02d', md5($title))[0,2] concat::fragment { "dummy_ip_${title}": target => '/etc/NetworkManager/system-connections/dummydsr.nmconnection', # 这里的序号可以用随机唯一值,若需要严格递增,建议优先选方案一 content => "ipaddress${order}=${ip}\n", order => "0${order}", } }
注意事项
- NetworkManager的配置文件权限必须设置为
0600,否则服务会忽略该配置。 - UUID建议用
uuidgen命令生成新的唯一值,不要固定使用示例中的值。 - 方案一的模板方式更适合需要严格递增序号的场景,逻辑更清晰,维护成本更低。
内容的提问来源于stack exchange,提问作者Eduardo Mayoral
相关产品推荐
相关产品推荐

