Exemplo n.º 1
0
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"
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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)
Exemplo n.º 6
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()
Exemplo n.º 7
0
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())