大厨11:任何方式将属性转换为ruby哈希?

我正在使用chef属性为我的服务生成配置。 但是,在某些时候,我需要将属性mash转换为简单的ruby哈希。 这曾经在Chef 10中正常工作:

node.myapp.config.to_hash 

但是,从Chef 11开始,这不起作用。 只有属性的顶级转换为散列,然后嵌套值保持不可变的mash对象。 修改它们会导致这样的错误:

Chef :: Exceptions :: ImmutableAttributeModification ——————————————- —–如果未指定要设置的优先级,则节点属性是只读的。 要设置属性,请使用类似`node.default [“key”] =“value”’的代码

我已经尝试了很多方法来解决这个问题,但这些方法都不起作用:

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

json解析hack,看起来应该很好用,导致:

 JSON::ParserError unexpected token at '"#"' 

有没有任何实际可靠的方法,在每个cookbook中包含嵌套解析函数,将属性转换为简单,普通,好的旧ruby哈希?

在这里以及在opscode chef邮件列表上大声缺乏答案之后,我最终使用了以下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 

我把它放在我的食谱中的图书馆里; 现在我可以在chef 10中使用attribute.to_hash(已经正常工作且不受此猴子补丁影响)和厨师11.我还将此报告为opscode的错误:

如果你不想对你的厨师进行修补,请在这个问题上大声说出来: http : //tickets.opscode.com/browse/CHEF-3857

我遇到了同样的问题,经过多次黑客攻击后想出了这个问题:

 json_string = node[:attr_tree].inspect.gsub(/\=\>/,':') my_hash = JSON.parse(json_string, {:symbolize_names => true}) 

inspect执行其他方法所缺少的深度解析,最后得到一个我可以根据需要修改和传递的哈希值。

我希望我对聚会不太晚,但是将节点对象与空哈希合并为我做了:

 chef (12.6.0)> {}.merge(node).class => Hash 

上面的答案有点不必要。 你可以这样做:

 json = node[:whatever][:whatever].to_hash.to_json JSON.parse(json)