def retrieve_items(folder, vm_prefix='', folder_prefix='', recursive=False): """ Retrieves VMs and folders from a folder structure. :param folder: Folder to begin search in (Note: it is NOT returned in list of folders) :type folder: vim.Folder :param str vm_prefix: VM prefix to search for :param str folder_prefix: Folder prefix to search for :param bool recursive: Recursively descend into sub-folders .. warning:: This will recurse regardless of folder prefix! :return: The VMs and folders found in the folder :rtype: tuple(list(vim.VirtualMachine), list(vim.Folder)) """ vms = [] folders = [] for item in folder.childEntity: # Iterate through all items in the folder if is_vm(item) and str(item.name).startswith(vm_prefix): vms.append(item) # Add matching vm to the list elif is_folder(item): if str(item.name).startswith(folder_prefix): folders.append(item) # Add matching folder to the list if recursive: # Recurse into sub-folders v, f = retrieve_items(item, vm_prefix, folder_prefix, recursive) vms.extend(v) folders.extend(f) return vms, folders
def find_in_folder(folder, name, recursive=False, vimtype=None): """ Finds and returns an specific object in a folder. :param folder: Folder to search in :type folder: vim.Folder :param str name: Name of the object to find :param bool recursive: Recurse into sub-folders :param vimtype: Type of object to search for :return: The object found :rtype: vimtype or None """ # NOTE: Convert to lowercase for case-insensitive comparisons item_name = name.lower() found = None for item in folder.childEntity: # Check if the name matches if hasattr(item, 'name') and item.name.lower() == item_name: if vimtype is not None and not isinstance(item, vimtype): continue found = item elif recursive and is_folder(item): # Recurse into sub-folders found = find_in_folder(item, name=item_name, recursive=recursive, vimtype=vimtype) if found is not None: return found return None
def traverse_path(folder, path, lookup_root=None, generate=False): """ Traverses a folder path to find a object with a specific name. :param folder: Folder to search in :type folder: vim.Folder :param str path: Path in POSIX format (Templates/Windows/ to get the 'Windows' folder) :param lookup_root: If root of path is not found in folder, lookup using this Vsphere object :type lookup_root: :class:`Vsphere` or None :param bool generate: Parts of the path that do not exist are created. :return: Object at the end of the path :rtype: vimtype or None """ logging.debug("Traversing path '%s' from folder '%s'", path, folder.name) folder_path, name = split_path(path) # Check if root of the path is in the folder # This is to allow relative paths to be used if lookup_root is defined folder_items = [ x.name.lower() for x in folder.childEntity if hasattr(x, 'name') ] if len(folder_path) > 0 and folder_path[0] not in folder_items: if lookup_root is not None: logging.debug("Root %s not in folder %s, looking up...", folder_path[0], folder.name) # Lookup the path root on server folder = lookup_root.get_folder(folder_path.pop(0)) else: logging.error( "Could not find root '%s' " "of path '%s' in folder '%s'", folder_path[0], path, folder.name) return None current = folder # Start with the defined folder for f in folder_path: # Try each folder name in the path found = None # Iterate through items in the current folder for item in current.childEntity: # If Folder is part of path if is_folder(item) and item.name.lower() == f: found = item # This is the next folder in the path # Break to outer loop to check this folder # for the next part of the path break if generate and found is None: # Can't find the folder, so create it logging.warning("Generating folder %s in path", f) create_folder(folder, f) # Generate the folder elif found is not None: current = found # Since the split had a basename, look for an item with matching name if name != '': return find_in_folder(current, name) else: # No basename, so just return whatever was at the end of the path return current
def _convert_and_verify(self, folder): """ Converts Masters to Templates before deployment. This also ensures they are powered off before being cloned. :param folder: Folder containing Master instances to convert and verify :type folder: vim.Folder """ self._log.debug("Converting Masters in folder '%s' to templates", folder.name) for item in folder.childEntity: if is_vm(item): vm = VM(vm=item) self.masters[vm.name] = vm if vm.is_template(): # Skip if they already exist from a previous run self._log.debug("Master '%s' is already a template", vm.name) continue # Cleanly power off VM before converting to template if vm.powered_on(): vm.change_state("off", attempt_guest=True) # Take a snapshot to allow reverts to the start of the exercise vm.create_snapshot( "Start of exercise", "Beginning of deployment phase, " "post-master configuration") # Convert Master instance to Template vm.convert_template() if not vm.is_template(): self._log.error("Master '%s' did not convert to Template", vm.name) else: self._log.debug("Converted Master '%s' to Template", vm.name) elif is_folder(item): # Recurse into sub-folders self._convert_and_verify(item) else: self._log.debug( "Unknown item found while " "templatizing Masters: %s", str(item))
def cleanup(folder, vm_prefix='', folder_prefix='', recursive=False, destroy_folders=False, destroy_self=False): """ Cleans a folder by selectively destroying any VMs and folders it contains. :param folder: Folder to cleanup :type folder: vim.Folder :param str vm_prefix: Only destroy VMs with names starting with the prefix :param str folder_prefix: Only destroy or search in folders with names starting with the prefix :param bool recursive: Recursively descend into any sub-folders :param bool destroy_folders: Destroy folders in addition to VMs :param bool destroy_self: Destroy the folder specified """ logging.debug("Cleaning folder '%s'", folder.name) from adles.vsphere.vm import VM for item in folder.childEntity: # Handle VMs if is_vm(item) and str(item.name).startswith(vm_prefix): VM(vm=item).destroy() # Delete the VM from the Datastore # Handle folders elif is_folder(item) and str(item.name).startswith(folder_prefix): if destroy_folders: # Destroys folder and ALL of it's sub-objects cleanup(item, destroy_folders=True, destroy_self=True) elif recursive: # Simply recurses to find more items cleanup(item, vm_prefix=vm_prefix, folder_prefix=folder_prefix, recursive=True) # Note: UnregisterAndDestroy does NOT delete VM files off the datastore # Only use if folder is already empty! if destroy_self: logging.debug("Destroying folder: '%s'", folder.name) folder.UnregisterAndDestroy_Task().wait()
def enumerate_folder(folder, recursive=True, power_status=False): """ Enumerates a folder structure and returns the result. as a python object with the same structure :param folder: Folder to enumerate :type folder: vim.Folder :param bool recursive: Whether to recurse into any sub-folders :param bool power_status: Display the power state of the VMs in the folder :return: The nested python object with the enumerated folder structure :rtype: list(list, str) """ children = [] for item in folder.childEntity: if is_folder(item): if recursive: # Recurse into sub-folders and append the sub-tree children.append(enumerate_folder(item, recursive)) else: # Don't recurse, just append the folder children.append('- ' + item.name) elif is_vm(item): if power_status: if item.runtime.powerState == \ vim.VirtualMachine.PowerState.poweredOn: children.append('* ON ' + item.name) elif item.runtime.powerState == \ vim.VirtualMachine.PowerState.poweredOff: children.append('* OFF ' + item.name) elif item.runtime.powerState == \ vim.VirtualMachine.PowerState.suspended: children.append('* SUS ' + item.name) else: logging.error("Invalid power state for VM: %s", item.name) else: children.append('* ' + item.name) else: children.append("UNKNOWN ITEM: %s" % str(item)) return '+ ' + folder.name, children # Return tuple of parent and children