/usr/lib/ruby/vendor_ruby/cheffish/base_resource.rb is in ruby-cheffish 4.0.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | require 'chef/resource'
require 'cheffish/base_properties'
module Cheffish
class BaseResource < Chef::Resource
include Cheffish::BaseProperties
declare_action_class.class_eval do
def rest
@rest ||= Cheffish.chef_server_api(new_resource.chef_server)
end
def current_resource_exists?
Array(current_resource.action) != [ :delete ]
end
def not_found_resource
resource = resource_class.new(new_resource.name, run_context)
resource.action :delete
resource
end
def normalize_for_put(json)
data_handler.normalize_for_put(json, fake_entry)
end
def normalize_for_post(json)
data_handler.normalize_for_post(json, fake_entry)
end
def new_json
@new_json ||= begin
if new_resource.complete
result = normalize(resource_to_json(new_resource))
else
# If the resource is incomplete, we use the current json to fill any holes
result = current_json.merge(resource_to_json(new_resource))
end
augment_new_json(result)
end
end
# Meant to be overridden
def augment_new_json(json)
json
end
def current_json
@current_json ||= begin
result = normalize(resource_to_json(current_resource))
result = augment_current_json(result)
result
end
end
# Meant to be overridden
def augment_current_json(json)
json
end
def resource_to_json(resource)
json = resource.raw_json || {}
keys.each do |json_key, resource_key|
value = resource.send(resource_key)
# This takes care of Chef ImmutableMash and ImmutableArray
value = value.to_hash if value.is_a?(Hash)
value = value.to_a if value.is_a?(Array)
json[json_key] = value if value
end
json
end
def json_to_resource(json)
resource = resource_class.new(new_resource.name, run_context)
keys.each do |json_key, resource_key|
resource.send(resource_key, json.delete(json_key))
end
# Set the leftover to raw_json
resource.raw_json json
resource
end
def normalize(json)
data_handler.normalize(json, fake_entry)
end
def json_differences(old_json, new_json, print_values=true, name = '', result = nil)
result ||= []
json_differences_internal(old_json, new_json, print_values, name, result)
result
end
def json_differences_internal(old_json, new_json, print_values, name, result)
if old_json.kind_of?(Hash) && new_json.kind_of?(Hash)
removed_keys = old_json.keys.inject({}) { |hash, key| hash[key] = true; hash }
new_json.each_pair do |new_key, new_value|
if old_json.has_key?(new_key)
removed_keys.delete(new_key)
if new_value != old_json[new_key]
json_differences_internal(old_json[new_key], new_value, print_values, name == '' ? new_key : "#{name}.#{new_key}", result)
end
else
if print_values
result << " add #{name == '' ? new_key : "#{name}.#{new_key}"} = #{new_value.inspect}"
else
result << " add #{name == '' ? new_key : "#{name}.#{new_key}"}"
end
end
end
removed_keys.keys.each do |removed_key|
result << " remove #{name == '' ? removed_key : "#{name}.#{removed_key}"}"
end
else
old_json = old_json.to_s if old_json.kind_of?(Symbol)
new_json = new_json.to_s if new_json.kind_of?(Symbol)
if old_json != new_json
if print_values
result << " update #{name} from #{old_json.inspect} to #{new_json.inspect}"
else
result << " update #{name}"
end
end
end
end
def apply_modifiers(modifiers, json)
return json if !modifiers || modifiers.size == 0
# If the attributes have nothing, set them to {} so we have something to add to
if json
json = Marshal.load(Marshal.dump(json)) # Deep copy
else
json = {}
end
modifiers.each do |path, value|
path = [path] if !path.kind_of?(Array)
path = path.map { |path_part| path_part.to_s }
parent = 0.upto(path.size-2).inject(json) do |hash, index|
if hash.nil?
nil
elsif !hash.is_a?(Hash)
raise "Attempt to set #{path} to #{value} when #{path[0..index-1]} is not a hash"
else
hash[path[index]]
end
end
if !parent.nil? && !parent.is_a?(Hash)
raise "Attempt to set #{path} to #{value} when #{path[0..-2]} is not a hash"
end
existing_value = parent ? parent[path[-1]] : nil
if value.is_a?(Proc)
value = value.call(existing_value)
end
if value == :delete
parent.delete(path[-1]) if parent
else
# Create parent if necessary, overwriting values
parent = path[0..-2].inject(json) do |hash, path_part|
hash[path_part] = {} if !hash[path_part]
hash[path_part]
end
if path.size > 0
parent[path[-1]] = value
else
json = value
end
end
end
json
end
def apply_run_list_modifiers(add_to_run_list, delete_from_run_list, run_list)
return run_list if (!add_to_run_list || add_to_run_list.size == 0) && (!delete_from_run_list || !delete_from_run_list.size)
delete_from_run_list ||= []
add_to_run_list ||= []
run_list = Chef::RunList.new(*run_list)
result = []
add_to_run_list_index = 0
run_list_index = 0
while run_list_index < run_list.run_list_items.size do
# See if the desired run list has this item
found_desired = add_to_run_list.index { |item| same_run_list_item(item, run_list[run_list_index]) }
if found_desired
# If so, copy all items up to that desired run list (to preserve order).
# If a run list item is out of order (run_list = X, B, Y, A, Z and desired = A, B)
# then this will give us X, A, B. When A is found later, nothing will be copied
# because found_desired will be less than add_to_run_list_index. The result will
# be X, A, B, Y, Z.
if found_desired >= add_to_run_list_index
result += add_to_run_list[add_to_run_list_index..found_desired].map { |item| item.to_s }
add_to_run_list_index = found_desired+1
end
else
# If not, just copy it in
unless delete_from_run_list.index { |item| same_run_list_item(item, run_list[run_list_index]) }
result << run_list[run_list_index].to_s
end
end
run_list_index += 1
end
# Copy any remaining desired items at the end
result += add_to_run_list[add_to_run_list_index..-1].map { |item| item.to_s }
result
end
def same_run_list_item(a, b)
a_name = a.name
b_name = b.name
# Handle "a::default" being the same as "a"
if a.type == :recipe && a_name =~ /(.+)::default$/
a_name = $1
elsif b.type == :recipe && b_name =~ /(.+)::default$/
b_name = $1
end
a_name == b_name && a.type == b.type # We want to replace things with same name and different version
end
private
# Needed to be able to use DataHandler classes
def fake_entry
FakeEntry.new("#{new_resource.send(keys.values.first)}.json")
end
class FakeEntry
def initialize(name, parent = nil)
@name = name
@parent = parent
@org = nil
end
attr_reader :name
attr_reader :parent
attr_reader :org
end
end
end
end
|