Move vsphere provider to its own gem

This commit is contained in:
Gene Liverman 2021-11-29 16:09:15 -05:00
parent 48c5d6d445
commit d1c86eaf9b
No known key found for this signature in database
GPG key ID: 3AF83985B6C857C6
10 changed files with 21 additions and 5857 deletions

View file

@ -7,7 +7,6 @@ module Vmpooler
require 'net/ldap' require 'net/ldap'
require 'open-uri' require 'open-uri'
require 'pickup' require 'pickup'
require 'rbvmomi'
require 'redis' require 'redis'
require 'set' require 'set'
require 'sinatra/base' require 'sinatra/base'

View file

@ -628,7 +628,7 @@ module Vmpooler
end end
# @return [Array] - a list of used providers from the config file, defaults to the default providers # @return [Array] - a list of used providers from the config file, defaults to the default providers
# ie. ["vsphere", "dummy"] # ie. ["dummy"]
def used_providers def used_providers
pools = config[:pools] || [] pools = config[:pools] || []
@used_providers ||= (pools.map { |pool| pool[:provider] || pool['provider'] }.compact + default_providers).uniq @used_providers ||= (pools.map { |pool| pool[:provider] || pool['provider'] }.compact + default_providers).uniq
@ -638,7 +638,7 @@ module Vmpooler
# note: vsphere is the default if user does not specify although this should not be # note: vsphere is the default if user does not specify although this should not be
# if vsphere is to no longer be loaded by default please remove # if vsphere is to no longer be loaded by default please remove
def default_providers def default_providers
@default_providers ||= %w[vsphere dummy] @default_providers ||= %w[dummy]
end end
def get_pool_name_for_vm(vm_name, redis) def get_pool_name_for_vm(vm_name, redis)
@ -1561,8 +1561,8 @@ module Vmpooler
# Set default provider for all pools that do not have one defined # Set default provider for all pools that do not have one defined
$config[:pools].each do |pool| $config[:pools].each do |pool|
if pool['provider'].nil? if pool['provider'].nil?
$logger.log('d', "[!] Setting provider for pool '#{pool['name']}' to 'vsphere' as default") $logger.log('d', "[!] Setting provider for pool '#{pool['name']}' to 'dummy' as default")
pool['provider'] = 'vsphere' pool['provider'] = 'dummy'
end end
end end

File diff suppressed because it is too large Load diff

View file

@ -1,98 +0,0 @@
#!/usr/bin/ruby
require 'rubygems'
require 'rbvmomi'
require 'yaml'
def load_configuration( file_array )
file_array.each do |file|
file = File.expand_path( file )
if File.exists?( file )
return YAML.load_file( file )
end
end
return false
end
def create_template_deltas( folder )
config = load_configuration( [ 'vmpooler.yaml', '~/.vmpooler' ] ) || nil
abort 'No config file (./vmpooler.yaml or ~/.vmpooler) found!' unless config
vim = RbVmomi::VIM.connect(
:host => config[ :providers ][ :vsphere ][ "server" ],
:user => config[ :providers ][ :vsphere ][ "username" ],
:password => config[ :providers ][ :vsphere ][ "password" ],
:ssl => true,
:insecure => true,
) or abort "Unable to connect to #{config[ :vsphere ][ "server" ]}!"
containerView = vim.serviceContent.viewManager.CreateContainerView( {
:container => vim.serviceContent.rootFolder,
:recursive => true,
:type => [ 'VirtualMachine' ]
} )
datacenter = vim.serviceInstance.find_datacenter
base = datacenter.vmFolder
case base
when RbVmomi::VIM::Folder
base = base.childEntity.find { |f| f.name == folder }
else
abort "Unexpected object type encountered (#{base.class}) while finding folder!"
end
unless base
abort "Folder #{ARGV[0]} not found!"
end
base.childEntity.each do |vm|
print vm.name
begin
disks = vm.config.hardware.device.grep( RbVmomi::VIM::VirtualDisk )
rescue
puts ' !'
next
end
begin
disks.select { |d| d.backing.parent == nil }.each do |disk|
linkSpec = {
:deviceChange => [
{
:operation => :remove,
:device => disk
},
{
:operation => :add,
:fileOperation => :create,
:device => disk.dup.tap { |x|
x.backing = x.backing.dup
x.backing.fileName = "[#{disk.backing.datastore.name}]"
x.backing.parent = disk.backing
}
}
]
}
vm.ReconfigVM_Task( :spec => linkSpec ).wait_for_completion
end
puts " \u2713"
rescue
puts ' !'
end
end
vim.close
end
if ARGV[0]
create_template_deltas( ARGV[0] )
else
puts "Usage: #{$0} <folder>"
end

View file

@ -1,922 +0,0 @@
# -----------------------------------------------------------------------------------------------------------------
# Managed Objects (https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/index-mo_types.html)
# -----------------------------------------------------------------------------------------------------------------
MockClusterComputeResource = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.ClusterComputeResource.html
# From MockClusterComputeResource
:actionHistory, :configuration, :drsFault, :drsRecommendation, :migrationHistory, :recommendation,
# From ComputeResource
:resourcePool,
# From ManagedEntity
:name
)
MockComputeResource = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ComputeResource.html
# From ComputeResource
:configurationEx, :datastore, :host, :network, :resourcePool, :summary,
# From ManagedEntity
:name
)
MockContainerView = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.view.ContainerView.html
# From ContainerView
:container, :recursive, :type
) do
def _search_tree(layer)
results = []
layer.children.each do |child|
if type.any? { |t| child.is_a?(RbVmomi::VIM.const_get(t)) }
results << child
end
if recursive && child.respond_to?(:children)
results += _search_tree(child)
end
end
results
end
def view
_search_tree(container)
end
def DestroyView
end
end
MockDatacenter = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datacenter.html
# From Datacenter
:datastore, :datastoreFolder, :hostFolder, :network, :networkFolder, :vmFolder,
# From ManagedEntity
:name
) do
# From RBVMOMI::VIM::Datacenter https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim/Datacenter.rb
# Find the Datastore with the given +name+.
def find_datastore name
datastore.find { |x| x.name == name }
end
end
MockNetwork = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Network.html
# From Network
:host, :name, :summary, :vm
)
MockVirtualVmxnet3 = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualVmxnet.html
# From VirtualEthenetCard
:addressType,
# From VirtualDevice
:key, :deviceInfo, :backing, :connectable
)
MockDatastore = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datastore.html
# From Datastore
:browser, :capability, :host, :info, :iormConfiguration, :summary, :vm,
# From ManagedEntity
:name
)
MockFolder = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Folder.html
# From Folder
:childEntity, :childType,
# From ManagedEntity
:name
) do
# From RBVMOMI::VIM::Folder https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim/Folder.rb#L107-L110
def children
childEntity
end
# https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim/Folder.rb#L9-L12
def find(name, type=Object)
# Fake the searchIndex
childEntity.each do |child|
if child.name == name
if child.kind_of?(type)
return child
else
return nil
end
end
end
nil
end
end
MockHostSystem = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.HostSystem.html
# From HostSystem
:capability, :config, :configManager, :datastore, :datastoreBrowser, :hardware, :network, :runtime, :summary, :systemResources, :vm,
# From ManagedEntity
:overallStatus, :name, :parent,
# From ManagedObject
:configIssue
)
MockPropertyCollector = Struct.new(
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.html
# PropertyCollector
:filter
)
MockResourcePool = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.ResourcePool.html
# From ResourcePool
:childConfiguration, :config, :owner, :resourcePool, :runtime, :summary, :vm,
# From ManagedEntity
:name
)
MockSearchIndex = Object
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.SearchIndex.html
MockServiceInstance = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ServiceInstance.html
# From ServiceInstance
:capability, :content, :serverClock
) do
# From ServiceInstance
# Mock the CurrentTime method so that it appears the ServiceInstance is valid.
def CurrentTime
Time.now
end
# From RBVMOMI::VIM::ServiceInstance https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim/ServiceInstance.rb
def find_datacenter(path=nil)
# In our mocked instance, DataCenters are always in the root Folder.
# If path is nil the first DC is returned otherwise match by name
content.rootFolder.childEntity.each do |child|
if child.is_a?(RbVmomi::VIM::Datacenter)
return child if path.nil? || child.name == path
end
end
nil
end
end
MockTask = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.Task.html
# From Task
:info,
) do
# From RBVMOMI https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim/Task.rb
# Mock the with 'Not Implemented'
def wait_for_completion
raise(RuntimeError,'Not Implemented')
end
end
MockViewManager = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.view.ViewManager.html
# From ViewManager
:viewList,
) do
# From ViewManager
def CreateContainerView(options)
mock_RbVmomi_VIM_ContainerView({
:container => options[:container],
:recursive => options[:recursive],
:type => options[:type],
})
end
end
MockVirtualDiskManager = Object
# https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.VirtualDiskManager.html
MockVirtualMachine = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.VirtualMachine.html
# From VirtualMachine
:config, :runtime, :snapshot, :summary,
# From ManagedEntity
:name,
# From RbVmomi::VIM::ManagedEntity
# https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim/ManagedEntity.rb
:path
)
MockVirtualMachineSnapshot = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.Snapshot.html
# From VirtualMachineSnapshot
:config
)
# -------------------------------------------------------------------------------------------------------------
# Data Objects (https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/index-do_types.html)
# -------------------------------------------------------------------------------------------------------------
MockDescription = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.Description.html
# From Description
:label, :summary
)
MockVirtualEthernetCardNetworkBackingInfo = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualEthernetCard.NetworkBackingInfo.html
# From VirtualEthernetCardNetworkBackingInfo
:network,
# From VirtualDeviceBackingInfo
:deviceName, :useAutoDetect
)
MockVirtualDeviceConnectInfo = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualDevice.ConnectInfo.html
# From VirtualDeviceConnectInfo
:allowGuestControl, :connected, :startConnected
)
MockVirtualMachineConfigSpec = Struct.new(
# https://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.ConfigSpec.html
# From VirtualMachineConfigSpec
:deviceChange, :annotation, :extraConfig
)
MockVirtualMachineRelocateSpec = Struct.new(
# https://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.RelocateSpec.html
# From VirtualMachineRelocateSpec
:datastore, :diskMoveType, :pool
)
MockDynamicProperty = Struct.new(
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.DynamicProperty.html
# From DynamicProperty
:name, :val
)
MockHostCpuPackage = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.CpuPackage.html
# From HostCpuPackage
:busHz, :cpuFeature, :description, :hz, :index, :threadId, :vendor
)
MockHostHardwareSummary = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.Summary.HardwareSummary.html
# From HostHardwareSummary
:cpuMhz, :numCpuCores, :numCpuPkgs, :memorySize
)
MockHostListSummary = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.Summary.html
# From HostListSummary
:quickStats, :hardware
)
MockHostListSummaryQuickStats = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.Summary.QuickStats.html
# From HostListSummaryQuickStats
:overallCpuUsage, :overallMemoryUsage
)
MockHostRuntimeInfo = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.RuntimeInfo.html
# From HostRuntimeInfo
:bootTime, :connectionState, :healthSystemRuntime, :inMaintenanceMode, :powerState, :tpmPcrValues
)
MockHostSystemHostHardwareInfo = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.HardwareInfo.html
# From HostHardwareInfo
:biosInfo, :cpuFeature, :cpuInfo, :cpuPkg, :cpuPowerManagementInfo, :memorySize, :numaInfo, :pciDevice, :systemInfo
)
MockObjectContent = Struct.new(
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.ObjectContent.html
# From ObjectContent
:missingSet, :obj, :propSet
)
MockRetrieveResult = Struct.new(
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.RetrieveResult.html
# From RetrieveResult
:objects, :token
)
MockServiceContent = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.ServiceInstanceContent.html#field_detail
# From ServiceContent
:propertyCollector, :rootFolder, :searchIndex, :viewManager, :virtualDiskManager
)
MockVirtualDevice = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualDevice.html
# From VirtualDevice
:deviceInfo, :controllerKey, :key, :backing, :connectable, :unitNumber
)
MockVirtualDisk = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualDisk.html
# From VirtualDisk
:capacityInKB, :shares,
# From VirtualDevice
:deviceInfo, :controllerKey, :key, :backing, :connectable, :unitNumber
)
MockVirtualHardware = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.VirtualHardware.html
# From VirtualHardware
:device
)
MockVirtualMachineConfigInfo = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.ConfigInfo.html
# From VirtualMachineConfigInfo
:hardware
)
MockVirtualMachineFileLayoutExFileInfo = Struct.new(
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.vm.FileLayoutEx.FileInfo.html
# From VirtualMachineFileLayoutExFileInfo
:key, :name, :size, :type, :uniqueSize
)
MockVirtualMachineGuestSummary = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.Summary.GuestSummary.html
# From VirtualMachineGuestSummary
:hostName
)
MockVirtualMachineRuntimeInfo = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.RuntimeInfo.html
# From VirtualMachineRuntimeInfo
:bootTime, :cleanPowerOff, :connectionState, :faultToleranceState, :host, :maxCpuUsage, :maxMemoryUsage, :memoryOverhead,
:needSecondaryReason, :numMksConnections, :powerState, :question, :recordReplayState, :suspendInterval, :suspendTime, :toolsInstallerMounted
)
MockVirtualMachineSnapshotInfo = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.SnapshotInfo.html
# From MockVirtualMachineSnapshotInfo
:currentSnapshot, :rootSnapshotList
)
MockVirtualMachineSnapshotTree = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.SnapshotTree.html
# From VirtualMachineSnapshotTree
:backupManifest, :childSnapshotList, :createTime, :description, :id, :name, :quiesced, :replaySupported,
:snapshot, :state, :vm
)
MockVirtualMachineSummary = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.Summary.html
# From VirtualMachineSummary
:config, :customValue, :guest, :quickStats, :runtime, :storage, :vm
)
MockVirtualSCSIController = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualSCSIController.html
# From VirtualSCSIController
:hotAddRemove, :scsiCtlrUnitNumber, :sharedBus,
# From VirtualDevice
:deviceInfo, :controllerKey, :key, :backing, :connectable, :unitNumber
)
# --------------------
# RBVMOMI only Objects
# --------------------
MockRbVmomiVIMConnection = Struct.new(
# https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim.rb
:serviceInstance, :serviceContent, :rootFolder, :root
) do
# From https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim.rb
# Alias to serviceContent.searchIndex
def searchIndex
serviceContent.searchIndex
end
# Alias to serviceContent.propertyCollector
def propertyCollector
serviceContent.propertyCollector
end
end
# -------------------------------------------------------------------------------------------------------------
# Mocking Methods
# -------------------------------------------------------------------------------------------------------------
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.ClusterComputeResource.html
def mock_RbVmomi_VIM_ClusterComputeResource(options = {})
options[:name] = 'Cluster' + rand(65536).to_s if options[:name].nil?
mock = MockClusterComputeResource.new()
mock.name = options[:name]
# All cluster compute resources have a root Resource Pool
mock.resourcePool = mock_RbVmomi_VIM_ResourcePool({:name => options[:name]})
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::ClusterComputeResource
end
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.view.ContainerView.html
def mock_RbVmomi_VIM_ContainerView(options = {})
mock = MockContainerView.new()
mock.container = options[:container]
mock.recursive = options[:recursive]
mock.type = options[:type]
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ComputeResource.html
def mock_RbVmomi_VIM_ComputeResource(options = {})
options[:name] = 'Compute' + rand(65536).to_s if options[:name].nil?
options[:hosts] = [{}] if options[:hosts].nil?
mock = MockComputeResource.new()
mock.name = options[:name]
mock.host = []
# A compute resource must have at least one host.
options[:hosts].each do |host_options|
mock_host = mock_RbVmomi_VIM_HostSystem(host_options)
mock_host.parent = mock
mock.host << mock_host
end
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::ComputeResource
end
mock
end
# https://github.com/vmware/rbvmomi/blob/master/lib/rbvmomi/vim.rb
def mock_RbVmomi_VIM_Connection(options = {})
options[:serviceInstance] = {} if options[:serviceInstance].nil?
options[:serviceContent] = {} if options[:serviceContent].nil?
mock = MockRbVmomiVIMConnection.new()
mock.serviceContent = mock_RbVmomi_VIM_ServiceContent(options[:serviceContent])
options[:serviceInstance][:servicecontent] = mock.serviceContent if options[:serviceInstance][:servicecontent].nil?
mock.serviceInstance = mock_RbVmomi_VIM_ServiceInstance(options[:serviceInstance])
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datastore.html
def mock_RbVmomi_VIM_Datacenter(options = {})
options[:hostfolder_tree] = {} if options[:hostfolder_tree].nil?
options[:vmfolder_tree] = {} if options[:vmfolder_tree].nil?
# Currently don't support mocking datastore tree
options[:datastores] = [] if options[:datastores].nil?
options[:name] = 'Datacenter' + rand(65536).to_s if options[:name].nil?
options[:networks] = [] if options[:networks].nil?
mock = MockDatacenter.new()
mock.name = options[:name]
mock.hostFolder = mock_RbVmomi_VIM_Folder({ :name => 'hostFolderRoot'})
mock.vmFolder = mock_RbVmomi_VIM_Folder({ :name => 'vmFolderRoot'})
mock.datastore = []
mock.network = []
# Create vmFolder hierarchy
recurse_folder_tree(options[:vmfolder_tree],mock.vmFolder.childEntity)
# Create hostFolder hierarchy
recurse_folder_tree(options[:hostfolder_tree],mock.hostFolder.childEntity)
# Create mock Datastores
options[:datastores].each do |datastorename|
mock_ds = mock_RbVmomi_VIM_Datastore({ :name => datastorename })
mock.datastore << mock_ds
end
# Create mock Networks
options[:networks].each do |networkname|
mock_nw = mock_RbVmomi_VIM_Network({ :name => networkname })
mock.network << mock_nw
end
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::Datacenter
end
mock
end
def recurse_folder_tree(tree, root_object)
tree.keys.each do |foldername|
folder_options = tree[foldername].nil? ? {} : tree[foldername]
folder_options[:name] = foldername if folder_options[:name].nil?
case folder_options[:object_type]
when 'vm'
child_object = mock_RbVmomi_VIM_VirtualMachine({ :name => folder_options[:name]})
when 'compute_resource'
child_object = mock_RbVmomi_VIM_ComputeResource({ :name => folder_options[:name]})
when 'cluster_compute_resource'
child_object = mock_RbVmomi_VIM_ClusterComputeResource({ :name => folder_options[:name]})
when 'resource_pool'
child_object = mock_RbVmomi_VIM_ResourcePool({ :name => folder_options[:name]})
else
child_object = mock_RbVmomi_VIM_Folder({:name => foldername})
end
# Recursively create children - Default is the child_object is a Folder
case folder_options[:object_type]
when 'cluster_compute_resource'
# Append children into the root Resource Pool for a cluster, instead of directly into the cluster itself.
recurse_folder_tree(folder_options[:children],child_object.resourcePool.resourcePool) unless folder_options[:children].nil?
when 'resource_pool'
recurse_folder_tree(folder_options[:children],child_object.resourcePool) unless folder_options[:children].nil?
else
recurse_folder_tree(folder_options[:children],child_object.childEntity) unless folder_options[:children].nil?
end
root_object << child_object
end
end
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datastore.html
def mock_RbVmomi_VIM_Datastore(options = {})
options[:name] = 'Datastore' + rand(65536).to_s if options[:name].nil?
mock = MockDatastore.new()
mock.name = options[:name]
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::Datastore
end
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Network.html
def mock_RbVmomi_VIM_Network(options = {})
options[:name] = 'Network' + rand(65536).to_s if options[:name].nil?
mock = MockNetwork.new()
mock.name = options[:name]
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::Network
end
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualVmxnet3.html
def mock_RbVmomi_VIM_VirtualVmxnet3(options = {})
options[:key] = rand(65536) if options[:key].nil?
options[:deviceInfo] = MockDescription.new()
options[:backing] = MockVirtualEthernetCardNetworkBackingInfo.new()
options[:addressType] = 'assigned'
options[:connectable] = MockVirtualDeviceConnectInfo.new()
mock = MockVirtualVmxnet3.new()
mock.key = options[:key]
mock.deviceInfo = options[:deviceInfo]
mock.backing = options[:backing]
mock.addressType = options[:addressType]
mock.connectable = options[:connectable]
allow(mock).to receive(:instance_of?) do |expected_type|
expected_type == RbVmomi::VIM::VirtualVmxnet3
end
mock
end
# https://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.RelocateSpec.html
def mock_RbVmomi_VIM_VirtualMachineRelocateSpec(options = {})
options[:datastore] = 'Datastore' + rand(65536).to_s if options[:datastore].nil?
options[:diskMoveType] = :moveChildMostDiskBacking
options[:pool] = 'Pool' + rand(65536).to_s if options[:pool].nil?
mock = MockVirtualMachineRelocateSpec.new
mock.datastore = mock_RbVmomi_VIM_Datastore({ :name => options[:datastore]})
mock.diskMoveType = options[:diskMoveType]
mock.pool = mock_RbVmomi_VIM_ResourcePool({:name => options[:pool]})
allow(mock).to receive(:is_a?).and_return(RbVmomi::VIM::VirtualMachineRelocateSpec)
mock
end
# https://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.ConfigSpec.html
def mock_RbVmomi_VIM_VirtualMachineConfigSpec(options = {})
options[:device] = mock_RbVmomi_VIM_VirtualVmxnet3()
mock = MockVirtualMachineConfigSpec.new
mock.deviceChange = []
mock.deviceChange << { operation: :edit, device: options[:device]}
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datastore.html
def mock_RbVmomi_VIM_Folder(options = {})
options[:name] = 'Folder' + rand(65536).to_s if options[:name].nil?
mock = MockFolder.new()
mock.name = options[:name]
mock.childEntity = []
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::Folder
end
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.HostSystem.html
def mock_RbVmomi_VIM_HostSystem(options = {})
options[:memory_size] = 4294967296 if options[:memory_size].nil? # 4GB RAM
options[:num_cpu] = 1 if options[:num_cpu].nil?
options[:num_cores_per_cpu] = 1 if options[:num_cores_per_cpu].nil?
options[:cpu_speed] = 2048 if options[:cpu_speed].nil? # 2.0 GHz
options[:cpu_model] = 'Intel(R) Xeon(R) CPU E5-2697 v4 @ 2.0GHz' if options[:cpu_model].nil?
options[:maintenance_mode] = false if options[:maintenance_mode].nil?
options[:overall_status] = 'green' if options[:overall_status].nil?
options[:overall_cpu_usage] = 1 if options[:overall_cpu_usage].nil?
options[:overall_memory_usage] = 1 if options[:overall_memory_usage].nil?
options[:name] = 'HOST' + rand(65536).to_s if options[:name].nil?
options[:config_issue] = [] if options[:config_issue].nil?
mock = MockHostSystem.new()
mock.name = options[:name]
mock.summary = MockHostListSummary.new()
mock.summary.quickStats = MockHostListSummaryQuickStats.new()
mock.summary.hardware = MockHostHardwareSummary.new()
mock.hardware = MockHostSystemHostHardwareInfo.new()
mock.runtime = MockHostRuntimeInfo.new()
mock.hardware.cpuPkg = []
(1..options[:num_cpu]).each do |cpuid|
mockcpu = MockHostCpuPackage.new()
mockcpu.hz = options[:cpu_speed] * 1024 * 1024
mockcpu.description = options[:cpu_model]
mockcpu.index = 0
mock.hardware.cpuPkg << mockcpu
end
mock.runtime.inMaintenanceMode = options[:maintenance_mode]
mock.overallStatus = options[:overall_status]
mock.configIssue = options[:config_issue]
mock.summary.hardware.memorySize = options[:memory_size]
mock.hardware.memorySize = options[:memory_size]
mock.summary.hardware.cpuMhz = options[:cpu_speed]
mock.summary.hardware.numCpuCores = options[:num_cpu] * options[:num_cores_per_cpu]
mock.summary.hardware.numCpuPkgs = options[:num_cpu]
mock.summary.quickStats.overallCpuUsage = options[:overall_cpu_usage]
mock.summary.quickStats.overallMemoryUsage = options[:overall_memory_usage]
mock
end
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.RetrieveResult.html
def mock_RbVmomi_VIM_RetrieveResult(options = {})
options[:response] = [] if options[:response].nil?
mock = MockRetrieveResult.new()
mock.objects = []
options[:response].each do |response|
mock_objectdata = MockObjectContent.new()
mock_objectdata.propSet = []
mock_objectdata.obj = response[:object]
# Mock the object properties
response.each do |key,value|
unless key == :object
mock_property = MockDynamicProperty.new()
mock_property.name = key
mock_property.val = value
mock_objectdata.propSet << mock_property
end
end
mock.objects << mock_objectdata
end
mock
end
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.html
def mock_RbVmomi_VIM_PropertyCollector(options = {})
mock = MockPropertyCollector.new()
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.ServiceInstanceContent.html#field_detail
def mock_RbVmomi_VIM_ServiceContent(options = {})
options[:propertyCollector] = {} if options[:propertyCollector].nil?
options[:datacenters] = [] if options[:datacenters].nil?
mock = MockServiceContent.new()
mock.searchIndex = MockSearchIndex.new()
mock.viewManager = MockViewManager.new()
mock.virtualDiskManager = MockVirtualDiskManager.new()
mock.rootFolder = mock_RbVmomi_VIM_Folder({ :name => 'RootFolder' })
mock.propertyCollector = mock_RbVmomi_VIM_PropertyCollector(options[:propertyCollector])
# Create the DCs in this ServiceContent
options[:datacenters].each do |dc_options|
mock_dc = mock_RbVmomi_VIM_Datacenter(dc_options)
mock.rootFolder.childEntity << mock_dc
end
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ServiceInstance.html
def mock_RbVmomi_VIM_ServiceInstance(options = {})
mock = MockServiceInstance.new()
mock.content = options[:servicecontent]
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.Task.html
def mock_RbVmomi_VIM_Task(options = {})
mock = MockTask.new()
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.ResourcePool.html
def mock_RbVmomi_VIM_ResourcePool(options = {})
options[:name] = 'ResourcePool' + rand(65536).to_s if options[:name].nil?
mock = MockResourcePool.new()
mock.name = options[:name]
mock.resourcePool = []
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::ResourcePool
end
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualDisk.html
def mock_RbVmomi_VIM_VirtualDisk(options = {})
options[:controllerKey] = rand(65536) if options[:controllerKey].nil?
options[:key] = rand(65536) if options[:key].nil?
options[:label] = 'SCSI' + rand(65536).to_s if options[:label].nil?
options[:unitNumber] = rand(65536) if options[:unitNumber].nil?
mock = MockVirtualDisk.new()
mock.deviceInfo = MockDescription.new()
mock.deviceInfo.label = options[:label]
mock.controllerKey = options[:controllerKey]
mock.key = options[:key]
mock.unitNumber = options[:unitNumber]
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::VirtualDisk
end
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.VirtualMachine.html
def mock_RbVmomi_VIM_VirtualMachine(options = {})
options[:snapshot_tree] = nil if options[:snapshot_tree].nil?
options[:name] = 'VM' + rand(65536).to_s if options[:name].nil?
options[:path] = [] if options[:path].nil?
mock = MockVirtualMachine.new()
mock.config = MockVirtualMachineConfigInfo.new()
mock.config.hardware = MockVirtualHardware.new([])
mock.summary = MockVirtualMachineSummary.new()
mock.summary.runtime = MockVirtualMachineRuntimeInfo.new()
mock.summary.guest = MockVirtualMachineGuestSummary.new()
mock.runtime = mock.summary.runtime
mock.name = options[:name]
mock.summary.guest.hostName = options[:hostname]
mock.runtime.bootTime = options[:boottime]
mock.runtime.powerState = options[:powerstate]
unless options[:snapshot_tree].nil?
mock.snapshot = MockVirtualMachineSnapshotInfo.new()
mock.snapshot.rootSnapshotList = []
index = 0
# Create a recursive snapshot tree
recurse_snapshot_tree(options[:snapshot_tree],mock.snapshot.rootSnapshotList,index)
end
# Create an array of items that describe the path of the VM from the root folder
# all the way to the VM itself
mock.path = []
options[:path].each do |path_item|
mock_item = nil
case path_item[:type]
when 'folder'
mock_item = mock_RbVmomi_VIM_Folder({ :name => path_item[:name] })
when 'datacenter'
mock_item = mock_RbVmomi_VIM_Datacenter({ :name => path_item[:name] })
else
raise("Unknown mock type #{path_item[:type]} for mock_RbVmomi_VIM_VirtualMachine")
end
mock.path << [mock_item,path_item[:name]]
end
mock.path << [mock,options[:name]]
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::VirtualMachine
end
mock
end
def recurse_snapshot_tree(tree, root_object, index)
tree.keys.each do |snapshotname|
snap_options = tree[snapshotname].nil? ? {} : tree[snapshotname]
snap = MockVirtualMachineSnapshotTree.new()
snap.id = index
snap.name = snapshotname
snap.childSnapshotList = []
snap.description = "Snapshot #{snapshotname}"
snap.snapshot = snap_options[:ref] unless snap_options[:ref].nil?
# Recursively create chilren
recurse_snapshot_tree(snap_options[:children],snap.childSnapshotList,index) unless snap_options[:children].nil?
root_object << snap
index += 1
end
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualDevice.html
def mock_RbVmomi_VIM_VirtualMachineDevice(options = {})
mock = MockVirtualDevice.new()
mock.deviceInfo = MockDescription.new()
mock.deviceInfo.label = options[:label]
mock
end
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.vm.FileLayoutEx.FileInfo.html
def mock_RbVmomi_VIM_VirtualMachineFileLayoutExFileInfo(options = {})
options[:key] = rand(65536).to_s if options[:key].nil?
mock = MockVirtualMachineFileLayoutExFileInfo.new()
mock.key = options[:key]
mock.name = options[:name]
mock.size = options[:size]
mock.type = options[:type]
mock.uniqueSize = options[:uniqueSize]
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.Snapshot.html
def mock_RbVmomi_VIM_VirtualMachineSnapshot(options = {})
mock = MockVirtualMachineSnapshot.new()
mock
end
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.vm.device.VirtualSCSIController.html
def mock_RbVmomi_VIM_VirtualSCSIController(options = {})
options[:controllerKey] = rand(65536) if options[:controllerKey].nil?
options[:key] = rand(65536) if options[:key].nil?
options[:label] = 'SCSI' + rand(65536).to_s if options[:label].nil?
options[:scsiCtlrUnitNumber] = 7 if options[:scsiCtlrUnitNumber].nil?
mock = MockVirtualSCSIController.new()
mock.deviceInfo = MockDescription.new()
mock.deviceInfo.label = options[:label]
mock.controllerKey = options[:controllerKey]
mock.key = options[:key]
mock.scsiCtlrUnitNumber = options[:scsiCtlrUnitNumber]
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::VirtualSCSIController
end
mock
end

View file

@ -3,8 +3,6 @@ SimpleCov.start do
add_filter '/spec/' add_filter '/spec/'
end end
require 'helpers' require 'helpers'
require 'rbvmomi_helper'
require 'rbvmomi'
require 'rspec' require 'rspec'
require 'vmpooler' require 'vmpooler'
require 'redis' require 'redis'

View file

@ -70,14 +70,13 @@ EOT
) )
} }
it do it do
files = ["#{project_root_dir}/lib/vmpooler/providers/vsphere.rb", files = ["#{project_root_dir}/lib/vmpooler/providers/dummy.rb"]
"#{project_root_dir}/lib/vmpooler/providers/dummy.rb"]
expect(subject.load_used_providers).to eq(files) expect(subject.load_used_providers).to eq(files)
end end
end end
it '#default_providers' do it '#default_providers' do
expect(subject.default_providers).to eq(['vsphere', 'dummy']) expect(subject.default_providers).to eq(['dummy'])
end end
describe '#check_pending_vm' do describe '#check_pending_vm' do
@ -2728,13 +2727,14 @@ EOT
:vsphere: {} :vsphere: {}
:pools: :pools:
- name: #{pool} - name: #{pool}
provider: 'vsphere'
- name: 'dummy' - name: 'dummy'
provider: 'vsphere' provider: 'vsphere'
EOT EOT
)} )}
it 'should call create_provider_object idempotently' do it 'should call create_provider_object idempotently' do
# Even though there are two pools using the vsphere provider (the default), it should only # Even though there are two pools using the vsphere provider, it should only
# create the provider object once. # create the provider object once.
expect(subject).to receive(:create_provider_object).with(Object, Object, Object, redis_connection_pool, 'vsphere', 'vsphere', Object).and_return(vsphere_provider) expect(subject).to receive(:create_provider_object).with(Object, Object, Object, redis_connection_pool, 'vsphere', 'vsphere', Object).and_return(vsphere_provider)
@ -2756,50 +2756,6 @@ EOT
end end
end end
context 'creating multiple vsphere Providers' do
let(:vsphere_provider) { double('vsphere_provider') }
let(:vsphere_provider2) { double('vsphere_provider') }
let(:provider1) { Vmpooler::PoolManager::Provider::Base.new(config, logger, metrics, redis_connection_pool, 'vsphere', provider_options) }
let(:provider2) { Vmpooler::PoolManager::Provider::Base.new(config, logger, metrics, redis_connection_pool, 'secondvsphere', provider_options) }
let(:config) {
YAML.load(<<-EOT
---
:providers:
:vsphere:
server: 'blah1'
provider_class: 'vsphere'
:secondvsphere:
server: 'blah2'
provider_class: 'vsphere'
:pools:
- name: #{pool}
provider: 'vsphere'
- name: 'secondpool'
provider: 'secondvsphere'
EOT
)}
it 'should call create_provider_object twice' do
# The two pools use a different provider name, but each provider_class is vsphere
expect(subject).to receive(:create_provider_object).with(Object, Object, Object, redis_connection_pool, "vsphere", "vsphere", Object).and_return(vsphere_provider)
expect(subject).to receive(:create_provider_object).with(Object, Object, Object, redis_connection_pool, "vsphere", "secondvsphere", Object).and_return(vsphere_provider2)
subject.execute!(1,0)
end
it 'should have vsphere providers with different servers' do
allow(subject).to receive(:get_provider_for_pool).with(pool).and_return(provider1)
result = subject.get_provider_for_pool(pool)
allow(provider1).to receive(:provider_config).and_call_original
expect(result.provider_config['server']).to eq('blah1')
allow(subject).to receive(:get_provider_for_pool).with('secondpool').and_return(provider2)
result = subject.get_provider_for_pool('secondpool')
allow(provider1).to receive(:provider_config).and_call_original
expect(result.provider_config['server']).to eq('blah2')
subject.execute!(1,0)
end
end
context 'modify configuration on startup' do context 'modify configuration on startup' do
context 'move vSphere configuration to providers location' do context 'move vSphere configuration to providers location' do
let(:config) { let(:config) {
@ -2830,7 +2786,7 @@ EOT
end end
context 'default to the vphere provider' do context 'default to the dummy provider' do
let(:config) { let(:config) {
YAML.load(<<-EOT YAML.load(<<-EOT
--- ---
@ -2841,18 +2797,18 @@ EOT
EOT EOT
)} )}
it 'should set providers with no provider to vsphere' do it 'should set providers with no provider to dummy' do
expect(subject.config[:pools][0]['provider']).to be_nil expect(subject.config[:pools][0]['provider']).to be_nil
expect(subject.config[:pools][1]['provider']).to eq('dummy') expect(subject.config[:pools][1]['provider']).to eq('dummy')
subject.execute!(1,0) subject.execute!(1,0)
expect(subject.config[:pools][0]['provider']).to eq('vsphere') expect(subject.config[:pools][0]['provider']).to eq('dummy')
expect(subject.config[:pools][1]['provider']).to eq('dummy') expect(subject.config[:pools][1]['provider']).to eq('dummy')
end end
it 'should log a message' do it 'should log a message' do
expect(logger).to receive(:log).with('d', "[!] Setting provider for pool '#{pool}' to 'vsphere' as default") expect(logger).to receive(:log).with('d', "[!] Setting provider for pool '#{pool}' to 'dummy' as default")
subject.execute!(1,0) subject.execute!(1,0)
end end

File diff suppressed because it is too large Load diff

View file

@ -12,12 +12,8 @@ describe 'providers' do
end end
it '#load_all_providers' do it '#load_all_providers' do
p = [ expect(Vmpooler::Providers.load_all_providers.join(', ')).to match(%r{#{project_root_dir}/lib/vmpooler/providers/base.rb})
File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'base.rb'), expect(Vmpooler::Providers.load_all_providers.join(', ')).to match(%r{#{project_root_dir}/lib/vmpooler/providers/dummy.rb})
File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'dummy.rb'),
File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'vsphere.rb')
]
expect(Vmpooler::Providers.load_all_providers).to match_array(p)
end end
it '#installed_providers' do it '#installed_providers' do
@ -30,21 +26,18 @@ describe 'providers' do
end end
it '#load_by_name' do it '#load_by_name' do
expect(Vmpooler::Providers.load_by_name('vsphere')).to eq([File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'vsphere.rb')]) expect(Vmpooler::Providers.load_by_name('dummy').join(', ')).to match(%r{#{project_root_dir}/lib/vmpooler/providers/dummy.rb})
expect(Vmpooler::Providers.load_by_name('dummy').join(', ')).to_not match(%r{,})
end end
it '#load only vpshere' do it '#load only dummy' do
expect(providers.load_from_gems('vsphere')).to eq([File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'vsphere.rb')]) expect(providers.load_from_gems('dummy').join(', ')).to match(%r{#{project_root_dir}/lib/vmpooler/providers/dummy.rb})
expect(providers.load_from_gems('dummy').join(', ')).to_not match(%r{,})
end end
it '#load all providers from gems' do it '#load all providers from gems' do
p = [ expect(providers.load_from_gems.join(', ')).to match(%r{#{project_root_dir}/lib/vmpooler/providers/base.rb})
File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'base.rb'), expect(providers.load_from_gems.join(', ')).to match(%r{#{project_root_dir}/lib/vmpooler/providers/dummy.rb})
File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'dummy.rb'),
File.join(project_root_dir, 'lib', 'vmpooler', 'providers', 'vsphere.rb')
]
expect(providers.load_from_gems).to match_array(p)
end end

View file

@ -32,7 +32,6 @@ Gem::Specification.new do |s|
s.add_dependency 'puma', '~> 5.0', '>= 5.0.4' s.add_dependency 'puma', '~> 5.0', '>= 5.0.4'
s.add_dependency 'rack', '~> 2.2' s.add_dependency 'rack', '~> 2.2'
s.add_dependency 'rake', '~> 13.0' s.add_dependency 'rake', '~> 13.0'
s.add_dependency 'rbvmomi', '>= 2.1', '< 4.0'
s.add_dependency 'redis', '~> 4.1' s.add_dependency 'redis', '~> 4.1'
s.add_dependency 'sinatra', '~> 2.0' s.add_dependency 'sinatra', '~> 2.0'
s.add_dependency 'spicy-proton', '~> 2.1' s.add_dependency 'spicy-proton', '~> 2.1'