diff --git a/lib/ansible/module_utils/vmware.py b/lib/ansible/module_utils/vmware.py index af8bbf8d0c..97ab4c1db5 100644 --- a/lib/ansible/module_utils/vmware.py +++ b/lib/ansible/module_utils/vmware.py @@ -213,6 +213,24 @@ def find_host_portgroup_by_name(host, portgroup_name): return None +def compile_folder_path_for_object(vobj): + """ make a /vm/foo/bar/baz like folder path for an object """ + + paths = [] + if isinstance(vobj, vim.Folder): + paths.append(vobj.name) + + thisobj = vobj + while hasattr(thisobj, 'parent'): + thisobj = thisobj.parent + if isinstance(thisobj, vim.Folder): + paths.append(thisobj.name) + paths.reverse() + if paths[0] == 'Datacenters': + paths.remove('Datacenters') + return '/' + '/'.join(paths) + + def _get_vm_prop(vm, attributes): """Safely get a property or return None""" result = vm diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest.py b/lib/ansible/modules/cloud/vmware/vmware_guest.py index 275fa250b2..c09c3b9c9f 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_guest.py +++ b/lib/ansible/modules/cloud/vmware/vmware_guest.py @@ -87,7 +87,7 @@ options: - ' folder: folder1/datacenter1/vm' - ' folder: /folder1/datacenter1/vm/folder2' - ' folder: vm/folder2' - - ' fodler: folder2' + - ' folder: folder2' default: /vm hardware: description: @@ -316,7 +316,7 @@ import time from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.pycompat24 import get_exception -from ansible.module_utils.vmware import connect_to_api, find_obj, gather_vm_facts, get_all_objs +from ansible.module_utils.vmware import connect_to_api, find_obj, gather_vm_facts, get_all_objs, compile_folder_path_for_object from ansible.module_utils.vmware import serialize_spec try: @@ -1211,7 +1211,6 @@ class PyVmomiHelper(object): # https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.RelocateSpec.html # FIXME: - # - multiple datacenters # - multiple templates by the same name # - static IPs @@ -1220,15 +1219,24 @@ class PyVmomiHelper(object): if datacenter is None: self.module.fail_json(msg='No datacenter named %(datacenter)s was found' % self.params) - destfolder = None + # Prepend / if it was missing from the folder path, also strip trailing slashes + if not self.params['folder'].startswith('/'): + self.params['folder'] = '/%(folder)s' % self.params + self.params['folder'] = self.params['folder'].rstrip('/') - # make an attempt with findinventorybypath, although this works poorly - # when datacenters are nested under folders - f_obj = self.content.searchIndex.FindByInventoryPath('%(folder)s' % self.params) + dcpath = compile_folder_path_for_object(datacenter) - # retry by walking down the object tree - if f_obj is None: - f_obj = self.find_folder(self.params['folder']) + # Check for full path first in case it was already supplied + if (self.params['folder'].startswith(dcpath + self.params['datacenter'] + '/vm')): + fullpath = self.params['folder'] + elif (self.params['folder'].startswith('/vm/') or self.params['folder'] == '/vm'): + fullpath = "%s%s%s" % (dcpath, self.params['datacenter'], self.params['folder']) + elif (self.params['folder'].startswith('/')): + fullpath = "%s%s/vm%s" % (dcpath, self.params['datacenter'], self.params['folder']) + else: + fullpath = "%s%s/vm/%s" % (dcpath, self.params['datacenter'], self.params['folder']) + + f_obj = self.content.searchIndex.FindByInventoryPath(fullpath) # abort if no strategy was successful if f_obj is None: diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest_find.py b/lib/ansible/modules/cloud/vmware/vmware_guest_find.py index dcea6fb39b..1da97d203f 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_guest_find.py +++ b/lib/ansible/modules/cloud/vmware/vmware_guest_find.py @@ -80,7 +80,7 @@ import os # import module snippets from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_native -from ansible.module_utils.vmware import connect_to_api, gather_vm_facts, get_all_objs +from ansible.module_utils.vmware import connect_to_api, gather_vm_facts, get_all_objs, compile_folder_path_for_object HAS_PYVMOMI = False @@ -126,7 +126,7 @@ class PyVmomiHelper(object): continue # Match by name or uuid if vobj.config.name == name or vobj.config.uuid == uuid: - folderpath = self.compile_folder_path_for_object(vobj) + folderpath = compile_folder_path_for_object(vobj) results.append(folderpath) return results @@ -200,24 +200,6 @@ class PyVmomiHelper(object): self.folders = self._build_folder_tree(self.datacenter.vmFolder) self._build_folder_map(self.folders) - @staticmethod - def compile_folder_path_for_object(vobj): - """ make a /vm/foo/bar/baz like folder path for an object """ - - paths = [] - if isinstance(vobj, vim.Folder): - paths.append(vobj.name) - - thisobj = vobj - while hasattr(thisobj, 'parent'): - thisobj = thisobj.parent - if isinstance(thisobj, vim.Folder): - paths.append(thisobj.name) - paths.reverse() - if paths[0] == 'Datacenters': - paths.remove('Datacenters') - return '/' + '/'.join(paths) - def get_datacenter(self): self.datacenter = get_obj( self.content,