def system_update(request_data, op_ctx: ctx.OperationContext): """Request handler for system update operation. :return: Dictionary with system update status. """ required = [RequestKey.SERVER_ACTION] req_utils.validate_payload(request_data, required) # Telemetry data preparation server_action = request_data.get(RequestKey.SERVER_ACTION) cse_operation = server_action or 'invalid server action' if server_action == 'enable': cse_operation = CseOperation.SYSTEM_ENABLE elif server_action == 'disable': cse_operation = CseOperation.SYSTEM_DISABLE elif server_action == 'stop': cse_operation = CseOperation.SYSTEM_STOP status = OperationStatus.FAILED if op_ctx.client.is_sysadmin: # circular dependency between request_processor.py and service.py import container_service_extension.server.service as service try: result = service.Service().update_status( request_data.get(RequestKey.SERVER_ACTION)) status = OperationStatus.SUCCESS return result finally: record_user_action(cse_operation=cse_operation, status=status) record_user_action(cse_operation=cse_operation, status=status) raise e.UnauthorizedRequestError( error_message='Unauthorized to update CSE')
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_cluster_info(request_data, op_ctx, **kwargs): """Get cluster details directly from cloud provider. Logic of the method is as follows. If 'ovdc' is present in the cluster spec, choose the right PKS broker to do get_cluster operation. else Invoke set of all PKS brokers in the org to find the cluster :return: a tuple of cluster information as dictionary and the broker instance used to find the cluster information. :rtype: tuple """ required = [RequestKey.CLUSTER_NAME] req_utils.validate_payload(request_data, required) org_name = request_data.get(RequestKey.ORG_NAME) ovdc_name = request_data.get(RequestKey.OVDC_NAME) if ovdc_name is not None and org_name is not None: k8s_metadata = \ ovdc_utils.get_ovdc_k8s_provider_metadata(op_ctx.sysadmin_client, # noqa: E501 org_name=org_name, ovdc_name=ovdc_name, include_credentials=True, include_nsxt_info=True) broker = _get_broker_from_k8s_metadata(k8s_metadata, op_ctx) return broker.get_cluster_info(data=request_data, **kwargs), broker return _get_cluster_and_broker(request_data, op_ctx, **kwargs)
def create_cluster(self, **kwargs): """Create cluster in PKS environment. To retain the user context, user-id of the logged-in user is appended to the original cluster name before the actual cluster creation. :param **data: dict cluster_spec: named parameters necessary to create cluster (cluster_name, node_count, pks_plan, pks_ext_host, compute- profile_name) :return: Details of the cluster :rtype: dict """ data = kwargs[KwargKey.DATA] required = [ RequestKey.CLUSTER_NAME, RequestKey.PKS_PLAN_NAME, RequestKey.PKS_EXT_HOST, RequestKey.ORG_NAME, RequestKey.OVDC_NAME ] req_utils.validate_payload(data, required) cluster_name = data[RequestKey.CLUSTER_NAME] qualified_cluster_name = self._append_user_id(cluster_name) data[RequestKey.CLUSTER_NAME] = qualified_cluster_name if not self.nsxt_server: raise CseServerError( "NSX-T server details not found for PKS server selected for " f"cluster : {cluster_name}. Cancelling the cluster creation.") # this needs to be refactored # when num_workers==None, PKS creates however many the plan specifies cluster = self._create_cluster( cluster_name=data[RequestKey.CLUSTER_NAME], num_workers=data.get(RequestKey.NUM_WORKERS), pks_plan_name=data[RequestKey.PKS_PLAN_NAME], pks_ext_host=data[RequestKey.PKS_EXT_HOST]) self._isolate_cluster(cluster_name, qualified_cluster_name, cluster.get('uuid')) self._restore_original_name(cluster) if not self.context.client.is_sysadmin(): self._filter_sensitive_pks_properties(cluster) return cluster
def ovdc_update(request_data, op_ctx: ctx.OperationContext): """Request handler for ovdc enable, disable operations. Required data: org_name, ovdc_name, k8s_provider Conditional data: if k8s_provider is 'ent-pks': pks_plan_name, pks_cluster_domain :return: Dictionary with org VDC update task href. """ # TODO the data flow here should be better understood. # org_name and ovdc_name seem redundant if we already have ovdc_id data = req_utils.flatten_request_data( request_data, [RequestKey.INPUT_SPEC, RequestKey.QUERY_PARAMS]) required = [ RequestKey.ORG_NAME, RequestKey.OVDC_NAME, RequestKey.K8S_PROVIDER, RequestKey.OVDC_ID ] validated_data = data req_utils.validate_payload(validated_data, required) k8s_provider = validated_data[RequestKey.K8S_PROVIDER] k8s_provider_info = {K8S_PROVIDER_KEY: k8s_provider} # Record the telemetry data cse_params = copy.deepcopy(validated_data) cse_params[PayloadKey. SOURCE_DESCRIPTION] = thread_local_data.get_thread_local_data( ThreadLocalData.USER_AGENT) # noqa: E501 cse_operation = CseOperation.OVDC_DISABLE if k8s_provider == K8sProvider.NONE else CseOperation.OVDC_ENABLE # noqa: E501 record_user_action_details(cse_operation=cse_operation, cse_params=cse_params) # noqa: E501 try: sysadmin_client_v33 = \ op_ctx.get_sysadmin_client(api_version=DEFAULT_API_VERSION) task = ovdc_utils.update_ovdc_k8s_provider_metadata( sysadmin_client_v33, validated_data[RequestKey.OVDC_ID], k8s_provider_data=k8s_provider_info, k8s_provider=k8s_provider) # Telemetry - Record successful enabling/disabling of ovdc record_user_action(cse_operation, status=OperationStatus.SUCCESS) return {'task_href': task.get('href')} except Exception as err: # Telemetry - Record failed enabling/disabling of ovdc record_user_action(cse_operation, status=OperationStatus.FAILED) raise err
def cluster_create(request_data, op_ctx: ctx.OperationContext): """Request handler for cluster create operation. Required data: org_name, ovdc_name, cluster_name (data validation handled in broker) :return: Dict """ _raise_error_if_pks_not_enabled() data = req_utils.flatten_request_data(request_data, [RequestKey.INPUT_SPEC]) required = [RequestKey.CLUSTER_NAME] req_utils.validate_payload(data, required) cluster_name = data[RequestKey.CLUSTER_NAME] data['is_org_admin_search'] = True try: _get_cluster_and_broker(data, op_ctx, telemetry=False) raise ClusterAlreadyExistsError(f"Cluster {cluster_name} " f"already exists.") except ClusterNotFoundError: pass sysadmin_client_v33 = op_ctx.get_sysadmin_client( api_version=DEFAULT_API_VERSION) k8s_metadata = \ ovdc_utils.get_ovdc_k8s_provider_metadata( sysadmin_client_v33, org_name=data[RequestKey.ORG_NAME], ovdc_name=data[RequestKey.OVDC_NAME], include_credentials=True, include_nsxt_info=True) broker = _get_broker_from_k8s_metadata(k8s_metadata, op_ctx) data[RequestKey.PKS_PLAN_NAME] = k8s_metadata[PKS_PLANS_KEY][0] data[RequestKey.PKS_EXT_HOST] = \ f"{cluster_name}.{k8s_metadata[PKS_CLUSTER_DOMAIN_KEY]}" cluster = broker.create_cluster(data=data) # Record telemetry data telemetry_handler.record_user_action_details( cse_operation=CseOperation.PKS_CLUSTER_CREATE, cse_params=_get_telemetry_data(data, cluster)) return cluster
def ovdc_info(request_data, op_ctx: ctx.OperationContext): """Request handler for ovdc info operation. Required data: org_name, ovdc_name :return: Dictionary with org VDC k8s provider metadata. """ required = [RequestKey.OVDC_ID] req_utils.validate_payload(request_data, required) # Record telemetry data cse_params = copy.deepcopy(request_data) cse_params[PayloadKey. SOURCE_DESCRIPTION] = thread_local_data.get_thread_local_data( ThreadLocalData.USER_AGENT) # noqa: E501 record_user_action_details(cse_operation=CseOperation.OVDC_INFO, cse_params=cse_params) return ovdc_utils.get_ovdc_k8s_provider_metadata( op_ctx.sysadmin_client, ovdc_id=request_data[RequestKey.OVDC_ID])
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 ovdc_update(request_data, op_ctx: ctx.OperationContext): """Request handler for ovdc enable, disable operations. Required data: org_name, ovdc_name, k8s_provider Conditional data: if k8s_provider is 'ent-pks': pks_plan_name, pks_cluster_domain :return: Dictionary with org VDC update task href. """ # TODO the data flow here should be better understood. # org_name and ovdc_name seem redundant if we already have ovdc_id data = req_utils.flatten_request_data( request_data, [RequestKey.INPUT_SPEC]) required = [ RequestKey.ORG_NAME, RequestKey.OVDC_NAME, RequestKey.K8S_PROVIDER, RequestKey.OVDC_ID ] validated_data = data req_utils.validate_payload(validated_data, required) k8s_provider = validated_data[RequestKey.K8S_PROVIDER] k8s_provider_info = {K8S_PROVIDER_KEY: k8s_provider} # Record the telemetry data cse_params = copy.deepcopy(validated_data) cse_params[PayloadKey.SOURCE_DESCRIPTION] = thread_local_data.get_thread_local_data(ThreadLocalData.USER_AGENT) # noqa: E501 cse_operation = CseOperation.OVDC_DISABLE if k8s_provider == K8sProvider.NONE else CseOperation.OVDC_ENABLE # noqa: E501 record_user_action_details(cse_operation=cse_operation, cse_params=cse_params) # noqa: E501 sysadmin_client_v33 = \ op_ctx.get_sysadmin_client(api_version=DEFAULT_API_VERSION) try: if k8s_provider == K8sProvider.PKS: if not server_utils.is_pks_enabled(): raise e.CseServerError('CSE server is not ' 'configured to work with PKS.') required = [ RequestKey.PKS_PLAN_NAME, RequestKey.PKS_CLUSTER_DOMAIN ] req_utils.validate_payload(validated_data, required) # Check if target ovdc is not already enabled for other non PKS k8 providers # noqa: E501 ovdc_metadata = ovdc_utils.get_ovdc_k8s_provider_metadata( sysadmin_client_v33, ovdc_id=validated_data[RequestKey.OVDC_ID]) ovdc_k8_provider = ovdc_metadata.get(K8S_PROVIDER_KEY) if ovdc_k8_provider != K8sProvider.NONE and \ ovdc_k8_provider != k8s_provider: raise e.CseServerError("Ovdc already enabled for different K8 provider") # noqa: E501 k8s_provider_info = ovdc_utils.construct_k8s_metadata_from_pks_cache( # noqa: E501 sysadmin_client_v33, ovdc_id=validated_data[RequestKey.OVDC_ID], org_name=validated_data[RequestKey.ORG_NAME], pks_plans=validated_data[RequestKey.PKS_PLAN_NAME], pks_cluster_domain=validated_data[RequestKey.PKS_CLUSTER_DOMAIN], # noqa: E501 k8s_provider=k8s_provider) ovdc_utils.create_pks_compute_profile(validated_data, op_ctx, k8s_provider_info) task = ovdc_utils.update_ovdc_k8s_provider_metadata( sysadmin_client_v33, validated_data[RequestKey.OVDC_ID], k8s_provider_data=k8s_provider_info, k8s_provider=k8s_provider) # Telemetry - Record successful enabling/disabling of ovdc record_user_action(cse_operation, status=OperationStatus.SUCCESS) return {'task_href': task.get('href')} except Exception as err: logger.SERVER_LOGGER.error(f"Error while updating OVDC: {str(err)}") # Telemetry - Record failed enabling/disabling of ovdc record_user_action(cse_operation, status=OperationStatus.FAILED) raise err