def assign_placement_policy_to_template(
    client,
    cse_placement_policy,
    catalog_name,
    catalog_item_name,
    org_name,
    logger=NULL_LOGGER,
    log_wire=False,
    msg_update_callback=NullPrinter()):  # noqa: E501

    policy = None
    cpm = compute_policy_manager.ComputePolicyManager(client,
                                                      log_wire=log_wire)
    try:
        policy = compute_policy_manager.get_cse_vdc_compute_policy(
            cpm, cse_placement_policy, is_placement_policy=True)
        task = cpm.assign_vdc_placement_policy_to_vapp_template_vms(
            policy['href'], org_name, catalog_name, catalog_item_name)
        if task is not None:
            client.get_task_monitor().wait_for_success(task)
            msg = "Successfully tagged template " \
                  f"{catalog_item_name} with placement policy " \
                  f"{cse_placement_policy}."
        else:
            msg = f"{catalog_item_name} already tagged with" \
                  f" placement policy {cse_placement_policy}."
        msg_update_callback.info(msg)
        logger.info(msg)
    except Exception as err:
        msg = f"Failed to tag template {catalog_item_name} with " \
              f"placement policy {cse_placement_policy}. Error: {err}"
        msg_update_callback.error(msg)
        logger.error(msg)
        raise
Exemple #2
0
 def _load_placement_policy_details(self,
                                    msg_update_callback=utils.NullPrinter()):  # noqa: E501
     msg = "Loading kubernetes runtime placement policies."
     logger.SERVER_LOGGER.info(msg)
     msg_update_callback.general(msg)
     try:
         sysadmin_client = vcd_utils.get_sys_admin_client()
         if float(sysadmin_client.get_api_version()) < compute_policy_manager.GLOBAL_PVDC_COMPUTE_POLICY_MIN_VERSION:  # noqa: E501
             msg = "Placement policies for kubernetes runtimes not " \
                   " supported in api version " \
                   f"{sysadmin_client.get_api_version()}"  # noqa: E501
             logger.SERVER_LOGGER.debug(msg)
             msg_update_callback.info(msg)
             return
         placement_policy_name_to_href = {}
         cpm = compute_policy_manager.ComputePolicyManager(sysadmin_client,
                                                           log_wire=self.config['service'].get('log_wire')) # noqa: E501
         for runtime_policy in shared_constants.CLUSTER_RUNTIME_PLACEMENT_POLICIES:  # noqa: E501
             k8_runtime = shared_constants.RUNTIME_INTERNAL_NAME_TO_DISPLAY_NAME_MAP[runtime_policy]  # noqa: E501
             try:
                 placement_policy_name_to_href[k8_runtime] = \
                     compute_policy_manager.get_cse_vdc_compute_policy(
                         cpm,
                         runtime_policy,
                         is_placement_policy=True)['href']
             except EntityNotFoundException:
                 pass
         self.config['placement_policy_hrefs'] = placement_policy_name_to_href  # noqa: E501
     except Exception as e:
         msg = f"Failed to load placement policies to server runtime configuration: {str(e)}" # noqa: E501
         msg_update_callback.error(msg)
         logger.SERVER_LOGGER.error(msg)
         raise
def ovdc_compute_policy_list(request_data, op_ctx: ctx.OperationContext):
    """Request handler for ovdc compute-policy list operation.

    Required data: ovdc_id

    :return: Dictionary with task href.
    """
    required = [RequestKey.OVDC_ID]
    req_utils.validate_payload(request_data, required)

    config = utils.get_server_runtime_config()
    cpm = compute_policy_manager.ComputePolicyManager(
        op_ctx.sysadmin_client,
        log_wire=utils.str_to_bool(config['service'].get('log_wire')))
    compute_policies = []
    for cp in \
            compute_policy_manager.list_cse_sizing_policies_on_vdc(
                cpm,
                request_data[RequestKey.OVDC_ID]):
        policy = {
            'name': cp['display_name'],
            'id': cp['id'],
            'href': cp['href']
        }
        compute_policies.append(policy)
    return compute_policies
Exemple #4
0
    def _process_template_compute_policy_compliance(self,
                                                    msg_update_callback=utils.NullPrinter()): # noqa: E501
        msg = "Processing compute policy for k8s templates."
        logger.SERVER_LOGGER.info(msg)
        msg_update_callback.general_no_color(msg)

        org_name = self.config['broker']['org']
        catalog_name = self.config['broker']['catalog']
        sysadmin_client = None
        try:
            sysadmin_client = vcd_utils.get_sys_admin_client()
            cpm = compute_policy_manager.ComputePolicyManager(sysadmin_client,
                                                              log_wire=self.config['service'].get('log_wire')) # noqa: E501

            for template in self.config['broker']['templates']:
                policy_name = template[LocalTemplateKey.COMPUTE_POLICY]
                catalog_item_name = template[LocalTemplateKey.CATALOG_ITEM_NAME] # noqa: E501
                # if policy name is not empty, stamp it on the template
                if policy_name:
                    try:
                        policy = cpm.get_policy(policy_name=policy_name)
                    except EntityNotFoundException:
                        # create the policy if it does not exist
                        msg = f"Creating missing compute policy " \
                              f"'{policy_name}'."
                        msg_update_callback.info(msg)
                        logger.SERVER_LOGGER.debug(msg)
                        policy = cpm.add_policy(policy_name=policy_name)

                    msg = f"Assigning compute policy '{policy_name}' to " \
                          f"template '{catalog_item_name}'."
                    msg_update_callback.general(msg)
                    logger.SERVER_LOGGER.debug(msg)
                    cpm.assign_compute_policy_to_vapp_template_vms(
                        compute_policy_href=policy['href'],
                        org_name=org_name,
                        catalog_name=catalog_name,
                        catalog_item_name=catalog_item_name)
                else:
                    # empty policy name means we should remove policy from
                    # template
                    msg = f"Removing compute policy from template " \
                          f"'{catalog_item_name}'."
                    msg_update_callback.general(msg)
                    logger.SERVER_LOGGER.debug(msg)

                    cpm.remove_all_compute_policies_from_vapp_template_vms(
                        org_name=org_name,
                        catalog_name=catalog_name,
                        catalog_item_name=catalog_item_name)
        except OperationNotSupportedException:
            msg = "Compute policy not supported by vCD. Skipping " \
                  "assigning/removing it to/from templates."
            msg_update_callback.info(msg)
            logger.SERVER_LOGGER.debug(msg)
        finally:
            if sysadmin_client is not None:
                sysadmin_client.logout()
Exemple #5
0
def _setup_placement_policies(client,
                              policy_list,
                              msg_update_callback=utils.NullPrinter(),
                              log_wire=False):
    """
    Create placement policies for each cluster type.

    Create the global pvdc compute policy if not present and create placement
    policy for each policy in the policy list. This should be done only for
    vcd api version >= 35 (zeus)

    :parma client vcdClient.Client
    :param policy_list str[]
    """
    msg = "Setting up placement policies for cluster types"
    msg_update_callback.info(msg)
    INSTALL_LOGGER.debug(msg)
    computePolicyManager = cpm.ComputePolicyManager(client, log_wire=log_wire)
    pvdc_compute_policy = None
    try:
        try:
            pvdc_compute_policy = computePolicyManager.get_pvdc_compute_policy(
                server_constants.CSE_GLOBAL_PVDC_COMPUTE_POLICY_NAME)
            msg = "Skipping global PVDC compute policy creation. Policy already exists"  # noqa: E501
            msg_update_callback.general(msg)
            INSTALL_LOGGER.debug(msg)
        except EntityNotFoundException:
            msg = "Creating global PVDC compute policy"
            msg_update_callback.general(msg)
            INSTALL_LOGGER.debug(msg)
            pvdc_compute_policy = computePolicyManager.add_pvdc_compute_policy(
                server_constants.CSE_GLOBAL_PVDC_COMPUTE_POLICY_NAME,
                server_constants.CSE_GLOBAL_PVDC_COMPUTE_POLICY_DESCRIPTION)

        for policy in policy_list:
            try:
                computePolicyManager.get_vdc_compute_policy(
                    policy, is_placement_policy=True)  # noqa: E501
                msg = f"Skipping creating VDC placement policy '{policy}'. Policy already exists"  # noqa: E501
                msg_update_callback.general(msg)
                INSTALL_LOGGER.debug(msg)
            except EntityNotFoundException:
                msg = f"Creating placement policy '{policy}'"
                msg_update_callback.general(msg)
                INSTALL_LOGGER.debug(msg)
                computePolicyManager.add_vdc_compute_policy(
                    policy, pvdc_compute_policy_id=pvdc_compute_policy['id']
                )  # noqa: E501
    except cse_exception.GlobalPvdcComputePolicyNotSupported:
        msg = "Global PVDC compute policies are not supported." \
              "Skipping placement policy creation."
        msg_update_callback.general(msg)
        INSTALL_LOGGER.debug(msg)
Exemple #6
0
def ovdc_compute_policy_list(request_data,
                             request_context: ctx.RequestContext):
    """Request handler for ovdc compute-policy list operation.

    Required data: ovdc_id

    :return: Dictionary with task href.
    """
    required = [RequestKey.OVDC_ID]
    req_utils.validate_payload(request_data, required)

    config = utils.get_server_runtime_config()
    cpm = compute_policy_manager.ComputePolicyManager(
        request_context.sysadmin_client,
        log_wire=utils.str_to_bool(config['service'].get('log_wire')))
    return cpm.list_compute_policies_on_vdc(request_data[RequestKey.OVDC_ID])
Exemple #7
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
Exemple #8
0
 def _tag_with_cse_placement_policy(self):
     """Tag the created template with placement policies if provided."""
     if not self.cse_placement_policy:
         msg = "Skipping tagging template with placement policy."
         self.msg_update_callback.info(msg)
         self.logger.debug(msg)
         return
     policy = None
     cpm = compute_policy_manager.ComputePolicyManager(self.client,
                                                       log_wire=self.log_wire) # noqa: E501
     try:
         policy = cpm.get_vdc_compute_policy(self.cse_placement_policy,
                                             is_placement_policy=True)
         task = cpm.assign_vdc_placement_policy_to_vapp_template_vms(
             policy['href'],
             self.org_name,
             self.catalog_name,
             self.catalog_item_name)
         if task:
             self.client.get_task_monitor().wait_for_success(task)
             msg = "Successfully tagged template " \
                   f"{self.catalog_item_name} with placement policy " \
                   f"{self.cse_placement_policy}."
         else:
             msg = f"{self.catalog_item_name} already tagged with" \
                   f" placement policy {self.cse_placement_policy}."
         self.msg_update_callback.info(msg)
         self.logger.info(msg)
     except EntityNotFoundException:
         msg = f"Placement policy {self.cse_placement_policy} not found"
         self.msg_update_callback.error(msg)
         self.logger.error(msg)
     except Exception as err:
         msg = f"Failed to tag template {self.catalog_item_name} with " \
               f"placement policy {self.cse_placement_policy}. Error: {err}"
         self.msg_update_callback.error(msg)
         self.logger.error(msg)
def _update_ovdc_using_placement_policy_async(operation_context: ctx.OperationContext,  # noqa: E501
                                              task: vcd_task.Task,
                                              task_href,
                                              user_href,
                                              policy_list,
                                              ovdc_id,
                                              vdc,
                                              remove_cp_from_vms_on_disable=False):  # noqa: E501
    """Enable ovdc using placement policies.

    :param ctx.OperationContext operation_context: operation context object
    :param vcd_task.Task task: Task resource to track progress
    :param str task_href: href of the task
    :param str user_href:
    :param List[str] policy_list: The new list of policies associated with
        the ovdc
    :param str ovdc_id:
    :param pyvcloud.vcd.vdc.VDC vdc: VDC object
    :param bool remove_cp_from_vms_on_disable: Set to true if placement
        policies need to be removed from the vms before removing from the VDC.
    """
    operation_name = "Update OVDC with placement policies"
    k8s_runtimes_added = ''
    k8s_runtimes_deleted = ''
    try:
        config = utils.get_server_runtime_config()
        log_wire = utils.str_to_bool(config.get('service', {}).get('log_wire'))
        cpm = compute_policy_manager.ComputePolicyManager(
            operation_context.sysadmin_client, log_wire=log_wire)
        existing_policies = []
        for cse_policy in \
                compute_policy_manager.list_cse_placement_policies_on_vdc(cpm, ovdc_id):  # noqa: E501
            existing_policies.append(cse_policy['display_name'])

        logger.SERVER_LOGGER.debug(policy_list)
        logger.SERVER_LOGGER.debug(existing_policies)
        policies_to_add = set(policy_list) - set(existing_policies)
        policies_to_delete = set(existing_policies) - set(policy_list)

        # Telemetry for 'vcd cse ovdc enable' command
        # TODO: Update telemetry request to handle 'k8s_runtime' array
        k8s_runtimes_added = ','.join(policies_to_add)
        if k8s_runtimes_added:
            cse_params = {
                RequestKey.K8S_PROVIDER: k8s_runtimes_added,
                RequestKey.OVDC_ID: ovdc_id,
            }
            telemetry_handler.record_user_action_details(cse_operation=CseOperation.OVDC_ENABLE, # noqa: E501
                                                         cse_params=cse_params)

        # Telemetry for 'vcd cse ovdc enable' command
        # TODO: Update telemetry request to handle 'k8s_runtime' array
        k8s_runtimes_deleted = '.'.join(policies_to_delete)
        if k8s_runtimes_deleted:
            cse_params = {
                RequestKey.K8S_PROVIDER: k8s_runtimes_deleted,
                RequestKey.OVDC_ID: ovdc_id,
                RequestKey.REMOVE_COMPUTE_POLICY_FROM_VMS: remove_cp_from_vms_on_disable # noqa: E501
            }
            telemetry_handler.record_user_action_details(cse_operation=CseOperation.OVDC_DISABLE, # noqa: E501
                                                         cse_params=cse_params)

        for cp_name in policies_to_add:
            msg = f"Adding k8s provider {cp_name} to OVDC {vdc.name}"
            logger.SERVER_LOGGER.debug(msg)
            task.update(status=vcd_client.TaskStatus.RUNNING.value,
                        namespace='vcloud.cse',
                        operation=msg,
                        operation_name=operation_name,
                        details='',
                        progress=None,
                        owner_href=vdc.href,
                        owner_name=vdc.name,
                        owner_type=vcd_client.EntityType.VDC.value,
                        user_href=user_href,
                        user_name=operation_context.user.name,
                        task_href=task_href,
                        org_href=operation_context.user.org_href)
            policy = compute_policy_manager.get_cse_vdc_compute_policy(
                cpm,
                cp_name,
                is_placement_policy=True)
            cpm.add_compute_policy_to_vdc(vdc_id=ovdc_id,
                                          compute_policy_href=policy['href'])

        for cp_name in policies_to_delete:
            msg = f"Removing k8s provider {RUNTIME_INTERNAL_NAME_TO_DISPLAY_NAME_MAP[cp_name]} from OVDC {ovdc_id}"  # noqa: E501
            logger.SERVER_LOGGER.debug(msg)
            task_resource = \
                task.update(status=vcd_client.TaskStatus.RUNNING.value,
                            namespace='vcloud.cse',
                            operation=msg,
                            operation_name=operation_name,
                            details='',
                            progress=None,
                            owner_href=vdc.href,
                            owner_name=vdc.name,
                            owner_type=vcd_client.EntityType.VDC.value,
                            user_href=user_href,
                            user_name=operation_context.user.name,
                            task_href=task_href,
                            org_href=operation_context.user.org_href)
            policy = compute_policy_manager.get_cse_vdc_compute_policy(cpm,
                                                                       cp_name,
                                                                       is_placement_policy=True)  # noqa: E501
            cpm.remove_compute_policy_from_vdc_sync(vdc=vdc,
                                                    compute_policy_href=policy['href'],  # noqa: E501
                                                    force=remove_cp_from_vms_on_disable, # noqa: E501
                                                    is_placement_policy=True,
                                                    task_resource=task_resource) # noqa: E501
        msg = f"Successfully updated OVDC: {vdc.name}"
        logger.SERVER_LOGGER.debug(msg)
        task.update(status=vcd_client.TaskStatus.SUCCESS.value,
                    namespace='vcloud.cse',
                    operation="Operation success",
                    operation_name=operation_name,
                    details=msg,
                    progress=None,
                    owner_href=vdc.href,
                    owner_name=vdc.name,
                    owner_type=vcd_client.EntityType.VDC.value,
                    user_href=user_href,
                    user_name=operation_context.user.name,
                    task_href=task_href,
                    org_href=operation_context.user.org_href)
        # Record telemetry
        if k8s_runtimes_added:
            telemetry_handler.record_user_action(CseOperation.OVDC_ENABLE,
                                                 status=OperationStatus.SUCCESS) # noqa: E501
        if k8s_runtimes_deleted:
            telemetry_handler.record_user_action(CseOperation.OVDC_DISABLE,
                                                 status=OperationStatus.SUCCESS) # noqa: E501
    except Exception as err:
        # Record telemetry
        if k8s_runtimes_added:
            telemetry_handler.record_user_action(CseOperation.OVDC_ENABLE,
                                                 status=OperationStatus.FAILED)
        if k8s_runtimes_deleted:
            telemetry_handler.record_user_action(CseOperation.OVDC_DISABLE,
                                                 status=OperationStatus.FAILED)
        logger.SERVER_LOGGER.error(err)
        task.update(status=vcd_client.TaskStatus.ERROR.value,
                    namespace='vcloud.cse',
                    operation='Failed to update OVDC',
                    operation_name=operation_name,
                    details=f'Failed with error: {err}',
                    progress=None,
                    owner_href=vdc.href,
                    owner_name=vdc.name,
                    owner_type=vcd_client.EntityType.VDC.value,
                    user_href=user_href,
                    user_name=operation_context.user.name,
                    task_href=task_href,
                    org_href=operation_context.user.org_href,
                    error_message=f"{err}")
    finally:
        if operation_context.sysadmin_client:
            operation_context.end()
def ovdc_compute_policy_update(request_data, op_ctx: ctx.OperationContext):
    """Request handler for ovdc compute-policy update operation.

    Required data: ovdc_id, compute_policy_action, compute_policy_names

    :return: Dictionary with task href.
    """
    required = [
        RequestKey.OVDC_ID, RequestKey.COMPUTE_POLICY_ACTION,
        RequestKey.COMPUTE_POLICY_NAME
    ]
    defaults = {
        RequestKey.REMOVE_COMPUTE_POLICY_FROM_VMS: False,
    }
    validated_data = {**defaults, **request_data}
    req_utils.validate_payload(validated_data, required)

    action = validated_data[RequestKey.COMPUTE_POLICY_ACTION]
    cp_name = validated_data[RequestKey.COMPUTE_POLICY_NAME]
    ovdc_id = validated_data[RequestKey.OVDC_ID]
    remove_compute_policy_from_vms = validated_data[
        RequestKey.REMOVE_COMPUTE_POLICY_FROM_VMS]  # noqa: E501
    try:
        config = utils.get_server_runtime_config()
        cpm = compute_policy_manager.ComputePolicyManager(
            op_ctx.sysadmin_client,
            log_wire=utils.str_to_bool(
                config['service'].get('log_wire')))  # noqa: E501
        cp_href = None
        cp_id = None
        if cp_name == SYSTEM_DEFAULT_COMPUTE_POLICY_NAME:
            for _cp in cpm.list_compute_policies_on_vdc(ovdc_id):
                if _cp['name'] == cp_name:
                    cp_href = _cp['href']
                    cp_id = _cp['id']
        else:
            try:
                _cp = cpm.get_vdc_compute_policy(cp_name)
                cp_href = _cp['href']
                cp_id = _cp['id']
            except vcd_e.EntityNotFoundException:
                pass

        if cp_href is None:
            raise e.BadRequestError(f"Compute policy '{cp_name}' not found.")

        if action == ComputePolicyAction.ADD:
            cpm.add_compute_policy_to_vdc(ovdc_id, cp_href)
            # Record telemetry data
            record_user_action(CseOperation.OVDC_COMPUTE_POLICY_ADD)
            return f"Added compute policy '{cp_name}' ({cp_id}) to ovdc " \
                   f"({ovdc_id})"

        if action == ComputePolicyAction.REMOVE:
            # TODO: fix remove_compute_policy by implementing a proper way
            # for calling async methods without having to pass op_ctx
            # outside handlers.
            task_href = cpm.remove_vdc_compute_policy_from_vdc(
                op_ctx,
                ovdc_id,
                cp_href,
                remove_compute_policy_from_vms=remove_compute_policy_from_vms)
            # Record telemetry data
            record_user_action(CseOperation.OVDC_COMPUTE_POLICY_REMOVE)
            return task_href

        raise e.BadRequestError("Unsupported compute policy action")

    except Exception as err:
        # Record telemetry data failure
        if action == ComputePolicyAction.ADD:
            record_user_action(CseOperation.OVDC_COMPUTE_POLICY_ADD,
                               status=OperationStatus.FAILED)
        elif action == ComputePolicyAction.REMOVE:
            record_user_action(CseOperation.OVDC_COMPUTE_POLICY_REMOVE,
                               status=OperationStatus.FAILED)
        raise err