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 coo
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.
I just ran into this while trying to access the current environment in a library. I couldn't really figure out how to use modules to get access to the node and I didn't want to pass the node into each method call (or the instantiation call) so I did this (example code.. not the actual functionality):
# libraries/account.rb
class Account
@@env = "_default"
def self.env=(env)
@@env = env
end
def settings
Chef::EncryptedDataBagItem.load(@@env, "settings") || {}
end
end
# recipes/accounts.rb
Account.env = node.chef_environment
Account.new.settings
I don't know if using class variables is frowned upon, but it works in all my tests and it's nice and easy to use.