diff --git a/docs/globals.rst b/docs/globals.rst index fc341f9ad8..5d1469e437 100644 --- a/docs/globals.rst +++ b/docs/globals.rst @@ -100,6 +100,7 @@ Currently, the following resources and properties are being supported: AccessLogSettings: Tags: DefaultRouteSettings: + RouteSettings: Domain: SimpleTable: diff --git a/samtranslator/model/api/http_api_generator.py b/samtranslator/model/api/http_api_generator.py index a1da483a3e..eb171d0439 100644 --- a/samtranslator/model/api/http_api_generator.py +++ b/samtranslator/model/api/http_api_generator.py @@ -42,6 +42,7 @@ def __init__( auth=None, cors_configuration=None, access_log_settings=None, + route_settings=None, default_route_settings=None, resource_attributes=None, passthrough_resource_attributes=None, @@ -73,6 +74,7 @@ def __init__( self.cors_configuration = cors_configuration self.tags = tags self.access_log_settings = access_log_settings + self.route_settings = route_settings self.default_route_settings = default_route_settings self.resource_attributes = resource_attributes self.passthrough_resource_attributes = passthrough_resource_attributes @@ -470,6 +472,7 @@ def _construct_stage(self): and not self.stage_variables and not self.access_log_settings and not self.default_route_settings + and not self.route_settings ): return @@ -490,6 +493,7 @@ def _construct_stage(self): stage.AccessLogSettings = self.access_log_settings stage.DefaultRouteSettings = self.default_route_settings stage.AutoDeploy = True + stage.RouteSettings = self.route_settings return stage diff --git a/samtranslator/model/apigatewayv2.py b/samtranslator/model/apigatewayv2.py index 695cec4a2d..589560b232 100644 --- a/samtranslator/model/apigatewayv2.py +++ b/samtranslator/model/apigatewayv2.py @@ -24,6 +24,7 @@ class ApiGatewayV2Stage(Resource): property_types = { "AccessLogSettings": PropertyType(False, is_type(dict)), "DefaultRouteSettings": PropertyType(False, is_type(dict)), + "RouteSettings": PropertyType(False, is_type(dict)), "ClientCertificateId": PropertyType(False, is_str()), "Description": PropertyType(False, is_str()), "ApiId": PropertyType(True, is_str()), diff --git a/samtranslator/model/eventsources/push.py b/samtranslator/model/eventsources/push.py index 944153bf76..e2bd338766 100644 --- a/samtranslator/model/eventsources/push.py +++ b/samtranslator/model/eventsources/push.py @@ -938,6 +938,7 @@ class HttpApi(PushEventSource): "Stage": PropertyType(False, is_str()), "Auth": PropertyType(False, is_type(dict)), "TimeoutInMillis": PropertyType(False, is_type(int)), + "RouteSettings": PropertyType(False, is_type(dict)), } def resources_to_link(self, resources): diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py index d6fcad40a1..88c16cae8c 100644 --- a/samtranslator/model/sam_resources.py +++ b/samtranslator/model/sam_resources.py @@ -876,6 +876,7 @@ class SamHttpApi(SamResourceMacro): "AccessLogSettings": PropertyType(False, is_type(dict)), "DefaultRouteSettings": PropertyType(False, is_type(dict)), "Auth": PropertyType(False, is_type(dict)), + "RouteSettings": PropertyType(False, is_type(dict)), "Domain": PropertyType(False, is_type(dict)), } @@ -910,6 +911,7 @@ def to_cloudformation(self, **kwargs): auth=self.Auth, cors_configuration=self.CorsConfiguration, access_log_settings=self.AccessLogSettings, + route_settings=self.RouteSettings, default_route_settings=self.DefaultRouteSettings, resource_attributes=self.resource_attributes, passthrough_resource_attributes=self.get_passthrough_resource_attributes(), diff --git a/samtranslator/plugins/api/implicit_api_plugin.py b/samtranslator/plugins/api/implicit_api_plugin.py index 8d8895e645..89da2c9647 100644 --- a/samtranslator/plugins/api/implicit_api_plugin.py +++ b/samtranslator/plugins/api/implicit_api_plugin.py @@ -162,7 +162,10 @@ def _add_api_to_swagger(self, event_id, event_properties, template): if isinstance(api_id, dict) or not template.get(api_id): raise InvalidEventException( event_id, - "RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource " "in same template", + self.api_id_property + + " must be a valid reference to an '" + + self._get_api_resource_type_name() + + "' resource in same template.", ) # Make sure Swagger is valid @@ -343,3 +346,11 @@ def _generate_implicit_api_resource(self): raise NotImplementedError( "Method _setup_api_properties() must be implemented in a " "subclass of ImplicitApiPlugin" ) + + def _get_api_resource_type_name(self): + """ + Returns the type of API resource + """ + raise NotImplementedError( + "Method _setup_api_properties() must be implemented in a " "subclass of ImplicitApiPlugin" + ) diff --git a/samtranslator/plugins/api/implicit_http_api_plugin.py b/samtranslator/plugins/api/implicit_http_api_plugin.py index 2e53190361..3f8849dbc1 100644 --- a/samtranslator/plugins/api/implicit_http_api_plugin.py +++ b/samtranslator/plugins/api/implicit_http_api_plugin.py @@ -1,5 +1,6 @@ import six +from samtranslator.model.intrinsics import make_conditional from samtranslator.model.naming import GeneratedLogicalId from samtranslator.plugins.api.implicit_api_plugin import ImplicitApiPlugin from samtranslator.public.open_api import OpenApiEditor @@ -88,6 +89,8 @@ def _process_api_events(self, function, api_events, template, condition=None): method_conditions[method] = condition self._add_api_to_swagger(logicalId, event_properties, template) + if "RouteSettings" in event_properties: + self._add_route_settings_to_api(logicalId, event_properties, template, condition) api_events[logicalId] = event # We could have made changes to the Events structure. Write it back to function @@ -116,6 +119,46 @@ def _get_api_definition_from_editor(self, editor): """ return editor.openapi + def _get_api_resource_type_name(self): + """ + Returns the type of API resource + """ + return "AWS::Serverless::HttpApi" + + def _add_route_settings_to_api(self, event_id, event_properties, template, condition): + """ + Adds the RouteSettings for this path/method from the given event to the RouteSettings configuration + on the AWS::Serverless::HttpApi that this refers to. + + :param string event_id: LogicalId of the event + :param dict event_properties: Properties of the event + :param SamTemplate template: SAM Template to search for Serverless::HttpApi resources + :param string condition: Condition on this HttpApi event (if any) + """ + + api_id = self._get_api_id(event_properties) + resource = template.get(api_id) + + path = event_properties["Path"] + method = event_properties["Method"] + + # Route should be in format "METHOD /path" or just "/path" if the ANY method is used + route = "{} {}".format(method.upper(), path) + if method == OpenApiEditor._X_ANY_METHOD: + route = path + + # Handle Resource-level conditions if necessary + api_route_settings = resource.properties.get("RouteSettings", {}) + event_route_settings = event_properties.get("RouteSettings", {}) + if condition: + event_route_settings = make_conditional(condition, event_properties.get("RouteSettings", {})) + + # Merge event-level and api-level RouteSettings properties + api_route_settings.setdefault(route, {}) + api_route_settings[route].update(event_route_settings) + resource.properties["RouteSettings"] = api_route_settings + template.set(api_id, resource) + class ImplicitHttpApiResource(SamResource): """ diff --git a/samtranslator/plugins/api/implicit_rest_api_plugin.py b/samtranslator/plugins/api/implicit_rest_api_plugin.py index ece4980fd0..3a6461928c 100644 --- a/samtranslator/plugins/api/implicit_rest_api_plugin.py +++ b/samtranslator/plugins/api/implicit_rest_api_plugin.py @@ -115,6 +115,12 @@ def _get_api_definition_from_editor(self, editor): """ return editor.swagger + def _get_api_resource_type_name(self): + """ + Returns the type of API resource + """ + return "AWS::Serverless::Api" + class ImplicitApiResource(SamResource): """ diff --git a/samtranslator/plugins/globals/globals.py b/samtranslator/plugins/globals/globals.py index e3cb4683b5..41afb4e137 100644 --- a/samtranslator/plugins/globals/globals.py +++ b/samtranslator/plugins/globals/globals.py @@ -72,6 +72,7 @@ class Globals(object): "CorsConfiguration", "DefaultRouteSettings", "Domain", + "RouteSettings", ], SamResourceType.SimpleTable.value: ["SSESpecification"], } diff --git a/tests/translator/input/http_api_explicit_stage.yaml b/tests/translator/input/http_api_explicit_stage.yaml index 36bca92b86..33a5f15047 100644 --- a/tests/translator/input/http_api_explicit_stage.yaml +++ b/tests/translator/input/http_api_explicit_stage.yaml @@ -2,6 +2,12 @@ Parameters: CorsParam: Type: String Default: True +Globals: + HttpApi: + RouteSettings: + "$default": + DataTraceEnabled: True + ThrottlingBurstLimit: 100 Resources: HttpApiFunction: Type: AWS::Serverless::Function @@ -14,10 +20,17 @@ Resources: Type: HttpApi Properties: ApiId: !Ref MyApi + RouteSettings: + ThrottlingBurstLimit: 300 + LoggingLevel: INFO MyApi: Type: AWS::Serverless::HttpApi Properties: StageName: Prod + RouteSettings: + "$default": + ThrottlingBurstLimit: 200 + ThrottlingRateLimit: 0.7 AccessLogSettings: DestinationArn: arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName Format: $context.requestId diff --git a/tests/translator/input/implicit_http_api_with_many_conditions.yaml b/tests/translator/input/implicit_http_api_with_many_conditions.yaml index 2fcda10e25..47dad4bd63 100644 --- a/tests/translator/input/implicit_http_api_with_many_conditions.yaml +++ b/tests/translator/input/implicit_http_api_with_many_conditions.yaml @@ -48,6 +48,9 @@ Conditions: - false Globals: HttpApi: + RouteSettings: + "GET /sub": + ThrottlingBurstLimit: 100 Auth: Authorizers: oauth2: @@ -73,6 +76,8 @@ Resources: HttpApiEvent: Type: HttpApi Properties: + RouteSettings: + ThrottlingBurstLimit: 200 Path: /sub Method: get helloworld1099: @@ -89,6 +94,8 @@ Resources: HttpApiEvent: Type: HttpApi Properties: + RouteSettings: + ThrottlingBurstLimit: 200 Auth: Authorizer: oauth2 HttpApiEvent2: diff --git a/tests/translator/output/aws-cn/http_api_explicit_stage.json b/tests/translator/output/aws-cn/http_api_explicit_stage.json index 13f444fb41..1865807fc3 100644 --- a/tests/translator/output/aws-cn/http_api_explicit_stage.json +++ b/tests/translator/output/aws-cn/http_api_explicit_stage.json @@ -1,10 +1,10 @@ { "Parameters": { "CorsParam": { - "Default": true, + "Default": true, "Type": "String" } - }, + }, "Resources": { "HttpApiFunctionSimpleCasePermission": { "Type": "AWS::Lambda::Permission", @@ -41,7 +41,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -53,23 +53,28 @@ "MyApiProdStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "MyApi" }, - "AutoDeploy": true, - "StageName": "Prod", + "StageName": "Prod", "AccessLogSettings": { - "DestinationArn": "arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName", + "DestinationArn": "arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName", "Format": "$context.requestId" + }, + "RouteSettings": { + "$default": { + "ThrottlingRateLimit": 0.7, + "DataTraceEnabled": true, + "ThrottlingBurstLimit": 300, + "LoggingLevel": "INFO" + } } } }, "HttpApiFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { - "ManagedPolicyArns": [ - "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ @@ -86,6 +91,9 @@ } ] }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], "Tags": [ { "Value": "SAM", @@ -103,12 +111,7 @@ "title": { "Ref": "AWS::StackName" } - }, - "x-amazon-apigateway-cors": { - "allowOrigins": [ - "*" - ] - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -125,6 +128,11 @@ } } }, + "x-amazon-apigateway-cors": { + "allowOrigins": [ + "*" + ] + }, "openapi": "3.0.1", "tags": [ { @@ -136,4 +144,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/implicit_http_api_with_many_conditions.json b/tests/translator/output/aws-cn/implicit_http_api_with_many_conditions.json index 519cb8083a..f2891303cc 100644 --- a/tests/translator/output/aws-cn/implicit_http_api_with_many_conditions.json +++ b/tests/translator/output/aws-cn/implicit_http_api_with_many_conditions.json @@ -199,12 +199,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "/hello/again": { "Fn::If": [ @@ -659,6 +653,7 @@ ] } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2": { @@ -676,7 +671,12 @@ } } }, - "openapi": "3.0.1" + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } }, "Condition": "ServerlessHttpApiCondition" @@ -1336,10 +1336,34 @@ "ServerlessHttpApiApiGatewayDefaultStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "ServerlessHttpApi" }, - "AutoDeploy": true, + "RouteSettings": { + "GET /sub": { + "Fn::If": [ + "MyCondition", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "$default": { + "Fn::If": [ + "Cond", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + } + }, "StageName": "$default" }, "Condition": "ServerlessHttpApiCondition" @@ -1476,4 +1500,4 @@ "Condition": "Cond3" } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/http_api_explicit_stage.json b/tests/translator/output/aws-us-gov/http_api_explicit_stage.json index b4007733df..4448303536 100644 --- a/tests/translator/output/aws-us-gov/http_api_explicit_stage.json +++ b/tests/translator/output/aws-us-gov/http_api_explicit_stage.json @@ -1,11 +1,10 @@ { "Parameters": { "CorsParam": { - "Default": true, + "Default": true, "Type": "String" } - }, - + }, "Resources": { "HttpApiFunctionSimpleCasePermission": { "Type": "AWS::Lambda::Permission", @@ -42,7 +41,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -54,23 +53,28 @@ "MyApiProdStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "MyApi" }, - "AutoDeploy": true, - "StageName": "Prod", + "StageName": "Prod", "AccessLogSettings": { - "DestinationArn": "arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName", + "DestinationArn": "arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName", "Format": "$context.requestId" + }, + "RouteSettings": { + "$default": { + "ThrottlingRateLimit": 0.7, + "DataTraceEnabled": true, + "ThrottlingBurstLimit": 300, + "LoggingLevel": "INFO" + } } } }, "HttpApiFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { - "ManagedPolicyArns": [ - "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ @@ -87,6 +91,9 @@ } ] }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], "Tags": [ { "Value": "SAM", @@ -105,17 +112,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], - "x-amazon-apigateway-cors": { - "allowOrigins": [ - "*" - ] - }, "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -132,9 +128,20 @@ } } }, - "openapi": "3.0.1" + "x-amazon-apigateway-cors": { + "allowOrigins": [ + "*" + ] + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/implicit_http_api_with_many_conditions.json b/tests/translator/output/aws-us-gov/implicit_http_api_with_many_conditions.json index c5eea99b65..24c96e8334 100644 --- a/tests/translator/output/aws-us-gov/implicit_http_api_with_many_conditions.json +++ b/tests/translator/output/aws-us-gov/implicit_http_api_with_many_conditions.json @@ -199,12 +199,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "/hello/again": { "Fn::If": [ @@ -659,6 +653,7 @@ ] } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2": { @@ -676,7 +671,12 @@ } } }, - "openapi": "3.0.1" + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } }, "Condition": "ServerlessHttpApiCondition" @@ -1336,10 +1336,34 @@ "ServerlessHttpApiApiGatewayDefaultStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "ServerlessHttpApi" }, - "AutoDeploy": true, + "RouteSettings": { + "GET /sub": { + "Fn::If": [ + "MyCondition", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "$default": { + "Fn::If": [ + "Cond", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + } + }, "StageName": "$default" }, "Condition": "ServerlessHttpApiCondition" @@ -1476,4 +1500,4 @@ "Condition": "Cond3" } } -} +} \ No newline at end of file diff --git a/tests/translator/output/error_api_invalid_restapiid.json b/tests/translator/output/error_api_invalid_restapiid.json index 58e049a957..aa4c86aa1d 100644 --- a/tests/translator/output/error_api_invalid_restapiid.json +++ b/tests/translator/output/error_api_invalid_restapiid.json @@ -1,8 +1,8 @@ { "errors": [ { - "errorMessage": "Resource with id [FunctionWithNonExistentApiReference] is invalid. Event with id [GetHtml] is invalid. RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource in same template" + "errorMessage": "Resource with id [FunctionWithNonExistentApiReference] is invalid. Event with id [GetHtml] is invalid. RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource in same template." } ], - "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [FunctionWithNonExistentApiReference] is invalid. Event with id [GetHtml] is invalid. RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource in same template" + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [FunctionWithNonExistentApiReference] is invalid. Event with id [GetHtml] is invalid. RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource in same template." } \ No newline at end of file diff --git a/tests/translator/output/error_http_api_event_invalid_api.json b/tests/translator/output/error_http_api_event_invalid_api.json index d979bb8bf3..acbe70f0ee 100644 --- a/tests/translator/output/error_http_api_event_invalid_api.json +++ b/tests/translator/output/error_http_api_event_invalid_api.json @@ -1,8 +1,8 @@ { "errors": [ { - "errorMessage": "Resource with id [HttpApiFunction] is invalid. Event with id [Api] is invalid. RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource in same template" + "errorMessage": "Resource with id [HttpApiFunction] is invalid. Event with id [Api] is invalid. ApiId must be a valid reference to an 'AWS::Serverless::HttpApi' resource in same template." } ], - "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [HttpApiFunction] is invalid. Event with id [Api] is invalid. RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource in same template" + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [HttpApiFunction] is invalid. Event with id [Api] is invalid. ApiId must be a valid reference to an 'AWS::Serverless::HttpApi' resource in same template." } \ No newline at end of file diff --git a/tests/translator/output/http_api_explicit_stage.json b/tests/translator/output/http_api_explicit_stage.json index f6795577a9..f0adc81739 100644 --- a/tests/translator/output/http_api_explicit_stage.json +++ b/tests/translator/output/http_api_explicit_stage.json @@ -1,10 +1,10 @@ { "Parameters": { "CorsParam": { - "Default": true, + "Default": true, "Type": "String" } - }, + }, "Resources": { "HttpApiFunctionSimpleCasePermission": { "Type": "AWS::Lambda::Permission", @@ -41,7 +41,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -53,23 +53,28 @@ "MyApiProdStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "MyApi" }, - "AutoDeploy": true, - "StageName": "Prod", + "StageName": "Prod", "AccessLogSettings": { - "DestinationArn": "arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName", + "DestinationArn": "arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName", "Format": "$context.requestId" + }, + "RouteSettings": { + "$default": { + "ThrottlingRateLimit": 0.7, + "DataTraceEnabled": true, + "ThrottlingBurstLimit": 300, + "LoggingLevel": "INFO" + } } } }, "HttpApiFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { - "ManagedPolicyArns": [ - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ @@ -86,6 +91,9 @@ } ] }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], "Tags": [ { "Value": "SAM", @@ -104,17 +112,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], - "x-amazon-apigateway-cors": { - "allowOrigins": [ - "*" - ] - }, "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -131,9 +128,20 @@ } } }, - "openapi": "3.0.1" + "x-amazon-apigateway-cors": { + "allowOrigins": [ + "*" + ] + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/implicit_http_api_with_many_conditions.json b/tests/translator/output/implicit_http_api_with_many_conditions.json index ac14371a17..b653dc3f0e 100644 --- a/tests/translator/output/implicit_http_api_with_many_conditions.json +++ b/tests/translator/output/implicit_http_api_with_many_conditions.json @@ -199,12 +199,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "/hello/again": { "Fn::If": [ @@ -659,6 +653,7 @@ ] } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2": { @@ -676,7 +671,12 @@ } } }, - "openapi": "3.0.1" + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } }, "Condition": "ServerlessHttpApiCondition" @@ -1336,10 +1336,34 @@ "ServerlessHttpApiApiGatewayDefaultStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "ServerlessHttpApi" }, - "AutoDeploy": true, + "RouteSettings": { + "GET /sub": { + "Fn::If": [ + "MyCondition", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "$default": { + "Fn::If": [ + "Cond", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + } + }, "StageName": "$default" }, "Condition": "ServerlessHttpApiCondition" @@ -1476,4 +1500,4 @@ "Condition": "Cond3" } } -} +} \ No newline at end of file diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 4b868ee675..459c280cd8 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -283,6 +283,7 @@ Tags | Map of `string` to `string` | A map (string to string) that specifies the AccessLogSettings | [AccessLogSettings](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-stage-accesslogsettings.html) | Settings for logging access in a stage. CorsConfiguration | `boolean` or [CorsConfiguration Object](#cors-configuration-object) | Enable CORS for all your Http APIs. Specify `true` for adding Cors with domain '*' to your Http APIs or specify a dictionary with additional [CorsConfiguration-Object](#cors-configuration-object). SAM adds `x-amazon-apigateway-cors` header in open api definition for your Http API when this property is defined. NOTE: Cors requires SAM to modify your OpenAPI definition. Hence it works only inline OpenAPI defined with `DefinitionBody`. DefaultRouteSettings | [RouteSettings](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-stage-routesettings.html) | The default route settings for this HTTP API. +RouteSettings | [RouteSettings](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-stage-routesettings.html) | Per-route route settings for this HTTP API. Domain | [Domain Configuration Object](#domain-configuration-object) | Configuration settings for custom domains on API. Must contain `DomainName` and `CertificateArn` ##### Return values