Support nested host folders in find_cluster()

Search the root and any subfolders for cluster or host resources.
This commit is contained in:
Sean Millichamp 2019-11-26 13:48:53 -05:00
parent 114cb9f398
commit f6fdfe42d7
3 changed files with 81 additions and 14 deletions

View file

@ -839,7 +839,20 @@ module Vmpooler
def find_cluster(cluster, connection, datacentername) def find_cluster(cluster, connection, datacentername)
datacenter = connection.serviceInstance.find_datacenter(datacentername) datacenter = connection.serviceInstance.find_datacenter(datacentername)
raise("Datacenter #{datacentername} does not exist") if datacenter.nil? raise("Datacenter #{datacentername} does not exist") if datacenter.nil?
datacenter.hostFolder.children.find { |cluster_object| cluster_object.name == cluster }
# In the event the cluster is not a direct descendent of the
# datacenter, we use a ContainerView to leverage its recursive
# search. This will find clusters which are, for example, in
# folders under the datacenter. This will also find standalone
# hosts which are not part of a cluster.
cv = connection.serviceContent.viewManager.CreateContainerView(
container: datacenter.hostFolder,
type: ['ComputeResource', 'ClusterComputeResource'],
recursive: true,
)
cluster = cv.view.find { |cluster_object| cluster_object.name == cluster }
cv.DestroyView
cluster
end end
def get_cluster_host_utilization(cluster, model = nil) def get_cluster_host_utilization(cluster, model = nil)

View file

@ -24,7 +24,29 @@ MockContainerView = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.view.ContainerView.html # https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.view.ContainerView.html
# From ContainerView # From ContainerView
:container, :recursive, :type :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( MockDatacenter = Struct.new(
# https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datacenter.html # https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Datacenter.html
@ -384,6 +406,10 @@ def mock_RbVmomi_VIM_ComputeResource(options = {})
mock.host << mock_host mock.host << mock_host
end end
allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::ComputeResource
end
mock mock
end end

View file

@ -2887,6 +2887,7 @@ EOT
describe '#find_cluster' do describe '#find_cluster' do
let(:cluster) {'cluster'} let(:cluster) {'cluster'}
let(:host) { 'host' }
let(:missing_cluster) {'missing_cluster'} let(:missing_cluster) {'missing_cluster'}
context 'no clusters in the datacenter' do context 'no clusters in the datacenter' do
@ -2909,10 +2910,11 @@ EOT
:datacenters => [ :datacenters => [
{ :name => datacenter_name, { :name => datacenter_name,
:hostfolder_tree => { :hostfolder_tree => {
'cluster1' => {:object_type => 'compute_resource'}, 'cluster1' => {:object_type => 'cluster_compute_resource'},
'cluster2' => {:object_type => 'compute_resource'}, 'cluster2' => {:object_type => 'cluster_compute_resource'},
cluster => {:object_type => 'compute_resource'}, cluster => {:object_type => 'cluster_compute_resource'},
'cluster3' => {:object_type => 'compute_resource'}, 'cluster3' => {:object_type => 'cluster_compute_resource'},
host => {:object_type => 'compute_resource'},
} }
} }
] ]
@ -2926,6 +2928,13 @@ EOT
expect(result.name).to eq(cluster) expect(result.name).to eq(cluster)
end end
it 'should return the single host when found' do
result = subject.find_cluster(host,connection,datacenter_name)
expect(result).to_not be_nil
expect(result.name).to eq(host)
end
it 'should return nil if the cluster is not found' do it 'should return nil if the cluster is not found' do
expect(subject.find_cluster(missing_cluster,connection,datacenter_name)).to be_nil expect(subject.find_cluster(missing_cluster,connection,datacenter_name)).to be_nil
end end
@ -2937,14 +2946,15 @@ EOT
:datacenters => [ :datacenters => [
{ :name => 'AnotherDC', { :name => 'AnotherDC',
:hostfolder_tree => { :hostfolder_tree => {
'cluster1' => {:object_type => 'compute_resource'}, 'cluster1' => {:object_type => 'cluster_compute_resource'},
'cluster2' => {:object_type => 'compute_resource'}, 'cluster2' => {:object_type => 'cluster_compute_resource'},
} }
}, },
{ :name => datacenter_name, { :name => datacenter_name,
:hostfolder_tree => { :hostfolder_tree => {
cluster => {:object_type => 'compute_resource'}, cluster => {:object_type => 'cluster_compute_resource'},
'cluster3' => {:object_type => 'compute_resource'}, 'cluster3' => {:object_type => 'cluster_compute_resource'},
host => {:object_type => 'compute_resource'}
} }
} }
] ]
@ -2958,6 +2968,13 @@ EOT
expect(result.name).to eq(cluster) expect(result.name).to eq(cluster)
end end
it 'should return the single host when found' do
result = subject.find_cluster(host,connection,datacenter_name)
expect(result).to_not be_nil
expect(result.name).to eq(host)
end
it 'should return nil if the cluster is not found' do it 'should return nil if the cluster is not found' do
expect(subject.find_cluster(missing_cluster,connection,'AnotherDC')).to be_nil expect(subject.find_cluster(missing_cluster,connection,'AnotherDC')).to be_nil
end end
@ -2969,13 +2986,18 @@ EOT
:datacenters => [ :datacenters => [
{ :name => datacenter_name, { :name => datacenter_name,
:hostfolder_tree => { :hostfolder_tree => {
'cluster1' => {:object_type => 'compute_resource'}, 'cluster1' => {:object_type => 'cluster_compute_resource'},
'folder2' => { 'folder2' => {
:children => { :children => {
cluster => {:object_type => 'compute_resource'}, cluster => {:object_type => 'cluster_compute_resource'},
} }
}, },
'cluster3' => {:object_type => 'compute_resource'}, 'cluster3' => {:object_type => 'cluster_compute_resource'},
'folder4' => {
:children => {
host => {:object_type => 'compute_resource'},
}
}
} }
} }
] ]
@ -2983,13 +3005,19 @@ EOT
}} }}
it 'should return the cluster when found' do it 'should return the cluster when found' do
pending('https://github.com/puppetlabs/vmpooler/issues/205')
result = subject.find_cluster(cluster,connection,datacenter_name) result = subject.find_cluster(cluster,connection,datacenter_name)
expect(result).to_not be_nil expect(result).to_not be_nil
expect(result.name).to eq(cluster) expect(result.name).to eq(cluster)
end end
it 'should return the host when found' do
result = subject.find_cluster(host,connection,datacenter_name)
expect(result).to_not be_nil
expect(result.name).to eq(host)
end
it 'should return nil if the cluster is not found' do it 'should return nil if the cluster is not found' do
expect(subject.find_cluster(missing_cluster,connection,datacenter_name)).to be_nil expect(subject.find_cluster(missing_cluster,connection,datacenter_name)).to be_nil
end end