class VCenterDriver::Datacenter
Class Datacenter
Constants
- DPG_CREATE_TIMEOUT
Attributes
item[RW]
Public Class Methods
new(item, vi_client = nil)
click to toggle source
# File lib/datacenter.rb, line 843 def initialize(item, vi_client = nil) check_item(item, RbVmomi::VIM::Datacenter) @vi_client = vi_client @item = item @net_rollback = [] @locking = true end
new_from_ref(ref, vi_client)
click to toggle source
# File lib/datacenter.rb, line 1312 def self.new_from_ref(ref, vi_client) new(RbVmomi::VIM::Datacenter.new(vi_client.vim, ref), vi_client) end
Public Instance Methods
create_dpg(dvs, pg_name, vlan_id, num_ports)
click to toggle source
Create a distributed vcenter port group
# File lib/datacenter.rb, line 1098 def create_dpg(dvs, pg_name, vlan_id, num_ports) spec = RbVmomi::VIM::DVPortgroupConfigSpec.new # OpenNebula use DVS static port binding with autoexpand if num_ports spec.autoExpand = true spec.numPorts = num_ports end # Distributed port group name spec.name = pg_name # Set VLAN information spec.defaultPortConfig = RbVmomi::VIM::VMwareDVSPortSetting.new spec.defaultPortConfig.vlan = RbVmomi::VIM::VmwareDistributedVirtualSwitchVlanIdSpec.new spec.defaultPortConfig.vlan.vlanId = vlan_id spec.defaultPortConfig.vlan.inherited = false # earlyBinding. A free DistributedVirtualPort will be selected and # assigned to a VirtualMachine when # the virtual machine is reconfigured # to connect to the portgroup. spec.type = 'earlyBinding' begin dvs .item .AddDVPortgroup_Task( :spec => [spec] ).wait_for_completion rescue StandardError => e raise "The Distributed port group #{pg_name} \ could not be created. "\ "Reason: #{e.message}" end # wait until the network is ready and we have a reference portgroups = dvs['portgroup'].select do |dpg| dpg.instance_of?(RbVmomi::VIM::DistributedVirtualPortgroup) && dpg['name'] == pg_name end (0..DPG_CREATE_TIMEOUT).each do break unless portgroups.empty? portgroups = dvs['portgroup'].select do |dpg| dpg .instance_of?( RbVmomi::VIM::DistributedVirtualPortgroup ) && dpg['name'] == pg_name end sleep 1 end if portgroups.empty? raise 'Cannot get VCENTER_NET_REF \ for new distributed port group' end @net_rollback << { :action => :delete_dpg, :dpg => portgroups.first, :name => pg_name } portgroups.first._ref end
create_dvs(switch_name, pnics, mtu = 1500)
click to toggle source
Create a distributed vcenter switch in a datacenter
# File lib/datacenter.rb, line 906 def create_dvs(switch_name, pnics, mtu = 1500) # Prepare spec for DVS creation spec = RbVmomi::VIM::DVSCreateSpec.new spec.configSpec = RbVmomi::VIM::VMwareDVSConfigSpec.new spec.configSpec.name = switch_name # Specify number of uplinks port for dpg if pnics pnics = pnics.split(',') if !pnics.empty? spec.configSpec.uplinkPortPolicy = RbVmomi::VIM::DVSNameArrayUplinkPortPolicy.new spec.configSpec.uplinkPortPolicy.uplinkPortName = [] (0..pnics.size-1).each do |index| spec .configSpec .uplinkPortPolicy .uplinkPortName[index]="dvUplink#{index+1}" end end end # Set maximum MTU spec.configSpec.maxMtu = mtu # The DVS must be created in the networkFolder of the datacenter dvs_creation_task = @item .networkFolder .CreateDVS_Task( :spec => spec ) dvs_creation_task.wait_for_completion # If task finished successfuly we rename the uplink portgroup dvs = nil if dvs_creation_task.info.state == 'success' dvs = dvs_creation_task.info.result dvs .config .uplinkPortgroup[0] .Rename_Task( :newName => "#{switch_name}-uplink-pg" ).wait_for_completion else raise "The Distributed vSwitch #{switch_name} \ could not be created. " end @net_rollback << { :action => :delete_dvs, :dvs => dvs, :name => switch_name } VCenterDriver::DistributedVirtualSwitch.new(dvs, @vi_client) end
datastore_folder()
click to toggle source
# File lib/datacenter.rb, line 852 def datastore_folder DatastoreFolder.new(@item.datastoreFolder) end
dpg_exists(pg_name, net_folder)
click to toggle source
Check if distributed port group exists in datacenter
# File lib/datacenter.rb, line 1048 def dpg_exists(pg_name, net_folder) net_folder.items.values.select do |dpg| dpg.instance_of?(VCenterDriver::DistributedPortGroup) && dpg['name'] == pg_name end.first rescue nil end
dvs_exists(switch_name, net_folder)
click to toggle source
Check if distributed virtual switch exists in host
# File lib/datacenter.rb, line 889 def dvs_exists(switch_name, net_folder) net_folder.items.values.select do |dvs| dvs.instance_of?(VCenterDriver::DistributedVirtualSwitch) && dvs['name'] == switch_name end.first rescue nil end
host_folder()
click to toggle source
# File lib/datacenter.rb, line 856 def host_folder HostFolder.new(@item.hostFolder) end
lock()
click to toggle source
Locking function. Similar to flock
# File lib/datacenter.rb, line 869 def lock hostlockname = @item['name'].downcase.tr(' ', '_') return unless @locking @locking_file = File .open("/tmp/vcenter-dc-#{hostlockname}-lock", 'w') @locking_file.flock(File::LOCK_EX) end
network_folder()
click to toggle source
# File lib/datacenter.rb, line 864 def network_folder NetworkFolder.new(@item.networkFolder) end
network_rollback()
click to toggle source
Perform vcenter network rollback operations
# File lib/datacenter.rb, line 1256 def network_rollback @net_rollback.reverse_each do |nr| case nr[:action] when :update_dpg begin nr[:dpg].ReconfigureDVPortgroup_Task(:spec => nr[:spec]) .wait_for_completion rescue StandardError => e raise "A rollback operation for distributed \ port group #{nr[:name]} could not \ be performed. Reason: #{e.message}" end when :update_dvs begin nr[:dvs].ReconfigureDvs_Task(:spec => nr[:spec]) .wait_for_completion rescue StandardError => e raise "A rollback operation for distributed\ standard switch #{nr[:name]} could \ not be performed. Reason: #{e.message}" end when :delete_dvs begin nr[:dvs].Destroy_Task.wait_for_completion rescue RbVmomi::VIM::ResourceInUse next # Ignore if switch in use rescue RbVmomi::VIM::NotFound next # Ignore if switch not found rescue StandardError => e raise "A rollback operation \ for standard switch #{nr[:name]} \ could not be performed. Reason: #{e.message}" end when :delete_dpg begin nr[:dpg].Destroy_Task.wait_for_completion rescue RbVmomi::VIM::ResourceInUse next # Ignore if pg in use rescue RbVmomi::VIM::NotFound next # Ignore if pg not found rescue StandardError => e raise "A rollback operation for \ standard port group #{nr[:name]} could \ not be performed. Reason: #{e.message}" end end end end
nsx_network(nsx_id, pg_type)
click to toggle source
Check if Opaque Network
exists in datacenter
# File lib/datacenter.rb, line 1058 def nsx_network(nsx_id, pg_type) timeout = 180 case pg_type when VCenterDriver::Network::NETWORK_TYPE_NSXT while timeout > 0 net_folder = network_folder net_folder.fetch! net_folder.items.values.each do |net| if net.instance_of?(VCenterDriver::OpaqueNetwork) && net.item.summary.opaqueNetworkId == nsx_id return net.item._ref end end sleep(1) timeout -= 1 end # Not used right now, but maybe neccesary in the future. when VCenterDriver::Network::NETWORK_TYPE_NSXV while timeout > 0 net_folder = network_folder net_folder.fetch! net_folder.items.values.each do |net| if net.instance_of?( VCenterDriver::DistributedPortGroup ) && net.item.key == nsx_id return net.item._ref end end sleep(1) timeout -= 1 end else raise "Unknown network Port Group type: #{pg_type}" end end
pg_changes_sw?(dpg, switch_name)
click to toggle source
Is the distributed switch for the distributed pg different?
# File lib/datacenter.rb, line 899 def pg_changes_sw?(dpg, switch_name) dpg['config.distributedVirtualSwitch.name'] != switch_name end
power_on_vm(vm)
click to toggle source
PowerOn VMs
# File lib/datacenter.rb, line 1308 def power_on_vm(vm) @item.PowerOnMultiVM_Task({ :vm => [vm] }).wait_for_completion end
remove_dpg(dpg)
click to toggle source
Remove distributed port group from datacenter
# File lib/datacenter.rb, line 1240 def remove_dpg(dpg) begin dpg.item.Destroy_Task.wait_for_completion rescue RbVmomi::VIM::ResourceInUse STDERR.puts "The distributed portgroup \ #{dpg['name']} is in use so it cannot be deleted" nil rescue StandardError => e raise "The Distributed portgroup #{dpg['name']} \ could not be deleted. Reason: #{e.message} " end end
remove_dvs(dvs)
click to toggle source
Remove a distributed vcenter switch in a datacenter
# File lib/datacenter.rb, line 1037 def remove_dvs(dvs) begin dvs.item.Destroy_Task.wait_for_completion rescue StandardError # Ignore destroy task exception end end
unlock()
click to toggle source
Unlock driver execution mutex
# File lib/datacenter.rb, line 880 def unlock return unless @locking @locking_file.close end
update_dpg(dpg, vlan_id, num_ports)
click to toggle source
Update a distributed vcenter port group
# File lib/datacenter.rb, line 1173 def update_dpg(dpg, vlan_id, num_ports) spec = RbVmomi::VIM::DVPortgroupConfigSpec.new changed = false orig_spec = RbVmomi::VIM::DVPortgroupConfigSpec.new orig_spec.numPorts = dpg['config.numPorts'] orig_spec.defaultPortConfig = RbVmomi::VIM::VMwareDVSPortSetting.new orig_spec.defaultPortConfig.vlan = RbVmomi::VIM::VmwareDistributedVirtualSwitchVlanIdSpec.new orig_spec.defaultPortConfig.vlan.vlanId = dpg['config.defaultPortConfig.vlan.vlanId'] orig_spec.defaultPortConfig.vlan.inherited = false if num_ports && num_ports != orig_spec.numPorts spec.numPorts = num_ports changed = true end # earlyBinding. A free DistributedVirtualPort # will be selected and # assigned to a VirtualMachine when # the virtual machine is reconfigured # to connect to the portgroup. spec.type = 'earlyBinding' if vlan_id != orig_spec.defaultPortConfig.vlan.vlanId spec.defaultPortConfig = RbVmomi::VIM::VMwareDVSPortSetting.new spec.defaultPortConfig.vlan = RbVmomi::VIM::VmwareDistributedVirtualSwitchVlanIdSpec.new spec.defaultPortConfig.vlan.vlanId = vlan_id spec.defaultPortConfig.vlan.inherited = false changed = true end return unless changed spec.configVersion = dpg['config.configVersion'] begin dpg .item .ReconfigureDVPortgroup_Task( :spec => spec ).wait_for_completion rescue StandardError => e raise "The Distributed port group #{dpg['name']} \ could not be created. "\ "Reason: #{e.message}" end @net_rollback << { :action => :update_dpg, :dpg => dpg.item, :name => dpg['name'], :spec => orig_spec } end
update_dvs(dvs, pnics, mtu)
click to toggle source
Update a distributed vcenter switch
# File lib/datacenter.rb, line 966 def update_dvs(dvs, pnics, mtu) # Prepare spec for DVS creation spec = RbVmomi::VIM::VMwareDVSConfigSpec.new changed = false orig_spec = RbVmomi::VIM::VMwareDVSConfigSpec.new orig_spec.maxMtu = dvs['config.maxMtu'] orig_spec.uplinkPortPolicy = RbVmomi::VIM::DVSNameArrayUplinkPortPolicy.new orig_spec.uplinkPortPolicy.uplinkPortName = [] (0..dvs['config.uplinkPortgroup'].length-1).each do |index| orig_spec .uplinkPortPolicy .uplinkPortName[index]="dvUplink#{index+1}" end # Add more uplinks to default uplink # port group according to number of pnics if pnics pnics = pnics.split(',') if !pnics.empty? && dvs['config.uplinkPortgroup'] .length != pnics.size spec.uplinkPortPolicy = RbVmomi::VIM::DVSNameArrayUplinkPortPolicy.new spec.uplinkPortPolicy.uplinkPortName = [] (dvs['config.uplinkPortgroup'] .length..num_pnics-1) .each do |index| spec .uplinkPortPolicy .uplinkPortName[index] = "dvUplink#{index+1}" end changed = true end end # Set maximum MTU if mtu != dvs['config.maxMtu'] spec.maxMtu = mtu changed = true end # The DVS must be created in the networkFolder of the datacenter return unless changed spec.configVersion = dvs['config.configVersion'] begin dvs .item .ReconfigureDvs_Task( :spec => spec ).wait_for_completion rescue StandardError => e raise "The Distributed switch #{dvs['name']} could \ not be updated. "\ "Reason: #{e.message}" end @net_rollback << { :action => :update_dvs, :dvs => dvs.item, :name => dvs['name'], :spec => orig_spec } end
vm_folder()
click to toggle source
# File lib/datacenter.rb, line 860 def vm_folder VirtualMachineFolder.new(@item.vmFolder) end