Ejemplo n.º 1
0
    def run(self):
        print("Enter the power operation you wish to perform")  # noqa: T001
        operation = prompt_for_choice(['on', 'off', 'reset', 'suspend'],
                                      padding=False)
        attempt_guest = prompt_for_confirmation("Attempt to use guest OS "
                                                "operations, if available? ")

        if prompt_for_confirmation("Multiple VMs? ", default=True):
            folder, folder_name = resolve_path(self.server, "folder",
                                               "with VMs")
            vms = [VM(vm=x) for x in folder.childEntity if is_vm(x)]
            self._log.info("Found %d VMs in folder '%s'", len(vms),
                           folder_name)
            if prompt_for_confirmation("Show the status of the "
                                       "VMs in the folder? "):
                self._log.info(
                    "Folder structure: \n%s",
                    format_structure(
                        folder.enumerate(recursive=True, power_status=True)))
            if prompt_for_confirmation("Continue? ", default=True):
                pbar = tqdm.tqdm(vms,
                                 unit="VMs",
                                 desc="Performing power operation " +
                                 operation)
                for vm in pbar:
                    pbar.set_postfix_str(vm.name)
                    vm.change_state(operation, attempt_guest)
                pbar.close()

        else:
            vm = resolve_path(self.server, "VM")[0]
            self._log.info("Changing power state of '%s' "
                           "to '%s'", vm.name, operation)
            vm.change_state(operation, attempt_guest)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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

    # TODO: progress bar
    # pbar = tqdm.tqdm(folder.childEntity, desc="Cleaning folder",
    #                  unit="Items", clear=True)
    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()
Ejemplo n.º 4
0
    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))
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
    def run(self):
        print("Enter Snapshot operation to perform")  # noqa: T001
        op = prompt_for_choice([
            'create', 'revert', 'revert-current', 'remove', 'remove-all',
            'get', 'get-current', 'get-all', 'disk-usage'
        ],
                               padding=False)
        if op in ['create', 'revert', 'remove', 'get']:
            name = input("Name of snapshot to %s: " % op)
            if op == "create":
                desc = input("Description of snapshot to create: ")
                memory = prompt_for_confirmation("Include memory?")
                quiesce = prompt_for_confirmation(
                    "Quiesce disks? (Requires VMware "
                    "Tools to be running on the VM)")
            elif op == "remove":
                children = prompt_for_confirmation(
                    "Remove any children of the "
                    "snapshot?", default=True)

        if prompt_for_confirmation("Multiple VMs? ", default=True):
            f, f_name = resolve_path(self.server, "folder", "with VMs")
            vms = [VM(vm=x) for x in f.childEntity if is_vm(x)]
            self._log.info("Found %d VMs in folder '%s'", len(vms), f_name)
            if prompt_for_confirmation("Show the status of the "
                                       "VMs in the folder? "):
                self._log.info(
                    "Folder structure: \n%s",
                    format_structure(
                        f.enumerate(recursive=True, power_status=True)))
            if not prompt_for_confirmation("Continue? ", default=True):
                self._log.info("User cancelled operation, exiting...")
                sys.exit(0)
        else:
            vms = [
                resolve_path(self.server, "vm",
                             "to perform snapshot operations on")[0]
            ]

        # Perform the operations
        pbar = tqdm.tqdm(vms,
                         total=len(vms),
                         unit="VMs",
                         desc="Taking snapshots")
        for vm in pbar:
            self._log.info("Performing operation '%s' on VM '%s'", op, vm.name)
            pbar.set_postfix_str(vm.name)
            if op == "create":
                vm.create_snapshot(name=name,
                                   description=desc,
                                   memory=memory,
                                   quiesce=quiesce)
            elif op == "revert":
                vm.revert_to_snapshot(snapshot=name)
            elif op == "revert-current":
                vm.revert_to_current_snapshot()
            elif op == "remove":
                vm.remove_snapshot(snapshot=name, remove_children=children)
            elif op == "remove-all":
                vm.remove_all_snapshots()
            elif op == "get":
                self._log.info(vm.get_snapshot_info(name))
            elif op == "get-current":
                self._log.info(vm.get_snapshot_info())
            elif op == "get-all":
                self._log.info(vm.get_all_snapshots_info())
            elif op == "disk-usage":
                self._log.info(vm.snapshot_disk_usage())
            else:
                self._log.error("Unknown operation: %s", op)
            pbar.update()
        pbar.close()
Ejemplo n.º 7
0
    def run(self):
        vms = []
        vm_names = []

        # Single-vm source
        if prompt_for_confirmation("Do you want to clone from a single VM?"):
            v = resolve_path(self.server, "VM",
                             "or template you wish to clone")[0]
            vms.append(v)
            vm_names.append(input("Base name for instances to be created: "))
        # Multi-VM source
        else:
            folder_from, from_name = resolve_path(
                self.server, "folder", "you want to clone all VMs in")
            # Get VMs in the folder
            v = [VM(vm=x) for x in folder_from.childEntity if is_vm(x)]
            vms.extend(v)
            self._log.info("%d VMs found in source folder %s", len(v),
                           from_name)
            if not prompt_for_confirmation("Keep the same names? "):
                names = []
                for i in range(len(v)):
                    names.append(input("Enter base name for VM %d: " % i))
            else:
                names = list(map(lambda x: x.name, v))  # Same names as sources
            vm_names.extend(names)

        create_in, create_in_name = resolve_path(self.server, "folder",
                                                 "in which to create VMs")
        instance_folder_base = None
        if prompt_for_confirmation("Do you want to create a "
                                   "folder for each instance? "):
            instance_folder_base = input("Enter instance folder base name: ")

        num_instances = int(input("Number of instances to be created: "))

        # Determine what will be the default
        pool_name = self.server.get_pool().name
        pool_name = default_prompt(prompt="Resource pool to assign VMs to",
                                   default=pool_name)
        pool = self.server.get_pool(pool_name)

        datastore_name = default_prompt(prompt="Datastore to put clones on")
        datastore = self.server.get_datastore(datastore_name)

        self._log.info("Creating %d instances under folder %s", num_instances,
                       create_in_name)
        for instance in tqdm.trange(num_instances,
                                    desc="Creating instances",
                                    unit="instances"):
            with tqdm.tqdm(total=len(vm_names),
                           leave=False,
                           desc="Creating VMs",
                           unit="VMs") as pbar:
                for vm, name in zip(vms, vm_names):
                    pbar.set_postfix_str(name)
                    if instance_folder_base:
                        # Create instance folders for a nested clone
                        f = self.server.create_folder(instance_folder_base +
                                                      pad(instance),
                                                      create_in=create_in)
                        vm_name = name
                    else:
                        f = create_in
                        vm_name = name + pad(
                            instance)  # Append instance number

                    new_vm = VM(name=vm_name,
                                folder=f,
                                resource_pool=pool,
                                datastore=datastore)
                    new_vm.create(template=vm.get_vim_vm())
                    pbar.update()