def is_pks_enabled(): from container_service_extension.server.service import Service return Service().is_pks_enabled()
def get_pks_cache(): from container_service_extension.server.service import Service return Service().get_pks_cache()
def get_registered_def_interface() -> common_models.DefInterface: """Fetch the native cluster interface loaded during server startup.""" from container_service_extension.server.service import Service return Service().get_kubernetes_interface()
def get_registered_def_entity_type() -> common_models.DefEntityType: """Fetch the native cluster entity type loaded during server startup.""" from container_service_extension.server.service import Service return Service().get_native_cluster_entity_type()
def process_request(message): """ Determine the correct api handler to invoke and invoke it. The request URI, api version and HTTP verb are used to determine the request operation and the corresponding handler. Additionaly support for payload verification, query param verification will be added in a later point of time. URL template matching is also performed to compute values of url template parameters. These computed values, request body and query params are all sent to handlers in form of a dictionary. :param dict message: message recived over AMQP/MQTT bus representing the incoming REST request. :returns: response computed by the handler after processing the request """ 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) # Convert to upper case for matching the ENUM values method = RequestMethod(message['method'].upper()) url = message['requestUri'] url_tokens = url.split("/") # ignore the vcd host and /api in the url if len(url_tokens) > 2: url_tokens = url_tokens[2:] query_params = None if message['queryString']: query_params = dict(parse_qsl(message['queryString'])) request_body = None # Should we do a content-type check? and allow only application/json content? # noqa: E501 if len(message['body']) > 0: raw_body = base64.b64decode(message['body']).decode( sys.getfilesystemencoding()) # noqa: E501 request_body = json.loads(raw_body) found = False url_data = {} for entry in CSE_REQUEST_DISPATCHER_LIST: if found: break if len(entry['url_tokens']) != len(url_tokens): continue url_matched = True for i in range(0, len(url_tokens)): token = entry['url_tokens'][i] if token.startswith("$"): url_data[token[1:]] = url_tokens[i] elif token.lower() != url_tokens[i].lower(): url_matched = False url_data.clear() break if not url_matched: continue if method not in entry.keys(): raise cse_exception.MethodNotAllowedRequestError() handlers = entry[method] matched_handler = None supported_api_versions = [] for versions in handlers.keys(): supported_api_versions.extend(list(versions)) if api_version in versions or '*' in versions: matched_handler = handlers[versions] break if not matched_handler: raise cse_exception.NotAcceptableRequestError( error_message="Invalid api version specified. Expected " f"api version '{supported_api_versions}'.") operation = matched_handler['operation'] handler_method = matched_handler['handler'] # ToDo: Extra validation based on allowed query params, content type etc. # noqa: E501 found = True if not found: raise cse_exception.NotFoundRequestError() # /system operations are excluded from these checks if operation not in (CseOperation.SYSTEM_INFO, CseOperation.SYSTEM_UPDATE): from container_service_extension.server.service import Service if not Service().is_running(): raise cse_exception.BadRequestError( error_message='CSE service is disabled. ' 'Contact the System Administrator.') # create request data dict from incoming message data request_data = {'url': url} # ToDo: Device better way to send request body to handlers. if request_body: # update request_data with request_body LOGGER.debug(f"request body: {request_data}") # update request data dict with query params data # ToDo: Device better way to send request query params to handlers. if query_params: # update request_data with 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 = handler_method(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 process_request(message): from container_service_extension.server.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 = server_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.INPUT_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