Class: Fog::Compute::Vsphere::Real
- Inherits:
-
Object
- Object
- Fog::Compute::Vsphere::Real
- Includes:
- Shared
- Defined in:
- lib/rackspace-fog/vsphere/requests/compute/find_vm_by_ref.rb,
lib/rackspace-fog/vsphere/compute.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_clone.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_create.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_reboot.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_destroy.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_migrate.rb,
lib/rackspace-fog/vsphere/requests/compute/datacenters.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_power_on.rb,
lib/rackspace-fog/vsphere/requests/compute/current_time.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_power_off.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_config_vnc.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_reconfig_cpus.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_reconfig_memory.rb,
lib/rackspace-fog/vsphere/requests/compute/vm_reconfig_hardware.rb,
lib/rackspace-fog/vsphere/requests/compute/list_virtual_machines.rb
Overview
The Real and Mock classes share the same method because list_virtual_machines will be properly mocked for us
Constant Summary
Constants included from Shared
Instance Attribute Summary
Attributes included from Shared
#vsphere_is_vcenter, #vsphere_rev, #vsphere_server, #vsphere_username
Instance Method Summary collapse
- #current_time ⇒ Object
- #datacenters ⇒ Object
-
#initialize(options = {}) ⇒ Real
constructor
A new instance of Real.
- #list_virtual_machines(options = {}) ⇒ Object
- #vm_clone(options = {}) ⇒ Object
- #vm_config_vnc(options = { }) ⇒ Object
- #vm_create(options = {}) ⇒ Object
- #vm_destroy(options = {}) ⇒ Object
-
#vm_get_vnc(uuid) ⇒ Object
return a hash of VNC attributes required to view the console.
- #vm_migrate(options = {}) ⇒ Object
- #vm_power_off(options = {}) ⇒ Object
- #vm_power_on(options = {}) ⇒ Object
- #vm_reboot(options = {}) ⇒ Object
- #vm_reconfig_cpus(options = {}) ⇒ Object
- #vm_reconfig_hardware(options = {}) ⇒ Object
- #vm_reconfig_memory(options = {}) ⇒ Object
Methods included from Shared
#convert_vm_mob_ref_to_attr_hash, #find_vm_by_ref
Constructor Details
#initialize(options = {}) ⇒ Real
Returns a new instance of Real.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/rackspace-fog/vsphere/compute.rb', line 111 def initialize(={}) require 'rbvmomi' @vsphere_username = [:vsphere_username] @vsphere_password = [:vsphere_password] @vsphere_server = [:vsphere_server] @vsphere_port = [:vsphere_port] || 443 @vsphere_path = [:vsphere_path] || '/sdk' @vsphere_ns = [:vsphere_ns] || 'urn:vim25' @vsphere_rev = [:vsphere_rev] || '4.0' @vsphere_ssl = [:vsphere_ssl] || true @vsphere_expected_pubkey_hash = [:vsphere_expected_pubkey_hash] @vsphere_must_reauthenticate = false @connection = nil # This is a state variable to allow digest validation of the SSL cert bad_cert = false loop do begin @connection = RbVmomi::VIM.new :host => @vsphere_server, :port => @vsphere_port, :path => @vsphere_path, :ns => @vsphere_ns, :rev => @vsphere_rev, :ssl => @vsphere_ssl, :insecure => bad_cert break rescue OpenSSL::SSL::SSLError raise if bad_cert bad_cert = true end end if bad_cert then validate_ssl_connection end # Negotiate the API revision if not [:vsphere_rev] rev = @connection.serviceContent.about.apiVersion @connection.rev = [ rev, ENV['FOG_VSPHERE_REV'] || '4.1' ].min end @vsphere_is_vcenter = @connection.serviceContent.about.apiType == "VirtualCenter" @vsphere_rev = @connection.rev authenticate end |
Instance Method Details
#current_time ⇒ Object
6 7 8 9 |
# File 'lib/rackspace-fog/vsphere/requests/compute/current_time.rb', line 6 def current_time current_time = @connection.serviceInstance.CurrentTime { 'current_time' => current_time } end |
#datacenters ⇒ Object
5 6 7 8 9 |
# File 'lib/rackspace-fog/vsphere/requests/compute/datacenters.rb', line 5 def datacenters @datacenters ||= datacenters_reload # Hide the values which are the RbVmomi instances @datacenters.keys end |
#list_virtual_machines(options = {}) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/rackspace-fog/vsphere/requests/compute/list_virtual_machines.rb', line 5 def list_virtual_machines( = {}) # Listing all VM's can be quite slow and expensive. Try and optimize # based on the available options we have. These conditions are in # ascending order of time to complete for large deployments. if ['instance_uuid'] then list_all_virtual_machines_by_instance_uuid() elsif ['folder'] then list_all_virtual_machines_in_folder() else list_all_virtual_machines end end |
#vm_clone(options = {}) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_clone.rb', line 33 def vm_clone( = {}) # Option handling = () notfound = lambda { raise Fog::Compute::Vsphere::NotFound, "Could not find VM template" } # Find the template in the folder. This is more efficient than # searching ALL VM's looking for the template. # Tap gets rid of the leading empty string and "Datacenters" element # and returns the array. path_elements = ['path'].split('/').tap { |ary| ary.shift 2 } # The DC name itself. template_dc = path_elements.shift # If the first path element contains "vm" this denotes the vmFolder # and needs to be shifted out path_elements.shift if path_elements[0] == 'vm' # The template name. The remaining elements are the folders in the # datacenter. template_name = path_elements.pop # Make sure @datacenters is populated. We need the instances from the Hash keys. self.datacenters # Get the datacenter managed object from the hash dc = @datacenters[template_dc] # Get the VM Folder (Group) efficiently vm_folder = dc.vmFolder # Walk the tree resetting the folder pointer as we go folder = path_elements.inject(vm_folder) do |current_folder, sub_folder_name| # JJM VIM::Folder#find appears to be quite efficient as it uses the # searchIndex It certainly appears to be faster than # VIM::Folder#inventory since that returns _all_ managed objects of # a certain type _and_ their properties. sub_folder = current_folder.find(sub_folder_name, RbVmomi::VIM::Folder) raise ArgumentError, "Could not descend into #{sub_folder_name}. Please check your path." unless sub_folder sub_folder end # Now find the template itself using the efficient find method vm_mob_ref = folder.find(template_name, RbVmomi::VIM::VirtualMachine) # Now find _a_ resource pool to use for the clone # (REVISIT: We need to support cloning into a specific RP) if ( vm_mob_ref.resourcePool == nil ) # If the template is really a template then there is no associated resource pool, # so we need to find one using the template's parent host or cluster esx_host = vm_mob_ref.collect!('runtime.host')['runtime.host'] # The parent of the ESX host itself is a ComputeResource which has a resourcePool resource_pool = esx_host.parent.resourcePool else # If the vm given did return a valid resource pool, default to using it for the clone. # Even if specific pools aren't implemented in this environment, we will still get back # at least the cluster or host we can pass on to the clone task resource_pool = vm_mob_ref.resourcePool end relocation_spec=nil if ( ['linked_clone'] ) # cribbed heavily from the rbvmomi clone_vm.rb # this chunk of code reconfigures the disk of the clone source to be read only, # and then creates a delta disk on top of that, this is required by the API in order to create # linked clondes disks = vm_mob_ref.config.hardware.device.select do |vm_device| vm_device.class == RbVmomi::VIM::VirtualDisk end disks.select{|vm_device| vm_device.backing.parent == nil}.each do |disk| disk_spec = { :deviceChange => [ { :operation => :remove, :device => disk }, { :operation => :add, :fileOperation => :create, :device => disk.dup.tap{|disk_backing| disk_backing.backing = disk_backing.backing.dup; disk_backing.backing.fileName = "[#{disk.backing.datastore.name}]"; disk_backing.backing.parent = disk.backing } }, ] } vm_mob_ref.ReconfigVM_Task(:spec => disk_spec).wait_for_completion end # Next, create a Relocation Spec instance relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool, :diskMoveType => :moveChildMostDiskBacking) else relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool, :transform => ['transform'] || 'sparse') end # And the clone specification clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocation_spec, :powerOn => ['power_on'] || true, :template => false) task = vm_mob_ref.CloneVM_Task(:folder => vm_mob_ref.parent, :name => ['name'], :spec => clone_spec) # Waiting for the VM to complete allows us to get the VirtulMachine # object of the new machine when it's done. It is HIGHLY recommended # to set 'wait' => true if your app wants to wait. Otherwise, you're # going to have to reload the server model over and over which # generates a lot of time consuming API calls to vmware. if ['wait'] then # REVISIT: It would be awesome to call a block passed to this # request to notify the application how far along in the process we # are. I'm thinking of updating a progress bar, etc... new_vm = task.wait_for_completion else tries = 0 new_vm = begin # Try and find the new VM (folder.find is quite efficient) folder.find(['name'], RbVmomi::VIM::VirtualMachine) or raise Fog::Vsphere::Errors::NotFound rescue Fog::Vsphere::Errors::NotFound tries += 1 if tries <= 10 then sleep 15 retry end nil end end # Return hash { 'vm_ref' => new_vm ? new_vm._ref : nil, 'vm_attributes' => new_vm ? convert_vm_mob_ref_to_attr_hash(new_vm) : {}, 'task_ref' => task._ref } end |
#vm_config_vnc(options = { }) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_config_vnc.rb', line 5 def vm_config_vnc( = { }) raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' search_filter = { :uuid => ['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first task = vm_mob_ref.ReconfigVM_Task(:spec => { :extraConfig => [ { :key => 'RemoteDisplay.vnc.enabled', :value => [:enabled] ? 'true' : 'false' }, { :key => 'RemoteDisplay.vnc.password', :value => [:password].to_s }, { :key => 'RemoteDisplay.vnc.port', :value => [:port].to_s || '5910' } ] }) task.wait_for_completion { 'task_state' => task.info.state } end |
#vm_create(options = {}) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_create.rb', line 29 def vm_create( = {}) # Option handling = () path_elements = ['path'].split('/').tap { |ary| ary.shift 2 } dc_name = path_elements.shift vm_cfg = { :name => ['name'], :guestId => ['guest_id'] ? ['guest_id'] : 'otherGuest', :files => { :vmPathName => "[#{['datastore']}]" }, :numCPUs => ['num_cpus'] ? ['num_cpus'] : 1 , :memoryMB => ['memory'] ? ['memory'] : 512, :memoryHotAddEnabled => ['memory_hot_add_enabled'] ? ['memory_hot_add_enabled'] : 0, :cpuHotAddEnabled => ['cpu_hot_add_enabled'] ? ['cpu_hot_add_enabled'] : 0, :deviceChange => ['device_array'].class == Array ? ['device_array'] : nil, :extraConfig => ['extra_config'].class == Array ? ['extra_config'] : nil, } self.datacenters dc = @datacenters[dc_name] vm_folder = dc.vmFolder folder = path_elements.inject(vm_folder) do |current_folder, sub_folder_name| sub_folder = current_folder.find(sub_folder_name, RbVmomi::VIM::Folder) raise ArgumentError, "Could not descend into #{sub_folder_name}. Please check your path." unless sub_folder sub_folder end clusters = dc.hostFolder.children build_cluster='' clusters.each { |my_cluster| if "#{my_cluster.name}" == "#{['cluster']}" build_cluster=my_cluster end } resource_pool = build_cluster.resourcePool task=folder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool) if ['wait'] then new_vm = task.wait_for_completion else tries = 0 new_vm = begin folder.find(['name'], RbVmomi::VIM::VirtualMachine) or raise Fog::Vsphere::Errors::NotFound rescue Fog::Vsphere::Errors::NotFound tries += 1 if tries <= 10 then sleep 15 retry end nil end end { 'vm_ref' => new_vm ? new_vm._ref : nil, 'vm_attributes' => new_vm ? convert_vm_mob_ref_to_attr_hash(new_vm) : {}, 'task_ref' => task._ref } end |
#vm_destroy(options = {}) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_destroy.rb', line 6 def vm_destroy( = {}) raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' # Find the VM Object search_filter = { :uuid => ['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first unless vm_mob_ref.kind_of? RbVmomi::VIM::VirtualMachine raise Fog::Vsphere::Errors::NotFound, "Could not find VirtualMachine with instance uuid #{['instance_uuid']}" end task = vm_mob_ref.Destroy_Task task.wait_for_completion { 'task_state' => task.info.state } end |
#vm_get_vnc(uuid) ⇒ Object
return a hash of VNC attributes required to view the console
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_config_vnc.rb', line 22 def vm_get_vnc uuid search_filter = { :uuid => uuid, 'vmSearch' => true, 'instanceUuid' => true } vm = @connection.searchIndex.FindAllByUuid(search_filter).first Hash[vm.config.extraConfig.map do |config| if config.key =~ /^RemoteDisplay\.vnc\.(\w+)$/ [$1.to_sym, config.value] end end.compact] end |
#vm_migrate(options = {}) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_migrate.rb', line 6 def vm_migrate( = {}) #priority is the only required option, and it has a sane default option. priority = ['priority'].nil? ? 'defaultPriority' : ["priority"] raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' # Find the VM Object search_filter = { :uuid => ['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first unless vm_mob_ref.kind_of? RbVmomi::VIM::VirtualMachine raise Fog::Vsphere::Errors::NotFound, "Could not find VirtualMachine with instance uuid #{['instance_uuid']}" end task = vm_mob_ref.MigrateVM_Task(:pool => ['pool'], :host => ['host'], :priority => "#{priority}", :state => ['state'] ) task.wait_for_completion { 'task_state' => task.info.state } end |
#vm_power_off(options = {}) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_power_off.rb', line 6 def vm_power_off( = {}) = { 'force' => false }.merge() raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' search_filter = { :uuid => ['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first if ['force'] then task = vm_mob_ref.PowerOffVM_Task task.wait_for_completion { 'task_state' => task.info.result, 'power_off_type' => 'cut_power' } else vm_mob_ref.ShutdownGuest { 'task_state' => "running", 'power_off_type' => 'shutdown_guest', } end end |
#vm_power_on(options = {}) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_power_on.rb', line 6 def vm_power_on( = {}) raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' search_filter = { :uuid => ['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first task = vm_mob_ref.PowerOnVM_Task task.wait_for_completion # 'success', 'running', 'queued', 'error' { 'task_state' => task.info.state } end |
#vm_reboot(options = {}) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_reboot.rb', line 6 def vm_reboot( = {}) = { 'force' => false }.merge() raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' search_filter = { :uuid => ['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first if ['force'] then task = vm_mob_ref.ResetVM_Task task.wait_for_completion { 'task_state' => task.info.result, 'reboot_type' => 'reset_power' } else vm_mob_ref.ShutdownGuest { 'task_state' => "running", 'reboot_type' => 'reboot_guest' } end end |
#vm_reconfig_cpus(options = {}) ⇒ Object
5 6 7 8 9 10 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_reconfig_cpus.rb', line 5 def vm_reconfig_cpus( = {}) raise ArgumentError, "cpus is a required parameter" unless .has_key? 'cpus' raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' hardware_spec={'numCPUs' => ['cpus']} vm_reconfig_hardware('instance_uuid' => ['instance_uuid'], 'hardware_spec' => hardware_spec ) end |
#vm_reconfig_hardware(options = {}) ⇒ Object
5 6 7 8 9 10 11 12 13 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_reconfig_hardware.rb', line 5 def vm_reconfig_hardware( = {}) raise ArgumentError, "hardware_spec is a required parameter" unless .has_key? 'hardware_spec' raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' search_filter = { :uuid => ['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true } vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first task = vm_mob_ref.ReconfigVM_Task(:spec => RbVmomi::VIM.VirtualMachineConfigSpec(['hardware_spec'])) task.wait_for_completion { 'task_state' => task.info.state } end |
#vm_reconfig_memory(options = {}) ⇒ Object
5 6 7 8 9 10 |
# File 'lib/rackspace-fog/vsphere/requests/compute/vm_reconfig_memory.rb', line 5 def vm_reconfig_memory( = {}) raise ArgumentError, "memory is a required parameter" unless .has_key? 'memory' raise ArgumentError, "instance_uuid is a required parameter" unless .has_key? 'instance_uuid' hardware_spec={'memoryMB' => ['memory']} vm_reconfig_hardware('instance_uuid' => ['instance_uuid'], 'hardware_spec' => hardware_spec ) end |