Class: PuppetX::VMware::Mapper::Map

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet_x/vmware/mapper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMap

abstract class

  • concrete classes contain initialization data

  • this class contains methods



178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/puppet_x/vmware/mapper.rb', line 178

def initialize
  # @initTree is defined in subclasses...
  @leaf_list = []
  @node_list = []

  # walk down the initTree and find the leaves
  walk_down @initTree, [], @leaf_list, @node_list

  # now that it's complete, go through leaf_list 
  # to resolve interdependencies
  requires_for_inheritable_policy
  requires_for_requires_siblings

end

Instance Attribute Details

#leaf_listObject (readonly)

Returns the value of attribute leaf_list.



193
194
195
# File 'lib/puppet_x/vmware/mapper.rb', line 193

def leaf_list
  @leaf_list
end

#node_listObject (readonly)

Returns the value of attribute node_list.



193
194
195
# File 'lib/puppet_x/vmware/mapper.rb', line 193

def node_list
  @node_list
end

Instance Method Details

#annotate_is_now(is_now) ⇒ Object



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/puppet_x/vmware/mapper.rb', line 290

def annotate_is_now is_now
  # for each Node representing an abstract type, annotate
  # the is_now tree to include the current :vsphereType
  @node_list.each do |node|
    if o = PuppetX::VMware::Util::nested_value(is_now, node.path_is_now)
      type_name = o.class.to_s.split('::').last.to_sym
      if node.node_type == :ABSTRACT2
        type_name = "type#{type_name}".to_sym
        o.props[type_name] = {}.update o.props
      elsif node.node_type == :ABSTRACT
        o[node.node_type_key] = type_name
      end
    end
  end
  is_now
end

#objectify(should) ⇒ Object



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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/puppet_x/vmware/mapper.rb', line 195

def objectify should
  obj_tree = Marshal.load(Marshal.dump(should))
  # Step through the node list, which is in bottom-up sequence.
  # If data for a vSphere object are found in 'should',
  # create the object and replace the data with the object.
  @node_list.each do |node|
    node = node.dup
    Puppet.debug "node #{node.path_should.join('.')}: checking #{node.inspect}"
    data = PuppetX::VMware::Util::nested_value(obj_tree, node.path_should)
    if data
      Puppet.debug "node #{node.path_should.join('.')}: found #{data.inspect}"

      # If this node is a concrete type, the type is in node.node_type
      # If it's an abstract type,
      #   ABSTRACT  requires the type be the value for a key in data
      #   ABSTRACT2 requires the type be derived from the sole key in data

      if node.node_types
        # the ABSTRACT2 paradigm... avoiding key conflicts among
        # concrete types by pushing concrete type keys down a level
        if \
            (data.size == 1) &&
            (the_key = data.keys.first) &&
              # the 'type' prefix is solely because puppet won't accept 
              # a hash key starting with an uppercase letter
            (the_key.to_s =~ /^type([A-Z][A-Za-z0-9_]*)$/) &&
            (Regexp.last_match.size > 1) &&
            (node.node_types.include? Regexp.last_match[1].to_sym)
          # we have a type; pull the data up, deleting the_key
          node_type = Regexp.last_match[1].to_sym
          data = data[the_key]
        end
      elsif node.node_type == :ABSTRACT
        node_type = data.delete(node.node_type_key)
      elsif node.node_type
        node_type = node.node_type
      else
        node_type = nil
      end

      if data.empty?
        # data was originally empty, or contained only type information
        parent = PuppetX::VMware::Util::nested_value(obj_tree, node.path_should[0..-2])
        parent.delete(node.path_should[-1])
        Puppet.debug "node #{node.path_should.join('.')}: key and value deleted"
      else
        # if node_type is unknown, there's a problem
        unless node_type
          if (node.node_type == :ABSTRACT) && node.node_type_key
            msg = "Input error. vSphere API object type required: " + 
                "[#{node.path_should.join('.')}.#{node.node_type_key}]"
          elsif node.node_types # :ABSTRACT2
            msg = "Input error. vSphere API type information required, one of: "
            node.node_types.each{|type| msg << "type#{type}; "}
          else
            # neither node_type nor node_type_key found in initTree
            msg = "Internal error. Type unknown for vSphere API object " +
                "at [#{node.path_should.join('.')}] type unknown."
          end
          fail msg
        end

        begin
          vso = RbVmomi::VIM.const_get(node_type).new data
          Puppet.debug "node #{node.path_should.join('.')}: created #{vso.inspect}"
        rescue RuntimeError => e
          # Check for invalid properties that can occur with abstract types.
          # See for example ClusterDasAdmissionControlPolicy at
          # http://pubs.vmware.com/vsphere-51/topic/
          # com.vmware.wssdk.apiref.doc/
          # vim.cluster.DasAdmissionControlPolicy.html
          r = e.message.match(/unexpected property name (.*)/)
          if r && r[1]
            name = r[1]
            msg = "Property [#{node.path_should.join('.')}.#{name}] " +
                "incompatible with type '#{node_type}'"
            fail msg
          else
            fail e.message
          end
        end

        # store the object in the tree in place of the data hash
        if node.path_should.empty?
          obj_tree = vso
        else
          PuppetX::VMware::Util::nested_value_set(obj_tree, node.path_should, vso)
        end
      end

    end
  end
  obj_tree
end