Puppet:检查变量集

Chr*_*is 6 puppet

编辑:我想出了我认为最好的方法来解决这个问题。感谢人们回答了我的问题 - 它一路走来。我将发布我的解决方案,以便其他人可以在需要时找到它。

原问题:

我想使用 puppet 来自动配置我们的一些 NFS 文件系统。但是,我希望清单在这样做之前确保它在正确的网络上有一个 IP。

Puppet 通过interfacesipaddress_***事实帮助提供了有关机器分配的 IP 的事实。问题是我需要检查所有接口(我宁愿不对它们的连接方式做出假设)。

问题 1:Puppet 可以遍历事实列表吗?例如:

for $if in $interfaces {
     //do something
}
Run Code Online (Sandbox Code Playgroud)

问题 2:如果 Puppet 可以做到这一点,是否有一种方法可以将字符串评估为变量。interfaces提供了一种非常好的方式来了解有多少ipaddress_***network_***变量,但即使我可以遍历它的值,我也需要执行以下操作:

for $if in $interfaces {
    $net_var = eval("network_${if}")
    if $net_var = /^192\.168\.2\.0$/ {
        //do something
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?我是不是完全错了(对 Puppet 来说有点新)?

我最终做了什么:

Puppet 允许您为模块定义自定义解析器函数。这些自定义函数只是 ruby​​,因此您可以有效地在其中执行任何您想做的事情,包括循环。

你把它们放在<module_dir>/lib/puppet/parser/functions/. 为了做我想做的事,我创建<module_dir>/lib/puppet/parser/functions/has_network.rb了以下内容:

#has_network.rb
require 'ipaddr'

module Puppet::Parser::Functions
    newfunction(:has_network, :type => :rvalue) do |args|

        retcon = ""

        if not /^[0-9]{1,3}(\.[0-9]{1,3}){3}\/[0-2]?[0-9]$/.match(args[0]) then
            raise Puppet::ParseError, "Network provided was not valid. Provide 192.168.0.0/16 format" 
        else
            requested_network = IPAddr.new(args[0])

            interfaces_fact =  lookupvar('interfaces')
            interfaces = interfaces_fact.split(",")
            interfaces.each do |interface|
                ip = IPAddr.new(lookupvar("ipaddress_#{interface}"))
                if requested_network.include?(ip)
                    retcon = "true"
                end
            end
        end

        retcon
    end
end
Run Code Online (Sandbox Code Playgroud)

这添加了一个新函数,我可以在我的清单中使用它,称为 has_network。如果机器的 IP 地址之一在提供给函数的网络上,则返回 true。现在我可以执行以下操作:

if has_network("192.168.1.0/24"){
    //do something
}
Run Code Online (Sandbox Code Playgroud)

关于自定义函数的一些注意事项

  • 这些在主服务器上运行。请注意lookupvar对 Facter 事实进行操作的使用。您不能使用其中之一在客户端上创建文件。
  • 更改功能时,必须重新启动puppetmaster。如果您不这样做,puppetmaster 将永远不会加载更新的函数,您会非常困惑。

qua*_*nta 6

正如@Zoredache 提到的,Puppet 中没有循环。但是您可以通过使用定义来解决这个问题,如下所示:

define show_ip {
    $inf = "ipaddress_${name}"
    $ip = inline_template('<%= scope.lookupvar(inf) %>')

    if $ip =~ /192\.168\.3.*/ {
        notify {"Found IP $ip": }
    }
}

$ifs = split($interfaces, ',')

show_ip { $ifs: }
Run Code Online (Sandbox Code Playgroud)

下面是直接调用时的输出:

# puppet manifests/defines/net.pp 
warning: Implicit invocation of 'puppet apply' by passing files (or flags) directly
to 'puppet' is deprecated, and will be removed in the 2.8 series.  Please
invoke 'puppet apply' directly in the future.

notice: Found IP 192.168.3.118
notice: /Stage[main]//Show_ip[eth1]/Notify[Found IP 192.168.3.118]/message: defined 'message' as 'Found IP 192.168.3.118'
notice: Finished catalog run in 0.07 seconds
Run Code Online (Sandbox Code Playgroud)

来源:https : //blog.kumina.nl/tag/puppet-tips-and-tricks/