Class: VCenterDriver::VIClient

Inherits:
Object
  • Object
show all
Defined in:
lib/vcenter_driver.rb

Overview

This class represents a VCenter connection and an associated OpenNebula client The connection is associated to the VCenter backing a given OpenNebula host. For the VCenter driver each OpenNebula host represents a VCenter cluster

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hid) ⇒ VIClient

Initializr the VIClient, and creates an OpenNebula client. The parameters are obtained from the associated OpenNebula host

Parameters:

  • hid (Integer)

    The OpenNebula host id with VCenter attributes



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
# File 'lib/vcenter_driver.rb', line 159

def initialize(hid)

    initialize_one

    @one_host = ::OpenNebula::Host.new_with_id(hid, @one)
    rc = @one_host.info

    if ::OpenNebula.is_error?(rc)
        raise "Error getting host information: #{rc.message}"
    end

    password = @one_host["TEMPLATE/VCENTER_PASSWORD"]

    if !@token.nil?
        begin
            cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")

            cipher.decrypt
            cipher.key = @token

            password =  cipher.update(Base64::decode64(password))
            password << cipher.final
        rescue
            raise "Error decrypting vCenter password"
        end
    end

    connection = {
        :host     => @one_host["TEMPLATE/VCENTER_HOST"],
        :user     => @one_host["TEMPLATE/VCENTER_USER"],
        :password => password
    }

    initialize_vim(connection)

    datacenters = VIClient.get_entities(@root, 'Datacenter')

    datacenters.each {|dc|
        ccrs = VIClient.get_entities(dc.hostFolder, 'ClusterComputeResource')

        next if ccrs.nil?

        @cluster = ccrs.find{ |ccr| @one_host.name == ccr.name }

        (@dc = dc; break) if @cluster
    }

    if @dc.nil? || @cluster.nil?
        raise "Cannot find DataCenter or ClusterComputeResource for host."
    end
end

Instance Attribute Details

#clusterObject (readonly)

The associated cluster for this connection



229
230
231
# File 'lib/vcenter_driver.rb', line 229

def cluster
  @cluster
end

#dcObject (readonly)

Returns the value of attribute dc.



118
119
120
# File 'lib/vcenter_driver.rb', line 118

def dc
  @dc
end

#hostObject (readonly)

Returns the value of attribute host.



118
119
120
# File 'lib/vcenter_driver.rb', line 118

def host
  @host
end

#oneObject (readonly)

Returns the value of attribute one.



118
119
120
# File 'lib/vcenter_driver.rb', line 118

def one
  @one
end

#passObject (readonly)

Returns the value of attribute pass.



118
119
120
# File 'lib/vcenter_driver.rb', line 118

def pass
  @pass
end

#rootObject (readonly)

Returns the value of attribute root.



118
119
120
# File 'lib/vcenter_driver.rb', line 118

def root
  @root
end

#userObject (readonly)

Returns the value of attribute user.



118
119
120
# File 'lib/vcenter_driver.rb', line 118

def user
  @user
end

#vimObject (readonly)

Returns the value of attribute vim.



118
119
120
# File 'lib/vcenter_driver.rb', line 118

def vim
  @vim
end

Class Method Details

.find_ds_name(ds_id) ⇒ Object



726
727
728
729
730
731
732
# File 'lib/vcenter_driver.rb', line 726

def self.find_ds_name(ds_id)
    ds = OpenNebula::Datastore.new_with_id(ds_id)
    rc = ds.info
    raise "Could not find datastore #{ds_id}" if OpenNebula.is_error?(rc)

    return ds.name
end

.get_entities(folder, type, entities = []) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/vcenter_driver.rb', line 120

def self.get_entities(folder, type, entities=[])
    return nil if folder == []

    folder.childEntity.each do |child|
        name, junk = child.to_s.split('(')

        case name
        when "Folder"
            VIClient.get_entities(child, type, entities)
        when type
            entities.push(child)
        end
    end

    return entities
end

.in_silenceObject

Silences standard output and error



912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
# File 'lib/vcenter_driver.rb', line 912

def self.in_silence
    begin
      orig_stderr = $stderr.clone
      orig_stdout = $stdout.clone
      $stderr.reopen File.new('/dev/null', 'w')
      $stdout.reopen File.new('/dev/null', 'w')
      retval = yield
    rescue Exception => e
      $stdout.reopen orig_stdout
      $stderr.reopen orig_stderr
      raise e
    ensure
      $stdout.reopen orig_stdout
      $stderr.reopen orig_stderr
    end
   retval
end

.in_stderr_silenceObject

Silences standard output and error



933
934
935
936
937
938
939
940
941
942
943
944
945
# File 'lib/vcenter_driver.rb', line 933

def self.in_stderr_silence
    begin
      orig_stderr = $stderr.clone
      $stderr.reopen File.new('/dev/null', 'w')
      retval = yield
    rescue Exception => e
      $stderr.reopen orig_stderr
      raise e
    ensure
      $stderr.reopen orig_stderr
    end
   retval
end

.new_connection(user_opts, one_client = nil) ⇒ Object

Initialize a VIConnection based just on the VIM parameters. The OpenNebula client is also initialized



215
216
217
218
219
220
221
222
223
224
# File 'lib/vcenter_driver.rb', line 215

def self.new_connection(user_opts, one_client=nil)

    conn = allocate

    conn.initialize_one(one_client)

    conn.initialize_vim(user_opts)

    return conn
end

.translate_hostname(hostname) ⇒ Object



717
718
719
720
721
722
723
724
# File 'lib/vcenter_driver.rb', line 717

def self.translate_hostname(hostname)
    host_pool = OpenNebula::HostPool.new(::OpenNebula::Client.new())
    rc        = host_pool.info
    raise "Could not find host #{hostname}" if OpenNebula.is_error?(rc)

    host = host_pool.select {|host_element| host_element.name==hostname }
    return host.first.id
end

Instance Method Details

#copy_virtual_disk(source_path, source_ds, target_path, target_ds = nil) ⇒ Object

Copy a VirtualDisk

Parameters:

  • ds_name (String)

    name of the datastore

  • img_str (String)

    path to the VirtualDisk



842
843
844
845
846
847
848
849
850
851
852
# File 'lib/vcenter_driver.rb', line 842

def copy_virtual_disk(source_path, source_ds, target_path, target_ds=nil)
    target_ds = source_ds if target_ds.nil?

    copy_params= {:sourceName => "[#{source_ds}] #{source_path}",
                  :sourceDatacenter => @dc,
                  :destName => "[#{target_ds}] #{target_path}"}

    @vdm.CopyVirtualDisk_Task(copy_params).wait_for_completion

    target_path
end

#create_directory(directory, ds_name) ⇒ Object

Delete a VirtualDisk

Parameters:

  • directory (String)

    name of the new directory

  • ds_name (String)

    name of the datastore where to create the dir



899
900
901
902
903
904
905
906
907
# File 'lib/vcenter_driver.rb', line 899

def create_directory(directory, ds_name)
    begin
        path = "[#{ds_name}] #{directory}"
        @file_manager.MakeDirectory(:name => path,
                                    :datacenter => @dc,
                                    :createParentDirectories => true)
    rescue RbVmomi::VIM::FileAlreadyExists => e
    end
end

#create_virtual_disk(img_name, ds_name, size, adapter_type, disk_type) ⇒ Object

Parameters:

  • img_name (String)

    name of the image

  • ds_name (String)

    name of the datastore on which the VD will be created

  • size (String)

    size of the new image in MB

  • adapter_type (String)

    as described in

  • disk_type (String)

    as described in

Returns:

  • name of the final image



866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
# File 'lib/vcenter_driver.rb', line 866

def create_virtual_disk(img_name, ds_name, size, adapter_type, disk_type)
    vmdk_spec = RbVmomi::VIM::FileBackedVirtualDiskSpec(
        :adapterType => adapter_type,
        :capacityKb  => size.to_i*1024,
        :diskType    => disk_type
    )

    @vdm.CreateVirtualDisk_Task(
      :datacenter => @dc,
      :name       => "[#{ds_name}] #{img_name}.vmdk",
      :spec       => vmdk_spec
    ).wait_for_completion

    "#{img_name}.vmdk"
end

#default_resource_poolObject

Get the default resource pool of the connection. Only valid if the connection is not confined in a resource pool

Returns:

  • ResourcePool the default resource pool



263
264
265
# File 'lib/vcenter_driver.rb', line 263

def default_resource_pool
    @cluster.resourcePool
end

#delete_virtual_disk(img_name, ds_name) ⇒ Object

Delete a VirtualDisk

Parameters:

  • img_name (String)

    name of the image

  • ds_name (String)

    name of the datastore where the VD resides



887
888
889
890
891
892
# File 'lib/vcenter_driver.rb', line 887

def delete_virtual_disk(img_name, ds_name)
    @vdm.DeleteVirtualDisk_Task(
      name: "[#{ds_name}] #{img_name}",
      datacenter: @dc
    ).wait_for_completion
end

#find_resource_pool(poolName) ⇒ Object

Searches the desired ResourcePool of the DataCenter for the current connection. Returns a RbVmomi::VIM::ResourcePool or the default pool if not found

Parameters:

  • rpool (String)

    the ResourcePool name



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
# File 'lib/vcenter_driver.rb', line 273

def find_resource_pool(poolName)
    baseEntity = @cluster

    entityArray = poolName.split('/')
    entityArray.each do |entityArrItem|
      if entityArrItem != ''
        if baseEntity.is_a? RbVmomi::VIM::Folder
            baseEntity = baseEntity.childEntity.find { |f|
                              f.name == entityArrItem
                          } or return @cluster.resourcePool
        elsif baseEntity.is_a? RbVmomi::VIM::ClusterComputeResource
            baseEntity = baseEntity.resourcePool.resourcePool.find { |f|
                              f.name == entityArrItem
                          } or return @cluster.resourcePool
        elsif baseEntity.is_a? RbVmomi::VIM::ResourcePool
            baseEntity = baseEntity.resourcePool.find { |f|
                              f.name == entityArrItem
                          } or return @cluster.resourcePool
        else
            return @cluster.resourcePool
        end
      end
    end

    if !baseEntity.is_a?(RbVmomi::VIM::ResourcePool) and
        baseEntity.respond_to?(:resourcePool)
          baseEntity = baseEntity.resourcePool
    end

    baseEntity
end

#find_vm(vm_name) ⇒ Object

Searches the associated vmFolder of the DataCenter for the current connection. Returns a RbVmomi::VIM::VirtualMachine or nil if not found

Parameters:

  • vm_name (String)

    the UUID of the VM or VM Template



333
334
335
336
337
338
339
340
341
342
343
# File 'lib/vcenter_driver.rb', line 333

def find_vm(vm_name)
    vms = VIClient.get_entities(@dc.vmFolder, 'VirtualMachine')

    return vms.find do |v|
        begin
            v.name == vm_name
        rescue RbVmomi::VIM::ManagedObjectNotFound
            false
        end
    end
end

#find_vm_template(uuid) ⇒ Object

Searches the associated vmFolder of the DataCenter for the current connection. Returns a RbVmomi::VIM::VirtualMachine or nil if not found

Parameters:

  • uuid (String)

    the UUID of the VM or VM Template



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/vcenter_driver.rb', line 310

def find_vm_template(uuid)
    version = @vim.serviceContent.about.version

    if version.split(".").first.to_i >= 6
        @dc.vmFolder.findByUuid(uuid, RbVmomi::VIM::VirtualMachine, @dc)
    else
        vms = VIClient.get_entities(@dc.vmFolder, 'VirtualMachine')

        return vms.find do |v|
            begin
                v.config && v.config.uuid == uuid
            rescue RbVmomi::VIM::ManagedObjectNotFound
                false
            end
        end
    end
end

#get_datastore(ds_name) ⇒ Object

Searches the associated datacenter for a particular datastore

Parameters:

  • ds_name (String)

    name of the datastore



350
351
352
353
# File 'lib/vcenter_driver.rb', line 350

def get_datastore(ds_name)
    datastores = VIClient.get_entities(@dc.datastoreFolder, 'Datastore')
    ds         = datastores.select{|ds| ds.name == ds_name}[0]
end

#get_entities_to_import(folder, type) ⇒ Object

Only retrieve properties with faster search



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/vcenter_driver.rb', line 138

def get_entities_to_import(folder, type)
     res = folder.inventory_flat(type => :all)
     objects = []

     res.each {|k,v|
        if k.to_s.split('(').first == type
            obj = {}
            v.propSet.each{ |dynprop|
                obj[dynprop.name] = dynprop.val
            }
            objects << OpenStruct.new(obj)
        end
    }
    return objects
end

#hierarchy(one_client = nil) ⇒ Hash

Builds a hash with the DataCenter / ClusterComputeResource hierarchy for this VCenter.

Returns:

  • (Hash)

    in the form [String] => ClusterComputeResources Names [Array - String]



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/vcenter_driver.rb', line 361

def hierarchy(one_client=nil)
    vc_hosts = {}

    datacenters = VIClient.get_entities(@root, 'Datacenter')

    hpool = OpenNebula::HostPool.new((one_client||@one))
    rc    = hpool.info

    datacenters.each { |dc|
        ccrs = VIClient.get_entities(dc.hostFolder, 'ClusterComputeResource')
        vc_hosts[dc.name] = []
        ccrs.each { |c|
            if !hpool["HOST[NAME=\"#{c.name}\"]"]
                vc_hosts[dc.name] << c.name
            end
          }
    }

    return vc_hosts
end

#initialize_one(one_client = nil) ⇒ Object

Initialize an OpenNebula connection with the default ONE_AUTH



737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
# File 'lib/vcenter_driver.rb', line 737

def initialize_one(one_client=nil)
    begin
        if one_client
            @one = one_client
        else
            @one = ::OpenNebula::Client.new()
        end

        system = ::OpenNebula::System.new(@one)

        config = system.get_configuration()

        if ::OpenNebula.is_error?(config)
            raise "Error getting oned configuration : #{config.message}"
        end

        @token = config["ONE_KEY"]
    rescue Exception => e
        raise "Error initializing OpenNebula client: #{e.message}"
    end
end

#initialize_vim(user_opts = {}) ⇒ Object

Initialize a connection with vCenter. Options

Parameters:

  • options (Hash)

    with: :user => The vcenter user :password => Password for the user :host => vCenter hostname or IP :insecure => SSL (optional, defaults to true)



767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
# File 'lib/vcenter_driver.rb', line 767

def initialize_vim(user_opts={})
    opts = {
        :insecure => true
    }.merge(user_opts)

    @user = opts[:user]
    @pass = opts[:password]
    @host = opts[:host]

    begin
        @vim  = RbVmomi::VIM.connect(opts)
        @root = @vim.root
        @vdm  = @vim.serviceContent.virtualDiskManager
        @file_manager  = @vim.serviceContent.fileManager
    rescue Exception => e
        raise "Error connecting to #{@host}: #{e.message}"
    end
end

#monitor_ds(ds_name) ⇒ String

Returns Datastore information

Parameters:

  • ds_name (String)

    name of the datastore

Returns:

  • (String)

    monitor information of the DS



825
826
827
828
829
830
831
832
833
834
835
# File 'lib/vcenter_driver.rb', line 825

def monitor_ds(ds_name)
    # Find datastore within datacenter
    ds = get_datastore(ds_name)

    total_mb = (ds.summary.capacity.to_i / 1024) / 1024
    free_mb = (ds.summary.freeSpace.to_i / 1024) / 1024
    used_mb = total_mb - free_mb
    ds_type = ds.summary.type

    "USED_MB=#{used_mb}\nFREE_MB=#{free_mb} \nTOTAL_MB=#{total_mb}"
end

#resource_poolResourcePool

The associated resource pool for this connection   resource pool. If the connection is confined to a particular   resource pool, then return just that one

Returns:

  • (ResourcePool)

    an array of resource pools including the default



246
247
248
249
250
251
252
253
254
255
256
# File 'lib/vcenter_driver.rb', line 246

def resource_pool
    rp_name = @one_host["TEMPLATE/VCENTER_RESOURCE_POOL"]

   if rp_name.nil?
      rp_array = @cluster.resourcePool.resourcePool
      rp_array << @cluster.resourcePool
      rp_array
   else
      [find_resource_pool(rp_name)]
   end
end

#rp_confined?Boolean

Is this Cluster confined in a resource pool?

Returns:

  • (Boolean)


236
237
238
# File 'lib/vcenter_driver.rb', line 236

def rp_confined?
   !@one_host["TEMPLATE/VCENTER_RESOURCE_POOL"].nil?
end

#stat(ds_name, img_str) ⇒ Object

Retrieve size for a VirtualDisk in a particular datastore

Parameters:

  • ds_name (String)

    name of the datastore

  • img_str (String)

    path to the VirtualDisk

Returns:

  • size of the file in Kb



794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
# File 'lib/vcenter_driver.rb', line 794

def stat(ds_name, img_str)
    img_path = File.dirname img_str
    img_name = File.basename img_str

    # Find datastore within datacenter
    ds = get_datastore(ds_name)

    # Create Search Spec
    spec         = RbVmomi::VIM::HostDatastoreBrowserSearchSpec.new
    spec.query   = [RbVmomi::VIM::VmDiskFileQuery.new,
                    RbVmomi::VIM::IsoImageFileQuery.new]
    spec.details = RbVmomi::VIM::FileQueryFlags(:fileOwner    => true,
                                                :fileSize     => true,
                                                :fileType     => true,
                                                :modification => true)
    spec.matchPattern=[img_name]

    search_params = {'datastorePath' => "[#{ds_name}] #{img_path}",
                     'searchSpec'    => spec}

    # Perform search task and return results
    search_task=ds.browser.SearchDatastoreSubFolders_Task(search_params)
    search_task.wait_for_completion
    (search_task.info.result[0].file[0].fileSize / 1024) / 1024
end

#vcenter_datastores(one_client = nil) ⇒ Hash

Builds a hash with the Datacenter / Datastores for this VCenter

Parameters:

Returns:

  • (Hash)

    in the form { dc_name [String] => Datastore [Array] of DS templates}



569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
# File 'lib/vcenter_driver.rb', line 569

def vcenter_datastores(one_client=nil)
    ds_templates = {}

    dspool = OpenNebula::DatastorePool.new(
        (one_client||@one))
    rc = dspool.info
    if OpenNebula.is_error?(rc)
        raise "Error contacting OpenNebula #{rc.message}"
    end

    hpool = OpenNebula::HostPool.new(
        (one_client||@one))
    rc = hpool.info
    if OpenNebula.is_error?(rc)
        raise "Error contacting OpenNebula #{rc.message}"
    end

    datacenters = VIClient.get_entities(@root, 'Datacenter')

    datacenters.each { |dc|
        one_tmp = []
        datastores = VIClient.get_entities(dc.datastoreFolder, 'Datastore')
        datastores.each { |ds|
            next if !ds.is_a? RbVmomi::VIM::Datastore
            # Find the Cluster from which to access this ds
            cluster_name = ds.host[0].key.parent.name

            if !dspool["DATASTORE[NAME=\"#{ds.name}\"]"] and
               hpool["HOST[NAME=\"#{cluster_name}\"]"]
                 one_tmp << {
                   :name     => "#{ds.name}",
                   :total_mb => ((ds.summary.capacity.to_i / 1024) / 1024),
                   :free_mb  => ((ds.summary.freeSpace.to_i / 1024) / 1024),
                   :cluster  => cluster_name,
                   :one  => "NAME=#{ds.name}\n"\
                            "DS_MAD=vcenter\n"\
                            "TM_MAD=vcenter\n"\
                            "VCENTER_CLUSTER=#{cluster_name}\n"
                 }
             end
        }
        ds_templates[dc.name] = one_tmp
    }

    return ds_templates
end

#vcenter_images(ds_name, one_client = nil) ⇒ Array

Builds a hash with the Images for a particular datastore

Parameters:

Returns:

  • (Array)

    of image templates



621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
# File 'lib/vcenter_driver.rb', line 621

def vcenter_images(ds_name, one_client=nil)
    img_types = ["FloppyImageFileInfo",
                 "IsoImageFileInfo",
                 "VmDiskFileInfo"]

    img_templates = []

    ipool = OpenNebula::ImagePool.new((one_client||@one))
    rc = ipool.info
    if OpenNebula.is_error?(rc)
        raise "Error contacting OpenNebula #{rc.message}"
    end

    dspool = OpenNebula::DatastorePool.new((one_client||@one))
    rc = dspool.info
    if OpenNebula.is_error?(rc)
        raise "Error contacting OpenNebula #{rc.message}"
    end

    ds_id = dspool["DATASTORE[NAME=\"#{ds_name}\"]/ID"]

    if !ds_id
        raise "Datastore not found in OpenNebula. Please import"\
              " it first and try again"
    end

    datacenters = VIClient.get_entities(@root, 'Datacenter')

    datacenters.each { |dc|

        # Find datastore within datacenter
        datastores = VIClient.get_entities(dc.datastoreFolder, 'Datastore')
        ds         = datastores.select{|ds| ds.name == ds_name}[0]
        next if !ds

        # Create Search Spec
        spec         = RbVmomi::VIM::HostDatastoreBrowserSearchSpec.new
        spec.query   = [RbVmomi::VIM::VmDiskFileQuery.new,
                        RbVmomi::VIM::IsoImageFileQuery.new]
        spec.details = RbVmomi::VIM::FileQueryFlags(:fileOwner => true,
                                                    :fileSize => true,
                                                    :fileType => true,
                                                    :modification => true)
        spec.matchPattern=[]

        search_params = {'datastorePath' => "[#{ds.name}]",
                         'searchSpec'    => spec}

        # Perform search task and return results
        search_task=ds.browser.SearchDatastoreSubFolders_Task(search_params)
        search_task.wait_for_completion

        search_task.info.result.each { |image|
            folderpath = ""
            if image.folderPath[-1] != "]"
                folderpath = image.folderPath.sub(/^\[#{ds_name}\] /, "")
            end

            image = image.file[0]

            # Skip not relevant files
            next if !img_types.include? image.class.to_s

            image_path = folderpath + image.path

            image_name = File.basename(image.path).reverse.sub("kdmv.","").reverse

            if !ipool["IMAGE[NAME=\"#{image_name} - #{ds_name}\"]"]
                img_templates << {
                    :name        => "#{image_name} - #{ds_name}",
                    :path        => image_path,
                    :size        => (image.fileSize / 1024).to_s,
                    :type        => image.class.to_s,
                    :dsid        => ds_id,
                    :one         => "NAME=\"#{image_name} - #{ds_name}\"\n"\
                                    "PATH=\"vcenter://#{image_path}\"\n"\
                                    "PERSISTENT=\"YES\"\n"\
                }

                if image.class.to_s == "VmDiskFileInfo"
                    img_templates[-1][:one] += "TYPE=\"OS\"\n"
                else
                    img_templates[-1][:one] += "TYPE=\"CDROM\"\n"
                end

                if image.class.to_s == "VmDiskFileInfo" &&
                   !image.diskType.nil?
                    img_templates[-1][:one] += "DISK_TYPE=#{image.diskType}\n"
                end
            end
        }
    }

    return img_templates
end

#vcenter_networks(one_client = nil) ⇒ Hash

Builds a hash with the Datacenter / CCR (Distributed)Networks for this VCenter

Parameters:

Returns:

  • (Hash)

    in the form { dc_name [String] => Networks [Array] }



454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/vcenter_driver.rb', line 454

def vcenter_networks(one_client=nil)
    vcenter_networks = {}

    vnpool = OpenNebula::VirtualNetworkPool.new(
        (one_client||@one), OpenNebula::Pool::INFO_ALL)
    rc     = vnpool.info
    if OpenNebula.is_error?(rc)
        raise "Error contacting OpenNebula #{rc.message}"
    end

    datacenters = VIClient.get_entities(@root, 'Datacenter')

    datacenters.each { |dc|
        networks = VIClient.get_entities(dc.networkFolder, 'Network' )
        one_nets = []

        networks.each { |n|
            # Skip those not in cluster
            next if !n[:host][0]

           # Networks can be in several cluster, create one per cluster
            Array(n[:host][0]).each{ |host_system|
                net_name = "#{n.name} - #{host_system.parent.name}"

                if !vnpool["VNET[BRIDGE=\"#{n[:name]}\"]/\
                        TEMPLATE[VCENTER_TYPE=\"Port Group\"]"]
                    one_nets << {
                        :name    => net_name,
                        :bridge  => n.name,
                        :cluster => host_system.parent.name,
                        :type    => "Port Group",
                        :one     => "NAME   = \"#{net_name}\"\n" \
                                    "BRIDGE = \"#{n[:name]}\"\n" \
                                    "VN_MAD = \"dummy\"\n" \
                                    "VCENTER_TYPE = \"Port Group\""
                    }
                end
            }
        }

        networks = VIClient.get_entities(dc.networkFolder,
                                         'DistributedVirtualPortgroup' )

        networks.each { |n|
            # Skip those not in cluster
            next if !n[:host][0]

            # DistributedVirtualPortgroup can be in several cluster,
            # create one per cluster
            Array(n[:host][0]).each{ |host_system|
             net_name = "#{n.name} - #{n[:host][0].parent.name}"

             if !vnpool["VNET[BRIDGE=\"#{n[:name]}\"]/\
                     TEMPLATE[VCENTER_TYPE=\"Distributed Port Group\"]"]
                 vnet_template = "NAME   = \"#{net_name}\"\n" \
                                 "BRIDGE = \"#{n[:name]}\"\n" \
                                 "VN_MAD = \"dummy\"\n" \
                                 "VCENTER_TYPE = \"Distributed Port Group\""


                 default_pc = n.config.defaultPortConfig

                 has_vlan = false
                 vlan_str = ""

                 if default_pc.methods.include? :vlan
                    has_vlan = default_pc.vlan.methods.include? :vlanId
                 end

                 if has_vlan
                     vlan     = n.config.defaultPortConfig.vlan.vlanId

                     if vlan != 0
                         if vlan.is_a? Array
                             vlan.each{|v|
                                 vlan_str += v.start.to_s + ".." +
                                             v.end.to_s + ","
                             }
                             vlan_str.chop!
                         else
                             vlan_str = vlan.to_s
                         end
                     end
                 end

                 if !vlan_str.empty?
                     vnet_template << "VLAN_ID=#{vlan_str}\n"
                 end

                 one_net = {:name    => net_name,
                            :bridge  => n.name,
                            :cluster => host_system.parent.name,
                            :type   => "Distributed Port Group",
                            :one    => vnet_template}

                 one_net[:vlan] = vlan_str if !vlan_str.empty?

                 one_nets << one_net
             end
            }
        }

        vcenter_networks[dc.name] = one_nets
    }

    return vcenter_networks
end

#vm_templates(one_client = nil) ⇒ Hash

Builds a hash with the Datacenter / VM Templates for this VCenter

Parameters:

Returns:

  • (Hash)

    in the form { dc_name [String] => Templates [Array] }



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'lib/vcenter_driver.rb', line 388

def vm_templates(one_client=nil)
    vm_templates = {}

    tpool = OpenNebula::TemplatePool.new(
        (one_client||@one), OpenNebula::Pool::INFO_ALL)
    rc = tpool.info
    if OpenNebula.is_error?(rc)
        raise "Error contacting OpenNebula #{rc.message}"
    end

    datacenters = VIClient.get_entities(@root, 'Datacenter')

    datacenters.each { |dc|
        vms = get_entities_to_import(dc.vmFolder, 'VirtualMachine')

        tmp = vms.select { |v| v.config && (v.config.template == true) }

        one_tmp    = []
        host_cache = {}
        ds_cache   = {}

        tmp.each { |t|
            vi_tmp = VCenterVm.new(self, t)

            if !tpool["VMTEMPLATE/TEMPLATE/PUBLIC_CLOUD[\
                    TYPE=\"vcenter\" \
                    and VM_TEMPLATE=\"#{vi_tmp.vm.config.uuid}\"]"]
                # Check cached objects
                if !host_cache[vi_tmp.vm.runtime.host.to_s]
                    host_cache[vi_tmp.vm.runtime.host.to_s] =
                               VCenterCachedHost.new vi_tmp.vm.runtime.host
                end

                if !ds_cache[t.datastore[0].to_s]
                    ds_cache[t.datastore[0].to_s] =
                               VCenterCachedDatastore.new  t.datastore[0]
                end

                host = host_cache[vi_tmp.vm.runtime.host.to_s]
                ds   = ds_cache[t.datastore[0].to_s]

                one_tmp << {
                    :name       => "#{vi_tmp.vm.name} - #{host.cluster_name}",
                    :uuid       => vi_tmp.vm.config.uuid,
                    :host       => host.cluster_name,
                    :one        => vi_tmp.to_one(host),
                    :ds         => vi_tmp.to_one_ds(host, ds.name),
                    :default_ds => ds.name,
                    :rp         => vi_tmp.to_one_rp(host)
                }
            end
        }

        vm_templates[dc.name] = one_tmp
    }

    return vm_templates
end