【问题标题】:Creating nested Puppet fact (Ruby) by iterating over gem query output通过迭代 gem 查询输出来创建嵌套的 Puppet fact (Ruby)
【发布时间】:2019-01-04 07:24:35
【问题描述】:

我有工作 Ruby 代码来查询 DNS 详细信息并创建 Puppet 自定义事实(puppet 5,Facter 3.11.6)但是我正在尝试修改它以从查询获得的键/值对创建嵌套事实。

使用键名设置单个事实的代码是:

  require 'resolv'
  Resolv::DNS::Config.default_config_hash.each do | key, value |
    if !value.nil?
      Facter.add("dns_#{key}") do
        if value.is_a?(Array)
          setcode { value.join(',') }
        else
          setcode { value }
        end
      end
    end
  end

这样创造了个人事实:

dns_nameserver => 192.168.1.1,192.168.1.2
dns_ndots => 1
dns_search => test.domain

到目前为止,我在“DNS”的父事实下创建嵌套事实的失败尝试是:

require 'resolv'
Facter.add("dns") do
  value ={}
  Resolv::DNS::Config.default_config_hash.each do | key, result |
    if !result.nil?
      if result.is_a?(Array)
        setcode { value['#{key}'] = result.join(',') }
      else
        setcode { value['#{key}'] = result }
      end
    end
  end
end

这给出了一个有限的结果:

dns => 1

我尝试过的其他代码似乎将数组输出放入字符串中,并且多个 IP 在方括号内被引用超过 2 行,而不是按照页面顶部的第一个代码块输出。

我试图实现的事实结构(通过修改页面顶部代码)是:

dns => {
  nameserver => 192.168.1.1,192.168.1.2,
  ndots => 1,
  search => test.domain,
}

提前感谢您的帮助。

【问题讨论】:

    标签: ruby puppet fact facter


    【解决方案1】:

    我终于在一位发布者的帮助下得到了这个,他在这里放了一些很棒的代码线索,但不幸的是不久之后就将其删除了。这是有效的代码:

    require 'resolv'
    Facter.add(:networking_dns) do
      setcode do
        Resolv::DNS::Config.default_config_hash.each_with_object({}) do | (key, value), sub|
          if !value.nil?
            sub[key] = value
            sub
          end
        end
      end
    end
    

    现在提供一些解释性说明(请随时纠正我或对此提供任何优化):

    # the resolv gem is required
    require 'resolv'
    # create the parent fact (has no value of its own)
    Facter.add(:networking_dns) do
    # start building instructions in the fact
      setcode do
    # use the resolv gem to lookup values in /etc/resolv.conf and add .each to process all key/value pairs returned
    # also add _with_object({}) and sub in the variables to set a blank value for sub.  Saves doing it separately.  Sub can be any name but denotes the declaration for the nested facts
        Resolv::DNS::Config.default_config_hash.each_with_object({}) do | (key, value), sub|
    # create facts only when the value is not nil
          if !value.nil?
            sub[key] = value
            sub
    # using a closing blank entry for a nested fact is critical or they won't create!  Place this outside of the case statement to prevent blank values
          end
        end
      end
    end
    # use the appropriate number of ends and indent for readability
    

    感谢在删除之前在此处发布指导的人。如果您再次发帖,我想为您投票。

    欢迎任何有关优化解决方案的技巧,因为我仍在掌握 Ruby(在这上面花了几个小时!)

    【讨论】:

    • 你应该将sub的返回值移到case之外,否则如果最终对象是NilClass,这个事实将返回nil
    • 谢谢马特,你能不能提供一个代码块,因为我不太确定你想把它移到哪里。顺便说一句,这个事实适用于 Windows 和 Linux,这太棒了。
    • 对于case 语句,它需要在end 之后。
    • 谢谢。我也很好奇这个事实是否可以附加到内置的网络事实中,显示为:networking { dns => { nameserver => 192.168.1.1,192.168.1.2, ndots => 1, search => test. domain, } 不确定是否可以将内置事实附加到...
    • 您需要核心 Facter 键的可写属性。我怀疑Facter.value 是可写的,但我最近没有看源码。它也从 C++14 绑定到 Ruby,所以也有拦截的可能性。
    猜你喜欢
    • 2022-09-27
    • 2014-06-05
    • 2020-11-12
    • 1970-01-01
    • 2014-06-10
    • 2017-03-29
    • 1970-01-01
    • 2018-12-03
    • 2021-11-29
    相关资源
    最近更新 更多