def connect_bulk(self, si, logger, vcenter_data_model, request):
        """
        :param si:
        :param logger:
        :param VMwarevCenterResourceModel vcenter_data_model:
        :param request:
        :return:
        """
        self.vcenter_data_model = vcenter_data_model
        if vcenter_data_model.reserved_networks:
            self.reserved_networks = [name.strip() for name in vcenter_data_model.reserved_networks.split(',')]

        dvswitch_location = VMLocation.create_from_full_path(vcenter_data_model.default_dvswitch)

        self.dv_switch_path = VMLocation.combine([vcenter_data_model.default_datacenter, dvswitch_location.path])
        self.dv_switch_name = dvswitch_location.name
        self.port_group_path = vcenter_data_model.default_port_group_location
        self.default_network = VMLocation.combine(
            [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network])
        holder = DeployDataHolder(jsonpickle.decode(request))

        mappings = self._map_requsets(holder.driverRequest.actions)

        pool = ThreadPool()
        async_results = self._run_async_connection_actions(si, mappings, pool, logger)

        results = self._get_async_results(async_results, pool)

        return results
Пример #2
0
 def _update_deploy_from_image_vm_location(self, data_holder, folder_manager, logger, si, vcenter_resource_model):
     vm_location = data_holder.image_params.vm_location or vcenter_resource_model.vm_location
     folder_path = VMLocation.combine([vcenter_resource_model.default_datacenter, vm_location])
     folder_manager.get_or_create_vcenter_folder(si,
                                                 logger,
                                                 folder_path,
                                                 DEPLOYED_APPS)
     data_holder.image_params.vm_location = VMLocation.combine([vm_location, DEPLOYED_APPS])
     logger.info('VM will be deployed to {0}'.format(data_holder.image_params.vm_location))
Пример #3
0
    def connect_bulk(self, si, logger, vcenter_data_model, request):
        """
        :param si:
        :param logger:
        :param VMwarevCenterResourceModel vcenter_data_model:
        :param request:
        :return:
        """
        self.logger = logger

        self.logger.info('Apply connectivity changes has started')
        self.logger.debug(
            'Apply connectivity changes has started with the requet: {0}'.
            format(request))

        holder = DeployDataHolder(jsonpickle.decode(request))

        self.vcenter_data_model = vcenter_data_model
        if vcenter_data_model.reserved_networks:
            self.reserved_networks = [
                name.strip()
                for name in vcenter_data_model.reserved_networks.split(',')
            ]

        if not vcenter_data_model.default_dvswitch:
            return self._handle_no_dvswitch_error(holder)

        dvswitch_location = VMLocation.create_from_full_path(
            vcenter_data_model.default_dvswitch)

        self.dv_switch_path = VMLocation.combine(
            [vcenter_data_model.default_datacenter, dvswitch_location.path])
        self.dv_switch_name = dvswitch_location.name
        self.default_network = VMLocation.combine([
            vcenter_data_model.default_datacenter,
            vcenter_data_model.holding_network
        ])

        mappings = self._map_requsets(holder.driverRequest.actions)
        self.logger.debug('Connectivity actions mappings: {0}'.format(
            jsonpickle.encode(mappings, unpicklable=False)))

        pool = ThreadPool()
        async_results = self._run_async_connection_actions(
            si, mappings, pool, logger)

        results = self._get_async_results(async_results, pool)
        self.logger.info('Apply connectivity changes done')
        self.logger.debug(
            'Apply connectivity has finished with the results: {0}'.format(
                jsonpickle.encode(results, unpicklable=False)))
        return results
    def disconnect_from_networks(self, si, logger, vcenter_data_model, vm_uuid, vm_network_remove_mappings):

        default_network = VMLocation.combine(
            [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network])

        vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid)
        if not vm:
            raise ValueError('VM having UUID {0} not found'.format(vm_uuid))

        default_network = self.pyvmomi_service.get_network_by_full_name(si, default_network)

        mappings = []
        vnics = []
        for vm_network_remove_mapping in vm_network_remove_mappings:
            vnic = self.pyvmomi_service.get_vnic_by_mac_address(vm, vm_network_remove_mapping.mac_address)
            if vnic is None:
                raise KeyError('VNIC having MAC address {0} not found on VM having UUID {1}'
                               .format(vm_network_remove_mapping.mac_address, vm_uuid))

            vnics.append(vnic)
            mappings.append(VNicDeviceMapper(connect=False, network=default_network,
                                             requested_vnic=vm_network_remove_mapping.mac_address,
                                             vnic=vnic, mac=vm_network_remove_mapping.mac_address))

        networks_to_remove = self.port_group_configurer.get_networks_on_vnics(vm, vnics, logger)

        res = self.port_group_configurer.update_vnic_by_mapping(vm, mappings, logger)
        self.port_group_configurer.erase_network_by_mapping(networks_to_remove, vcenter_data_model.reserved_networks,
                                                            logger)
        return res
Пример #5
0
    def refresh_ip(self, si, logger, session, vcenter_data_model, vm_uuid, resource_name, cancellation_context,app_request_json):
        """
        Refreshes IP address of virtual machine and updates Address property on the resource

        :param vim.ServiceInstance si: py_vmomi service instance
        :param logger:
        :param vCenterShell.driver.SecureCloudShellApiSession session: cloudshell session
        :param str vm_uuid: UUID of Virtual Machine
        :param str resource_name: Logical resource name to update address property on
        :param VMwarevCenterResourceModel vcenter_data_model: the vcenter data model attributes
        :param cancellation_context:
        """
        self._do_not_run_on_static_vm(app_request_json=app_request_json)

        default_network = VMLocation.combine(
            [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network])

        resource = session.GetResourceDetails(resource_name)

        match_function = self.ip_manager.get_ip_match_function(self._get_ip_refresh_ip_regex(resource))

        timeout = self._get_ip_refresh_timeout(resource)

        vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid)

        ip_res = self.ip_manager.get_ip(vm, default_network, match_function, cancellation_context, timeout, logger)

        if ip_res.reason == IpReason.Timeout:
            raise ValueError('IP address of VM \'{0}\' could not be obtained during {1} seconds'
                             .format(resource_name, timeout))

        if ip_res.reason == IpReason.Success:
            session.UpdateResourceAddress(resource_name, ip_res.ip_address)

            return ip_res.ip_address
Пример #6
0
    def get_vm_full_path(self, si, vm):
        """
        :param vm: vim.VirtualMachine
        :return:
        """
        folder_name = None
        folder = vm.parent

        if folder:
            folder_name = folder.name
            folder_parent = folder.parent

            while folder_parent and folder_parent.name and folder_parent != si.content.rootFolder and not isinstance(
                    folder_parent, vim.Datacenter):
                folder_name = folder_parent.name + '/' + folder_name
                try:
                    folder_parent = folder_parent.parent
                except Exception:
                    break
            # at this stage we receive a path like this: vm/FOLDER1/FOLDER2;
            # we're not interested in the "vm" part, so we throw that away
            folder_name = '/'.join(folder_name.split('/')[1:])
        # ok, now we're adding the vm name; btw, if there is no folder, that's cool, just return vm.name
        return VMLocation.combine([folder_name, vm.name
                                   ]) if folder_name else vm.name
Пример #7
0
    def get_or_create_vcenter_folder(self, si, logger, path, folder_name):
        logger.info('Getting or creating {0} in {1}'.format(folder_name, path))
        folder_parent = self.pv_service.get_folder(si, path)
        if not folder_parent:
            logger.error('Could not find {0}'.format(path))
            raise Exception("Could not find " + path)

        vcenter_folder_path = VMLocation.combine([path, folder_name])

        if vcenter_folder_path not in self.locks.keys():
            with self.locks_lock:
                if vcenter_folder_path not in self.locks.keys():
                    self.locks[vcenter_folder_path] = Lock()

        vcenter_folder = self.pv_service.get_folder(si, vcenter_folder_path)
        if not vcenter_folder:
            with self.locks[vcenter_folder_path]:
                vcenter_folder = self.pv_service.get_folder(si, vcenter_folder_path)
                if not vcenter_folder:
                    logger.info('{0} was not found under {1}, creating...'.format(folder_name, path))
                    folder_parent.CreateFolder(folder_name)
                    logger.info('{0} created in path {1}'.format(folder_name, path))
                else:
                    logger.info('{0} already exists'.format(folder_name))

        return vcenter_folder
Пример #8
0
    def _deploy_a_clone(self, si, logger, app_name, template_name, other_params, vcenter_data_model, snapshot=''):
        # generate unique name
        vm_name = self.name_generator(app_name)

        VCenterDetailsFactory.set_deplyment_vcenter_params(
            vcenter_resource_model=vcenter_data_model, deploy_params=other_params)

        template_name = VMLocation.combine([other_params.default_datacenter,
                                            template_name])

        params = self.pv_service.CloneVmParameters(si=si,
                                                   template_name=template_name,
                                                   vm_name=vm_name,
                                                   vm_folder=other_params.vm_location,
                                                   datastore_name=other_params.vm_storage,
                                                   cluster_name=other_params.vm_cluster,
                                                   resource_pool=other_params.vm_resource_pool,
                                                   power_on=other_params.auto_power_on,
                                                   snapshot=snapshot)

        clone_vm_result = self.pv_service.clone_vm(clone_params=params, logger=logger)
        if clone_vm_result.error:
            raise Exception(clone_vm_result.error)

        return DeployResult(vm_name=vm_name,
                            vm_uuid=clone_vm_result.vm.summary.config.uuid,
                            cloud_provider_resource_name=other_params.vcenter_name,
                            ip_regex=other_params.ip_regex,
                            refresh_ip_timeout=other_params.refresh_ip_timeout,
                            auto_power_on=other_params.auto_power_on,
                            auto_power_off=other_params.auto_power_off,
                            wait_for_ip=other_params.wait_for_ip,
                            auto_delete=other_params.auto_delete,
                            autoload=other_params.autoload
                            )
Пример #9
0
    def clone_vm(self, clone_params, logger):
        """
        Clone a VM from a template/VM and return the vm oject or throws argument is not valid

        :param clone_params: CloneVmParameters =
        :param logger:
        """
        result = self.CloneVmResult()

        if not isinstance(clone_params.si, self.vim.ServiceInstance):
            result.error = 'si must be init as ServiceInstance'
            return result

        if clone_params.template_name is None:
            result.error = 'template_name param cannot be None'
            return result

        if clone_params.vm_name is None:
            result.error = 'vm_name param cannot be None'
            return result

        if clone_params.vm_folder is None:
            result.error = 'vm_folder param cannot be None'
            return result

        datacenter = self.get_datacenter(clone_params)

        dest_folder = self._get_destination_folder(clone_params)

        vm_location = VMLocation.create_from_full_path(clone_params.template_name)

        template = self._get_template(clone_params, vm_location)

        datastore = self._get_datastore(clone_params)

        resource_pool, host = self._get_resource_pool(datacenter.name, clone_params)

        if not resource_pool and not host:
            raise ValueError('The specifed host, cluster or resource pool could not be found')

        '# set relo_spec'
        placement = self.vim.vm.RelocateSpec()
        placement.datastore = datastore
        if resource_pool:
            placement.pool = resource_pool
        if host:
            placement.host = host

        clone_spec = self.vim.vm.CloneSpec()
        clone_spec.location = placement
        clone_spec.powerOn = clone_params.power_on

        logger.info("cloning VM...")

        task = template.Clone(folder=dest_folder, name=clone_params.vm_name, spec=clone_spec)
        vm = self.wait_for_task(task, logger)
        result.vm = vm
        return result
Пример #10
0
    def load_vm_uuid_by_name(self, si, vcenter_data_model, vm_name):
        """
        Returns the vm uuid
        :param si: Service instance to the vcenter
        :param vcenter_data_model: vcenter data model
        :param vm_name: the vm name
        :return: str uuid
        """
        path = VMLocation.combine([vcenter_data_model.default_datacenter, vm_name])
        paths = path.split('/')
        name = paths[len(paths) - 1]
        path = VMLocation.combine(paths[:len(paths) - 1])
        vm = self.pv_service.find_vm_by_name(si, path, name)
        if not vm:
            raise ValueError('Could not find the vm in the given path: {0}/{1}'.format(path, name))

        if isinstance(vm, vim.VirtualMachine):
            return vm.config.uuid

        raise ValueError('The given object is not a vm: {0}/{1}'.format(path, name))
Пример #11
0
    def disconnect(self,
                   si,
                   logger,
                   vcenter_data_model,
                   vm_uuid,
                   network_name=None,
                   vm=None):
        """
        disconnect network adapter of the vm. If 'network_name' = None - disconnect ALL interfaces
        :param <str> si:
        :param logger:
        :param VMwarevCenterResourceModel vcenter_data_model:
        :param <str> vm_uuid: the uuid of the vm
        :param <str | None> network_name: the name of the specific network to disconnect
        :param <pyvmomi vm object> vm: If the vm obj is None will use vm_uuid to fetch the object
        :return: Started Task
        """
        logger.debug(
            "Disconnect Interface VM: '{0}' Network: '{1}' ...".format(
                vm_uuid, network_name or "ALL"))
        if vm is None:
            vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid)
            if not vm:
                return "Warning: failed to locate vm {0} in vCenter".format(
                    vm_uuid)

        if network_name:
            network = self.pyvmomi_service.vm_get_network_by_name(
                vm, network_name)
            if network is None:
                raise KeyError('Network not found ({0})'.format(network_name))
        else:
            network = None

        network_full_name = VMLocation.combine([
            vcenter_data_model.default_datacenter,
            vcenter_data_model.holding_network
        ])

        default_network = self.pyvmomi_service.get_network_by_full_name(
            si, network_full_name)
        if network:
            return self.port_group_configurer.disconnect_network(
                vm,
                network,
                default_network,
                vcenter_data_model.reserved_networks,
                logger=logger)
        else:
            return self.port_group_configurer.disconnect_all_networks(
                vm,
                default_network,
                vcenter_data_model.reserved_networks,
                logger=logger)
    def connect_bulk(self, si, logger, vcenter_data_model, request):
        """
        :param si:
        :param logger:
        :param VMwarevCenterResourceModel vcenter_data_model:
        :param request:
        :return:
        """
        self.logger = logger

        self.logger.info('Apply connectivity changes has started')
        self.logger.debug('Apply connectivity changes has started with the requet: {0}'.format(request))

        holder = DeployDataHolder(jsonpickle.decode(request))

        self.vcenter_data_model = vcenter_data_model
        if vcenter_data_model.reserved_networks:
            self.reserved_networks = [name.strip() for name in vcenter_data_model.reserved_networks.split(',')]

        if not vcenter_data_model.default_dvswitch:
            return self._handle_no_dvswitch_error(holder)

        dvswitch_location = VMLocation.create_from_full_path(vcenter_data_model.default_dvswitch)

        self.dv_switch_path = VMLocation.combine([vcenter_data_model.default_datacenter, dvswitch_location.path])
        self.dv_switch_name = dvswitch_location.name
        self.default_network = VMLocation.combine(
            [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network])

        mappings = self._map_requsets(holder.driverRequest.actions)
        self.logger.debug('Connectivity actions mappings: {0}'.format(jsonpickle.encode(mappings, unpicklable=False)))

        pool = ThreadPool()
        async_results = self._run_async_connection_actions(si, mappings, pool, logger)

        results = self._get_async_results(async_results, pool)
        self.logger.info('Apply connectivity changes done')
        self.logger.debug('Apply connectivity has finished with the results: {0}'.format(jsonpickle.encode(results,
                                                                                                           unpicklable=False)))
        return results
Пример #13
0
    def delete(self, delete_saved_app_actions, cancellation_context, pool):
        self.logger.info('Delete saved sandbox started')

        tasks = self._get_delete_tasks(delete_saved_app_actions)

        if self.cs.check_if_cancelled(cancellation_context):
            raise Exception('Delete saved sandbox was cancelled')

        artifacts = [(artifact, cancellation_context) for task in tasks
                     for artifact in task.artifacts]

        pool.map(self._get_rid_of_vm_if_found, artifacts)

        if self.cs.check_if_cancelled(cancellation_context):
            raise Exception('Delete saved sandbox was cancelled')

        root_path = VMLocation.combine([
            self.vcenter_data_model.default_datacenter,
            self.vcenter_data_model.vm_location
        ])

        saved_sandbox_paths = {
            self._get_saved_sandbox_id_full_path(
                root_path, task.action.actionParams.savedSandboxId)
            for task in tasks
        }

        self.logger.info('Saved sandbox path/s: {0}'.format(
            ', '.join(saved_sandbox_paths)))

        for path in saved_sandbox_paths:
            self.logger.info(
                'Going to dispose of saved sandbox {0}'.format(path))
            folder = self.pv_service.get_folder(self.si, path)
            if not folder:
                folder_not_found_msg = 'Could not find folder: {0}'.format(
                    path)
                self.logger.info(folder_not_found_msg)
                result = SUCCESS
                msg = folder_not_found_msg
            else:
                self.logger.info('Found folder: {0}'.format(path))
                result = self.folder_manager.delete_folder(folder, self.logger)
                msg = ''
            [
                task.set_result(result) and task.set_msg(msg) for task in tasks
                if task.action.actionParams.savedSandboxId in path
            ]

        return [task.DeleteSavedAppResult() for task in tasks]
Пример #14
0
    def load_vm_uuid_by_name(self, si, vcenter_data_model, vm_name):
        """
        Returns the vm uuid
        :param si: Service instance to the vcenter
        :param vcenter_data_model: vcenter data model
        :param vm_name: the vm name
        :return: str uuid
        """
        path = VMLocation.combine(
            [vcenter_data_model.default_datacenter, vm_name])
        paths = path.split('/')
        name = paths[len(paths) - 1]
        path = VMLocation.combine(paths[:len(paths) - 1])
        vm = self.pv_service.find_vm_by_name(si, path, name)
        if not vm:
            raise ValueError(
                'Could not find the vm in the given path: {0}/{1}'.format(
                    path, name))

        if isinstance(vm, vim.VirtualMachine):
            return vm.config.uuid

        raise ValueError('The given object is not a vm: {0}/{1}'.format(
            path, name))
Пример #15
0
    def _deploy_a_clone(self, si, logger, app_name, template_name, other_params, vcenter_data_model, reservation_id,
                        cancellation_context,
                        snapshot=''):
        """
        :rtype DeployAppResult:
        """
        # generate unique name
        vm_name = self.name_generator(app_name, reservation_id)

        VCenterDetailsFactory.set_deplyment_vcenter_params(
            vcenter_resource_model=vcenter_data_model, deploy_params=other_params)

        template_name = VMLocation.combine([other_params.default_datacenter,
                                            template_name])

        params = self.pv_service.CloneVmParameters(si=si,
                                                   template_name=template_name,
                                                   vm_name=vm_name,
                                                   vm_folder=other_params.vm_location,
                                                   datastore_name=other_params.vm_storage,
                                                   cluster_name=other_params.vm_cluster,
                                                   resource_pool=other_params.vm_resource_pool,
                                                   power_on=False,
                                                   snapshot=snapshot)

        if cancellation_context.is_cancelled:
            raise Exception("Action 'Clone VM' was cancelled.")

        clone_vm_result = self.pv_service.clone_vm(clone_params=params, logger=logger,
                                                   cancellation_context=cancellation_context)
        if clone_vm_result.error:
            raise Exception(clone_vm_result.error)

        # remove a new created vm due to cancellation
        if cancellation_context.is_cancelled:
            self.pv_service.destroy_vm(vm=clone_vm_result.vm, logger=logger)
            raise Exception("Action 'Clone VM' was cancelled.")

        vm_details_data = self._safely_get_vm_details(clone_vm_result.vm, vm_name, vcenter_data_model, other_params,
                                                      logger)

        return DeployAppResult(vmName=vm_name,
                               vmUuid=clone_vm_result.vm.summary.config.uuid,
                               vmDetailsData=vm_details_data,
                               deployedAppAdditionalData={'ip_regex': other_params.ip_regex,
                                                          'refresh_ip_timeout': other_params.refresh_ip_timeout,
                                                          'auto_power_off': convert_to_bool(other_params.auto_power_off),
                                                          'auto_delete': convert_to_bool(other_params.auto_delete)})
Пример #16
0
 def _disconnect_all_quali_created_networks(self, result):
     thread_id = threading.current_thread().ident
     self.logger.info(
         '{0} clearing networks configured by cloudshell on saved sandbox source app {1}'
         .format(thread_id, result.vmName))
     network_full_name = VMLocation.combine([
         self.vcenter_data_model.default_datacenter,
         self.vcenter_data_model.holding_network
     ])
     self.logger.info('{0} Holding network is {1}'.format(
         thread_id, network_full_name))
     default_network = self.pv_service.get_network_by_full_name(
         self.si, network_full_name)
     vm = self.pv_service.get_vm_by_uuid(self.si, result.vmUuid)
     self.pg_configurer.disconnect_all_networks_if_created_by_quali(
         vm, default_network, self.vcenter_data_model.reserved_networks,
         self.logger)
Пример #17
0
    def deploy_from_template(self, si, logger, data_holder, resource_context):
        """
        :param si:
        :param logger:
        :type data_holder: DeployFromTemplateDetails
        :type resource_context
        :return:
        """
        # generate unique name
        vm_name = self.name_generator(data_holder.app_name)

        vcenter_resource_model = self.resource_model_parser.convert_to_resource_model(resource_context,
                                                                                      VMwarevCenterResourceModel)

        template_resource_model = data_holder.template_resource_model
        VCenterDetailsFactory.set_deplyment_vcenter_params(
            vcenter_resource_model=vcenter_resource_model, deploy_params=template_resource_model)

        template_name = VMLocation.combine([template_resource_model.default_datacenter,
                                            template_resource_model.vcenter_template])

        params = self.pv_service.CloneVmParameters(si=si,
                                                   template_name=template_name,
                                                   vm_name=vm_name,
                                                   vm_folder=template_resource_model.vm_location,
                                                   datastore_name=template_resource_model.vm_storage,
                                                   cluster_name=template_resource_model.vm_cluster,
                                                   resource_pool=template_resource_model.vm_resource_pool,
                                                   power_on=template_resource_model.auto_power_on)

        clone_vm_result = self.pv_service.clone_vm(clone_params=params, logger=logger)
        if clone_vm_result.error:
            raise Exception(clone_vm_result.error)

        return DeployResult(vm_name=vm_name,
                            vm_uuid=clone_vm_result.vm.summary.config.uuid,
                            cloud_provider_resource_name=template_resource_model.vcenter_name,
                            ip_regex=template_resource_model.ip_regex,
                            refresh_ip_timeout=template_resource_model.refresh_ip_timeout,
                            auto_power_on=template_resource_model.auto_power_on,
                            auto_power_off=template_resource_model.auto_power_off,
                            wait_for_ip=template_resource_model.wait_for_ip,
                            auto_delete=template_resource_model.auto_delete,
                            autoload=template_resource_model.autoload
                            )
Пример #18
0
    def disconnect_from_networks(self, si, logger, vcenter_data_model, vm_uuid,
                                 vm_network_remove_mappings):

        default_network = VMLocation.combine([
            vcenter_data_model.default_datacenter,
            vcenter_data_model.holding_network
        ])

        vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid)
        if not vm:
            raise ValueError('VM having UUID {0} not found'.format(vm_uuid))

        default_network = self.pyvmomi_service.get_network_by_full_name(
            si, default_network)

        mappings = []
        vnics = []
        for vm_network_remove_mapping in vm_network_remove_mappings:
            vnic = self.pyvmomi_service.get_vnic_by_mac_address(
                vm, vm_network_remove_mapping.mac_address)
            if vnic is None:
                raise KeyError(
                    'VNIC having MAC address {0} not found on VM having UUID {1}'
                    .format(vm_network_remove_mapping.mac_address, vm_uuid))

            vnics.append(vnic)
            mappings.append(
                VNicDeviceMapper(
                    connect=False,
                    network=default_network,
                    requested_vnic=vm_network_remove_mapping.mac_address,
                    vnic=vnic,
                    mac=vm_network_remove_mapping.mac_address))

        networks_to_remove = self.port_group_configurer.get_networks_on_vnics(
            vm, vnics, logger)

        res = self.port_group_configurer.update_vnic_by_mapping(
            vm, mappings, logger)
        self.port_group_configurer.erase_network_by_mapping(
            networks_to_remove, vcenter_data_model.reserved_networks, logger)
        return res
Пример #19
0
    def refresh_ip(self, si, logger, session, vcenter_data_model,
                   resource_model, cancellation_context, app_request_json):
        """
        Refreshes IP address of virtual machine and updates Address property on the resource

        :param vim.ServiceInstance si: py_vmomi service instance
        :param logger:
        :param vCenterShell.driver.SecureCloudShellApiSession session: cloudshell session
        :param GenericDeployedAppResourceModel resource_model: UUID of Virtual Machine
        :param VMwarevCenterResourceModel vcenter_data_model: the vcenter data model attributes
        :param cancellation_context:
        """
        self._do_not_run_on_static_vm(app_request_json=app_request_json)

        default_network = VMLocation.combine([
            vcenter_data_model.default_datacenter,
            vcenter_data_model.holding_network
        ])

        match_function = self.ip_manager.get_ip_match_function(
            self._get_ip_refresh_ip_regex(resource_model.vm_custom_params))

        timeout = self._get_ip_refresh_timeout(resource_model.vm_custom_params)

        vm = self.pyvmomi_service.find_by_uuid(si, resource_model.vm_uuid)

        ip_res = self.ip_manager.get_ip(vm, default_network, match_function,
                                        cancellation_context, timeout, logger)

        if ip_res.reason == IpReason.Timeout:
            raise ValueError(
                'IP address of VM \'{0}\' could not be obtained during {1} seconds'
                .format(resource_model.fullname, timeout))

        if ip_res.reason == IpReason.Success:
            self._update_resource_address_with_retry(
                session=session,
                resource_name=resource_model.fullname,
                ip_address=ip_res.ip_address)

            return ip_res.ip_address
Пример #20
0
    def refresh_ip(self, si, logger, session, vcenter_data_model, vm_uuid,
                   resource_name, cancellation_context):
        """
        Refreshes IP address of virtual machine and updates Address property on the resource

        :param vim.ServiceInstance si: py_vmomi service instance
        :param logger:
        :param vCenterShell.driver.SecureCloudShellApiSession session: cloudshell session
        :param str vm_uuid: UUID of Virtual Machine
        :param str resource_name: Logical resource name to update address property on
        :param VMwarevCenterResourceModel vcenter_data_model: the vcenter data model attributes
        :param cancellation_context:
        """
        default_network = VMLocation.combine([
            vcenter_data_model.default_datacenter,
            vcenter_data_model.holding_network
        ])

        resource = session.GetResourceDetails(resource_name)

        match_function = self.ip_manager.get_ip_match_function(
            self._get_ip_refresh_ip_regex(resource))

        timeout = self._get_ip_refresh_timeout(resource)

        vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid)

        ip_res = self.ip_manager.get_ip(vm, default_network, match_function,
                                        cancellation_context, timeout, logger)

        if ip_res.reason == IpReason.Timeout:
            raise ValueError(
                'IP address of VM \'{0}\' could not be obtained during {1} seconds'
                .format(resource_name, timeout))

        if ip_res.reason == IpReason.Success:
            session.UpdateResourceAddress(resource_name, ip_res.ip_address)

            return ip_res.ip_address
Пример #21
0
    def set_deplyment_vcenter_params(vcenter_resource_model, deploy_params):
        """
        Sets the vcenter parameters if not already set at the deployment option
        :param deploy_params:  vCenterVMFromTemplateResourceModel or vCenterVMFromImageResourceModel
        :type vcenter_resource_model: VMwarevCenterResourceModel
        """
        # Override attributes
        deploy_params.vm_cluster = deploy_params.vm_cluster or vcenter_resource_model.vm_cluster
        deploy_params.vm_storage = deploy_params.vm_storage or vcenter_resource_model.vm_storage
        deploy_params.vm_resource_pool = deploy_params.vm_resource_pool or vcenter_resource_model.vm_resource_pool
        deploy_params.vm_location = deploy_params.vm_location or vcenter_resource_model.vm_location
        deploy_params.default_datacenter = vcenter_resource_model.default_datacenter

        if not deploy_params.vm_cluster:
            raise ValueError('VM Cluster is empty')
        if not deploy_params.vm_storage:
            raise ValueError('VM Storage is empty')
        if not deploy_params.vm_location:
            raise ValueError('VM Location is empty')
        if not deploy_params.default_datacenter:
            raise ValueError('Default Datacenter attribute on VMWare vCenter is empty')

        deploy_params.vm_location = VMLocation.combine([deploy_params.default_datacenter, deploy_params.vm_location])
    def disconnect(self, si, logger, vcenter_data_model, vm_uuid, network_name=None, vm=None):
        """
        disconnect network adapter of the vm. If 'network_name' = None - disconnect ALL interfaces
        :param <str> si:
        :param logger:
        :param VMwarevCenterResourceModel vcenter_data_model:
        :param <str> vm_uuid: the uuid of the vm
        :param <str | None> network_name: the name of the specific network to disconnect
        :param <pyvmomi vm object> vm: If the vm obj is None will use vm_uuid to fetch the object
        :return: Started Task
        """
        logger.debug("Disconnect Interface VM: '{0}' Network: '{1}' ...".format(vm_uuid, network_name or "ALL"))
        if vm is None:
            vm = self.pyvmomi_service.find_by_uuid(si, vm_uuid)
            if not vm:
                return "Warning: failed to locate vm {0} in vCenter".format(vm_uuid)

        if network_name:
            network = self.pyvmomi_service.vm_get_network_by_name(vm, network_name)
            if network is None:
                raise KeyError('Network not found ({0})'.format(network_name))
        else:
            network = None

        network_full_name = VMLocation.combine(
            [vcenter_data_model.default_datacenter, vcenter_data_model.holding_network])

        default_network = self.pyvmomi_service.get_network_by_full_name(si, network_full_name)
        if network:
            return self.port_group_configurer.disconnect_network(vm, network, default_network,
                                                                 vcenter_data_model.reserved_networks,
                                                                 logger=logger)
        else:
            return self.port_group_configurer.disconnect_all_networks(vm, default_network,
                                                                      vcenter_data_model.reserved_networks,
                                                                      logger=logger)
    def test_create_from_full_path(self):
        vm_location = VMLocation.create_from_full_path('QualiSB/Alex/test')

        self.assertEqual(vm_location.path, 'QualiSB/Alex')
        self.assertEqual(vm_location.name, 'test')
Пример #24
0
    def clone_vm(self, clone_params, logger):
        """
        Clone a VM from a template/VM and return the vm oject or throws argument is not valid

        :param clone_params: CloneVmParameters =
        :param logger:
        """
        result = self.CloneVmResult()

        if not isinstance(clone_params.si, self.vim.ServiceInstance):
            result.error = 'si must be init as ServiceInstance'
            return result

        if clone_params.template_name is None:
            result.error = 'template_name param cannot be None'
            return result

        if clone_params.vm_name is None:
            result.error = 'vm_name param cannot be None'
            return result

        if clone_params.vm_folder is None:
            result.error = 'vm_folder param cannot be None'
            return result

        datacenter = self.get_datacenter(clone_params)

        dest_folder = self._get_destination_folder(clone_params)

        vm_location = VMLocation.create_from_full_path(clone_params.template_name)

        template = self._get_template(clone_params, vm_location)

        snapshot = self._get_snapshot(clone_params, template)

        resource_pool, host = self._get_resource_pool(datacenter.name, clone_params)

        if not resource_pool and not host:
            raise ValueError('The specifed host, cluster or resource pool could not be found')

        '# set relo_spec'
        placement = self.vim.vm.RelocateSpec()
        if resource_pool:
            placement.pool = resource_pool
        if host:
            placement.host = host

        clone_spec = self.vim.vm.CloneSpec()

        if snapshot:
            clone_spec.snapshot = snapshot
            clone_spec.template = False
            placement.diskMoveType = 'createNewChildDiskBacking'

        placement.datastore = self._get_datastore(clone_params)

        # after deployment the vm must be powered off and will be powered on if needed by orchestration driver
        clone_spec.location = placement
        # clone_params.power_on
        # due to hotfix 1 for release 1.0,
        clone_spec.powerOn = False

        logger.info("cloning VM...")
        try:
            task = template.Clone(folder=dest_folder, name=clone_params.vm_name, spec=clone_spec)
            vm = self.task_waiter.wait_for_task(task=task, logger=logger, action_name='Clone VM')

        except vim.fault.NoPermission as error:
            logger.error("vcenter returned - no permission: {0}".format(error))
            raise Exception('Permissions is not set correctly, please check the log for more info.')
        except Exception as e:
            logger.error("error deploying: {0}".format(e))
            raise Exception('Error has occurred while deploying, please look at the log for more info.')

        result.vm = vm
        return result
Пример #25
0
    def clone_vm(self, clone_params, logger, cancellation_context):
        """
        Clone a VM from a template/VM and return the vm oject or throws argument is not valid

        :param cancellation_context:
        :param clone_params: CloneVmParameters =
        :param logger:
        """

        result = self.CloneVmResult()

        if not isinstance(clone_params.si, self.vim.ServiceInstance):
            result.error = 'si must be init as ServiceInstance'
            return result

        if clone_params.template_name is None:
            result.error = 'template_name param cannot be None'
            return result

        if clone_params.vm_name is None:
            result.error = 'vm_name param cannot be None'
            return result

        if clone_params.vm_folder is None:
            result.error = 'vm_folder param cannot be None'
            return result

        datacenter = self.get_datacenter(clone_params)

        dest_folder = self._get_destination_folder(clone_params)

        vm_location = VMLocation.create_from_full_path(
            clone_params.template_name)

        template = self._get_template(clone_params, vm_location)

        snapshot = self._get_snapshot(clone_params, template)

        resource_pool, host = self.get_resource_pool(datacenter.name,
                                                     clone_params)

        if not resource_pool and not host:
            raise ValueError(
                'The specifed host, cluster or resource pool could not be found'
            )

        '# set relo_spec'
        placement = self.vim.vm.RelocateSpec()
        if resource_pool:
            placement.pool = resource_pool
        if host:
            placement.host = host

        clone_spec = self.vim.vm.CloneSpec()

        if snapshot:
            clone_spec.snapshot = snapshot
            clone_spec.template = False
            placement.diskMoveType = 'createNewChildDiskBacking'

        placement.datastore = self._get_datastore(clone_params)

        # after deployment the vm must be powered off and will be powered on if needed by orchestration driver
        clone_spec.location = placement
        # clone_params.power_on
        # due to hotfix 1 for release 1.0,
        clone_spec.powerOn = False

        logger.info("cloning VM...")
        try:
            task = template.Clone(folder=dest_folder,
                                  name=clone_params.vm_name,
                                  spec=clone_spec)
            vm = self.task_waiter.wait_for_task(
                task=task,
                logger=logger,
                action_name='Clone VM',
                cancellation_context=cancellation_context)
        except TaskFaultException:
            raise
        except vim.fault.NoPermission as error:
            logger.error("vcenter returned - no permission: {0}".format(error))
            raise Exception(
                'Permissions is not set correctly, please check the log for more info.'
            )
        except Exception as e:
            logger.error("error deploying: {0}".format(e))
            raise Exception(
                'Error has occurred while deploying, please look at the log for more info.'
            )

        result.vm = vm
        return result
    def test_combine(self):
        combined_path = VMLocation.combine(['QualiSB', 'Alex'])

        self.assertEqual(combined_path, 'QualiSB/Alex')
Пример #27
0
 def _get_saved_sandbox_id_full_path(self, vm_location, saved_sandbox_id):
     saved_sandbox_path = VMLocation.combine(
         [vm_location, SAVED_SANDBOXES, saved_sandbox_id])
     return saved_sandbox_path