Linux

/etc/hosts 模板的 puppet 內容與 facter

  • April 19, 2022

我已經設置了一個模板來設置 /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 提供的內容來規則主機文件,但類似於:

# 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看成一個數組,而是一個正則字元串。

事實是否有可能返回一個數組而不是字元串作為數組的連接元素?

非常感謝!

好的,根據 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 的“預設”事實。

感謝您的幫助,希望它可以幫助別人:)

您在以下方面有語法錯誤:

<%= scope.lookupvar('interfaces').each do |interface| %> <%= scope.lookupvar('ipaddress_'+interface) %>
  1. <%=在開始迭代時使用:應該是<%
  2. 你沒有關閉你的街區

改寫如下:

<% scope.lookupvar('interfaces').each do |interface| %>
<%= scope.lookupvar('ipaddress_'+interface) %>
<% end %>

其次,代表您機器上所有可用的介面interfacesString您需要將其轉換StringEnumerable,在這種情況下,該#split方法會派上用場:

<% scope.lookupvar('interfaces').split(",").each do |interface| %>
<%= scope.lookupvar('ipaddress_'+interface) %>
<% end %>

引用自:https://serverfault.com/questions/426665