Beispiel #1
0
 def update_account(
     self, context: RequestContext, patch_operations: ListOfPatchOperation = None
 ) -> Account:
     region_details = APIGatewayRegion.get()
     apply_json_patch_safe(region_details.account, patch_operations, in_place=True)
     result = to_account_response_json(region_details.account)
     return Account(**result)
Beispiel #2
0
    def apigateway_response_usage_plan_individual(self, request, full_url,
                                                  headers, *args, **kwargs):
        self.setup_class(request, full_url, headers)
        if self.method == "PATCH":
            url_path_parts = self.path.split("/")
            usage_plan_id = url_path_parts[2]
            patch_operations = self._get_param("patchOperations")
            usage_plan = self.backend.usage_plans.get(usage_plan_id)
            if not usage_plan:
                raise UsagePlanNotFoundException()

            apply_json_patch_safe(usage_plan, patch_operations, in_place=True)
            # fix certain attributes after running the patch updates
            if isinstance(usage_plan.get("apiStages"), (dict, str)):
                usage_plan["apiStages"] = [usage_plan["apiStages"]]
            api_stages = usage_plan.get("apiStages") or []
            for i in range(len(api_stages)):
                if isinstance(api_stages[i], str) and ":" in api_stages[i]:
                    api_id, stage = api_stages[i].split(":")
                    api_stages[i] = {"apiId": api_id, "stage": stage}

            return 200, {}, json.dumps(usage_plan)
        result = apigateway_response_usage_plan_individual_orig(
            self, request, full_url, headers, *args, **kwargs)
        return result
Beispiel #3
0
 def backend_update_deployment(self, function_id, deployment_id,
                               patch_operations):
     rest_api = self.get_rest_api(function_id)
     deployment = rest_api.get_deployment(deployment_id)
     deployment = deployment or {}
     apply_json_patch_safe(deployment, patch_operations, in_place=True)
     return deployment
Beispiel #4
0
    def apigateway_response_restapis_individual(self, request, full_url,
                                                headers):
        if request.method in ["GET", "DELETE"]:
            return apigateway_response_restapis_individual_orig(
                self, request, full_url, headers)

        self.setup_class(request, full_url, headers)
        function_id = self.path.replace("/restapis/", "", 1).split("/")[0]

        if self.method == "PATCH":
            not_supported_attributes = ["/id", "/region_name", "/createdDate"]

            rest_api = self.backend.apis.get(function_id)
            if not rest_api:
                msg = "Invalid API identifier specified %s:%s" % (
                    TEST_AWS_ACCOUNT_ID,
                    function_id,
                )
                return 404, {}, msg

            patch_operations = self._get_param("patchOperations")
            model_attributes = list(rest_api.__dict__.keys())
            for operation in patch_operations:
                if operation["path"] in not_supported_attributes:
                    msg = "Invalid patch path %s" % (operation["path"])
                    return 400, {}, msg
                path_start = operation["path"].strip("/").split("/")[0]
                path_start_usc = camelcase_to_underscores(path_start)
                if path_start not in model_attributes and path_start_usc in model_attributes:
                    operation["path"] = operation["path"].replace(
                        path_start, path_start_usc)

            rest_api.__dict__ = DelSafeDict(rest_api.__dict__)
            apply_json_patch_safe(rest_api.__dict__,
                                  patch_operations,
                                  in_place=True)

            # fix data types after patches have been applied
            rest_api.minimum_compression_size = int(
                rest_api.minimum_compression_size or -1)
            endpoint_configs = rest_api.endpoint_configuration or {}
            if isinstance(endpoint_configs.get("vpcEndpointIds"), str):
                endpoint_configs["vpcEndpointIds"] = [
                    endpoint_configs["vpcEndpointIds"]
                ]

            return 200, {}, json.dumps(
                self.backend.get_rest_api(function_id).to_dict())

        # handle import rest_api via swagger file
        if self.method == "PUT":
            body = json.loads(to_str(self.body))
            rest_api = self.backend.put_rest_api(function_id, body,
                                                 self.querystring)
            return 200, {}, json.dumps(rest_api.to_dict())

        return 400, {}, ""
Beispiel #5
0
 def backend_model_apply_operations(self, patch_operations):
     # run pre-actions
     if isinstance(self, apigateway_models.Stage) and [
         op for op in patch_operations if "/accessLogSettings" in op.get("path", "")
     ]:
         self["accessLogSettings"] = self.get("accessLogSettings") or {}
     # apply patches
     apply_json_patch_safe(self, patch_operations, in_place=True)
     # run post-actions
     if isinstance(self, apigateway_models.Stage):
         bool_params = ["cacheClusterEnabled", "tracingEnabled"]
         for bool_param in bool_params:
             if self.get(bool_param):
                 self[bool_param] = str_to_bool(self.get(bool_param))
     return self
Beispiel #6
0
    def update_base_path_mapping(
        self,
        context: RequestContext,
        domain_name: String,
        base_path: String,
        patch_operations: ListOfPatchOperation = None,
    ) -> BasePathMapping:
        region_details = APIGatewayRegion.get()

        mappings_list = region_details.base_path_mappings.get(domain_name) or []

        mapping = ([m for m in mappings_list if m["basePath"] == base_path] or [None])[0]
        if mapping is None:
            raise NotFoundException(
                f"Not found: mapping for domain name {domain_name}, "
                f"base path {base_path} in list {mappings_list}"
            )

        patch_operations = ensure_list(patch_operations)
        for operation in patch_operations:
            if operation["path"] == "/restapiId":
                operation["path"] = "/restApiId"
        result = apply_json_patch_safe(mapping, patch_operations)

        for i in range(len(mappings_list)):
            if mappings_list[i]["basePath"] == base_path:
                mappings_list[i] = result

        result = to_base_mapping_response_json(domain_name, base_path, result)
        return BasePathMapping(**result)
Beispiel #7
0
    def update_request_validator(
        self,
        context: RequestContext,
        rest_api_id: String,
        request_validator_id: String,
        patch_operations: ListOfPatchOperation = None,
    ) -> RequestValidator:
        region_details = APIGatewayRegion.get()

        auth_list = region_details.validators.get(rest_api_id) or []
        validator = ([a for a in auth_list if a["id"] == request_validator_id] or [None])[0]

        if validator is None:
            raise NotFoundException(
                f"Validator {request_validator_id} for API Gateway {rest_api_id} not found"
            )

        result = apply_json_patch_safe(validator, patch_operations)

        entry_list = region_details.validators[rest_api_id]
        for i in range(len(entry_list)):
            if entry_list[i]["id"] == request_validator_id:
                entry_list[i] = result

        result = to_validator_response_json(rest_api_id, result)
        return RequestValidator(**result)
Beispiel #8
0
    def apigateway_response_restapis_individual(self, request, full_url,
                                                headers):
        if request.method in ['GET', 'DELETE']:
            return apigateway_response_restapis_individual_orig(
                self, request, full_url, headers)

        self.setup_class(request, full_url, headers)
        function_id = self.path.replace('/restapis/', '', 1).split('/')[0]

        if self.method == 'PATCH':
            not_supported_attributes = ['/id', '/region_name', '/createdDate']

            rest_api = self.backend.apis.get(function_id)
            if not rest_api:
                msg = 'Invalid API identifier specified %s:%s' % (
                    TEST_AWS_ACCOUNT_ID, function_id)
                return 404, {}, msg

            patch_operations = self._get_param('patchOperations')
            model_attributes = list(rest_api.__dict__.keys())
            for operation in patch_operations:
                if operation['path'] in not_supported_attributes:
                    msg = 'Invalid patch path %s' % (operation['path'])
                    return 400, {}, msg
                path_stripped = operation['path'].strip('/')
                path_underscores = camelcase_to_underscores(path_stripped)
                if path_stripped not in model_attributes and path_underscores in model_attributes:
                    operation['path'] = operation['path'].replace(
                        path_stripped, path_underscores)

            rest_api.__dict__ = DelSafeDict(rest_api.__dict__)
            apply_json_patch_safe(rest_api.__dict__,
                                  patch_operations,
                                  in_place=True)

            return 200, {}, json.dumps(
                self.backend.get_rest_api(function_id).to_dict())

        # handle import rest_api via swagger file
        if self.method == 'PUT':
            body = json.loads(to_str(self.body))
            rest_api = self.backend.put_rest_api(function_id, body)
            return 200, {}, json.dumps(rest_api.to_dict())

        return 400, {}, ''
Beispiel #9
0
    def apigateway_response_integrations(self, request, *args, **kwargs):
        result = apigateway_response_integrations_orig(self, request, *args,
                                                       **kwargs)

        if self.method not in ["PUT", "PATCH"]:
            return result

        url_path_parts = self.path.split("/")
        function_id = url_path_parts[2]
        resource_id = url_path_parts[4]
        method_type = url_path_parts[6]

        integration = self.backend.get_integration(function_id, resource_id,
                                                   method_type)
        if not integration:
            return result

        if self.method == "PUT":
            timeout_milliseconds = self._get_param("timeoutInMillis")
            request_parameters = self._get_param("requestParameters") or {}
            cache_key_parameters = self._get_param("cacheKeyParameters") or []
            content_handling = self._get_param("contentHandling")
            integration["timeoutInMillis"] = timeout_milliseconds
            integration["requestParameters"] = request_parameters
            integration["cacheKeyParameters"] = cache_key_parameters
            integration["contentHandling"] = content_handling
            return 200, {}, json.dumps(integration)

        if self.method == "PATCH":
            patch_operations = self._get_param("patchOperations")
            apply_json_patch_safe(integration, patch_operations, in_place=True)
            # fix data types
            if integration.get("timeoutInMillis"):
                integration["timeoutInMillis"] = int(
                    integration.get("timeoutInMillis"))
            skip_verification = (integration.get("tlsConfig")
                                 or {}).get("insecureSkipVerification")
            if skip_verification:
                integration["tlsConfig"][
                    "insecureSkipVerification"] = str_to_bool(
                        skip_verification)

        return result
Beispiel #10
0
    def apigateway_response_integrations(self, request, *args, **kwargs):
        result = apigateway_response_integrations_orig(self, request, *args,
                                                       **kwargs)

        if self.method not in ['PUT', 'PATCH']:
            return result

        url_path_parts = self.path.split('/')
        function_id = url_path_parts[2]
        resource_id = url_path_parts[4]
        method_type = url_path_parts[6]

        integration = self.backend.get_integration(function_id, resource_id,
                                                   method_type)
        if not integration:
            return result

        if self.method == 'PUT':
            timeout_milliseconds = self._get_param('timeoutInMillis')
            request_parameters = self._get_param('requestParameters') or {}
            cache_key_parameters = self._get_param('cacheKeyParameters') or []
            content_handling = self._get_param('contentHandling')
            integration['timeoutInMillis'] = timeout_milliseconds
            integration['requestParameters'] = request_parameters
            integration['cacheKeyParameters'] = cache_key_parameters
            integration['contentHandling'] = content_handling
            return 200, {}, json.dumps(integration)

        if self.method == 'PATCH':
            patch_operations = self._get_param('patchOperations')
            apply_json_patch_safe(integration, patch_operations, in_place=True)
            # fix data types
            if integration.get('timeoutInMillis'):
                integration['timeoutInMillis'] = int(
                    integration.get('timeoutInMillis'))
            skip_verification = (integration.get('tlsConfig')
                                 or {}).get('insecureSkipVerification')
            if skip_verification:
                integration['tlsConfig']['insecureSkipVerification'] = str(
                    skip_verification) in TRUE_STRINGS

        return result
Beispiel #11
0
    def _patch_api_gateway_entity(
            self, entity: Dict) -> Optional[Tuple[int, Dict, str]]:
        not_supported_attributes = ["/id", "/region_name", "/create_date"]

        patch_operations = self._get_param("patchOperations")

        model_attributes = list(entity.keys())
        for operation in patch_operations:
            if operation["path"].strip("/") in REST_API_ATTRIBUTES:
                operation["path"] = camelcase_to_underscores(operation["path"])
            path_start = operation["path"].strip("/").split("/")[0]
            path_start_usc = camelcase_to_underscores(path_start)
            if path_start not in model_attributes and path_start_usc in model_attributes:
                operation["path"] = operation["path"].replace(
                    path_start, path_start_usc)
            if operation["path"] in not_supported_attributes:
                msg = "Invalid patch path %s" % (operation["path"])
                return 400, {}, msg

        apply_json_patch_safe(entity, patch_operations, in_place=True)
Beispiel #12
0
 def update_client_certificate(
     self,
     context: RequestContext,
     client_certificate_id: String,
     patch_operations: ListOfPatchOperation = None,
 ) -> ClientCertificate:
     region_details = APIGatewayRegion.get()
     entity = region_details.client_certificates.get(client_certificate_id)
     if entity is None:
         raise NotFoundException(f'Client certificate ID "{client_certificate_id}" not found')
     result = apply_json_patch_safe(entity, patch_operations)
     result = to_client_cert_response_json(result)
     return ClientCertificate(**result)
Beispiel #13
0
 def update_vpc_link(
     self,
     context: RequestContext,
     vpc_link_id: String,
     patch_operations: ListOfPatchOperation = None,
 ) -> VpcLink:
     region_details = APIGatewayRegion.get()
     vpc_link = region_details.vpc_links.get(vpc_link_id)
     if vpc_link is None:
         raise NotFoundException(f'VPC link ID "{vpc_link_id}" not found')
     result = apply_json_patch_safe(vpc_link, patch_operations)
     result = to_vpc_link_response_json(result)
     return VpcLink(**result)
Beispiel #14
0
    def _patch_api_gateway_entity(self, entity: Dict) -> Optional[Tuple[int, Dict, str]]:
        not_supported_attributes = ["/id", "/region_name", "/create_date"]

        patch_operations = self._get_param("patchOperations")

        model_attributes = list(entity.keys())
        for operation in patch_operations:
            if operation["path"].strip("/") in REST_API_ATTRIBUTES:
                operation["path"] = camelcase_to_underscores(operation["path"])
            path_start = operation["path"].strip("/").split("/")[0]
            path_start_usc = camelcase_to_underscores(path_start)
            if path_start not in model_attributes and path_start_usc in model_attributes:
                operation["path"] = operation["path"].replace(path_start, path_start_usc)
            if operation["path"] in not_supported_attributes:
                msg = f'Invalid patch path {operation["path"]}'
                return 400, {}, msg

        apply_json_patch_safe(entity, patch_operations, in_place=True)
        # apply some type fixes - TODO refactor/generalize
        if "disable_execute_api_endpoint" in entity:
            entity["disableExecuteApiEndpoint"] = bool(entity.pop("disable_execute_api_endpoint"))
        if "binary_media_types" in entity:
            entity["binaryMediaTypes"] = ensure_list(entity.pop("binary_media_types"))
Beispiel #15
0
    def update_documentation_part(
        self,
        context: RequestContext,
        rest_api_id: String,
        documentation_part_id: String,
        patch_operations: ListOfPatchOperation = None,
    ) -> DocumentationPart:
        region_details = APIGatewayRegion.get()

        entity = find_api_subentity_by_id(rest_api_id, documentation_part_id, "documentation_parts")
        if entity is None:
            raise NotFoundException(f"Documentation part not found: {documentation_part_id}")

        result = apply_json_patch_safe(entity, patch_operations)

        auth_list = region_details.documentation_parts[rest_api_id]
        for i in range(len(auth_list)):
            if auth_list[i]["id"] == documentation_part_id:
                auth_list[i] = result

        result = to_documentation_part_response_json(rest_api_id, result)
        return DocumentationPart(**result)
Beispiel #16
0
    def update_authorizer(
        self,
        context: RequestContext,
        rest_api_id: String,
        authorizer_id: String,
        patch_operations: ListOfPatchOperation = None,
    ) -> Authorizer:
        region_details = APIGatewayRegion.get()

        authorizer = find_api_subentity_by_id(rest_api_id, authorizer_id, "authorizers")
        if authorizer is None:
            raise NotFoundException(f"Authorizer not found: {authorizer_id}")

        result = apply_json_patch_safe(authorizer, patch_operations)
        result = normalize_authorizer(result)

        auth_list = region_details.authorizers[rest_api_id]
        for i in range(len(auth_list)):
            if auth_list[i]["id"] == authorizer_id:
                auth_list[i] = result

        result = to_authorizer_response_json(rest_api_id, result)
        return Authorizer(**result)
 def backend_model_apply_operations(self, patch_operations):
     apply_json_patch_safe(self, patch_operations, in_place=True)
     return self