Пример #1
0
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
Пример #2
0
 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
Пример #3
0
    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
Пример #4
0
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