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)
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
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
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, {}, ""
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
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)
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)
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, {}, ''
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
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
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)
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)
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)
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"))
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)
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