Reputation: 55199
I'd like to create a Chef library that:
That library is meant to interface with an external system and retrieve some inputs from there. I need to access the node attributes to allow the user to override the inputs received from the external system:
inputs = MyLib.get_inputs
This is inspired by those docs.
class Chef::Recipe::MyLib
def self.get_inputs
override_inputs = node.fetch(:mylib, Hash.new).fetch(:override_inputs, nil)
unless override_inputs.nil?
return override_inputs
end
# Do stuff and return inputs (no problem here)
# ...
end
end
Right now I'm getting:
undefined local variable or method `node' for Chef::Recipe::Scalr:Class
Upvotes: 15
Views: 10949
Reputation: 2153
I think there is a scoping issue here as the Node's scope is under Chef::Recipe. So try omitting MyLib in the definition and see if it works. I have a library defined this way that works:
class Chef
class Recipe
def my_library_method
#access node stuff here should be fine
end
end
end
Upvotes: 4
Reputation: 26997
You don't have access to the node object in a library unless you pass it into the initializer:
class MyHelper
def self.get_inputs_for(node)
# Your code will work fine
end
end
Then you call it with:
inputs = MyHelper.get_inputs_for(node)
Alternative, you can to create a module and mix it into the Chef Recipe DSL:
module MyHelper
def get_inputs
# Same code, but you'll get "node" since this is a mixin
end
end
Chef::Recipe.send(:include, MyHelper)
Then you have access to the get_inputs
method right in a recipe:
inputs = get_inputs
Notice this is an instance method versus a class method.
In short, libraries don't have access to the node
object unless given as a parameter. Modules will, if they are mixed into the Recipe DSL. Additionally, the node
object is actually an instance variable, so it's not available at the class level (i.e. self.
).
Upvotes: 19