我设置了一个模板来设置 /etc/hosts 文件的内容。这是我的模板:
127.0.0.1 localhost.localdomain localhost
<%= scope.lookupvar('ipaddress') %> <%= scope.lookupvar('fqdn') %> <%= scope.lookupvar('hostname') %>
这是正确的,但我想在具有多个网络接口的节点上为两个 IP 地址提供主机名。然后我尝试了以下模板:
<%= scope.lookupvar('interfaces').each do |interface| %> <%= scope.lookupvar('ipaddress_'+interface) %>
但是 Puppet 在客户端显示错误:
Could not retrieve catalog from remote server: wrong header line format
当然,我可以使用 puppet 提供的内容来规则 hosts 文件,但是类似这样的操作:
# host entry with multiple aliases
host { 'dashboard':
ip => [$ipaddress_eth0, $ipaddress_eth1]
host_aliases => [ 'nagios', 'munin' ],
}
是不允许的(ip显然不能是一个数组,而且我无法确定节点是否有2个接口还是只有一个)。
感谢您的帮助!
然后我创建了这个事实,并导出到目标节点。它应该返回一个已使用的 IP 地址数组:
Facter.add('network_interfaces') do
result = []
setcode do
f = File.open('/etc/network/interfaces', 'r')
f.each_line{|line|
if line =~ /^.*address ((([0-9]{1,3})\.){3}([0-9]{1,3})).*$/i
result << $1
end
}
result
end
end
以下是 facter -p network_interfaces 的输出
192.168.10.10
172.23.10.10
这是我创建主机行的代码:
# host entry with multiple aliases
host { 'dashboard':
ip => $network_interfaces
host_aliases => [ 'nagios', 'munin' ],
}
但是 Puppet 失败并出现以下错误:
Parameter ip failed: Invalid IP address "192.168.10.10172.23.10.10"
显然,fact返回的ip数组并不被puppet当成数组,而是当成一个普通的字符串。
事实是否有可能返回一个数组而不是字符串作为数组的连接元素?
非常感谢!
答案1
您在以下位置有语法错误:
<%= scope.lookupvar('interfaces').each do |interface| %> <%= scope.lookupvar('ipaddress_'+interface) %>
- 当你开始迭代时使用
<%=
:它应该是<%
- 你没有关闭你的街区
改写如下:
<% scope.lookupvar('interfaces').each do |interface| %>
<%= scope.lookupvar('ipaddress_'+interface) %>
<% end %>
第二,interfaces
是一个String
代表您机器上所有可用接口的 。您需要将其转换String
为Enumerable
,在这种情况下,该#split
方法就派上用场了:
<% scope.lookupvar('interfaces').split(",").each do |interface| %>
<%= scope.lookupvar('ipaddress_'+interface) %>
<% end %>
答案2
好的,根据 man hosts,每个主机都应该有一行。
每个主机不应有超过一个 IP 地址。
我已经完成了以下操作:如果我可以在我的节点上找到生产接口,我会使用这个,否则,我会使用用于管理的默认接口。
我的事实是这样的:
Facter.add('ip_prod') do
require 'facter/util/ip'
confine :interface => "eth0,eth1,lo"
setcode do
ip = Facter::Util::IP.get_interface_value('eth1', 'ipaddress')
ip
end
end
仅当存在 eth0 和 eth1 作为物理接口时才会加载此选项。
作为主机模板;我使用这个:
<% if @ip_prod %>
<%= ip_prod %> <%= scope.lookupvar('fqdn') %> <%= scope.lookupvar('hostname') %>
<% else %>
<%= ip_admin %> <%= scope.lookupvar('fqdn') %> <%= scope.lookupvar('hostname') %>
<% end%>
如果存在相关事实,我会运行每个可能的网络接口并分配它,否则我会使用在此文件中分配管理 IP 的“默认”事实。
谢谢您的帮助,希望它能够帮助别人:)