I'm attempting to write a library for a chef cookbook that simplifies some common searches.
For example, I'd like to be able to do something like this in cookbook/libraries/library.rb
and then use it from a recipe in the same cookbook:
module Example
def self.search_attribute(attribute_name)
return search(:nodes, node[attribute_name])
end
end
The problem is that, inside a Chef library file neither the node
object or search
function are available.
Search seems to be possible by using Chef::Search::Query.new().search(...)
, but I can't find anything that works to access node
. The resulting error from this is:
undefined local variable or method `node' for Example:Module
Using Chef 10.16.4.
A node is any machine—physical, virtual, cloud, network device, etc. —that is under management by Chef. A physical node is typically a server or a virtual machine, but it can be any active device attached to a network that is capable of sending, receiving, and forwarding information over a communications channel.
You can assign the cookbook directly to a node by adding it to the node's run list. You can add a cookbook to the role and add the role to the node's run list. You can add the role to the run list of another role and add that other role to the node's run list.
Libraries in Chef provides a place to encapsulate compiled logic so that the cookbook recipes remain neat and clean.
What you can do is to include the module in your recipe. That way, your module functions get access to the methods of the recipe, including node
.
I normally do this for my library modules:
# my_cookbook/libraries/helpers.rb
module MyCookbook
module Helpers
def foo
node["foo"]
end
end
end
Then, in the recipe, I include the module into the current instance of a recipe:
# my_cookbook/recipes/default.rb
extend MyCookbook::Helpers
That way, only the current recipe gets the module included, not all of them in the whole chef run (you thus avoid name clashes).
Alternatively, you could pass the current node as a parameter to the function. That way, you don't need to include the module (which has the upside of keeping the module namespaces) but has the downside of a more convoluted method call.
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