How to use library module in Cookbook recipes

Biswajit Das picture Biswajit Das · May 25, 2016 · Viewed 8.5k times · Source

In a cookbook I have a library(client_helper.rb). A module is defined inside it. Module name is Client_helper. Here is the module code.

module Client_helper
# This module contains helper methods

def network_zone
        Chef::Log.debug('network zone called...********')
        Chef::Log.debug("inside-::::"+self.class.to_s)
end    

end
Chef::Recipe.send(:include, Client_helper)

Now I have default recipe. Where I am calling the method network_zone from direct recipe it is working.

But when I am calling the method network_zone inside ruby_block(eg. Client_helper.network_zone) it is not working.

Please find the recipe code.

# Cookbook: client
# Recipe: default

Chef::Resource.send(:include, Sap_splunk_client_helper)   


  host_network_zone = network_zone # This is working

Log.info("inside-::::"+self.class.to_s)

ruby_block 'parse auto generated templates' do
  block do
    host_network_zone = Client_helper.network_zone #This is not working
    Log.info("inside ruby block-::::"+self.class.to_s)
end
end

My cookbook directory structure-

enter image description here

Please help me.

Answer

lamont picture lamont · May 27, 2016

Its unnecessary to inject the method into any provider class, and its better to inject it only into the classes that you require:

Chef::Recipe.send(:include, Client_helper)
Chef::Resource::RubyBlock.send(:include, Client_helper)

By injecting methods you are monkeypatching those classes, and that comes with all the risks associated with 'monkeypatching' (a google search will probably be educational).

If you inject your #network_zone helper into the Chef::Provider and Chef::Resource base classes that will overwrite any similarly named method in any core resource or provider, or any cookbook resource or provider. If anyone else uses a method of that name, you'll break their code.