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)
pull/46059/head
Pieter Avonts 6 years ago committed by Toshio Kuratomi
parent ccde3dc66b
commit 190cdd3a29

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

@ -76,28 +76,20 @@ def wait_for_vm_ip(content, vm, timeout=300):
return facts return facts
def find_obj(content, vimtype, name, first=True): def find_obj(content, vimtype, name, first=True, folder=None):
container = content.viewManager.CreateContainerView(container=content.rootFolder, recursive=True, type=vimtype) container = content.viewManager.CreateContainerView(folder or content.rootFolder, recursive=True, type=vimtype)
obj_list = container.view # 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() container.Destroy()
# Backward compatible with former get_obj() function # Return first match or None
if name is None: if first:
if obj_list: if obj_list:
return obj_list[0] return obj_list[0]
return None return None
# Select the first match # Return all matching objects or empty list
if first is True: return obj_list
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]
def find_dvspg_by_name(dv_switch, portgroup_name): def find_dvspg_by_name(dv_switch, portgroup_name):

@ -1850,33 +1850,6 @@ class PyVmomiHelper(PyVmomi):
if current_parent is None: if current_parent is None:
return False 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): def get_scsi_type(self):
disk_controller_type = "paravirtual" disk_controller_type = "paravirtual"
# set cpu/memory/etc # set cpu/memory/etc
@ -1921,28 +1894,39 @@ class PyVmomiHelper(PyVmomi):
return root return root
def get_resource_pool(self): def get_resource_pool(self, cluster=None, host=None, resource_pool=None):
resource_pool = None """ Get a resource pool, filter on cluster, esxi_hostname or resource_pool if given """
# highest priority, resource_pool given.
if self.params['resource_pool']: cluster_name = cluster or self.params.get('cluster', None)
resource_pool = self.select_resource_pool_by_name(self.params['resource_pool']) host_name = host or self.params.get('esxi_hostname', None)
# next priority, esxi hostname given. resource_pool_name = resource_pool or self.params.get('resource_pool', None)
elif self.params['esxi_hostname']:
host = self.select_host() # get the datacenter object
resource_pool = self.select_resource_pool_by_host(host) datacenter = find_obj(self.content, [vim.Datacenter], self.params['datacenter'])
# next priority, cluster given, take the root of the pool if not datacenter:
elif self.params['cluster']: self.module.fail_json(msg='Unable to find datacenter "%s"' % self.params['datacenter'])
cluster = self.cache.get_cluster(self.params['cluster'])
if cluster is None: # if cluster is given, get the cluster object
self.module.fail_json(msg="Unable to find cluster '%(cluster)s'" % self.params) if cluster_name:
resource_pool = cluster.resourcePool cluster = find_obj(self.content, [vim.ComputeResource], cluster_name, folder=datacenter)
# fallback, pick any RP 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: else:
resource_pool = self.select_resource_pool_by_name(self.params['resource_pool']) cluster = None
if resource_pool is None:
self.module.fail_json(msg='Unable to find resource pool, need esxi_hostname, resource_pool, or cluster')
# 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 return resource_pool
def deploy_vm(self): def deploy_vm(self):
@ -2189,12 +2173,9 @@ class PyVmomiHelper(PyVmomi):
relospec = vim.vm.RelocateSpec() relospec = vim.vm.RelocateSpec()
if self.params['resource_pool']: 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) task = self.current_vm_obj.RelocateVM_Task(spec=relospec)
self.wait_for_task(task) self.wait_for_task(task)
change_applied = True change_applied = True

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

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

Loading…
Cancel
Save