def process_request(body): from container_service_extension.service import Service LOGGER.debug(f"Incoming request body: {json.dumps(body)}") url_data = _get_url_data(body['method'], body['requestUri']) operation = url_data[_OPERATION_KEY] # check if server is disabled if operation not in (CseOperation.SYSTEM_INFO, CseOperation.SYSTEM_UPDATE)\ and not Service().is_running(): raise e.BadRequestError(error_message='CSE service is disabled. ' 'Contact the System Administrator.') # create request data dict from request body data request_data = {} if len(body['body']) > 0: raw_body = base64.b64decode(body['body']).decode( sys.getfilesystemencoding()) # noqa: E501 request_data = json.loads(raw_body) LOGGER.debug(f"request body: {request_data}") # update request data dict with query params data if body['queryString']: query_params = dict(parse_qsl(body['queryString'])) request_data.update(query_params) LOGGER.debug(f"query parameters: {query_params}") # update request spec with operation specific data in the url request_data.update(url_data) # remove None values from request payload data = {k: v for k, v in request_data.items() if v is not None} # extract out the authorization token tenant_auth_token = body['headers'].get('x-vcloud-authorization') is_jwt_token = False auth_header = body['headers'].get('Authorization') if auth_header: tokens = auth_header.split(" ") if len(tokens) == 2 and tokens[0].lower() == 'bearer': tenant_auth_token = tokens[1] is_jwt_token = True # process the request context = ctx.RequestContext(tenant_auth_token, is_jwt=is_jwt_token, request_id=body['id']) try: body_content = OPERATION_TO_HANDLER[operation](data, context) finally: if not context.is_async: context.end() if not isinstance(body_content, (list, dict)): body_content = {RESPONSE_MESSAGE_KEY: str(body_content)} response = { 'status_code': operation.ideal_response_code, 'body': body_content, } LOGGER.debug(f"Outgoing response: {str(response)}") return response
def exception_handler_wrapper(*args, **kwargs): try: result = func(*args, **kwargs) except (KeyError, TypeError, ValueError) as error: LOGGER.error(error) raise cse_exception.BadRequestError(error_message=str(error)) except Exception as error: LOGGER.error(error) raise error return result
def update_status(self, server_action: ServerAction): def graceful_shutdown(): message = 'Shutting down CSE' n = self.active_requests_count() if n > 0: message += f" CSE will finish processing {n} requests." self._state = ServerState.STOPPING return message if self._state == ServerState.RUNNING: if server_action == ServerAction.ENABLE: return 'CSE is already enabled and running.' if server_action == ServerAction.DISABLE: self._state = ServerState.DISABLED return 'CSE has been disabled.' if server_action == ServerAction.STOP: raise cse_exception.BadRequestError( error_message='CSE must be disabled before ' 'it can be stopped.') raise cse_exception.BadRequestError( error_message=f"Invalid server action: '{server_action}'") if self._state == ServerState.DISABLED: if server_action == ServerAction.ENABLE: self._state = ServerState.RUNNING return 'CSE has been enabled and is running.' if server_action == ServerAction.DISABLE: return 'CSE is already disabled.' if server_action == ServerAction.STOP: return graceful_shutdown() if self._state == ServerState.STOPPING: if server_action == ServerAction.ENABLE: raise cse_exception.BadRequestError( error_message='Cannot enable CSE while it is being' 'stopped.') if server_action == ServerAction.DISABLE: raise cse_exception.BadRequestError( error_message='Cannot disable CSE while it is being' ' stopped.') if server_action == ServerAction.STOP: return graceful_shutdown() raise cse_exception.CseServerError( f"Invalid server state: '{self._state}'") # noqa: E501
def process_request(message): from container_service_extension.service import Service LOGGER.debug(f"Incoming request message: {json.dumps(message)}") api_version_header = _parse_accept_header( accept_header=message['headers'].get('Accept')) api_version = _get_api_version_from_accept_header( api_version_header=api_version_header) url_data = _get_url_data(method=message['method'], url=message['requestUri'], api_version=api_version) # noqa: E501 operation = url_data[_OPERATION_KEY] # Check api version and if server is disabled or not # /system operations are excluded from these checks if operation not in (CseOperation.SYSTEM_INFO, CseOperation.SYSTEM_UPDATE): if not Service().is_running(): raise cse_exception.BadRequestError( error_message='CSE service is disabled. ' 'Contact the System Administrator.') else: server_api_version = utils.get_server_api_version() if api_version != server_api_version: raise cse_exception.NotAcceptableRequestError( error_message="Invalid api version specified. Expected " f"api version '{server_api_version}'.") # create request data dict from incoming message data request_data = {} is_cse_3_0_request = _is_cse_3_0_endpoint(message['requestUri']) if len(message['body']) > 0: raw_body = base64.b64decode(message['body']).decode( sys.getfilesystemencoding()) # noqa: E501 request_body = json.loads(raw_body) if is_cse_3_0_request: request_data[shared_constants.RequestKey.V35_SPEC] = request_body else: request_data.update(request_body) LOGGER.debug(f"request body: {request_data}") # update request data dict with query params data if message['queryString']: query_params = dict(parse_qsl(message['queryString'])) if is_cse_3_0_request: request_data[shared_constants.RequestKey.V35_QUERY] = query_params else: request_data.update(query_params) LOGGER.debug(f"query parameters: {query_params}") # update request spec with operation specific data in the url request_data.update(url_data) # remove None values from request payload data = {k: v for k, v in request_data.items() if v is not None} # extract out the authorization token tenant_auth_token = message['headers'].get('x-vcloud-authorization') is_jwt_token = False auth_header = message['headers'].get('Authorization') if auth_header: tokens = auth_header.split(" ") if len(tokens) == 2 and tokens[0].lower() == 'bearer': tenant_auth_token = tokens[1] is_jwt_token = True # create operation context operation_ctx = ctx.OperationContext(tenant_auth_token, is_jwt=is_jwt_token, request_id=message['id']) try: body_content = OPERATION_TO_HANDLER[operation](data, operation_ctx) finally: if not operation_ctx.is_async: operation_ctx.end() if not isinstance(body_content, (list, dict)): body_content = \ {shared_constants.RESPONSE_MESSAGE_KEY: str(body_content)} response = { 'status_code': operation.ideal_response_code, 'body': body_content, } LOGGER.debug(f"Outgoing response: {str(response)}") return response
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