Example #1
0
    def __init__(self, module):
        super(VMwareHostDatastore, self).__init__(module)

        # NOTE: The below parameter is deprecated starting from Ansible v2.11
        self.datacenter_name = module.params['datacenter_name']
        self.datastore_name = module.params['datastore_name']
        self.datastore_type = module.params['datastore_type']
        self.nfs_server = module.params['nfs_server']
        self.nfs_path = module.params['nfs_path']
        self.nfs_ro = module.params['nfs_ro']
        self.vmfs_device_name = module.params['vmfs_device_name']
        self.vmfs_version = module.params['vmfs_version']
        self.esxi_hostname = module.params['esxi_hostname']
        self.state = module.params['state']

        if self.is_vcenter():
            if not self.esxi_hostname:
                self.module.fail_json(
                    msg="esxi_hostname is mandatory with a vcenter")
            self.esxi = self.find_hostsystem_by_name(self.esxi_hostname)
            if self.esxi is None:
                self.module.fail_json(msg="Failed to find ESXi hostname %s" %
                                      self.esxi_hostname)
        else:
            self.esxi = find_obj(self.content, [vim.HostSystem], None)
Example #2
0
    def execute(self):
        result = dict(changed=False)

        obj = find_obj(self.content, [vim.HostSystem], self.esxi_hostname)
        if (obj):
            for pg in obj.config.network.portgroup:
                if (isinstance(pg, vim.host.PortGroup)
                        and pg.spec.name == self.pg_name):
                    portgroup_spec = pg.spec
                    portgroup_spec.policy.security.allowPromiscuous = self.promiscuous_mode
                    portgroup_spec.policy.security.forgedTransmits = self.forged_transmits
                    portgroup_spec.policy.security.macChanges = self.mac_address_changes

                    try:
                        obj.configManager.networkSystem.UpdatePortGroup(
                            self.pg_name, portgroup_spec)
                    except:
                        self.module.fail_json(
                            msg="Failed to portgroup security update %s." %
                            self.pg_name)

                    result['changed'] = True
                    self.module.exit_json(**result)
                else:
                    self.module.fail_json(msg="%s not found" % self.pg_name)
        else:
            self.module.fail_json(msg="%s not found." % self.esxi_hostname)
Example #3
0
    def __init__(self, module):
        super(VMwareHostDatastore, self).__init__(module)

        self.datacenter_name = module.params['datacenter_name']
        self.datastore_name = module.params['datastore_name']
        self.esxi_hostname = module.params['esxi_hostname']
        self.esxi_hostname = module.params['esxi_hostname']
        self.vmfs_device_name = module.params['vmfs_device_name']
        self.folder_name = module.params['folder_name']

        self.esxi = self.find_hostsystem_by_name(self.esxi_hostname)
        if self.esxi is None:
            self.module.fail_json(msg="Failed to find ESXi hostname %s." %
                                  self.esxi_hostname)

        if self.folder_name:
            self.folder = find_obj(self.content, [vim.Folder],
                                   self.folder_name,
                                   first=True)
            if self.folder is None:
                self.module.fail_json(
                    msg=
                    "Failed to find storage folder '%s'. Make sure the folder exists, "
                    "or remove module parameter folder_name." %
                    self.folder_name)

        self.check_datastore_host_state()
    def get_object(self):
        # find_obj doesn't include rootFolder
        if self.params['object_type'] == 'Folder' and self.params[
                'object_name'] == 'rootFolder':
            self.current_obj = self.content.rootFolder
            return
        try:
            object_type = getattr(vim, self.params['object_type'])
        except AttributeError:
            self.module.fail_json(msg="Object type %s is not valid." %
                                  self.params['object_type'])
        self.current_obj = find_obj(
            content=self.content,
            vimtype=[getattr(vim, self.params['object_type'])],
            name=self.params['object_name'])

        if self.current_obj is None:
            self.module.fail_json(
                msg="Specified object %s of type %s was not found." %
                (self.params['object_name'], self.params['object_type']))
        if self.params['object_type'] == 'DistributedVirtualSwitch':
            msg = "You are applying permissions to a Distributed vSwitch. " \
                  "This will probably fail, since Distributed vSwitches inherits permissions " \
                  "from the datacenter or a folder level. " \
                  "Define permissions on the datacenter or the folder containing the switch."
            self.module.warn(msg)
Example #5
0
def all_facts(content):
    host = find_obj(content, [vim.HostSystem], None)
    ansible_facts = {}
    ansible_facts.update(get_cpu_facts(host))
    ansible_facts.update(get_memory_facts(host))
    ansible_facts.update(get_datastore_facts(host))
    ansible_facts.update(get_network_facts(host))
    ansible_facts.update(get_system_facts(host))
    return ansible_facts
 def find_obj(self, content, types, name, confine_to_datacenter=True):
     """ Wrapper around find_obj to set datacenter context """
     result = find_obj(content, types, name)
     if result and confine_to_datacenter:
         if self.get_parent_datacenter(result).name != self.dc_name:
             result = None
             objects = self.get_all_objs(content, types, confine_to_datacenter=True)
             for obj in objects:
                 if name is None or obj.name == name:
                     return obj
     return result
Example #7
0
    def __init__(self, module):
        super(VmwareHostSnmp, self).__init__(module)

        if self.is_vcenter():
            self.module.fail_json(
                msg="You have to connect directly to the ESXi host. "
                "It's not possible to configure SNMP through a vCenter connection."
            )
        else:
            self.host = find_obj(self.content, [vim.HostSystem], None)
            if self.host is None:
                self.module.fail_json(msg="Failed to find host system.")
Example #8
0
    def sanitize_params(self):
        '''
        this method is used to verify user provided parameters
        '''
        self.vm_obj = self.get_vm()
        if self.vm_obj is None:
            vm_id = self.vm_uuid or self.vm_name or self.moid
            self.module.fail_json(
                msg="Failed to find the VM/template with %s" % vm_id)

        # connect to destination VC
        self.destination_content = connect_to_api(
            self.module,
            hostname=self.destination_vcenter,
            username=self.destination_vcenter_username,
            password=self.destination_vcenter_password,
            port=self.destination_vcenter_port,
            validate_certs=self.destination_vcenter_validate_certs)

        # Check if vm name already exists in the destination VC
        vm = find_vm_by_name(content=self.destination_content,
                             vm_name=self.params['destination_vm_name'])
        if vm:
            self.module.exit_json(
                changed=False, msg="A VM with the given name already exists")

        datastore_name = self.params['destination_datastore']
        datastore_cluster = find_obj(self.destination_content,
                                     [vim.StoragePod], datastore_name)
        if datastore_cluster:
            # If user specified datastore cluster so get recommended datastore
            datastore_name = self.get_recommended_datastore(
                datastore_cluster_obj=datastore_cluster)
            # Check if get_recommended_datastore or user specified datastore exists or not
        self.destination_datastore = find_datastore_by_name(
            content=self.destination_content, datastore_name=datastore_name)
        if self.destination_datastore is None:
            self.module.fail_json(msg="Destination datastore not found.")

        self.destination_host = find_hostsystem_by_name(
            content=self.destination_content,
            hostname=self.params['destination_host'])
        if self.destination_host is None:
            self.module.fail_json(msg="Destination host not found.")

        if self.params['destination_resource_pool']:
            self.destination_resource_pool = find_resource_pool_by_name(
                content=self.destination_content,
                resource_pool_name=self.params['destination_resource_pool'])
        else:
            self.destination_resource_pool = self.destination_host.parent.resourcePool
Example #9
0
    def __init__(self, module):
        super(VMwareHostFactManager, self).__init__(module)
        esxi_host_name = self.params.get('esxi_hostname', None)
        if self.is_vcenter():
            if esxi_host_name is None:
                self.module.fail_json(msg="Connected to a vCenter system without specifying esxi_hostname")
            self.host = self.get_all_host_objs(esxi_host_name=esxi_host_name)
            if len(self.host) > 1:
                self.module.fail_json(msg="esxi_hostname matched multiple hosts")
            self.host = self.host[0]
        else:
            self.host = find_obj(self.content, [vim.HostSystem], None)

        if self.host is None:
            self.module.fail_json(msg="Failed to find host system.")
    def get_object(self):
        try:
            object_type = getattr(vim, self.params['object_type'])
        except AttributeError:
            self.module.fail_json(msg="Object type %s is not valid." %
                                  self.params['object_type'])

        self.current_obj = find_obj(
            content=self.content,
            vimtype=[getattr(vim, self.params['object_type'])],
            name=self.params['object_name'])

        if self.current_obj is None:
            self.module.fail_json(
                msg="Specified object %s of type %s was not found." %
                (self.params['object_name'], self.params['object_type']))
Example #11
0
    def get_object(self):
        # find_obj doesn't include rootFolder
        if self.params['object_type'] == 'Folder' and self.params['object_name'] == 'rootFolder':
            self.current_obj = self.content.rootFolder
            return
        try:
            object_type = getattr(vim, self.params['object_type'])
        except AttributeError:
            self.module.fail_json(msg="Object type %s is not valid." % self.params['object_type'])
        self.current_obj = find_obj(content=self.content,
                                    vimtype=[getattr(vim, self.params['object_type'])],
                                    name=self.params['object_name'])

        if self.current_obj is None:
            self.module.fail_json(
                msg="Specified object %s of type %s was not found."
                % (self.params['object_name'], self.params['object_type'])
            )
Example #12
0
    def ensure_disks(self, vm_obj=None):
        """
        Manage internal state of virtual machine disks
        Args:
            vm_obj: Managed object of virtual machine

        """
        # Set vm object
        self.vm = vm_obj
        # Sanitize user input
        disk_data = self.sanitize_disk_inputs()
        # Create stateful information about SCSI devices
        current_scsi_info = dict()
        results = dict(changed=False, disk_data=None, disk_changes=dict())

        # Deal with SCSI Controller
        for device in vm_obj.config.hardware.device:
            if isinstance(device, tuple(self.scsi_device_type.values())):
                # Found SCSI device
                if device.busNumber not in current_scsi_info:
                    device_bus_number = 1000 + device.busNumber
                    current_scsi_info[device_bus_number] = dict(disks=dict())

        scsi_changed = False
        for disk in disk_data:
            scsi_controller = disk['scsi_controller'] + 1000
            if scsi_controller not in current_scsi_info and disk[
                    'state'] == 'present':
                scsi_ctl = self.create_scsi_controller(disk['scsi_type'],
                                                       disk['scsi_controller'])
                current_scsi_info[scsi_controller] = dict(disks=dict())
                self.config_spec.deviceChange.append(scsi_ctl)
                scsi_changed = True
        if scsi_changed:
            self.reconfigure_vm(self.config_spec, 'SCSI Controller')
            self.config_spec = vim.vm.ConfigSpec()
            self.config_spec.deviceChange = []

        # Deal with Disks
        for device in vm_obj.config.hardware.device:
            if isinstance(device, vim.vm.device.VirtualDisk):
                # Found Virtual Disk device
                if device.controllerKey not in current_scsi_info:
                    current_scsi_info[device.controllerKey] = dict(
                        disks=dict())
                current_scsi_info[device.controllerKey]['disks'][
                    device.unitNumber] = device

        vm_name = self.vm.name
        disk_change_list = []
        for disk in disk_data:
            disk_change = False
            scsi_controller = disk[
                'scsi_controller'] + 1000  # VMware auto assign 1000 + SCSI Controller
            if disk['disk_unit_number'] not in current_scsi_info[
                    scsi_controller]['disks'] and disk['state'] == 'present':
                # Add new disk
                disk_spec = self.create_scsi_disk(scsi_controller,
                                                  disk['disk_unit_number'],
                                                  disk['disk_mode'],
                                                  disk['filename'])
                if disk['filename'] is None:
                    disk_spec.device.capacityInKB = disk['size']
                if disk['disk_type'] == 'thin':
                    disk_spec.device.backing.thinProvisioned = True
                elif disk['disk_type'] == 'eagerzeroedthick':
                    disk_spec.device.backing.eagerlyScrub = True
                # get Storage DRS recommended datastore from the datastore cluster
                if disk['datastore_cluster'] is not None:
                    datastore_name = self.get_recommended_datastore(
                        datastore_cluster_obj=disk['datastore_cluster'],
                        disk_spec_obj=disk_spec)
                    disk['datastore'] = find_obj(self.content, [vim.Datastore],
                                                 datastore_name)
                if disk['filename'] is None:
                    disk_spec.device.backing.fileName = "[%s] %s/%s_%s_%s.vmdk" % (
                        disk['datastore'].name, vm_name, vm_name,
                        str(scsi_controller), str(disk['disk_unit_number']))
                else:
                    disk_spec.device.backing.fileName = disk['filename']
                disk_spec.device.backing.datastore = disk['datastore']
                disk_spec = self.get_ioandshares_diskconfig(disk_spec, disk)
                self.config_spec.deviceChange.append(disk_spec)
                disk_change = True
                current_scsi_info[scsi_controller]['disks'][
                    disk['disk_unit_number']] = disk_spec.device
                results['disk_changes'][disk['disk_index']] = "Disk created."
            elif disk['disk_unit_number'] in current_scsi_info[
                    scsi_controller]['disks']:
                if disk['state'] == 'present':
                    disk_spec = vim.vm.device.VirtualDeviceSpec()
                    # set the operation to edit so that it knows to keep other settings
                    disk_spec.device = current_scsi_info[scsi_controller][
                        'disks'][disk['disk_unit_number']]
                    # Edit and no resizing allowed
                    if disk['size'] < disk_spec.device.capacityInKB:
                        self.module.fail_json(
                            msg=
                            "Given disk size at disk index [%s] is smaller than found (%d < %d)."
                            "Reducing disks is not allowed." %
                            (disk['disk_index'], disk['size'],
                             disk_spec.device.capacityInKB))
                    if disk['size'] != disk_spec.device.capacityInKB:
                        disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
                        disk_spec = self.get_ioandshares_diskconfig(
                            disk_spec, disk)
                        disk_spec.device.capacityInKB = disk['size']
                        self.config_spec.deviceChange.append(disk_spec)
                        disk_change = True
                        results['disk_changes'][
                            disk['disk_index']] = "Disk size increased."
                    else:
                        results['disk_changes'][
                            disk['disk_index']] = "Disk already exists."

                elif disk['state'] == 'absent':
                    # Disk already exists, deleting
                    disk_spec = vim.vm.device.VirtualDeviceSpec()
                    disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove
                    if disk['destroy'] is True:
                        disk_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.destroy
                    disk_spec.device = current_scsi_info[scsi_controller][
                        'disks'][disk['disk_unit_number']]
                    self.config_spec.deviceChange.append(disk_spec)
                    disk_change = True
                    results['disk_changes'][
                        disk['disk_index']] = "Disk deleted."

            if disk_change:
                # Adding multiple disks in a single attempt raises weird errors
                # So adding single disk at a time.
                self.reconfigure_vm(self.config_spec, 'disks')
                self.config_spec = vim.vm.ConfigSpec()
                self.config_spec.deviceChange = []
            disk_change_list.append(disk_change)

        if any(disk_change_list):
            results['changed'] = True
        results['disk_data'] = self.gather_disk_facts(vm_obj=self.vm)
        self.module.exit_json(**results)
 def get_cluster(self, cluster):
     if cluster not in self.clusters:
         self.clusters[cluster] = find_obj(self.content,
                                           [vim.ClusterComputeResource],
                                           cluster)
     return self.clusters[cluster]
Example #14
0
    def sanitize_disk_inputs(self):
        """
        Check correctness of disk input provided by user
        Returns: A list of dictionary containing disk information

        """
        disks_data = list()
        if not self.desired_disks:
            self.module.exit_json(changed=False, msg="No disks provided for virtual"
                                                     " machine '%s' for management." % self.vm.name)

        for disk_index, disk in enumerate(self.desired_disks):
            # Initialize default value for disk
            current_disk = dict(disk_index=disk_index,
                                state='present',
                                datastore=None,
                                autoselect_datastore=True,
                                disk_unit_number=0,
                                scsi_controller=0)
            # Check state
            if 'state' in disk:
                if disk['state'] not in ['absent', 'present']:
                    self.module.fail_json(msg="Invalid state provided '%s' for disk index [%s]."
                                              " State can be either - 'absent', 'present'" % (disk['state'],
                                                                                              disk_index))
                else:
                    current_disk['state'] = disk['state']

            if current_disk['state'] == 'present':
                # Select datastore or datastore cluster
                if 'datastore' in disk:
                    if 'autoselect_datastore' in disk:
                        self.module.fail_json(msg="Please specify either 'datastore' "
                                                  "or 'autoselect_datastore' for disk index [%s]" % disk_index)

                    # Check if given value is datastore or datastore cluster
                    datastore_name = disk['datastore']
                    datastore_cluster = find_obj(self.content, [vim.StoragePod], datastore_name)
                    if datastore_cluster:
                        # If user specified datastore cluster so get recommended datastore
                        datastore_name = self.get_recommended_datastore(datastore_cluster_obj=datastore_cluster)
                    # Check if get_recommended_datastore or user specified datastore exists or not
                    datastore = find_obj(self.content, [vim.Datastore], datastore_name)
                    if datastore is None:
                        self.module.fail_json(msg="Failed to find datastore named '%s' "
                                                  "in given configuration." % disk['datastore'])
                    current_disk['datastore'] = datastore
                    current_disk['autoselect_datastore'] = False
                elif 'autoselect_datastore' in disk:
                    # Find datastore which fits requirement
                    datastores = get_all_objs(self.content, [vim.Datastore])
                    if not datastores:
                        self.module.fail_json(msg="Failed to gather information about"
                                                  " available datastores in given datacenter.")
                    datastore = None
                    datastore_freespace = 0
                    for ds in datastores:
                        if ds.summary.freeSpace > datastore_freespace:
                            # If datastore field is provided, filter destination datastores
                            datastore = ds
                            datastore_freespace = ds.summary.freeSpace
                    current_disk['datastore'] = datastore

                if 'datastore' not in disk and 'autoselect_datastore' not in disk:
                    self.module.fail_json(msg="Either 'datastore' or 'autoselect_datastore' is"
                                              " required parameter while creating disk for "
                                              "disk index [%s]." % disk_index)

                if [x for x in disk.keys() if x.startswith('size_') or x == 'size']:
                    # size, size_tb, size_gb, size_mb, size_kb
                    disk_size_parse_failed = False
                    if 'size' in disk:
                        size_regex = re.compile(r'(\d+(?:\.\d+)?)([tgmkTGMK][bB])')
                        disk_size_m = size_regex.match(disk['size'])
                        if disk_size_m:
                            expected = disk_size_m.group(1)
                            unit = disk_size_m.group(2)
                        else:
                            disk_size_parse_failed = True
                        try:
                            if re.match(r'\d+\.\d+', expected):
                                # We found float value in string, let's typecast it
                                expected = float(expected)
                            else:
                                # We found int value in string, let's typecast it
                                expected = int(expected)
                        except (TypeError, ValueError, NameError):
                            disk_size_parse_failed = True
                    else:
                        # Even multiple size_ parameter provided by user,
                        # consider first value only
                        param = [x for x in disk.keys() if x.startswith('size_')][0]
                        unit = param.split('_')[-1]
                        disk_size = disk[param]
                        if isinstance(disk_size, (float, int)):
                            disk_size = str(disk_size)

                        try:
                            if re.match(r'\d+\.\d+', disk_size):
                                # We found float value in string, let's typecast it
                                expected = float(disk_size)
                            else:
                                # We found int value in string, let's typecast it
                                expected = int(disk_size)
                        except (TypeError, ValueError, NameError):
                            disk_size_parse_failed = True

                    if disk_size_parse_failed:
                        # Common failure
                        self.module.fail_json(msg="Failed to parse disk size for disk index [%s],"
                                                  " please review value provided"
                                                  " using documentation." % disk_index)

                    disk_units = dict(tb=3, gb=2, mb=1, kb=0)
                    unit = unit.lower()
                    if unit in disk_units:
                        current_disk['size'] = expected * (1024 ** disk_units[unit])
                    else:
                        self.module.fail_json(msg="%s is not a supported unit for disk size for disk index [%s]."
                                                  " Supported units are ['%s']." % (unit,
                                                                                    disk_index,
                                                                                    "', '".join(disk_units.keys())))

                else:
                    # No size found but disk, fail
                    self.module.fail_json(msg="No size, size_kb, size_mb, size_gb or size_tb"
                                              " attribute found into disk index [%s] configuration." % disk_index)
            # Check SCSI controller key
            if 'scsi_controller' in disk:
                try:
                    temp_disk_controller = int(disk['scsi_controller'])
                except ValueError:
                    self.module.fail_json(msg="Invalid SCSI controller ID '%s' specified"
                                              " at index [%s]" % (disk['scsi_controller'], disk_index))
                if temp_disk_controller not in range(0, 4):
                    # Only 4 SCSI controllers are allowed per VM
                    self.module.fail_json(msg="Invalid SCSI controller ID specified [%s],"
                                              " please specify value between 0 to 3 only." % temp_disk_controller)
                current_disk['scsi_controller'] = temp_disk_controller
            else:
                self.module.fail_json(msg="Please specify 'scsi_controller' under disk parameter"
                                          " at index [%s], which is required while creating disk." % disk_index)
            # Check for disk unit number
            if 'unit_number' in disk:
                try:
                    temp_disk_unit_number = int(disk['unit_number'])
                except ValueError:
                    self.module.fail_json(msg="Invalid Disk unit number ID '%s'"
                                              " specified at index [%s]" % (disk['unit_number'], disk_index))
                if temp_disk_unit_number not in range(0, 16):
                    self.module.fail_json(msg="Invalid Disk unit number ID specified for disk [%s] at index [%s],"
                                              " please specify value between 0 to 15"
                                              " only (excluding 7)." % (temp_disk_unit_number, disk_index))

                if temp_disk_unit_number == 7:
                    self.module.fail_json(msg="Invalid Disk unit number ID specified for disk at index [%s],"
                                              " please specify value other than 7 as it is reserved"
                                              "for SCSI Controller" % disk_index)
                current_disk['disk_unit_number'] = temp_disk_unit_number

            else:
                self.module.fail_json(msg="Please specify 'unit_number' under disk parameter"
                                          " at index [%s], which is required while creating disk." % disk_index)

            # Type of Disk
            disk_type = disk.get('type', 'thick').lower()
            if disk_type not in ['thin', 'thick', 'eagerzeroedthick']:
                self.module.fail_json(msg="Invalid 'disk_type' specified for disk index [%s]. Please specify"
                                          " 'disk_type' value from ['thin', 'thick', 'eagerzeroedthick']." % disk_index)
            current_disk['disk_type'] = disk_type

            # SCSI Controller Type
            scsi_contrl_type = disk.get('scsi_type', 'paravirtual').lower()
            if scsi_contrl_type not in self.scsi_device_type.keys():
                self.module.fail_json(msg="Invalid 'scsi_type' specified for disk index [%s]. Please specify"
                                          " 'scsi_type' value from ['%s']" % (disk_index,
                                                                              "', '".join(self.scsi_device_type.keys())))
            current_disk['scsi_type'] = scsi_contrl_type

            disks_data.append(current_disk)
        return disks_data
Example #15
0
 def __init__(self, module):
     super(VMwareHostFactManager, self).__init__(module)
     self.host = find_obj(self.content, [vim.HostSystem], None)
     if self.host is None:
         self.module.fail_json(msg="Failed to find host system.")
Example #16
0
 def __init__(self, module):
     super(VMwareHostFactManager, self).__init__(module)
     self.host = find_obj(self.content, [vim.HostSystem], None)
     if self.host is None:
         self.module.fail_json(msg="Failed to find host system.")
Example #17
0
    def download(self):
        ovf_files = []
        result = dict(changed=False)

        # Thread class.
        class downloadThread(threading.Thread):
            def __init__(self):
                threading.Thread.__init__(self)

            def run(self):
                url = self.deviceUrl.url
                if (re.search(r"\*", url)): url = url.replace("*", self.host)
                file_name = url.split("/").pop()
                save_path = os.path.join(self.path, file_name)

                headers = {
                    "Content-Type": "application/x-vnd.vmware-streamVmdk"
                }
                r = requests.get(url,
                                 headers=headers,
                                 stream=True,
                                 verify=self.ssl_verify)
                if (r.status_code == 200):
                    total_byte = 0
                    with open(save_path, "wb") as f:
                        for chunk in r.iter_content(chunk_size=2048):
                            if (chunk):
                                f.write(chunk)
                                f.flush()
                            total_byte += len(chunk)

                    ovf_file = vim.OvfManager.OvfFile()
                    ovf_file.deviceId = self.deviceUrl.key
                    ovf_file.path = self.deviceUrl.targetId
                    ovf_file.size = total_byte
                    ovf_files.append(ovf_file)

        # Check exist of directory path.
        if (not (os.path.isdir(self.path))):
            self.module.fail_json(msg="%s not found" % self.path)

        # Get VirtualMachine obj.
        obj = find_obj(self.content, [vim.VirtualMachine], self.name)
        if (obj == None): self.module.fail_json(msg="%s not found" % self.name)

        # Export ovf.
        lease = obj.ExportVm()
        while True:
            if (lease.state == vim.HttpNfcLease.State.ready): break
            elif (lease.state == vim.HttpNfcLease.State.error):
                self.module.fail_json(msg="ovf export state error")
            time.sleep(1)

        threads = []
        for deviceUrl in lease.info.deviceUrl:
            if (deviceUrl.targetId):
                t = downloadThread()
                t.host = self.module.params["hostname"]
                t.ssl_verify = self.module.params["validate_certs"]
                t.path = self.path
                t.deviceUrl = deviceUrl
                t.start()
                threads.append(t)

        # Check Threads.
        while True:
            if (threads):
                for t in threads:
                    if (not (t.is_alive())):
                        lease.HttpNfcLeaseProgress(percent=int(100 /
                                                               len(threads)))
                        threads.remove(t)
                    else:
                        time.sleep(1)
            else:
                break

        # Create of ovf file.
        ovf_manager = self.content.ovfManager
        ovf_parameters = vim.OvfManager.CreateDescriptorParams()
        ovf_parameters.name = obj.name
        ovf_parameters.ovfFiles = ovf_files
        vm_descriptor_result = ovf_manager.CreateDescriptor(obj=obj,
                                                            cdp=ovf_parameters)
        save_path = os.path.join(self.path, "%s.ovf" % obj.name)
        with open(save_path, "w") as f:
            f.writelines(vm_descriptor_result.ovfDescriptor)

        # ovf download finish.
        lease.HttpNfcLeaseComplete()
        self.module.exit_json(**result)
Example #18
0
    def deploy(self):
        result = dict(changed=False)

        # Thread class
        class deployThread(threading.Thread):
            def __init__(self):
                threading.Thread.__init__(self)

            def run(self):
                url = self.deviceUrl.url
                if (re.search(r"\*", url)): url = url.replace("*", self.host)
                file_path = os.path.join(self.path, self.targetId)

                headers = {
                    "Content-Type": "application/x-vnd.vmware-streamVmdk"
                }
                requests.post(url,
                              headers=headers,
                              data=open(file_path, 'rb'),
                              verify=self.ssl_verify)

        # Check exist of directory path.
        if (not (os.path.isdir(self.path))):
            self.module.fail_json(msg="%s not found" % self.path)

        # Search of Managed Objects.
        datastore = find_obj(self.content, [vim.Datastore], self.datastore)
        if (datastore == None):
            self.module.fail_json(msg="%s not found" % self.datastore)
        folder = self.content.searchIndex.FindByInventoryPath(
            "/%s/%s" % (self.datacenter, self.folder))
        if (folder == None):
            self.module.fail_json(
                msg=
                "/%s/%s not found. There is no datacenter or folder, or both."
                % (self.datacenter, self.folder))
        if (self.resource_pool):
            resource_pool = find_obj(self.content, [vim.ResourcePool],
                                     self.resource_pool)
            if (resource_pool == None):
                self.module.fail_json(msg="%s not found" % self.resource_pool)
        elif (self.compute_resource):
            compute_resource = find_obj(self.content, [vim.ComputeResource],
                                        self.compute_resource)
            if (compute_resource == None):
                self.module.fail_json(msg="%s not found" %
                                      self.compute_resource)
            resource_pool = compute_resource.resourcePool
        else:
            self.module.fail_json(
                msg="Please specify resource_pool or compute_resource")

        # Get file list related to ovf.
        files = os.listdir(self.path)

        # Read ovf file.
        ovf_file_path = os.path.join(
            self.path,
            list(filter(lambda x: re.match(r".*\.ovf$", x), files))[0])
        if (os.path.isfile(ovf_file_path)):
            with open(ovf_file_path, "r") as f:
                ovf_file = xmltodict.parse(f.read())
                del ovf_file['Envelope']['VirtualSystem'][
                    'VirtualHardwareSection']['System'][
                        'vssd:VirtualSystemType']
                ovf_file = xmltodict.unparse(ovf_file)
        else:
            self.module.fail_json(msg="%s not found" % ovf_file_path)

        # Import ovf.
        spec_params = vim.OvfManager.CreateImportSpecParams()
        spec_params.entityName = self.name
        spec_params.diskProvisioning = self.disk_type
        ovf_manager = self.content.ovfManager
        ovf_import_spec = ovf_manager.CreateImportSpec(ovf_file, resource_pool,
                                                       datastore, spec_params)
        lease = resource_pool.ImportVApp(ovf_import_spec.importSpec, folder)

        while True:
            if (lease.state == vim.HttpNfcLease.State.ready): break
            elif (lease.state == vim.HttpNfcLease.State.error):
                self.module.fail_json(msg="ovf import state error")
            time.sleep(1)

        threads = []
        for deviceUrl in lease.info.deviceUrl:
            if (deviceUrl.targetId):
                t = deployThread()
                t.host = self.module.params["hostname"]
                t.ssl_verify = self.module.params["validate_certs"]
                t.path = self.path
                t.deviceUrl = deviceUrl
                t.targetId = deviceUrl.targetId
                t.start()
                threads.append(t)

        # Check Threads.
        while True:
            if (threads):
                for t in threads:
                    if (not (t.is_alive())):
                        lease.HttpNfcLeaseProgress(percent=int(100 /
                                                               len(threads)))
                        threads.remove(t)
                    else:
                        time.sleep(1)
            else:
                break

        lease.HttpNfcLeaseComplete()
        self.module.exit_json(**result)