There are multiple ways to check for the existence of a nested attribute in chef, and I'm not sure which is correct/best, and if any will result in empty attributes being stored on the node:
node[:parent] and node[:parent][:child]
node.attribute?(:parent) and node[:parent].attribute?(:child))
node[:parent].nil? and node[:parent][:child].nil?
It'd be greatly preferred to be able to check for the parent and child at the same time, but I don't know if that's possible. I am using Chef 10, not Chef 11, though answers explaining either are welcome.
Node attribute object is HashMap. You can use ruby native API to lookup nested attributes.
Chef Node Object provides a number of helper methods like:
node.attribute?()
node[:foo].attribute?(:bar)
node[:foo].member?(:bar)
There is also a new method node.debug_value()
in chef 11 to help you debug node attributes which is also helpful:
node.debug_value(:foo, :bar)
Details can be found from the article Chef 11 In-Depth: Attributes Changes
The correct "modern" way to do this is to use the exist?()
helper:
if node.exist?('foo', 'bar', 'baz')
# do stuff with node['foo']['bar']['baz']
end
This supersedes the old chef-sugar deep_fetch
mechanism and has been built into chef-client for a very long time at this point.
There is also a read()
helper to get the value out, which will return nil if any intermediate key does not exist:
fizz = node.read('foo', 'bar', 'baz')
It is identical to the Hash#dig method which was later added to ruby which is also supported as an alias:
fizz = node.dig('foo', 'bar', 'baz')
The way I've solved this more recently has been to always set default values for attributes used in a cookbook where possible.
For example, cookbook/attributes/default.rb
would contain:
default[:parent][:child] = nil
And the in the recipe, any check for the attributes value can be reduced to:
node[:parent][:child].nil?
Of course, it's usually far more useful to have a usable default value and to not have to check at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With