Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

chef 11: any way to turn attributes into a ruby hash?

I'm generating a config for my service in chef attributes. However, at some point, I need to turn the attribute mash into a simple ruby hash. This used to work fine in Chef 10:

node.myapp.config.to_hash

However, starting with Chef 11, this does not work. Only the top-level of the attribute is converted to a hash, with then nested values remaining immutable mash objects. Modifying them leads to errors like this:

Chef::Exceptions::ImmutableAttributeModification ------------------------------------------------ Node attributes are read-only when you do not specify which precedence level to set. To set an attribute use code like `node.default["key"] = "value"'

I've tried a bunch of ways to get around this issue which do not work:

node.myapp.config.dup.to_hash
JSON.parse(node.myapp.config.to_json)

The json parsing hack, which seems like it should work great, results in:

JSON::ParserError
unexpected token at '"#<Chef::Node::Attribute:0x000000020eee88>"'

Is there any actual reliable way, short of including a nested parsing function in each cookbook, to convert attributes to a simple, ordinary, good old ruby hash?

like image 779
Igor Serebryany Avatar asked Feb 06 '13 20:02

Igor Serebryany


1 Answers

after a resounding lack of answers both here and on the opscode chef mailing list, i ended up using the following hack:

class Chef
  class Node
   class ImmutableMash
      def to_hash
        h = {}
        self.each do |k,v|
          if v.respond_to?('to_hash')
            h[k] = v.to_hash
          else
            h[k] = v
          end
        end
        return h
      end
    end
  end
end

i put this into the libraries dir in my cookbook; now i can use attribute.to_hash in both chef 10 (which already worked properly and which is unaffected by this monkey-patch) and chef 11. i've also reported this as a bug to opscode:

if you don't want to have to monkey-patch your chef, speak up on this issue: http://tickets.opscode.com/browse/CHEF-3857

Update: monkey-patch ticket was marked closed by these PRs

like image 160
Igor Serebryany Avatar answered Oct 12 '22 23:10

Igor Serebryany