VMware: Rewrite get_resource_pool method for correct resource_pool selection (#39792)

* rewrite get_resource_pool method for correct resource_pool selection
* only keep name if path is given for cluster, esxi_hostname or resource_pool
* Revert "only keep name if path is given for cluster, esxi_hostname or resource_pool"
* This reverts commit 50293ec763c024b0eaceac5d775ccc0ad3ff8bd7.
* if the name argument contains a path, only use the last part for matching
* remove path from cluster argument in tests
* remove find_objs in favour of reusing find_obj with an extra folder argument
* fix find_obj ignoring first if name is not given

(cherry picked from commit 1a810f8f11)
This commit is contained in:
Pieter Avonts 2018-09-07 14:53:26 +02:00 committed by Toshio Kuratomi
parent ccde3dc66b
commit 190cdd3a29
5 changed files with 45 additions and 70 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Rewrite get_resource_pool method for correct resource_pool selection.

View file

@ -76,28 +76,20 @@ def wait_for_vm_ip(content, vm, timeout=300):
return facts
def find_obj(content, vimtype, name, first=True):
container = content.viewManager.CreateContainerView(container=content.rootFolder, recursive=True, type=vimtype)
obj_list = container.view
def find_obj(content, vimtype, name, first=True, folder=None):
container = content.viewManager.CreateContainerView(folder or content.rootFolder, recursive=True, type=vimtype)
# Get all objects matching type (and name if given)
obj_list = [obj for obj in container.view if not name or to_text(obj.name) == to_text(name)]
container.Destroy()
# Backward compatible with former get_obj() function
if name is None:
# Return first match or None
if first:
if obj_list:
return obj_list[0]
return None
# Select the first match
if first is True:
for obj in obj_list:
if to_text(obj.name) == to_text(name):
return obj
# If no object found, return None
return None
# Return all matching objects if needed
return [obj for obj in obj_list if obj.name == name]
# Return all matching objects or empty list
return obj_list
def find_dvspg_by_name(dv_switch, portgroup_name):

View file

@ -1850,33 +1850,6 @@ class PyVmomiHelper(PyVmomi):
if current_parent is None:
return False
def select_resource_pool_by_name(self, resource_pool_name):
resource_pool = self.cache.find_obj(self.content, [vim.ResourcePool], resource_pool_name)
if resource_pool is None:
self.module.fail_json(msg='Could not find resource_pool "%s"' % resource_pool_name)
return resource_pool
def select_resource_pool_by_host(self, host):
resource_pools = self.cache.get_all_objs(self.content, [vim.ResourcePool])
for rp in resource_pools.items():
if not rp[0]:
continue
if not hasattr(rp[0], 'parent') or not rp[0].parent:
continue
# Find resource pool on host
if self.obj_has_parent(rp[0].parent, host.parent):
# If no resource_pool selected or it's the selected pool, return it
if self.module.params['resource_pool'] is None or rp[0].name == self.module.params['resource_pool']:
return rp[0]
if self.module.params['resource_pool'] is not None:
self.module.fail_json(msg="Could not find resource_pool %s for selected host %s"
% (self.module.params['resource_pool'], host.name))
else:
self.module.fail_json(msg="Failed to find a resource group for %s" % host.name)
def get_scsi_type(self):
disk_controller_type = "paravirtual"
# set cpu/memory/etc
@ -1921,28 +1894,39 @@ class PyVmomiHelper(PyVmomi):
return root
def get_resource_pool(self):
resource_pool = None
# highest priority, resource_pool given.
if self.params['resource_pool']:
resource_pool = self.select_resource_pool_by_name(self.params['resource_pool'])
# next priority, esxi hostname given.
elif self.params['esxi_hostname']:
host = self.select_host()
resource_pool = self.select_resource_pool_by_host(host)
# next priority, cluster given, take the root of the pool
elif self.params['cluster']:
cluster = self.cache.get_cluster(self.params['cluster'])
if cluster is None:
self.module.fail_json(msg="Unable to find cluster '%(cluster)s'" % self.params)
resource_pool = cluster.resourcePool
# fallback, pick any RP
def get_resource_pool(self, cluster=None, host=None, resource_pool=None):
""" Get a resource pool, filter on cluster, esxi_hostname or resource_pool if given """
cluster_name = cluster or self.params.get('cluster', None)
host_name = host or self.params.get('esxi_hostname', None)
resource_pool_name = resource_pool or self.params.get('resource_pool', None)
# get the datacenter object
datacenter = find_obj(self.content, [vim.Datacenter], self.params['datacenter'])
if not datacenter:
self.module.fail_json(msg='Unable to find datacenter "%s"' % self.params['datacenter'])
# if cluster is given, get the cluster object
if cluster_name:
cluster = find_obj(self.content, [vim.ComputeResource], cluster_name, folder=datacenter)
if not cluster:
self.module.fail_json(msg='Unable to find cluster "%s"' % cluster_name)
# if host is given, get the cluster object using the host
elif host_name:
host = find_obj(self.content, [vim.HostSystem], host_name, folder=datacenter)
if not host:
self.module.fail_json(msg='Unable to find host "%s"' % host_name)
cluster = host.parent
else:
resource_pool = self.select_resource_pool_by_name(self.params['resource_pool'])
if resource_pool is None:
self.module.fail_json(msg='Unable to find resource pool, need esxi_hostname, resource_pool, or cluster')
cluster = None
# get resource pools limiting search to cluster or datacenter
resource_pool = find_obj(self.content, [vim.ResourcePool], resource_pool_name, folder=cluster or datacenter)
if not resource_pool:
if resource_pool_name:
self.module.fail_json(msg='Unable to find resource_pool "%s"' % resource_pool_name)
else:
self.module.fail_json(msg='Unable to find resource pool, need esxi_hostname, resource_pool, or cluster')
return resource_pool
def deploy_vm(self):
@ -2189,12 +2173,9 @@ class PyVmomiHelper(PyVmomi):
relospec = vim.vm.RelocateSpec()
if self.params['resource_pool']:
relospec.pool = self.select_resource_pool_by_name(self.params['resource_pool'])
relospec.pool = self.get_resource_pool()
if relospec.pool is None:
self.module.fail_json(msg='Unable to find resource pool "%(resource_pool)s"' % self.params)
elif relospec.pool != self.current_vm_obj.resourcePool:
if relospec.pool != self.current_vm_obj.resourcePool:
task = self.current_vm_obj.RelocateVM_Task(spec=relospec)
self.wait_for_task(task)
change_applied = True

View file

@ -35,7 +35,7 @@
folder: "/{{ (clusterlist['json'][0]|basename).split('_')[0] }}/vm"
name: CDROM-Test
datacenter: "{{ (clusterlist['json'][0]|basename).split('_')[0] }}"
cluster: "{{ clusterlist['json'][0] }}"
cluster: "{{ clusterlist['json'][0]|basename }}"
resource_pool: Resources
guest_id: centos64Guest
hardware:

View file

@ -35,7 +35,7 @@
folder: "/{{ (clusterlist['json'][0]|basename).split('_')[0] }}/vm"
name: vApp-Test
datacenter: "{{ (clusterlist['json'][0]|basename).split('_')[0] }}"
cluster: "{{ clusterlist['json'][0] }}"
cluster: "{{ clusterlist['json'][0]|basename }}"
resource_pool: Resources
guest_id: centos64Guest
hardware: