Class: Chef::ChefFS::DataHandler::DataHandlerBase

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/chef_fs/data_handler/data_handler_base.rb

Overview

The base class for all *DataHandlers.

DataHandlers’ job is to know the innards of Chef objects and manipulate JSON for them, adding defaults and formatting them.

Instance Method Summary collapse

Instance Method Details

#chef_classObject

Get the class for instances of this type. Must be overridden.

Raises:

  • (NotImplementedError)


133
134
135
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 133

def chef_class
  raise NotImplementedError
end

#chef_object(object) ⇒ Object

Turn a JSON hash into a bona fide Chef object (like Chef::Node).



119
120
121
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 119

def chef_object(object)
  chef_class.json_create(object)
end

#default(entry) ⇒ Object

Get the default value for an entry. Calls normalize({}, entry).



48
49
50
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 48

def default(entry)
  normalize({}, entry)
end

#from_ruby(ruby) ⇒ Object

Bring in an instance of this object from Ruby. (Like roles/x.rb)



112
113
114
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 112

def from_ruby(ruby)
  chef_class.from_file(ruby).to_hash
end

#minimize(object, entry) ⇒ Object

Remove all default values from a Chef object’s JSON so that the only thing you see are the values that have been explicitly set. Achieves this by calling normalize({}, entry) to get the list of defaults, and subtracting anything that is the same.



17
18
19
20
21
22
23
24
25
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 17

def minimize(object, entry)
  default_object = default(entry)
  object.each_pair do |key, value|
    if default_object[key] == value && !preserve_key?(key)
      object.delete(key)
    end
  end
  object
end

#normalize_for_post(object, entry) ⇒ Object

Specialized function to normalize an object before POSTing it, since some object types want slightly different values on POST. If not overridden, this just calls normalize()



80
81
82
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 80

def normalize_for_post(object, entry)
  normalize(object, entry)
end

#normalize_for_put(object, entry) ⇒ Object

Specialized function to normalize an object before PUTing it, since some object types want slightly different values on PUT. If not overridden, this just calls normalize().



87
88
89
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 87

def normalize_for_put(object, entry)
  normalize(object, entry)
end

#normalize_hash(object, defaults) ⇒ Object

Utility function to help subclasses do normalize(). Pass in a hash and a list of keys with defaults, and normalize will:

  1. Fill in the defaults

  2. Put the actual values in the order of the defaults

  3. Move any other values to the end

Example

normalize_hash({x: 100, c: 2, a: 1}, { a: 10, b: 20, c: 30})
-> { a: 1, b: 20, c: 2, x: 100}


65
66
67
68
69
70
71
72
73
74
75
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 65

def normalize_hash(object, defaults)
  # Make a normalized result in the specified order for diffing
  result = {}
  defaults.each_pair do |key, default|
    result[key] = object.has_key?(key) ? object[key] : default
  end
  object.each_pair do |key, value|
    result[key] = value if !result.has_key?(key)
  end
  result
end

#normalize_run_list(run_list) ⇒ Object

normalize a run list (an array of run list items). Leaves recipe and role alone, and translates name to recipe. Then calls uniq on the result.



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 96

def normalize_run_list(run_list)
  run_list.map{|item|
    case item.to_s
    when /^recipe\[.*\]$/
      item # explicit recipe
    when /^role\[.*\]$/
      item # explicit role
    else
      "recipe[#{item}]"
    end
  }.uniq
end

#preserve_key?(key) ⇒ Boolean

Return true if minimize() should preserve a key even if it is the same as the default. Often used for ids and names.

Returns:

  • (Boolean)


41
42
43
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 41

def preserve_key?(key)
  false
end

#remove_dot_json(name) ⇒ Object

Takes a name like blah.json and removes the .json from it.



30
31
32
33
34
35
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 30

def remove_dot_json(name)
  if name.length < 5 || name[-5,5] != ".json"
    raise "Invalid name #{path}: must end in .json"
  end
  name[0,name.length-5]
end

#to_ruby(object) ⇒ Object

Write out the Ruby file for this instance. (Like roles/x.rb)

Raises:

  • (NotImplementedError)


126
127
128
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 126

def to_ruby(object)
  raise NotImplementedError
end

#to_ruby_keys(object, keys) ⇒ Object

Helper to write out a Ruby file for a JSON hash. Writes out only the keys specified in “keys”; anything else must be emitted by the caller.

Example

to_ruby_keys({"name" => "foo", "environment" => "desert", "foo": "bar"}, [ "name", "environment" ])
->
'name "foo"
environment "desert"'


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
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 149

def to_ruby_keys(object, keys)
  result = ''
  keys.each do |key|
    if object[key]
      if object[key].is_a?(Hash)
        if object[key].size > 0
          result << key
          first = true
          object[key].each_pair do |k,v|
            if first
              first = false
            else
              result << ' '*key.length
            end
            result << " #{k.inspect} => #{v.inspect}\n"
          end
        end
      elsif object[key].is_a?(Array)
        if object[key].size > 0
          result << key
          first = true
          object[key].each do |value|
            if first
              first = false
            else
              result << ", "
            end
            result << value.inspect
          end
          result << "\n"
        end
      elsif !object[key].nil?
        result << "#{key} #{object[key].inspect}\n"
      end
    end
  end
  result
end

#verify_integrity(object, entry, &on_error) ⇒ Object

Verify that the JSON hash for this type has a key that matches its name. Calls the on_error block with the error, if there is one.



192
193
194
195
196
197
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 192

def verify_integrity(object, entry, &on_error)
  base_name = remove_dot_json(entry.name)
  if object['name'] != base_name
    on_error.call("Name must be '#{base_name}' (is '#{object['name']}')")
  end
end