def _deploy_gen_services(self, services, parent, path, instance): """ Generates the services in a folder. :param dict services: The "services" dict in a folder :param parent: Parent folder :type parent: vim.Folder :param str path: Folders path at the current level :param int instance: What instance of a base folder this is """ # Iterate through the services for service_name, value in services.items(): if not self._is_vsphere(value["service"]): # Ignore non-vsphere services self._log.debug("Skipping non-vsphere service '%s'", service_name) continue self._log.info("Generating service '%s' in folder '%s'", service_name, parent.name) # Check if number of instances for service exceeds configured limits num_instances, prefix = self._instances_handler( value, service_name, "service") # Get the Master template instance to clone from master = self.masters.get(self.master_prefix + value["service"], None) if master is None: # Check if the lookup was successful self._log.error( "Couldn't find Master for service '%s' " "in this path:\n%s", value["service"], path) continue # Skip to the next service # Clone the instances of the service from the master for i in range(num_instances): instance_name = prefix + service_name + ( " " + pad(i) if num_instances > 1 else "") vm = VM(name=instance_name, folder=parent, resource_pool=self.server.get_pool(), datastore=self.server.datastore, host=self.host) if not vm.create(template=master.get_vim_vm()): self._log.error("Failed to create instance %s", instance_name) else: self._configure_nics(vm, value["networks"], instance=instance)
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)
def resolve_path(server, thing, prompt=""): """ This is a hacked together script utility to get folders or VMs. :param server: Vsphere instance :type server: :class:`Vsphere` :param str thing: String name of thing to get (folder | vm) :param str prompt: Message to display :return: (thing, thing name) :rtype: tuple(vimtype, str) """ from adles.vsphere.vm import VM if thing.lower() == "vm": get = server.get_vm elif thing.lower() == "folder": get = server.get_folder else: logging.error("Invalid thing passed to resolve_path: %s", thing) raise ValueError res = user_input( "Name of or path to %s %s: " % (thing, prompt), thing, lambda x: server.find_by_inv_path("vm/" + x) if '/' in x else get(x)) if thing.lower() == "vm": return VM(vm=res[0]), res[1] else: return res
def main(): args = get_args(__doc__, __version__, 'vm_snapshots.log') server = script_setup(args=args, script_info=(__file__, __version__)) op = str(input("Enter Snapshot operation [create | revert | revert-current " "| remove | remove-all | get | " "get-current | get-all | disk-usage]: ")) if op == "create" or op == "revert" or op == "remove" or op == "get": name = str(input("Name of snapshot to %s: " % op)) if op == "create": desc = str(input("Description of snapshot to create: ")) memory = ask_question("Include memory?") quiesce = ask_question("Quiesce disks? (Requires VMware Tools " "to be running on the VM)") elif op == "remove": children = ask_question("Remove any children of the snapshot?", default="yes") if ask_question("Multiple VMs? ", default="yes"): f, f_name = resolve_path(server, "folder", "with VMs") vms = [VM(vm=x) for x in f.childEntity if is_vm(x)] logging.info("Found %d VMs in folder '%s'", len(vms), f_name) if ask_question("Show the status of the VMs in the folder? "): logging.info("Folder structure: \n%s", format_structure( f.enumerate(recursive=True, power_status=True))) if not ask_question("Continue? ", default="yes"): logging.info("User cancelled operation, exiting...") exit(0) else: vms = [resolve_path(server, "vm", "to perform snapshot operations on")[0]] # Perform the operations for vm in vms: logging.info("Performing operation '%s' on VM '%s'", op, 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": logging.info(vm.get_snapshot_info(name)) elif op == "get-current": logging.info(vm.get_snapshot_info()) elif op == "get-all": logging.info(vm.get_all_snapshots_info()) elif op == "disk-usage": logging.info(vm.snapshot_disk_usage()) else: logging.error("Unknown operation: %s", op)
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()
def main(): args = get_args(__doc__, __version__, 'vm_power.log') server = script_setup(args=args, script_info=(__file__, __version__)) operation = str(input("Enter the power operation you wish to perform" " [on | off | reset | suspend]: ")) attempt_guest = ask_question("Attempt to use guest OS operations, " "if available? ") if ask_question("Multiple VMs? ", default="yes"): folder, folder_name = resolve_path(server, "folder", "with VMs") vms = [VM(vm=x) for x in folder.childEntity if is_vm(x)] logging.info("Found %d VMs in folder '%s'", len(vms), folder_name) if ask_question("Show the status of the VMs in the folder? "): logging.info("Folder structure: \n%s", format_structure( folder.enumerate(recursive=True, power_status=True))) if ask_question("Continue? ", default="yes"): for vm in vms: vm.change_state(operation, attempt_guest) else: vm = resolve_path(server, "VM")[0] logging.info("Changing power state of '%s' to '%s'", vm.name, operation) vm.change_state(operation, attempt_guest)
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 _create_service(self, folder, service_name, networks): """ Retrieves and clones a service into a master folder. :param folder: Folder to create service in :type folder: vim.Folder :param str service_name: Name of the service to clone :param list networks: Networks to configure the service with :return: The service VM instance :rtype: :class:`VM` """ if not self._is_vsphere(service_name): self._log.debug("Skipping non-vsphere service '%s'", service_name) return None config = self.services[service_name] vm_name = self.master_prefix + service_name test = folder.traverse_path(vm_name) # Check service already exists if test is None: # Find the template that matches the service definition template = self.template_folder.traverse_path(config["template"]) if not template: self._log.error( "Could not find template '%s' for service '%s'", config["template"], service_name) return None self._log.info("Creating service '%s'", service_name) vm = VM(name=vm_name, folder=folder, resource_pool=self.server.get_pool(), datastore=self.server.datastore, host=self.host) if not vm.create(template=template): return None else: self._log.warning("Service %s already exists", service_name) vm = VM(vm=test) if vm.is_template(): # Check if it's been converted already self._log.warning( "Service %s is a Template, " "skipping configuration", service_name) return vm # Resource configurations (minus storage currently) if "resource-config" in config: vm.edit_resources(**config["resource-config"]) if "note" in config: # Set VM note if specified vm.set_note(config["note"]) # NOTE: management interfaces matter here! # (If implemented with Monitoring extensions) self._configure_nics(vm, networks=networks) # Configure VM NICs # Post-creation snapshot vm.create_snapshot("Start of Mastering", "Beginning of Mastering phase for exercise %s", self.metadata["name"]) return vm
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()
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()
def main(): args = get_args(__doc__, __version__, 'clone_vms.log') server = script_setup(args=args, script_info=(__file__, __version__)) vms = [] vm_names = [] # Single-vm source if ask_question("Do you want to clone from a single VM?"): v = resolve_path(server, "VM", "or template you wish to clone")[0] vms.append(v) vm_names.append(str(input("Base name for instances to be created: "))) # Multi-VM source else: folder_from, from_name = resolve_path(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) logging.info("%d VMs found in source folder %s", len(v), from_name) if not ask_question("Keep the same names? "): names = [] for i in range(len(v)): names.append(str(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(server, "folder", "in which to create VMs") instance_folder_base = None if ask_question("Do you want to create a folder for each instance? "): instance_folder_base = str(input("Enter instance folder base name: ")) num_instances = int(input("Number of instances to be created: ")) pool_name = server.get_pool().name # Determine what will be the default pool_name = default_prompt(prompt="Resource pool to assign VMs to", default=pool_name) pool = server.get_pool(pool_name) datastore_name = default_prompt(prompt="Datastore to put clones on") datastore = server.get_datastore(datastore_name) logging.info("Creating %d instances under folder %s", num_instances, create_in_name) for instance in range(num_instances): for vm, name in zip(vms, vm_names): if instance_folder_base: # Create instance folders for a nested clone f = 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())