Class: PuppetX::VMware::MapperNsx::Map

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

Constant Summary collapse

PIN_NO_PARENT =
:'!parent'
PIN_NO_VALUE =
:'!value'
PIN_NIL_VALUE =
:'!nil'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMap

abstract class

  • concrete classes contain initialization data

  • this class contains methods



190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 190

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.



205
206
207
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 205

def leaf_list
  @leaf_list
end

#node_listObject (readonly)

Returns the value of attribute node_list.



205
206
207
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 205

def node_list
  @node_list
end

Instance Method Details

#ensure_is_class(cfg, keypath, klass) ⇒ Object



325
326
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 325

def ensure_is_class cfg, keypath, klass
end

#gyoku_issue_48(cfg, node) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 214

def gyoku_issue_48 cfg, node
  return unless node.misc.include? :gyoku_issue_48
  self_closing = node.misc.include? :self_closing
  # full keypaths
  k_target     = node.path_should
  k_parent     = node.path_should[0..-2]
  # relative key to target from parent
  r_target     = k_target[-1]
  #
  parent = nested_value cfg, k_parent
  parent[r_target].each{|tel|
    attribute_keys = node.xml_attr
    unless attribute_keys.empty?
      gsk = :'attributes!'
      parent[gsk]           ||= {}
      parent[gsk][r_target] ||= []
      parent[gsk][r_target] <<
        # attribute keys have '@' prefix except in :attributes! 
        # hash, so keys are changed as values are transferred
        attribute_keys.reduce({}){|h, ak| h[ak[1..-1]] = tel.delete ak; h}
    end
  }
  parent[r_target] = Array.new(parent.delete(r_target).size, '') if self_closing
end

#gyoku_self_closing_keys(cfg, node) ⇒ Object



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
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 239

def gyoku_self_closing_keys cfg, node
  return unless node.misc.include? :self_closing
  key_parent = node.path_should[0..-2]
  if parent = nested_value(cfg, key_parent)
    old_rel = node.path_should[-1]
    new_rel = old_rel + '/'
    new_abs = key_parent + [new_rel]
    # move content from old to new key in parent
    if (parent.include? old_rel)
      nested_value_set cfg, new_abs, (parent.delete old_rel)
    end
    # fixup :order!
    if parent.include? :order!
      o = parent[:order!]
      i = o.index old_rel
      o[i] = new_rel if i
    end
    # fixup :attributes!
    if parent.include? :attributes!
      a = parent[:attributes!]
      if a.include? old_rel
        # move value from old key to new key
        a[new_rel] = a.delete old_rel
      end
    end
  end
end

#nested_value(*args, &block) ⇒ Object



207
208
209
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 207

def nested_value *args, &block
  PuppetX::VMware::Util.nested_value *args, &block
end

#nested_value_set(*args) ⇒ Object



210
211
212
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 210

def nested_value_set *args
  PuppetX::VMware::Util.nested_value_set *args, transform_keys=false
end

#prep_for_serialization(should) ⇒ Object Also known as: objectify



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 267

def prep_for_serialization should
  cfg = Marshal.load(Marshal.dump(should))
  # Step through the node list, which is in bottom-up sequence.
  @node_list.each do |node|
    # for vcd api - add order of enclosed elements
    # for gyoku   - use pseudo-element key :order!
    unless node.xml_order.empty?
      container = nested_value cfg, node.path_should
      if container
        keys_in_use = container.keys
        order = node.xml_order.select{|e| keys_in_use.include? e}
        p = node.path_should + [:'order!']
        nested_value_set cfg, p, order
      end
    end
    # for vcd api - add type
    # for gyoku   - prefix '@' to flag as attribute
    unless node.xml_type == ""
      p = node.path_should + ['@type']
      nested_value_set cfg, p, node.xml_type
    end
    # for vcd api - add xmlns
    # for gyoku   - prefix '@' to flag as attribute
    unless node.xml_ns == ""
      p = node.path_should + ['@xmlns']
      nested_value_set cfg, p, node.xml_ns
    end
    # for vcd api - delete 'Link' elements
    node_ref = nested_value(cfg, node.path_should)
    node_ref.delete 'Link' if node_ref
    # for vcd api - delete a key if it is empty and we dont want to send
    if node.misc.include? :del_if_empty
      parent = nested_value(cfg,node.path_should[0..-2])
      child  = nested_value(cfg,node.path_should)
      parent.delete(node.path_should[-1]) if child and child.empty?
    end
    # for gyoku   - https://github.com/savonrb/gyoku/issues/48
    # *** MOVES CONTENT AWAY FROM PATH_SHOULD ***
    gyoku_issue_48 cfg, node
  end
  @node_list.each do |node|
    # for gyoku   - mark self-closing elements
    # *** MOVES CONTENT AWAY FROM PATH_SHOULD ***
    # This changes sibling values, and is delayed
    # until a second pass through node_list so that
    # all siblings will have been created.
    # - :order! => [..., mykey, ...]     : 
    #   created when parent node is processed by
    #   prep_for_serialization (see xml_order)
    # - :attributes! => { ..., mykey => {}, ...}
    #   created when this node is processed by
    #   prep_for_serialization (gyoku_issue_48)
    gyoku_self_closing_keys cfg, node
  end
  cfg
end

#prep_is_now(is_now) ⇒ Object Also known as: annotate_is_now



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/puppet_x/vmware/mapper_nsx.rb', line 332

def prep_is_now is_now
  cfg = Marshal.load(Marshal.dump(is_now))
  # visit each Node and Leaf in the is_now tree
  # - clean up deserialization artifacts
  # - node_list is ordered for bottom-up sequence
  #   but here we work top down, so containers 
  #   will be created before we attempt to create
  #   their contents
  [@node_list.reverse, @leaf_list].flatten.each do |mapc|
    if mapc.olio.include? :ensure_is_class
      klass   = mapc.olio[:ensure_is_class]
      keypath = mapc.path_is_now
      value   = nested_value(cfg, keypath) \
          do |hash, keys, index|
            if index < keys.size - 1
              PIN_NO_PARENT
            else
              parent = nested_value hash, keys[0..-2]
              # note that parent[keys[-1]] has returned 
              # nil; that's why we've reached this block
              if parent.respond_to? :has_key? and parent.has_key? keys[-1]
                PIN_NIL_VALUE
              else
                PIN_NO_VALUE
              end
            end
          end
      case value
      when PIN_NO_PARENT, PIN_NO_VALUE
        # that's all, folks!
      when PIN_NIL_VALUE
        eligible = [::Array, ::Hash, ::String]
        if eligible.include? klass
          value = klass.new
        else
          fail "For #{mapc.full_name}: unable to create object of class #{klass} from nil"
        end
        nested_value_set cfg, keypath, value
      else
        unless value.class.eql? klass
          if (klass.eql? ::Array) or (klass < ::Array)
            value = [value]
          elsif klass.respond_to? :new
            begin
              value = klass.new value
            rescue
              fail "For #{mapc.full_name}: unable to create object using #{klass}.new from value: #{value.inspect}"
            end
          else
            value = \
              case (s = String klass)
              when 'String'   then String value
              when 'Integer'  then Integer value
              when 'Float'    then Float value
              when 'Array'    then Array value
              when 'Complex'  then value.to_c
              when 'Rational' then value.to_r
              else
                fail "For #{mapc.full_name}: unable to create object of class #{klass} from value: #{value.inspect}"
              end
          end
          nested_value_set cfg, keypath, value
        end
      end
    end
  end
  cfg
end