def list_ovdc(operation_context: ctx.OperationContext) -> List[dict]:
    """List all ovdc and their k8s runtimes.

    :param ctx.OperationContext operation_context: context for the request
    :return: list of dictionary containing details about the ovdc
    :rtype: List[dict]
    """
    # NOTE: For CSE 3.0, if `enable_tkg_plus` flag in config is set to false,
    # Prevent showing information about TKG+ by skipping TKG+ from the result.
    # Record telemetry
    telemetry_handler.record_user_action_details(cse_operation=CseOperation.OVDC_LIST, # noqa: E501
                                                 cse_params={})

    ovdcs = []
    org_vdcs = vcd_utils.get_all_ovdcs(operation_context.client)
    for ovdc in org_vdcs:
        ovdc_name = ovdc.get('name')
        config = utils.get_server_runtime_config()
        log_wire = utils.str_to_bool(config.get('service', {}).get('log_wire'))
        ovdc_id = vcd_utils.extract_id(ovdc.get('id'))
        ovdc_details = asdict(
            get_ovdc_k8s_runtime_details(operation_context.sysadmin_client,
                                         ovdc_id=ovdc_id,
                                         ovdc_name=ovdc_name,
                                         log_wire=log_wire))
        if ClusterEntityKind.TKG_PLUS.value in ovdc_details['k8s_runtime'] \
                and not utils.is_tkg_plus_enabled():  # noqa: E501
            ovdc_details['k8s_runtime'].remove(ClusterEntityKind.TKG_PLUS.value)  # noqa: E501
        # TODO: Find a better way to remove remove_cp_from_vms_on_disable
        del ovdc_details['remove_cp_from_vms_on_disable']
        ovdcs.append(ovdc_details)
    return ovdcs
Ejemplo n.º 2
0
def get_ovdc_k8s_runtime_details(sysadmin_client: vcd_client.Client,
                                 ovdc_id=None,
                                 ovdc_name=None,
                                 org_name=None,
                                 log_wire=False) -> def_models.Ovdc:
    """Get k8s runtime details for an ovdc.

    Atleast ovdc_id and ovdc_name or org_name and ovdc_name should be provided.
    Additional call to get ovdc details can be avoided by providing ovdc_id and
    ovdc_name.

    :param sysadmin_client vcd_client.Client: vcd sysadmin client
    :param str org_name:
    :param str ovdc_name:
    :param str ovdc_id:
    :param bool log_wire:
    :return: Ovdc object with k8s runtimes
    :rtype: def_models.Ovdc
    """
    vcd_utils.raise_error_if_user_not_from_system_org(sysadmin_client)
    cpm = compute_policy_manager.ComputePolicyManager(sysadmin_client,
                                                      log_wire=log_wire)
    if not (org_name and ovdc_name) and not ovdc_id:
        msg = "Unable to fetch OVDC k8 runtime details with the " \
              "provided parameters"
        logger.SERVER_LOGGER.error(msg)
        raise Exception(msg)
    if not ovdc_id or not ovdc_name:
        # populate ovdc_id and ovdc_name
        ovdc = vcd_utils.get_vdc(client=sysadmin_client,
                                 vdc_id=ovdc_id,
                                 vdc_name=ovdc_name,
                                 org_name=org_name,
                                 is_admin_operation=True)
        ovdc_id = vcd_utils.extract_id(ovdc.get_resource().get('id'))
        ovdc_name = ovdc.get_resource().get('name')
    policies = []
    for cse_policy in \
            compute_policy_manager.list_cse_placement_policies_on_vdc(cpm, ovdc_id):  # noqa: E501
        policies.append(RUNTIME_INTERNAL_NAME_TO_DISPLAY_NAME_MAP[
            cse_policy['display_name']])  # noqa: E501
    return def_models.Ovdc(ovdc_name=ovdc_name,
                           ovdc_id=ovdc_id,
                           k8s_runtime=policies)  # noqa: E501
Ejemplo n.º 3
0
    def remove_compute_policy_from_vdc_sync(self,
                                            vdc,
                                            compute_policy_href,
                                            force=False,
                                            is_placement_policy=False,
                                            task_resource=None):
        """Remove compute policy from vdc.

        This method makes use of an umbrella task which can be used for
        tracking progress. If the umbrella task is not specified, it is
        created.

        :param pyvcloud.vcd.vdc.VDC vdc: VDC object
        :param str compute_policy_href: href of the compute policy to remove
        :param bool force: Force remove compute policy from vms in the VDC
            as well
        :param lxml.objectify.Element task_resource: Task resource for
            the umbrella task
        """
        user_name = self._session.get('user')

        task = Task(self._sysadmin_client)
        task_href = None
        is_umbrella_task = task_resource is not None
        # Create a task if not umbrella task
        if not is_umbrella_task:
            # TODO the following org will be associated with 'System' org.
            # task created should be associated with the corresponding org of
            # the vdc object.
            org = vcd_utils.get_org(self._sysadmin_client)
            org.reload()
            user_href = org.get_user(user_name).get('href')
            org_href = org.href
            task_resource = task.update(
                status=vcd_client.TaskStatus.RUNNING.value,
                namespace='vcloud.cse',
                operation=
                f"Removing compute policy (href: {compute_policy_href})"  # noqa: E501
                f" from org VDC (vdc id: {vdc.name})",
                operation_name='Remove org VDC compute policy',
                details='',
                progress=None,
                owner_href=vdc.href,
                owner_name=vdc.name,
                owner_type=vcd_client.EntityType.VDC.value,
                user_href=user_href,
                user_name=user_name,
                org_href=org.href)
        else:
            user_href = task_resource.User.get('href')
            org_href = task_resource.Organization.get('href')

        task_href = task_resource.get('href')

        try:
            # remove the compute policy from VMs if force is True
            if force:
                compute_policy_id = retrieve_compute_policy_id_from_href(
                    compute_policy_href)  # noqa: E501
                vdc_id = vcd_utils.extract_id(vdc.get_resource().get('id'))
                vapps = vcd_utils.get_all_vapps_in_ovdc(
                    client=self._sysadmin_client, ovdc_id=vdc_id)
                target_vms = []
                system_default_href = None
                operation_msg = None
                for cp_dict in self.list_compute_policies_on_vdc(vdc_id):
                    if cp_dict['name'] == _SYSTEM_DEFAULT_COMPUTE_POLICY:
                        system_default_href = cp_dict['href']
                        break
                if is_placement_policy:
                    for vapp in vapps:
                        target_vms += \
                            [vm for vm in vapp.get_all_vms()
                                if self._get_vm_placement_policy_id(vm) == compute_policy_id] # noqa: E501
                    vm_names = [vm.get('name') for vm in target_vms]
                    operation_msg = f"Removing placement policy from " \
                                    f"{len(vm_names)} VMs. " \
                                    f"Affected VMs: {vm_names}"
                else:
                    for vapp in vapps:
                        target_vms += \
                            [vm for vm in vapp.get_all_vms()
                                if self._get_vm_sizing_policy_id(vm) == compute_policy_id] # noqa: E501
                    vm_names = [vm.get('name') for vm in target_vms]
                    operation_msg = "Setting sizing policy to " \
                                    f"'{_SYSTEM_DEFAULT_COMPUTE_POLICY}' on " \
                                    f"{len(vm_names)} VMs. " \
                                    f"Affected VMs: {vm_names}"

                task.update(status=vcd_client.TaskStatus.RUNNING.value,
                            namespace='vcloud.cse',
                            operation=operation_msg,
                            operation_name='Remove org VDC compute policy',
                            details='',
                            progress=None,
                            owner_href=vdc.href,
                            owner_name=vdc.name,
                            owner_type=vcd_client.EntityType.VDC.value,
                            user_href=user_href,
                            user_name=user_name,
                            task_href=task_href,
                            org_href=org_href)

                task_monitor = self._sysadmin_client.get_task_monitor()
                for vm_resource in target_vms:
                    vm = VM(self._sysadmin_client,
                            href=vm_resource.get('href'))
                    _task = None
                    operation_msg = None
                    if is_placement_policy:
                        if hasattr(vm_resource, 'ComputePolicy') and \
                                not hasattr(vm_resource.ComputePolicy, 'VmSizingPolicy'):  # noqa: E501
                            # Updating sizing policy for the VM
                            _task = vm.update_compute_policy(
                                compute_policy_href=system_default_href)
                            operation_msg = \
                                "Setting compute policy to " \
                                f"'{_SYSTEM_DEFAULT_COMPUTE_POLICY}' "\
                                f"on VM '{vm_resource.get('name')}'"
                            task.update(
                                status=vcd_client.TaskStatus.RUNNING.value,
                                namespace='vcloud.cse',
                                operation=operation_msg,
                                operation_name=
                                f'Setting sizing policy to {_SYSTEM_DEFAULT_COMPUTE_POLICY}',  # noqa: E501
                                details='',
                                progress=None,
                                owner_href=vdc.href,
                                owner_name=vdc.name,
                                owner_type=vcd_client.EntityType.VDC.value,
                                user_href=user_href,
                                user_name=user_name,
                                task_href=task_href,
                                org_href=org_href)
                            task_monitor.wait_for_success(_task)
                        _task = vm.remove_placement_policy()
                        operation_msg = "Removing placement policy on VM " \
                                        f"'{vm_resource.get('name')}'"
                        task.update(
                            status=vcd_client.TaskStatus.RUNNING.value,
                            namespace='vcloud.cse',
                            operation=operation_msg,
                            operation_name='Remove org VDC compute policy',
                            details='',
                            progress=None,
                            owner_href=vdc.href,
                            owner_name=vdc.name,
                            owner_type=vcd_client.EntityType.VDC.value,
                            user_href=user_href,
                            user_name=user_name,
                            task_href=task_href,
                            org_href=org_href)
                        task_monitor.wait_for_success(_task)
                    else:
                        _task = vm.update_compute_policy(
                            compute_policy_href=system_default_href)
                        operation_msg = "Setting sizing policy to " \
                                        f"'{_SYSTEM_DEFAULT_COMPUTE_POLICY}' "\
                                        f"on VM '{vm_resource.get('name')}'"
                        task.update(
                            status=vcd_client.TaskStatus.RUNNING.value,
                            namespace='vcloud.cse',
                            operation=operation_msg,
                            operation_name='Remove org VDC compute policy',
                            details='',
                            progress=None,
                            owner_href=vdc.href,
                            owner_name=vdc.name,
                            owner_type=vcd_client.EntityType.VDC.value,
                            user_href=user_href,
                            user_name=user_name,
                            task_href=task_href,
                            org_href=org_href)
                        task_monitor.wait_for_success(_task)

            final_status = vcd_client.TaskStatus.RUNNING.value \
                if is_umbrella_task else vcd_client.TaskStatus.SUCCESS.value
            task.update(status=final_status,
                        namespace='vcloud.cse',
                        operation=f"Removing compute policy (href:"
                        f"{compute_policy_href}) from org VDC '{vdc.name}'",
                        operation_name='Remove org VDC compute policy',
                        details='',
                        progress=None,
                        owner_href=vdc.href,
                        owner_name=vdc.name,
                        owner_type=vcd_client.EntityType.VDC.value,
                        user_href=user_href,
                        user_name=user_name,
                        task_href=task_href,
                        org_href=org_href)

            vdc.remove_compute_policy(compute_policy_href)
        except Exception as err:
            logger.SERVER_LOGGER.error(err, exc_info=True)
            # Set task to error if not an umbrella task
            if not is_umbrella_task:
                msg = 'Failed to remove compute policy: ' \
                      f'{compute_policy_href} from the OVDC: {vdc.name}'
                task.update(status=vcd_client.TaskStatus.ERROR.value,
                            namespace='vcloud.cse',
                            operation=msg,
                            operation_name='Remove org VDC compute policy',
                            details='',
                            progress=None,
                            owner_href=vdc.href,
                            owner_name=vdc.name,
                            owner_type=vcd_client.EntityType.VDC.value,
                            user_href=user_href,
                            user_name=self._session.get('user'),
                            task_href=task_href,
                            org_href=org_href,
                            error_message=f"{err}",
                            stack_trace='')
            raise err
def ovdc_list(request_data, op_ctx: ctx.OperationContext):
    """Request handler for ovdc list operation.

    :return: List of dictionaries with org VDC k8s provider metadata.
    """
    defaults = {RequestKey.LIST_PKS_PLANS: False}
    validated_data = {**defaults, **request_data}

    list_pks_plans = utils.str_to_bool(
        validated_data[RequestKey.LIST_PKS_PLANS])  # noqa: E501

    # Record telemetry data
    cse_params = copy.deepcopy(validated_data)
    cse_params[RequestKey.LIST_PKS_PLANS] = list_pks_plans
    record_user_action_details(cse_operation=CseOperation.OVDC_LIST,
                               cse_params=cse_params)

    if list_pks_plans and not op_ctx.client.is_sysadmin():
        raise e.UnauthorizedRequestError(
            'Operation denied. Enterprise PKS plans visible only '
            'to System Administrators.')

    ovdcs = []
    org_vdcs = vcd_utils.get_all_ovdcs(op_ctx.client)
    for ovdc in org_vdcs:
        ovdc_name = ovdc.get('name')
        org_name = ovdc.get('orgName')
        ovdc_id = vcd_utils.extract_id(ovdc.get('id'))
        k8s_metadata = ovdc_utils.get_ovdc_k8s_provider_metadata(
            op_ctx.sysadmin_client,
            ovdc_id=ovdc_id,
            ovdc_name=ovdc_name,
            org_name=org_name)
        k8s_provider = k8s_metadata[K8S_PROVIDER_KEY]
        ovdc_dict = {
            'name': ovdc_name,
            'org': org_name,
            'k8s provider': k8s_provider
        }

        if list_pks_plans:
            pks_plans = ''
            pks_server = ''
            if k8s_provider == K8sProvider.PKS:
                # vc name for vdc can only be found using typed query
                qfilter = f"name=={urllib.parse.quote(ovdc_name)};" \
                          f"orgName=={urllib.parse.quote(org_name)}"
                q = op_ctx.client.get_typed_query(
                    vcd_client.ResourceType.ADMIN_ORG_VDC.value,
                    query_result_format=vcd_client.QueryResultFormat.
                    RECORDS,  # noqa: E501
                    qfilter=qfilter)
                # should only ever be one element in the generator
                ovdc_records = list(q.execute())
                if len(ovdc_records) == 0:
                    raise vcd_e.EntityNotFoundException(
                        f"Org VDC {ovdc_name} not found in org {org_name}")
                ovdc_record = None
                for record in ovdc_records:
                    ovdc_record = pyvcd_utils.to_dict(
                        record,
                        resource_type=vcd_client.ResourceType.ADMIN_ORG_VDC.
                        value)  # noqa: E501
                    break

                vc_to_pks_plans_map = {}
                pks_contexts = pksbroker_manager.create_pks_context_for_all_accounts_in_org(
                    op_ctx)  # noqa: E501

                for pks_context in pks_contexts:
                    if pks_context['vc'] in vc_to_pks_plans_map:
                        continue
                    pks_broker = pksbroker.PksBroker(pks_context, op_ctx)
                    plans = pks_broker.list_plans()
                    plan_names = [plan.get('name') for plan in plans]
                    vc_to_pks_plans_map[pks_context['vc']] = \
                        [plan_names, pks_context['host']]

                pks_plan_and_server_info = vc_to_pks_plans_map.get(
                    ovdc_record['vcName'], [])
                if len(pks_plan_and_server_info) > 0:
                    pks_plans = pks_plan_and_server_info[0]
                    pks_server = pks_plan_and_server_info[1]

            ovdc_dict['pks api server'] = pks_server
            ovdc_dict['available pks plans'] = pks_plans
        ovdcs.append(ovdc_dict)

    return ovdcs