Я создал шаблон для настройки содержимого файла / 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) %>
Но марионетка отображает ошибку на клиенте:
Could not retrieve catalog from remote server: wrong header line format
Конечно, я мог бы использовать то, что марионетка предоставляет для файла хостов правил, но что-то вроде:
# 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
Вот мой код для создания строки hosts:
# host entry with multiple aliases
host { 'dashboard':
ip => $network_interfaces
host_aliases => [ 'nagios', 'munin' ],
}
Но марионетка выдает ошибку:
Parameter ip failed: Invalid IP address "192.168.10.10172.23.10.10"
Очевидно, что массив ip, возвращаемый фактом, не рассматривается марионеткой как массив, а как обычная строка.
Может ли факт вернуть массив вместо строки в качестве объединенных элементов массива?
Большое спасибо!
У вас есть синтаксическая ошибка:
<%= 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 %>
Итак, согласно 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-адрес управления в этом файле.
Спасибо за вашу помощь, надеюсь, что это может помочь кому-то другому :)