首页 > 解决方案 > 如何使用 node.attribute 检查节点属性是否存在?

问题描述

想检查食谱中是否声明了厨师属性,但它似乎没有按预期工作,谁能告诉我如何使用“node.attribute”正确地做到这一点?

这是一个场景,在执行 chef-client 时可能未声明某些属性,因为此参数是可选的,并且可能在 chef-client -j some.json 文件中作为外部传递

if node.attribute(node['some']['attr'])
   list = node['some']['attr']
else
   list = node['defalut_attr']
end  

标签: rubychef-infracookbook

解决方案


在 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不再存在。为了使这项工作:

  1. 您将不得不edit node删除此属性。
  2. 以模式运行 chef-client --override-runlist(并跳过节点保存)。

例子:

没有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

注意:虽然这将解决这个特殊要求,但总是跳过节点保存不是一个好主意。您可能需要重新考虑使用属性优先级来为您的用例工作。


推荐阅读