Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support nested host folders in find_cluster() #1

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion lib/vmpooler/providers/vsphere.rb
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,20 @@ def find_least_used_host(cluster, connection, datacentername)
def find_cluster(cluster, connection, datacentername)
datacenter = connection.serviceInstance.find_datacenter(datacentername)
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

def get_cluster_host_utilization(cluster, model = nil)
Expand Down
28 changes: 27 additions & 1 deletion spec/rbvmomi_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,29 @@
# 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
Expand Down Expand Up @@ -384,6 +406,10 @@ def mock_RbVmomi_VIM_ComputeResource(options = {})
mock.host << mock_host
end

allow(mock).to receive(:is_a?) do |expected_type|
expected_type == RbVmomi::VIM::ComputeResource
end

mock
end

Expand Down
52 changes: 40 additions & 12 deletions spec/unit/providers/vsphere_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2887,6 +2887,7 @@

describe '#find_cluster' do
let(:cluster) {'cluster'}
let(:host) { 'host' }
let(:missing_cluster) {'missing_cluster'}

context 'no clusters in the datacenter' do
Expand All @@ -2909,10 +2910,11 @@
:datacenters => [
{ :name => datacenter_name,
:hostfolder_tree => {
'cluster1' => {:object_type => 'compute_resource'},
'cluster2' => {:object_type => 'compute_resource'},
cluster => {:object_type => 'compute_resource'},
'cluster3' => {:object_type => 'compute_resource'},
'cluster1' => {:object_type => 'cluster_compute_resource'},
'cluster2' => {:object_type => 'cluster_compute_resource'},
cluster => {:object_type => 'cluster_compute_resource'},
'cluster3' => {:object_type => 'cluster_compute_resource'},
host => {:object_type => 'compute_resource'},
}
}
]
Expand All @@ -2926,6 +2928,13 @@
expect(result.name).to eq(cluster)
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
expect(subject.find_cluster(missing_cluster,connection,datacenter_name)).to be_nil
end
Expand All @@ -2937,14 +2946,15 @@
:datacenters => [
{ :name => 'AnotherDC',
:hostfolder_tree => {
'cluster1' => {:object_type => 'compute_resource'},
'cluster2' => {:object_type => 'compute_resource'},
'cluster1' => {:object_type => 'cluster_compute_resource'},
'cluster2' => {:object_type => 'cluster_compute_resource'},
}
},
{ :name => datacenter_name,
:hostfolder_tree => {
cluster => {:object_type => 'compute_resource'},
'cluster3' => {:object_type => 'compute_resource'},
cluster => {:object_type => 'cluster_compute_resource'},
'cluster3' => {:object_type => 'cluster_compute_resource'},
host => {:object_type => 'compute_resource'}
}
}
]
Expand All @@ -2958,6 +2968,13 @@
expect(result.name).to eq(cluster)
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
expect(subject.find_cluster(missing_cluster,connection,'AnotherDC')).to be_nil
end
Expand All @@ -2969,27 +2986,38 @@
:datacenters => [
{ :name => datacenter_name,
:hostfolder_tree => {
'cluster1' => {:object_type => 'compute_resource'},
'cluster1' => {:object_type => 'cluster_compute_resource'},
'folder2' => {
: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'},
}
}
}
}
]
}
}}

it 'should return the cluster when found' do
pending('https://github.com/puppetlabs/vmpooler/issues/205')
result = subject.find_cluster(cluster,connection,datacenter_name)

expect(result).to_not be_nil
expect(result.name).to eq(cluster)
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
expect(subject.find_cluster(missing_cluster,connection,datacenter_name)).to be_nil
end
Expand Down