想要检查配方中是否声明了chef属性,但它似乎没有如预期的那样工作,有人能告诉我如何用";node.attribute">
这是一个场景在执行chef-client时,可能没有声明一些属性,因为该参数是可选的,并且可能作为外部传入chef-client-jsome.json文件
if node.attribute(node['some']['attr'])
list = node['some']['attr']
else
list = node['defalut_attr']
end
在Ruby中,我们可以使用nil
来表示空的东西。出于您的目的,您可以使用此功能最初将节点属性保持为空。然后在需要时从外部提供一个值。
示例:
在您的attributes/default.rb
:中
default['some']['attr'] = nil
default['default_attr'] = 'one, two, three, four'
在some.json
:中
{
"some": {
"attr": "one, two"
}
}
然后在您的recipes/default.rb
:中
list = nil
if node['some']['attr'].nil?
list = node['default_attr']
else
list = node['some']['attr']
end
puts "***** list: #{list}"
现在,如果通过-j some.json
设置值,该值将用于list
。否则,list
将被设置为node['default_attr']
。
更新:
第一次提供-j some.json
时,节点属性已保存。所以在下一次运行中,['some']['attr']
不再是nil
。实现这一点:
- 您必须
edit node
并删除此属性 - 在
--override-runlist
模式下运行chef客户端(并跳过节点保存(
示例:
无some.json
:
~$ chef-client -o recipe[my_cookbook]
Compiling Cookbooks...
***** list: one, two, three, four
带some.json
:
~$ chef-client -o recipe[my_cookbook] -j ./node.json
Compiling Cookbooks...
***** list: one, two
注意:虽然这将解决这一特定要求,但跳过节点保存始终不是一个好主意。您可能需要重新考虑如何使用属性优先级来处理您的用例。
node.exist?()
助手就是为它设计的:
list = if node.exist?("some", "attr")
node['some']['attr']
else
node['default_attr']
end
还有其他让生活更轻松的帮手:
# this avoids "trainwrecking" with NoMethodError on NilClass if node["some"] does not exist
# and will return nil if the attribute is not found.
#
list = node.read("some", "attr")
# there is also an alias to #dig which was created after Hash#dig was added to ruby:
#
list = node.dig("some", "attr")
# this raises a consistent Chef::AttributeNotFound error if the attribute does not exist:
#
list = node.read!("some", "attr")
如果你真的需要,你可以在子Mashes上使用所有这些方法(默认/覆盖等(:
# this only checks the default level:
node.default.exist?("some", "attr")
你可能需要考虑你的代码是否对它的使用方式了解得太多太深,尽管如果你在这样的单个优先级中四处寻找。除了调试目的之外,我强烈反对使用那个API。