Назад | Перейти на главную страницу

марионеточное содержимое шаблона / etc / hosts с фактером

Я создал шаблон для настройки содержимого файла / 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) %>
  1. Ты используешь <%= когда вы начинаете повторять: это должно быть <%
  2. Вы не закрываете свой блок

Вместо этого перепишите так:

<% 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-адрес управления в этом файле.

Спасибо за вашу помощь, надеюсь, что это может помочь кому-то другому :)