def test_pad(): from adles.utils import pad assert pad(0) == "00" assert pad(5) == "05" assert pad(9, 3) == "009" assert pad(value=10, length=4) == "0010" assert pad(50, 5) == "00050"
def _deploy_parent_folder_gen(self, spec, parent, path): """ Generates parent-type folder trees. :param dict spec: Dict with folder specification :param parent: Parent folder :type parent: vim.Folder :param str path: Folders path at the current level """ skip_keys = ["instances", "description", "master-group", "enabled"] if not self._is_enabled(spec): # Check if disabled self._log.warning("Skipping disabled parent-type folder %s", parent.name) return for sub_name, sub_value in spec.items(): if sub_name in skip_keys: # Skip configurations that are not relevant continue elif sub_name == "group": # Configure group pass # group = self._get_group(sub_value) else: # Create instances of the parent folder self._log.debug("Deploying parent-type folder '%s'", sub_name) num_instances, prefix = self._instances_handler( spec, sub_name, "folder") for i in range(num_instances): # If prefix is undefined or there's a single instance, # use the folder's name instance_name = (sub_name if prefix == "" or num_instances == 1 else prefix) # If multiple instances, append padded instance number instance_name += (pad(i) if num_instances > 1 else "") # Create a folder for the instance new_folder = self.server.create_folder(instance_name, create_in=parent) if "services" in sub_value: # It's a base folder if self._is_enabled(sub_value): self._deploy_base_folder_gen( folder_name=sub_name, folder_items=sub_value, parent=new_folder, path=self._path(path, sub_name)) else: self._log.warning( "Skipping disabled " "base-type folder %s", sub_name) else: # It's a parent folder if self._is_enabled(sub_value): self._deploy_parent_folder_gen(parent=new_folder, spec=sub_value, path=self._path( path, sub_name)) else: self._log.warning( "Skipping disabled " "parent-type folder %s", sub_name)
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 _get_net(self, name, instance=-1): """ Resolves network names. This is mainly to handle generic-type networks. If a generic network does not exist, it is created and added to the interface lookup table. :param str name: Name of the network :param int instance: Instance number .. note:: Only applies to generic-type networks :return: Resolved network name :rtype: str """ net_type = self._determine_net_type(name) if net_type == "unique-networks": return name elif net_type == "generic-networks": if instance == -1: self._log.error("Invalid instance for _get_net: %d", instance) raise ValueError # Generate full name for the generic network net_name = name + "-GENERIC-" + pad(instance) if net_name not in self.net_table: exists = self.server.get_network(net_name) if exists is not None: self._log.debug("PortGroup '%s' already exists " "on host '%s'", net_name, self.host.name) else: # Create the generic network if it does not exist # WARNING: lookup of name is case-sensitive! # This can (and has0 lead to bugs self._log.debug("Creating portgroup '%s' on host '%s'", net_name, self.host.name) vsw = self.networks["generic-networks"][name].get( "vswitch", self.vswitch_name) create_portgroup(name=net_name, host=self.host, promiscuous=False, vlan=next(get_vlan()), vswitch_name=vsw) # Register the existence of the generic network self.net_table[net_name] = True return net_name else: self._log.error("Invalid network type %s for network %s", net_type, name) raise TypeError
def _deploy_base_folder_gen(self, folder_name, folder_items, parent, path): """ Generates folder tree for deployment stage. :param str folder_name: Name of the folder :param dict folder_items: Dict of items in the folder :param parent: Parent folder :type parent: vim.Folder :param str path: Folders path at the current level """ # Set the group to apply permissions for # group = self._get_group(folder_items["group"]) # Check if number of instances for the folder exceeds configured limits num_instances, prefix = self._instances_handler( folder_items, folder_name, "folder") # Create instances self._log.info("Deploying base-type folder '%s'", folder_name) for i in range(num_instances): # If no prefix is defined or there's only a single instance, # use the folder's name instance_name = (folder_name if prefix == "" or num_instances == 1 else prefix) # If multiple instances, append padded instance number instance_name += (pad(i) if num_instances > 1 else "") if num_instances > 1: # Create a folder for the instance new_folder = self.server.create_folder(instance_name, create_in=parent) else: # Don't duplicate folder name for single instances new_folder = parent # Use the folder's name for the path, # as that's what matches the Master version self._log.info( "Generating services for " "base-type folder instance '%s'", instance_name) self._deploy_gen_services(services=folder_items["services"], parent=new_folder, path=path, instance=i)
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())