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/examples/2016-10-31/policy_templates/all_policy_templates.yaml b/examples/2016-10-31/policy_templates/all_policy_templates.yaml index e7875577b8..27e05190cb 100644 --- a/examples/2016-10-31/policy_templates/all_policy_templates.yaml +++ b/examples/2016-10-31/policy_templates/all_policy_templates.yaml @@ -26,6 +26,9 @@ Resources: - DynamoDBReadPolicy: TableName: name + - DynamoDBWritePolicy: + TableName: name + - SESSendBouncePolicy: IdentityName: name @@ -38,6 +41,9 @@ Resources: - S3CrudPolicy: BucketName: name + - S3WritePolicy: + BucketName: name + - AMIDescribePolicy: {} - CloudFormationDescribeStacksPolicy: {} diff --git a/samtranslator/model/api/http_api_generator.py b/samtranslator/model/api/http_api_generator.py index a1da483a3e..15c843ce57 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 @@ -195,6 +197,7 @@ def _construct_api_domain(self, http_api): ) domain_config = dict() domain.DomainName = self.domain.get("DomainName") + domain.Tags = self.tags endpoint = self.domain.get("EndpointConfiguration") if endpoint is None: @@ -418,10 +421,15 @@ def _get_authorizers(self, authorizers_config, default_authorizer=None): self.logical_id, "Authorizer %s must be a dictionary." % (authorizer_name) ) + if "OpenIdConnectUrl" in authorizer: + raise InvalidResourceException( + self.logical_id, + "'OpenIdConnectUrl' is no longer a supported property for authorizer '%s'. Please refer to the AWS SAM documentation." + % (authorizer_name), + ) authorizers[authorizer_name] = ApiGatewayV2Authorizer( api_logical_id=self.logical_id, name=authorizer_name, - open_id_connect_url=authorizer.get("OpenIdConnectUrl"), authorization_scopes=authorizer.get("AuthorizationScopes"), jwt_configuration=authorizer.get("JwtConfiguration"), id_source=authorizer.get("IdentitySource"), @@ -470,6 +478,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 @@ -489,12 +498,14 @@ def _construct_stage(self): stage.StageVariables = self.stage_variables stage.AccessLogSettings = self.access_log_settings stage.DefaultRouteSettings = self.default_route_settings + stage.Tags = self.tags stage.AutoDeploy = True + stage.RouteSettings = self.route_settings return stage def to_cloudformation(self): - """Generates CloudFormation resources from a SAM API resource + """Generates CloudFormation resources from a SAM HTTP API resource :returns: a tuple containing the HttpApi and Stage for an empty Api. :rtype: tuple diff --git a/samtranslator/model/apigatewayv2.py b/samtranslator/model/apigatewayv2.py index 695cec4a2d..1345cd79a9 100644 --- a/samtranslator/model/apigatewayv2.py +++ b/samtranslator/model/apigatewayv2.py @@ -12,7 +12,6 @@ class ApiGatewayV2HttpApi(Resource): "Description": PropertyType(False, is_str()), "FailOnWarnings": PropertyType(False, is_type(bool)), "BasePath": PropertyType(False, is_str()), - "Tags": PropertyType(False, list_of(is_type(dict))), "CorsConfiguration": PropertyType(False, is_type(dict)), } @@ -24,11 +23,12 @@ 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()), "StageName": PropertyType(False, one_of(is_str(), is_type(dict))), - "Tags": PropertyType(False, list_of(is_type(dict))), + "Tags": PropertyType(False, is_type(dict)), "StageVariables": PropertyType(False, is_type(dict)), "AutoDeploy": PropertyType(False, is_type(bool)), } @@ -41,7 +41,7 @@ class ApiGatewayV2DomainName(Resource): property_types = { "DomainName": PropertyType(True, is_str()), "DomainNameConfigurations": PropertyType(False, list_of(is_type(dict))), - "Tags": PropertyType(False, list_of(is_type(dict))), + "Tags": PropertyType(False, is_type(dict)), } @@ -57,33 +57,24 @@ class ApiGatewayV2ApiMapping(Resource): class ApiGatewayV2Authorizer(object): def __init__( - self, - api_logical_id=None, - name=None, - open_id_connect_url=None, - authorization_scopes=[], - jwt_configuration={}, - id_source=None, + self, api_logical_id=None, name=None, authorization_scopes=[], jwt_configuration={}, id_source=None, ): """ Creates an authorizer for use in V2 Http Apis """ - # OIDC uses a connect url, oauth2 doesn't - self.auth_type = "openIdConnect" - if open_id_connect_url is None: - self.auth_type = "oauth2" + # Currently only one type of auth + self.auth_type = "oauth2" self.api_logical_id = api_logical_id self.name = name - self.open_id_connect_url = open_id_connect_url self.authorization_scopes = authorization_scopes # Validate necessary parameters exist if not jwt_configuration: - raise InvalidResourceException(api_logical_id, name + " Authorizer must define 'JwtConfiguration'") + raise InvalidResourceException(api_logical_id, name + " Authorizer must define 'JwtConfiguration'.") self.jwt_configuration = jwt_configuration if not id_source: - raise InvalidResourceException(api_logical_id, name + " Authorizer must define 'IdentitySource'") + raise InvalidResourceException(api_logical_id, name + " Authorizer must define 'IdentitySource'.") self.id_source = id_source def generate_openapi(self): @@ -98,6 +89,4 @@ def generate_openapi(self): "type": "jwt", }, } - if self.open_id_connect_url: - openapi["x-amazon-apigateway-authorizer"]["openIdConnectUrl"] = self.open_id_connect_url return openapi diff --git a/samtranslator/model/cognito.py b/samtranslator/model/cognito.py index a78cfae1bd..bd9a830319 100644 --- a/samtranslator/model/cognito.py +++ b/samtranslator/model/cognito.py @@ -23,7 +23,7 @@ class CognitoUserPool(Resource): "UsernameAttributes": PropertyType(False, list_of(is_str())), "UserPoolAddOns": PropertyType(False, list_of(dict)), "UserPoolName": PropertyType(False, is_str()), - "UserPoolTags": PropertyType(False, is_str()), + "UserPoolTags": PropertyType(False, is_type(dict)), "VerificationMessageTemplate": PropertyType(False, is_type(dict)), } 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/samtranslator/policy_templates_data/policy_templates.json b/samtranslator/policy_templates_data/policy_templates.json index 4b21e3063f..d14758caac 100644 --- a/samtranslator/policy_templates_data/policy_templates.json +++ b/samtranslator/policy_templates_data/policy_templates.json @@ -205,6 +205,48 @@ ] } }, + "DynamoDBWritePolicy": { + "Description": "Gives write only access to a DynamoDB Table", + "Parameters": { + "TableName": { + "Description": "Name of the DynamoDB Table" + } + }, + "Definition": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "dynamodb:PutItem", + "dynamodb:UpdateItem", + "dynamodb:BatchWriteItem" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}", + { + "tableName": { + "Ref": "TableName" + } + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}/index/*", + { + "tableName": { + "Ref": "TableName" + } + } + ] + } + ] + } + ] + } + }, "DynamoDBReconfigurePolicy": { "Description": "Gives access reconfigure to a DynamoDB Table", "Parameters": { @@ -334,6 +376,48 @@ ] } }, + "S3WritePolicy": { + "Description": "Gives write permissions to objects in the S3 Bucket", + "Parameters": { + "BucketName": { + "Description": "Name of the Bucket" + } + }, + "Definition": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:PutObjectAcl", + "s3:PutLifecycleConfiguration" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}", + { + "bucketName": { + "Ref": "BucketName" + } + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}/*", + { + "bucketName": { + "Ref": "BucketName" + } + } + ] + } + ] + } + ] + } + }, "S3CrudPolicy": { "Description": "Gives CRUD permissions to objects in the S3 Bucket", "Parameters": { diff --git a/tests/model/test_api_v2.py b/tests/model/test_api_v2.py index 36d87b5e1e..e9fe87d934 100644 --- a/tests/model/test_api_v2.py +++ b/tests/model/test_api_v2.py @@ -15,16 +15,6 @@ def test_create_oauth2_auth(self): ) self.assertEquals(auth.auth_type, "oauth2") - def test_create_oidc_auth(self): - auth = ApiGatewayV2Authorizer( - api_logical_id="logicalId", - name="authName", - open_id_connect_url="https://example.com", - jwt_configuration={"config": "value"}, - id_source="https://example.com", - ) - self.assertEquals(auth.auth_type, "openIdConnect") - def test_create_authorizer_no_id_source(self): with pytest.raises(InvalidResourceException): auth = ApiGatewayV2Authorizer( diff --git a/tests/openapi/test_openapi.py b/tests/openapi/test_openapi.py index 95eceb135a..dde6ea061f 100644 --- a/tests/openapi/test_openapi.py +++ b/tests/openapi/test_openapi.py @@ -353,7 +353,6 @@ def test_must_fail_for_invalid_values(self, data, case): self.assertFalse(OpenApiEditor.is_valid(data), "openapi dictionary with {} must not be valid".format(case)) -# TODO this needs to be updated with OIDC auth - authorization scopes and anything else that needs testing the swagger class TestOpenApiEditor_add_auth(TestCase): def setUp(self): diff --git a/tests/translator/input/all_policy_templates.yaml b/tests/translator/input/all_policy_templates.yaml index 9038a3048a..5216a65f2c 100644 --- a/tests/translator/input/all_policy_templates.yaml +++ b/tests/translator/input/all_policy_templates.yaml @@ -160,5 +160,11 @@ Resources: - AthenaQueryPolicy: WorkGroupName: name + - S3WritePolicy: + BucketName: name + + - DynamoDBWritePolicy: + TableName: name + - EventBridgePutEventsPolicy: EventBusName: name diff --git a/tests/translator/input/error_http_api_invalid_auth.yaml b/tests/translator/input/error_http_api_invalid_auth.yaml index 76f24464be..a45f748002 100644 --- a/tests/translator/input/error_http_api_invalid_auth.yaml +++ b/tests/translator/input/error_http_api_invalid_auth.yaml @@ -53,6 +53,20 @@ Resources: Authorizer: OAuth2 AuthorizationScopes: "scope" + Function5: + Type: AWS::Serverless::Function + Properties: + Runtime: python3.7 + Handler: index.handler + CodeUri: s3://bucket/key + Events: + Api4: + Type: HttpApi + Properties: + ApiId: !Ref MyApi5 + Auth: + Authorizer: OIDC + MyApi: Type: AWS::Serverless::HttpApi Properties: @@ -120,6 +134,28 @@ Resources: audience: - MyApi IdentitySource: "$request.querystring.param" + DefinitionBody: + info: + version: '1.0' + title: + Ref: AWS::StackName + paths: {} + openapi: 3.0.1 + + MyApi5: + Type: AWS::Serverless::HttpApi + Properties: + Auth: + Authorizers: + OIDC: + OpenIdConnectUrl: "https://example.com/url" + AuthorizationScopes: + - scope4 + JwtConfiguration: + issuer: "https://www.example.com/v1/connect/oidc" + audience: + - MyApi + IdentitySource: "$request.querystring.param" DefinitionBody: info: version: '1.0' diff --git a/tests/translator/input/http_api_explicit_stage.yaml b/tests/translator/input/http_api_explicit_stage.yaml index 36bca92b86..f24269ccc7 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,19 @@ Resources: Type: HttpApi Properties: ApiId: !Ref MyApi + RouteSettings: + ThrottlingBurstLimit: 300 + LoggingLevel: INFO MyApi: Type: AWS::Serverless::HttpApi Properties: StageName: Prod + StageVariables: + VarName: VarValue + 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_auth_and_simple_case.yaml b/tests/translator/input/implicit_http_api_auth_and_simple_case.yaml index ff37c4daab..944e7c8400 100644 --- a/tests/translator/input/implicit_http_api_auth_and_simple_case.yaml +++ b/tests/translator/input/implicit_http_api_auth_and_simple_case.yaml @@ -27,13 +27,6 @@ Resources: Auth: AuthorizationScopes: - scope3 - SomeAuth: - Type: HttpApi - Properties: - Path: /someauth - Method: post - Auth: - Authorizer: OpenIdAuth oauth2Path: Type: HttpApi Properties: @@ -48,16 +41,6 @@ Globals: HttpApi: Auth: Authorizers: - OpenIdAuth: - AuthorizationScopes: - - scope1 - - scope2 - OpenIdConnectUrl: "https://www.example.com/v1/connect" - JwtConfiguration: - issuer: "https://www.example.com/v1/connect/oidc" - audience: - - MyApi - IdentitySource: "$request.querystring.param" oauth2Auth: AuthorizationScopes: - scope4 @@ -66,4 +49,4 @@ Globals: audience: - MyApi IdentitySource: "$request.querystring.param" - DefaultAuthorizer: OpenIdAuth + DefaultAuthorizer: oauth2Auth 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/all_policy_templates.json b/tests/translator/output/all_policy_templates.json index 7c6a7d2a7c..f98f0fbc16 100644 --- a/tests/translator/output/all_policy_templates.json +++ b/tests/translator/output/all_policy_templates.json @@ -1487,7 +1487,73 @@ } }, { - "PolicyName": "KitchenSinkFunctionRolePolicy55", + "PolicyName": "KitchenSinkFunctionRolePolicy55", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:PutObjectAcl", + "s3:PutLifecycleConfiguration" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}", + { + "bucketName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}/*", + { + "bucketName": "name" + } + ] + } + ] + } + ] + } + }, + { + "PolicyName": "KitchenSinkFunctionRolePolicy56", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "dynamodb:PutItem", + "dynamodb:UpdateItem", + "dynamodb:BatchWriteItem" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}", + { + "tableName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}/index/*", + { + "tableName": "name" + } + ] + } + ] + } + ] + } + }, + { + "PolicyName": "KitchenSinkFunctionRolePolicy57", "PolicyDocument": { "Statement": [ { diff --git a/tests/translator/output/api_with_basic_custom_domain_http.json b/tests/translator/output/api_with_basic_custom_domain_http.json index c37e4a826e..7bf4fefba7 100644 --- a/tests/translator/output/api_with_basic_custom_domain_http.json +++ b/tests/translator/output/api_with_basic_custom_domain_http.json @@ -32,7 +32,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -158,7 +161,10 @@ "EndpointType": "REGIONAL" } ], - "DomainName": "sam-v2-regional-test.com" + "DomainName": "sam-v2-regional-test.com", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApi": { diff --git a/tests/translator/output/api_with_basic_custom_domain_intrinsics_http.json b/tests/translator/output/api_with_basic_custom_domain_intrinsics_http.json index 6a85c1dd7e..4d351c3018 100644 --- a/tests/translator/output/api_with_basic_custom_domain_intrinsics_http.json +++ b/tests/translator/output/api_with_basic_custom_domain_intrinsics_http.json @@ -255,14 +255,17 @@ "ApiGatewayDomainNameV2c0ed6fae34": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": { + "Fn::Sub": "example-ap-southeast-1.com" + }, "DomainNameConfigurations": [ { "CertificateArn": "another-api-arn", "EndpointType": "REGIONAL" } ], - "DomainName": { - "Fn::Sub": "example-ap-southeast-1.com" + "Tags": { + "httpapi:createdBy": "SAM" } }, "Condition": "C1" @@ -274,7 +277,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "C1" }, @@ -285,7 +291,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "C1" }, diff --git a/tests/translator/output/api_with_custom_domain_route53_hosted_zone_name_http.json b/tests/translator/output/api_with_custom_domain_route53_hosted_zone_name_http.json index 5c1096fd72..d3351418d8 100644 --- a/tests/translator/output/api_with_custom_domain_route53_hosted_zone_name_http.json +++ b/tests/translator/output/api_with_custom_domain_route53_hosted_zone_name_http.json @@ -39,7 +39,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApioneApiMapping": { @@ -60,13 +63,16 @@ "ApiGatewayDomainNameV20caaf24ab1": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": "example.com", "DomainNameConfigurations": [ { "CertificateArn": "cert-arn-in-us-east-1", "EndpointType": "EDGE" } ], - "DomainName": "example.com" + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "RecordSetGroup456ebaf280": { diff --git a/tests/translator/output/api_with_custom_domain_route53_http.json b/tests/translator/output/api_with_custom_domain_route53_http.json index 0a24aca116..92bb463f52 100644 --- a/tests/translator/output/api_with_custom_domain_route53_http.json +++ b/tests/translator/output/api_with_custom_domain_route53_http.json @@ -84,13 +84,16 @@ "ApiGatewayDomainNameV20caaf24ab1": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": "example.com", "DomainNameConfigurations": [ { "CertificateArn": "cert-arn-in-us-east-1", "EndpointType": "EDGE" } ], - "DomainName": "example.com" + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApiProdStage": { @@ -100,7 +103,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyFunctionRole": { diff --git a/tests/translator/output/aws-cn/all_policy_templates.json b/tests/translator/output/aws-cn/all_policy_templates.json index f682ecd81d..fdd861115b 100644 --- a/tests/translator/output/aws-cn/all_policy_templates.json +++ b/tests/translator/output/aws-cn/all_policy_templates.json @@ -1487,7 +1487,73 @@ } }, { - "PolicyName": "KitchenSinkFunctionRolePolicy55", + "PolicyName": "KitchenSinkFunctionRolePolicy55", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:PutObjectAcl", + "s3:PutLifecycleConfiguration" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}", + { + "bucketName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}/*", + { + "bucketName": "name" + } + ] + } + ] + } + ] + } + }, + { + "PolicyName": "KitchenSinkFunctionRolePolicy56", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "dynamodb:PutItem", + "dynamodb:UpdateItem", + "dynamodb:BatchWriteItem" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}", + { + "tableName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}/index/*", + { + "tableName": "name" + } + ] + } + ] + } + ] + } + }, + { + "PolicyName": "KitchenSinkFunctionRolePolicy57", "PolicyDocument": { "Statement": [ { diff --git a/tests/translator/output/aws-cn/api_with_basic_custom_domain_http.json b/tests/translator/output/aws-cn/api_with_basic_custom_domain_http.json index 744faa7444..64561b3b69 100644 --- a/tests/translator/output/aws-cn/api_with_basic_custom_domain_http.json +++ b/tests/translator/output/aws-cn/api_with_basic_custom_domain_http.json @@ -32,7 +32,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -152,13 +155,16 @@ "ApiGatewayDomainNameV2ab8e63947d": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": "sam-v2-regional-test.com", "DomainNameConfigurations": [ { "CertificateArn": "arn:aws:acm:us-east-1:551213647843:certificate/6c911401-620d-4d41-b89e-366c238bb2f3", "EndpointType": "REGIONAL" } ], - "DomainName": "sam-v2-regional-test.com" + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApi": { diff --git a/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics_http.json b/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics_http.json index 55846f7ad9..e6dbc7df18 100644 --- a/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics_http.json +++ b/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics_http.json @@ -48,7 +48,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "C1" }, @@ -176,6 +179,9 @@ ], "DomainName": { "Fn::Sub": "example-cn-north-1.com" + }, + "Tags": { + "httpapi:createdBy": "SAM" } }, "Condition": "C1" @@ -225,7 +231,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "C1" }, diff --git a/tests/translator/output/aws-cn/api_with_custom_domain_route53_hosted_zone_name_http.json b/tests/translator/output/aws-cn/api_with_custom_domain_route53_hosted_zone_name_http.json index 73714c6cdf..f614884a85 100644 --- a/tests/translator/output/aws-cn/api_with_custom_domain_route53_hosted_zone_name_http.json +++ b/tests/translator/output/aws-cn/api_with_custom_domain_route53_hosted_zone_name_http.json @@ -39,7 +39,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApioneApiMapping": { @@ -66,7 +69,10 @@ "EndpointType": "EDGE" } ], - "DomainName": "example.com" + "DomainName": "example.com", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "RecordSetGroup456ebaf280": { diff --git a/tests/translator/output/aws-cn/api_with_custom_domain_route53_http.json b/tests/translator/output/aws-cn/api_with_custom_domain_route53_http.json index 82bb133608..f4067c80b0 100644 --- a/tests/translator/output/aws-cn/api_with_custom_domain_route53_http.json +++ b/tests/translator/output/aws-cn/api_with_custom_domain_route53_http.json @@ -84,13 +84,16 @@ "ApiGatewayDomainNameV20caaf24ab1": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": "example.com", "DomainNameConfigurations": [ { "CertificateArn": "cert-arn-in-us-east-1", "EndpointType": "EDGE" } ], - "DomainName": "example.com" + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApiProdStage": { @@ -100,7 +103,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyFunctionRole": { diff --git a/tests/translator/output/aws-cn/explicit_http_api.json b/tests/translator/output/aws-cn/explicit_http_api.json index f104793d30..3672f8b187 100644 --- a/tests/translator/output/aws-cn/explicit_http_api.json +++ b/tests/translator/output/aws-cn/explicit_http_api.json @@ -7,7 +7,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApi2ApiGatewayDefaultStage": { @@ -17,7 +20,10 @@ "Ref": "MyApi2" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -74,12 +80,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -101,6 +101,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "OAuth2": { @@ -118,7 +119,12 @@ } } }, - "openapi": "3.0.1" + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } }, @@ -183,12 +189,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -212,6 +212,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "OAuth2": { @@ -229,9 +230,14 @@ } } }, - "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-cn/explicit_http_api_minimum.json b/tests/translator/output/aws-cn/explicit_http_api_minimum.json index 01e8424af4..4a7270a868 100644 --- a/tests/translator/output/aws-cn/explicit_http_api_minimum.json +++ b/tests/translator/output/aws-cn/explicit_http_api_minimum.json @@ -138,7 +138,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "ApiApiGatewayDefaultStage": { @@ -148,7 +151,10 @@ "Ref": "Api" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } } } diff --git a/tests/translator/output/aws-cn/http_api_existing_openapi.json b/tests/translator/output/aws-cn/http_api_existing_openapi.json index c27d4b4e5a..c1df5c259a 100644 --- a/tests/translator/output/aws-cn/http_api_existing_openapi.json +++ b/tests/translator/output/aws-cn/http_api_existing_openapi.json @@ -1,10 +1,10 @@ { "Parameters": { "Timeout": { - "Default": 15000, + "Default": 15000, "Type": "Number" } - }, + }, "Resources": { "HttpApiFunctionSimpleCasePermission": { "Type": "AWS::Lambda::Permission", @@ -34,7 +34,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -51,7 +54,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -101,36 +104,17 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], - "x-amazon-apigateway-cors": { - "allowHeaders": [ - "x-apigateway-header" - ], - "allowMethods": [ - "GET" - ], - "allowOrigins": [ - "https://global.com", - "https://local.com" - ], - "maxAge": 6000 - }, "paths": { "/basic": { "post": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "timeoutInMillis": 10000, + "payloadFormatVersion": "1.0", "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DifferentFunction.Arn}/invocations" }, - "payloadFormatVersion": "1.0" + "httpMethod": "POST", + "timeoutInMillis": 10000 }, "security": [ { @@ -175,15 +159,15 @@ ], "isDefaultRoute": true, "x-amazon-apigateway-integration": { - "httpMethod": "POST", + "payloadFormatVersion": "1.0", "type": "aws_proxy", - "timeoutInMillis": { - "Ref": "Timeout" - }, "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" }, - "payloadFormatVersion": "1.0" + "httpMethod": "POST", + "timeoutInMillis": { + "Ref": "Timeout" + } }, "responses": {} } @@ -209,6 +193,26 @@ } } }, + "x-amazon-apigateway-cors": { + "allowMethods": [ + "GET" + ], + "allowHeaders": [ + "x-apigateway-header" + ], + "allowOrigins": [ + "https://global.com", + "https://local.com" + ], + "maxAge": 6000 + }, + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ], + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2Auth": { @@ -239,10 +243,9 @@ } } } - }, - "openapi": "3.0.1" + } } } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/http_api_existing_openapi_conditions.json b/tests/translator/output/aws-cn/http_api_existing_openapi_conditions.json index 2e839b97a1..1b70975cc7 100644 --- a/tests/translator/output/aws-cn/http_api_existing_openapi_conditions.json +++ b/tests/translator/output/aws-cn/http_api_existing_openapi_conditions.json @@ -37,7 +37,12 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM", + "Tag1": "value1", + "Tag2": "value2" + } } }, "HttpApiFunction": { 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..ceae81a4f0 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,34 @@ "MyApiProdStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, + "StageVariables": { + "VarName": "VarValue" + }, "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" + } + }, + "Tags": { + "httpapi:createdBy": "SAM" } } }, "HttpApiFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { - "ManagedPolicyArns": [ - "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ @@ -86,6 +97,9 @@ } ] }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], "Tags": [ { "Value": "SAM", @@ -103,12 +117,7 @@ "title": { "Ref": "AWS::StackName" } - }, - "x-amazon-apigateway-cors": { - "allowOrigins": [ - "*" - ] - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -125,6 +134,11 @@ } } }, + "x-amazon-apigateway-cors": { + "allowOrigins": [ + "*" + ] + }, "openapi": "3.0.1", "tags": [ { @@ -136,4 +150,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/http_api_with_cors.json b/tests/translator/output/aws-cn/http_api_with_cors.json index 7aa824cb52..0510e7722d 100644 --- a/tests/translator/output/aws-cn/http_api_with_cors.json +++ b/tests/translator/output/aws-cn/http_api_with_cors.json @@ -2,123 +2,129 @@ "Conditions": { "C1": { "Fn::Equals": [ - true, + true, true ] } - }, + }, "Resources": { "MyApiApiGatewayDefaultStage": { - "Type": "AWS::ApiGatewayV2::Stage", + "Type": "AWS::ApiGatewayV2::Stage", "Properties": { "ApiId": { "Ref": "MyApi" - }, - "AutoDeploy": true, - "StageName": "$default" + }, + "AutoDeploy": true, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } - }, + }, "ServerlessHttpApiApiGatewayDefaultStage": { - "Type": "AWS::ApiGatewayV2::Stage", + "Type": "AWS::ApiGatewayV2::Stage", "Properties": { "ApiId": { "Ref": "ServerlessHttpApi" - }, - "AutoDeploy": true, - "StageName": "$default" + }, + "AutoDeploy": true, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } - }, + }, "ServerlessHttpApi": { - "Type": "AWS::ApiGatewayV2::Api", + "Type": "AWS::ApiGatewayV2::Api", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" - }, + }, "payloadFormatVersion": "1.0" - }, - "isDefaultRoute": true, + }, + "isDefaultRoute": true, "responses": {} } } - }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], + }, "x-amazon-apigateway-cors": { "Fn::If": [ - "C1", + "C1", { "allowHeaders": [ "x-apigateway-header" - ], + ], "allowMethods": [ "GET" - ], + ], "allowOrigins": [ "https://foo.com" - ], + ], "exposeHeaders": [ "x-amzn-header" ] - }, + }, "AWS::NoValue" ] - }, - "openapi": "3.0.1" + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } - }, + }, "HttpApiFunction": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { "ZipFile": "exports.handler = async (event) => {\n console.log(\"Hello from MyAuthFunction\")\n return {\n statusCode: 200,\n body: JSON.stringify(event),\n headers: {}\n }\n}\n" - }, + }, "Role": { "Fn::GetAtt": [ - "HttpApiFunctionRole", + "HttpApiFunctionRole", "Arn" ] - }, - "Runtime": "nodejs12.x", + }, + "Runtime": "nodejs12.x", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "HttpApiFunctionSimpleCasePermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:InvokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { "Ref": "HttpApiFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", + "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -126,20 +132,20 @@ ] } } - }, + }, "HttpApiFunctionImplicitApiPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:InvokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { "Ref": "HttpApiFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", + "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessHttpApi" } @@ -147,18 +153,18 @@ ] } } - }, + }, "HttpApiFunctionRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -166,50 +172,44 @@ } } ] - }, + }, "ManagedPolicyArns": [ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "MyApi": { - "Type": "AWS::ApiGatewayV2::Api", + "Type": "AWS::ApiGatewayV2::Api", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" - }, + }, "payloadFormatVersion": "1.0" - }, - "isDefaultRoute": true, + }, + "isDefaultRoute": true, "responses": {} } } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "x-amazon-apigateway-cors": { "Fn::If": [ "C1", @@ -228,8 +228,15 @@ ] }, "AWS::NoValue" - ] }, - "openapi": "3.0.1" + ] + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } } diff --git a/tests/translator/output/aws-cn/implicit_http_api.json b/tests/translator/output/aws-cn/implicit_http_api.json index 72bb1a03d3..1769e0cd4e 100644 --- a/tests/translator/output/aws-cn/implicit_http_api.json +++ b/tests/translator/output/aws-cn/implicit_http_api.json @@ -7,7 +7,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunctionRole": { diff --git a/tests/translator/output/aws-cn/implicit_http_api_auth_and_simple_case.json b/tests/translator/output/aws-cn/implicit_http_api_auth_and_simple_case.json index 48f64be9c1..0680233088 100644 --- a/tests/translator/output/aws-cn/implicit_http_api_auth_and_simple_case.json +++ b/tests/translator/output/aws-cn/implicit_http_api_auth_and_simple_case.json @@ -7,7 +7,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "RestApiFunctionRole": { @@ -55,7 +58,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -95,34 +98,8 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { - "/scope3": { - "post": { - "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", - "uri": { - "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${RestApiFunction.Arn}/invocations" - }, - "payloadFormatVersion": "1.0" - }, - "security": [ - { - "OpenIdAuth": [ - "scope3" - ] - } - ], - "responses": {} - } - }, - "/someauth": { + "/defaultauth": { "post": { "x-amazon-apigateway-integration": { "httpMethod": "POST", @@ -134,9 +111,8 @@ }, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope4" ] } ], @@ -176,9 +152,8 @@ "isDefaultRoute": true, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope4" ] } ], @@ -203,7 +178,7 @@ "responses": {} } }, - "/defaultauth": { + "/scope3": { "post": { "x-amazon-apigateway-integration": { "httpMethod": "POST", @@ -215,9 +190,8 @@ }, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope3" ] } ], @@ -225,6 +199,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2Auth": { @@ -239,26 +214,17 @@ "issuer": "https://www.example.com/v1/connect/oidc" } } - }, - "OpenIdAuth": { - "type": "openIdConnect", - "x-amazon-apigateway-authorizer": { - "identitySource": "$request.querystring.param", - "type": "jwt", - "jwtConfiguration": { - "audience": [ - "MyApi" - ], - "issuer": "https://www.example.com/v1/connect/oidc" - }, - "openIdConnectUrl": "https://www.example.com/v1/connect" - } } } }, - "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-cn/implicit_http_api_with_many_conditions.json b/tests/translator/output/aws-cn/implicit_http_api_with_many_conditions.json index 519cb8083a..3469cc26fd 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,11 +1336,38 @@ "ServerlessHttpApiApiGatewayDefaultStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "ServerlessHttpApi" }, - "AutoDeploy": true, - "StageName": "$default" + "RouteSettings": { + "GET /sub": { + "Fn::If": [ + "MyCondition", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "$default": { + "Fn::If": [ + "Cond", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + } + }, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "ServerlessHttpApiCondition" }, @@ -1476,4 +1503,4 @@ "Condition": "Cond3" } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/all_policy_templates.json b/tests/translator/output/aws-us-gov/all_policy_templates.json index 77a7d97d22..9f9ac33a79 100644 --- a/tests/translator/output/aws-us-gov/all_policy_templates.json +++ b/tests/translator/output/aws-us-gov/all_policy_templates.json @@ -1487,7 +1487,73 @@ } }, { - "PolicyName": "KitchenSinkFunctionRolePolicy55", + "PolicyName": "KitchenSinkFunctionRolePolicy55", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:PutObjectAcl", + "s3:PutLifecycleConfiguration" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}", + { + "bucketName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:s3:::${bucketName}/*", + { + "bucketName": "name" + } + ] + } + ] + } + ] + } + }, + { + "PolicyName": "KitchenSinkFunctionRolePolicy56", + "PolicyDocument": { + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "dynamodb:PutItem", + "dynamodb:UpdateItem", + "dynamodb:BatchWriteItem" + ], + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}", + { + "tableName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tableName}/index/*", + { + "tableName": "name" + } + ] + } + ] + } + ] + } + }, + { + "PolicyName": "KitchenSinkFunctionRolePolicy57", "PolicyDocument": { "Statement": [ { diff --git a/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_http.json b/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_http.json index 589b610a23..691caa2faa 100644 --- a/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_http.json +++ b/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_http.json @@ -32,7 +32,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -158,7 +161,10 @@ "EndpointType": "REGIONAL" } ], - "DomainName": "sam-v2-regional-test.com" + "DomainName": "sam-v2-regional-test.com", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApi": { diff --git a/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics_http.json b/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics_http.json index f786841828..1086f4a048 100644 --- a/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics_http.json +++ b/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics_http.json @@ -48,7 +48,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "C1" }, @@ -168,14 +171,17 @@ "ApiGatewayDomainNameV29c93aac102": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": { + "Fn::Sub": "example-us-gov-west-1.com" + }, "DomainNameConfigurations": [ { "CertificateArn": "another-api-arn", "EndpointType": "REGIONAL" } ], - "DomainName": { - "Fn::Sub": "example-us-gov-west-1.com" + "Tags": { + "httpapi:createdBy": "SAM" } }, "Condition": "C1" @@ -225,7 +231,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "C1" }, diff --git a/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_hosted_zone_name_http.json b/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_hosted_zone_name_http.json index 821e6bc248..d46cce973a 100644 --- a/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_hosted_zone_name_http.json +++ b/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_hosted_zone_name_http.json @@ -39,7 +39,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApioneApiMapping": { @@ -60,13 +63,16 @@ "ApiGatewayDomainNameV20caaf24ab1": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": "example.com", "DomainNameConfigurations": [ { "CertificateArn": "cert-arn-in-us-east-1", "EndpointType": "EDGE" } ], - "DomainName": "example.com" + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "RecordSetGroup456ebaf280": { @@ -177,4 +183,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_http.json b/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_http.json index 956e7ac727..15b6346051 100644 --- a/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_http.json +++ b/tests/translator/output/aws-us-gov/api_with_custom_domain_route53_http.json @@ -84,13 +84,16 @@ "ApiGatewayDomainNameV20caaf24ab1": { "Type": "AWS::ApiGatewayV2::DomainName", "Properties": { + "DomainName": "example.com", "DomainNameConfigurations": [ { "CertificateArn": "cert-arn-in-us-east-1", "EndpointType": "EDGE" } ], - "DomainName": "example.com" + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApiProdStage": { @@ -100,7 +103,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod" + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyFunctionRole": { diff --git a/tests/translator/output/aws-us-gov/explicit_http_api.json b/tests/translator/output/aws-us-gov/explicit_http_api.json index 50cb6158ad..0c97ee2c84 100644 --- a/tests/translator/output/aws-us-gov/explicit_http_api.json +++ b/tests/translator/output/aws-us-gov/explicit_http_api.json @@ -7,7 +7,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApi2ApiGatewayDefaultStage": { @@ -17,7 +20,10 @@ "Ref": "MyApi2" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -74,12 +80,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -101,6 +101,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "OAuth2": { @@ -118,7 +119,12 @@ } } }, - "openapi": "3.0.1" + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } }, @@ -183,12 +189,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -212,6 +212,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "OAuth2": { @@ -229,9 +230,14 @@ } } }, - "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/explicit_http_api_minimum.json b/tests/translator/output/aws-us-gov/explicit_http_api_minimum.json index 0a35ee12b5..205c7c1555 100644 --- a/tests/translator/output/aws-us-gov/explicit_http_api_minimum.json +++ b/tests/translator/output/aws-us-gov/explicit_http_api_minimum.json @@ -138,7 +138,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "ApiApiGatewayDefaultStage": { @@ -148,7 +151,10 @@ "Ref": "Api" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } } } diff --git a/tests/translator/output/aws-us-gov/http_api_existing_openapi.json b/tests/translator/output/aws-us-gov/http_api_existing_openapi.json index 1044072e8f..01da21adf8 100644 --- a/tests/translator/output/aws-us-gov/http_api_existing_openapi.json +++ b/tests/translator/output/aws-us-gov/http_api_existing_openapi.json @@ -1,10 +1,10 @@ { "Parameters": { "Timeout": { - "Default": 15000, + "Default": 15000, "Type": "Number" } - }, + }, "Resources": { "HttpApiFunctionSimpleCasePermission": { "Type": "AWS::Lambda::Permission", @@ -34,7 +34,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -51,7 +54,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -101,36 +104,17 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], - "x-amazon-apigateway-cors": { - "allowHeaders": [ - "x-apigateway-header" - ], - "allowMethods": [ - "GET" - ], - "allowOrigins": [ - "https://global.com", - "https://local.com" - ], - "maxAge": 6000 - }, "paths": { "/basic": { "post": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "timeoutInMillis": 10000, + "payloadFormatVersion": "1.0", "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DifferentFunction.Arn}/invocations" }, - "payloadFormatVersion": "1.0" + "httpMethod": "POST", + "timeoutInMillis": 10000 }, "security": [ { @@ -175,15 +159,15 @@ ], "isDefaultRoute": true, "x-amazon-apigateway-integration": { - "httpMethod": "POST", + "payloadFormatVersion": "1.0", "type": "aws_proxy", - "timeoutInMillis": { - "Ref": "Timeout" - }, "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" }, - "payloadFormatVersion": "1.0" + "httpMethod": "POST", + "timeoutInMillis": { + "Ref": "Timeout" + } }, "responses": {} } @@ -209,6 +193,26 @@ } } }, + "x-amazon-apigateway-cors": { + "allowMethods": [ + "GET" + ], + "allowHeaders": [ + "x-apigateway-header" + ], + "allowOrigins": [ + "https://global.com", + "https://local.com" + ], + "maxAge": 6000 + }, + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ], + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2Auth": { @@ -239,10 +243,9 @@ } } } - }, - "openapi": "3.0.1" + } } } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/http_api_existing_openapi_conditions.json b/tests/translator/output/aws-us-gov/http_api_existing_openapi_conditions.json index 07e7c51583..e5eb69fb2e 100644 --- a/tests/translator/output/aws-us-gov/http_api_existing_openapi_conditions.json +++ b/tests/translator/output/aws-us-gov/http_api_existing_openapi_conditions.json @@ -37,7 +37,12 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM", + "Tag1": "value1", + "Tag2": "value2" + } } }, "HttpApiFunction": { 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..509c33ea6a 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,34 @@ "MyApiProdStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "StageVariables": { + "VarName": "VarValue" + }, + "AccessLogSettings": { + "DestinationArn": "arn:aws:logs:us-east-1:123456789012:log-group:LogGroupName", + "Format": "$context.requestId" + }, + "StageName": "Prod", + "Tags": { + "httpapi:createdBy": "SAM" + }, "ApiId": { "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "Prod", - "AccessLogSettings": { - "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 +97,9 @@ } ] }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], "Tags": [ { "Value": "SAM", @@ -105,17 +118,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 +134,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/http_api_with_cors.json b/tests/translator/output/aws-us-gov/http_api_with_cors.json index e9f3561604..fe60926e7b 100644 --- a/tests/translator/output/aws-us-gov/http_api_with_cors.json +++ b/tests/translator/output/aws-us-gov/http_api_with_cors.json @@ -2,123 +2,129 @@ "Conditions": { "C1": { "Fn::Equals": [ - true, + true, true ] } - }, + }, "Resources": { "MyApiApiGatewayDefaultStage": { - "Type": "AWS::ApiGatewayV2::Stage", + "Type": "AWS::ApiGatewayV2::Stage", "Properties": { "ApiId": { "Ref": "MyApi" - }, - "AutoDeploy": true, - "StageName": "$default" + }, + "AutoDeploy": true, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } - }, + }, "ServerlessHttpApiApiGatewayDefaultStage": { - "Type": "AWS::ApiGatewayV2::Stage", + "Type": "AWS::ApiGatewayV2::Stage", "Properties": { "ApiId": { "Ref": "ServerlessHttpApi" - }, - "AutoDeploy": true, - "StageName": "$default" + }, + "AutoDeploy": true, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } - }, + }, "ServerlessHttpApi": { - "Type": "AWS::ApiGatewayV2::Api", + "Type": "AWS::ApiGatewayV2::Api", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" - }, + }, "payloadFormatVersion": "1.0" - }, - "isDefaultRoute": true, + }, + "isDefaultRoute": true, "responses": {} } } - }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], + }, "x-amazon-apigateway-cors": { "Fn::If": [ - "C1", + "C1", { "allowHeaders": [ "x-apigateway-header" - ], + ], "allowMethods": [ "GET" - ], + ], "allowOrigins": [ "https://foo.com" - ], + ], "exposeHeaders": [ "x-amzn-header" ] - }, + }, "AWS::NoValue" ] - }, - "openapi": "3.0.1" + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } - }, + }, "HttpApiFunction": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { "ZipFile": "exports.handler = async (event) => {\n console.log(\"Hello from MyAuthFunction\")\n return {\n statusCode: 200,\n body: JSON.stringify(event),\n headers: {}\n }\n}\n" - }, + }, "Role": { "Fn::GetAtt": [ - "HttpApiFunctionRole", + "HttpApiFunctionRole", "Arn" ] - }, - "Runtime": "nodejs12.x", + }, + "Runtime": "nodejs12.x", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "HttpApiFunctionSimpleCasePermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:InvokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { "Ref": "HttpApiFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", + "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -126,20 +132,20 @@ ] } } - }, + }, "HttpApiFunctionImplicitApiPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:InvokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { "Ref": "HttpApiFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", + "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessHttpApi" } @@ -147,18 +153,18 @@ ] } } - }, + }, "HttpApiFunctionRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -166,71 +172,71 @@ } } ] - }, + }, "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "MyApi": { - "Type": "AWS::ApiGatewayV2::Api", + "Type": "AWS::ApiGatewayV2::Api", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" - }, + }, "payloadFormatVersion": "1.0" - }, - "isDefaultRoute": true, + }, + "isDefaultRoute": true, "responses": {} } } - }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], + }, "x-amazon-apigateway-cors": { "Fn::If": [ - "C1", + "C1", { "allowHeaders": [ "x-apigateway-header" - ], + ], "allowMethods": [ "GET" - ], + ], "allowOrigins": [ "https://foo.com" - ], + ], "exposeHeaders": [ "x-amzn-header" ] - }, + }, "AWS::NoValue" ] - }, - "openapi": "3.0.1" + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } } diff --git a/tests/translator/output/aws-us-gov/implicit_http_api.json b/tests/translator/output/aws-us-gov/implicit_http_api.json index aaee74da6e..46660faf30 100644 --- a/tests/translator/output/aws-us-gov/implicit_http_api.json +++ b/tests/translator/output/aws-us-gov/implicit_http_api.json @@ -7,7 +7,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunctionRole": { diff --git a/tests/translator/output/aws-us-gov/implicit_http_api_auth_and_simple_case.json b/tests/translator/output/aws-us-gov/implicit_http_api_auth_and_simple_case.json index 4e4d6387f8..a3bf1e3951 100644 --- a/tests/translator/output/aws-us-gov/implicit_http_api_auth_and_simple_case.json +++ b/tests/translator/output/aws-us-gov/implicit_http_api_auth_and_simple_case.json @@ -7,7 +7,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "RestApiFunctionRole": { @@ -55,7 +58,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -95,34 +98,8 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { - "/scope3": { - "post": { - "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", - "uri": { - "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${RestApiFunction.Arn}/invocations" - }, - "payloadFormatVersion": "1.0" - }, - "security": [ - { - "OpenIdAuth": [ - "scope3" - ] - } - ], - "responses": {} - } - }, - "/someauth": { + "/defaultauth": { "post": { "x-amazon-apigateway-integration": { "httpMethod": "POST", @@ -134,9 +111,8 @@ }, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope4" ] } ], @@ -176,9 +152,8 @@ "isDefaultRoute": true, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope4" ] } ], @@ -203,7 +178,7 @@ "responses": {} } }, - "/defaultauth": { + "/scope3": { "post": { "x-amazon-apigateway-integration": { "httpMethod": "POST", @@ -215,9 +190,8 @@ }, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope3" ] } ], @@ -225,6 +199,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2Auth": { @@ -239,26 +214,17 @@ "issuer": "https://www.example.com/v1/connect/oidc" } } - }, - "OpenIdAuth": { - "type": "openIdConnect", - "x-amazon-apigateway-authorizer": { - "identitySource": "$request.querystring.param", - "type": "jwt", - "jwtConfiguration": { - "audience": [ - "MyApi" - ], - "issuer": "https://www.example.com/v1/connect/oidc" - }, - "openIdConnectUrl": "https://www.example.com/v1/connect" - } } } }, - "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..10fbf280fb 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,11 +1336,38 @@ "ServerlessHttpApiApiGatewayDefaultStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "ServerlessHttpApi" }, - "AutoDeploy": true, - "StageName": "$default" + "RouteSettings": { + "GET /sub": { + "Fn::If": [ + "MyCondition", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "$default": { + "Fn::If": [ + "Cond", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + } + }, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "ServerlessHttpApiCondition" }, @@ -1476,4 +1503,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/error_http_api_invalid_auth.json b/tests/translator/output/error_http_api_invalid_auth.json index ade985d7c1..e5bdcb426d 100644 --- a/tests/translator/output/error_http_api_invalid_auth.json +++ b/tests/translator/output/error_http_api_invalid_auth.json @@ -4,5 +4,5 @@ "errorMessage": "Resource with id [Function] is invalid. Event with id [Api] is invalid. Unable to set Authorizer [myAuth] on API method [x-amazon-apigateway-any-method] for path [$default] because the related API does not define any Authorizers. Resource with id [Function2] is invalid. Event with id [Api2] is invalid. Unable to set Authorizer [myAuth] on API method [x-amazon-apigateway-any-method] for path [$default] because it wasn't defined in the API's Authorizers. Resource with id [Function3] is invalid. Event with id [Api3] is invalid. Unable to set Authorizer on API method [x-amazon-apigateway-any-method] for path [$default] because 'NONE' is only a valid value when a DefaultAuthorizer on the API is specified. Resource with id [Function4] is invalid. Event with id [Api4] is invalid. Unable to set Authorizer on API method [x-amazon-apigateway-any-method] for path [$default] because 'AuthorizationScopes' must be a list of strings." } ], - "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 4. Resource with id [Function] is invalid. Event with id [Api] is invalid. Unable to set Authorizer [myAuth] on API method [x-amazon-apigateway-any-method] for path [$default] because the related API does not define any Authorizers. Resource with id [Function2] is invalid. Event with id [Api2] is invalid. Unable to set Authorizer [myAuth] on API method [x-amazon-apigateway-any-method] for path [$default] because it wasn't defined in the API's Authorizers. Resource with id [Function3] is invalid. Event with id [Api3] is invalid. Unable to set Authorizer on API method [x-amazon-apigateway-any-method] for path [$default] because 'NONE' is only a valid value when a DefaultAuthorizer on the API is specified. Resource with id [Function4] is invalid. Event with id [Api4] is invalid. Unable to set Authorizer on API method [x-amazon-apigateway-any-method] for path [$default] because 'AuthorizationScopes' must be a list of strings." + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 5. Resource with id [Function] is invalid. Event with id [Api] is invalid. Unable to set Authorizer [myAuth] on API method [x-amazon-apigateway-any-method] for path [$default] because the related API does not define any Authorizers. Resource with id [Function2] is invalid. Event with id [Api2] is invalid. Unable to set Authorizer [myAuth] on API method [x-amazon-apigateway-any-method] for path [$default] because it wasn't defined in the API's Authorizers. Resource with id [Function3] is invalid. Event with id [Api3] is invalid. Unable to set Authorizer on API method [x-amazon-apigateway-any-method] for path [$default] because 'NONE' is only a valid value when a DefaultAuthorizer on the API is specified. Resource with id [Function4] is invalid. Event with id [Api4] is invalid. Unable to set Authorizer on API method [x-amazon-apigateway-any-method] for path [$default] because 'AuthorizationScopes' must be a list of strings. Resource with id [MyApi5] is invalid. 'OpenIdConnectUrl' is no longer a supported property for authorizer 'OIDC'. Please refer to the AWS SAM documentation." } \ No newline at end of file diff --git a/tests/translator/output/explicit_http_api.json b/tests/translator/output/explicit_http_api.json index 8fc5d920d1..070bd89351 100644 --- a/tests/translator/output/explicit_http_api.json +++ b/tests/translator/output/explicit_http_api.json @@ -7,7 +7,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "MyApi2ApiGatewayDefaultStage": { @@ -17,7 +20,10 @@ "Ref": "MyApi2" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -74,12 +80,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -101,6 +101,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "OAuth2": { @@ -118,7 +119,12 @@ } } }, - "openapi": "3.0.1" + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } }, @@ -183,12 +189,6 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { "$default": { "x-amazon-apigateway-any-method": { @@ -212,6 +212,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "OAuth2": { @@ -229,9 +230,14 @@ } } }, - "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/explicit_http_api_minimum.json b/tests/translator/output/explicit_http_api_minimum.json index 6695f3404e..bb8fa7b6f3 100644 --- a/tests/translator/output/explicit_http_api_minimum.json +++ b/tests/translator/output/explicit_http_api_minimum.json @@ -138,7 +138,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "ApiApiGatewayDefaultStage": { @@ -148,7 +151,10 @@ "Ref": "Api" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } } } diff --git a/tests/translator/output/http_api_def_uri.json b/tests/translator/output/http_api_def_uri.json index e6a1041ffa..fd5dedd146 100644 --- a/tests/translator/output/http_api_def_uri.json +++ b/tests/translator/output/http_api_def_uri.json @@ -45,14 +45,14 @@ "MyApiStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "MyApi" }, - "AutoDeploy": true, "DefaultRouteSettings": { - "ThrottlingBurstLimit": 50, + "ThrottlingBurstLimit": 50, "ThrottlingRateLimit": 100.0 - }, + }, "StageName": { "Fn::Join": [ "", @@ -67,9 +67,6 @@ "FunctionRole": { "Type": "AWS::IAM::Role", "Properties": { - "ManagedPolicyArns": [ - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ @@ -86,6 +83,9 @@ } ] }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], "Tags": [ { "Value": "SAM", @@ -97,13 +97,13 @@ "MyApi2ApiGatewayDefaultStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "MyApi2" }, - "AutoDeploy": true, "DefaultRouteSettings": { - "ThrottlingRateLimit": 100 - }, + "ThrottlingRateLimit": 100.0 + }, "StageName": "$default" } }, @@ -148,4 +148,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/http_api_existing_openapi.json b/tests/translator/output/http_api_existing_openapi.json index 2e3c2446f1..8edcb35ab2 100644 --- a/tests/translator/output/http_api_existing_openapi.json +++ b/tests/translator/output/http_api_existing_openapi.json @@ -1,10 +1,10 @@ { "Parameters": { "Timeout": { - "Default": 15000, + "Default": 15000, "Type": "Number" } - }, + }, "Resources": { "HttpApiFunctionSimpleCasePermission": { "Type": "AWS::Lambda::Permission", @@ -34,7 +34,10 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunction": { @@ -51,7 +54,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -101,36 +104,17 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], - "x-amazon-apigateway-cors": { - "allowHeaders": [ - "x-apigateway-header" - ], - "allowMethods": [ - "GET" - ], - "allowOrigins": [ - "https://global.com", - "https://local.com" - ], - "maxAge": 6000 - }, "paths": { "/basic": { "post": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "timeoutInMillis": 10000, + "payloadFormatVersion": "1.0", "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DifferentFunction.Arn}/invocations" }, - "payloadFormatVersion": "1.0" + "httpMethod": "POST", + "timeoutInMillis": 10000 }, "security": [ { @@ -173,17 +157,17 @@ ] } ], - "isDefaultRoute": true, + "isDefaultRoute": true, "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "timeoutInMillis": { - "Ref": "Timeout" - }, + "payloadFormatVersion": "1.0", "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" }, - "payloadFormatVersion": "1.0" + "httpMethod": "POST", + "timeoutInMillis": { + "Ref": "Timeout" + } }, "responses": {} } @@ -209,6 +193,26 @@ } } }, + "x-amazon-apigateway-cors": { + "allowMethods": [ + "GET" + ], + "allowHeaders": [ + "x-apigateway-header" + ], + "allowOrigins": [ + "https://global.com", + "https://local.com" + ], + "maxAge": 6000 + }, + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ], + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2Auth": { @@ -239,10 +243,9 @@ } } } - }, - "openapi": "3.0.1" + } } } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/http_api_existing_openapi_conditions.json b/tests/translator/output/http_api_existing_openapi_conditions.json index 9dd6bcace4..5a4df14edf 100644 --- a/tests/translator/output/http_api_existing_openapi_conditions.json +++ b/tests/translator/output/http_api_existing_openapi_conditions.json @@ -37,7 +37,12 @@ "Ref": "MyApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM", + "Tag1": "value1", + "Tag2": "value2" + } } }, "HttpApiFunction": { diff --git a/tests/translator/output/http_api_explicit_stage.json b/tests/translator/output/http_api_explicit_stage.json index f6795577a9..715ea85898 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,34 @@ "MyApiProdStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, + "StageVariables": { + "VarName": "VarValue" + }, "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" + } + }, + "Tags": { + "httpapi:createdBy": "SAM" } } }, "HttpApiFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { - "ManagedPolicyArns": [ - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ @@ -86,6 +97,9 @@ } ] }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], "Tags": [ { "Value": "SAM", @@ -104,17 +118,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 +134,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/http_api_with_cors.json b/tests/translator/output/http_api_with_cors.json index f80c8dafc4..b9e7aa9c26 100644 --- a/tests/translator/output/http_api_with_cors.json +++ b/tests/translator/output/http_api_with_cors.json @@ -2,123 +2,129 @@ "Conditions": { "C1": { "Fn::Equals": [ - true, + true, true ] } - }, + }, "Resources": { "MyApiApiGatewayDefaultStage": { - "Type": "AWS::ApiGatewayV2::Stage", + "Type": "AWS::ApiGatewayV2::Stage", "Properties": { "ApiId": { "Ref": "MyApi" - }, - "AutoDeploy": true, - "StageName": "$default" + }, + "AutoDeploy": true, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } - }, + }, "ServerlessHttpApiApiGatewayDefaultStage": { - "Type": "AWS::ApiGatewayV2::Stage", + "Type": "AWS::ApiGatewayV2::Stage", "Properties": { "ApiId": { "Ref": "ServerlessHttpApi" - }, - "AutoDeploy": true, - "StageName": "$default" + }, + "AutoDeploy": true, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } - }, + }, "ServerlessHttpApi": { - "Type": "AWS::ApiGatewayV2::Api", + "Type": "AWS::ApiGatewayV2::Api", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" - }, + }, "payloadFormatVersion": "1.0" - }, - "isDefaultRoute": true, + }, + "isDefaultRoute": true, "responses": {} } } - }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], + }, "x-amazon-apigateway-cors": { "Fn::If": [ - "C1", + "C1", { "allowHeaders": [ "x-apigateway-header" - ], + ], "allowMethods": [ "GET" - ], + ], "allowOrigins": [ "https://foo.com" - ], + ], "exposeHeaders": [ "x-amzn-header" ] - }, + }, "AWS::NoValue" ] - }, - "openapi": "3.0.1" + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } - }, + }, "HttpApiFunction": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { "ZipFile": "exports.handler = async (event) => {\n console.log(\"Hello from MyAuthFunction\")\n return {\n statusCode: 200,\n body: JSON.stringify(event),\n headers: {}\n }\n}\n" - }, + }, "Role": { "Fn::GetAtt": [ - "HttpApiFunctionRole", + "HttpApiFunctionRole", "Arn" ] - }, - "Runtime": "nodejs12.x", + }, + "Runtime": "nodejs12.x", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "HttpApiFunctionSimpleCasePermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:InvokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { "Ref": "HttpApiFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", + "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -126,20 +132,20 @@ ] } } - }, + }, "HttpApiFunctionImplicitApiPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:InvokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { "Ref": "HttpApiFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", + "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/*", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessHttpApi" } @@ -147,18 +153,18 @@ ] } } - }, + }, "HttpApiFunctionRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -166,70 +172,71 @@ } } ] - }, + }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "MyApi": { - "Type": "AWS::ApiGatewayV2::Api", + "Type": "AWS::ApiGatewayV2::Api", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "$default": { "x-amazon-apigateway-any-method": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HttpApiFunction.Arn}/invocations" - }, + }, "payloadFormatVersion": "1.0" - }, - "isDefaultRoute": true, + }, + "isDefaultRoute": true, "responses": {} } } - }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], + }, "x-amazon-apigateway-cors": { "Fn::If": [ - "C1", + "C1", { "allowHeaders": [ "x-apigateway-header" - ], + ], "allowMethods": [ "GET" - ], + ], "allowOrigins": [ "https://foo.com" - ], + ], "exposeHeaders": [ "x-amzn-header" ] - }, + }, "AWS::NoValue" - ] }, - "openapi": "3.0.1" + ] + }, + "openapi": "3.0.1", + "tags": [ + { + "name": "httpapi:createdBy", + "x-amazon-apigateway-tag-value": "SAM" + } + ] } } } diff --git a/tests/translator/output/implicit_http_api.json b/tests/translator/output/implicit_http_api.json index 6218d21173..31bab67999 100644 --- a/tests/translator/output/implicit_http_api.json +++ b/tests/translator/output/implicit_http_api.json @@ -7,7 +7,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "HttpApiFunctionRole": { diff --git a/tests/translator/output/implicit_http_api_auth_and_simple_case.json b/tests/translator/output/implicit_http_api_auth_and_simple_case.json index efcd8d3bbd..1e55d720bc 100644 --- a/tests/translator/output/implicit_http_api_auth_and_simple_case.json +++ b/tests/translator/output/implicit_http_api_auth_and_simple_case.json @@ -7,7 +7,10 @@ "Ref": "ServerlessHttpApi" }, "AutoDeploy": true, - "StageName": "$default" + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } } }, "RestApiFunctionRole": { @@ -55,7 +58,7 @@ "Arn" ] }, - "Runtime": "nodejs12.x", + "Runtime": "nodejs12.x", "Tags": [ { "Value": "SAM", @@ -95,34 +98,8 @@ "Ref": "AWS::StackName" } }, - "tags": [ - { - "name": "httpapi:createdBy", - "x-amazon-apigateway-tag-value": "SAM" - } - ], "paths": { - "/scope3": { - "post": { - "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", - "uri": { - "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${RestApiFunction.Arn}/invocations" - }, - "payloadFormatVersion": "1.0" - }, - "security": [ - { - "OpenIdAuth": [ - "scope3" - ] - } - ], - "responses": {} - } - }, - "/someauth": { + "/defaultauth": { "post": { "x-amazon-apigateway-integration": { "httpMethod": "POST", @@ -134,9 +111,8 @@ }, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope4" ] } ], @@ -176,9 +152,8 @@ "isDefaultRoute": true, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope4" ] } ], @@ -203,7 +178,7 @@ "responses": {} } }, - "/defaultauth": { + "/scope3": { "post": { "x-amazon-apigateway-integration": { "httpMethod": "POST", @@ -215,9 +190,8 @@ }, "security": [ { - "OpenIdAuth": [ - "scope1", - "scope2" + "oauth2Auth": [ + "scope3" ] } ], @@ -225,6 +199,7 @@ } } }, + "openapi": "3.0.1", "components": { "securitySchemes": { "oauth2Auth": { @@ -239,26 +214,17 @@ "issuer": "https://www.example.com/v1/connect/oidc" } } - }, - "OpenIdAuth": { - "type": "openIdConnect", - "x-amazon-apigateway-authorizer": { - "identitySource": "$request.querystring.param", - "type": "jwt", - "jwtConfiguration": { - "audience": [ - "MyApi" - ], - "issuer": "https://www.example.com/v1/connect/oidc" - }, - "openIdConnectUrl": "https://www.example.com/v1/connect" - } } } }, - "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..1d7a3e9c21 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,11 +1336,38 @@ "ServerlessHttpApiApiGatewayDefaultStage": { "Type": "AWS::ApiGatewayV2::Stage", "Properties": { + "AutoDeploy": true, "ApiId": { "Ref": "ServerlessHttpApi" }, - "AutoDeploy": true, - "StageName": "$default" + "RouteSettings": { + "GET /sub": { + "Fn::If": [ + "MyCondition", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + }, + "$default": { + "Fn::If": [ + "Cond", + { + "ThrottlingBurstLimit": 200 + }, + { + "Ref": "AWS::NoValue" + } + ] + } + }, + "StageName": "$default", + "Tags": { + "httpapi:createdBy": "SAM" + } }, "Condition": "ServerlessHttpApiCondition" }, @@ -1476,4 +1503,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..afb71dd658 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -283,7 +283,9 @@ 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` +StageVariables | Map of `string` to `string` | A map that defines the stage variables for a Stage. Variable names can have alphanumeric and underscore characters, and the values must match [A-Za-z0-9-._~:/?#&=,]+. ##### Return values