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)

137
138
139
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 137

def chef_class
  raise NotImplementedError
end

#chef_object(object) ⇒ Object

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


123
124
125
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 123

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

#default(entry) ⇒ Object

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


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

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

#from_ruby(path) ⇒ Object

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


114
115
116
117
118
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 114

def from_ruby(path)
  r = chef_class.new
  r.from_file(path)
  r.to_h
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()


82
83
84
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 82

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().


89
90
91
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 89

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

Examples:

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

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

def normalize_hash(object, defaults)
  # Make a normalized result in the specified order for diffing
  result = {}
  defaults.each_pair do |key, value|
    result[key] = object.is_a?(Hash) && object.key?(key) ? object[key] : value
  end
  if object.is_a?(Hash)
    object.each_pair do |key, value|
      result[key] = value unless result.key?(key)
    end
  else
    Chef::Log.warn "Encountered invalid object during normalization. Using these defaults #{defaults}"
  end
  result
end

#normalize_run_list(run_list) ⇒ Object

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


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

def normalize_run_list(run_list)
  run_list.map do |item|
    case item.to_s
    when /^recipe\[.*\]$/
      item # explicit recipe
    when /^role\[.*\]$/
      item # explicit role
    else
      "recipe[#{item}]"
    end
  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)

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

def preserve_key?(key)
  false
end

#remove_file_extension(name, ext = ".*") ⇒ Object Also known as: remove_dot_json


27
28
29
30
31
32
33
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 27

def remove_file_extension(name, ext = ".*")
  if %w{ .rb .json }.include?(File.extname(name))
    File.basename(name, ext)
  else
    name
  end
end

#to_ruby(object) ⇒ Object

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

Raises:

  • (NotImplementedError)

130
131
132
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 130

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.

Examples:

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

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

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) {|s| ... } ⇒ Object

Verify that the JSON hash for this type has a key that matches its name.

Parameters:

Yields:

  • (s)

    callback to handle errors

Yield Parameters:

  • error (s<string>)

    message


197
198
199
200
201
202
# File 'lib/chef/chef_fs/data_handler/data_handler_base.rb', line 197

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