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
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
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()
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)
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])
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
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