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 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.general(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
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 = server_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
def _get_cse_ovdc_list(sysadmin_client: vcd_client.Client, ovdc_list: list): ovdcs = [] config = server_utils.get_server_runtime_config() log_wire = utils.str_to_bool(config.get('service', {}).get('log_wire')) cpm = compute_policy_manager.ComputePolicyManager(sysadmin_client, log_wire=log_wire) for ovdc in ovdc_list: ovdc_name = ovdc.get('name') ovdc_id = vcd_utils.extract_id(ovdc.get('id')) # obtain ovdc runtime details for the ovdc ovdc_details = asdict( get_ovdc_k8s_runtime_details(sysadmin_client, ovdc_id=ovdc_id, ovdc_name=ovdc_name, cpm=cpm, log_wire=log_wire)) # 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. if ClusterEntityKind.TKG_PLUS.value in ovdc_details['k8s_runtime'] \ and not server_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
def _load_placement_policy_details( self, msg_update_callback=utils.NullPrinter()): 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(api_version=None) 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 get_ovdc_k8s_runtime_details( sysadmin_client: vcd_client.Client, ovdc_id=None, ovdc_name=None, org_name=None, cpm: Optional[ compute_policy_manager.ComputePolicyManager] = None, # noqa: E501 log_wire=False) -> common_models.Ovdc: """Get k8s runtime details for an ovdc. At least 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 vcd_client.Client sysadmin_client: vcd sysadmin client :param str ovdc_id: :param str ovdc_name: :param str org_name: :param compute_policy_manager.ComputePolicyManager cpm: :param bool log_wire: :return: Ovdc object with k8s runtimes :rtype: common_models.Ovdc """ vcd_utils.raise_error_if_user_not_from_system_org(sysadmin_client) if not cpm: 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 common_models.Ovdc(ovdc_name=ovdc_name, ovdc_id=ovdc_id, k8s_runtime=policies) # noqa: E501
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 = server_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 = compute_policy_manager.get_cse_vdc_compute_policy( cpm, cp_name) # noqa: E501 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. op_ctx.is_async = True response = cpm.remove_vdc_compute_policy_from_vdc( ovdc_id, cp_href, force=remove_compute_policy_from_vms) # Follow task_href to completion in a different thread and end # operation context _follow_task(op_ctx, response['task_href'], ovdc_id) # Record telemetry data record_user_action(CseOperation.OVDC_COMPUTE_POLICY_REMOVE) return response 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
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(api_version=None) 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[server_constants.LegacyLocalTemplateKey. COMPUTE_POLICY] # noqa: E501 catalog_item_name = template[ server_constants.LegacyLocalTemplateKey. CATALOG_ITEM_NAME] # noqa: E501 # if policy name is not empty, stamp it on the template if policy_name: try: policy = \ compute_policy_manager.get_cse_vdc_compute_policy( cpm, policy_name) # noqa: E501 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 = \ compute_policy_manager.add_cse_vdc_compute_policy( cpm, 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_vdc_sizing_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_vdc_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()
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, org_name, 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 str org_name: name of the organization that vdc provides resource :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 = server_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, RequestKey.ORG_NAME: org_name, PayloadKey.SOURCE_DESCRIPTION: thread_local_data.get_thread_local_data( ThreadLocalData.USER_AGENT) # noqa: E501 } 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.ORG_NAME: org_name, RequestKey.REMOVE_COMPUTE_POLICY_FROM_VMS: remove_cp_from_vms_on_disable, # noqa: E501 PayloadKey.SOURCE_DESCRIPTION: thread_local_data.get_thread_local_data( ThreadLocalData.USER_AGENT) # 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()