From 60043088b4f99d174c4c96c02bbbf43f76d005b3 Mon Sep 17 00:00:00 2001 From: gomi_ningen Date: Wed, 3 Jul 2019 02:20:19 +0900 Subject: [PATCH 01/31] fix: remove unused CollectionId parameter of RekognitionFacesPolicy (#985) --- .../policy_templates_data/policy_templates.json | 15 ++------------- tests/translator/input/all_policy_templates.yaml | 3 +-- tests/translator/output/all_policy_templates.json | 9 +-------- .../output/aws-cn/all_policy_templates.json | 9 +-------- .../output/aws-us-gov/all_policy_templates.json | 9 +-------- 5 files changed, 6 insertions(+), 39 deletions(-) diff --git a/samtranslator/policy_templates_data/policy_templates.json b/samtranslator/policy_templates_data/policy_templates.json index f15dc1308d..1e424c6591 100644 --- a/samtranslator/policy_templates_data/policy_templates.json +++ b/samtranslator/policy_templates_data/policy_templates.json @@ -1051,9 +1051,7 @@ "RekognitionFacesPolicy": { "Description": "Gives permission to compare and detect faces and labels", "Parameters": { - "CollectionId": { - "Description": "ID of the collection" - } + }, "Definition": { "Statement": [ @@ -1063,16 +1061,7 @@ "rekognition:CompareFaces", "rekognition:DetectFaces" ], - "Resource": { - "Fn::Sub": [ - "arn:${AWS::Partition}:rekognition:${AWS::Region}:${AWS::AccountId}:collection/${collectionId}", - { - "collectionId": { - "Ref": "CollectionId" - } - } - ] - } + "Resource": "*" } ] } diff --git a/tests/translator/input/all_policy_templates.yaml b/tests/translator/input/all_policy_templates.yaml index 2cca6996f8..b6d97bd814 100644 --- a/tests/translator/input/all_policy_templates.yaml +++ b/tests/translator/input/all_policy_templates.yaml @@ -98,8 +98,7 @@ Resources: - CloudWatchDashboardPolicy: {} - - RekognitionFacesPolicy: - CollectionId: collection + - RekognitionFacesPolicy: {} - RekognitionLabelsPolicy: {} diff --git a/tests/translator/output/all_policy_templates.json b/tests/translator/output/all_policy_templates.json index 4488918b0f..520267a5d2 100644 --- a/tests/translator/output/all_policy_templates.json +++ b/tests/translator/output/all_policy_templates.json @@ -809,14 +809,7 @@ "rekognition:CompareFaces", "rekognition:DetectFaces" ], - "Resource": { - "Fn::Sub": [ - "arn:${AWS::Partition}:rekognition:${AWS::Region}:${AWS::AccountId}:collection/${collectionId}", - { - "collectionId": "collection" - } - ] - }, + "Resource": "*", "Effect": "Allow" } ] diff --git a/tests/translator/output/aws-cn/all_policy_templates.json b/tests/translator/output/aws-cn/all_policy_templates.json index 0bf9d32254..3216366b8a 100644 --- a/tests/translator/output/aws-cn/all_policy_templates.json +++ b/tests/translator/output/aws-cn/all_policy_templates.json @@ -808,14 +808,7 @@ "rekognition:CompareFaces", "rekognition:DetectFaces" ], - "Resource": { - "Fn::Sub": [ - "arn:${AWS::Partition}:rekognition:${AWS::Region}:${AWS::AccountId}:collection/${collectionId}", - { - "collectionId": "collection" - } - ] - }, + "Resource": "*", "Effect": "Allow" } ] 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 9e8386268d..661c731218 100644 --- a/tests/translator/output/aws-us-gov/all_policy_templates.json +++ b/tests/translator/output/aws-us-gov/all_policy_templates.json @@ -808,14 +808,7 @@ "rekognition:CompareFaces", "rekognition:DetectFaces" ], - "Resource": { - "Fn::Sub": [ - "arn:${AWS::Partition}:rekognition:${AWS::Region}:${AWS::AccountId}:collection/${collectionId}", - { - "collectionId": "collection" - } - ] - }, + "Resource": "*", "Effect": "Allow" } ] From 73610020489e819bf9253883b2a72baf4581814a Mon Sep 17 00:00:00 2001 From: gomi_ningen Date: Wed, 3 Jul 2019 02:50:26 +0900 Subject: [PATCH 02/31] feat: Add support to specify a SNS topic that belongs to a different region (#989) --- samtranslator/model/eventsources/push.py | 7 +++++-- samtranslator/model/sns.py | 1 + samtranslator/validator/sam_schema/schema.json | 3 +++ tests/model/eventsources/test_sns_event_source.py | 13 +++++++++++++ ...nction_with_sns_event_source_all_parameters.yaml | 1 + ...nction_with_sns_event_source_all_parameters.json | 3 ++- ...nction_with_sns_event_source_all_parameters.json | 3 ++- ...nction_with_sns_event_source_all_parameters.json | 3 ++- versions/2016-10-31.md | 1 + 9 files changed, 30 insertions(+), 5 deletions(-) diff --git a/samtranslator/model/eventsources/push.py b/samtranslator/model/eventsources/push.py index 14217806fb..6b759ab5f9 100644 --- a/samtranslator/model/eventsources/push.py +++ b/samtranslator/model/eventsources/push.py @@ -344,6 +344,7 @@ class SNS(PushEventSource): principal = 'sns.amazonaws.com' property_types = { 'Topic': PropertyType(True, is_str()), + 'Region': PropertyType(False, is_str()), 'FilterPolicy': PropertyType(False, dict_of(is_str(), list_of(one_of(is_str(), is_type(dict))))) } @@ -360,13 +361,15 @@ def to_cloudformation(self, **kwargs): raise TypeError("Missing required keyword argument: function") return [self._construct_permission(function, source_arn=self.Topic), - self._inject_subscription(function, self.Topic, self.FilterPolicy)] + self._inject_subscription(function, self.Topic, self.Region, self.FilterPolicy)] - def _inject_subscription(self, function, topic, filterPolicy): + def _inject_subscription(self, function, topic, region, filterPolicy): subscription = SNSSubscription(self.logical_id) subscription.Protocol = 'lambda' subscription.Endpoint = function.get_runtime_attr("arn") subscription.TopicArn = topic + if region is not None: + subscription.Region = region if CONDITION in function.resource_attributes: subscription.set_resource_attribute(CONDITION, function.resource_attributes[CONDITION]) diff --git a/samtranslator/model/sns.py b/samtranslator/model/sns.py index 7bfb1b94a6..4b4290b946 100644 --- a/samtranslator/model/sns.py +++ b/samtranslator/model/sns.py @@ -8,5 +8,6 @@ class SNSSubscription(Resource): 'Endpoint': PropertyType(True, is_str()), 'Protocol': PropertyType(True, is_str()), 'TopicArn': PropertyType(True, is_str()), + 'Region': PropertyType(False, is_str()), 'FilterPolicy': PropertyType(False, is_type(dict)) } diff --git a/samtranslator/validator/sam_schema/schema.json b/samtranslator/validator/sam_schema/schema.json index 8fa499b9e2..98046249f4 100644 --- a/samtranslator/validator/sam_schema/schema.json +++ b/samtranslator/validator/sam_schema/schema.json @@ -632,6 +632,9 @@ "Topic": { "type": "string" }, + "Region": { + "type": "string" + }, "FilterPolicy": { "type": "object" } diff --git a/tests/model/eventsources/test_sns_event_source.py b/tests/model/eventsources/test_sns_event_source.py index efedec6cac..434aca9486 100644 --- a/tests/model/eventsources/test_sns_event_source.py +++ b/tests/model/eventsources/test_sns_event_source.py @@ -31,8 +31,21 @@ def test_to_cloudformation_returns_permission_and_subscription_resources(self): self.assertEqual(subscription.TopicArn, 'arn:aws:sns:MyTopic') self.assertEqual(subscription.Protocol, 'lambda') self.assertEqual(subscription.Endpoint, 'arn:aws:lambda:mock') + self.assertIsNone(subscription.Region) self.assertIsNone(subscription.FilterPolicy) + def test_to_cloudformation_passes_the_region(self): + region = 'us-west-2' + self.sns_event_source.Region = region + + resources = self.sns_event_source.to_cloudformation( + function=self.function) + self.assertEqual(len(resources), 2) + self.assertEqual(resources[1].resource_type, + 'AWS::SNS::Subscription') + subscription = resources[1] + self.assertEqual(subscription.Region, region) + def test_to_cloudformation_passes_the_filter_policy(self): filterPolicy = { 'attribute1': ['value1'], diff --git a/tests/translator/input/function_with_sns_event_source_all_parameters.yaml b/tests/translator/input/function_with_sns_event_source_all_parameters.yaml index a745b2f9c8..65711e7330 100644 --- a/tests/translator/input/function_with_sns_event_source_all_parameters.yaml +++ b/tests/translator/input/function_with_sns_event_source_all_parameters.yaml @@ -11,6 +11,7 @@ Resources: Type: SNS Properties: Topic: topicArn + Region: region FilterPolicy: store: - example_corp diff --git a/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json b/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json index 2a2072b9b2..cac15164c9 100644 --- a/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json +++ b/tests/translator/output/aws-cn/function_with_sns_event_source_all_parameters.json @@ -33,7 +33,8 @@ ] }, "Protocol": "lambda", - "TopicArn": "topicArn" + "TopicArn": "topicArn", + "Region": "region" } }, "MyAwesomeFunctionNotificationTopicPermission": { diff --git a/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json b/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json index 4e682d5be2..5ebf5d48e6 100644 --- a/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json +++ b/tests/translator/output/aws-us-gov/function_with_sns_event_source_all_parameters.json @@ -33,7 +33,8 @@ ] }, "Protocol": "lambda", - "TopicArn": "topicArn" + "TopicArn": "topicArn", + "Region": "region" } }, "MyAwesomeFunctionNotificationTopicPermission": { diff --git a/tests/translator/output/function_with_sns_event_source_all_parameters.json b/tests/translator/output/function_with_sns_event_source_all_parameters.json index fb74655888..698eb00559 100644 --- a/tests/translator/output/function_with_sns_event_source_all_parameters.json +++ b/tests/translator/output/function_with_sns_event_source_all_parameters.json @@ -33,7 +33,8 @@ ] }, "Protocol": "lambda", - "TopicArn": "topicArn" + "TopicArn": "topicArn", + "Region": "region" } }, "MyAwesomeFunctionNotificationTopicPermission": { diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 9493abadee..bab076985a 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -426,6 +426,7 @@ The object describing an event source with type `SNS`. Property Name | Type | Description ---|:---:|--- Topic | `string` | **Required.** Topic ARN. +Region | `string` | Region. FilterPolicy | [Amazon SNS filter policy](https://docs.aws.amazon.com/sns/latest/dg/message-filtering.html) | Policy assigned to the topic subscription in order to receive only a subset of the messages. ##### Example: SNS event source object From 0d1246676bfb211b0f6bcb7f3afd840ef6a91bfd Mon Sep 17 00:00:00 2001 From: Cris Barbero Date: Tue, 2 Jul 2019 18:52:55 -0600 Subject: [PATCH 03/31] feat: add ApiKey Auth support (#943) * Initial work to add ApiKeyRequired support - Implement new translator tests - Add swagger.py unit tests - Update documentation - refactor Auth handling in swagger.py * Fix spacing * undo space changes * Add openapi3 tests * Fix linting errors * Update apikey openapi3 tests with expected output. * Move OpenApi Auth processing- Since the ApiKey setting can be specified just at a Function level, we need to ensure the OpenApi Auth post processing happens even if the API has no explicit Auth Settings --- samtranslator/model/api/api_generator.py | 21 +- samtranslator/model/eventsources/push.py | 18 +- samtranslator/swagger/swagger.py | 323 ++++++-- tests/swagger/test_swagger.py | 120 ++- .../api_with_apikey_default_override.yaml | 51 ++ .../input/api_with_apikey_required.yaml | 21 + .../api_with_apikey_required_openapi_3.yaml | 22 + .../input/api_with_auth_all_maximum.yaml | 1 + .../api_with_auth_all_maximum_openapi_3.yaml | 1 + tests/translator/input/globals_for_api.yaml | 1 + ...icit_api_with_auth_and_conditions_max.yaml | 4 +- .../api_with_apikey_default_override.json | 363 ++++++++ .../output/api_with_apikey_required.json | 155 ++++ .../api_with_apikey_required_openapi_3.json | 156 ++++ .../output/api_with_auth_all_maximum.json | 474 ++++++----- .../api_with_auth_all_maximum_openapi_3.json | 90 +- .../api_with_apikey_default_override.json | 371 +++++++++ .../aws-cn/api_with_apikey_required.json | 163 ++++ .../api_with_apikey_required_openapi_3.json | 164 ++++ .../aws-cn/api_with_auth_all_maximum.json | 478 ++++++----- .../api_with_auth_all_maximum_openapi_3.json | 120 +-- .../output/aws-cn/globals_for_api.json | 60 +- ...icit_api_with_auth_and_conditions_max.json | 98 ++- .../api_with_apikey_default_override.json | 371 +++++++++ .../aws-us-gov/api_with_apikey_required.json | 163 ++++ .../api_with_apikey_required_openapi_3.json | 164 ++++ .../aws-us-gov/api_with_auth_all_maximum.json | 478 ++++++----- .../api_with_auth_all_maximum_openapi_3.json | 90 +- .../output/aws-us-gov/globals_for_api.json | 44 +- ...icit_api_with_auth_and_conditions_max.json | 774 +++++++++--------- tests/translator/output/globals_for_api.json | 60 +- ...icit_api_with_auth_and_conditions_max.json | 98 ++- tests/translator/test_translator.py | 5 +- versions/2016-10-31.md | 33 +- 34 files changed, 4144 insertions(+), 1411 deletions(-) create mode 100644 tests/translator/input/api_with_apikey_default_override.yaml create mode 100644 tests/translator/input/api_with_apikey_required.yaml create mode 100644 tests/translator/input/api_with_apikey_required_openapi_3.yaml create mode 100644 tests/translator/output/api_with_apikey_default_override.json create mode 100644 tests/translator/output/api_with_apikey_required.json create mode 100644 tests/translator/output/api_with_apikey_required_openapi_3.json create mode 100644 tests/translator/output/aws-cn/api_with_apikey_default_override.json create mode 100644 tests/translator/output/aws-cn/api_with_apikey_required.json create mode 100644 tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json create mode 100644 tests/translator/output/aws-us-gov/api_with_apikey_default_override.json create mode 100644 tests/translator/output/aws-us-gov/api_with_apikey_required.json create mode 100644 tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py index c906c0e6e0..4949309d98 100644 --- a/samtranslator/model/api/api_generator.py +++ b/samtranslator/model/api/api_generator.py @@ -21,8 +21,9 @@ CorsProperties.__new__.__defaults__ = (None, None, _CORS_WILDCARD, None, False) AuthProperties = namedtuple("_AuthProperties", - ["Authorizers", "DefaultAuthorizer", "InvokeRole", "AddDefaultAuthorizerToCorsPreflight"]) -AuthProperties.__new__.__defaults__ = (None, None, None, True) + ["Authorizers", "DefaultAuthorizer", "InvokeRole", "AddDefaultAuthorizerToCorsPreflight", + "ApiKeyRequired"]) +AuthProperties.__new__.__defaults__ = (None, None, None, True, None) GatewayResponseProperties = ["ResponseParameters", "ResponseTemplates", "StatusCode"] @@ -115,6 +116,8 @@ def _construct_rest_api(self): if self.definition_uri: rest_api.BodyS3Location = self._construct_body_s3_dict() elif self.definition_body: + # # Post Process OpenApi Auth Settings + self.definition_body = self._openapi_auth_postprocess(self.definition_body) rest_api.Body = self.definition_body if self.name: @@ -308,13 +311,17 @@ def _add_auth(self): authorizers = self._get_authorizers(auth_properties.Authorizers, auth_properties.DefaultAuthorizer) if authorizers: - swagger_editor.add_authorizers(authorizers) + swagger_editor.add_authorizers_security_definitions(authorizers) self._set_default_authorizer(swagger_editor, authorizers, auth_properties.DefaultAuthorizer, auth_properties.AddDefaultAuthorizerToCorsPreflight) - # Assign the Swagger back to template + if auth_properties.ApiKeyRequired: + swagger_editor.add_apikey_security_definition() + self._set_default_apikey_required(swagger_editor) - self.definition_body = self._openapi_auth_postprocess(swagger_editor.swagger) + # Assign the Swagger back to template + # self.definition_body = self._openapi_auth_postprocess(swagger_editor.swagger) + self.definition_body = swagger_editor.swagger def _openapi_auth_postprocess(self, definition_body): """ @@ -523,6 +530,10 @@ def _set_default_authorizer(self, swagger_editor, authorizers, default_authorize swagger_editor.set_path_default_authorizer(path, default_authorizer, authorizers=authorizers, add_default_auth_to_preflight=add_default_auth_to_preflight) + def _set_default_apikey_required(self, swagger_editor): + for path in swagger_editor.iter_on_path(): + swagger_editor.set_path_default_apikey_required(path) + def _set_endpoint_configuration(self, rest_api, value): """ Sets endpoint configuration property of AWS::ApiGateway::RestApi resource diff --git a/samtranslator/model/eventsources/push.py b/samtranslator/model/eventsources/push.py index 6b759ab5f9..5fa9863015 100644 --- a/samtranslator/model/eventsources/push.py +++ b/samtranslator/model/eventsources/push.py @@ -123,9 +123,9 @@ class CloudWatchEvent(PushEventSource): resource_type = 'CloudWatchEvent' principal = 'events.amazonaws.com' property_types = { - 'Pattern': PropertyType(False, is_type(dict)), - 'Input': PropertyType(False, is_str()), - 'InputPath': PropertyType(False, is_str()) + 'Pattern': PropertyType(False, is_type(dict)), + 'Input': PropertyType(False, is_str()), + 'InputPath': PropertyType(False, is_str()) } def to_cloudformation(self, **kwargs): @@ -539,9 +539,9 @@ def _add_swagger_integration(self, api, function): if self.Auth: method_authorizer = self.Auth.get('Authorizer') + api_auth = api.get('Auth') if method_authorizer: - api_auth = api.get('Auth') api_authorizers = api_auth and api_auth.get('Authorizers') if method_authorizer != 'AWS_IAM': @@ -566,6 +566,16 @@ def _add_swagger_integration(self, api, function): 'is only a valid value when a DefaultAuthorizer on the API is specified.'.format( method=self.Method, path=self.Path)) + apikey_required_setting = self.Auth.get('ApiKeyRequired') + apikey_required_setting_is_false = apikey_required_setting is not None and not apikey_required_setting + if apikey_required_setting_is_false and not api_auth.get('ApiKeyRequired'): + raise InvalidEventException( + self.relative_id, + 'Unable to set ApiKeyRequired [False] on API method [{method}] for path [{path}] ' + 'because the related API does not specify any ApiKeyRequired.'.format( + method=self.Method, path=self.Path)) + + if method_authorizer or apikey_required_setting is not None: editor.add_auth_to_method(api=api, path=self.Path, method_name=self.Method, auth=self.Auth) if self.RequestModel: diff --git a/samtranslator/swagger/swagger.py b/samtranslator/swagger/swagger.py index c823e2a6a0..2b61f509f1 100644 --- a/samtranslator/swagger/swagger.py +++ b/samtranslator/swagger/swagger.py @@ -160,9 +160,9 @@ def add_lambda_integration(self, path, method, integration_uri, path_dict = self.get_path(path) path_dict[method][self._X_APIGW_INTEGRATION] = { - 'type': 'aws_proxy', - 'httpMethod': 'POST', - 'uri': integration_uri + 'type': 'aws_proxy', + 'httpMethod': 'POST', + 'uri': integration_uri } method_auth_config = method_auth_config or {} @@ -389,7 +389,7 @@ def _make_cors_allowed_methods_for_path(self, path): # Allow-Methods is comma separated string return ','.join(allow_methods) - def add_authorizers(self, authorizers): + def add_authorizers_security_definitions(self, authorizers): """ Add Authorizer definitions to the securityDefinitions part of Swagger. @@ -400,11 +400,56 @@ def add_authorizers(self, authorizers): for authorizer_name, authorizer in authorizers.items(): self.security_definitions[authorizer_name] = authorizer.generate_swagger() + def add_awsiam_security_definition(self): + """ + Adds AWS_IAM definition to the securityDefinitions part of Swagger. + Note: this method is idempotent + """ + + aws_iam_security_definition = { + 'AWS_IAM': { + 'x-amazon-apigateway-authtype': 'awsSigv4', + 'type': 'apiKey', + 'name': 'Authorization', + 'in': 'header' + } + } + + self.security_definitions = self.security_definitions or {} + + # Only add the security definition if it doesn't exist. This helps ensure + # that we minimize changes to the swagger in the case of user defined swagger + if 'AWS_IAM' not in self.security_definitions: + self.security_definitions.update(aws_iam_security_definition) + + def add_apikey_security_definition(self): + """ + Adds api_key definition to the securityDefinitions part of Swagger. + Note: this method is idempotent + """ + + api_key_security_definition = { + 'api_key': { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + + self.security_definitions = self.security_definitions or {} + + # Only add the security definition if it doesn't exist. This helps ensure + # that we minimize changes to the swagger in the case of user defined swagger + if 'api_key' not in self.security_definitions: + self.security_definitions.update(api_key_security_definition) + def set_path_default_authorizer(self, path, default_authorizer, authorizers, add_default_auth_to_preflight=True): """ - Sets the DefaultAuthorizer for each method on this path. The DefaultAuthorizer won't be set if an Authorizer - was defined at the Function/Path/Method level + Adds the default_authorizer to the security block for each method on this path unless an Authorizer + was defined at the Function/Path/Method level. This is intended to be used to set the + authorizer security restriction for all api methods based upon the default configured in the + Serverless API. :param string path: Path name :param string default_authorizer: Name of the authorizer to use as the default. Must be a key in the @@ -416,35 +461,170 @@ def set_path_default_authorizer(self, path, default_authorizer, authorizers, for method_name, method in self.get_path(path).items(): normalized_method_name = self._normalize_method_name(method_name) + # Excluding paramters section if normalized_method_name == "parameters": continue if add_default_auth_to_preflight or normalized_method_name != "options": - self.set_method_authorizer(path, method_name, default_authorizer, authorizers, - default_authorizer=default_authorizer, is_default=True) + normalized_method_name = self._normalize_method_name(method_name) + # It is possible that the method could have two definitions in a Fn::If block. + for method_definition in self.get_method_contents(self.get_path(path)[normalized_method_name]): + + # If no integration given, then we don't need to process this definition (could be AWS::NoValue) + if not self.method_definition_has_integration(method_definition): + continue + existing_security = method_definition.get('security', []) + authorizer_list = ['AWS_IAM'] + if authorizers: + authorizer_list.extend(authorizers.keys()) + authorizer_names = set(authorizer_list) + existing_non_authorizer_security = [] + existing_authorizer_security = [] + + # Split existing security into Authorizers and everything else + # (e.g. sigv4 (AWS_IAM), api_key (API Key/Usage Plans), NONE (marker for ignoring default)) + # We want to ensure only a single Authorizer security entry exists while keeping everything else + for security in existing_security: + if authorizer_names.isdisjoint(security.keys()): + existing_non_authorizer_security.append(security) + else: + existing_authorizer_security.append(security) + + none_idx = -1 + authorizer_security = [] + + # Check for an existing Authorizer before applying the default. It would be simpler + # if instead we applied the DefaultAuthorizer first and then simply + # overwrote it if necessary, however, the order in which things get + # applied (Function Api Events first; then Api Resource) complicates it. + # Check if Function/Path/Method specified 'NONE' for Authorizer + for idx, security in enumerate(existing_non_authorizer_security): + is_none = any(key == 'NONE' for key in security.keys()) + + if is_none: + none_idx = idx + break + + # NONE was found; remove it and don't add the DefaultAuthorizer + if none_idx > -1: + del existing_non_authorizer_security[none_idx] + + # Existing Authorizer found (defined at Function/Path/Method); use that instead of default + elif existing_authorizer_security: + authorizer_security = existing_authorizer_security + + # No existing Authorizer found; use default + else: + security_dict = {} + security_dict[default_authorizer] = [] + authorizer_security = [security_dict] + + security = existing_non_authorizer_security + authorizer_security + + if security: + method_definition['security'] = security + + # The first element of the method_definition['security'] should be AWS_IAM + # because authorizer_list = ['AWS_IAM'] is hardcoded above + if 'AWS_IAM' in method_definition['security'][0]: + self.add_awsiam_security_definition() + + def set_path_default_apikey_required(self, path): + """ + Add the ApiKey security as required for each method on this path unless ApiKeyRequired + was defined at the Function/Path/Method level. This is intended to be used to set the + apikey security restriction for all api methods based upon the default configured in the + Serverless API. + + :param string path: Path name + """ + + for method_name, _ in self.get_path(path).items(): + # Excluding paramters section + if method_name == "parameters": + continue + + normalized_method_name = self._normalize_method_name(method_name) + # It is possible that the method could have two definitions in a Fn::If block. + for method_definition in self.get_method_contents(self.get_path(path)[normalized_method_name]): + + # If no integration given, then we don't need to process this definition (could be AWS::NoValue) + if not self.method_definition_has_integration(method_definition): + continue + + existing_security = method_definition.get('security', []) + apikey_security_names = set(['api_key', 'api_key_false']) + existing_non_apikey_security = [] + existing_apikey_security = [] + apikey_security = [] + + # Split existing security into ApiKey and everything else + # (e.g. sigv4 (AWS_IAM), authorizers, NONE (marker for ignoring default authorizer)) + # We want to ensure only a single ApiKey security entry exists while keeping everything else + for security in existing_security: + if apikey_security_names.isdisjoint(security.keys()): + existing_non_apikey_security.append(security) + else: + existing_apikey_security.append(security) + + # Check for an existing method level ApiKey setting before applying the default. It would be simpler + # if instead we applied the default first and then simply + # overwrote it if necessary, however, the order in which things get + # applied (Function Api Events first; then Api Resource) complicates it. + # Check if Function/Path/Method specified 'False' for ApiKeyRequired + apikeyfalse_idx = -1 + for idx, security in enumerate(existing_apikey_security): + is_none = any(key == 'api_key_false' for key in security.keys()) + + if is_none: + apikeyfalse_idx = idx + break + + # api_key_false was found; remove it and don't add default api_key security setting + if apikeyfalse_idx > -1: + del existing_apikey_security[apikeyfalse_idx] + + # No existing ApiKey setting found or it's already set to the default + else: + security_dict = {} + security_dict['api_key'] = [] + apikey_security = [security_dict] + + security = existing_non_apikey_security + apikey_security + + if security != existing_security: + method_definition['security'] = security def add_auth_to_method(self, path, method_name, auth, api): """ - Adds auth settings for this path/method. Auth settings currently consist solely of Authorizers - but this method will eventually include setting other auth settings such as API Key, - Resource Policy, etc. + Adds auth settings for this path/method. Auth settings currently consist of Authorizers and ApiKeyRequired + but this method will eventually include setting other auth settings such as Resource Policy, etc. + This is used to configure the security for individual functions. :param string path: Path name :param string method_name: Method name - :param dict auth: Auth configuration such as Authorizers, ApiKey, ResourcePolicy (only Authorizers supported - currently) + :param dict auth: Auth configuration such as Authorizers, ApiKeyRequired, ResourcePolicy + (Authorizers and ApiKeyRequired supported currently) :param dict api: Reference to the related Api's properties as defined in the template. """ method_authorizer = auth and auth.get('Authorizer') if method_authorizer: - api_auth = api.get('Auth') - api_authorizers = api_auth and api_auth.get('Authorizers') - default_authorizer = api_auth and api_auth.get('DefaultAuthorizer') + self._set_method_authorizer(path, method_name, method_authorizer) + + method_apikey_required = auth and auth.get('ApiKeyRequired') + if method_apikey_required is not None: + self._set_method_apikey_handling(path, method_name, method_apikey_required) - self.set_method_authorizer(path, method_name, method_authorizer, api_authorizers, default_authorizer) + def _set_method_authorizer(self, path, method_name, authorizer_name): + """ + Adds the authorizer_name to the security block for each method on this path. + This is used to configure the authorizer for individual functions. - def set_method_authorizer(self, path, method_name, authorizer_name, authorizers, default_authorizer, - is_default=False): + :param string path: Path name + :param string method_name: Method name + :param string authorizer_name: Name of the authorizer to use. Must be a key in the + authorizers param. + """ normalized_method_name = self._normalize_method_name(method_name) # It is possible that the method could have two definitions in a Fn::If block. for method_definition in self.get_method_contents(self.get_path(path)[normalized_method_name]): @@ -452,82 +632,63 @@ def set_method_authorizer(self, path, method_name, authorizer_name, authorizers, # If no integration given, then we don't need to process this definition (could be AWS::NoValue) if not self.method_definition_has_integration(method_definition): continue + existing_security = method_definition.get('security', []) - # TEST: [{'sigv4': []}, {'api_key': []}]) - authorizer_list = ['AWS_IAM'] - if authorizers: - authorizer_list.extend(authorizers.keys()) - authorizer_names = set(authorizer_list) - existing_non_authorizer_security = [] - existing_authorizer_security = [] - - # Split existing security into Authorizers and everything else - # (e.g. sigv4 (AWS_IAM), api_key (API Key/Usage Plans), NONE (marker for ignoring default)) - # We want to ensure only a single Authorizer security entry exists while keeping everything else - for security in existing_security: - if authorizer_names.isdisjoint(security.keys()): - existing_non_authorizer_security.append(security) - else: - existing_authorizer_security.append(security) - none_idx = -1 - authorizer_security = [] + security_dict = {} + security_dict[authorizer_name] = [] + authorizer_security = [security_dict] - # If this is the Api-level DefaultAuthorizer we need to check for an - # existing Authorizer before applying the default. It would be simpler - # if instead we applied the DefaultAuthorizer first and then simply - # overwrote it if necessary, however, the order in which things get - # applied (Function Api Events first; then Api Resource) complicates it. - if is_default: - # Check if Function/Path/Method specified 'NONE' for Authorizer - for idx, security in enumerate(existing_non_authorizer_security): - is_none = any(key == 'NONE' for key in security.keys()) + # This assumes there are no autorizers already configured in the existing security block + security = existing_security + authorizer_security - if is_none: - none_idx = idx - break + if security: + method_definition['security'] = security - # NONE was found; remove it and don't add the DefaultAuthorizer - if none_idx > -1: - del existing_non_authorizer_security[none_idx] + # The first element of the method_definition['security'] should be AWS_IAM + # because authorizer_list = ['AWS_IAM'] is hardcoded above + if 'AWS_IAM' in method_definition['security'][0]: + self.add_awsiam_security_definition() - # Existing Authorizer found (defined at Function/Path/Method); use that instead of default - elif existing_authorizer_security: - authorizer_security = existing_authorizer_security + def _set_method_apikey_handling(self, path, method_name, apikey_required): + """ + Adds the apikey setting to the security block for each method on this path. + This is used to configure the authorizer for individual functions. - # No existing Authorizer found; use default - else: - security_dict = {} - security_dict[authorizer_name] = [] - authorizer_security = [security_dict] + :param string path: Path name + :param string method_name: Method name + :param bool apikey_required: Whether the apikey security is required + """ + normalized_method_name = self._normalize_method_name(method_name) + # It is possible that the method could have two definitions in a Fn::If block. + for method_definition in self.get_method_contents(self.get_path(path)[normalized_method_name]): + + # If no integration given, then we don't need to process this definition (could be AWS::NoValue) + if not self.method_definition_has_integration(method_definition): + continue + + existing_security = method_definition.get('security', []) - # This is a Function/Path/Method level Authorizer; simply set it + if apikey_required: + # We want to enable apikey required security + security_dict = {} + security_dict['api_key'] = [] + apikey_security = [security_dict] + self.add_apikey_security_definition() else: + # The method explicitly does NOT require apikey and there is an API default + # so let's add a marker 'api_key_false' so that we don't incorrectly override + # with the api default security_dict = {} - security_dict[authorizer_name] = [] - authorizer_security = [security_dict] + security_dict['api_key_false'] = [] + apikey_security = [security_dict] - security = existing_non_authorizer_security + authorizer_security + # This assumes there are no autorizers already configured in the existing security block + security = existing_security + apikey_security - if security: + if security != existing_security: method_definition['security'] = security - # The first element of the method_definition['security'] should be AWS_IAM - # because authorizer_list = ['AWS_IAM'] is hardcoded above - if 'AWS_IAM' in method_definition['security'][0]: - aws_iam_security_definition = { - 'AWS_IAM': { - 'x-amazon-apigateway-authtype': 'awsSigv4', - 'type': 'apiKey', - 'name': 'Authorization', - 'in': 'header' - } - } - if not self.security_definitions: - self.security_definitions = aws_iam_security_definition - elif 'AWS_IAM' not in self.security_definitions: - self.security_definitions.update(aws_iam_security_definition) - def add_request_model_to_method(self, path, method_name, request_model): """ Adds request model body parameter for this path/method. diff --git a/tests/swagger/test_swagger.py b/tests/swagger/test_swagger.py index e3771e87bf..907e091cb8 100644 --- a/tests/swagger/test_swagger.py +++ b/tests/swagger/test_swagger.py @@ -131,6 +131,7 @@ def test_must_not_fail_on_bad_path(self): self.assertTrue(self.editor.has_path("badpath")) self.assertFalse(self.editor.has_path("badpath", "somemethod")) + class TestSwaggerEditor_has_integration(TestCase): def setUp(self): @@ -725,6 +726,7 @@ def test_allow_credentials_is_skipped_with_false_value(self): actual = options_config[_X_INTEGRATION]["responses"]["default"]["responseParameters"] self.assertEqual(expected, actual) + class TestSwaggerEditor_make_cors_allowed_methods_for_path(TestCase): def setUp(self): @@ -1112,4 +1114,120 @@ def test_must_add_body_parameter_to_method_openapi_required_true(self): } } - self.assertEqual(expected, editor.swagger['paths']['/foo']['get']['requestBody']) \ No newline at end of file + self.assertEqual(expected, editor.swagger['paths']['/foo']['get']['requestBody']) + +class TestSwaggerEditor_add_auth(TestCase): + + def setUp(self): + + self.original_swagger = { + "swagger": "2.0", + "paths": { + "/foo": { + "get": { + _X_INTEGRATION: { + "a": "b" + } + }, + "post":{ + _X_INTEGRATION: { + "a": "b" + } + } + }, + "/bar": { + "get": { + _X_INTEGRATION: { + "a": "b" + } + } + }, + } + } + + self.editor = SwaggerEditor(self.original_swagger) + + def test_add_apikey_security_definition_is_added(self): + expected = { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + + self.editor.add_apikey_security_definition() + self.assertIn('securityDefinitions', self.editor.swagger) + self.assertIn('api_key', self.editor.swagger["securityDefinitions"]) + self.assertEqual(expected, self.editor.swagger["securityDefinitions"]['api_key']) + + def test_must_add_default_apikey_to_all_paths(self): + expected = [{ + "api_key": [] + }] + path = "/foo" + + + self.editor.set_path_default_apikey_required(path) + methods = self.editor.swagger["paths"][path] + for method in methods: + self.assertEqual(expected, methods[method]["security"]) + + def test_add_default_apikey_to_all_paths_correctly_handles_method_level_settings(self): + self.original_swagger = { + "swagger": "2.0", + "paths": { + "/foo": { + "apikeyfalse": { + _X_INTEGRATION: { + "a": "b" + }, + "security":[ + {"api_key_false":[]} + ] + }, + "apikeytrue": { + _X_INTEGRATION: { + "a": "b" + }, + "security":[ + {"api_key":[]} + ] + }, + "apikeydefault":{ + _X_INTEGRATION: { + "a": "b" + } + } + }, + } + } + + self.editor = SwaggerEditor(self.original_swagger) + api_key_exists = [{ + "api_key": [] + }] + path = "/foo" + + self.editor.set_path_default_apikey_required(path) + self.assertEqual([], self.editor.swagger["paths"][path]['apikeyfalse']["security"]) + self.assertEqual(api_key_exists, self.editor.swagger["paths"][path]['apikeytrue']["security"]) + self.assertEqual(api_key_exists, self.editor.swagger["paths"][path]['apikeydefault']["security"]) + + def test_set_method_apikey_handling_apikeyrequired_false(self): + expected = [{ + "api_key_false": [] + }] + path = "/bar" + method = "get" + + self.editor._set_method_apikey_handling(path, method, False) + self.assertEqual(expected, self.editor.swagger["paths"][path][method]["security"]) + + def test_set_method_apikey_handling_apikeyrequired_true(self): + expected = [{ + "api_key": [] + }] + path = "/bar" + method = "get" + + self.editor._set_method_apikey_handling(path, method, True) + self.assertEqual(expected, self.editor.swagger["paths"][path][method]["security"]) diff --git a/tests/translator/input/api_with_apikey_default_override.yaml b/tests/translator/input/api_with_apikey_default_override.yaml new file mode 100644 index 0000000000..53a94e3b62 --- /dev/null +++ b/tests/translator/input/api_with_apikey_default_override.yaml @@ -0,0 +1,51 @@ +Resources: + MyApiWithAuth: + Type: "AWS::Serverless::Api" + Properties: + StageName: Prod + Auth: + ApiKeyRequired: true + + MyFunctionWithApiKeyRequiredDefault: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + MyApiWithApiKeyRequiredDefault: + Type: Api + Properties: + RestApiId: !Ref MyApiWithAuth + Path: /ApiKeyDefault + Method: get + MyFunctionWithApiKeyRequiredTrue: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + MyApiWithApiKeyRequiredTrue: + Type: Api + Properties: + RestApiId: !Ref MyApiWithAuth + Path: /ApiKeyTrue + Method: get + Auth: + ApiKeyRequired: true + MyFunctionWithApiKeyRequiredFalse: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + MyApiWithApiKeyRequiredFalse: + Type: Api + Properties: + RestApiId: !Ref MyApiWithAuth + Path: /ApiKeyFalse + Method: get + Auth: + ApiKeyRequired: false diff --git a/tests/translator/input/api_with_apikey_required.yaml b/tests/translator/input/api_with_apikey_required.yaml new file mode 100644 index 0000000000..e5c562c916 --- /dev/null +++ b/tests/translator/input/api_with_apikey_required.yaml @@ -0,0 +1,21 @@ +Resources: + MyApiWithoutAuth: + Type: "AWS::Serverless::Api" + Properties: + StageName: Prod + + MyFunctionWithApiKeyRequired: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + MyApiWithApiKeyRequired: + Type: Api + Properties: + RestApiId: !Ref MyApiWithoutAuth + Path: /ApiKeyRequiredTrue + Method: get + Auth: + ApiKeyRequired: true diff --git a/tests/translator/input/api_with_apikey_required_openapi_3.yaml b/tests/translator/input/api_with_apikey_required_openapi_3.yaml new file mode 100644 index 0000000000..95d7727c58 --- /dev/null +++ b/tests/translator/input/api_with_apikey_required_openapi_3.yaml @@ -0,0 +1,22 @@ +Resources: + MyApiWithoutAuth: + Type: "AWS::Serverless::Api" + Properties: + StageName: Prod + OpenApiVersion: '3.0.1' + + MyFunctionWithApiKeyRequired: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + MyApiWithApiKeyRequired: + Type: Api + Properties: + RestApiId: !Ref MyApiWithoutAuth + Path: /ApiKeyRequiredTrue + Method: get + Auth: + ApiKeyRequired: true diff --git a/tests/translator/input/api_with_auth_all_maximum.yaml b/tests/translator/input/api_with_auth_all_maximum.yaml index 89c94fdc7e..e3dbd397b3 100644 --- a/tests/translator/input/api_with_auth_all_maximum.yaml +++ b/tests/translator/input/api_with_auth_all_maximum.yaml @@ -5,6 +5,7 @@ Resources: StageName: Prod Auth: DefaultAuthorizer: MyCognitoAuth + ApiKeyRequired: true Authorizers: MyCognitoAuth: UserPoolArn: arn:aws:1 diff --git a/tests/translator/input/api_with_auth_all_maximum_openapi_3.yaml b/tests/translator/input/api_with_auth_all_maximum_openapi_3.yaml index 8cab3cd48c..bb236464fe 100644 --- a/tests/translator/input/api_with_auth_all_maximum_openapi_3.yaml +++ b/tests/translator/input/api_with_auth_all_maximum_openapi_3.yaml @@ -6,6 +6,7 @@ Resources: OpenApiVersion: '3.0.1' Auth: DefaultAuthorizer: MyCognitoAuth + ApiKeyRequired: true Authorizers: MyCognitoAuth: UserPoolArn: arn:aws:1 diff --git a/tests/translator/input/globals_for_api.yaml b/tests/translator/input/globals_for_api.yaml index 5d3a956322..92aca3703e 100644 --- a/tests/translator/input/globals_for_api.yaml +++ b/tests/translator/input/globals_for_api.yaml @@ -8,6 +8,7 @@ Globals: Authorizers: MyCognitoAuth: UserPoolArn: !GetAtt MyUserPool.Arn + ApiKeyRequired: true Variables: SomeVar: Value diff --git a/tests/translator/input/implicit_api_with_auth_and_conditions_max.yaml b/tests/translator/input/implicit_api_with_auth_and_conditions_max.yaml index 61d2751a21..3c0ac05049 100644 --- a/tests/translator/input/implicit_api_with_auth_and_conditions_max.yaml +++ b/tests/translator/input/implicit_api_with_auth_and_conditions_max.yaml @@ -161,4 +161,6 @@ Resources: Type: Api Properties: Path: /users - Method: put \ No newline at end of file + Method: put + Auth: + ApiKeyRequired: true \ No newline at end of file diff --git a/tests/translator/output/api_with_apikey_default_override.json b/tests/translator/output/api_with_apikey_default_override.json new file mode 100644 index 0000000000..03f6db829a --- /dev/null +++ b/tests/translator/output/api_with_apikey_default_override.json @@ -0,0 +1,363 @@ +{ + "Resources": { + "MyApiWithAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithAuthDeployment054e605502" + }, + "RestApiId": { + "Ref": "MyApiWithAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredTrueMyApiWithApiKeyRequiredTruePermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredTrue" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredFalseMyApiWithApiKeyRequiredFalsePermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredFalse" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyFalse", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredFalseMyApiWithApiKeyRequiredFalsePermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredFalse" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyFalse", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrue": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredTrueRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredDefault": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredDefaultRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredDefaultMyApiWithApiKeyRequiredDefaultPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredDefault" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyDefault", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyApiWithAuthDeployment054e605502": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAuth" + }, + "Description": "RestApi deployment id: 054e60550295973114b1bc4384d00c8b641ea20f", + "StageName": "Stage" + } + }, + "MyFunctionWithApiKeyRequiredFalse": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredFalseRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredFalseRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredDefaultRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredDefaultMyApiWithApiKeyRequiredDefaultPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredDefault" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyDefault", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrueMyApiWithApiKeyRequiredTruePermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredTrue" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrueRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyApiWithAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyFalse": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredFalse.Arn}/invocations" + } + }, + "security": [], + "responses": {} + } + }, + "/ApiKeyTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredTrue.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + }, + "/ApiKeyDefault": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredDefault.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + } + } + } + } + } \ No newline at end of file diff --git a/tests/translator/output/api_with_apikey_required.json b/tests/translator/output/api_with_apikey_required.json new file mode 100644 index 0000000000..b864a2dcc8 --- /dev/null +++ b/tests/translator/output/api_with_apikey_required.json @@ -0,0 +1,155 @@ +{ + "Resources": { + "MyFunctionWithApiKeyRequiredRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyApiWithoutAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyRequiredTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequired.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + } + } + }, + "MyApiWithoutAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithoutAuthDeployment3ab9d13134" + }, + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequired": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyApiWithoutAuthDeployment3ab9d13134": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: 3ab9d13134bf550e275a303c6987801dfb7f9d7b", + "StageName": "Stage" + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/api_with_apikey_required_openapi_3.json b/tests/translator/output/api_with_apikey_required_openapi_3.json new file mode 100644 index 0000000000..e913e63751 --- /dev/null +++ b/tests/translator/output/api_with_apikey_required_openapi_3.json @@ -0,0 +1,156 @@ +{ + "Resources": { + "MyFunctionWithApiKeyRequiredRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyApiWithoutAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyRequiredTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequired.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "openapi": "3.0.1", + "components": { + "securitySchemes": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + } + } + } + }, + "MyApiWithoutAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithoutAuthDeployment741383c56d" + }, + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequired": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyApiWithoutAuthDeployment741383c56d": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: 741383c56de0cab1f561223582a9259cf165b42f" + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/api_with_auth_all_maximum.json b/tests/translator/output/api_with_auth_all_maximum.json index 61b4a6b398..3701420314 100644 --- a/tests/translator/output/api_with_auth_all_maximum.json +++ b/tests/translator/output/api_with_auth_all_maximum.json @@ -1,39 +1,41 @@ { "Resources": { "MyFunction": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, - "Handler": "index.handler", + }, "Role": { "Fn::GetAtt": [ - "MyFunctionRole", + "MyFunctionRole", "Arn" ] - }, - "Runtime": "nodejs8.10", - "Tags": [{ - "Value": "SAM", - "Key": "lambda:createdBy" - }] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] } - }, + }, "MyFunctionWithLambdaTokenAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -41,16 +43,16 @@ ] } } - }, + }, "MyApiMyLambdaRequestAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -59,20 +61,20 @@ ] } } - }, + }, "MyFunctionWithLambdaTokenAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -80,20 +82,20 @@ ] } } - }, + }, "MyFunctionWithDefaultAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -101,20 +103,20 @@ ] } } - }, + }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -122,20 +124,20 @@ ] } } - }, + }, "MyFunctionWithNoAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -143,210 +145,242 @@ ] } } - }, + }, "MyFunctionRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", - "Statement": [{ - "Action": [ - "sts:AssumeRole" - ], - "Effect": "Allow", - "Principal": { - "Service": [ - "lambda.amazonaws.com" - ] + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } } - }] + ] } } - }, + }, "MyApi": { - "Type": "AWS::ApiGateway::RestApi", + "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "/": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "NONE": [] - }], + }, + "security": [ + { + "NONE": [] + }, + { + "api_key": [] + } + ], "responses": {} } - }, + }, "/users": { "put": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyCognitoAuth": [] - }], + }, + "security": [ + { + "MyCognitoAuth": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "post": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyCognitoAuthMultipleUserPools": [] - }], + }, + "security": [ + { + "MyCognitoAuthMultipleUserPools": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "patch": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyLambdaTokenAuthNoneFunctionInvokeRole": [] - }], + }, + "security": [ + { + "MyLambdaTokenAuthNoneFunctionInvokeRole": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "delete": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyLambdaRequestAuth": [] - }], + }, + "security": [ + { + "MyLambdaRequestAuth": [] + }, + { + "api_key": [] + } + ], "responses": {} } } - }, - "swagger": "2.0", + }, + "swagger": "2.0", "securityDefinitions": { - "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, "MyLambdaTokenAuthNoneFunctionInvokeRole": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 0, + "type": "token", + "authorizerResultTtlInSeconds": 0, "authorizerUri": { "Fn::Sub": [ - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] } - }, + }, "x-amazon-apigateway-authtype": "custom" - }, + }, "MyCognitoAuthMultipleUserPools": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader2", + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader2", "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression2", + "identityValidationExpression": "myauthvalidationexpression2", "providerARNs": [ - "arn:aws:2", + "arn:aws:2", "arn:aws:3" - ], + ], "type": "cognito_user_pools" - }, + }, "x-amazon-apigateway-authtype": "cognito_user_pools" - }, - "MyLambdaTokenAuth": { - "in": "header", - "type": "apiKey", - "name": "MyCustomAuthHeader", + }, + "MyLambdaRequestAuth": { + "in": "header", + "type": "apiKey", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 20, + "type": "request", + "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", - "identityValidationExpression": "mycustomauthexpression" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + }, "x-amazon-apigateway-authtype": "custom" - }, - "MyLambdaRequestAuth": { - "in": "header", - "type": "apiKey", - "name": "Unused", + }, + "MyCognitoAuth": { + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader", + "x-amazon-apigateway-authorizer": { + "identityValidationExpression": "myauthvalidationexpression", + "providerARNs": [ + "arn:aws:1" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "MyLambdaTokenAuth": { + "in": "header", + "type": "apiKey", + "name": "MyCustomAuthHeader", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", + "type": "token", + "authorizerResultTtlInSeconds": 20, "authorizerUri": { "Fn::Sub": [ - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", + "identityValidationExpression": "mycustomauthexpression" + }, "x-amazon-apigateway-authtype": "custom" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } } } - }, + }, "MyApiMyLambdaTokenAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -355,20 +389,20 @@ ] } } - }, + }, "MyFunctionWithLambdaRequestAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -376,20 +410,20 @@ ] } } - }, + }, "MyFunctionWithLambdaRequestAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -397,30 +431,20 @@ ] } } - }, - "MyApiDeployment22f365e69f": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: 22f365e69fd10c36975a60c0b715eb1340f4b5e6", - "StageName": "Stage" - } - }, + }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -428,16 +452,26 @@ ] } } - }, + }, + "MyApiDeployment0cec4886a5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: 0cec4886a504a36373a7cbd8952ec7aa9643bfbd", + "StageName": "Stage" + } + }, "MyApiMyLambdaTokenAuthNoneFunctionInvokeRoleAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -446,32 +480,32 @@ ] } } - }, + }, "MyApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeployment22f365e69f" - }, + "Ref": "MyApiDeployment0cec4886a5" + }, "RestApiId": { "Ref": "MyApi" - }, + }, "StageName": "Prod" } - }, + }, "MyFunctionWithNoAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -479,20 +513,20 @@ ] } } - }, + }, "MyFunctionWithDefaultAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } diff --git a/tests/translator/output/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/api_with_auth_all_maximum_openapi_3.json index 1968c4ec00..ff6efcd6f9 100644 --- a/tests/translator/output/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/api_with_auth_all_maximum_openapi_3.json @@ -170,6 +170,15 @@ } } }, + "MyApiDeployment959b43a9ef": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: 959b43a9efc3347ee417e242c5f936bbd40ef663" + } + }, "MyApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -193,6 +202,9 @@ "security": [ { "NONE": [] + }, + { + "api_key": [] } ], "responses": {} @@ -210,6 +222,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -225,6 +240,9 @@ "security": [ { "MyCognitoAuthMultipleUserPools": [] + }, + { + "api_key": [] } ], "responses": {} @@ -240,6 +258,9 @@ "security": [ { "MyLambdaTokenAuthNoneFunctionInvokeRole": [] + }, + { + "api_key": [] } ], "responses": {} @@ -255,6 +276,9 @@ "security": [ { "MyLambdaRequestAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -264,19 +288,6 @@ "openapi": "3.0.1", "components": { "securitySchemes": { - "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, "MyLambdaTokenAuthNoneFunctionInvokeRole": { "in": "header", "type": "apiKey", @@ -309,13 +320,14 @@ }, "x-amazon-apigateway-authtype": "cognito_user_pools" }, - "MyLambdaTokenAuth": { + "MyLambdaRequestAuth": { "in": "header", "type": "apiKey", - "name": "MyCustomAuthHeader", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 20, + "type": "request", + "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -324,19 +336,30 @@ } ] }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", - "identityValidationExpression": "mycustomauthexpression" + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" }, "x-amazon-apigateway-authtype": "custom" }, - "MyLambdaRequestAuth": { + "MyCognitoAuth": { "in": "header", "type": "apiKey", - "name": "Unused", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", + "identityValidationExpression": "myauthvalidationexpression", + "providerARNs": [ + "arn:aws:1" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "MyLambdaTokenAuth": { + "in": "header", + "type": "apiKey", + "name": "MyCustomAuthHeader", + "x-amazon-apigateway-authorizer": { + "type": "token", + "authorizerResultTtlInSeconds": 20, "authorizerUri": { "Fn::Sub": [ "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -345,9 +368,15 @@ } ] }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", + "identityValidationExpression": "mycustomauthexpression" }, "x-amazon-apigateway-authtype": "custom" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } } @@ -453,20 +482,11 @@ } } }, - "MyApiDeployment18e0cddfbf": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: 18e0cddfbf74ca986461d5a484b9eedd934a6423" - } - }, "MyApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeployment18e0cddfbf" + "Ref": "MyApiDeployment959b43a9ef" }, "RestApiId": { "Ref": "MyApi" diff --git a/tests/translator/output/aws-cn/api_with_apikey_default_override.json b/tests/translator/output/aws-cn/api_with_apikey_default_override.json new file mode 100644 index 0000000000..31e38efe95 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_apikey_default_override.json @@ -0,0 +1,371 @@ +{ + "Resources": { + "MyApiWithAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithAuthDeployment12e3363002" + }, + "RestApiId": { + "Ref": "MyApiWithAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredTrueMyApiWithApiKeyRequiredTruePermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredTrue" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredFalseMyApiWithApiKeyRequiredFalsePermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredFalse" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyFalse", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredFalseMyApiWithApiKeyRequiredFalsePermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredFalse" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyFalse", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrue": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredTrueRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredDefault": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredDefaultRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredDefaultMyApiWithApiKeyRequiredDefaultPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredDefault" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyDefault", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyApiWithAuthDeployment12e3363002": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAuth" + }, + "Description": "RestApi deployment id: 12e33630022574b70be75950554db06d81af114d", + "StageName": "Stage" + } + }, + "MyFunctionWithApiKeyRequiredFalse": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredFalseRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredFalseRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredDefaultRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredDefaultMyApiWithApiKeyRequiredDefaultPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredDefault" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyDefault", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrueMyApiWithApiKeyRequiredTruePermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredTrue" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrueRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyApiWithAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyFalse": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredFalse.Arn}/invocations" + } + }, + "security": [], + "responses": {} + } + }, + "/ApiKeyTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredTrue.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + }, + "/ApiKeyDefault": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredDefault.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_apikey_required.json b/tests/translator/output/aws-cn/api_with_apikey_required.json new file mode 100644 index 0000000000..65a966df63 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_apikey_required.json @@ -0,0 +1,163 @@ +{ + "Resources": { + "MyFunctionWithApiKeyRequiredRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyApiWithoutAuthDeploymentcc6d6fc40a": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: cc6d6fc40a37188fe0115a039b24e397dc149478", + "StageName": "Stage" + } + }, + "MyApiWithoutAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyRequiredTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequired.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "MyApiWithoutAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithoutAuthDeploymentcc6d6fc40a" + }, + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequired": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json b/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json new file mode 100644 index 0000000000..0ecfb136d8 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json @@ -0,0 +1,164 @@ +{ + "Resources": { + "MyFunctionWithApiKeyRequiredRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyApiWithoutAuthDeployment859a8b8388": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: 859a8b8388c863dbda96b384cefea4ac988f5f81" + } + }, + "MyApiWithoutAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyRequiredTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequired.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "openapi": "3.0.1", + "components": { + "securitySchemes": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "MyApiWithoutAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithoutAuthDeployment859a8b8388" + }, + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequired": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_auth_all_maximum.json b/tests/translator/output/aws-cn/api_with_auth_all_maximum.json index 781c9b8bef..b74a6965e7 100644 --- a/tests/translator/output/aws-cn/api_with_auth_all_maximum.json +++ b/tests/translator/output/aws-cn/api_with_auth_all_maximum.json @@ -1,39 +1,41 @@ { "Resources": { "MyFunction": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, - "Handler": "index.handler", + }, "Role": { "Fn::GetAtt": [ - "MyFunctionRole", + "MyFunctionRole", "Arn" ] - }, - "Runtime": "nodejs8.10", - "Tags": [{ - "Value": "SAM", - "Key": "lambda:createdBy" - }] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] } - }, + }, "MyFunctionWithLambdaTokenAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -41,16 +43,16 @@ ] } } - }, + }, "MyApiMyLambdaRequestAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -59,20 +61,20 @@ ] } } - }, + }, "MyFunctionWithLambdaTokenAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -80,20 +82,20 @@ ] } } - }, + }, "MyFunctionWithDefaultAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -101,30 +103,20 @@ ] } } - }, - "MyApiDeployment8401165542": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: 8401165542e94cea0086026b427b10c966b84f1d", - "StageName": "Stage" - } - }, + }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -132,20 +124,20 @@ ] } } - }, + }, "MyFunctionWithNoAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -153,218 +145,250 @@ ] } } - }, + }, "MyFunctionRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", - "Statement": [{ - "Action": [ - "sts:AssumeRole" - ], - "Effect": "Allow", - "Principal": { - "Service": [ - "lambda.amazonaws.com" - ] + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } } - }] + ] } } - }, + }, "MyApi": { - "Type": "AWS::ApiGateway::RestApi", + "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "/": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "NONE": [] - }], + }, + "security": [ + { + "NONE": [] + }, + { + "api_key": [] + } + ], "responses": {} } - }, + }, "/users": { "put": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyCognitoAuth": [] - }], + }, + "security": [ + { + "MyCognitoAuth": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "post": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyCognitoAuthMultipleUserPools": [] - }], + }, + "security": [ + { + "MyCognitoAuthMultipleUserPools": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "patch": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyLambdaTokenAuthNoneFunctionInvokeRole": [] - }], + }, + "security": [ + { + "MyLambdaTokenAuthNoneFunctionInvokeRole": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "delete": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyLambdaRequestAuth": [] - }], + }, + "security": [ + { + "MyLambdaRequestAuth": [] + }, + { + "api_key": [] + } + ], "responses": {} } } - }, - "swagger": "2.0", + }, + "swagger": "2.0", "securityDefinitions": { - "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, "MyLambdaTokenAuthNoneFunctionInvokeRole": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 0, + "type": "token", + "authorizerResultTtlInSeconds": 0, "authorizerUri": { "Fn::Sub": [ - "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] } - }, + }, "x-amazon-apigateway-authtype": "custom" - }, + }, "MyCognitoAuthMultipleUserPools": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader2", + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader2", "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression2", + "identityValidationExpression": "myauthvalidationexpression2", "providerARNs": [ - "arn:aws:2", + "arn:aws:2", "arn:aws:3" - ], + ], "type": "cognito_user_pools" - }, + }, "x-amazon-apigateway-authtype": "cognito_user_pools" - }, - "MyLambdaTokenAuth": { - "in": "header", - "type": "apiKey", - "name": "MyCustomAuthHeader", + }, + "MyLambdaRequestAuth": { + "in": "header", + "type": "apiKey", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 20, + "type": "request", + "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ - "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", - "identityValidationExpression": "mycustomauthexpression" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + }, "x-amazon-apigateway-authtype": "custom" - }, - "MyLambdaRequestAuth": { - "in": "header", - "type": "apiKey", - "name": "Unused", + }, + "MyCognitoAuth": { + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", + "identityValidationExpression": "myauthvalidationexpression", + "providerARNs": [ + "arn:aws:1" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "MyLambdaTokenAuth": { + "in": "header", + "type": "apiKey", + "name": "MyCustomAuthHeader", + "x-amazon-apigateway-authorizer": { + "type": "token", + "authorizerResultTtlInSeconds": 20, "authorizerUri": { "Fn::Sub": [ - "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", + "identityValidationExpression": "mycustomauthexpression" + }, "x-amazon-apigateway-authtype": "custom" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } - }, + }, "EndpointConfiguration": { "Types": [ "REGIONAL" ] - }, + }, "Parameters": { "endpointConfigurationTypes": "REGIONAL" } } - }, + }, "MyApiMyLambdaTokenAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -373,20 +397,20 @@ ] } } - }, + }, "MyFunctionWithLambdaRequestAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -394,20 +418,20 @@ ] } } - }, + }, "MyFunctionWithLambdaRequestAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -415,20 +439,20 @@ ] } } - }, + }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -436,16 +460,16 @@ ] } } - }, + }, "MyApiMyLambdaTokenAuthNoneFunctionInvokeRoleAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -454,32 +478,42 @@ ] } } - }, + }, + "MyApiDeployment2b4f028142": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: 2b4f028142eb38900e00f362b76751032ac4e464", + "StageName": "Stage" + } + }, "MyApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeployment8401165542" - }, + "Ref": "MyApiDeployment2b4f028142" + }, "RestApiId": { "Ref": "MyApi" - }, + }, "StageName": "Prod" } - }, + }, "MyFunctionWithNoAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -487,20 +521,20 @@ ] } } - }, + }, "MyFunctionWithDefaultAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } diff --git a/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json index de778924c6..33c63f8623 100644 --- a/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json @@ -193,6 +193,9 @@ "security": [ { "NONE": [] + }, + { + "api_key": [] } ], "responses": {} @@ -210,6 +213,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -225,6 +231,9 @@ "security": [ { "MyCognitoAuthMultipleUserPools": [] + }, + { + "api_key": [] } ], "responses": {} @@ -240,6 +249,9 @@ "security": [ { "MyLambdaTokenAuthNoneFunctionInvokeRole": [] + }, + { + "api_key": [] } ], "responses": {} @@ -255,6 +267,9 @@ "security": [ { "MyLambdaRequestAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -264,19 +279,6 @@ "openapi": "3.0.1", "components": { "securitySchemes": { - "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, "MyLambdaTokenAuthNoneFunctionInvokeRole": { "in": "header", "type": "apiKey", @@ -309,13 +311,14 @@ }, "x-amazon-apigateway-authtype": "cognito_user_pools" }, - "MyLambdaTokenAuth": { + "MyLambdaRequestAuth": { "in": "header", "type": "apiKey", - "name": "MyCustomAuthHeader", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 20, + "type": "request", + "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -324,19 +327,30 @@ } ] }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", - "identityValidationExpression": "mycustomauthexpression" + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" }, "x-amazon-apigateway-authtype": "custom" }, - "MyLambdaRequestAuth": { + "MyCognitoAuth": { "in": "header", "type": "apiKey", - "name": "Unused", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", + "identityValidationExpression": "myauthvalidationexpression", + "providerARNs": [ + "arn:aws:1" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "MyLambdaTokenAuth": { + "in": "header", + "type": "apiKey", + "name": "MyCustomAuthHeader", + "x-amazon-apigateway-authorizer": { + "type": "token", + "authorizerResultTtlInSeconds": 20, "authorizerUri": { "Fn::Sub": [ "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -345,9 +359,15 @@ } ] }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", + "identityValidationExpression": "mycustomauthexpression" }, "x-amazon-apigateway-authtype": "custom" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } } @@ -362,22 +382,13 @@ } } }, - "MyApiMyLambdaTokenAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "MyApiDeploymente3164c0eda": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", - "SourceArn": { - "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", - { - "__ApiId__": { - "Ref": "MyApi" - } - } - ] - } + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: e3164c0edaf0d9fc342c47f30edf05040f87af8b" } }, "MyFunctionWithLambdaRequestAuthorizerPermissionTest": { @@ -422,15 +433,6 @@ } } }, - "MyApiDeploymentbaa112a5f1": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: baa112a5f13c2489dbb3bde338d974cf87541b01" - } - }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -470,11 +472,29 @@ } } }, + "MyApiMyLambdaTokenAuthAuthorizerPermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + { + "__ApiId__": { + "Ref": "MyApi" + } + } + ] + } + } + }, "MyApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeploymentbaa112a5f1" + "Ref": "MyApiDeploymente3164c0eda" }, "RestApiId": { "Ref": "MyApi" diff --git a/tests/translator/output/aws-cn/globals_for_api.json b/tests/translator/output/aws-cn/globals_for_api.json index bcfdd57cad..8bd110f3fc 100644 --- a/tests/translator/output/aws-cn/globals_for_api.json +++ b/tests/translator/output/aws-cn/globals_for_api.json @@ -91,6 +91,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -115,6 +118,11 @@ "type": "cognito_user_pools" }, "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } }, @@ -142,20 +150,10 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ServerlessRestApiDeploymente1212668e0" + "Ref": "ServerlessRestApiDeploymentf6c326a165" } } }, - "ServerlessRestApiDeploymente1212668e0": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: e1212668e096994ab32167666f5a877bd6ac5fad", - "StageName": "Stage" - } - }, "ExplicitApiSomeStageStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { @@ -169,10 +167,30 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeploymentd5fa0145e9" + "Ref": "ExplicitApiDeployment43e01e673d" } } }, + "ServerlessRestApiDeploymentf6c326a165": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: f6c326a1656cc9fbb0106cc645598d88575554eb", + "StageName": "Stage" + } + }, + "ExplicitApiDeployment43e01e673d": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 43e01e673d7acbd09e4c38ff78dd6ddaf2ed1d55", + "StageName": "Stage" + } + }, "ImplicitApiFunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -194,16 +212,6 @@ } } }, - "ExplicitApiDeploymentd5fa0145e9": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: d5fa0145e9e6393911d32967e66fd7091d605483", - "StageName": "Stage" - } - }, "MyUserPool": { "Type": "AWS::Cognito::UserPool", "Properties": { @@ -248,6 +256,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -272,6 +283,11 @@ "type": "cognito_user_pools" }, "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } }, diff --git a/tests/translator/output/aws-cn/implicit_api_with_auth_and_conditions_max.json b/tests/translator/output/aws-cn/implicit_api_with_auth_and_conditions_max.json index 1ffd2bd98b..2ced69491d 100644 --- a/tests/translator/output/aws-cn/implicit_api_with_auth_and_conditions_max.json +++ b/tests/translator/output/aws-cn/implicit_api_with_auth_and_conditions_max.json @@ -223,7 +223,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment13185ed4f8" + "Ref": "ServerlessRestApiDeployment6b0de9dc9a" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -594,17 +594,6 @@ }, "Condition": "FunctionCondition" }, - "ServerlessRestApiDeployment13185ed4f8": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: 13185ed4f830a9731f30c8561a781a0f560748c1", - "StageName": "Stage" - }, - "Condition": "ServerlessRestApiCondition" - }, "MyFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -652,6 +641,17 @@ }, "Condition": "FunctionCondition5" }, + "ServerlessRestApiDeployment6b0de9dc9a": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 6b0de9dc9a2450a248988d39c61e2ee23b257724", + "StageName": "Stage" + }, + "Condition": "ServerlessRestApiCondition" + }, "MyFunction3WithLambdaTokenAuthorizerPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -772,6 +772,9 @@ } }, "security": [ + { + "api_key": [] + }, { "MyCognitoAuth": [] } @@ -916,26 +919,37 @@ }, "swagger": "2.0", "securityDefinitions": { - "MyCognitoAuth": { + "MyLambdaTokenAuthNoneFunctionInvokeRole": { "in": "header", "type": "apiKey", - "name": "MyAuthorizationHeader", + "name": "Authorization", "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" + "type": "token", + "authorizerResultTtlInSeconds": 0, + "authorizerUri": { + "Fn::Sub": [ + "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + { + "__FunctionArn__": "arn:aws" + } + ] + } }, - "x-amazon-apigateway-authtype": "cognito_user_pools" + "x-amazon-apigateway-authtype": "custom" }, - "MyLambdaTokenAuthNoneFunctionInvokeRole": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + }, + "MyLambdaRequestAuth": { "in": "header", "type": "apiKey", - "name": "Authorization", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", + "type": "request", "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -943,19 +957,19 @@ "__FunctionArn__": "arn:aws" } ] - } + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" }, "x-amazon-apigateway-authtype": "custom" }, - "MyCognitoAuthMultipleUserPools": { + "MyCognitoAuth": { "in": "header", "type": "apiKey", - "name": "MyAuthorizationHeader2", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression2", + "identityValidationExpression": "myauthvalidationexpression", "providerARNs": [ - "arn:aws:2", - "arn:aws:3" + "arn:aws:1" ], "type": "cognito_user_pools" }, @@ -981,25 +995,19 @@ }, "x-amazon-apigateway-authtype": "custom" }, - "MyLambdaRequestAuth": { + "MyCognitoAuthMultipleUserPools": { "in": "header", "type": "apiKey", - "name": "Unused", + "name": "MyAuthorizationHeader2", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", - "authorizerUri": { - "Fn::Sub": [ - "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", - { - "__FunctionArn__": "arn:aws" - } - ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + "identityValidationExpression": "myauthvalidationexpression2", + "providerARNs": [ + "arn:aws:2", + "arn:aws:3" + ], + "type": "cognito_user_pools" }, - "x-amazon-apigateway-authtype": "custom" + "x-amazon-apigateway-authtype": "cognito_user_pools" } } }, @@ -1037,4 +1045,4 @@ "Condition": "FunctionCondition2" } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_apikey_default_override.json b/tests/translator/output/aws-us-gov/api_with_apikey_default_override.json new file mode 100644 index 0000000000..a508c0e137 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_apikey_default_override.json @@ -0,0 +1,371 @@ +{ + "Resources": { + "MyApiWithAuthDeployment084855ab6d": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAuth" + }, + "Description": "RestApi deployment id: 084855ab6d04ef5b762ac75de403810cd5f0c166", + "StageName": "Stage" + } + }, + "MyFunctionWithApiKeyRequiredTrueMyApiWithApiKeyRequiredTruePermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredTrue" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredFalseMyApiWithApiKeyRequiredFalsePermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredFalse" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyFalse", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredFalseMyApiWithApiKeyRequiredFalsePermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredFalse" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyFalse", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyApiWithAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithAuthDeployment084855ab6d" + }, + "RestApiId": { + "Ref": "MyApiWithAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredTrue": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredTrueRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredDefault": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredDefaultRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredDefaultMyApiWithApiKeyRequiredDefaultPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredDefault" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyDefault", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredFalse": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredFalseRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionWithApiKeyRequiredFalseRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredDefaultRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredDefaultMyApiWithApiKeyRequiredDefaultPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredDefault" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyDefault", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrueMyApiWithApiKeyRequiredTruePermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequiredTrue" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredTrueRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyApiWithAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyFalse": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredFalse.Arn}/invocations" + } + }, + "security": [], + "responses": {} + } + }, + "/ApiKeyTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredTrue.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + }, + "/ApiKeyDefault": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequiredDefault.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_apikey_required.json b/tests/translator/output/aws-us-gov/api_with_apikey_required.json new file mode 100644 index 0000000000..0d7f930765 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_apikey_required.json @@ -0,0 +1,163 @@ +{ + "Resources": { + "MyFunctionWithApiKeyRequiredRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyApiWithoutAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyRequiredTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequired.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "MyApiWithoutAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithoutAuthDeployment1f6bf4c0d5" + }, + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequired": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyApiWithoutAuthDeployment1f6bf4c0d5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: 1f6bf4c0d5babf513c5623a65931134211ad3d0b", + "StageName": "Stage" + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json new file mode 100644 index 0000000000..90fc4e9da9 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json @@ -0,0 +1,164 @@ +{ + "Resources": { + "MyFunctionWithApiKeyRequiredRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyApiWithoutAuth": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/ApiKeyRequiredTrue": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithApiKeyRequired.Arn}/invocations" + } + }, + "security": [ + { + "api_key": [] + } + ], + "responses": {} + } + } + }, + "openapi": "3.0.1", + "components": { + "securitySchemes": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + } + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "MyApiWithoutAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithoutAuthDeploymentfee0b2b452" + }, + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "StageName": "Prod" + } + }, + "MyFunctionWithApiKeyRequiredMyApiWithApiKeyRequiredPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithApiKeyRequired" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/ApiKeyRequiredTrue", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithoutAuth" + } + } + ] + } + } + }, + "MyFunctionWithApiKeyRequired": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionWithApiKeyRequiredRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyApiWithoutAuthDeploymentfee0b2b452": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: fee0b2b45266fff45b8edba43206618eabefebfe" + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum.json b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum.json index 7faead9d31..589b9fd953 100644 --- a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum.json +++ b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum.json @@ -1,39 +1,41 @@ { "Resources": { "MyFunction": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, - "Handler": "index.handler", + }, "Role": { "Fn::GetAtt": [ - "MyFunctionRole", + "MyFunctionRole", "Arn" ] - }, - "Runtime": "nodejs8.10", - "Tags": [{ - "Value": "SAM", - "Key": "lambda:createdBy" - }] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] } - }, + }, "MyFunctionWithLambdaTokenAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -41,16 +43,16 @@ ] } } - }, + }, "MyApiMyLambdaRequestAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -59,20 +61,20 @@ ] } } - }, + }, "MyFunctionWithLambdaTokenAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -80,20 +82,20 @@ ] } } - }, + }, "MyFunctionWithDefaultAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -101,20 +103,20 @@ ] } } - }, + }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -122,20 +124,20 @@ ] } } - }, + }, "MyFunctionWithNoAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -143,218 +145,260 @@ ] } } - }, + }, + "MyApiDeployment7939ed72e3": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: 7939ed72e39cf5e3c86aaa365a531790a1d244e6", + "StageName": "Stage" + } + }, "MyFunctionRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", - "Statement": [{ - "Action": [ - "sts:AssumeRole" - ], - "Effect": "Allow", - "Principal": { - "Service": [ - "lambda.amazonaws.com" - ] + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } } - }] + ] } } - }, + }, "MyApi": { - "Type": "AWS::ApiGateway::RestApi", + "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "/": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "NONE": [] - }], + }, + "security": [ + { + "NONE": [] + }, + { + "api_key": [] + } + ], "responses": {} } - }, + }, "/users": { "put": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyCognitoAuth": [] - }], + }, + "security": [ + { + "MyCognitoAuth": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "post": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyCognitoAuthMultipleUserPools": [] - }], + }, + "security": [ + { + "MyCognitoAuthMultipleUserPools": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "patch": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyLambdaTokenAuthNoneFunctionInvokeRole": [] - }], + }, + "security": [ + { + "MyLambdaTokenAuthNoneFunctionInvokeRole": [] + }, + { + "api_key": [] + } + ], "responses": {} - }, + }, "delete": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" } - }, - "security": [{ - "MyLambdaRequestAuth": [] - }], + }, + "security": [ + { + "MyLambdaRequestAuth": [] + }, + { + "api_key": [] + } + ], "responses": {} } } - }, - "swagger": "2.0", + }, + "swagger": "2.0", "securityDefinitions": { - "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, "MyLambdaTokenAuthNoneFunctionInvokeRole": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 0, + "type": "token", + "authorizerResultTtlInSeconds": 0, "authorizerUri": { "Fn::Sub": [ - "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] } - }, + }, "x-amazon-apigateway-authtype": "custom" - }, + }, "MyCognitoAuthMultipleUserPools": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader2", + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader2", "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression2", + "identityValidationExpression": "myauthvalidationexpression2", "providerARNs": [ - "arn:aws:2", + "arn:aws:2", "arn:aws:3" - ], + ], "type": "cognito_user_pools" - }, + }, "x-amazon-apigateway-authtype": "cognito_user_pools" - }, - "MyLambdaTokenAuth": { - "in": "header", - "type": "apiKey", - "name": "MyCustomAuthHeader", + }, + "MyLambdaRequestAuth": { + "in": "header", + "type": "apiKey", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 20, + "type": "request", + "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ - "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", - "identityValidationExpression": "mycustomauthexpression" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + }, "x-amazon-apigateway-authtype": "custom" - }, - "MyLambdaRequestAuth": { - "in": "header", - "type": "apiKey", - "name": "Unused", + }, + "MyCognitoAuth": { + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", + "identityValidationExpression": "myauthvalidationexpression", + "providerARNs": [ + "arn:aws:1" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "MyLambdaTokenAuth": { + "in": "header", + "type": "apiKey", + "name": "MyCustomAuthHeader", + "x-amazon-apigateway-authorizer": { + "type": "token", + "authorizerResultTtlInSeconds": 20, "authorizerUri": { "Fn::Sub": [ - "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", + "identityValidationExpression": "mycustomauthexpression" + }, "x-amazon-apigateway-authtype": "custom" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } - }, + }, "EndpointConfiguration": { "Types": [ "REGIONAL" ] - }, + }, "Parameters": { "endpointConfigurationTypes": "REGIONAL" } } - }, + }, "MyApiMyLambdaTokenAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -363,20 +407,20 @@ ] } } - }, + }, "MyFunctionWithLambdaRequestAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -384,20 +428,20 @@ ] } } - }, + }, "MyFunctionWithLambdaRequestAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -405,30 +449,20 @@ ] } } - }, - "MyApiDeploymentf9e0be23dc": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: f9e0be23dccfaabdc2729c4d2221a3eeaa8e87db", - "StageName": "Stage" - } - }, + }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -436,16 +470,16 @@ ] } } - }, + }, "MyApiMyLambdaTokenAuthNoneFunctionInvokeRoleAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "MyApi" @@ -454,32 +488,32 @@ ] } } - }, + }, "MyApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeploymentf9e0be23dc" - }, + "Ref": "MyApiDeployment7939ed72e3" + }, "RestApiId": { "Ref": "MyApi" - }, + }, "StageName": "Prod" } - }, + }, "MyFunctionWithNoAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -487,20 +521,20 @@ ] } } - }, + }, "MyFunctionWithDefaultAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } diff --git a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json index c8187e9b8d..a4e560599a 100644 --- a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json @@ -104,15 +104,6 @@ } } }, - "MyApiDeployment26330d35c8": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: 26330d35c82ff087c8d34db2cade570f0e02910f" - } - }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -202,6 +193,9 @@ "security": [ { "NONE": [] + }, + { + "api_key": [] } ], "responses": {} @@ -219,6 +213,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -234,6 +231,9 @@ "security": [ { "MyCognitoAuthMultipleUserPools": [] + }, + { + "api_key": [] } ], "responses": {} @@ -249,6 +249,9 @@ "security": [ { "MyLambdaTokenAuthNoneFunctionInvokeRole": [] + }, + { + "api_key": [] } ], "responses": {} @@ -264,6 +267,9 @@ "security": [ { "MyLambdaRequestAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -273,19 +279,6 @@ "openapi": "3.0.1", "components": { "securitySchemes": { - "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, "MyLambdaTokenAuthNoneFunctionInvokeRole": { "in": "header", "type": "apiKey", @@ -318,13 +311,14 @@ }, "x-amazon-apigateway-authtype": "cognito_user_pools" }, - "MyLambdaTokenAuth": { + "MyLambdaRequestAuth": { "in": "header", "type": "apiKey", - "name": "MyCustomAuthHeader", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 20, + "type": "request", + "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -333,19 +327,30 @@ } ] }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", - "identityValidationExpression": "mycustomauthexpression" + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" }, "x-amazon-apigateway-authtype": "custom" }, - "MyLambdaRequestAuth": { + "MyCognitoAuth": { "in": "header", "type": "apiKey", - "name": "Unused", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", + "identityValidationExpression": "myauthvalidationexpression", + "providerARNs": [ + "arn:aws:1" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "MyLambdaTokenAuth": { + "in": "header", + "type": "apiKey", + "name": "MyCustomAuthHeader", + "x-amazon-apigateway-authorizer": { + "type": "token", + "authorizerResultTtlInSeconds": 20, "authorizerUri": { "Fn::Sub": [ "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -354,9 +359,15 @@ } ] }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", + "identityValidationExpression": "mycustomauthexpression" }, "x-amazon-apigateway-authtype": "custom" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } } @@ -470,11 +481,20 @@ } } }, + "MyApiDeploymente67481ad45": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: e67481ad4559fa2ba87f90009db679ae7d0c7c57" + } + }, "MyApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeployment26330d35c8" + "Ref": "MyApiDeploymente67481ad45" }, "RestApiId": { "Ref": "MyApi" diff --git a/tests/translator/output/aws-us-gov/globals_for_api.json b/tests/translator/output/aws-us-gov/globals_for_api.json index 138c62aedb..42b4008f31 100644 --- a/tests/translator/output/aws-us-gov/globals_for_api.json +++ b/tests/translator/output/aws-us-gov/globals_for_api.json @@ -91,6 +91,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -115,6 +118,11 @@ "type": "cognito_user_pools" }, "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } }, @@ -142,7 +150,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentc969c99f9d" + "Ref": "ServerlessRestApiDeployment6fd1928d9b" } } }, @@ -159,10 +167,20 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeploymentd5fa0145e9" + "Ref": "ExplicitApiDeployment43e01e673d" } } }, + "ExplicitApiDeployment43e01e673d": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 43e01e673d7acbd09e4c38ff78dd6ddaf2ed1d55", + "StageName": "Stage" + } + }, "ImplicitApiFunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -184,23 +202,13 @@ } } }, - "ServerlessRestApiDeploymentc969c99f9d": { + "ServerlessRestApiDeployment6fd1928d9b": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: c969c99f9d6b6921dff605a206e8989bdb7d1bc7", - "StageName": "Stage" - } - }, - "ExplicitApiDeploymentd5fa0145e9": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: d5fa0145e9e6393911d32967e66fd7091d605483", + "Description": "RestApi deployment id: 6fd1928d9b9ad3c711a371e1337306458029f8bd", "StageName": "Stage" } }, @@ -248,6 +256,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -272,6 +283,11 @@ "type": "cognito_user_pools" }, "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } }, diff --git a/tests/translator/output/aws-us-gov/implicit_api_with_auth_and_conditions_max.json b/tests/translator/output/aws-us-gov/implicit_api_with_auth_and_conditions_max.json index ee12134b50..c29ef0c3b5 100644 --- a/tests/translator/output/aws-us-gov/implicit_api_with_auth_and_conditions_max.json +++ b/tests/translator/output/aws-us-gov/implicit_api_with_auth_and_conditions_max.json @@ -4,259 +4,248 @@ "Fn::Or": [ { "Condition": "FunctionCondition" - }, + }, { "Condition": "FunctionCondition2" - }, + }, { "Condition": "FunctionCondition3" - }, + }, { "Condition": "FunctionCondition4" - }, + }, { "Condition": "FunctionCondition5" - }, + }, { "Condition": "FunctionCondition6" } ] - }, + }, "FunctionCondition6": { "Fn::Equals": [ - true, + true, false ] - }, + }, "FunctionCondition5": { "Fn::Equals": [ - true, + true, false ] - }, + }, "FunctionCondition4": { "Fn::Equals": [ - true, + true, false ] - }, + }, "FunctionCondition3": { "Fn::Equals": [ - true, + true, false ] - }, + }, "FunctionCondition2": { "Fn::Equals": [ - true, + true, false ] - }, + }, "ServerlessRestApiSLASHusersPathCondition": { "Fn::Or": [ { "Condition": "FunctionCondition2" - }, + }, { "Condition": "FunctionCondition3" - }, + }, { "Condition": "FunctionCondition4" - }, + }, { "Condition": "FunctionCondition5" - }, + }, { "Condition": "FunctionCondition6" } ] - }, + }, "FunctionCondition": { "Fn::Equals": [ - true, + true, false ] } - }, + }, "Resources": { "MyFunction4WithLambdaTokenAuthorizerPermissionTest": { - "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": "MyFunction4" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition4" - }, + }, "MyFunction4": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunction4Role", + "MyFunction4Role", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] - }, + }, "Condition": "FunctionCondition4" - }, + }, "MyFunction6": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunction6Role", + "MyFunction6Role", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] - }, + }, "Condition": "FunctionCondition6" - }, - "ServerlessRestApiDeploymentc06acce7cc": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: c06acce7cc8764dcad4cb4a7c74b2d0b43310c00", - "StageName": "Stage" - }, - "Condition": "ServerlessRestApiCondition" - }, + }, "MyFunction2WithCognitoMultipleUserPoolsAuthorizerPermissionProd": { - "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": "MyFunction2" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition2" - }, + }, "MyFunction3": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunction3Role", + "MyFunction3Role", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] - }, + }, "Condition": "FunctionCondition3" - }, + }, "MyFunction2": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunction2Role", + "MyFunction2Role", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] - }, + }, "Condition": "FunctionCondition2" - }, + }, "ServerlessRestApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentc06acce7cc" - }, + "Ref": "ServerlessRestApiDeployment91a6380656" + }, "RestApiId": { "Ref": "ServerlessRestApi" - }, + }, "StageName": "Prod" - }, + }, "Condition": "ServerlessRestApiCondition" - }, + }, "MyFunction5Role": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -265,23 +254,23 @@ } ] } - }, + }, "Condition": "FunctionCondition5" - }, + }, "MyFunction2Role": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -290,23 +279,23 @@ } ] } - }, + }, "Condition": "FunctionCondition2" - }, + }, "MyFunction4Role": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -315,69 +304,69 @@ } ] } - }, + }, "Condition": "FunctionCondition4" - }, + }, "MyFunction3WithLambdaTokenAuthorizerPermissionTest": { - "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": "MyFunction3" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition3" - }, + }, "MyFunction5": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunction5Role", + "MyFunction5Role", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] - }, + }, "Condition": "FunctionCondition5" - }, + }, "MyFunction6Role": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -386,18 +375,18 @@ } ] } - }, + }, "Condition": "FunctionCondition6" - }, + }, "ServerlessRestApiMyLambdaTokenAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "ServerlessRestApi" @@ -405,67 +394,67 @@ } ] } - }, + }, "Condition": "ServerlessRestApiCondition" - }, + }, "MyFunctionWithNoAuthorizerPermissionProd": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition" - }, + }, "MyFunction6WithDefaultAuthorizerPermissionTest": { - "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": "MyFunction6" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition6" - }, + }, "MyFunction3Role": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -474,64 +463,64 @@ } ] } - }, + }, "Condition": "FunctionCondition3" - }, + }, "MyFunction": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "sam-demo-bucket", + "S3Bucket": "sam-demo-bucket", "S3Key": "thumbnails.zip" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionRole", + "MyFunctionRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] - }, + }, "Condition": "FunctionCondition" - }, + }, "MyFunction4WithLambdaTokenAuthorizerPermissionProd": { - "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": "MyFunction4" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PATCH/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition4" - }, + }, "ServerlessRestApiMyLambdaRequestAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "ServerlessRestApi" @@ -539,40 +528,40 @@ } ] } - }, + }, "Condition": "ServerlessRestApiCondition" - }, + }, "MyFunction5WithLambdaRequestAuthorizerPermissionProd": { - "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": "MyFunction5" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition5" - }, + }, "ServerlessRestApiMyLambdaTokenAuthNoneFunctionInvokeRoleAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { "__ApiId__": { "Ref": "ServerlessRestApi" @@ -580,45 +569,45 @@ } ] } - }, + }, "Condition": "ServerlessRestApiCondition" - }, + }, "MyFunctionWithNoAuthorizerPermissionTest": { - "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": "MyFunction" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition" - }, + }, "MyFunctionRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -627,414 +616,433 @@ } ] } - }, + }, "Condition": "FunctionCondition" - }, + }, "MyFunction5WithLambdaRequestAuthorizerPermissionTest": { - "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": "MyFunction5" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition5" - }, + }, + "ServerlessRestApiDeployment91a6380656": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 91a63806562bbe4a3ad1c14c2444bc7d8d27397c", + "StageName": "Stage" + }, + "Condition": "ServerlessRestApiCondition" + }, "MyFunction3WithLambdaTokenAuthorizerPermissionProd": { - "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": "MyFunction3" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition3" - }, + }, "MyFunction6WithDefaultAuthorizerPermissionProd": { - "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": "MyFunction6" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/PUT/users", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition6" - }, + }, "ServerlessRestApi": { - "Type": "AWS::ApiGateway::RestApi", + "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { "/": { "Fn::If": [ - "FunctionCondition", + "FunctionCondition", { "get": { "Fn::If": [ - "FunctionCondition", + "FunctionCondition", { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::If": [ - "FunctionCondition", + "FunctionCondition", { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, "security": [ { "NONE": [] } - ], + ], "responses": {} - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, { "Ref": "AWS::NoValue" } ] - }, + }, "/users": { "Fn::If": [ - "ServerlessRestApiSLASHusersPathCondition", + "ServerlessRestApiSLASHusersPathCondition", { "put": { "Fn::If": [ - "FunctionCondition6", + "FunctionCondition6", { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::If": [ - "FunctionCondition6", + "FunctionCondition6", { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction6.Arn}/invocations" - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, "security": [ + { + "api_key": [] + }, { "MyCognitoAuth": [] } - ], + ], "responses": {} - }, + }, { "Ref": "AWS::NoValue" } ] - }, + }, "patch": { "Fn::If": [ - "FunctionCondition4", + "FunctionCondition4", { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::If": [ - "FunctionCondition4", + "FunctionCondition4", { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction4.Arn}/invocations" - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, "security": [ { "MyLambdaTokenAuthNoneFunctionInvokeRole": [] } - ], + ], "responses": {} - }, + }, { "Ref": "AWS::NoValue" } ] - }, + }, "post": { "Fn::If": [ - "FunctionCondition2", + "FunctionCondition2", { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::If": [ - "FunctionCondition2", + "FunctionCondition2", { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction2.Arn}/invocations" - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, "security": [ { "MyCognitoAuthMultipleUserPools": [] } - ], + ], "responses": {} - }, + }, { "Ref": "AWS::NoValue" } ] - }, + }, "get": { "Fn::If": [ - "FunctionCondition3", + "FunctionCondition3", { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::If": [ - "FunctionCondition3", + "FunctionCondition3", { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction3.Arn}/invocations" - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, "security": [ { "MyLambdaTokenAuth": [] } - ], + ], "responses": {} - }, + }, { "Ref": "AWS::NoValue" } ] - }, + }, "delete": { "Fn::If": [ - "FunctionCondition5", + "FunctionCondition5", { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::If": [ - "FunctionCondition5", + "FunctionCondition5", { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction5.Arn}/invocations" - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, "security": [ { "MyLambdaRequestAuth": [] } - ], + ], "responses": {} - }, + }, { "Ref": "AWS::NoValue" } ] } - }, + }, { "Ref": "AWS::NoValue" } ] } - }, - "swagger": "2.0", + }, + "swagger": "2.0", "securityDefinitions": { - "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, "MyLambdaTokenAuthNoneFunctionInvokeRole": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 0, + "type": "token", + "authorizerResultTtlInSeconds": 0, "authorizerUri": { "Fn::Sub": [ - "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] } - }, + }, "x-amazon-apigateway-authtype": "custom" - }, - "MyCognitoAuthMultipleUserPools": { - "in": "header", - "type": "apiKey", - "name": "MyAuthorizationHeader2", - "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression2", - "providerARNs": [ - "arn:aws:2", - "arn:aws:3" - ], - "type": "cognito_user_pools" - }, - "x-amazon-apigateway-authtype": "cognito_user_pools" - }, - "MyLambdaTokenAuth": { - "in": "header", - "type": "apiKey", - "name": "MyCustomAuthHeader", + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + }, + "MyLambdaRequestAuth": { + "in": "header", + "type": "apiKey", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", - "authorizerResultTtlInSeconds": 20, + "type": "request", + "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ - "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", - "identityValidationExpression": "mycustomauthexpression" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + }, "x-amazon-apigateway-authtype": "custom" - }, - "MyLambdaRequestAuth": { - "in": "header", - "type": "apiKey", - "name": "Unused", + }, + "MyCognitoAuth": { + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", + "identityValidationExpression": "myauthvalidationexpression", + "providerARNs": [ + "arn:aws:1" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "MyLambdaTokenAuth": { + "in": "header", + "type": "apiKey", + "name": "MyCustomAuthHeader", + "x-amazon-apigateway-authorizer": { + "type": "token", + "authorizerResultTtlInSeconds": 20, "authorizerUri": { "Fn::Sub": [ - "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", { "__FunctionArn__": "arn:aws" } ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" - }, + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access", + "identityValidationExpression": "mycustomauthexpression" + }, "x-amazon-apigateway-authtype": "custom" + }, + "MyCognitoAuthMultipleUserPools": { + "in": "header", + "type": "apiKey", + "name": "MyAuthorizationHeader2", + "x-amazon-apigateway-authorizer": { + "identityValidationExpression": "myauthvalidationexpression2", + "providerARNs": [ + "arn:aws:2", + "arn:aws:3" + ], + "type": "cognito_user_pools" + }, + "x-amazon-apigateway-authtype": "cognito_user_pools" } } - }, + }, "EndpointConfiguration": { "Types": [ "REGIONAL" ] - }, + }, "Parameters": { "endpointConfigurationTypes": "REGIONAL" } - }, + }, "Condition": "ServerlessRestApiCondition" - }, + }, "MyFunction2WithCognitoMultipleUserPoolsAuthorizerPermissionTest": { - "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": "MyFunction2" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "ServerlessRestApi" } } ] } - }, + }, "Condition": "FunctionCondition2" } } -} +} \ No newline at end of file diff --git a/tests/translator/output/globals_for_api.json b/tests/translator/output/globals_for_api.json index 13abe41971..23bbf1472d 100644 --- a/tests/translator/output/globals_for_api.json +++ b/tests/translator/output/globals_for_api.json @@ -68,6 +68,16 @@ } } }, + "ServerlessRestApiDeploymentaa32438b68": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: aa32438b68e05d3771a975585dfbc7b012672b55", + "StageName": "Stage" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -91,6 +101,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -115,6 +128,11 @@ "type": "cognito_user_pools" }, "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } }, @@ -134,20 +152,10 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentdb4b9da82a" + "Ref": "ServerlessRestApiDeploymentaa32438b68" } } }, - "ServerlessRestApiDeploymentdb4b9da82a": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: db4b9da82adc6031fcd32bf3a4954485464fc009", - "StageName": "Stage" - } - }, "ExplicitApiSomeStageStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { @@ -161,10 +169,20 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeploymentd5fa0145e9" + "Ref": "ExplicitApiDeployment43e01e673d" } } }, + "ExplicitApiDeployment43e01e673d": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 43e01e673d7acbd09e4c38ff78dd6ddaf2ed1d55", + "StageName": "Stage" + } + }, "ImplicitApiFunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -186,16 +204,6 @@ } } }, - "ExplicitApiDeploymentd5fa0145e9": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: d5fa0145e9e6393911d32967e66fd7091d605483", - "StageName": "Stage" - } - }, "MyUserPool": { "Type": "AWS::Cognito::UserPool", "Properties": { @@ -240,6 +248,9 @@ "security": [ { "MyCognitoAuth": [] + }, + { + "api_key": [] } ], "responses": {} @@ -264,6 +275,11 @@ "type": "cognito_user_pools" }, "x-amazon-apigateway-authtype": "cognito_user_pools" + }, + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" } } }, diff --git a/tests/translator/output/implicit_api_with_auth_and_conditions_max.json b/tests/translator/output/implicit_api_with_auth_and_conditions_max.json index a3e2433541..28dc23d353 100644 --- a/tests/translator/output/implicit_api_with_auth_and_conditions_max.json +++ b/tests/translator/output/implicit_api_with_auth_and_conditions_max.json @@ -223,7 +223,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymente09cc405ab" + "Ref": "ServerlessRestApiDeploymentcbc79073ff" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -282,6 +282,17 @@ }, "Condition": "FunctionCondition2" }, + "ServerlessRestApiDeploymentcbc79073ff": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: cbc79073ff900d53c3f67ea223640210914a672c", + "StageName": "Stage" + }, + "Condition": "ServerlessRestApiCondition" + }, "MyFunction4Role": { "Type": "AWS::IAM::Role", "Properties": { @@ -685,17 +696,6 @@ }, "Condition": "FunctionCondition6" }, - "ServerlessRestApiDeploymente09cc405ab": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: e09cc405abe09a0afb9e5f0cb2e94cfba98767d5", - "StageName": "Stage" - }, - "Condition": "ServerlessRestApiCondition" - }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -772,6 +772,9 @@ } }, "security": [ + { + "api_key": [] + }, { "MyCognitoAuth": [] } @@ -916,26 +919,37 @@ }, "swagger": "2.0", "securityDefinitions": { - "MyCognitoAuth": { + "MyLambdaTokenAuthNoneFunctionInvokeRole": { "in": "header", "type": "apiKey", - "name": "MyAuthorizationHeader", + "name": "Authorization", "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression", - "providerARNs": [ - "arn:aws:1" - ], - "type": "cognito_user_pools" + "type": "token", + "authorizerResultTtlInSeconds": 0, + "authorizerUri": { + "Fn::Sub": [ + "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", + { + "__FunctionArn__": "arn:aws" + } + ] + } }, - "x-amazon-apigateway-authtype": "cognito_user_pools" + "x-amazon-apigateway-authtype": "custom" }, - "MyLambdaTokenAuthNoneFunctionInvokeRole": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "header" + }, + "MyLambdaRequestAuth": { "in": "header", "type": "apiKey", - "name": "Authorization", + "name": "Unused", "x-amazon-apigateway-authorizer": { - "type": "token", + "type": "request", "authorizerResultTtlInSeconds": 0, + "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", "authorizerUri": { "Fn::Sub": [ "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", @@ -943,19 +957,19 @@ "__FunctionArn__": "arn:aws" } ] - } + }, + "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" }, "x-amazon-apigateway-authtype": "custom" }, - "MyCognitoAuthMultipleUserPools": { + "MyCognitoAuth": { "in": "header", "type": "apiKey", - "name": "MyAuthorizationHeader2", + "name": "MyAuthorizationHeader", "x-amazon-apigateway-authorizer": { - "identityValidationExpression": "myauthvalidationexpression2", + "identityValidationExpression": "myauthvalidationexpression", "providerARNs": [ - "arn:aws:2", - "arn:aws:3" + "arn:aws:1" ], "type": "cognito_user_pools" }, @@ -981,25 +995,19 @@ }, "x-amazon-apigateway-authtype": "custom" }, - "MyLambdaRequestAuth": { + "MyCognitoAuthMultipleUserPools": { "in": "header", "type": "apiKey", - "name": "Unused", + "name": "MyAuthorizationHeader2", "x-amazon-apigateway-authorizer": { - "type": "request", - "authorizerResultTtlInSeconds": 0, - "identitySource": "method.request.header.Authorization1, method.request.querystring.Authorization2, stageVariables.Authorization3, context.Authorization4", - "authorizerUri": { - "Fn::Sub": [ - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${__FunctionArn__}/invocations", - { - "__FunctionArn__": "arn:aws" - } - ] - }, - "authorizerCredentials": "arn:aws:iam::123456789012:role/S3Access" + "identityValidationExpression": "myauthvalidationexpression2", + "providerARNs": [ + "arn:aws:2", + "arn:aws:3" + ], + "type": "cognito_user_pools" }, - "x-amazon-apigateway-authtype": "custom" + "x-amazon-apigateway-authtype": "cognito_user_pools" } } } @@ -1029,4 +1037,4 @@ "Condition": "FunctionCondition2" } } -} +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index 89402cfbfd..f2c4049cef 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -260,6 +260,8 @@ class TestTranslatorEndToEnd(TestCase): 'implicit_and_explicit_api_with_conditions', 'api_with_cors_and_conditions_no_definitionbody', 'api_with_auth_and_conditions_all_max', + 'api_with_apikey_default_override', + 'api_with_apikey_required', ], [ ("aws", "ap-southeast-1"), @@ -331,7 +333,8 @@ def test_transform_success(self, testcase, partition_with_region): 'api_with_auth_all_minimum_openapi', 'api_with_swagger_and_openapi_with_auth', 'api_with_openapi_definition_body_no_flag', - 'api_request_model_openapi_3' + 'api_request_model_openapi_3', + 'api_with_apikey_required_openapi_3' ], [ ("aws", "ap-southeast-1"), diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index bab076985a..0742cc8e58 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -226,7 +226,7 @@ EndpointConfiguration | `string` | Specify the type of endpoint for API endpoint BinaryMediaTypes | List of `string` | List of MIME types that your API could return. Use this to enable binary support for APIs. Use `~1` instead of `/` in the mime types (See examples in [template.yaml](../examples/2016-10-31/implicit_api_settings/template.yaml)). MinimumCompressionSize | `int` | Allow compression of response bodies based on client's Accept-Encoding header. Compression is triggered when response body size is greater than or equal to your configured threshold. The maximum body size threshold is 10 MB (10,485,760 Bytes). The following compression types are supported: gzip, deflate, and identity. Cors | `string` or [Cors Configuration](#cors-configuration) | Enable CORS for all your APIs. Specify the domain to allow as a string or specify a dictionary with additional [Cors Configuration](#cors-configuration). NOTE: Cors requires SAM to modify your Swagger definition. Hence it works only inline swagger defined with `DefinitionBody`. -Auth | [API Auth Object](#api-auth-object) | Auth configuration for this API. Define Lambda and Cognito `Authorizers` and specify a `DefaultAuthorizer` for this API. +Auth | [API Auth Object](#api-auth-object) | Auth configuration for this API. Define Lambda and Cognito `Authorizers` and specify a `DefaultAuthorizer` for this API. Can specify default ApiKey restriction using `ApiKeyRequired`. GatewayResponses | Map of [Gateway Response Type](https://docs.aws.amazon.com/apigateway/api-reference/resource/gateway-response/) to [Gateway Response Object](#gateway-response-object) | Configures Gateway Reponses for an API. Gateway Responses are responses returned by API Gateway, either directly or through the use of Lambda Authorizers. Keys for this object are passed through to Api Gateway, so any value supported by `GatewayResponse.responseType` is supported here. AccessLogSetting | [CloudFormation AccessLogSetting property](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-stage-accesslogsetting.html) | Configures Access Log Setting for a stage. This value is passed through to CloudFormation, so any value supported by `AccessLogSetting` is supported here. CanarySetting | [CloudFormation CanarySetting property](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-stage-canarysetting.html) | Configure a Canary Setting to a Stage of a regular deployment. This value is passed through to Cloudformation, so any value supported by `CanarySetting` is supported here. @@ -527,7 +527,7 @@ Property Name | Type | Description Path | `string` | **Required.** Uri path for which this function is invoked. MUST start with `/`. Method | `string` | **Required.** HTTP method for which this function is invoked. RestApiId | `string` | Identifier of a RestApi resource which MUST contain an operation with the given path and method. Typically, this is set to [reference](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) an `AWS::Serverless::Api` resource defined in this template. If not defined, a default `AWS::Serverless::Api` resource is created using a generated Swagger document contains a union of all paths and methods defined by `Api` events defined in this template that do not specify a RestApiId. -Auth | [Function Auth Object](#function-auth-object) | Auth configuration for this specific Api+Path+Method. Useful for overriding the API's `DefaultAuthorizer` or setting auth config on an individual path when no `DefaultAuthorizer` is specified. +Auth | [Function Auth Object](#function-auth-object) | Auth configuration for this specific Api+Path+Method. Useful for overriding the API's `DefaultAuthorizer` setting auth config on an individual path when no `DefaultAuthorizer` is specified or overriding the default `ApiKeyRequired' setting. RequestModel | [Function Request Model Object](#function-request-model-object) | Request model configuration for this specific Api+Path+Method. ##### Example: Api event source object @@ -782,10 +782,14 @@ Cors: #### API Auth Object -Configure Auth on APIs. Define Lambda and Cognito `Authorizers` and specify a `DefaultAuthorizer`. If you use IAM permission, only specify `AWS_IAM` to a `DefaultAuthorizer`. For more information, see the documentation on [Lambda Authorizers](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) and [Amazon Cognito User Pool Authorizers](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html) and [IAM Permissions](https://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html). +Configure Auth on APIs. + +**Authorizers:** +Define Lambda and Cognito `Authorizers` and specify a `DefaultAuthorizer`. If you use IAM permission, only specify `AWS_IAM` to a `DefaultAuthorizer`. For more information, see the documentation on [Lambda Authorizers](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) and [Amazon Cognito User Pool Authorizers](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html) and [IAM Permissions](https://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html). ```yaml Auth: + ApiKeyRequired: true # OPTIONAL DefaultAuthorizer: MyCognitoAuth # OPTIONAL, if you use IAM permissions, specify AWS_IAM. Authorizers: MyCognitoAuth: @@ -820,6 +824,15 @@ Auth: ReauthorizeEvery: 0 # OPTIONAL; Service Default: 300 ``` +**ApiKey:** +Configure ApiKey restriction for all methods and paths on an API. This setting can be overriden on individual `AWS::Serverless::Function` using the [Function Auth Object](#function-auth-object). Typically this would be used to require ApiKey on all methods and then override it on select methods that you want to be public. + +```yaml +Auth: + ApiKeyRequired: true +``` + + #### Function Auth Object Configure Auth for a specific Api+Path+Method. @@ -836,6 +849,20 @@ Auth: Authorizer: 'NONE' ``` +Require api keys for a specific Api+Path+Method. + +```yaml +Auth: + ApiKeyRequired: true +``` + +If you have specified `ApiKeyRequired: true` globally on the API and want to make a specific Function public, override with the following: + +```yaml +Auth: + ApiKeyRequired: false +``` + #### Function Request Model Object Configure Request Model for a specific Api+Path+Method. From 275e46195a1dc97b97909bea2cdcb3ece152cb5d Mon Sep 17 00:00:00 2001 From: Eduardo Vieira Date: Fri, 5 Jul 2019 19:15:28 -0300 Subject: [PATCH 04/31] feat: Add API stage tags support (#384) (#993) --- samtranslator/model/api/api_generator.py | 8 +- samtranslator/model/apigateway.py | 3 +- samtranslator/model/sam_resources.py | 2 + tests/model/test_sam_resources.py | 34 +++++++++ .../translator/input/api_with_stage_tags.yaml | 16 ++++ .../output/api_with_stage_tags.json | 67 +++++++++++++++++ .../output/aws-cn/api_with_stage_tags.json | 75 +++++++++++++++++++ .../aws-us-gov/api_with_stage_tags.json | 75 +++++++++++++++++++ tests/translator/test_translator.py | 1 + versions/2016-10-31.md | 1 + 10 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 tests/translator/input/api_with_stage_tags.yaml create mode 100644 tests/translator/output/api_with_stage_tags.json create mode 100644 tests/translator/output/aws-cn/api_with_stage_tags.json create mode 100644 tests/translator/output/aws-us-gov/api_with_stage_tags.json diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py index 4949309d98..42cc417eb9 100644 --- a/samtranslator/model/api/api_generator.py +++ b/samtranslator/model/api/api_generator.py @@ -13,6 +13,7 @@ from samtranslator.model.intrinsics import is_instrinsic, fnSub from samtranslator.model.lambda_ import LambdaPermission from samtranslator.translator.arn_generator import ArnGenerator +from samtranslator.model.tags.resource_tagging import get_tag_list _CORS_WILDCARD = "'*'" CorsProperties = namedtuple("_CorsProperties", ["AllowMethods", "AllowHeaders", "AllowOrigin", "MaxAge", @@ -31,7 +32,7 @@ class ApiGenerator(object): def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variables, depends_on, - definition_body, definition_uri, name, stage_name, endpoint_configuration=None, + definition_body, definition_uri, name, stage_name, tags=None, endpoint_configuration=None, method_settings=None, binary_media=None, minimum_compression_size=None, cors=None, auth=None, gateway_responses=None, access_log_setting=None, canary_setting=None, tracing_enabled=None, resource_attributes=None, passthrough_resource_attributes=None, @@ -47,6 +48,7 @@ def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variab :param definition_uri: URI to API definition :param name: Name of the API Gateway resource :param stage_name: Name of the Stage + :param tags: Stage Tags :param access_log_setting: Whether to send access logs and where for Stage :param canary_setting: Canary Setting for Stage :param tracing_enabled: Whether active tracing with X-ray is enabled @@ -63,6 +65,7 @@ def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variab self.definition_uri = definition_uri self.name = name self.stage_name = stage_name + self.tags = tags self.endpoint_configuration = endpoint_configuration self.method_settings = method_settings self.binary_media = binary_media @@ -198,6 +201,9 @@ def _construct_stage(self, deployment, swagger): if swagger is not None: deployment.make_auto_deployable(stage, swagger) + if self.tags is not None: + stage.Tags = get_tag_list(self.tags) + return stage def to_cloudformation(self): diff --git a/samtranslator/model/apigateway.py b/samtranslator/model/apigateway.py index 37347ebdc6..4dac1b4493 100644 --- a/samtranslator/model/apigateway.py +++ b/samtranslator/model/apigateway.py @@ -2,7 +2,7 @@ from samtranslator.model import PropertyType, Resource from samtranslator.model.exceptions import InvalidResourceException -from samtranslator.model.types import is_type, one_of, is_str +from samtranslator.model.types import is_type, one_of, is_str, list_of from samtranslator.model.intrinsics import ref, fnSub from samtranslator.translator import logical_id_generator from samtranslator.translator.arn_generator import ArnGenerator @@ -40,6 +40,7 @@ class ApiGatewayStage(Resource): 'Description': PropertyType(False, is_str()), 'RestApiId': PropertyType(True, is_str()), 'StageName': PropertyType(True, one_of(is_str(), is_type(dict))), + 'Tags': PropertyType(False, list_of(is_type(dict))), 'TracingEnabled': PropertyType(False, is_type(bool)), 'Variables': PropertyType(False, is_type(dict)), "MethodSettings": PropertyType(False, is_type(list)) diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py index 5f251ecefe..df8a62925d 100644 --- a/samtranslator/model/sam_resources.py +++ b/samtranslator/model/sam_resources.py @@ -440,6 +440,7 @@ class SamApi(SamResourceMacro): 'Name': PropertyType(False, one_of(is_str(), is_type(dict))), 'StageName': PropertyType(True, one_of(is_str(), is_type(dict))), + 'Tags': PropertyType(False, is_type(dict)), 'DefinitionBody': PropertyType(False, is_type(dict)), 'DefinitionUri': PropertyType(False, one_of(is_str(), is_type(dict))), 'CacheClusterEnabled': PropertyType(False, is_type(bool)), @@ -483,6 +484,7 @@ def to_cloudformation(self, **kwargs): self.DefinitionUri, self.Name, self.StageName, + tags=self.Tags, endpoint_configuration=self.EndpointConfiguration, method_settings=self.MethodSettings, binary_media=self.BinaryMediaTypes, diff --git a/tests/model/test_sam_resources.py b/tests/model/test_sam_resources.py index ff59a063e7..c38ce1a7bf 100644 --- a/tests/model/test_sam_resources.py +++ b/tests/model/test_sam_resources.py @@ -7,6 +7,7 @@ from samtranslator.model.lambda_ import LambdaFunction, LambdaVersion from samtranslator.model.apigateway import ApiGatewayRestApi from samtranslator.model.apigateway import ApiGatewayDeployment +from samtranslator.model.apigateway import ApiGatewayStage from samtranslator.model.sam_resources import SamFunction from samtranslator.model.sam_resources import SamApi @@ -121,3 +122,36 @@ def test_with_swagger_no_stage(self): self.assertEqual(deployment.__len__(), 1) self.assertEqual(deployment[0].StageName, "Stage") + +class TestApiTags(TestCase): + kwargs = { + 'intrinsics_resolver': IntrinsicsResolver({}), + 'event_resources': [], + 'managed_policy_map': { + "foo": "bar" + } + } + + def test_with_no_tags(self): + api = SamApi("foo") + api.Tags = {} + + resources = api.to_cloudformation(**self.kwargs) + deployment = [x for x in resources if isinstance(x, ApiGatewayStage)] + + self.assertEqual(deployment.__len__(), 1) + self.assertEqual(deployment[0].Tags, []) + + def test_with_tags(self): + api = SamApi("foo") + api.Tags = { + 'MyKey': 'MyValue' + } + + resources = api.to_cloudformation(**self.kwargs) + deployment = [x for x in resources if isinstance(x, ApiGatewayStage)] + + self.assertEqual(deployment.__len__(), 1) + self.assertEqual(deployment[0].Tags, [ + {'Key': 'MyKey', 'Value': 'MyValue'} + ]) diff --git a/tests/translator/input/api_with_stage_tags.yaml b/tests/translator/input/api_with_stage_tags.yaml new file mode 100644 index 0000000000..83473e1163 --- /dev/null +++ b/tests/translator/input/api_with_stage_tags.yaml @@ -0,0 +1,16 @@ +Parameters: + TagValueParam: + Type: String + Default: value + +Resources: + MyApiWithStageTags: + Type: "AWS::Serverless::Api" + Properties: + StageName: Prod + Tags: + TagKey1: TagValue1 + TagKey2: "" + TagKey3: + Ref: TagValueParam + TagKey4: "123" diff --git a/tests/translator/output/api_with_stage_tags.json b/tests/translator/output/api_with_stage_tags.json new file mode 100644 index 0000000000..702a6b1815 --- /dev/null +++ b/tests/translator/output/api_with_stage_tags.json @@ -0,0 +1,67 @@ +{ + "Parameters": { + "TagValueParam": { + "Default": "value", + "Type": "String" + } + }, + "Resources": { + "MyApiWithStageTagsDeployment5332c373d4": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithStageTags" + }, + "Description": "RestApi deployment id: 5332c373d45c69e6c0f562b4a419aa8eb311adc7", + "StageName": "Stage" + } + }, + "MyApiWithStageTags": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0" + } + } + }, + "MyApiWithStageTagsProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithStageTagsDeployment5332c373d4" + }, + "RestApiId": { + "Ref": "MyApiWithStageTags" + }, + "StageName": "Prod", + "Tags": [ + { + "Value": "TagValue1", + "Key": "TagKey1" + }, + { + "Value": "", + "Key": "TagKey2" + }, + { + "Value": { + "Ref": "TagValueParam" + }, + "Key": "TagKey3" + }, + { + "Value": "123", + "Key": "TagKey4" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_stage_tags.json b/tests/translator/output/aws-cn/api_with_stage_tags.json new file mode 100644 index 0000000000..1e99128862 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_stage_tags.json @@ -0,0 +1,75 @@ +{ + "Parameters": { + "TagValueParam": { + "Default": "value", + "Type": "String" + } + }, + "Resources": { + "MyApiWithStageTagsDeployment5332c373d4": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithStageTags" + }, + "Description": "RestApi deployment id: 5332c373d45c69e6c0f562b4a419aa8eb311adc7", + "StageName": "Stage" + } + }, + "MyApiWithStageTags": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "MyApiWithStageTagsProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithStageTagsDeployment5332c373d4" + }, + "RestApiId": { + "Ref": "MyApiWithStageTags" + }, + "StageName": "Prod", + "Tags": [ + { + "Value": "TagValue1", + "Key": "TagKey1" + }, + { + "Value": "", + "Key": "TagKey2" + }, + { + "Value": { + "Ref": "TagValueParam" + }, + "Key": "TagKey3" + }, + { + "Value": "123", + "Key": "TagKey4" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_stage_tags.json b/tests/translator/output/aws-us-gov/api_with_stage_tags.json new file mode 100644 index 0000000000..1e99128862 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_stage_tags.json @@ -0,0 +1,75 @@ +{ + "Parameters": { + "TagValueParam": { + "Default": "value", + "Type": "String" + } + }, + "Resources": { + "MyApiWithStageTagsDeployment5332c373d4": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithStageTags" + }, + "Description": "RestApi deployment id: 5332c373d45c69e6c0f562b4a419aa8eb311adc7", + "StageName": "Stage" + } + }, + "MyApiWithStageTags": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "MyApiWithStageTagsProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithStageTagsDeployment5332c373d4" + }, + "RestApiId": { + "Ref": "MyApiWithStageTags" + }, + "StageName": "Prod", + "Tags": [ + { + "Value": "TagValue1", + "Key": "TagKey1" + }, + { + "Value": "", + "Key": "TagKey2" + }, + { + "Value": { + "Ref": "TagValueParam" + }, + "Key": "TagKey3" + }, + { + "Value": "123", + "Key": "TagKey4" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index f2c4049cef..e536803cee 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -201,6 +201,7 @@ class TestTranslatorEndToEnd(TestCase): 'api_with_canary_setting', 'api_with_xray_tracing', 'api_request_model', + 'api_with_stage_tags', 's3', 's3_create_remove', 's3_existing_lambda_notification_configuration', diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 0742cc8e58..71ee4d03bb 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -222,6 +222,7 @@ CacheClusterEnabled | `boolean` | Indicates whether cache clustering is enabled CacheClusterSize | `string` | The stage's cache cluster size. Variables | Map of `string` to `string` | A map (string to string map) that defines the stage variables, where the variable name is the key and the variable value is the value. Variable names are limited to alphanumeric characters. Values must match the following regular expression: `[A-Za-z0-9._~:/?#&=,-]+`. MethodSettings | [CloudFormation MethodSettings property](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-stage-methodsetting.html) | Configures all settings for API stage including Logging, Metrics, CacheTTL, Throttling. This value is passed through to CloudFormation. So any values supported by CloudFormation ``MethodSettings`` property can be used here. +Tags | Map of `string` to `string` | A map (string to string) that specifies the tags to be added to this API Stage. Keys and values are limited to alphanumeric characters. EndpointConfiguration | `string` | Specify the type of endpoint for API endpoint. Value is either `REGIONAL`, `EDGE`, or `PRIVATE`. BinaryMediaTypes | List of `string` | List of MIME types that your API could return. Use this to enable binary support for APIs. Use `~1` instead of `/` in the mime types (See examples in [template.yaml](../examples/2016-10-31/implicit_api_settings/template.yaml)). MinimumCompressionSize | `int` | Allow compression of response bodies based on client's Accept-Encoding header. Compression is triggered when response body size is greater than or equal to your configured threshold. The maximum body size threshold is 10 MB (10,485,760 Bytes). The following compression types are supported: gzip, deflate, and identity. From 1e39662995acb36592fcf12745ecf5ad9f686268 Mon Sep 17 00:00:00 2001 From: gomi_ningen Date: Tue, 16 Jul 2019 08:53:51 +0900 Subject: [PATCH 05/31] docs: update to_cloudformation functions of PushEventSource class docstrings (#1018) --- samtranslator/model/eventsources/push.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samtranslator/model/eventsources/push.py b/samtranslator/model/eventsources/push.py index 5fa9863015..0162bb7c83 100644 --- a/samtranslator/model/eventsources/push.py +++ b/samtranslator/model/eventsources/push.py @@ -79,7 +79,7 @@ def to_cloudformation(self, **kwargs): """Returns the CloudWatch Events Rule and Lambda Permission to which this Schedule event source corresponds. :param dict kwargs: no existing resources need to be modified - :returns: a list of vanilla CloudFormation Resources, to which this pull event expands + :returns: a list of vanilla CloudFormation Resources, to which this Schedule event expands :rtype: list """ function = kwargs.get('function') @@ -133,7 +133,7 @@ def to_cloudformation(self, **kwargs): corresponds. :param dict kwargs: no existing resources need to be modified - :returns: a list of vanilla CloudFormation Resources, to which this pull event expands + :returns: a list of vanilla CloudFormation Resources, to which this CloudWatch Events event expands :rtype: list """ function = kwargs.get('function') From d9b04f3abfc1698f50ff08de1c7971379c2a65cb Mon Sep 17 00:00:00 2001 From: Jan Alfred Richter Date: Tue, 16 Jul 2019 12:19:35 +1200 Subject: [PATCH 06/31] docs: add all event types to documentation (#996) --- versions/2016-10-31.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 71ee4d03bb..56bb1f3107 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -658,7 +658,7 @@ The object describing the source of events which trigger the function. Property Name | Type | Description ---|:---:|--- -Type | `string` | **Required.** Event type. Event source types include '[S3](#s3), '[Api](#api)', '[SNS](#sns)', '[Kinesis](#kinesis)', '[DynamoDB](#dynamodb)'. For more information about all types, see [Event source types](#event-source-types). +Type | `string` | **Required.** Event type. Event source types include '[S3](#s3), '[SNS](#sns)', '[Kinesis](#kinesis)', '[DynamoDB](#dynamodb)', '[SQS](#sqs)', '[Api](#api)', '[Schedule](#schedule)', '[CloudWatchEvent](#cloudwatchevent)', '[CloudWatchLogs](#cloudwatchlogs)', '[IoTRule](#iotrule)', '[AlexaSkill](#alexaskill)'. For more information about the types, see [Event source types](#event-source-types). Properties | * | **Required.** Object describing properties of this event mapping. Must conform to the defined `Type`. For more information about all types, see [Event source types](#event-source-types). ##### Example: Event source object From 3e9e5c48d10074a6d00a9a21914f2e28149443b0 Mon Sep 17 00:00:00 2001 From: KIDANI Akito Date: Wed, 17 Jul 2019 02:02:36 +0900 Subject: [PATCH 07/31] docs: add missing backslash to bash commands (#1023) --- HOWTO.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HOWTO.md b/HOWTO.md index aca0e2e4a7..26b9802dec 100644 --- a/HOWTO.md +++ b/HOWTO.md @@ -53,7 +53,7 @@ packaged template that can be readily deployed to CloudFormation. $ aws cloudformation package \ --template-file /path_to_template/template.yaml \ --s3-bucket bucket-name \ - --s3-prefix appname/branchname/version + --s3-prefix appname/branchname/version \ --output-template-file packaged-template.yaml ``` @@ -63,7 +63,7 @@ Or using the aws-sam-cli $ sam package \ --template-file /path_to_template/template.yaml \ --s3-bucket bucket-name \ - --s3-prefix appname/branchname/version + --s3-prefix appname/branchname/version \ --output-template-file packaged-template.yaml ``` @@ -104,7 +104,7 @@ Or using aws-sam-cli ```bash $ sam deploy \ --template-file /path_to_template/packaged-template.yaml \ - --stack-name my-new-stack + --stack-name my-new-stack \ --capabilities CAPABILITY_IAM ``` From cd05bab23ca4885694d2b5ff087f76ebd7b41f8b Mon Sep 17 00:00:00 2001 From: Gaurav Date: Wed, 17 Jul 2019 05:04:41 +1200 Subject: [PATCH 08/31] feat: add es:ESHttpPut in ElasticsearchHttpPostPolicy (#1011) --- samtranslator/policy_templates_data/policy_templates.json | 5 +++-- tests/translator/output/all_policy_templates.json | 3 ++- tests/translator/output/aws-cn/all_policy_templates.json | 3 ++- tests/translator/output/aws-us-gov/all_policy_templates.json | 3 ++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/samtranslator/policy_templates_data/policy_templates.json b/samtranslator/policy_templates_data/policy_templates.json index 1e424c6591..4b3dc28e69 100644 --- a/samtranslator/policy_templates_data/policy_templates.json +++ b/samtranslator/policy_templates_data/policy_templates.json @@ -246,7 +246,7 @@ } }, "ElasticsearchHttpPostPolicy": { - "Description": "Gives POST permissions to Elasticsearch", + "Description": "Gives POST and PUT permissions to Elasticsearch", "Parameters": { "DomainName": { "Description": "Name of Domain" @@ -257,7 +257,8 @@ { "Effect": "Allow", "Action": [ - "es:ESHttpPost" + "es:ESHttpPost", + "es:ESHttpPut" ], "Resource": { "Fn::Sub": [ diff --git a/tests/translator/output/all_policy_templates.json b/tests/translator/output/all_policy_templates.json index 520267a5d2..9690d5bc6e 100644 --- a/tests/translator/output/all_policy_templates.json +++ b/tests/translator/output/all_policy_templates.json @@ -208,7 +208,8 @@ "Statement": [ { "Action": [ - "es:ESHttpPost" + "es:ESHttpPost", + "es:ESHttpPut" ], "Resource": { "Fn::Sub": [ diff --git a/tests/translator/output/aws-cn/all_policy_templates.json b/tests/translator/output/aws-cn/all_policy_templates.json index 3216366b8a..6b8be0e273 100644 --- a/tests/translator/output/aws-cn/all_policy_templates.json +++ b/tests/translator/output/aws-cn/all_policy_templates.json @@ -207,7 +207,8 @@ "Statement": [ { "Action": [ - "es:ESHttpPost" + "es:ESHttpPost", + "es:ESHttpPut" ], "Resource": { "Fn::Sub": [ 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 661c731218..87621eb9dc 100644 --- a/tests/translator/output/aws-us-gov/all_policy_templates.json +++ b/tests/translator/output/aws-us-gov/all_policy_templates.json @@ -207,7 +207,8 @@ "Statement": [ { "Action": [ - "es:ESHttpPost" + "es:ESHttpPost", + "es:ESHttpPut" ], "Resource": { "Fn::Sub": [ From 33572b30456cd7df515991ebe402652694a88099 Mon Sep 17 00:00:00 2001 From: Sam Battalio Date: Tue, 16 Jul 2019 16:27:14 -0400 Subject: [PATCH 09/31] feat: add additional properties for Cloudwatch Schedule - Enabled, Name, Description (#1006) --- docs/cloudformation_compatibility.rst | 3 + samtranslator/model/eventsources/push.py | 9 +- .../validator/sam_schema/schema.json | 11 +- .../cloudwatchevent_schedule_properties.yaml | 30 +++ .../output/aws-cn/cloudwatchevent.json | 4 +- .../cloudwatchevent_schedule_properties.json | 175 ++++++++++++++++++ .../output/aws-us-gov/cloudwatchevent.json | 4 +- .../cloudwatchevent_schedule_properties.json | 175 ++++++++++++++++++ tests/translator/output/cloudwatchevent.json | 4 +- .../cloudwatchevent_schedule_properties.json | 175 ++++++++++++++++++ tests/translator/test_translator.py | 1 + versions/2016-10-31.md | 6 + 12 files changed, 589 insertions(+), 8 deletions(-) create mode 100644 tests/translator/input/cloudwatchevent_schedule_properties.yaml create mode 100644 tests/translator/output/aws-cn/cloudwatchevent_schedule_properties.json create mode 100644 tests/translator/output/aws-us-gov/cloudwatchevent_schedule_properties.json create mode 100644 tests/translator/output/cloudwatchevent_schedule_properties.json diff --git a/docs/cloudformation_compatibility.rst b/docs/cloudformation_compatibility.rst index 9118c33955..a89430e705 100644 --- a/docs/cloudformation_compatibility.rst +++ b/docs/cloudformation_compatibility.rst @@ -125,6 +125,9 @@ Schedule ======================== ================================== ======================== Schedule All Input All +Name All +Description All +Enabled All ======================== ================================== ======================== CloudWatchEvent diff --git a/samtranslator/model/eventsources/push.py b/samtranslator/model/eventsources/push.py index 0162bb7c83..17aa68f384 100644 --- a/samtranslator/model/eventsources/push.py +++ b/samtranslator/model/eventsources/push.py @@ -72,7 +72,10 @@ class Schedule(PushEventSource): principal = 'events.amazonaws.com' property_types = { 'Schedule': PropertyType(True, is_str()), - 'Input': PropertyType(False, is_str()) + 'Input': PropertyType(False, is_str()), + 'Enabled': PropertyType(False, is_type(bool)), + 'Name': PropertyType(False, is_str()), + 'Description': PropertyType(False, is_str()) } def to_cloudformation(self, **kwargs): @@ -93,6 +96,10 @@ def to_cloudformation(self, **kwargs): resources.append(events_rule) events_rule.ScheduleExpression = self.Schedule + if self.Enabled is not None: + events_rule.State = "ENABLED" if self.Enabled else "DISABLED" + events_rule.Name = self.Name + events_rule.Description = self.Description events_rule.Targets = [self._construct_target(function)] source_arn = events_rule.get_runtime_attr("arn") diff --git a/samtranslator/validator/sam_schema/schema.json b/samtranslator/validator/sam_schema/schema.json index 98046249f4..082c633d13 100644 --- a/samtranslator/validator/sam_schema/schema.json +++ b/samtranslator/validator/sam_schema/schema.json @@ -652,7 +652,16 @@ }, "Schedule": { "type": "string" - } + }, + "Name": { + "type": "string" + }, + "Description": { + "type": "string" + }, + "Enabled": { + "type": "boolean" + } }, "required": [ "Schedule" diff --git a/tests/translator/input/cloudwatchevent_schedule_properties.yaml b/tests/translator/input/cloudwatchevent_schedule_properties.yaml new file mode 100644 index 0000000000..72a6120347 --- /dev/null +++ b/tests/translator/input/cloudwatchevent_schedule_properties.yaml @@ -0,0 +1,30 @@ +Resources: + ScheduledFunction: + Type: 'AWS::Serverless::Function' + Properties: + CodeUri: s3://sam-demo-bucket/hello.zip?versionId=3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO + Handler: hello.handler + Runtime: python2.7 + Events: + Schedule: + Type: Schedule + Properties: + Schedule: 'rate(1 minute)' + Name: test-schedule + Description: Test Schedule + Enabled: True + + TriggeredFunction: + Type: 'AWS::Serverless::Function' + Properties: + CodeUri: s3://sam-demo-bucket/hello.zip?versionId=3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO + Handler: hello.handler + Runtime: python2.7 + Events: + OnTerminate: + Type: CloudWatchEvent + Properties: + Pattern: + detail: + state: + - terminated diff --git a/tests/translator/output/aws-cn/cloudwatchevent.json b/tests/translator/output/aws-cn/cloudwatchevent.json index e7b0bd8f3f..64003f5575 100644 --- a/tests/translator/output/aws-cn/cloudwatchevent.json +++ b/tests/translator/output/aws-cn/cloudwatchevent.json @@ -154,7 +154,7 @@ "ScheduledFunctionSchedule": { "Type": "AWS::Events::Rule", "Properties": { - "ScheduleExpression": "rate(1 minute)", + "ScheduleExpression": "rate(1 minute)", "Targets": [ { "Id": "ScheduledFunctionScheduleLambdaTarget", @@ -169,4 +169,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-cn/cloudwatchevent_schedule_properties.json b/tests/translator/output/aws-cn/cloudwatchevent_schedule_properties.json new file mode 100644 index 0000000000..c947e4bc21 --- /dev/null +++ b/tests/translator/output/aws-cn/cloudwatchevent_schedule_properties.json @@ -0,0 +1,175 @@ +{ + "Resources": { + "ScheduledFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "TriggeredFunctionOnTerminatePermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "events.amazonaws.com", + "FunctionName": { + "Ref": "TriggeredFunction" + }, + "SourceArn": { + "Fn::GetAtt": [ + "TriggeredFunctionOnTerminate", + "Arn" + ] + } + } + }, + "ScheduledFunctionSchedulePermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "events.amazonaws.com", + "FunctionName": { + "Ref": "ScheduledFunction" + }, + "SourceArn": { + "Fn::GetAtt": [ + "ScheduledFunctionSchedule", + "Arn" + ] + } + } + }, + "ScheduledFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip", + "S3ObjectVersion": "3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "ScheduledFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "TriggeredFunctionOnTerminate": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventPattern": { + "detail": { + "state": [ + "terminated" + ] + } + }, + "Targets": [ + { + "Id": "TriggeredFunctionOnTerminateLambdaTarget", + "Arn": { + "Fn::GetAtt": [ + "TriggeredFunction", + "Arn" + ] + } + } + ] + } + }, + "TriggeredFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip", + "S3ObjectVersion": "3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "TriggeredFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "TriggeredFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "ScheduledFunctionSchedule": { + "Type": "AWS::Events::Rule", + "Properties": { + "ScheduleExpression": "rate(1 minute)", + "Name": "test-schedule", + "Description": "Test Schedule", + "State": "ENABLED", + "Targets": [ + { + "Id": "ScheduledFunctionScheduleLambdaTarget", + "Arn": { + "Fn::GetAtt": [ + "ScheduledFunction", + "Arn" + ] + } + } + ] + } + } + } +} diff --git a/tests/translator/output/aws-us-gov/cloudwatchevent.json b/tests/translator/output/aws-us-gov/cloudwatchevent.json index cec52175ae..75979c84b6 100644 --- a/tests/translator/output/aws-us-gov/cloudwatchevent.json +++ b/tests/translator/output/aws-us-gov/cloudwatchevent.json @@ -154,7 +154,7 @@ "ScheduledFunctionSchedule": { "Type": "AWS::Events::Rule", "Properties": { - "ScheduleExpression": "rate(1 minute)", + "ScheduleExpression": "rate(1 minute)", "Targets": [ { "Id": "ScheduledFunctionScheduleLambdaTarget", @@ -169,4 +169,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-us-gov/cloudwatchevent_schedule_properties.json b/tests/translator/output/aws-us-gov/cloudwatchevent_schedule_properties.json new file mode 100644 index 0000000000..3913b5c724 --- /dev/null +++ b/tests/translator/output/aws-us-gov/cloudwatchevent_schedule_properties.json @@ -0,0 +1,175 @@ +{ + "Resources": { + "ScheduledFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "TriggeredFunctionOnTerminatePermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "events.amazonaws.com", + "FunctionName": { + "Ref": "TriggeredFunction" + }, + "SourceArn": { + "Fn::GetAtt": [ + "TriggeredFunctionOnTerminate", + "Arn" + ] + } + } + }, + "ScheduledFunctionSchedulePermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "events.amazonaws.com", + "FunctionName": { + "Ref": "ScheduledFunction" + }, + "SourceArn": { + "Fn::GetAtt": [ + "ScheduledFunctionSchedule", + "Arn" + ] + } + } + }, + "ScheduledFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip", + "S3ObjectVersion": "3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "ScheduledFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "TriggeredFunctionOnTerminate": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventPattern": { + "detail": { + "state": [ + "terminated" + ] + } + }, + "Targets": [ + { + "Id": "TriggeredFunctionOnTerminateLambdaTarget", + "Arn": { + "Fn::GetAtt": [ + "TriggeredFunction", + "Arn" + ] + } + } + ] + } + }, + "TriggeredFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip", + "S3ObjectVersion": "3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "TriggeredFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "TriggeredFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "ScheduledFunctionSchedule": { + "Type": "AWS::Events::Rule", + "Properties": { + "ScheduleExpression": "rate(1 minute)", + "Name": "test-schedule", + "Description": "Test Schedule", + "State": "ENABLED", + "Targets": [ + { + "Id": "ScheduledFunctionScheduleLambdaTarget", + "Arn": { + "Fn::GetAtt": [ + "ScheduledFunction", + "Arn" + ] + } + } + ] + } + } + } +} diff --git a/tests/translator/output/cloudwatchevent.json b/tests/translator/output/cloudwatchevent.json index afe566a039..53b58bb37c 100644 --- a/tests/translator/output/cloudwatchevent.json +++ b/tests/translator/output/cloudwatchevent.json @@ -154,7 +154,7 @@ "ScheduledFunctionSchedule": { "Type": "AWS::Events::Rule", "Properties": { - "ScheduleExpression": "rate(1 minute)", + "ScheduleExpression": "rate(1 minute)", "Targets": [ { "Id": "ScheduledFunctionScheduleLambdaTarget", @@ -169,4 +169,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/cloudwatchevent_schedule_properties.json b/tests/translator/output/cloudwatchevent_schedule_properties.json new file mode 100644 index 0000000000..5737fa5e69 --- /dev/null +++ b/tests/translator/output/cloudwatchevent_schedule_properties.json @@ -0,0 +1,175 @@ +{ + "Resources": { + "ScheduledFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "TriggeredFunctionOnTerminatePermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "events.amazonaws.com", + "FunctionName": { + "Ref": "TriggeredFunction" + }, + "SourceArn": { + "Fn::GetAtt": [ + "TriggeredFunctionOnTerminate", + "Arn" + ] + } + } + }, + "ScheduledFunctionSchedulePermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "events.amazonaws.com", + "FunctionName": { + "Ref": "ScheduledFunction" + }, + "SourceArn": { + "Fn::GetAtt": [ + "ScheduledFunctionSchedule", + "Arn" + ] + } + } + }, + "ScheduledFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip", + "S3ObjectVersion": "3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "ScheduledFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "TriggeredFunctionOnTerminate": { + "Type": "AWS::Events::Rule", + "Properties": { + "EventPattern": { + "detail": { + "state": [ + "terminated" + ] + } + }, + "Targets": [ + { + "Id": "TriggeredFunctionOnTerminateLambdaTarget", + "Arn": { + "Fn::GetAtt": [ + "TriggeredFunction", + "Arn" + ] + } + } + ] + } + }, + "TriggeredFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip", + "S3ObjectVersion": "3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "TriggeredFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "TriggeredFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "ScheduledFunctionSchedule": { + "Type": "AWS::Events::Rule", + "Properties": { + "ScheduleExpression": "rate(1 minute)", + "Name": "test-schedule", + "Description": "Test Schedule", + "State": "ENABLED", + "Targets": [ + { + "Id": "ScheduledFunctionScheduleLambdaTarget", + "Arn": { + "Fn::GetAtt": [ + "ScheduledFunction", + "Arn" + ] + } + } + ] + } + } + } +} diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index e536803cee..a84ea5cb14 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -162,6 +162,7 @@ class TestTranslatorEndToEnd(TestCase): 'application_with_intrinsics', 'basic_layer', 'cloudwatchevent', + 'cloudwatchevent_schedule_properties', 'cloudwatch_logs_with_ref', 'cloudwatchlog', 'streams', diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 56bb1f3107..322f9a3ecb 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -550,6 +550,9 @@ Property Name | Type | Description ---|:---:|--- Schedule | `string` | **Required.** Schedule expression, which MUST follow the [schedule expression syntax rules](http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html). Input | `string` | JSON-formatted string to pass to the function as the event body. +Name | `string` | A name for the Schedule. If you don't specify a name, a unique name will be generated. +Description | `string` | Description of Schedule. +Enabled | `boolean` | Indicated whether the Schedule is enabled. ##### Example: Schedule event source object @@ -557,6 +560,9 @@ Input | `string` | JSON-formatted string to pass to the function as the event bo Type: Schedule Properties: Schedule: rate(5 minutes) + Name: my-schedule + Description: Example schedule + Enabled: True ``` #### CloudWatchEvent From 4564732e07f41c1a3364abb653d6c5ea39d71f94 Mon Sep 17 00:00:00 2001 From: Brett Andrews Date: Fri, 19 Jul 2019 10:59:32 -0700 Subject: [PATCH 10/31] docs: fix MethodSettings CloudFormation link (#1027) --- versions/2016-10-31.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 322f9a3ecb..acad2a0435 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -221,7 +221,7 @@ DefinitionBody | `JSON or YAML Object` | Swagger specification that describes yo CacheClusterEnabled | `boolean` | Indicates whether cache clustering is enabled for the stage. CacheClusterSize | `string` | The stage's cache cluster size. Variables | Map of `string` to `string` | A map (string to string map) that defines the stage variables, where the variable name is the key and the variable value is the value. Variable names are limited to alphanumeric characters. Values must match the following regular expression: `[A-Za-z0-9._~:/?#&=,-]+`. -MethodSettings | [CloudFormation MethodSettings property](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-stage-methodsetting.html) | Configures all settings for API stage including Logging, Metrics, CacheTTL, Throttling. This value is passed through to CloudFormation. So any values supported by CloudFormation ``MethodSettings`` property can be used here. +MethodSettings | [CloudFormation MethodSettings property](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apitgateway-stage-methodsetting.html) | Configures all settings for API stage including Logging, Metrics, CacheTTL, Throttling. This value is passed through to CloudFormation. So any values supported by CloudFormation ``MethodSettings`` property can be used here. Tags | Map of `string` to `string` | A map (string to string) that specifies the tags to be added to this API Stage. Keys and values are limited to alphanumeric characters. EndpointConfiguration | `string` | Specify the type of endpoint for API endpoint. Value is either `REGIONAL`, `EDGE`, or `PRIVATE`. BinaryMediaTypes | List of `string` | List of MIME types that your API could return. Use this to enable binary support for APIs. Use `~1` instead of `/` in the mime types (See examples in [template.yaml](../examples/2016-10-31/implicit_api_settings/template.yaml)). From aa8b3f373633c3c8a303a3a5703e8bbab4976ebd Mon Sep 17 00:00:00 2001 From: easydonny Date: Tue, 23 Jul 2019 13:14:37 -0400 Subject: [PATCH 11/31] docs: unindent line 36 in example app (#1031) --- .../apps/microservice-http-endpoint-python3/lambda_function.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/apps/microservice-http-endpoint-python3/lambda_function.py b/examples/apps/microservice-http-endpoint-python3/lambda_function.py index 838fd389d0..b00a29872e 100644 --- a/examples/apps/microservice-http-endpoint-python3/lambda_function.py +++ b/examples/apps/microservice-http-endpoint-python3/lambda_function.py @@ -33,7 +33,7 @@ def lambda_handler(event, context): operations = { 'DELETE': lambda dynamo, x: dynamo.delete_item(TableName=table_name, **x), - 'GET': lambda dynamo, x: dynamo.scan(TableName=table_name, **x) if x else dynamo.scan(TableName=table_name), + 'GET': lambda dynamo, x: dynamo.scan(TableName=table_name, **x) if x else dynamo.scan(TableName=table_name), 'POST': lambda dynamo, x: dynamo.put_item(TableName=table_name, **x), 'PUT': lambda dynamo, x: dynamo.update_item(TableName=table_name, **x), } From cb9a42f2cb5043703cc7df0b2c50ee9edef90bdc Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Wed, 24 Jul 2019 01:20:46 +0800 Subject: [PATCH 12/31] chore: refine requirements/dev.txt (#998) * py is a dependency of pytest, and apparently it's not imported directly in this project * requests is used in examples only --- requirements/dev.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 1fe5d9f99e..4ec433f415 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -7,11 +7,12 @@ pyyaml>=4.2b1 # Test requirements pytest>=3.0.7 -py>=1.4.33 mock>=2.0.0 parameterized>=0.6.1 -requests>=2.20.0 cfn-lint>=0.18.1 +# Requirements for examples +requests>=2.20.0 + # CLI requirements docopt>=0.6.2 From 07128374a0a424d9ba443bf5fb6f108cc9daa81b Mon Sep 17 00:00:00 2001 From: Keeton Hodgson Date: Tue, 23 Jul 2019 10:48:21 -0700 Subject: [PATCH 13/31] docs: added helpful comments in 2016-10-31.md (#1024) --- versions/2016-10-31.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index acad2a0435..988e91af66 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -196,7 +196,7 @@ Events: PhotoUpload: Type: S3 Properties: - Bucket: my-photo-bucket + Bucket: my-photo-bucket # bucket must be created in the same template Tags: AppNameTag: ThumbnailApp DepartmentNameTag: ThumbnailDepartment @@ -409,7 +409,7 @@ NOTE: To specify an S3 bucket as an event source for a Lambda function, both res ```yaml Type: S3 Properties: - Bucket: my-photo-bucket + Bucket: my-photo-bucket # bucket must be created in the same template Events: s3:ObjectCreated:* Filter: S3Key: @@ -672,7 +672,7 @@ Properties | * | **Required.** Object describing properties of this event mappin ```yaml Type: S3 Properties: - Bucket: my-photo-bucket + Bucket: my-photo-bucket # bucket must be created in the same template ``` ```yaml From 990c7f69a919eaede24934f2fb25a437973f3af5 Mon Sep 17 00:00:00 2001 From: Keeton Hodgson Date: Fri, 26 Jul 2019 09:49:22 -0700 Subject: [PATCH 14/31] fix: allow setting InvokeRole to NONE or null (#986) --- .../2016-10-31/api_aws_iam_auth/template.yaml | 2 +- samtranslator/swagger/swagger.py | 14 +- .../api_with_aws_iam_auth_overrides.yaml | 68 ++ .../api_with_aws_iam_auth_overrides.json | 913 ++++++++++++----- .../api_with_aws_iam_auth_overrides.json | 921 +++++++++++++----- .../api_with_aws_iam_auth_overrides.json | 921 +++++++++++++----- versions/2016-10-31.md | 3 + 7 files changed, 2172 insertions(+), 670 deletions(-) diff --git a/examples/2016-10-31/api_aws_iam_auth/template.yaml b/examples/2016-10-31/api_aws_iam_auth/template.yaml index 935e45c71b..56551333de 100644 --- a/examples/2016-10-31/api_aws_iam_auth/template.yaml +++ b/examples/2016-10-31/api_aws_iam_auth/template.yaml @@ -8,7 +8,7 @@ Resources: StageName: Prod Auth: DefaultAuthorizer: AWS_IAM - InvokeRole: CALLER_CREDENTIALS + InvokeRole: CALLER_CREDENTIALS # default, can specify other role or NONE MyFunction: Type: AWS::Serverless::Function diff --git a/samtranslator/swagger/swagger.py b/samtranslator/swagger/swagger.py index 2b61f509f1..7180aeb4c8 100644 --- a/samtranslator/swagger/swagger.py +++ b/samtranslator/swagger/swagger.py @@ -169,10 +169,18 @@ def add_lambda_integration(self, path, method, integration_uri, api_auth_config = api_auth_config or {} if method_auth_config.get('Authorizer') == 'AWS_IAM' \ or api_auth_config.get('DefaultAuthorizer') == 'AWS_IAM' and not method_auth_config: - self.paths[path][method][self._X_APIGW_INTEGRATION]['credentials'] = self._generate_integration_credentials( - method_invoke_role=method_auth_config.get('InvokeRole'), - api_invoke_role=api_auth_config.get('InvokeRole') + method_invoke_role = method_auth_config.get('InvokeRole') + if not method_invoke_role and 'InvokeRole' in method_auth_config: + method_invoke_role = 'NONE' + api_invoke_role = api_auth_config.get('InvokeRole') + if not api_invoke_role and 'InvokeRole' in api_auth_config: + api_invoke_role = 'NONE' + credentials = self._generate_integration_credentials( + method_invoke_role=method_invoke_role, + api_invoke_role=api_invoke_role ) + if credentials and credentials != 'NONE': + self.paths[path][method][self._X_APIGW_INTEGRATION]['credentials'] = credentials # If 'responses' key is *not* present, add it with an empty dict as value path_dict[method].setdefault('responses', {}) diff --git a/tests/translator/input/api_with_aws_iam_auth_overrides.yaml b/tests/translator/input/api_with_aws_iam_auth_overrides.yaml index f9cd47765a..5ce61f7924 100644 --- a/tests/translator/input/api_with_aws_iam_auth_overrides.yaml +++ b/tests/translator/input/api_with_aws_iam_auth_overrides.yaml @@ -1,4 +1,11 @@ Resources: + MyApiWithAwsIamAuthNoCallerCredentials: + Type: "AWS::Serverless::Api" + Properties: + StageName: Prod + Auth: + DefaultAuthorizer: AWS_IAM + InvokeRole: NONE MyApiWithAwsIamAuth: Type: "AWS::Serverless::Api" Properties: @@ -84,3 +91,64 @@ Resources: Auth: Authorizer: AWS_IAM InvokeRole: arn:aws:iam::456::role/something-else + MyFunctionNONEInvokeRole: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + API3: + Type: Api + Properties: + RestApiId: !Ref MyApiWithAwsIamAuth + Method: get + Path: /MyFunctionNONEInvokeRole + Auth: + Authorizer: AWS_IAM + InvokeRole: NONE + MyFunctionNullInvokeRole: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + API3: + Type: Api + Properties: + RestApiId: !Ref MyApiWithAwsIamAuth + Method: get + Path: /MyFunctionNullInvokeRole + Auth: + Authorizer: AWS_IAM + InvokeRole: null + MyFunctionCallerCredentialsOverride: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + API3: + Type: Api + Properties: + RestApiId: !Ref MyApiWithAwsIamAuthNoCallerCredentials + Method: get + Path: / + Auth: + Authorizer: AWS_IAM + InvokeRole: CALLER_CREDENTIALS + MyFunctionNoCallerCredentials: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://bucket/key + Handler: index.handler + Runtime: nodejs8.10 + Events: + API3: + Type: Api + Properties: + RestApiId: !Ref MyApiWithAwsIamAuthNoCallerCredentials + Method: post + Path: / diff --git a/tests/translator/output/api_with_aws_iam_auth_overrides.json b/tests/translator/output/api_with_aws_iam_auth_overrides.json index 6ca104082e..c1906a4f37 100644 --- a/tests/translator/output/api_with_aws_iam_auth_overrides.json +++ b/tests/translator/output/api_with_aws_iam_auth_overrides.json @@ -1,77 +1,142 @@ { "Resources": { "MyFunctionCustomInvokeRole": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionCustomInvokeRoleRole", + "MyFunctionCustomInvokeRoleRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "MyFunctionNoneAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionNoneAuthRole", + "MyFunctionNoneAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, + "MyFunctionNullInvokeRole": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNullInvokeRoleRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionNullInvokeRoleAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNullInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNullInvokeRole", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyApiWithAwsIamAuthProdStage": { - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithAwsIamAuthDeployment8a32fb1652" - }, + "Ref": "MyApiWithAwsIamAuthDeployment3bec5f30f2" + }, "RestApiId": { "Ref": "MyApiWithAwsIamAuth" - }, + }, "StageName": "Prod" } - }, + }, + "MyFunctionCallerCredentialsOverrideAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionCallerCredentialsOverride" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + } + } + ] + } + } + }, "MyFunctionWithoutAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -81,20 +146,20 @@ ] } } - }, + }, "MyFunctionCustomInvokeRoleAPI3PermissionProd": { - "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": "MyFunctionCustomInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -102,20 +167,20 @@ ] } } - }, - "MyFunctionWithoutAuthAPI2PermissionProd": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionMyCognitoAuthAPI1PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionWithoutAuth" - }, + "Ref": "MyFunctionMyCognitoAuth" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -123,30 +188,98 @@ ] } } - }, - "MyApiWithAwsIamAuthDeployment8a32fb1652": { - "Type": "AWS::ApiGateway::Deployment", + }, + "MyApiWithAwsIamAuthNoCallerCredentials": { + "Type": "AWS::ApiGateway::RestApi", "Properties": { - "RestApiId": { - "Ref": "MyApiWithAwsIamAuth" - }, - "Description": "RestApi deployment id: 8a32fb165218ee858b16980eed421b4f38d18f00", - "StageName": "Stage" + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/": { + "post": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoCallerCredentials.Arn}/invocations" + } + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + }, + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionCallerCredentialsOverride.Arn}/invocations" + }, + "credentials": "arn:aws:iam::*:user/*" + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "AWS_IAM": { + "in": "header", + "type": "apiKey", + "name": "Authorization", + "x-amazon-apigateway-authtype": "awsSigv4" + } + } + } } - }, + }, + "MyFunctionWithoutAuthAPI2PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithoutAuth" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyFunctionMyCognitoAuthAPI1PermissionTest": { - "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": "MyFunctionMyCognitoAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -154,65 +287,154 @@ ] } } - }, + }, + "MyFunctionDefaultInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionDefaultInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyFunctionMyCognitoAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionMyCognitoAuthRole", + "MyFunctionMyCognitoAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, - "MyFunctionDefaultInvokeRoleAPI3PermissionProd": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionNullInvokeRoleRole": { + "Type": "AWS::IAM::Role", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionNoCallerCredentialsAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionDefaultInvokeRole" - }, + "Ref": "MyFunctionNoCallerCredentials" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/", { - "__Stage__": "Prod", + "__Stage__": "*", "__ApiId__": { - "Ref": "MyApiWithAwsIamAuth" + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" } } ] } } - }, + }, + "MyFunctionNONEInvokeRole": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNONEInvokeRoleRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionNoCallerCredentialsAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNoCallerCredentials" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + } + } + ] + } + } + }, "MyFunctionNoneAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -222,21 +444,21 @@ ] } } - }, + }, "MyFunctionCustomInvokeRoleRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -246,20 +468,20 @@ ] } } - }, + }, "MyFunctionDefaultInvokeRoleAPI3PermissionTest": { - "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": "MyFunctionDefaultInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -267,64 +489,107 @@ ] } } - }, - "MyFunctionWithoutAuthAPI2PermissionTest": { - "Type": "AWS::Lambda::Permission", + }, + "MyApiWithAwsIamAuthDeployment3bec5f30f2": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAwsIamAuth" + }, + "Description": "RestApi deployment id: 3bec5f30f275272b5feee10af30f848d1ce4400d", + "StageName": "Stage" + } + }, + "MyApiWithAwsIamAuthNoCallerCredentialsDeployment38c75afec1": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + }, + "Description": "RestApi deployment id: 38c75afec1f32ff6e177b0f49a2b9e86958f594e", + "StageName": "Stage" + } + }, + "MyFunctionCallerCredentialsOverrideAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionWithoutAuth" - }, + "Ref": "MyFunctionCallerCredentialsOverride" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "*", + "__Stage__": "Prod", "__ApiId__": { - "Ref": "MyApiWithAwsIamAuth" + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" } } ] } } - }, + }, + "MyFunctionCallerCredentialsOverride": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionCallerCredentialsOverrideRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, "MyFunctionWithoutAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionWithoutAuthRole", + "MyFunctionWithoutAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, - "MyFunctionMyCognitoAuthAPI1PermissionProd": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionNullInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionMyCognitoAuth" - }, + "Ref": "MyFunctionNullInvokeRole" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNullInvokeRole", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -332,21 +597,111 @@ ] } } - }, + }, + "MyFunctionNONEInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNONEInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNONEInvokeRole", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyFunctionNoCallerCredentialsRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, "MyFunctionDefaultInvokeRoleRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithoutAuthAPI2PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithoutAuth" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyFunctionCallerCredentialsOverrideRole": { + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -356,21 +711,42 @@ ] } } - }, + }, + "MyFunctionNONEInvokeRoleAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNONEInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNONEInvokeRole", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyFunctionMyCognitoAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -380,20 +756,32 @@ ] } } - }, + }, + "MyApiWithAwsIamAuthNoCallerCredentialsProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentialsDeployment38c75afec1" + }, + "RestApiId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + }, + "StageName": "Prod" + } + }, "MyFunctionCustomInvokeRoleAPI3PermissionTest": { - "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": "MyFunctionCustomInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -401,43 +789,66 @@ ] } } - }, + }, "MyFunctionDefaultInvokeRole": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionDefaultInvokeRoleRole", + "MyFunctionDefaultInvokeRoleRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, + "MyFunctionNoCallerCredentials": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNoCallerCredentialsRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, "MyFunctionNoneAuthAPI3PermissionTest": { - "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": "MyFunctionNoneAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -445,144 +856,178 @@ ] } } - }, + }, "MyApiWithAwsIamAuth": { - "Type": "AWS::ApiGateway::RestApi", + "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { - "/MyFunctionDefaultInvokeRole": { + "/MyFunctionWithoutAuth": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionDefaultInvokeRole.Arn}/invocations" - }, - "credentials": "arn:aws:iam::*:user/*" - }, + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithoutAuth.Arn}/invocations" + }, + "credentials": "arn:aws:iam::123:role/AUTH_AWS_IAM" + }, "security": [ { "AWS_IAM": [] } - ], + ], "responses": {} } - }, - "/MyFunctionWithoutAuth": { + }, + "/MyFunctionNONEInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithoutAuth.Arn}/invocations" - }, - "credentials": "arn:aws:iam::123:role/AUTH_AWS_IAM" - }, + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNONEInvokeRole.Arn}/invocations" + } + }, "security": [ { "AWS_IAM": [] } - ], + ], "responses": {} } - }, - "/MyFunctionNoneAuth": { + }, + "/MyFunctionMyCognitoAuth": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoneAuth.Arn}/invocations" + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionMyCognitoAuth.Arn}/invocations" } - }, + }, "security": [ { - "NONE": [] + "MyCognitoAuth": [] } - ], + ], "responses": {} } - }, - "/MyFunctionMyCognitoAuth": { + }, + "/MyFunctionDefaultInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionMyCognitoAuth.Arn}/invocations" - } - }, + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionDefaultInvokeRole.Arn}/invocations" + }, + "credentials": "arn:aws:iam::*:user/*" + }, "security": [ { - "MyCognitoAuth": [] + "AWS_IAM": [] } - ], + ], "responses": {} } - }, + }, "/MyFunctionCustomInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionCustomInvokeRole.Arn}/invocations" - }, + }, "credentials": "arn:aws:iam::456::role/something-else" - }, + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + } + }, + "/MyFunctionNullInvokeRole": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNullInvokeRole.Arn}/invocations" + } + }, "security": [ { "AWS_IAM": [] } - ], + ], + "responses": {} + } + }, + "/MyFunctionNoneAuth": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoneAuth.Arn}/invocations" + } + }, + "security": [ + { + "NONE": [] + } + ], "responses": {} } } - }, - "swagger": "2.0", + }, + "swagger": "2.0", "securityDefinitions": { "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authorizer": { "providerARNs": [ "arn:aws:cognito-idp:xxxxxxxxx" - ], + ], "type": "cognito_user_pools" - }, + }, "x-amazon-apigateway-authtype": "cognito_user_pools" - }, + }, "AWS_IAM": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authtype": "awsSigv4" } } } } - }, + }, "MyFunctionNoneAuthAPI3PermissionProd": { - "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": "MyFunctionNoneAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -590,6 +1035,30 @@ ] } } + }, + "MyFunctionNONEInvokeRoleRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } } } } diff --git a/tests/translator/output/aws-cn/api_with_aws_iam_auth_overrides.json b/tests/translator/output/aws-cn/api_with_aws_iam_auth_overrides.json index 49f1e90a40..ea4ab32eed 100644 --- a/tests/translator/output/aws-cn/api_with_aws_iam_auth_overrides.json +++ b/tests/translator/output/aws-cn/api_with_aws_iam_auth_overrides.json @@ -1,77 +1,152 @@ { "Resources": { "MyFunctionCustomInvokeRole": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionCustomInvokeRoleRole", + "MyFunctionCustomInvokeRoleRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "MyFunctionNoneAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionNoneAuthRole", + "MyFunctionNoneAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, + "MyFunctionNullInvokeRole": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNullInvokeRoleRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionNullInvokeRoleAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNullInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNullInvokeRole", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyApiWithAwsIamAuthProdStage": { - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithAwsIamAuthDeploymented0a631915" - }, + "Ref": "MyApiWithAwsIamAuthDeployment4253f994cd" + }, "RestApiId": { "Ref": "MyApiWithAwsIamAuth" - }, + }, "StageName": "Prod" } - }, + }, + "MyApiWithAwsIamAuthDeployment4253f994cd": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAwsIamAuth" + }, + "Description": "RestApi deployment id: 4253f994cdaf14767907decd5cb875cbafc08704", + "StageName": "Stage" + } + }, + "MyFunctionCallerCredentialsOverrideAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionCallerCredentialsOverride" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + } + } + ] + } + } + }, "MyFunctionWithoutAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -81,20 +156,20 @@ ] } } - }, + }, "MyFunctionCustomInvokeRoleAPI3PermissionProd": { - "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": "MyFunctionCustomInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -102,20 +177,116 @@ ] } } - }, + }, + "MyFunctionMyCognitoAuthAPI1PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionMyCognitoAuth" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyApiWithAwsIamAuthNoCallerCredentialsDeployment07ee28f86e": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + }, + "Description": "RestApi deployment id: 07ee28f86edc705d064d88266db4dea8f5c305b1", + "StageName": "Stage" + } + }, + "MyApiWithAwsIamAuthNoCallerCredentials": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/": { + "post": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoCallerCredentials.Arn}/invocations" + } + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + }, + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionCallerCredentialsOverride.Arn}/invocations" + }, + "credentials": "arn:aws:iam::*:user/*" + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "AWS_IAM": { + "in": "header", + "type": "apiKey", + "name": "Authorization", + "x-amazon-apigateway-authtype": "awsSigv4" + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, "MyFunctionWithoutAuthAPI2PermissionProd": { - "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": "MyFunctionWithoutAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -123,20 +294,20 @@ ] } } - }, + }, "MyFunctionMyCognitoAuthAPI1PermissionTest": { - "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": "MyFunctionMyCognitoAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -144,75 +315,154 @@ ] } } - }, - "MyApiWithAwsIamAuthDeploymented0a631915": { - "Type": "AWS::ApiGateway::Deployment", + }, + "MyFunctionDefaultInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "RestApiId": { - "Ref": "MyApiWithAwsIamAuth" - }, - "Description": "RestApi deployment id: ed0a631915dc4df4436f471e81cd69beb6f89603", - "StageName": "Stage" + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionDefaultInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } } - }, + }, "MyFunctionMyCognitoAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionMyCognitoAuthRole", + "MyFunctionMyCognitoAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, - "MyFunctionDefaultInvokeRoleAPI3PermissionProd": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionNullInvokeRoleRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionNoCallerCredentialsAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionDefaultInvokeRole" - }, + "Ref": "MyFunctionNoCallerCredentials" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/", { - "__Stage__": "Prod", + "__Stage__": "*", "__ApiId__": { - "Ref": "MyApiWithAwsIamAuth" + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" } } ] } } - }, + }, + "MyFunctionNONEInvokeRole": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNONEInvokeRoleRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionNoCallerCredentialsAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNoCallerCredentials" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + } + } + ] + } + } + }, "MyFunctionNoneAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -222,21 +472,21 @@ ] } } - }, + }, "MyFunctionCustomInvokeRoleRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -246,20 +496,20 @@ ] } } - }, + }, "MyFunctionDefaultInvokeRoleAPI3PermissionTest": { - "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": "MyFunctionDefaultInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -267,64 +517,87 @@ ] } } - }, - "MyFunctionWithoutAuthAPI2PermissionTest": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionCallerCredentialsOverrideAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionWithoutAuth" - }, + "Ref": "MyFunctionCallerCredentialsOverride" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "*", + "__Stage__": "Prod", "__ApiId__": { - "Ref": "MyApiWithAwsIamAuth" + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" } } ] } } - }, + }, + "MyFunctionCallerCredentialsOverride": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionCallerCredentialsOverrideRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, "MyFunctionWithoutAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionWithoutAuthRole", + "MyFunctionWithoutAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, - "MyFunctionMyCognitoAuthAPI1PermissionProd": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionNullInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionMyCognitoAuth" - }, + "Ref": "MyFunctionNullInvokeRole" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNullInvokeRole", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -332,21 +605,111 @@ ] } } - }, + }, + "MyFunctionNONEInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNONEInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNONEInvokeRole", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyFunctionNoCallerCredentialsRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, "MyFunctionDefaultInvokeRoleRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithoutAuthAPI2PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithoutAuth" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyFunctionCallerCredentialsOverrideRole": { + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -356,21 +719,42 @@ ] } } - }, + }, + "MyFunctionNONEInvokeRoleAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNONEInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNONEInvokeRole", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyFunctionMyCognitoAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -380,20 +764,32 @@ ] } } - }, + }, + "MyApiWithAwsIamAuthNoCallerCredentialsProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentialsDeployment07ee28f86e" + }, + "RestApiId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + }, + "StageName": "Prod" + } + }, "MyFunctionCustomInvokeRoleAPI3PermissionTest": { - "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": "MyFunctionCustomInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -401,43 +797,66 @@ ] } } - }, + }, "MyFunctionDefaultInvokeRole": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionDefaultInvokeRoleRole", + "MyFunctionDefaultInvokeRoleRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, + "MyFunctionNoCallerCredentials": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNoCallerCredentialsRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, "MyFunctionNoneAuthAPI3PermissionTest": { - "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": "MyFunctionNoneAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -445,152 +864,186 @@ ] } } - }, + }, "MyApiWithAwsIamAuth": { - "Type": "AWS::ApiGateway::RestApi", + "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { - "/MyFunctionDefaultInvokeRole": { + "/MyFunctionWithoutAuth": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionDefaultInvokeRole.Arn}/invocations" - }, - "credentials": "arn:aws:iam::*:user/*" - }, + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithoutAuth.Arn}/invocations" + }, + "credentials": "arn:aws:iam::123:role/AUTH_AWS_IAM" + }, "security": [ { "AWS_IAM": [] } - ], + ], "responses": {} } - }, - "/MyFunctionWithoutAuth": { + }, + "/MyFunctionNONEInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithoutAuth.Arn}/invocations" - }, - "credentials": "arn:aws:iam::123:role/AUTH_AWS_IAM" - }, + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNONEInvokeRole.Arn}/invocations" + } + }, "security": [ { "AWS_IAM": [] } - ], + ], "responses": {} } - }, - "/MyFunctionNoneAuth": { + }, + "/MyFunctionMyCognitoAuth": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoneAuth.Arn}/invocations" + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionMyCognitoAuth.Arn}/invocations" } - }, + }, "security": [ { - "NONE": [] + "MyCognitoAuth": [] } - ], + ], "responses": {} } - }, - "/MyFunctionMyCognitoAuth": { + }, + "/MyFunctionDefaultInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionMyCognitoAuth.Arn}/invocations" - } - }, + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionDefaultInvokeRole.Arn}/invocations" + }, + "credentials": "arn:aws:iam::*:user/*" + }, "security": [ { - "MyCognitoAuth": [] + "AWS_IAM": [] } - ], + ], "responses": {} } - }, + }, "/MyFunctionCustomInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionCustomInvokeRole.Arn}/invocations" - }, + }, "credentials": "arn:aws:iam::456::role/something-else" - }, + }, "security": [ { "AWS_IAM": [] } - ], + ], + "responses": {} + } + }, + "/MyFunctionNullInvokeRole": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNullInvokeRole.Arn}/invocations" + } + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + } + }, + "/MyFunctionNoneAuth": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoneAuth.Arn}/invocations" + } + }, + "security": [ + { + "NONE": [] + } + ], "responses": {} } } - }, - "swagger": "2.0", + }, + "swagger": "2.0", "securityDefinitions": { "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authorizer": { "providerARNs": [ "arn:aws:cognito-idp:xxxxxxxxx" - ], + ], "type": "cognito_user_pools" - }, + }, "x-amazon-apigateway-authtype": "cognito_user_pools" - }, + }, "AWS_IAM": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authtype": "awsSigv4" } } - }, + }, "EndpointConfiguration": { "Types": [ "REGIONAL" ] - }, + }, "Parameters": { "endpointConfigurationTypes": "REGIONAL" } } - }, + }, "MyFunctionNoneAuthAPI3PermissionProd": { - "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": "MyFunctionNoneAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -598,6 +1051,30 @@ ] } } + }, + "MyFunctionNONEInvokeRoleRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } } } } diff --git a/tests/translator/output/aws-us-gov/api_with_aws_iam_auth_overrides.json b/tests/translator/output/aws-us-gov/api_with_aws_iam_auth_overrides.json index cf8d219509..77cc8a3298 100644 --- a/tests/translator/output/aws-us-gov/api_with_aws_iam_auth_overrides.json +++ b/tests/translator/output/aws-us-gov/api_with_aws_iam_auth_overrides.json @@ -1,87 +1,142 @@ { "Resources": { "MyFunctionCustomInvokeRole": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionCustomInvokeRoleRole", + "MyFunctionCustomInvokeRoleRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, "MyFunctionNoneAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionNoneAuthRole", + "MyFunctionNoneAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, - "MyApiWithAwsIamAuthDeploymentd6dd2d1504": { - "Type": "AWS::ApiGateway::Deployment", + }, + "MyFunctionNullInvokeRole": { + "Type": "AWS::Lambda::Function", "Properties": { - "RestApiId": { - "Ref": "MyApiWithAwsIamAuth" - }, - "Description": "RestApi deployment id: d6dd2d1504ea960bdb50055b256d9292aa565e4b", - "StageName": "Stage" + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNullInvokeRoleRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] } - }, + }, + "MyFunctionNullInvokeRoleAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNullInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNullInvokeRole", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyApiWithAwsIamAuthProdStage": { - "Type": "AWS::ApiGateway::Stage", + "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithAwsIamAuthDeploymentd6dd2d1504" - }, + "Ref": "MyApiWithAwsIamAuthDeploymentc7d4214444" + }, "RestApiId": { "Ref": "MyApiWithAwsIamAuth" - }, + }, "StageName": "Prod" } - }, + }, + "MyFunctionCallerCredentialsOverrideAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionCallerCredentialsOverride" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + } + } + ] + } + } + }, "MyFunctionWithoutAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -91,20 +146,41 @@ ] } } - }, + }, "MyFunctionCustomInvokeRoleAPI3PermissionProd": { - "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": "MyFunctionCustomInvokeRole" - }, + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyFunctionMyCognitoAuthAPI1PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionMyCognitoAuth" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -112,20 +188,95 @@ ] } } - }, + }, + "MyApiWithAwsIamAuthDeploymentc7d4214444": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAwsIamAuth" + }, + "Description": "RestApi deployment id: c7d4214444b325ee43f7a16744a5a74d01b268b2", + "StageName": "Stage" + } + }, + "MyApiWithAwsIamAuthNoCallerCredentials": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/": { + "post": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoCallerCredentials.Arn}/invocations" + } + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + }, + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionCallerCredentialsOverride.Arn}/invocations" + }, + "credentials": "arn:aws:iam::*:user/*" + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + } + } + }, + "swagger": "2.0", + "securityDefinitions": { + "AWS_IAM": { + "in": "header", + "type": "apiKey", + "name": "Authorization", + "x-amazon-apigateway-authtype": "awsSigv4" + } + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, "MyFunctionWithoutAuthAPI2PermissionProd": { - "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": "MyFunctionWithoutAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -133,20 +284,20 @@ ] } } - }, + }, "MyFunctionMyCognitoAuthAPI1PermissionTest": { - "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": "MyFunctionMyCognitoAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -154,65 +305,154 @@ ] } } - }, + }, + "MyFunctionDefaultInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionDefaultInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyFunctionMyCognitoAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionMyCognitoAuthRole", + "MyFunctionMyCognitoAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, - "MyFunctionDefaultInvokeRoleAPI3PermissionProd": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionNullInvokeRoleRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionNoCallerCredentialsAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionDefaultInvokeRole" - }, + "Ref": "MyFunctionNoCallerCredentials" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/", { - "__Stage__": "Prod", + "__Stage__": "*", "__ApiId__": { - "Ref": "MyApiWithAwsIamAuth" + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" } } ] } } - }, + }, + "MyFunctionNONEInvokeRole": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNONEInvokeRoleRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyFunctionNoCallerCredentialsAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNoCallerCredentials" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + } + } + ] + } + } + }, "MyFunctionNoneAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -222,21 +462,21 @@ ] } } - }, + }, "MyFunctionCustomInvokeRoleRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -246,20 +486,20 @@ ] } } - }, + }, "MyFunctionDefaultInvokeRoleAPI3PermissionTest": { - "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": "MyFunctionDefaultInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionDefaultInvokeRole", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -267,64 +507,87 @@ ] } } - }, - "MyFunctionWithoutAuthAPI2PermissionTest": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionCallerCredentialsOverrideAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionWithoutAuth" - }, + "Ref": "MyFunctionCallerCredentialsOverride" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/", { - "__Stage__": "*", + "__Stage__": "Prod", "__ApiId__": { - "Ref": "MyApiWithAwsIamAuth" + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" } } ] } } - }, + }, + "MyFunctionCallerCredentialsOverride": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionCallerCredentialsOverrideRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, "MyFunctionWithoutAuth": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionWithoutAuthRole", + "MyFunctionWithoutAuthRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, - "MyFunctionMyCognitoAuthAPI1PermissionProd": { - "Type": "AWS::Lambda::Permission", + }, + "MyFunctionNullInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFunctionMyCognitoAuth" - }, + "Ref": "MyFunctionNullInvokeRole" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionMyCognitoAuth", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNullInvokeRole", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -332,21 +595,111 @@ ] } } - }, + }, + "MyFunctionNONEInvokeRoleAPI3PermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNONEInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNONEInvokeRole", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyFunctionNoCallerCredentialsRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, "MyFunctionDefaultInvokeRoleRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MyFunctionWithoutAuthAPI2PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionWithoutAuth" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionWithoutAuth", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, + "MyFunctionCallerCredentialsOverrideRole": { + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -356,21 +709,42 @@ ] } } - }, + }, + "MyFunctionNONEInvokeRoleAPI3PermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFunctionNONEInvokeRole" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNONEInvokeRole", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithAwsIamAuth" + } + } + ] + } + } + }, "MyFunctionMyCognitoAuthRole": { - "Type": "AWS::IAM::Role", + "Type": "AWS::IAM::Role", "Properties": { "ManagedPolicyArns": [ "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ], + ], "AssumeRolePolicyDocument": { - "Version": "2012-10-17", + "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" - ], - "Effect": "Allow", + ], + "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" @@ -380,20 +754,32 @@ ] } } - }, + }, + "MyApiWithAwsIamAuthNoCallerCredentialsProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentialsDeployment673da6c5e9" + }, + "RestApiId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + }, + "StageName": "Prod" + } + }, "MyFunctionCustomInvokeRoleAPI3PermissionTest": { - "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": "MyFunctionCustomInvokeRole" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionCustomInvokeRole", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -401,43 +787,66 @@ ] } } - }, + }, "MyFunctionDefaultInvokeRole": { - "Type": "AWS::Lambda::Function", + "Type": "AWS::Lambda::Function", "Properties": { - "Handler": "index.handler", + "Handler": "index.handler", "Code": { - "S3Bucket": "bucket", + "S3Bucket": "bucket", "S3Key": "key" - }, + }, "Role": { "Fn::GetAtt": [ - "MyFunctionDefaultInvokeRoleRole", + "MyFunctionDefaultInvokeRoleRole", "Arn" ] - }, - "Runtime": "nodejs8.10", + }, + "Runtime": "nodejs8.10", "Tags": [ { - "Value": "SAM", + "Value": "SAM", "Key": "lambda:createdBy" } ] } - }, + }, + "MyFunctionNoCallerCredentials": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Code": { + "S3Bucket": "bucket", + "S3Key": "key" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionNoCallerCredentialsRole", + "Arn" + ] + }, + "Runtime": "nodejs8.10", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, "MyFunctionNoneAuthAPI3PermissionTest": { - "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": "MyFunctionNoneAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", { - "__Stage__": "*", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -445,152 +854,186 @@ ] } } - }, + }, "MyApiWithAwsIamAuth": { - "Type": "AWS::ApiGateway::RestApi", + "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "info": { - "version": "1.0", + "version": "1.0", "title": { "Ref": "AWS::StackName" } - }, + }, "paths": { - "/MyFunctionDefaultInvokeRole": { + "/MyFunctionWithoutAuth": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionDefaultInvokeRole.Arn}/invocations" - }, - "credentials": "arn:aws:iam::*:user/*" - }, + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithoutAuth.Arn}/invocations" + }, + "credentials": "arn:aws:iam::123:role/AUTH_AWS_IAM" + }, "security": [ { "AWS_IAM": [] } - ], + ], "responses": {} } - }, - "/MyFunctionWithoutAuth": { + }, + "/MyFunctionNONEInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionWithoutAuth.Arn}/invocations" - }, - "credentials": "arn:aws:iam::123:role/AUTH_AWS_IAM" - }, + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNONEInvokeRole.Arn}/invocations" + } + }, "security": [ { "AWS_IAM": [] } - ], + ], "responses": {} } - }, - "/MyFunctionNoneAuth": { + }, + "/MyFunctionMyCognitoAuth": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoneAuth.Arn}/invocations" + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionMyCognitoAuth.Arn}/invocations" } - }, + }, "security": [ { - "NONE": [] + "MyCognitoAuth": [] } - ], + ], "responses": {} } - }, - "/MyFunctionMyCognitoAuth": { + }, + "/MyFunctionDefaultInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { - "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionMyCognitoAuth.Arn}/invocations" - } - }, + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionDefaultInvokeRole.Arn}/invocations" + }, + "credentials": "arn:aws:iam::*:user/*" + }, "security": [ { - "MyCognitoAuth": [] + "AWS_IAM": [] } - ], + ], "responses": {} } - }, + }, "/MyFunctionCustomInvokeRole": { "get": { "x-amazon-apigateway-integration": { - "httpMethod": "POST", - "type": "aws_proxy", + "httpMethod": "POST", + "type": "aws_proxy", "uri": { "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionCustomInvokeRole.Arn}/invocations" - }, + }, "credentials": "arn:aws:iam::456::role/something-else" - }, + }, + "security": [ + { + "AWS_IAM": [] + } + ], + "responses": {} + } + }, + "/MyFunctionNullInvokeRole": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNullInvokeRole.Arn}/invocations" + } + }, "security": [ { "AWS_IAM": [] } - ], + ], + "responses": {} + } + }, + "/MyFunctionNoneAuth": { + "get": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunctionNoneAuth.Arn}/invocations" + } + }, + "security": [ + { + "NONE": [] + } + ], "responses": {} } } - }, - "swagger": "2.0", + }, + "swagger": "2.0", "securityDefinitions": { "MyCognitoAuth": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authorizer": { "providerARNs": [ "arn:aws:cognito-idp:xxxxxxxxx" - ], + ], "type": "cognito_user_pools" - }, + }, "x-amazon-apigateway-authtype": "cognito_user_pools" - }, + }, "AWS_IAM": { - "in": "header", - "type": "apiKey", - "name": "Authorization", + "in": "header", + "type": "apiKey", + "name": "Authorization", "x-amazon-apigateway-authtype": "awsSigv4" } } - }, + }, "EndpointConfiguration": { "Types": [ "REGIONAL" ] - }, + }, "Parameters": { "endpointConfigurationTypes": "REGIONAL" } } - }, + }, "MyFunctionNoneAuthAPI3PermissionProd": { - "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": "MyFunctionNoneAuth" - }, + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/MyFunctionNoneAuth", { - "__Stage__": "Prod", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApiWithAwsIamAuth" } @@ -598,6 +1041,40 @@ ] } } + }, + "MyApiWithAwsIamAuthNoCallerCredentialsDeployment673da6c5e9": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithAwsIamAuthNoCallerCredentials" + }, + "Description": "RestApi deployment id: 673da6c5e9481163e7b1cbf6d5604eb84cf64fd0", + "StageName": "Stage" + } + }, + "MyFunctionNONEInvokeRoleRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } } } } diff --git a/versions/2016-10-31.md b/versions/2016-10-31.md index 988e91af66..6078ab8366 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -798,6 +798,9 @@ Define Lambda and Cognito `Authorizers` and specify a `DefaultAuthorizer`. If yo Auth: ApiKeyRequired: true # OPTIONAL DefaultAuthorizer: MyCognitoAuth # OPTIONAL, if you use IAM permissions, specify AWS_IAM. + # For AWS_IAM: + # DefaultAuthorizer: AWS_IAM + # InvokeRole: NONE # CALLER_CREDENTIALS by default unless overridden Authorizers: MyCognitoAuth: UserPoolArn: !GetAtt MyCognitoUserPool.Arn # Can also accept an array From af20fb5543037c28b1e33c8ed060b9faed77031c Mon Sep 17 00:00:00 2001 From: Keeton Hodgson Date: Fri, 26 Jul 2019 10:23:35 -0700 Subject: [PATCH 15/31] fix: remove cfn lint (#1034) --- requirements/dev.txt | 1 - tests/translator/test_translator.py | 51 ----------------------------- 2 files changed, 52 deletions(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 4ec433f415..4c55168794 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -9,7 +9,6 @@ pyyaml>=4.2b1 pytest>=3.0.7 mock>=2.0.0 parameterized>=0.6.1 -cfn-lint>=0.18.1 # Requirements for examples requests>=2.20.0 diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index a84ea5cb14..d07822ef0f 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -1,6 +1,4 @@ import json -import cfnlint.core -from cfnlint import Runner import itertools import os.path import hashlib @@ -36,21 +34,6 @@ INPUT_FOLDER = os.path.join(BASE_PATH, 'input') OUTPUT_FOLDER = os.path.join(BASE_PATH, 'output') -LINT_IGNORE_WARNINGS = [ - 'W2001', # unused parameters. Sometimes, SAM uses parameters and removes the param reference from the output template, but the parameter stays in the parameters section. - 'W1001', # Ref/GetAtt with conditions. This incorrectly flags resources since it can't map conditions fully. - 'E3001', # Check for resource availability in a region. - 'W7001', # Check if mappings are used. Serverless::Application uses mappings, the output CFN doesn't use them anymore. - 'W1020', # Sub isn't needed if it doesn't have a variable defined. SAM leaves `!Sub` in even if it tries to resolve variables. - 'E2531', # we don't care if a runtime has been deprecated in our tests. - 'E3038', # Serverless resources- test for invalid resources. -] - -LINT_IGNORE_TESTS = [ - 'function_with_resource_refs', # Tests functionality of the translator in ways that result in improper GetAtt calls on CFN resources. - 'api_with_canary_setting', # Has stage variable overrides for nonexistent stage variables. -] - def deep_sort_lists(value): """ @@ -300,29 +283,12 @@ def test_transform_success(self, testcase, partition_with_region): print(json.dumps(output_fragment, indent=2)) - # Run cfn-lint on translator test output files. - rules = cfnlint.core.get_rules([], LINT_IGNORE_WARNINGS, []) - # Only update the deployment Logical Id hash in Py3. if sys.version_info.major >= 3: self._update_logical_id_hash(expected) self._update_logical_id_hash(output_fragment) - output_template = cfnlint.decode.cfn_json.load(expected_filepath) - else: # deprecation warning catching in py2 - import warnings - with warnings.catch_warnings(): - warnings.filterwarnings("ignore",category=DeprecationWarning) - output_template = cfnlint.decode.cfn_json.load(expected_filepath) - runner = cfnlint.Runner(rules, expected_filepath, output_template, [region]) - matches = [] - - # Only run linter on normal/gov partitions. It errors on china regions - if testcase not in LINT_IGNORE_TESTS and partition != 'aws-cn': - matches = runner.run() - print('cfn-lint ({}): {}'.format(expected_filepath, matches)) assert deep_sort_lists(output_fragment) == deep_sort_lists(expected) - assert len(matches) == 0 @parameterized.expand( itertools.product([ @@ -373,29 +339,12 @@ def test_transform_success_openapi3(self, testcase, partition_with_region): print(json.dumps(output_fragment, indent=2)) - # Run cfn-lint on translator test output files. - rules = cfnlint.core.get_rules([], LINT_IGNORE_WARNINGS, []) - # Only update the deployment Logical Id hash in Py3. if sys.version_info.major >= 3: self._update_logical_id_hash(expected) self._update_logical_id_hash(output_fragment) - output_template = cfnlint.decode.cfn_json.load(expected_filepath) - else: # deprecation warning catching in py2 - import warnings - with warnings.catch_warnings(): - warnings.filterwarnings("ignore",category=DeprecationWarning) - output_template = cfnlint.decode.cfn_json.load(expected_filepath) - runner = cfnlint.Runner(rules, expected_filepath, output_template, [region]) - matches = [] - - # Only run linter on normal/gov partitions. It errors on china regions - if testcase not in LINT_IGNORE_TESTS and partition != 'aws-cn': - matches = runner.run() - print('cfn-lint ({}): {}'.format(expected_filepath, matches)) assert deep_sort_lists(output_fragment) == deep_sort_lists(expected) - assert len(matches) == 0 def _update_logical_id_hash(self, resources): """ From 7fd10a739957ef83e6ce36a549898c17ea0d6c28 Mon Sep 17 00:00:00 2001 From: Keeton Hodgson Date: Fri, 26 Jul 2019 10:27:54 -0700 Subject: [PATCH 16/31] fix: binary media types bug fix (#1043) --- samtranslator/model/sam_resources.py | 3 ++ samtranslator/swagger/swagger.py | 4 +- .../input/api_with_binary_media_types.yaml | 11 ++-- ...th_binary_media_types_definition_body.yaml | 13 +++-- .../output/api_with_binary_media_types.json | 47 +++++++++------- ...th_binary_media_types_definition_body.json | 54 +++++++++++-------- .../aws-cn/api_with_binary_media_types.json | 47 +++++++++------- ...th_binary_media_types_definition_body.json | 54 +++++++++++-------- .../api_with_binary_media_types.json | 27 ++++++---- ...th_binary_media_types_definition_body.json | 54 +++++++++++-------- 10 files changed, 190 insertions(+), 124 deletions(-) diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py index df8a62925d..8bf97994d0 100644 --- a/samtranslator/model/sam_resources.py +++ b/samtranslator/model/sam_resources.py @@ -475,6 +475,9 @@ def to_cloudformation(self, **kwargs): """ resources = [] + intrinsics_resolver = kwargs["intrinsics_resolver"] + self.BinaryMediaTypes = intrinsics_resolver.resolve_parameter_refs(self.BinaryMediaTypes) + api_generator = ApiGenerator(self.logical_id, self.CacheClusterEnabled, self.CacheClusterSize, diff --git a/samtranslator/swagger/swagger.py b/samtranslator/swagger/swagger.py index 7180aeb4c8..38a5c3ea36 100644 --- a/samtranslator/swagger/swagger.py +++ b/samtranslator/swagger/swagger.py @@ -1,4 +1,5 @@ import copy +import json import re from six import string_types @@ -265,7 +266,8 @@ def add_cors(self, path, allowed_origins, allowed_headers=None, allowed_methods= allow_credentials) def add_binary_media_types(self, binary_media_types): - self._doc[self._X_APIGW_BINARY_MEDIA_TYPES] = binary_media_types + bmt = json.loads(json.dumps(binary_media_types).replace('~1', '/')) + self._doc[self._X_APIGW_BINARY_MEDIA_TYPES] = bmt def _options_method_response_for_cors(self, allowed_origins, allowed_headers=None, allowed_methods=None, max_age=None, allow_credentials=None): diff --git a/tests/translator/input/api_with_binary_media_types.yaml b/tests/translator/input/api_with_binary_media_types.yaml index 0aa8f85916..dfe4ed0f22 100644 --- a/tests/translator/input/api_with_binary_media_types.yaml +++ b/tests/translator/input/api_with_binary_media_types.yaml @@ -1,8 +1,12 @@ +Parameters: + BMT: + Type: String + Default: 'image~1jpg' Globals: Api: BinaryMediaTypes: - - image/jpg - - {"Fn::Join": ["/", ["image", "png"]]} + - image~1gif + - {"Fn::Join": ["~1", ["image", "png"]]} Resources: ImplicitApiFunction: @@ -24,4 +28,5 @@ Resources: StageName: Prod DefinitionUri: s3://sam-demo-bucket/webpage_swagger.json BinaryMediaTypes: - - image/gif + - application~1octet-stream + - !Ref BMT diff --git a/tests/translator/input/api_with_binary_media_types_definition_body.yaml b/tests/translator/input/api_with_binary_media_types_definition_body.yaml index ecbbb01220..6730419d4f 100644 --- a/tests/translator/input/api_with_binary_media_types_definition_body.yaml +++ b/tests/translator/input/api_with_binary_media_types_definition_body.yaml @@ -1,8 +1,13 @@ +Parameters: + BMT: + Type: String + Default: image~1jpeg Globals: Api: BinaryMediaTypes: - - image/jpg - - {"Fn::Join": ["/", ["image", "png"]]} + - !Ref BMT + - image~1jpg + - {"Fn::Join": ["~1", ["image", "png"]]} Resources: ExplicitApiManagedSwagger: @@ -10,14 +15,14 @@ Resources: Properties: StageName: Prod BinaryMediaTypes: - - image/gif + - image~1gif ExplicitApiDefinitionBody: Type: AWS::Serverless::Api Properties: StageName: Prod BinaryMediaTypes: - - application/json + - application~1json DefinitionBody: { "paths": {}, "swagger": "2.0", diff --git a/tests/translator/output/api_with_binary_media_types.json b/tests/translator/output/api_with_binary_media_types.json index 75a3bd69f7..e157d5f5f1 100644 --- a/tests/translator/output/api_with_binary_media_types.json +++ b/tests/translator/output/api_with_binary_media_types.json @@ -1,4 +1,10 @@ { + "Parameters": { + "BMT": { + "Default": "image~1jpg", + "Type": "String" + } + }, "Resources": { "ImplicitApiFunction": { "Type": "AWS::Lambda::Function", @@ -47,16 +53,6 @@ } } }, - "ExplicitApiDeploymentf117c932f7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", - "StageName": "Stage" - } - }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -103,17 +99,18 @@ "Type": "AWS::ApiGateway::RestApi", "Properties": { "BinaryMediaTypes": [ - "image/jpg", + "image~1gif", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "image/gif" + "application~1octet-stream", + "image~1jpg" ], "BodyS3Location": { "Bucket": "sam-demo-bucket", @@ -137,7 +134,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment706c6ba929" + "Ref": "ServerlessRestApiDeployment4f3fcf6bd1" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -145,13 +142,23 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeployment706c6ba929": { + "ExplicitApiDeploymentf117c932f7": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", + "StageName": "Stage" + } + }, + "ServerlessRestApiDeployment4f3fcf6bd1": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 706c6ba9298c730536b2f4c51409cf33e5d616d4", + "Description": "RestApi deployment id: 4f3fcf6bd13686961885c787e3a117b084ec6c3a", "StageName": "Stage" } }, @@ -181,7 +188,7 @@ }, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ - "image/jpg", + "image/gif", { "Fn::Join": [ "/", @@ -194,10 +201,10 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1gif", { "Fn::Join": [ - "/", + "~1", [ "image", "png" @@ -208,4 +215,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/api_with_binary_media_types_definition_body.json b/tests/translator/output/api_with_binary_media_types_definition_body.json index be8dce728b..6a9e500f8b 100644 --- a/tests/translator/output/api_with_binary_media_types_definition_body.json +++ b/tests/translator/output/api_with_binary_media_types_definition_body.json @@ -1,20 +1,16 @@ { + "Parameters": { + "BMT": { + "Default": "image~1jpeg", + "Type": "String" + } + }, "Resources": { - "ExplicitApiManagedSwaggerDeployment51ba79c0e7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApiManagedSwagger" - }, - "Description": "RestApi deployment id: 51ba79c0e7185c019037fb7f9f9f2235547af57b", - "StageName": "Stage" - } - }, "ExplicitApiManagedSwaggerProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiManagedSwaggerDeployment51ba79c0e7" + "Ref": "ExplicitApiManagedSwaggerDeploymentfe9c2c09a2" }, "RestApiId": { "Ref": "ExplicitApiManagedSwagger" @@ -22,13 +18,13 @@ "StageName": "Prod" } }, - "ExplicitApiDefinitionBodyDeploymentcb68c305fb": { + "ExplicitApiManagedSwaggerDeploymentfe9c2c09a2": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ExplicitApiDefinitionBody" + "Ref": "ExplicitApiManagedSwagger" }, - "Description": "RestApi deployment id: cb68c305fb80d8e723c6c5d51a7b62462a25f5ba", + "Description": "RestApi deployment id: fe9c2c09a27ce00c2fa53d5a491cf343e6a3278e", "StageName": "Stage" } }, @@ -39,6 +35,7 @@ "paths": {}, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ + "image/jpeg", "image/jpg", { "Fn::Join": [ @@ -53,25 +50,36 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1jpeg", + "image~1jpg", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "application/json" + "application~1json" ] } }, + "ExplicitApiDefinitionBodyDeployment1f26996adb": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApiDefinitionBody" + }, + "Description": "RestApi deployment id: 1f26996adbe5077359ecb2bb0688a9cc0ae8e4fc", + "StageName": "Stage" + } + }, "ExplicitApiDefinitionBodyProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDefinitionBodyDeploymentcb68c305fb" + "Ref": "ExplicitApiDefinitionBodyDeployment1f26996adb" }, "RestApiId": { "Ref": "ExplicitApiDefinitionBody" @@ -92,6 +100,7 @@ "paths": {}, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ + "image/jpeg", "image/jpg", { "Fn::Join": [ @@ -106,19 +115,20 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1jpeg", + "image~1jpg", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "image/gif" + "image~1gif" ] } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-cn/api_with_binary_media_types.json b/tests/translator/output/aws-cn/api_with_binary_media_types.json index 701e261d64..44362e0e56 100644 --- a/tests/translator/output/aws-cn/api_with_binary_media_types.json +++ b/tests/translator/output/aws-cn/api_with_binary_media_types.json @@ -1,4 +1,10 @@ { + "Parameters": { + "BMT": { + "Default": "image~1jpg", + "Type": "String" + } + }, "Resources": { "ImplicitApiFunction": { "Type": "AWS::Lambda::Function", @@ -47,16 +53,6 @@ } } }, - "ExplicitApiDeploymentf117c932f7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", - "StageName": "Stage" - } - }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -103,17 +99,18 @@ "Type": "AWS::ApiGateway::RestApi", "Properties": { "BinaryMediaTypes": [ - "image/jpg", + "image~1gif", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "image/gif" + "application~1octet-stream", + "image~1jpg" ], "EndpointConfiguration": { "Types": [ @@ -145,7 +142,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentd244838cf7" + "Ref": "ServerlessRestApiDeploymentcc75b253a7" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -153,13 +150,23 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeploymentd244838cf7": { + "ServerlessRestApiDeploymentcc75b253a7": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: d244838cf7da9d22daa2df81b63056f8b578f711", + "Description": "RestApi deployment id: cc75b253a750cc6450a4de493f56a526d23b52d4", + "StageName": "Stage" + } + }, + "ExplicitApiDeploymentf117c932f7": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", "StageName": "Stage" } }, @@ -189,7 +196,7 @@ }, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ - "image/jpg", + "image/gif", { "Fn::Join": [ "/", @@ -202,10 +209,10 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1gif", { "Fn::Join": [ - "/", + "~1", [ "image", "png" @@ -224,4 +231,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-cn/api_with_binary_media_types_definition_body.json b/tests/translator/output/aws-cn/api_with_binary_media_types_definition_body.json index 0e654720a9..75b031c547 100644 --- a/tests/translator/output/aws-cn/api_with_binary_media_types_definition_body.json +++ b/tests/translator/output/aws-cn/api_with_binary_media_types_definition_body.json @@ -1,20 +1,16 @@ { + "Parameters": { + "BMT": { + "Default": "image~1jpeg", + "Type": "String" + } + }, "Resources": { - "ExplicitApiManagedSwaggerDeployment51ba79c0e7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApiManagedSwagger" - }, - "Description": "RestApi deployment id: 51ba79c0e7185c019037fb7f9f9f2235547af57b", - "StageName": "Stage" - } - }, "ExplicitApiManagedSwaggerProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiManagedSwaggerDeployment51ba79c0e7" + "Ref": "ExplicitApiManagedSwaggerDeploymentfe9c2c09a2" }, "RestApiId": { "Ref": "ExplicitApiManagedSwagger" @@ -22,13 +18,13 @@ "StageName": "Prod" } }, - "ExplicitApiDefinitionBodyDeploymentcb68c305fb": { + "ExplicitApiManagedSwaggerDeploymentfe9c2c09a2": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ExplicitApiDefinitionBody" + "Ref": "ExplicitApiManagedSwagger" }, - "Description": "RestApi deployment id: cb68c305fb80d8e723c6c5d51a7b62462a25f5ba", + "Description": "RestApi deployment id: fe9c2c09a27ce00c2fa53d5a491cf343e6a3278e", "StageName": "Stage" } }, @@ -39,6 +35,7 @@ "paths": {}, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ + "image/jpeg", "image/jpg", { "Fn::Join": [ @@ -53,17 +50,18 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1jpeg", + "image~1jpg", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "application/json" + "application~1json" ], "EndpointConfiguration": { "Types": [ @@ -75,11 +73,21 @@ } } }, + "ExplicitApiDefinitionBodyDeployment1f26996adb": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApiDefinitionBody" + }, + "Description": "RestApi deployment id: 1f26996adbe5077359ecb2bb0688a9cc0ae8e4fc", + "StageName": "Stage" + } + }, "ExplicitApiDefinitionBodyProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDefinitionBodyDeploymentcb68c305fb" + "Ref": "ExplicitApiDefinitionBodyDeployment1f26996adb" }, "RestApiId": { "Ref": "ExplicitApiDefinitionBody" @@ -100,6 +108,7 @@ "paths": {}, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ + "image/jpeg", "image/jpg", { "Fn::Join": [ @@ -114,17 +123,18 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1jpeg", + "image~1jpg", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "image/gif" + "image~1gif" ], "EndpointConfiguration": { "Types": [ @@ -137,4 +147,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-us-gov/api_with_binary_media_types.json b/tests/translator/output/aws-us-gov/api_with_binary_media_types.json index 5ca64cccb7..7ebb493c39 100644 --- a/tests/translator/output/aws-us-gov/api_with_binary_media_types.json +++ b/tests/translator/output/aws-us-gov/api_with_binary_media_types.json @@ -1,4 +1,10 @@ { + "Parameters": { + "BMT": { + "Default": "image~1jpg", + "Type": "String" + } + }, "Resources": { "ImplicitApiFunction": { "Type": "AWS::Lambda::Function", @@ -103,17 +109,18 @@ "Type": "AWS::ApiGateway::RestApi", "Properties": { "BinaryMediaTypes": [ - "image/jpg", + "image~1gif", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "image/gif" + "application~1octet-stream", + "image~1jpg" ], "EndpointConfiguration": { "Types": [ @@ -145,7 +152,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentea8de7b9f0" + "Ref": "ServerlessRestApiDeployment9746c8328e" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -153,13 +160,13 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeploymentea8de7b9f0": { + "ServerlessRestApiDeployment9746c8328e": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: ea8de7b9f04eec70c7dba6863ed6ff707ea129de", + "Description": "RestApi deployment id: 9746c8328eca81d7b29fed89d9203021b42242ec", "StageName": "Stage" } }, @@ -189,7 +196,7 @@ }, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ - "image/jpg", + "image/gif", { "Fn::Join": [ "/", @@ -202,10 +209,10 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1gif", { "Fn::Join": [ - "/", + "~1", [ "image", "png" @@ -224,4 +231,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-us-gov/api_with_binary_media_types_definition_body.json b/tests/translator/output/aws-us-gov/api_with_binary_media_types_definition_body.json index 0e654720a9..75b031c547 100644 --- a/tests/translator/output/aws-us-gov/api_with_binary_media_types_definition_body.json +++ b/tests/translator/output/aws-us-gov/api_with_binary_media_types_definition_body.json @@ -1,20 +1,16 @@ { + "Parameters": { + "BMT": { + "Default": "image~1jpeg", + "Type": "String" + } + }, "Resources": { - "ExplicitApiManagedSwaggerDeployment51ba79c0e7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApiManagedSwagger" - }, - "Description": "RestApi deployment id: 51ba79c0e7185c019037fb7f9f9f2235547af57b", - "StageName": "Stage" - } - }, "ExplicitApiManagedSwaggerProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiManagedSwaggerDeployment51ba79c0e7" + "Ref": "ExplicitApiManagedSwaggerDeploymentfe9c2c09a2" }, "RestApiId": { "Ref": "ExplicitApiManagedSwagger" @@ -22,13 +18,13 @@ "StageName": "Prod" } }, - "ExplicitApiDefinitionBodyDeploymentcb68c305fb": { + "ExplicitApiManagedSwaggerDeploymentfe9c2c09a2": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ExplicitApiDefinitionBody" + "Ref": "ExplicitApiManagedSwagger" }, - "Description": "RestApi deployment id: cb68c305fb80d8e723c6c5d51a7b62462a25f5ba", + "Description": "RestApi deployment id: fe9c2c09a27ce00c2fa53d5a491cf343e6a3278e", "StageName": "Stage" } }, @@ -39,6 +35,7 @@ "paths": {}, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ + "image/jpeg", "image/jpg", { "Fn::Join": [ @@ -53,17 +50,18 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1jpeg", + "image~1jpg", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "application/json" + "application~1json" ], "EndpointConfiguration": { "Types": [ @@ -75,11 +73,21 @@ } } }, + "ExplicitApiDefinitionBodyDeployment1f26996adb": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApiDefinitionBody" + }, + "Description": "RestApi deployment id: 1f26996adbe5077359ecb2bb0688a9cc0ae8e4fc", + "StageName": "Stage" + } + }, "ExplicitApiDefinitionBodyProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDefinitionBodyDeploymentcb68c305fb" + "Ref": "ExplicitApiDefinitionBodyDeployment1f26996adb" }, "RestApiId": { "Ref": "ExplicitApiDefinitionBody" @@ -100,6 +108,7 @@ "paths": {}, "swagger": "2.0", "x-amazon-apigateway-binary-media-types": [ + "image/jpeg", "image/jpg", { "Fn::Join": [ @@ -114,17 +123,18 @@ ] }, "BinaryMediaTypes": [ - "image/jpg", + "image~1jpeg", + "image~1jpg", { "Fn::Join": [ - "/", + "~1", [ "image", "png" ] ] }, - "image/gif" + "image~1gif" ], "EndpointConfiguration": { "Types": [ @@ -137,4 +147,4 @@ } } } -} \ No newline at end of file +} From 5f886df0045823e3768030dfbaa9051793741db3 Mon Sep 17 00:00:00 2001 From: gomi_ningen Date: Sat, 27 Jul 2019 02:44:53 +0900 Subject: [PATCH 17/31] fix: fix lambda permission for API path parameters (#992) --- samtranslator/model/eventsources/push.py | 2 +- .../eventsources/test_api_event_source.py | 30 ++++ .../input/api_with_path_parameters.yaml | 20 +++ .../output/api_with_path_parameters.json | 120 ++++++++++++++++ .../aws-cn/api_with_path_parameters.json | 128 ++++++++++++++++++ .../aws-us-gov/api_with_path_parameters.json | 128 ++++++++++++++++++ tests/translator/test_translator.py | 1 + 7 files changed, 428 insertions(+), 1 deletion(-) create mode 100644 tests/translator/input/api_with_path_parameters.yaml create mode 100644 tests/translator/output/api_with_path_parameters.json create mode 100644 tests/translator/output/aws-cn/api_with_path_parameters.json create mode 100644 tests/translator/output/aws-us-gov/api_with_path_parameters.json diff --git a/samtranslator/model/eventsources/push.py b/samtranslator/model/eventsources/push.py index 17aa68f384..d70c7bb37f 100644 --- a/samtranslator/model/eventsources/push.py +++ b/samtranslator/model/eventsources/push.py @@ -502,7 +502,7 @@ def _get_permission(self, resources_to_link, stage, suffix): if not stage or not suffix: raise RuntimeError("Could not add permission to lambda function.") - path = path.replace('{proxy+}', '*') + path = re.sub(r'{([a-zA-Z0-9._-]+|proxy\+)}', '*', path) method = '*' if self.Method.lower() == 'any' else self.Method.upper() api_id = self.RestApiId diff --git a/tests/model/eventsources/test_api_event_source.py b/tests/model/eventsources/test_api_event_source.py index df240b6fad..92d946bf39 100644 --- a/tests/model/eventsources/test_api_event_source.py +++ b/tests/model/eventsources/test_api_event_source.py @@ -51,6 +51,36 @@ def test_get_permission_with_trailing_slash(self): self.assertEqual(arn, "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/foo") + @patch("boto3.session.Session.region_name", "eu-west-2") + def test_get_permission_with_path_parameter(self): + self.api_event_source.Path = "/foo/{userId}/bar" + cfn = self.api_event_source.to_cloudformation(function=self.func, explicit_api={}) + + perm = cfn[0] + self.assertIsInstance(perm, LambdaPermission) + + try: + arn = self._extract_path_from_arn("{}PermissionTest".format(self.logical_id), perm) + except AttributeError: + self.fail("Permission class isn't valid") + + self.assertEqual(arn, "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/foo/*/bar") + + @patch("boto3.session.Session.region_name", "eu-west-2") + def test_get_permission_with_proxy_resource(self): + self.api_event_source.Path = "/foo/{proxy+}" + cfn = self.api_event_source.to_cloudformation(function=self.func, explicit_api={}) + + perm = cfn[0] + self.assertIsInstance(perm, LambdaPermission) + + try: + arn = self._extract_path_from_arn("{}PermissionTest".format(self.logical_id), perm) + except AttributeError: + self.fail("Permission class isn't valid") + + self.assertEqual(arn, "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/foo/*") + @patch("boto3.session.Session.region_name", "eu-west-2") def test_get_permission_with_just_slash(self): self.api_event_source.Path = "/" diff --git a/tests/translator/input/api_with_path_parameters.yaml b/tests/translator/input/api_with_path_parameters.yaml new file mode 100644 index 0000000000..4e1b751051 --- /dev/null +++ b/tests/translator/input/api_with_path_parameters.yaml @@ -0,0 +1,20 @@ +Resources: + HtmlFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://sam-demo-bucket/member_portal.zip + Handler: index.gethtml + Runtime: nodejs4.3 + Events: + GetHtml: + Type: Api + Properties: + RestApiId: HtmlApi + Path: /{prameter}/resources + Method: get + + HtmlApi: + Type: AWS::Serverless::Api + Properties: + StageName: Prod + DefinitionUri: s3://sam-demo-bucket/webpage_swagger.json diff --git a/tests/translator/output/api_with_path_parameters.json b/tests/translator/output/api_with_path_parameters.json new file mode 100644 index 0000000000..e9c4f7e149 --- /dev/null +++ b/tests/translator/output/api_with_path_parameters.json @@ -0,0 +1,120 @@ +{ + "Resources": { + "HtmlFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "HtmlApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "HtmlApiDeploymentf117c932f7" + }, + "RestApiId": { + "Ref": "HtmlApi" + }, + "StageName": "Prod" + } + }, + "HtmlFunctionGetHtmlPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "HtmlFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources", + { + "__Stage__": "Prod", + "__ApiId__": "HtmlApi" + } + ] + } + } + }, + "HtmlFunctionGetHtmlPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "HtmlFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources", + { + "__Stage__": "*", + "__ApiId__": "HtmlApi" + } + ] + } + } + }, + "HtmlApiDeploymentf117c932f7": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "HtmlApi" + }, + "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", + "StageName": "Stage" + } + }, + "HtmlApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "BodyS3Location": { + "Bucket": "sam-demo-bucket", + "Key": "webpage_swagger.json" + } + } + }, + "HtmlFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "member_portal.zip" + }, + "Handler": "index.gethtml", + "Role": { + "Fn::GetAtt": [ + "HtmlFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs4.3", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_path_parameters.json b/tests/translator/output/aws-cn/api_with_path_parameters.json new file mode 100644 index 0000000000..f8914fdb13 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_path_parameters.json @@ -0,0 +1,128 @@ +{ + "Resources": { + "HtmlFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "HtmlApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "HtmlApiDeploymentf117c932f7" + }, + "RestApiId": { + "Ref": "HtmlApi" + }, + "StageName": "Prod" + } + }, + "HtmlFunctionGetHtmlPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "HtmlFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources", + { + "__Stage__": "Prod", + "__ApiId__": "HtmlApi" + } + ] + } + } + }, + "HtmlFunctionGetHtmlPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "HtmlFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources", + { + "__Stage__": "*", + "__ApiId__": "HtmlApi" + } + ] + } + } + }, + "HtmlApiDeploymentf117c932f7": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "HtmlApi" + }, + "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", + "StageName": "Stage" + } + }, + "HtmlApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "BodyS3Location": { + "Bucket": "sam-demo-bucket", + "Key": "webpage_swagger.json" + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "HtmlFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "member_portal.zip" + }, + "Handler": "index.gethtml", + "Role": { + "Fn::GetAtt": [ + "HtmlFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs4.3", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_path_parameters.json b/tests/translator/output/aws-us-gov/api_with_path_parameters.json new file mode 100644 index 0000000000..390e6c87e8 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_path_parameters.json @@ -0,0 +1,128 @@ +{ + "Resources": { + "HtmlFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "HtmlApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "HtmlApiDeploymentf117c932f7" + }, + "RestApiId": { + "Ref": "HtmlApi" + }, + "StageName": "Prod" + } + }, + "HtmlFunctionGetHtmlPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "HtmlFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources", + { + "__Stage__": "Prod", + "__ApiId__": "HtmlApi" + } + ] + } + } + }, + "HtmlFunctionGetHtmlPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "HtmlFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources", + { + "__Stage__": "*", + "__ApiId__": "HtmlApi" + } + ] + } + } + }, + "HtmlApiDeploymentf117c932f7": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "HtmlApi" + }, + "Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289", + "StageName": "Stage" + } + }, + "HtmlApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "BodyS3Location": { + "Bucket": "sam-demo-bucket", + "Key": "webpage_swagger.json" + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "HtmlFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "member_portal.zip" + }, + "Handler": "index.gethtml", + "Role": { + "Fn::GetAtt": [ + "HtmlFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs4.3", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + } + } +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index d07822ef0f..bc8a90f6f7 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -247,6 +247,7 @@ class TestTranslatorEndToEnd(TestCase): 'api_with_auth_and_conditions_all_max', 'api_with_apikey_default_override', 'api_with_apikey_required', + 'api_with_path_parameters', ], [ ("aws", "ap-southeast-1"), From 0a74002309e6b8cdfa7ea33a82a9d2cc39c00093 Mon Sep 17 00:00:00 2001 From: praneetap Date: Mon, 29 Jul 2019 16:06:07 -0700 Subject: [PATCH 18/31] fix merge conflict --- samtranslator/model/api/api_generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py index 98c580c995..8d15bbbbaa 100644 --- a/samtranslator/model/api/api_generator.py +++ b/samtranslator/model/api/api_generator.py @@ -120,7 +120,7 @@ def _construct_rest_api(self): rest_api.BodyS3Location = self._construct_body_s3_dict() elif self.definition_body: # # Post Process OpenApi Auth Settings - self.definition_body = self._openapi_auth_postprocess(self.definition_body) + self.definition_body = self._openapi_postprocess(self.definition_body) rest_api.Body = self.definition_body if self.name: From d4b955e21912bbab454ec42b23bde76c76e91488 Mon Sep 17 00:00:00 2001 From: Jacob Fuss <32497805+jfuss@users.noreply.github.com> Date: Tue, 30 Jul 2019 10:56:07 -0700 Subject: [PATCH 19/31] chore: fix copyright in LICENSE (#1041) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 8dada3edaf..6474801f62 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 71de14ac03f77513934b0ebd57f076572fea0611 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2019 11:01:41 -0700 Subject: [PATCH 20/31] chore(deps-dev): bump lodash (#1048) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.13. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.13) Signed-off-by: dependabot[bot] --- .../apps/api-gateway-multiple-origin-cors/package-lock.json | 6 +++--- examples/apps/api-gateway-multiple-origin-cors/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/apps/api-gateway-multiple-origin-cors/package-lock.json b/examples/apps/api-gateway-multiple-origin-cors/package-lock.json index 9287383682..3a6a0fc546 100644 --- a/examples/apps/api-gateway-multiple-origin-cors/package-lock.json +++ b/examples/apps/api-gateway-multiple-origin-cors/package-lock.json @@ -3151,9 +3151,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==", "dev": true }, "lodash.sortby": { diff --git a/examples/apps/api-gateway-multiple-origin-cors/package.json b/examples/apps/api-gateway-multiple-origin-cors/package.json index e2c80cd073..d87477c793 100644 --- a/examples/apps/api-gateway-multiple-origin-cors/package.json +++ b/examples/apps/api-gateway-multiple-origin-cors/package.json @@ -9,7 +9,7 @@ "author": "", "devDependencies": { "jest": "^23.1.0", - "lodash": ">=4.17.11", + "lodash": ">=4.17.13", "merge": ">=1.2.1" }, "jest": { From 8c0c0a0e2b4fa9fbfb3069ae4d2f8ffe67676ff3 Mon Sep 17 00:00:00 2001 From: gomi_ningen Date: Wed, 31 Jul 2019 03:06:28 +0900 Subject: [PATCH 21/31] fix(examples): remove hardcoded region/stack name from api_cognito_auth example (#1049) --- examples/2016-10-31/api_cognito_auth/package.json | 8 ++++---- examples/2016-10-31/api_cognito_auth/template.yaml | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/2016-10-31/api_cognito_auth/package.json b/examples/2016-10-31/api_cognito_auth/package.json index 997222c19a..6bd1d43b3a 100644 --- a/examples/2016-10-31/api_cognito_auth/package.json +++ b/examples/2016-10-31/api_cognito_auth/package.json @@ -19,12 +19,12 @@ "configure-cognito-user-pool": "npm run set-cognito-user-pool-id && npm run set-cognito-user-pool-client-id && npm run set-api-id && npm run set-api-url && npm run update-user-pool-client && npm run create-user-pool-domain", "set-cognito-user-pool-id": "npm config set COGNITO_USER_POOL_ID $(aws cloudformation describe-stacks --stack-name $(npm config get STACK_NAME) --query 'Stacks[].Outputs[?OutputKey==`CognitoUserPoolId`].OutputValue' --output text)", "set-cognito-user-pool-client-id": "npm config set COGNITO_USER_POOL_CLIENT_ID $(aws cloudformation describe-stacks --stack-name $(npm config get STACK_NAME) --query 'Stacks[].Outputs[?OutputKey==`CognitoUserPoolClientId`].OutputValue' --output text)", - "set-api-url": "npm config set API_URL $(aws cloudformation describe-stacks --stack-name sam-example-api-cognito-auth --query 'Stacks[].Outputs[?OutputKey==`ApiUrl`].OutputValue' --output text)", - "set-api-id": "npm config set API_ID $(aws cloudformation describe-stacks --stack-name sam-example-api-cognito-auth --query 'Stacks[].Outputs[?OutputKey==`ApiId`].OutputValue' --output text)", + "set-api-url": "npm config set API_URL $(aws cloudformation describe-stacks --stack-name $(npm config get STACK_NAME) --query 'Stacks[].Outputs[?OutputKey==`ApiUrl`].OutputValue' --output text)", + "set-api-id": "npm config set API_ID $(aws cloudformation describe-stacks --stack-name $(npm config get STACK_NAME) --query 'Stacks[].Outputs[?OutputKey==`ApiId`].OutputValue' --output text)", "update-user-pool-client": "aws cognito-idp update-user-pool-client --user-pool-id $(npm config get COGNITO_USER_POOL_ID) --client-id $(npm config get COGNITO_USER_POOL_CLIENT_ID) --supported-identity-providers COGNITO --callback-urls \"[\\\"$(npm config get API_URL)\\\"]\" --allowed-o-auth-flows code implicit --allowed-o-auth-scopes openid email --allowed-o-auth-flows-user-pool-client", "create-user-pool-domain": "aws cognito-idp create-user-pool-domain --domain $(npm config get API_ID) --user-pool-id $(npm config get COGNITO_USER_POOL_ID)", - "open-signup-page": "open \"https://$(npm config get API_ID).auth.us-east-1.amazoncognito.com/signup?response_type=code&client_id=$(npm config get COGNITO_USER_POOL_CLIENT_ID)&redirect_uri=$(npm config get API_URL)\"", - "open-login-page": "open \"https://$(npm config get API_ID).auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=$(npm config get COGNITO_USER_POOL_CLIENT_ID)&redirect_uri=$(npm config get API_URL)\"", + "open-signup-page": "open \"https://$(npm config get API_ID).auth.$(aws cloudformation describe-stacks --stack-name $(npm config get STACK_NAME) --query 'Stacks[].Outputs[?OutputKey==`Region`].OutputValue' --output text).amazoncognito.com/signup?response_type=code&client_id=$(npm config get COGNITO_USER_POOL_CLIENT_ID)&redirect_uri=$(npm config get API_URL)\"", + "open-login-page": "open \"https://$(npm config get API_ID).auth.$(aws cloudformation describe-stacks --stack-name $(npm config get STACK_NAME) --query 'Stacks[].Outputs[?OutputKey==`Region`].OutputValue' --output text).amazoncognito.com/login?response_type=code&client_id=$(npm config get COGNITO_USER_POOL_CLIENT_ID)&redirect_uri=$(npm config get API_URL)\"", "open-api-ui": "open \"$(npm config get API_URL)\"" } } diff --git a/examples/2016-10-31/api_cognito_auth/template.yaml b/examples/2016-10-31/api_cognito_auth/template.yaml index b1dc1dacc3..0b1042f344 100644 --- a/examples/2016-10-31/api_cognito_auth/template.yaml +++ b/examples/2016-10-31/api_cognito_auth/template.yaml @@ -140,6 +140,10 @@ Resources: # UserPool: !Ref MyCognitoUserPool Outputs: + Region: + Description: "Region" + Value: !Ref AWS::Region + ApiId: Description: "API ID" Value: !Ref MyApi From 88047337f7b445453e1b0eebb481ff8389158b4f Mon Sep 17 00:00:00 2001 From: gomi_ningen Date: Wed, 31 Jul 2019 04:31:36 +0900 Subject: [PATCH 22/31] fix: make sure Name and Type exists as a property of PrimaryKey of SimpleTable (#1054) --- samtranslator/model/sam_resources.py | 5 +++++ .../input/error_table_primary_key_missing_name.yaml | 7 +++++++ .../input/error_table_primary_key_missing_type.yaml | 6 ++++++ .../output/error_table_primary_key_missing_name.json | 8 ++++++++ .../output/error_table_primary_key_missing_type.json | 8 ++++++++ tests/translator/test_translator.py | 2 ++ 6 files changed, 36 insertions(+) create mode 100644 tests/translator/input/error_table_primary_key_missing_name.yaml create mode 100644 tests/translator/input/error_table_primary_key_missing_type.yaml create mode 100644 tests/translator/output/error_table_primary_key_missing_name.json create mode 100644 tests/translator/output/error_table_primary_key_missing_type.json diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py index 8bf97994d0..dfacebbecc 100644 --- a/samtranslator/model/sam_resources.py +++ b/samtranslator/model/sam_resources.py @@ -537,6 +537,11 @@ def _construct_dynamodb_table(self): dynamodb_table = DynamoDBTable(self.logical_id, depends_on=self.depends_on, attributes=self.resource_attributes) if self.PrimaryKey: + if 'Name' not in self.PrimaryKey or 'Type' not in self.PrimaryKey: + raise InvalidResourceException( + self.logical_id, + '\'PrimaryKey\' is missing required Property \'Name\' or \'Type\'.' + ) primary_key = { 'AttributeName': self.PrimaryKey['Name'], 'AttributeType': self._convert_attribute_type(self.PrimaryKey['Type']) diff --git a/tests/translator/input/error_table_primary_key_missing_name.yaml b/tests/translator/input/error_table_primary_key_missing_name.yaml new file mode 100644 index 0000000000..af257bc02f --- /dev/null +++ b/tests/translator/input/error_table_primary_key_missing_name.yaml @@ -0,0 +1,7 @@ +Resources: + Table: + Type: AWS::Serverless::SimpleTable + Properties: + PrimaryKey: + Id: id + Type: String diff --git a/tests/translator/input/error_table_primary_key_missing_type.yaml b/tests/translator/input/error_table_primary_key_missing_type.yaml new file mode 100644 index 0000000000..3ff377e3b4 --- /dev/null +++ b/tests/translator/input/error_table_primary_key_missing_type.yaml @@ -0,0 +1,6 @@ +Resources: + Table: + Type: AWS::Serverless::SimpleTable + Properties: + PrimaryKey: + Name: id diff --git a/tests/translator/output/error_table_primary_key_missing_name.json b/tests/translator/output/error_table_primary_key_missing_name.json new file mode 100644 index 0000000000..de5a712c21 --- /dev/null +++ b/tests/translator/output/error_table_primary_key_missing_name.json @@ -0,0 +1,8 @@ +{ + "errors": [ + { + "errorMessage": "Resource with id [Table] is invalid. 'PrimaryKey' is missing required Property 'Name' or 'Type'." + } + ], + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [Table] is invalid. 'PrimaryKey' is missing required Property 'Name' or 'Type'." +} \ No newline at end of file diff --git a/tests/translator/output/error_table_primary_key_missing_type.json b/tests/translator/output/error_table_primary_key_missing_type.json new file mode 100644 index 0000000000..de5a712c21 --- /dev/null +++ b/tests/translator/output/error_table_primary_key_missing_type.json @@ -0,0 +1,8 @@ +{ + "errors": [ + { + "errorMessage": "Resource with id [Table] is invalid. 'PrimaryKey' is missing required Property 'Name' or 'Type'." + } + ], + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [Table] is invalid. 'PrimaryKey' is missing required Property 'Name' or 'Type'." +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index bc8a90f6f7..957748715f 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -457,6 +457,8 @@ def _generate_new_deployment_hash(self, logical_id, dict_to_hash, rest_api_to_sw 'error_multiple_resource_errors', 'error_s3_not_in_template', 'error_table_invalid_attributetype', + 'error_table_primary_key_missing_name', + 'error_table_primary_key_missing_type', 'error_invalid_resource_parameters', 'error_reserved_sam_tag', 'existing_event_logical_id', From 9ebe0b0e49bf11c92c7293181db62d3c9f75ef0d Mon Sep 17 00:00:00 2001 From: Keeton Hodgson Date: Wed, 31 Jul 2019 21:02:35 -0700 Subject: [PATCH 23/31] chore: bump version to 1.14.0 (#1055) --- samtranslator/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samtranslator/__init__.py b/samtranslator/__init__.py index 84c54b7482..e4f2ad49d9 100644 --- a/samtranslator/__init__.py +++ b/samtranslator/__init__.py @@ -1 +1 @@ -__version__ = '1.13.0' +__version__ = '1.14.0' From 4df24a365f3aa1109b38696fd5118fe8cb8a462a Mon Sep 17 00:00:00 2001 From: praneetap Date: Wed, 31 Jul 2019 23:12:28 -0700 Subject: [PATCH 24/31] fix: redeploy api if the openapi version changes (#1056) --- samtranslator/model/api/api_generator.py | 2 +- samtranslator/model/apigateway.py | 10 +- .../output/api_request_model_openapi_3.json | 20 +-- .../api_with_apikey_required_openapi_3.json | 20 +-- .../api_with_auth_all_maximum_openapi_3.json | 20 +-- .../api_with_auth_all_minimum_openapi.json | 128 +++++++++--------- .../output/api_with_cors_openapi_3.json | 16 +-- ..._with_gateway_responses_all_openapi_3.json | 20 +-- .../output/api_with_open_api_version.json | 50 +++---- .../output/api_with_open_api_version_2.json | 40 +++--- ..._with_openapi_definition_body_no_flag.json | 20 +-- .../aws-cn/api_request_model_openapi_3.json | 6 +- .../api_with_apikey_required_openapi_3.json | 6 +- .../api_with_auth_all_maximum_openapi_3.json | 50 +++---- .../api_with_auth_all_minimum_openapi.json | 86 ++++++------ .../aws-cn/api_with_cors_openapi_3.json | 28 ++-- ..._with_gateway_responses_all_openapi_3.json | 20 +-- .../aws-cn/api_with_open_api_version.json | 28 ++-- .../aws-cn/api_with_open_api_version_2.json | 40 +++--- ..._with_openapi_definition_body_no_flag.json | 20 +-- .../output/aws-cn/explicit_api_openapi_3.json | 20 +-- .../api_request_model_openapi_3.json | 22 +-- .../api_with_apikey_required_openapi_3.json | 20 +-- .../api_with_auth_all_maximum_openapi_3.json | 20 +-- .../api_with_auth_all_minimum_openapi.json | 120 ++++++++-------- .../aws-us-gov/api_with_cors_openapi_3.json | 40 +++--- ..._with_gateway_responses_all_openapi_3.json | 22 +-- .../aws-us-gov/api_with_open_api_version.json | 38 +++--- .../api_with_open_api_version_2.json | 48 +++---- ..._with_openapi_definition_body_no_flag.json | 20 +-- .../aws-us-gov/explicit_api_openapi_3.json | 20 +-- .../output/explicit_api_openapi_3.json | 20 +-- 32 files changed, 522 insertions(+), 518 deletions(-) diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py index 8d15bbbbaa..9e21d314a0 100644 --- a/samtranslator/model/api/api_generator.py +++ b/samtranslator/model/api/api_generator.py @@ -199,7 +199,7 @@ def _construct_stage(self, deployment, swagger): stage.TracingEnabled = self.tracing_enabled if swagger is not None: - deployment.make_auto_deployable(stage, swagger) + deployment.make_auto_deployable(stage, self.open_api_version, swagger) if self.tags is not None: stage.Tags = get_tag_list(self.tags) diff --git a/samtranslator/model/apigateway.py b/samtranslator/model/apigateway.py index 4dac1b4493..27a466d1a3 100644 --- a/samtranslator/model/apigateway.py +++ b/samtranslator/model/apigateway.py @@ -74,9 +74,10 @@ class ApiGatewayDeployment(Resource): "deployment_id": lambda self: ref(self.logical_id), } - def make_auto_deployable(self, stage, swagger=None): + def make_auto_deployable(self, stage, openapi_version=None, swagger=None): """ - Sets up the resource such that it will triggers a re-deployment when Swagger changes + Sets up the resource such that it will trigger a re-deployment when Swagger changes + or the openapi version changes. :param swagger: Dictionary containing the Swagger definition of the API """ @@ -89,7 +90,10 @@ def make_auto_deployable(self, stage, swagger=None): # to prevent redeployment when API has not changed # NOTE: `str(swagger)` is for backwards compatibility. Changing it to a JSON or something will break compat - generator = logical_id_generator.LogicalIdGenerator(self.logical_id, str(swagger)) + hash_input = str(swagger) + if openapi_version: + hash_input = hash_input + str(openapi_version) + generator = logical_id_generator.LogicalIdGenerator(self.logical_id, hash_input) self.logical_id = generator.gen() hash = generator.get_hash(length=40) # Get the full hash self.Description = "RestApi deployment id: {}".format(hash) diff --git a/tests/translator/output/api_request_model_openapi_3.json b/tests/translator/output/api_request_model_openapi_3.json index ce91e1aa79..229354b2a1 100644 --- a/tests/translator/output/api_request_model_openapi_3.json +++ b/tests/translator/output/api_request_model_openapi_3.json @@ -21,6 +21,15 @@ } } }, + "HtmlApiDeployment77aaf3ac13": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "HtmlApi" + }, + "Description": "RestApi deployment id: 77aaf3ac132a9282281fd55bdeac6fe7466e8337" + } + }, "HtmlFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -49,7 +58,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "HtmlApiDeployment47f78fe7d9" + "Ref": "HtmlApiDeployment77aaf3ac13" }, "RestApiId": { "Ref": "HtmlApi" @@ -164,15 +173,6 @@ } } }, - "HtmlApiDeployment47f78fe7d9": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "HtmlApi" - }, - "Description": "RestApi deployment id: 47f78fe7d91eb5d2070674ad77943842c49dab89" - } - }, "HtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { diff --git a/tests/translator/output/api_with_apikey_required_openapi_3.json b/tests/translator/output/api_with_apikey_required_openapi_3.json index e913e63751..d91a848e56 100644 --- a/tests/translator/output/api_with_apikey_required_openapi_3.json +++ b/tests/translator/output/api_with_apikey_required_openapi_3.json @@ -45,6 +45,15 @@ } } }, + "MyApiWithoutAuthDeployment140350c252": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: 140350c2525068ff2e9bb5e7ee0765718974523d" + } + }, "MyApiWithoutAuth": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -91,7 +100,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithoutAuthDeployment741383c56d" + "Ref": "MyApiWithoutAuthDeployment140350c252" }, "RestApiId": { "Ref": "MyApiWithoutAuth" @@ -142,15 +151,6 @@ } ] } - }, - "MyApiWithoutAuthDeployment741383c56d": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithoutAuth" - }, - "Description": "RestApi deployment id: 741383c56de0cab1f561223582a9259cf165b42f" - } } } } \ No newline at end of file diff --git a/tests/translator/output/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/api_with_auth_all_maximum_openapi_3.json index ff6efcd6f9..0009c756ee 100644 --- a/tests/translator/output/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/api_with_auth_all_maximum_openapi_3.json @@ -170,15 +170,6 @@ } } }, - "MyApiDeployment959b43a9ef": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: 959b43a9efc3347ee417e242c5f936bbd40ef663" - } - }, "MyApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -486,7 +477,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeployment959b43a9ef" + "Ref": "MyApiDeploymente181e32adc" }, "RestApiId": { "Ref": "MyApi" @@ -515,6 +506,15 @@ } } }, + "MyApiDeploymente181e32adc": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: e181e32adcccf59d699baf300078344166614113" + } + }, "MyFunctionWithDefaultAuthorizerPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { diff --git a/tests/translator/output/api_with_auth_all_minimum_openapi.json b/tests/translator/output/api_with_auth_all_minimum_openapi.json index ba1b635ff5..2653f2c477 100644 --- a/tests/translator/output/api_with_auth_all_minimum_openapi.json +++ b/tests/translator/output/api_with_auth_all_minimum_openapi.json @@ -54,11 +54,20 @@ } } }, + "MyApiWithLambdaTokenAuthDeployment5100134cea": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaTokenAuth" + }, + "Description": "RestApi deployment id: 5100134cea4b4506bd0894f86bfe775c9903ae82" + } + }, "MyApiWithLambdaRequestAuthProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaRequestAuthDeployment54a6335ed7" + "Ref": "MyApiWithLambdaRequestAuthDeployment195678a2e7" }, "RestApiId": { "Ref": "MyApiWithLambdaRequestAuth" @@ -89,6 +98,15 @@ } } }, + "MyApiWithLambdaRequestAuthDeployment195678a2e7": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaRequestAuth" + }, + "Description": "RestApi deployment id: 195678a2e73ee92ca367f5b4ba814c6e0022df01" + } + }, "MyFnLambdaRequestPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -131,13 +149,25 @@ } } }, - "MyApiWithLambdaTokenAuthDeployment2ac4484273": { - "Type": "AWS::ApiGateway::Deployment", + "MyFnCognitoPermissionTest": { + "Type": "AWS::Lambda::Permission", "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaTokenAuth" + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFn" }, - "Description": "RestApi deployment id: 2ac4484273f55c601b17c8491ffad73a979b2aeb" + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/cognito", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithCognitoAuth" + } + } + ] + } } }, "MyAuthFn": { @@ -163,15 +193,6 @@ ] } }, - "MyApiWithCognitoAuthDeployment2eadfec019": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithCognitoAuth" - }, - "Description": "RestApi deployment id: 2eadfec019d342cb7f6d66f595b9ab88e82fa00a" - } - }, "MyFnRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -200,7 +221,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithCognitoAuthDeployment2eadfec019" + "Ref": "MyApiWithCognitoAuthDeploymentcae360c856" }, "RestApiId": { "Ref": "MyApiWithCognitoAuth" @@ -229,36 +250,6 @@ } } }, - "MyApiWithLambdaRequestAuthDeployment54a6335ed7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaRequestAuth" - }, - "Description": "RestApi deployment id: 54a6335ed76c2060eaf1fff2ff6522f20ecaef0f" - } - }, - "MyUserPool": { - "Type": "AWS::Cognito::UserPool", - "Properties": { - "UsernameAttributes": [ - "email" - ], - "UserPoolName": "UserPoolName", - "Policies": { - "PasswordPolicy": { - "MinimumLength": 8 - } - }, - "Schema": [ - { - "AttributeDataType": "String", - "Required": false, - "Name": "email" - } - ] - } - }, "MyApiWithLambdaRequestAuthMyLambdaRequestAuthAuthorizerPermission": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -383,25 +374,34 @@ } } }, - "MyFnCognitoPermissionTest": { - "Type": "AWS::Lambda::Permission", + "MyApiWithCognitoAuthDeploymentcae360c856": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": { - "Ref": "MyFn" + "RestApiId": { + "Ref": "MyApiWithCognitoAuth" }, - "SourceArn": { - "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/cognito", - { - "__Stage__": "*", - "__ApiId__": { - "Ref": "MyApiWithCognitoAuth" - } - } - ] - } + "Description": "RestApi deployment id: cae360c856d65fceaffb4bf24ebf5c4eac239e53" + } + }, + "MyUserPool": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "UsernameAttributes": [ + "email" + ], + "UserPoolName": "UserPoolName", + "Policies": { + "PasswordPolicy": { + "MinimumLength": 8 + } + }, + "Schema": [ + { + "AttributeDataType": "String", + "Required": false, + "Name": "email" + } + ] } }, "MyFn": { @@ -455,7 +455,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaTokenAuthDeployment2ac4484273" + "Ref": "MyApiWithLambdaTokenAuthDeployment5100134cea" }, "RestApiId": { "Ref": "MyApiWithLambdaTokenAuth" diff --git a/tests/translator/output/api_with_cors_openapi_3.json b/tests/translator/output/api_with_cors_openapi_3.json index 02d888397a..16f4ca8a6e 100644 --- a/tests/translator/output/api_with_cors_openapi_3.json +++ b/tests/translator/output/api_with_cors_openapi_3.json @@ -253,7 +253,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment36174ded39" + "Ref": "ServerlessRestApiDeployment3e214d1cac" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -265,7 +265,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment3a5a78688c" + "Ref": "ExplicitApiDeploymentbabea58445" }, "RestApiId": { "Ref": "ExplicitApi" @@ -318,13 +318,13 @@ } } }, - "ExplicitApiDeployment3a5a78688c": { + "ServerlessRestApiDeployment3e214d1cac": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ExplicitApi" + "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 3a5a78688c9bc377d53aa4153a11f0c4f6e7364c" + "Description": "RestApi deployment id: 3e214d1cac2e110e6e28a389a4ba80057c5f0842" } }, "RestApiFunction": { @@ -350,13 +350,13 @@ ] } }, - "ServerlessRestApiDeployment36174ded39": { + "ExplicitApiDeploymentbabea58445": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ServerlessRestApi" + "Ref": "ExplicitApi" }, - "Description": "RestApi deployment id: 36174ded3978092f96669107074db6caeaaafddd" + "Description": "RestApi deployment id: babea584458ca2e980baa334bd70f8b193375895" } }, "ServerlessRestApi": { diff --git a/tests/translator/output/api_with_gateway_responses_all_openapi_3.json b/tests/translator/output/api_with_gateway_responses_all_openapi_3.json index 357ad0e911..a5a75340d8 100644 --- a/tests/translator/output/api_with_gateway_responses_all_openapi_3.json +++ b/tests/translator/output/api_with_gateway_responses_all_openapi_3.json @@ -23,15 +23,6 @@ ] } }, - "ExplicitApiDeployment47d77987a3": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 47d77987a3152a97c89d794f2682485b9dafde5d" - } - }, "FunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -104,11 +95,20 @@ } } }, + "ExplicitApiDeployment23e7ed36e4": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 23e7ed36e41c87979e26864331c8fbd0a22d2906" + } + }, "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment47d77987a3" + "Ref": "ExplicitApiDeployment23e7ed36e4" }, "RestApiId": { "Ref": "ExplicitApi" diff --git a/tests/translator/output/api_with_open_api_version.json b/tests/translator/output/api_with_open_api_version.json index 1224c70597..4a754b73b0 100644 --- a/tests/translator/output/api_with_open_api_version.json +++ b/tests/translator/output/api_with_open_api_version.json @@ -68,15 +68,6 @@ } } }, - "ExplicitApiDeployment01dd43a75f": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 01dd43a75fc0e125c678d20749bacde95d723928" - } - }, "ImplicitApiFunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -113,30 +104,48 @@ } } }, - "ServerlessRestApiProdStage": { + "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment82c7b2e316" + "Ref": "ExplicitApiDeployment1e9fbca603" }, "RestApiId": { - "Ref": "ServerlessRestApi" + "Ref": "ExplicitApi" }, "StageName": "Prod" } }, - "ExplicitApiProdStage": { + "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment01dd43a75f" + "Ref": "ServerlessRestApiDeploymentacd2d469b0" }, "RestApiId": { - "Ref": "ExplicitApi" + "Ref": "ServerlessRestApi" }, "StageName": "Prod" } }, + "ExplicitApiDeployment1e9fbca603": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 1e9fbca603907b0cfb3e8164fa9d4c3b95b4272d" + } + }, + "ServerlessRestApiDeploymentacd2d469b0": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: acd2d469b0bc58a0e115764c4385e0254ae0bd7e" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -204,15 +213,6 @@ "openapi": "3.0.1" } } - }, - "ServerlessRestApiDeployment82c7b2e316": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: 82c7b2e3162ebd01c9b3ccaa1fafa5cc1df94a68" - } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/api_with_open_api_version_2.json b/tests/translator/output/api_with_open_api_version_2.json index ba6e1a5fbe..f1367adb84 100644 --- a/tests/translator/output/api_with_open_api_version_2.json +++ b/tests/translator/output/api_with_open_api_version_2.json @@ -89,6 +89,15 @@ } } }, + "ExplicitApiDeployment323af4d2f5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 323af4d2f576d27b094bb4e64e6fd8ada81b630b" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -104,20 +113,11 @@ } } }, - "ServerlessRestApiDeploymentb9bf7835be": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: b9bf7835be8ea0cb2c188b846e03ff6f79f4d330" - } - }, "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment5332c373d4" + "Ref": "ExplicitApiDeployment323af4d2f5" }, "RestApiId": { "Ref": "ExplicitApi" @@ -129,7 +129,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentb9bf7835be" + "Ref": "ServerlessRestApiDeployment3644a4133f" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -137,6 +137,15 @@ "StageName": "Prod" } }, + "ServerlessRestApiDeployment3644a4133f": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 3644a4133f18ca79220abe30b7f27b7e9a55cd06" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -204,15 +213,6 @@ "swagger": "2.0" } } - }, - "ExplicitApiDeployment5332c373d4": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 5332c373d45c69e6c0f562b4a419aa8eb311adc7" - } } } } \ No newline at end of file diff --git a/tests/translator/output/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/api_with_openapi_definition_body_no_flag.json index abc141ca3d..b810aa9690 100644 --- a/tests/translator/output/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/api_with_openapi_definition_body_no_flag.json @@ -47,15 +47,6 @@ } } }, - "ExplicitApiDeployment9252467a1e": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1" - } - }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -172,7 +163,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment9252467a1e" + "Ref": "ExplicitApiDeployment748947f06a" } } }, @@ -218,6 +209,15 @@ ] } }, + "ExplicitApiDeployment748947f06a": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 748947f06a1a8de71a295f51af31d94b932fe2fc" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-cn/api_request_model_openapi_3.json b/tests/translator/output/aws-cn/api_request_model_openapi_3.json index 63e5818f49..c08d5f6037 100644 --- a/tests/translator/output/aws-cn/api_request_model_openapi_3.json +++ b/tests/translator/output/aws-cn/api_request_model_openapi_3.json @@ -49,7 +49,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "HtmlApiDeployment78cd64f7cb" + "Ref": "HtmlApiDeploymentdcba4b4073" }, "RestApiId": { "Ref": "HtmlApi" @@ -172,13 +172,13 @@ } } }, - "HtmlApiDeployment78cd64f7cb": { + "HtmlApiDeploymentdcba4b4073": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "HtmlApi" }, - "Description": "RestApi deployment id: 78cd64f7cb1e91b0fda215267bac0aac70b20b1b" + "Description": "RestApi deployment id: dcba4b407341ea76ae262bf7fd11078328e52168" } }, "HtmlFunctionGetHtmlPermissionTest": { diff --git a/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json b/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json index 0ecfb136d8..795017bf90 100644 --- a/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json @@ -45,13 +45,13 @@ } } }, - "MyApiWithoutAuthDeployment859a8b8388": { + "MyApiWithoutAuthDeployment357a42f0aa": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "MyApiWithoutAuth" }, - "Description": "RestApi deployment id: 859a8b8388c863dbda96b384cefea4ac988f5f81" + "Description": "RestApi deployment id: 357a42f0aa7732edc83e7064dab8dc4050abb0e9" } }, "MyApiWithoutAuth": { @@ -108,7 +108,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithoutAuthDeployment859a8b8388" + "Ref": "MyApiWithoutAuthDeployment357a42f0aa" }, "RestApiId": { "Ref": "MyApiWithoutAuth" diff --git a/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json index 33c63f8623..38aca8c4e5 100644 --- a/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json @@ -146,6 +146,15 @@ } } }, + "MyApiDeploymentc3ee011ecc": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: c3ee011ecc11fa841524767079400e1fb8a3d57c" + } + }, "MyFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -382,28 +391,16 @@ } } }, - "MyApiDeploymente3164c0eda": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: e3164c0edaf0d9fc342c47f30edf05040f87af8b" - } - }, - "MyFunctionWithLambdaRequestAuthorizerPermissionTest": { + "MyApiMyLambdaTokenAuthAuthorizerPermission": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:invokeFunction", "Principal": "apigateway.amazonaws.com", - "FunctionName": { - "Ref": "MyFunction" - }, + "FunctionName": "arn:aws", "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { - "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -412,7 +409,7 @@ } } }, - "MyFunctionWithLambdaRequestAuthorizerPermissionProd": { + "MyFunctionWithLambdaRequestAuthorizerPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:invokeFunction", @@ -424,7 +421,7 @@ "Fn::Sub": [ "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "Prod", + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -433,7 +430,7 @@ } } }, - "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { + "MyFunctionWithLambdaRequestAuthorizerPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:invokeFunction", @@ -443,9 +440,9 @@ }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/DELETE/users", { - "__Stage__": "*", + "__Stage__": "Prod", "__ApiId__": { "Ref": "MyApi" } @@ -454,16 +451,19 @@ } } }, - "MyApiMyLambdaTokenAuthNoneFunctionInvokeRoleAuthorizerPermission": { + "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:invokeFunction", "Principal": "apigateway.amazonaws.com", - "FunctionName": "arn:aws", + "FunctionName": { + "Ref": "MyFunction" + }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/users", { + "__Stage__": "*", "__ApiId__": { "Ref": "MyApi" } @@ -472,7 +472,7 @@ } } }, - "MyApiMyLambdaTokenAuthAuthorizerPermission": { + "MyApiMyLambdaTokenAuthNoneFunctionInvokeRoleAuthorizerPermission": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:invokeFunction", @@ -494,7 +494,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeploymente3164c0eda" + "Ref": "MyApiDeploymentc3ee011ecc" }, "RestApiId": { "Ref": "MyApi" diff --git a/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json b/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json index a7abb6fded..690ae2fe13 100644 --- a/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json +++ b/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json @@ -66,7 +66,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaRequestAuthDeploymentf8f280f2eb" + "Ref": "MyApiWithLambdaRequestAuthDeployment50560e1b93" }, "RestApiId": { "Ref": "MyApiWithLambdaRequestAuth" @@ -74,36 +74,22 @@ "StageName": "Prod" } }, - "MyApiWithLambdaTokenAuthMyLambdaTokenAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", + "MyApiWithLambdaRequestAuthDeployment50560e1b93": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": { - "Fn::GetAtt": [ - "MyAuthFn", - "Arn" - ] + "RestApiId": { + "Ref": "MyApiWithLambdaRequestAuth" }, - "SourceArn": { - "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", - { - "__ApiId__": { - "Ref": "MyApiWithLambdaTokenAuth" - } - } - ] - } + "Description": "RestApi deployment id: 50560e1b93c278b5dedf0adcaf531cde88700103" } }, - "MyApiWithLambdaRequestAuthDeploymentf8f280f2eb": { + "MyApiWithLambdaTokenAuthDeploymente8e324a96a": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "MyApiWithLambdaRequestAuth" + "Ref": "MyApiWithLambdaTokenAuth" }, - "Description": "RestApi deployment id: f8f280f2eb973eb694b872901c9395c3d3e05252" + "Description": "RestApi deployment id: e8e324a96af0eefc9f8b328f9abdb94af12348ed" } }, "MyFnLambdaRequestPermissionTest": { @@ -220,7 +206,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithCognitoAuthDeploymente116f8541f" + "Ref": "MyApiWithCognitoAuthDeployment943c497d0c" }, "RestApiId": { "Ref": "MyApiWithCognitoAuth" @@ -228,6 +214,15 @@ "StageName": "Prod" } }, + "MyApiWithCognitoAuthDeployment943c497d0c": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithCognitoAuth" + }, + "Description": "RestApi deployment id: 943c497d0c89ac6ab9c933c386e68f15b8cde482" + } + }, "MyFnCognitoPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -381,15 +376,6 @@ } } }, - "MyApiWithLambdaTokenAuthDeploymentae2752e462": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaTokenAuth" - }, - "Description": "RestApi deployment id: ae2752e46261b6dac7c962a6a65154ea5189f594" - } - }, "MyUserPool": { "Type": "AWS::Cognito::UserPool", "Properties": { @@ -434,6 +420,29 @@ ] } }, + "MyApiWithLambdaTokenAuthMyLambdaTokenAuthAuthorizerPermission": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Fn::GetAtt": [ + "MyAuthFn", + "Arn" + ] + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + { + "__ApiId__": { + "Ref": "MyApiWithLambdaTokenAuth" + } + } + ] + } + } + }, "MyAuthFnRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -462,7 +471,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaTokenAuthDeploymentae2752e462" + "Ref": "MyApiWithLambdaTokenAuthDeploymente8e324a96a" }, "RestApiId": { "Ref": "MyApiWithLambdaTokenAuth" @@ -537,15 +546,6 @@ "endpointConfigurationTypes": "REGIONAL" } } - }, - "MyApiWithCognitoAuthDeploymente116f8541f": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithCognitoAuth" - }, - "Description": "RestApi deployment id: e116f8541f950bade71c8656c6a8493fd823d35c" - } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_cors_openapi_3.json b/tests/translator/output/aws-cn/api_with_cors_openapi_3.json index 77acdd9cde..6c8f9fbbae 100644 --- a/tests/translator/output/aws-cn/api_with_cors_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_cors_openapi_3.json @@ -261,7 +261,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment5f2f2e0731" + "Ref": "ServerlessRestApiDeployment85d3360729" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -273,7 +273,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment3a5a78688c" + "Ref": "ExplicitApiDeploymentbabea58445" }, "RestApiId": { "Ref": "ExplicitApi" @@ -281,15 +281,6 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeployment5f2f2e0731": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: 5f2f2e07317e5f71e17f2a1f0cb2c1833f881340" - } - }, "RestApiFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -335,13 +326,13 @@ } } }, - "ExplicitApiDeployment3a5a78688c": { + "ServerlessRestApiDeployment85d3360729": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ExplicitApi" + "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 3a5a78688c9bc377d53aa4153a11f0c4f6e7364c" + "Description": "RestApi deployment id: 85d33607297efc01252aeae20f6a000ac2843483" } }, "RestApiFunction": { @@ -367,6 +358,15 @@ ] } }, + "ExplicitApiDeploymentbabea58445": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: babea584458ca2e980baa334bd70f8b193375895" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json b/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json index 8da7e78f03..aa0bfcba55 100644 --- a/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json @@ -107,7 +107,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment4c4177079d" + "Ref": "ExplicitApiDeployment9cf935255f" }, "RestApiId": { "Ref": "ExplicitApi" @@ -115,6 +115,15 @@ "StageName": "Prod" } }, + "ExplicitApiDeployment9cf935255f": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 9cf935255fad6f1e878435583797e0245e85e570" + } + }, "FunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -136,15 +145,6 @@ } } }, - "ExplicitApiDeployment4c4177079d": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 4c4177079dd342a2b71978bd25721b7b774295ad" - } - }, "FunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { diff --git a/tests/translator/output/aws-cn/api_with_open_api_version.json b/tests/translator/output/aws-cn/api_with_open_api_version.json index 647d4ae32c..79b221f463 100644 --- a/tests/translator/output/aws-cn/api_with_open_api_version.json +++ b/tests/translator/output/aws-cn/api_with_open_api_version.json @@ -68,15 +68,6 @@ } } }, - "ExplicitApiDeployment01dd43a75f": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 01dd43a75fc0e125c678d20749bacde95d723928" - } - }, "ImplicitApiFunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -125,7 +116,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentb86b9dad9d" + "Ref": "ServerlessRestApiDeployment1eb1f25f25" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -133,11 +124,20 @@ "StageName": "Prod" } }, + "ExplicitApiDeployment1e9fbca603": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 1e9fbca603907b0cfb3e8164fa9d4c3b95b4272d" + } + }, "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment01dd43a75f" + "Ref": "ExplicitApiDeployment1e9fbca603" }, "RestApiId": { "Ref": "ExplicitApi" @@ -221,14 +221,14 @@ } } }, - "ServerlessRestApiDeploymentb86b9dad9d": { + "ServerlessRestApiDeployment1eb1f25f25": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: b86b9dad9d2fd5286c7b355dbd5350987cf492c1" + "Description": "RestApi deployment id: 1eb1f25f25d73d4340cd16527052e2efcdca8b74" } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_open_api_version_2.json b/tests/translator/output/aws-cn/api_with_open_api_version_2.json index a49aa983b9..4dfd9b7df8 100644 --- a/tests/translator/output/aws-cn/api_with_open_api_version_2.json +++ b/tests/translator/output/aws-cn/api_with_open_api_version_2.json @@ -89,6 +89,15 @@ } } }, + "ServerlessRestApiDeployment2bcbad30d7": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 2bcbad30d76c3d64bfb45cf0c5e883588cf75944" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -112,11 +121,20 @@ } } }, + "ExplicitApiDeployment323af4d2f5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 323af4d2f576d27b094bb4e64e6fd8ada81b630b" + } + }, "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentc444e5d902" + "Ref": "ServerlessRestApiDeployment2bcbad30d7" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -128,7 +146,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment5332c373d4" + "Ref": "ExplicitApiDeployment323af4d2f5" }, "RestApiId": { "Ref": "ExplicitApi" @@ -136,15 +154,6 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeploymentc444e5d902": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: c444e5d902971761ced658a7ce701149743eb376" - } - }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -220,15 +229,6 @@ "endpointConfigurationTypes": "REGIONAL" } } - }, - "ExplicitApiDeployment5332c373d4": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 5332c373d45c69e6c0f562b4a419aa8eb311adc7" - } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json index a5ba263166..ceb7de17f2 100644 --- a/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json @@ -47,15 +47,6 @@ } } }, - "ExplicitApiDeployment9252467a1e": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1" - } - }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -180,7 +171,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment9252467a1e" + "Ref": "ExplicitApiDeployment748947f06a" } } }, @@ -226,6 +217,15 @@ ] } }, + "ExplicitApiDeployment748947f06a": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 748947f06a1a8de71a295f51af31d94b932fe2fc" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-cn/explicit_api_openapi_3.json b/tests/translator/output/aws-cn/explicit_api_openapi_3.json index d98d610a6f..52e5843307 100644 --- a/tests/translator/output/aws-cn/explicit_api_openapi_3.json +++ b/tests/translator/output/aws-cn/explicit_api_openapi_3.json @@ -37,7 +37,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ApiWithInlineSwaggerDeployment09cda3d97b" + "Ref": "ApiWithInlineSwaggerDeployment88733439c5" }, "RestApiId": { "Ref": "ApiWithInlineSwagger" @@ -47,6 +47,15 @@ } } }, + "ApiWithInlineSwaggerDeployment88733439c5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ApiWithInlineSwagger" + }, + "Description": "RestApi deployment id: 88733439c55b6ebd05ddec6505b6d8647d145b50" + } + }, "GetHtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -180,15 +189,6 @@ "Ref": "MyStageName" } } - }, - "ApiWithInlineSwaggerDeployment09cda3d97b": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ApiWithInlineSwagger" - }, - "Description": "RestApi deployment id: 09cda3d97b008bed7bd4ebb1b5304ed622492941" - } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json b/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json index 12ffb120cd..07371a7036 100644 --- a/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json @@ -21,6 +21,15 @@ } } }, + "HtmlApiDeploymentda3232aa55": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "HtmlApi" + }, + "Description": "RestApi deployment id: da3232aa55c051d9a70127cb968912176f191af7" + } + }, "HtmlFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -49,7 +58,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "HtmlApiDeployment73fda15117" + "Ref": "HtmlApiDeploymentda3232aa55" }, "RestApiId": { "Ref": "HtmlApi" @@ -172,15 +181,6 @@ } } }, - "HtmlApiDeployment73fda15117": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "HtmlApi" - }, - "Description": "RestApi deployment id: 73fda151173319fe1f84fa9c2a7ff69514fced3b" - } - }, "HtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -243,4 +243,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json index 90fc4e9da9..d631f22760 100644 --- a/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json @@ -45,6 +45,15 @@ } } }, + "MyApiWithoutAuthDeploymentb6f62a92bd": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithoutAuth" + }, + "Description": "RestApi deployment id: b6f62a92bd079aa91036e202673cedd83b73e0c3" + } + }, "MyApiWithoutAuth": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -99,7 +108,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithoutAuthDeploymentfee0b2b452" + "Ref": "MyApiWithoutAuthDeploymentb6f62a92bd" }, "RestApiId": { "Ref": "MyApiWithoutAuth" @@ -150,15 +159,6 @@ } ] } - }, - "MyApiWithoutAuthDeploymentfee0b2b452": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithoutAuth" - }, - "Description": "RestApi deployment id: fee0b2b45266fff45b8edba43206618eabefebfe" - } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json index a4e560599a..f81a275e5e 100644 --- a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json @@ -442,6 +442,15 @@ } } }, + "MyApiDeploymentcc3d4f033f": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: cc3d4f033f302fc0827f2ec54ee1b394474f3bc8" + } + }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -481,20 +490,11 @@ } } }, - "MyApiDeploymente67481ad45": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: e67481ad4559fa2ba87f90009db679ae7d0c7c57" - } - }, "MyApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeploymente67481ad45" + "Ref": "MyApiDeploymentcc3d4f033f" }, "RestApiId": { "Ref": "MyApi" diff --git a/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json b/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json index 0c7839fa63..24488ae815 100644 --- a/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json +++ b/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json @@ -1,14 +1,5 @@ { "Resources": { - "MyApiWithLambdaTokenAuthDeployment0add72ee5b": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaTokenAuth" - }, - "Description": "RestApi deployment id: 0add72ee5b93d4332ccfaf6b521b1d6c98346235" - } - }, "MyApiWithCognitoAuth": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -75,7 +66,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaRequestAuthDeploymente9da24fd8b" + "Ref": "MyApiWithLambdaRequestAuthDeployment26f2ec8dc2" }, "RestApiId": { "Ref": "MyApiWithLambdaRequestAuth" @@ -106,25 +97,31 @@ } } }, - "MyFnLambdaRequestPermissionTest": { - "Type": "AWS::Lambda::Permission", + "MyApiWithLambdaTokenAuthDeployment12dbbda3a3": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": { - "Ref": "MyFn" + "RestApiId": { + "Ref": "MyApiWithLambdaTokenAuth" }, - "SourceArn": { - "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/lambda-request", - { - "__Stage__": "*", - "__ApiId__": { - "Ref": "MyApiWithLambdaRequestAuth" - } - } - ] - } + "Description": "RestApi deployment id: 12dbbda3a3bf53e42069a9045c5a54b8650b092d" + } + }, + "MyApiWithCognitoAuthDeployment2813ca7ed8": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithCognitoAuth" + }, + "Description": "RestApi deployment id: 2813ca7ed87e18b2a034b30d5c5696abd95d7c66" + } + }, + "MyApiWithLambdaRequestAuthDeployment26f2ec8dc2": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaRequestAuth" + }, + "Description": "RestApi deployment id: 26f2ec8dc2f36b8ae66401fa2c1e915b6c9130e2" } }, "MyFnLambdaTokenPermissionTest": { @@ -220,7 +217,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithCognitoAuthDeploymentc77185482f" + "Ref": "MyApiWithCognitoAuthDeployment2813ca7ed8" }, "RestApiId": { "Ref": "MyApiWithCognitoAuth" @@ -249,25 +246,25 @@ } } }, - "MyUserPool": { - "Type": "AWS::Cognito::UserPool", + "MyFnLambdaRequestPermissionTest": { + "Type": "AWS::Lambda::Permission", "Properties": { - "UsernameAttributes": [ - "email" - ], - "UserPoolName": "UserPoolName", - "Policies": { - "PasswordPolicy": { - "MinimumLength": 8 - } + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFn" }, - "Schema": [ - { - "AttributeDataType": "String", - "Required": false, - "Name": "email" - } - ] + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/lambda-request", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithLambdaRequestAuth" + } + } + ] + } } }, "MyApiWithLambdaRequestAuthMyLambdaRequestAuthAuthorizerPermission": { @@ -402,13 +399,25 @@ } } }, - "MyApiWithCognitoAuthDeploymentc77185482f": { - "Type": "AWS::ApiGateway::Deployment", + "MyUserPool": { + "Type": "AWS::Cognito::UserPool", "Properties": { - "RestApiId": { - "Ref": "MyApiWithCognitoAuth" + "UsernameAttributes": [ + "email" + ], + "UserPoolName": "UserPoolName", + "Policies": { + "PasswordPolicy": { + "MinimumLength": 8 + } }, - "Description": "RestApi deployment id: c77185482f5da13033fc9807c218b651c53a8c6c" + "Schema": [ + { + "AttributeDataType": "String", + "Required": false, + "Name": "email" + } + ] } }, "MyFn": { @@ -434,15 +443,6 @@ ] } }, - "MyApiWithLambdaRequestAuthDeploymente9da24fd8b": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaRequestAuth" - }, - "Description": "RestApi deployment id: e9da24fd8b2ad6c40b7137492a1a1c9a3cdf1908" - } - }, "MyAuthFnRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -471,7 +471,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaTokenAuthDeployment0add72ee5b" + "Ref": "MyApiWithLambdaTokenAuthDeployment12dbbda3a3" }, "RestApiId": { "Ref": "MyApiWithLambdaTokenAuth" diff --git a/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json index 9a66ac27de..428c03d793 100644 --- a/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json @@ -261,7 +261,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment2cd28b2066" + "Ref": "ServerlessRestApiDeploymentdd32a75aeb" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -273,7 +273,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment3a5a78688c" + "Ref": "ExplicitApiDeploymentbabea58445" }, "RestApiId": { "Ref": "ExplicitApi" @@ -326,24 +326,6 @@ } } }, - "ServerlessRestApiDeployment2cd28b2066": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: 2cd28b2066d69ecfb44eb7e024734cab2f3f9dac" - } - }, - "ExplicitApiDeployment3a5a78688c": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 3a5a78688c9bc377d53aa4153a11f0c4f6e7364c" - } - }, "RestApiFunction": { "Type": "AWS::Lambda::Function", "Properties": { @@ -367,6 +349,24 @@ ] } }, + "ExplicitApiDeploymentbabea58445": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: babea584458ca2e980baa334bd70f8b193375895" + } + }, + "ServerlessRestApiDeploymentdd32a75aeb": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: dd32a75aeb16c5183a85dd7fe7591c4b88387b6d" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json index 8b758bbd47..3f54f873b9 100644 --- a/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json @@ -23,15 +23,6 @@ ] } }, - "ExplicitApiDeployment3a19adf892": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 3a19adf892fbe70d360659eb3660359ade61913b" - } - }, "FunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -116,7 +107,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment3a19adf892" + "Ref": "ExplicitApiDeployment81c693e541" }, "RestApiId": { "Ref": "ExplicitApi" @@ -124,6 +115,15 @@ "StageName": "Prod" } }, + "ExplicitApiDeployment81c693e541": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 81c693e5415eab343422dcaa0b0899ff31e192d0" + } + }, "FunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -167,4 +167,4 @@ } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_open_api_version.json b/tests/translator/output/aws-us-gov/api_with_open_api_version.json index 5cd2019b48..48a31d1394 100644 --- a/tests/translator/output/aws-us-gov/api_with_open_api_version.json +++ b/tests/translator/output/aws-us-gov/api_with_open_api_version.json @@ -112,23 +112,20 @@ } } }, - "ExplicitApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "ExplicitApiDeployment1e9fbca603": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "DeploymentId": { - "Ref": "ExplicitApiDeployment01dd43a75f" - }, "RestApiId": { "Ref": "ExplicitApi" }, - "StageName": "Prod" + "Description": "RestApi deployment id: 1e9fbca603907b0cfb3e8164fa9d4c3b95b4272d" } }, "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment3f1d889857" + "Ref": "ServerlessRestApiDeployment63c7ea66fa" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -136,13 +133,25 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeployment3f1d889857": { + "ServerlessRestApiDeployment63c7ea66fa": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 3f1d889857c22227451ab7a02be7ea74b2e9d5b4" + "Description": "RestApi deployment id: 63c7ea66fa789640585db13196d24833004df4e0" + } + }, + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeployment1e9fbca603" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" } }, "ServerlessRestApi": { @@ -220,15 +229,6 @@ "endpointConfigurationTypes": "REGIONAL" } } - }, - "ExplicitApiDeployment01dd43a75f": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 01dd43a75fc0e125c678d20749bacde95d723928" - } } } -} +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json b/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json index 466cc85271..89e0308f5e 100644 --- a/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json +++ b/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json @@ -47,6 +47,15 @@ } } }, + "ServerlessRestApiDeploymentde54219387": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: de542193875063eb109b0bb4f1a6bfd6ca3cec29" + } + }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -89,6 +98,15 @@ } } }, + "ExplicitApiDeployment323af4d2f5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 323af4d2f576d27b094bb4e64e6fd8ada81b630b" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -112,35 +130,26 @@ } } }, - "ServerlessRestApiDeployment3d22acdeb7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: 3d22acdeb7a3302c0b978e3dbb15c149380fbe77" - } - }, - "ExplicitApiProdStage": { + "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment5332c373d4" + "Ref": "ServerlessRestApiDeploymentde54219387" }, "RestApiId": { - "Ref": "ExplicitApi" + "Ref": "ServerlessRestApi" }, "StageName": "Prod" } }, - "ServerlessRestApiProdStage": { + "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment3d22acdeb7" + "Ref": "ExplicitApiDeployment323af4d2f5" }, "RestApiId": { - "Ref": "ServerlessRestApi" + "Ref": "ExplicitApi" }, "StageName": "Prod" } @@ -220,15 +229,6 @@ "endpointConfigurationTypes": "REGIONAL" } } - }, - "ExplicitApiDeployment5332c373d4": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 5332c373d45c69e6c0f562b4a419aa8eb311adc7" - } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json index e47a67dc67..f4692eb169 100644 --- a/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json @@ -47,15 +47,6 @@ } } }, - "ExplicitApiDeployment9252467a1e": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1" - } - }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -170,7 +161,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment9252467a1e" + "Ref": "ExplicitApiDeployment748947f06a" } } }, @@ -226,6 +217,15 @@ ] } }, + "ExplicitApiDeployment748947f06a": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 748947f06a1a8de71a295f51af31d94b932fe2fc" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json b/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json index 307a76ae2e..5cc1c80fd2 100644 --- a/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json +++ b/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json @@ -37,7 +37,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ApiWithInlineSwaggerDeployment09cda3d97b" + "Ref": "ApiWithInlineSwaggerDeployment88733439c5" }, "RestApiId": { "Ref": "ApiWithInlineSwagger" @@ -47,6 +47,15 @@ } } }, + "ApiWithInlineSwaggerDeployment88733439c5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ApiWithInlineSwagger" + }, + "Description": "RestApi deployment id: 88733439c55b6ebd05ddec6505b6d8647d145b50" + } + }, "GetHtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -180,15 +189,6 @@ "Ref": "MyStageName" } } - }, - "ApiWithInlineSwaggerDeployment09cda3d97b": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ApiWithInlineSwagger" - }, - "Description": "RestApi deployment id: 09cda3d97b008bed7bd4ebb1b5304ed622492941" - } } } } \ No newline at end of file diff --git a/tests/translator/output/explicit_api_openapi_3.json b/tests/translator/output/explicit_api_openapi_3.json index 327871d4dc..2ca3f634b1 100644 --- a/tests/translator/output/explicit_api_openapi_3.json +++ b/tests/translator/output/explicit_api_openapi_3.json @@ -37,7 +37,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ApiWithInlineSwaggerDeployment09cda3d97b" + "Ref": "ApiWithInlineSwaggerDeployment88733439c5" }, "RestApiId": { "Ref": "ApiWithInlineSwagger" @@ -47,6 +47,15 @@ } } }, + "ApiWithInlineSwaggerDeployment88733439c5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ApiWithInlineSwagger" + }, + "Description": "RestApi deployment id: 88733439c55b6ebd05ddec6505b6d8647d145b50" + } + }, "GetHtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -164,15 +173,6 @@ "Ref": "MyStageName" } } - }, - "ApiWithInlineSwaggerDeployment09cda3d97b": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ApiWithInlineSwagger" - }, - "Description": "RestApi deployment id: 09cda3d97b008bed7bd4ebb1b5304ed622492941" - } } } } \ No newline at end of file From 05eae607b667a6b5a9d7d613fe99152eb3f1c718 Mon Sep 17 00:00:00 2001 From: praneetap Date: Thu, 1 Aug 2019 12:39:40 -0700 Subject: [PATCH 25/31] fix: adding delimiter between the hash data components. (#1060) --- samtranslator/model/apigateway.py | 14 +- .../output/api_request_model_openapi_3.json | 6 +- .../api_with_apikey_required_openapi_3.json | 6 +- .../api_with_auth_all_maximum_openapi_3.json | 18 +-- .../api_with_auth_all_minimum_openapi.json | 60 ++++----- .../output/api_with_cors_openapi_3.json | 26 ++-- ..._with_gateway_responses_all_openapi_3.json | 20 +-- .../output/api_with_open_api_version.json | 38 +++--- .../output/api_with_open_api_version_2.json | 26 ++-- ..._with_openapi_definition_body_no_flag.json | 20 +-- .../aws-cn/api_request_model_openapi_3.json | 20 +-- .../api_with_apikey_required_openapi_3.json | 6 +- .../api_with_auth_all_maximum_openapi_3.json | 20 +-- .../api_with_auth_all_minimum_openapi.json | 122 +++++++++--------- .../aws-cn/api_with_cors_openapi_3.json | 28 ++-- ..._with_gateway_responses_all_openapi_3.json | 20 +-- .../aws-cn/api_with_open_api_version.json | 26 ++-- .../aws-cn/api_with_open_api_version_2.json | 38 +++--- ..._with_openapi_definition_body_no_flag.json | 20 +-- .../output/aws-cn/explicit_api_openapi_3.json | 20 +-- .../api_request_model_openapi_3.json | 6 +- .../api_with_apikey_required_openapi_3.json | 6 +- .../api_with_auth_all_maximum_openapi_3.json | 20 +-- .../api_with_auth_all_minimum_openapi.json | 80 ++++++------ .../aws-us-gov/api_with_cors_openapi_3.json | 26 ++-- ..._with_gateway_responses_all_openapi_3.json | 20 +-- .../aws-us-gov/api_with_open_api_version.json | 34 ++--- .../api_with_open_api_version_2.json | 48 +++---- ..._with_openapi_definition_body_no_flag.json | 20 +-- .../aws-us-gov/explicit_api_openapi_3.json | 20 +-- .../output/explicit_api_openapi_3.json | 20 +-- 31 files changed, 429 insertions(+), 425 deletions(-) diff --git a/samtranslator/model/apigateway.py b/samtranslator/model/apigateway.py index 27a466d1a3..e2cc90095a 100644 --- a/samtranslator/model/apigateway.py +++ b/samtranslator/model/apigateway.py @@ -62,6 +62,8 @@ class ApiGatewayAccount(Resource): class ApiGatewayDeployment(Resource): + _X_HASH_DELIMITER = "||" + resource_type = 'AWS::ApiGateway::Deployment' property_types = { 'Description': PropertyType(False, is_str()), @@ -90,13 +92,15 @@ def make_auto_deployable(self, stage, openapi_version=None, swagger=None): # to prevent redeployment when API has not changed # NOTE: `str(swagger)` is for backwards compatibility. Changing it to a JSON or something will break compat - hash_input = str(swagger) + hash_input = [str(swagger)] if openapi_version: - hash_input = hash_input + str(openapi_version) - generator = logical_id_generator.LogicalIdGenerator(self.logical_id, hash_input) + hash_input.append(str(openapi_version)) + + data = self._X_HASH_DELIMITER.join(hash_input) + generator = logical_id_generator.LogicalIdGenerator(self.logical_id, data) self.logical_id = generator.gen() - hash = generator.get_hash(length=40) # Get the full hash - self.Description = "RestApi deployment id: {}".format(hash) + digest = generator.get_hash(length=40) # Get the full hash + self.Description = "RestApi deployment id: {}".format(digest) stage.update_deployment_ref(self.logical_id) diff --git a/tests/translator/output/api_request_model_openapi_3.json b/tests/translator/output/api_request_model_openapi_3.json index 229354b2a1..a65d44b484 100644 --- a/tests/translator/output/api_request_model_openapi_3.json +++ b/tests/translator/output/api_request_model_openapi_3.json @@ -21,13 +21,13 @@ } } }, - "HtmlApiDeployment77aaf3ac13": { + "HtmlApiDeploymentefb667b26e": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "HtmlApi" }, - "Description": "RestApi deployment id: 77aaf3ac132a9282281fd55bdeac6fe7466e8337" + "Description": "RestApi deployment id: efb667b26e8a0b0f733f5dfc27d039c1a2867db0" } }, "HtmlFunctionRole": { @@ -58,7 +58,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "HtmlApiDeployment77aaf3ac13" + "Ref": "HtmlApiDeploymentefb667b26e" }, "RestApiId": { "Ref": "HtmlApi" diff --git a/tests/translator/output/api_with_apikey_required_openapi_3.json b/tests/translator/output/api_with_apikey_required_openapi_3.json index d91a848e56..cc53ba7465 100644 --- a/tests/translator/output/api_with_apikey_required_openapi_3.json +++ b/tests/translator/output/api_with_apikey_required_openapi_3.json @@ -45,13 +45,13 @@ } } }, - "MyApiWithoutAuthDeployment140350c252": { + "MyApiWithoutAuthDeployment8770e31c42": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "MyApiWithoutAuth" }, - "Description": "RestApi deployment id: 140350c2525068ff2e9bb5e7ee0765718974523d" + "Description": "RestApi deployment id: 8770e31c425e4cc01e67db6627300b459720eff9" } }, "MyApiWithoutAuth": { @@ -100,7 +100,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithoutAuthDeployment140350c252" + "Ref": "MyApiWithoutAuthDeployment8770e31c42" }, "RestApiId": { "Ref": "MyApiWithoutAuth" diff --git a/tests/translator/output/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/api_with_auth_all_maximum_openapi_3.json index 0009c756ee..a666019774 100644 --- a/tests/translator/output/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/api_with_auth_all_maximum_openapi_3.json @@ -473,16 +473,13 @@ } } }, - "MyApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "MyApiDeployment98ad824f7d": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "DeploymentId": { - "Ref": "MyApiDeploymente181e32adc" - }, "RestApiId": { "Ref": "MyApi" }, - "StageName": "Prod" + "Description": "RestApi deployment id: 98ad824f7db83981e747e44ba34d318c7fa410c8" } }, "MyFunctionWithNoAuthorizerPermissionProd": { @@ -506,13 +503,16 @@ } } }, - "MyApiDeploymente181e32adc": { - "Type": "AWS::ApiGateway::Deployment", + "MyApiProdStage": { + "Type": "AWS::ApiGateway::Stage", "Properties": { + "DeploymentId": { + "Ref": "MyApiDeployment98ad824f7d" + }, "RestApiId": { "Ref": "MyApi" }, - "Description": "RestApi deployment id: e181e32adcccf59d699baf300078344166614113" + "StageName": "Prod" } }, "MyFunctionWithDefaultAuthorizerPermissionProd": { diff --git a/tests/translator/output/api_with_auth_all_minimum_openapi.json b/tests/translator/output/api_with_auth_all_minimum_openapi.json index 2653f2c477..1b77d6680e 100644 --- a/tests/translator/output/api_with_auth_all_minimum_openapi.json +++ b/tests/translator/output/api_with_auth_all_minimum_openapi.json @@ -54,20 +54,11 @@ } } }, - "MyApiWithLambdaTokenAuthDeployment5100134cea": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaTokenAuth" - }, - "Description": "RestApi deployment id: 5100134cea4b4506bd0894f86bfe775c9903ae82" - } - }, "MyApiWithLambdaRequestAuthProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaRequestAuthDeployment195678a2e7" + "Ref": "MyApiWithLambdaRequestAuthDeployment14ab3ddf12" }, "RestApiId": { "Ref": "MyApiWithLambdaRequestAuth" @@ -98,15 +89,6 @@ } } }, - "MyApiWithLambdaRequestAuthDeployment195678a2e7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaRequestAuth" - }, - "Description": "RestApi deployment id: 195678a2e73ee92ca367f5b4ba814c6e0022df01" - } - }, "MyFnLambdaRequestPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -217,11 +199,20 @@ } } }, + "MyApiWithLambdaRequestAuthDeployment14ab3ddf12": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaRequestAuth" + }, + "Description": "RestApi deployment id: 14ab3ddf12ee76d46cac076ecffc24b3acd2fb7f" + } + }, "MyApiWithCognitoAuthProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithCognitoAuthDeploymentcae360c856" + "Ref": "MyApiWithCognitoAuthDeployment87cdbda651" }, "RestApiId": { "Ref": "MyApiWithCognitoAuth" @@ -374,15 +365,6 @@ } } }, - "MyApiWithCognitoAuthDeploymentcae360c856": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithCognitoAuth" - }, - "Description": "RestApi deployment id: cae360c856d65fceaffb4bf24ebf5c4eac239e53" - } - }, "MyUserPool": { "Type": "AWS::Cognito::UserPool", "Properties": { @@ -455,7 +437,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaTokenAuthDeployment5100134cea" + "Ref": "MyApiWithLambdaTokenAuthDeployment4fdb5f4e3c" }, "RestApiId": { "Ref": "MyApiWithLambdaTokenAuth" @@ -463,6 +445,15 @@ "StageName": "Prod" } }, + "MyApiWithCognitoAuthDeployment87cdbda651": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithCognitoAuth" + }, + "Description": "RestApi deployment id: 87cdbda651523df8d04d15fc50f72ae8ead08c1d" + } + }, "MyApiWithLambdaRequestAuth": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -522,6 +513,15 @@ } } } + }, + "MyApiWithLambdaTokenAuthDeployment4fdb5f4e3c": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaTokenAuth" + }, + "Description": "RestApi deployment id: 4fdb5f4e3c6e0e2b12af6d7a637ce66bb5bf7d0a" + } } } } \ No newline at end of file diff --git a/tests/translator/output/api_with_cors_openapi_3.json b/tests/translator/output/api_with_cors_openapi_3.json index 16f4ca8a6e..9a1658febc 100644 --- a/tests/translator/output/api_with_cors_openapi_3.json +++ b/tests/translator/output/api_with_cors_openapi_3.json @@ -253,7 +253,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment3e214d1cac" + "Ref": "ServerlessRestApiDeploymentf0997bcd64" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -265,7 +265,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeploymentbabea58445" + "Ref": "ExplicitApiDeployment8cc53ffaa5" }, "RestApiId": { "Ref": "ExplicitApi" @@ -318,13 +318,22 @@ } } }, - "ServerlessRestApiDeployment3e214d1cac": { + "ExplicitApiDeployment8cc53ffaa5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 8cc53ffaa59a19b69e73d5b422142c7396739b16" + } + }, + "ServerlessRestApiDeploymentf0997bcd64": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 3e214d1cac2e110e6e28a389a4ba80057c5f0842" + "Description": "RestApi deployment id: f0997bcd645ceb1529586bc2b9faf855687b46ce" } }, "RestApiFunction": { @@ -350,15 +359,6 @@ ] } }, - "ExplicitApiDeploymentbabea58445": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: babea584458ca2e980baa334bd70f8b193375895" - } - }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/api_with_gateway_responses_all_openapi_3.json b/tests/translator/output/api_with_gateway_responses_all_openapi_3.json index a5a75340d8..da03f6d536 100644 --- a/tests/translator/output/api_with_gateway_responses_all_openapi_3.json +++ b/tests/translator/output/api_with_gateway_responses_all_openapi_3.json @@ -47,6 +47,15 @@ } } }, + "ExplicitApiDeploymenta8fcf1dd74": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: a8fcf1dd7480d58309d5673300f397de4f515e47" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -95,20 +104,11 @@ } } }, - "ExplicitApiDeployment23e7ed36e4": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 23e7ed36e41c87979e26864331c8fbd0a22d2906" - } - }, "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment23e7ed36e4" + "Ref": "ExplicitApiDeploymenta8fcf1dd74" }, "RestApiId": { "Ref": "ExplicitApi" diff --git a/tests/translator/output/api_with_open_api_version.json b/tests/translator/output/api_with_open_api_version.json index 4a754b73b0..98ad31b0fd 100644 --- a/tests/translator/output/api_with_open_api_version.json +++ b/tests/translator/output/api_with_open_api_version.json @@ -68,6 +68,15 @@ } } }, + "ServerlessRestApiDeployment83a174fb31": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 83a174fb31472bc23ccc2f0d96eebff659e59cd2" + } + }, "ImplicitApiFunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -104,23 +113,20 @@ } } }, - "ExplicitApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "ExplicitApiDeploymentd9a0f2ae4f": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "DeploymentId": { - "Ref": "ExplicitApiDeployment1e9fbca603" - }, "RestApiId": { "Ref": "ExplicitApi" }, - "StageName": "Prod" + "Description": "RestApi deployment id: d9a0f2ae4fe2d97b9b91644934a878b6a08cf1c3" } }, "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentacd2d469b0" + "Ref": "ServerlessRestApiDeployment83a174fb31" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -128,22 +134,16 @@ "StageName": "Prod" } }, - "ExplicitApiDeployment1e9fbca603": { - "Type": "AWS::ApiGateway::Deployment", + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" + "DeploymentId": { + "Ref": "ExplicitApiDeploymentd9a0f2ae4f" }, - "Description": "RestApi deployment id: 1e9fbca603907b0cfb3e8164fa9d4c3b95b4272d" - } - }, - "ServerlessRestApiDeploymentacd2d469b0": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { "RestApiId": { - "Ref": "ServerlessRestApi" + "Ref": "ExplicitApi" }, - "Description": "RestApi deployment id: acd2d469b0bc58a0e115764c4385e0254ae0bd7e" + "StageName": "Prod" } }, "ServerlessRestApi": { diff --git a/tests/translator/output/api_with_open_api_version_2.json b/tests/translator/output/api_with_open_api_version_2.json index f1367adb84..c3798099dd 100644 --- a/tests/translator/output/api_with_open_api_version_2.json +++ b/tests/translator/output/api_with_open_api_version_2.json @@ -89,15 +89,6 @@ } } }, - "ExplicitApiDeployment323af4d2f5": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 323af4d2f576d27b094bb4e64e6fd8ada81b630b" - } - }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -117,7 +108,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment323af4d2f5" + "Ref": "ExplicitApiDeployment4154e1c30c" }, "RestApiId": { "Ref": "ExplicitApi" @@ -129,7 +120,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment3644a4133f" + "Ref": "ServerlessRestApiDeployment32f05a472e" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -137,13 +128,13 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeployment3644a4133f": { + "ServerlessRestApiDeployment32f05a472e": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 3644a4133f18ca79220abe30b7f27b7e9a55cd06" + "Description": "RestApi deployment id: 32f05a472e885a4cf62d1ae534486511f6152624" } }, "ServerlessRestApi": { @@ -213,6 +204,15 @@ "swagger": "2.0" } } + }, + "ExplicitApiDeployment4154e1c30c": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 4154e1c30c97469d4946280461125dbfd4324f15" + } } } } \ No newline at end of file diff --git a/tests/translator/output/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/api_with_openapi_definition_body_no_flag.json index b810aa9690..02ab6e4891 100644 --- a/tests/translator/output/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/api_with_openapi_definition_body_no_flag.json @@ -68,6 +68,15 @@ } } }, + "ExplicitApiDeployment63a10e26af": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 63a10e26af7194aefd61ead891c470ed75ce20be" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -163,7 +172,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment748947f06a" + "Ref": "ExplicitApiDeployment63a10e26af" } } }, @@ -209,15 +218,6 @@ ] } }, - "ExplicitApiDeployment748947f06a": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 748947f06a1a8de71a295f51af31d94b932fe2fc" - } - }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-cn/api_request_model_openapi_3.json b/tests/translator/output/aws-cn/api_request_model_openapi_3.json index c08d5f6037..c5f80388f9 100644 --- a/tests/translator/output/aws-cn/api_request_model_openapi_3.json +++ b/tests/translator/output/aws-cn/api_request_model_openapi_3.json @@ -21,6 +21,15 @@ } } }, + "HtmlApiDeploymentbe02cbff83": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "HtmlApi" + }, + "Description": "RestApi deployment id: be02cbff831c2acb5672650bc54b204366bef429" + } + }, "HtmlFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -49,7 +58,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "HtmlApiDeploymentdcba4b4073" + "Ref": "HtmlApiDeploymentbe02cbff83" }, "RestApiId": { "Ref": "HtmlApi" @@ -172,15 +181,6 @@ } } }, - "HtmlApiDeploymentdcba4b4073": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "HtmlApi" - }, - "Description": "RestApi deployment id: dcba4b407341ea76ae262bf7fd11078328e52168" - } - }, "HtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { diff --git a/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json b/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json index 795017bf90..15f1809328 100644 --- a/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_apikey_required_openapi_3.json @@ -45,13 +45,13 @@ } } }, - "MyApiWithoutAuthDeployment357a42f0aa": { + "MyApiWithoutAuthDeployment44fb9ac597": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "MyApiWithoutAuth" }, - "Description": "RestApi deployment id: 357a42f0aa7732edc83e7064dab8dc4050abb0e9" + "Description": "RestApi deployment id: 44fb9ac5971a18de67dd843c5c069f07726ad36c" } }, "MyApiWithoutAuth": { @@ -108,7 +108,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithoutAuthDeployment357a42f0aa" + "Ref": "MyApiWithoutAuthDeployment44fb9ac597" }, "RestApiId": { "Ref": "MyApiWithoutAuth" diff --git a/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json index 38aca8c4e5..2cf0759cc2 100644 --- a/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_auth_all_maximum_openapi_3.json @@ -146,15 +146,6 @@ } } }, - "MyApiDeploymentc3ee011ecc": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: c3ee011ecc11fa841524767079400e1fb8a3d57c" - } - }, "MyFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -472,6 +463,15 @@ } } }, + "MyApiDeploymentcc3ee70601": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: cc3ee706016a512ef6fe9e3608b7b637fd4c7abd" + } + }, "MyApiMyLambdaTokenAuthNoneFunctionInvokeRoleAuthorizerPermission": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -494,7 +494,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeploymentc3ee011ecc" + "Ref": "MyApiDeploymentcc3ee70601" }, "RestApiId": { "Ref": "MyApi" diff --git a/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json b/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json index 690ae2fe13..33e5d53432 100644 --- a/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json +++ b/tests/translator/output/aws-cn/api_with_auth_all_minimum_openapi.json @@ -62,34 +62,48 @@ } } }, - "MyApiWithLambdaRequestAuthProdStage": { - "Type": "AWS::ApiGateway::Stage", + "MyApiWithCognitoAuthDeployment1ecccf8f28": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "DeploymentId": { - "Ref": "MyApiWithLambdaRequestAuthDeployment50560e1b93" - }, "RestApiId": { - "Ref": "MyApiWithLambdaRequestAuth" + "Ref": "MyApiWithCognitoAuth" }, - "StageName": "Prod" + "Description": "RestApi deployment id: 1ecccf8f2823a4777fc271569a1688db777f1302" } }, - "MyApiWithLambdaRequestAuthDeployment50560e1b93": { - "Type": "AWS::ApiGateway::Deployment", + "MyApiWithLambdaRequestAuthProdStage": { + "Type": "AWS::ApiGateway::Stage", "Properties": { + "DeploymentId": { + "Ref": "MyApiWithLambdaRequestAuthDeployment81b8e9784c" + }, "RestApiId": { "Ref": "MyApiWithLambdaRequestAuth" }, - "Description": "RestApi deployment id: 50560e1b93c278b5dedf0adcaf531cde88700103" + "StageName": "Prod" } }, - "MyApiWithLambdaTokenAuthDeploymente8e324a96a": { - "Type": "AWS::ApiGateway::Deployment", + "MyApiWithLambdaTokenAuthMyLambdaTokenAuthAuthorizerPermission": { + "Type": "AWS::Lambda::Permission", "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaTokenAuth" + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Fn::GetAtt": [ + "MyAuthFn", + "Arn" + ] }, - "Description": "RestApi deployment id: e8e324a96af0eefc9f8b328f9abdb94af12348ed" + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + { + "__ApiId__": { + "Ref": "MyApiWithLambdaTokenAuth" + } + } + ] + } } }, "MyFnLambdaRequestPermissionTest": { @@ -206,7 +220,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithCognitoAuthDeployment943c497d0c" + "Ref": "MyApiWithCognitoAuthDeployment1ecccf8f28" }, "RestApiId": { "Ref": "MyApiWithCognitoAuth" @@ -214,59 +228,68 @@ "StageName": "Prod" } }, - "MyApiWithCognitoAuthDeployment943c497d0c": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithCognitoAuth" - }, - "Description": "RestApi deployment id: 943c497d0c89ac6ab9c933c386e68f15b8cde482" - } - }, - "MyFnCognitoPermissionProd": { + "MyApiWithLambdaRequestAuthMyLambdaRequestAuthAuthorizerPermission": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:invokeFunction", "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Ref": "MyFn" + "Fn::GetAtt": [ + "MyAuthFn", + "Arn" + ] }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/cognito", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", { - "__Stage__": "Prod", "__ApiId__": { - "Ref": "MyApiWithCognitoAuth" + "Ref": "MyApiWithLambdaRequestAuth" } } ] } } }, - "MyApiWithLambdaRequestAuthMyLambdaRequestAuthAuthorizerPermission": { + "MyFnCognitoPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:invokeFunction", "Principal": "apigateway.amazonaws.com", "FunctionName": { - "Fn::GetAtt": [ - "MyAuthFn", - "Arn" - ] + "Ref": "MyFn" }, "SourceArn": { "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/cognito", { + "__Stage__": "Prod", "__ApiId__": { - "Ref": "MyApiWithLambdaRequestAuth" + "Ref": "MyApiWithCognitoAuth" } } ] } } }, + "MyApiWithLambdaRequestAuthDeployment81b8e9784c": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaRequestAuth" + }, + "Description": "RestApi deployment id: 81b8e9784c9a74f2875713fd92384bb67e756f82" + } + }, + "MyApiWithLambdaTokenAuthDeployment53baac2c0b": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaTokenAuth" + }, + "Description": "RestApi deployment id: 53baac2c0b5f582d951d933f66c102f8f467770b" + } + }, "MyFnLambdaTokenPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -420,29 +443,6 @@ ] } }, - "MyApiWithLambdaTokenAuthMyLambdaTokenAuthAuthorizerPermission": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": { - "Fn::GetAtt": [ - "MyAuthFn", - "Arn" - ] - }, - "SourceArn": { - "Fn::Sub": [ - "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/authorizers/*", - { - "__ApiId__": { - "Ref": "MyApiWithLambdaTokenAuth" - } - } - ] - } - } - }, "MyAuthFnRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -471,7 +471,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaTokenAuthDeploymente8e324a96a" + "Ref": "MyApiWithLambdaTokenAuthDeployment53baac2c0b" }, "RestApiId": { "Ref": "MyApiWithLambdaTokenAuth" diff --git a/tests/translator/output/aws-cn/api_with_cors_openapi_3.json b/tests/translator/output/aws-cn/api_with_cors_openapi_3.json index 6c8f9fbbae..6c2a897e00 100644 --- a/tests/translator/output/aws-cn/api_with_cors_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_cors_openapi_3.json @@ -47,6 +47,15 @@ } } }, + "ServerlessRestApiDeployment5a1885dc4a": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 5a1885dc4a36fdbd8b638b37b7bd6fbd1636e07e" + } + }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -261,7 +270,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment85d3360729" + "Ref": "ServerlessRestApiDeployment5a1885dc4a" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -273,7 +282,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeploymentbabea58445" + "Ref": "ExplicitApiDeployment8cc53ffaa5" }, "RestApiId": { "Ref": "ExplicitApi" @@ -326,13 +335,13 @@ } } }, - "ServerlessRestApiDeployment85d3360729": { + "ExplicitApiDeployment8cc53ffaa5": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ServerlessRestApi" + "Ref": "ExplicitApi" }, - "Description": "RestApi deployment id: 85d33607297efc01252aeae20f6a000ac2843483" + "Description": "RestApi deployment id: 8cc53ffaa59a19b69e73d5b422142c7396739b16" } }, "RestApiFunction": { @@ -358,15 +367,6 @@ ] } }, - "ExplicitApiDeploymentbabea58445": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: babea584458ca2e980baa334bd70f8b193375895" - } - }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json b/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json index aa0bfcba55..672a1b1603 100644 --- a/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json +++ b/tests/translator/output/aws-cn/api_with_gateway_responses_all_openapi_3.json @@ -23,6 +23,15 @@ ] } }, + "ExplicitApiDeploymenta2f31986fe": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: a2f31986fe718bd69858a109ac2b401fb7d8560f" + } + }, "FunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -107,7 +116,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment9cf935255f" + "Ref": "ExplicitApiDeploymenta2f31986fe" }, "RestApiId": { "Ref": "ExplicitApi" @@ -115,15 +124,6 @@ "StageName": "Prod" } }, - "ExplicitApiDeployment9cf935255f": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 9cf935255fad6f1e878435583797e0245e85e570" - } - }, "FunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { diff --git a/tests/translator/output/aws-cn/api_with_open_api_version.json b/tests/translator/output/aws-cn/api_with_open_api_version.json index 79b221f463..703427ee48 100644 --- a/tests/translator/output/aws-cn/api_with_open_api_version.json +++ b/tests/translator/output/aws-cn/api_with_open_api_version.json @@ -112,11 +112,20 @@ } } }, + "ExplicitApiDeploymentd9a0f2ae4f": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: d9a0f2ae4fe2d97b9b91644934a878b6a08cf1c3" + } + }, "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment1eb1f25f25" + "Ref": "ServerlessRestApiDeploymentb51bf3171c" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -124,20 +133,11 @@ "StageName": "Prod" } }, - "ExplicitApiDeployment1e9fbca603": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 1e9fbca603907b0cfb3e8164fa9d4c3b95b4272d" - } - }, "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment1e9fbca603" + "Ref": "ExplicitApiDeploymentd9a0f2ae4f" }, "RestApiId": { "Ref": "ExplicitApi" @@ -221,13 +221,13 @@ } } }, - "ServerlessRestApiDeployment1eb1f25f25": { + "ServerlessRestApiDeploymentb51bf3171c": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 1eb1f25f25d73d4340cd16527052e2efcdca8b74" + "Description": "RestApi deployment id: b51bf3171cc3cd5bdc024b45dda8a6ec14dcd6ef" } } } diff --git a/tests/translator/output/aws-cn/api_with_open_api_version_2.json b/tests/translator/output/aws-cn/api_with_open_api_version_2.json index 4dfd9b7df8..64ac6bcc8b 100644 --- a/tests/translator/output/aws-cn/api_with_open_api_version_2.json +++ b/tests/translator/output/aws-cn/api_with_open_api_version_2.json @@ -89,15 +89,6 @@ } } }, - "ServerlessRestApiDeployment2bcbad30d7": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: 2bcbad30d76c3d64bfb45cf0c5e883588cf75944" - } - }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -121,20 +112,20 @@ } } }, - "ExplicitApiDeployment323af4d2f5": { + "ServerlessRestApiDeployment3146d7e6fb": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { - "Ref": "ExplicitApi" + "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 323af4d2f576d27b094bb4e64e6fd8ada81b630b" + "Description": "RestApi deployment id: 3146d7e6fbaece0e0eb82d0c91c86c9b74dc217b" } }, "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment2bcbad30d7" + "Ref": "ServerlessRestApiDeployment3146d7e6fb" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -142,16 +133,13 @@ "StageName": "Prod" } }, - "ExplicitApiProdStage": { - "Type": "AWS::ApiGateway::Stage", + "ExplicitApiDeployment4154e1c30c": { + "Type": "AWS::ApiGateway::Deployment", "Properties": { - "DeploymentId": { - "Ref": "ExplicitApiDeployment323af4d2f5" - }, "RestApiId": { "Ref": "ExplicitApi" }, - "StageName": "Prod" + "Description": "RestApi deployment id: 4154e1c30c97469d4946280461125dbfd4324f15" } }, "ServerlessRestApi": { @@ -229,6 +217,18 @@ "endpointConfigurationTypes": "REGIONAL" } } + }, + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeployment4154e1c30c" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json index ceb7de17f2..815e57e930 100644 --- a/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json @@ -68,6 +68,15 @@ } } }, + "ExplicitApiDeployment63a10e26af": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 63a10e26af7194aefd61ead891c470ed75ce20be" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -171,7 +180,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment748947f06a" + "Ref": "ExplicitApiDeployment63a10e26af" } } }, @@ -217,15 +226,6 @@ ] } }, - "ExplicitApiDeployment748947f06a": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 748947f06a1a8de71a295f51af31d94b932fe2fc" - } - }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-cn/explicit_api_openapi_3.json b/tests/translator/output/aws-cn/explicit_api_openapi_3.json index 52e5843307..b606898c4f 100644 --- a/tests/translator/output/aws-cn/explicit_api_openapi_3.json +++ b/tests/translator/output/aws-cn/explicit_api_openapi_3.json @@ -37,7 +37,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ApiWithInlineSwaggerDeployment88733439c5" + "Ref": "ApiWithInlineSwaggerDeployment74abcb3a5b" }, "RestApiId": { "Ref": "ApiWithInlineSwagger" @@ -47,15 +47,6 @@ } } }, - "ApiWithInlineSwaggerDeployment88733439c5": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ApiWithInlineSwagger" - }, - "Description": "RestApi deployment id: 88733439c55b6ebd05ddec6505b6d8647d145b50" - } - }, "GetHtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -87,6 +78,15 @@ "StageName": "Stage" } }, + "ApiWithInlineSwaggerDeployment74abcb3a5b": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ApiWithInlineSwagger" + }, + "Description": "RestApi deployment id: 74abcb3a5bbe7ad58dfc543740af3be156736130" + } + }, "GetHtmlFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { diff --git a/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json b/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json index 07371a7036..f093d78bba 100644 --- a/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_request_model_openapi_3.json @@ -21,13 +21,13 @@ } } }, - "HtmlApiDeploymentda3232aa55": { + "HtmlApiDeploymente91bc94e87": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "HtmlApi" }, - "Description": "RestApi deployment id: da3232aa55c051d9a70127cb968912176f191af7" + "Description": "RestApi deployment id: e91bc94e874a30084312552d628dd248890ad7f9" } }, "HtmlFunctionRole": { @@ -58,7 +58,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "HtmlApiDeploymentda3232aa55" + "Ref": "HtmlApiDeploymente91bc94e87" }, "RestApiId": { "Ref": "HtmlApi" diff --git a/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json index d631f22760..80dfe87167 100644 --- a/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_apikey_required_openapi_3.json @@ -45,13 +45,13 @@ } } }, - "MyApiWithoutAuthDeploymentb6f62a92bd": { + "MyApiWithoutAuthDeployment36e0aae784": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "MyApiWithoutAuth" }, - "Description": "RestApi deployment id: b6f62a92bd079aa91036e202673cedd83b73e0c3" + "Description": "RestApi deployment id: 36e0aae784b2c12681164079395d2d416638051f" } }, "MyApiWithoutAuth": { @@ -108,7 +108,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithoutAuthDeploymentb6f62a92bd" + "Ref": "MyApiWithoutAuthDeployment36e0aae784" }, "RestApiId": { "Ref": "MyApiWithoutAuth" diff --git a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json index f81a275e5e..090a460b92 100644 --- a/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_auth_all_maximum_openapi_3.json @@ -170,6 +170,15 @@ } } }, + "MyApiDeployment57e8e73ac5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApi" + }, + "Description": "RestApi deployment id: 57e8e73ac5d3dea833fbbfb4d0d67328fb198a35" + } + }, "MyApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -442,15 +451,6 @@ } } }, - "MyApiDeploymentcc3d4f033f": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApi" - }, - "Description": "RestApi deployment id: cc3d4f033f302fc0827f2ec54ee1b394474f3bc8" - } - }, "MyFunctionWithCognitoMultipleUserPoolsAuthorizerPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -494,7 +494,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiDeploymentcc3d4f033f" + "Ref": "MyApiDeployment57e8e73ac5" }, "RestApiId": { "Ref": "MyApi" diff --git a/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json b/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json index 24488ae815..b16e2d8c8f 100644 --- a/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json +++ b/tests/translator/output/aws-us-gov/api_with_auth_all_minimum_openapi.json @@ -62,11 +62,29 @@ } } }, + "MyApiWithLambdaRequestAuthDeployment7c3972b020": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithLambdaRequestAuth" + }, + "Description": "RestApi deployment id: 7c3972b020afc5a3f348a527f9cbf5108557b930" + } + }, + "MyApiWithCognitoAuthDeploymente1765ad6c1": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "MyApiWithCognitoAuth" + }, + "Description": "RestApi deployment id: e1765ad6c129adfb32be52dea3fa053e2ce02d51" + } + }, "MyApiWithLambdaRequestAuthProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaRequestAuthDeployment26f2ec8dc2" + "Ref": "MyApiWithLambdaRequestAuthDeployment7c3972b020" }, "RestApiId": { "Ref": "MyApiWithLambdaRequestAuth" @@ -97,31 +115,34 @@ } } }, - "MyApiWithLambdaTokenAuthDeployment12dbbda3a3": { + "MyApiWithLambdaTokenAuthDeploymentfc5424e34c": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "MyApiWithLambdaTokenAuth" }, - "Description": "RestApi deployment id: 12dbbda3a3bf53e42069a9045c5a54b8650b092d" + "Description": "RestApi deployment id: fc5424e34c86d9c2c71ee87d32bc82555a3c577d" } }, - "MyApiWithCognitoAuthDeployment2813ca7ed8": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "MyApiWithCognitoAuth" - }, - "Description": "RestApi deployment id: 2813ca7ed87e18b2a034b30d5c5696abd95d7c66" - } - }, - "MyApiWithLambdaRequestAuthDeployment26f2ec8dc2": { - "Type": "AWS::ApiGateway::Deployment", + "MyFnLambdaRequestPermissionTest": { + "Type": "AWS::Lambda::Permission", "Properties": { - "RestApiId": { - "Ref": "MyApiWithLambdaRequestAuth" + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MyFn" }, - "Description": "RestApi deployment id: 26f2ec8dc2f36b8ae66401fa2c1e915b6c9130e2" + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/lambda-request", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "MyApiWithLambdaRequestAuth" + } + } + ] + } } }, "MyFnLambdaTokenPermissionTest": { @@ -217,7 +238,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithCognitoAuthDeployment2813ca7ed8" + "Ref": "MyApiWithCognitoAuthDeploymente1765ad6c1" }, "RestApiId": { "Ref": "MyApiWithCognitoAuth" @@ -246,27 +267,6 @@ } } }, - "MyFnLambdaRequestPermissionTest": { - "Type": "AWS::Lambda::Permission", - "Properties": { - "Action": "lambda:invokeFunction", - "Principal": "apigateway.amazonaws.com", - "FunctionName": { - "Ref": "MyFn" - }, - "SourceArn": { - "Fn::Sub": [ - "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/lambda-request", - { - "__Stage__": "*", - "__ApiId__": { - "Ref": "MyApiWithLambdaRequestAuth" - } - } - ] - } - } - }, "MyApiWithLambdaRequestAuthMyLambdaRequestAuthAuthorizerPermission": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -471,7 +471,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "MyApiWithLambdaTokenAuthDeployment12dbbda3a3" + "Ref": "MyApiWithLambdaTokenAuthDeploymentfc5424e34c" }, "RestApiId": { "Ref": "MyApiWithLambdaTokenAuth" diff --git a/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json index 428c03d793..6527c99b1d 100644 --- a/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_cors_openapi_3.json @@ -261,7 +261,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentdd32a75aeb" + "Ref": "ServerlessRestApiDeployment5e7d1b38bf" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -273,7 +273,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeploymentbabea58445" + "Ref": "ExplicitApiDeployment8cc53ffaa5" }, "RestApiId": { "Ref": "ExplicitApi" @@ -326,6 +326,15 @@ } } }, + "ExplicitApiDeployment8cc53ffaa5": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 8cc53ffaa59a19b69e73d5b422142c7396739b16" + } + }, "RestApiFunction": { "Type": "AWS::Lambda::Function", "Properties": { @@ -349,22 +358,13 @@ ] } }, - "ExplicitApiDeploymentbabea58445": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: babea584458ca2e980baa334bd70f8b193375895" - } - }, - "ServerlessRestApiDeploymentdd32a75aeb": { + "ServerlessRestApiDeployment5e7d1b38bf": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: dd32a75aeb16c5183a85dd7fe7591c4b88387b6d" + "Description": "RestApi deployment id: 5e7d1b38bf567c46a1fc95b97a22d3cbf171216c" } }, "ServerlessRestApi": { diff --git a/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json b/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json index 3f54f873b9..baa1ae69c7 100644 --- a/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json +++ b/tests/translator/output/aws-us-gov/api_with_gateway_responses_all_openapi_3.json @@ -107,7 +107,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment81c693e541" + "Ref": "ExplicitApiDeployment0f8408588e" }, "RestApiId": { "Ref": "ExplicitApi" @@ -115,15 +115,6 @@ "StageName": "Prod" } }, - "ExplicitApiDeployment81c693e541": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 81c693e5415eab343422dcaa0b0899ff31e192d0" - } - }, "FunctionGetHtmlPermissionProd": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -145,6 +136,15 @@ } } }, + "ExplicitApiDeployment0f8408588e": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 0f8408588e16013e6d4fa0f1fd2390d0a7ec15ed" + } + }, "FunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { diff --git a/tests/translator/output/aws-us-gov/api_with_open_api_version.json b/tests/translator/output/aws-us-gov/api_with_open_api_version.json index 48a31d1394..7335be520c 100644 --- a/tests/translator/output/aws-us-gov/api_with_open_api_version.json +++ b/tests/translator/output/aws-us-gov/api_with_open_api_version.json @@ -112,20 +112,20 @@ } } }, - "ExplicitApiDeployment1e9fbca603": { + "ExplicitApiDeploymentd9a0f2ae4f": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ExplicitApi" }, - "Description": "RestApi deployment id: 1e9fbca603907b0cfb3e8164fa9d4c3b95b4272d" + "Description": "RestApi deployment id: d9a0f2ae4fe2d97b9b91644934a878b6a08cf1c3" } }, "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeployment63c7ea66fa" + "Ref": "ServerlessRestApiDeployment7af82eda48" }, "RestApiId": { "Ref": "ServerlessRestApi" @@ -133,25 +133,13 @@ "StageName": "Prod" } }, - "ServerlessRestApiDeployment63c7ea66fa": { + "ServerlessRestApiDeployment7af82eda48": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "ServerlessRestApi" }, - "Description": "RestApi deployment id: 63c7ea66fa789640585db13196d24833004df4e0" - } - }, - "ExplicitApiProdStage": { - "Type": "AWS::ApiGateway::Stage", - "Properties": { - "DeploymentId": { - "Ref": "ExplicitApiDeployment1e9fbca603" - }, - "RestApiId": { - "Ref": "ExplicitApi" - }, - "StageName": "Prod" + "Description": "RestApi deployment id: 7af82eda48a23d84634abd7aa0865898d3b17810" } }, "ServerlessRestApi": { @@ -229,6 +217,18 @@ "endpointConfigurationTypes": "REGIONAL" } } + }, + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeploymentd9a0f2ae4f" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json b/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json index 89e0308f5e..ad8462bc07 100644 --- a/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json +++ b/tests/translator/output/aws-us-gov/api_with_open_api_version_2.json @@ -47,15 +47,6 @@ } } }, - "ServerlessRestApiDeploymentde54219387": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ServerlessRestApi" - }, - "Description": "RestApi deployment id: de542193875063eb109b0bb4f1a6bfd6ca3cec29" - } - }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -98,15 +89,6 @@ } } }, - "ExplicitApiDeployment323af4d2f5": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 323af4d2f576d27b094bb4e64e6fd8ada81b630b" - } - }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -130,30 +112,39 @@ } } }, - "ServerlessRestApiProdStage": { + "ExplicitApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ServerlessRestApiDeploymentde54219387" + "Ref": "ExplicitApiDeployment4154e1c30c" }, "RestApiId": { - "Ref": "ServerlessRestApi" + "Ref": "ExplicitApi" }, "StageName": "Prod" } }, - "ExplicitApiProdStage": { + "ServerlessRestApiProdStage": { "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ExplicitApiDeployment323af4d2f5" + "Ref": "ServerlessRestApiDeployment2ce765616b" }, "RestApiId": { - "Ref": "ExplicitApi" + "Ref": "ServerlessRestApi" }, "StageName": "Prod" } }, + "ExplicitApiDeployment4154e1c30c": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 4154e1c30c97469d4946280461125dbfd4324f15" + } + }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -229,6 +220,15 @@ "endpointConfigurationTypes": "REGIONAL" } } + }, + "ServerlessRestApiDeployment2ce765616b": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 2ce765616b7cfaba8ae0ad0877bd94cfbe0bc0fb" + } } } } \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json index f4692eb169..f9513c92fe 100644 --- a/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json @@ -68,6 +68,15 @@ } } }, + "ExplicitApiDeployment63a10e26af": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 63a10e26af7194aefd61ead891c470ed75ce20be" + } + }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -161,7 +170,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment748947f06a" + "Ref": "ExplicitApiDeployment63a10e26af" } } }, @@ -217,15 +226,6 @@ ] } }, - "ExplicitApiDeployment748947f06a": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 748947f06a1a8de71a295f51af31d94b932fe2fc" - } - }, "ServerlessRestApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { diff --git a/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json b/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json index 5cc1c80fd2..2e5ba08501 100644 --- a/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json +++ b/tests/translator/output/aws-us-gov/explicit_api_openapi_3.json @@ -37,7 +37,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ApiWithInlineSwaggerDeployment88733439c5" + "Ref": "ApiWithInlineSwaggerDeployment74abcb3a5b" }, "RestApiId": { "Ref": "ApiWithInlineSwagger" @@ -47,15 +47,6 @@ } } }, - "ApiWithInlineSwaggerDeployment88733439c5": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ApiWithInlineSwagger" - }, - "Description": "RestApi deployment id: 88733439c55b6ebd05ddec6505b6d8647d145b50" - } - }, "GetHtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -87,6 +78,15 @@ "StageName": "Stage" } }, + "ApiWithInlineSwaggerDeployment74abcb3a5b": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ApiWithInlineSwagger" + }, + "Description": "RestApi deployment id: 74abcb3a5bbe7ad58dfc543740af3be156736130" + } + }, "GetHtmlFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { diff --git a/tests/translator/output/explicit_api_openapi_3.json b/tests/translator/output/explicit_api_openapi_3.json index 2ca3f634b1..cf92ad161a 100644 --- a/tests/translator/output/explicit_api_openapi_3.json +++ b/tests/translator/output/explicit_api_openapi_3.json @@ -37,7 +37,7 @@ "Type": "AWS::ApiGateway::Stage", "Properties": { "DeploymentId": { - "Ref": "ApiWithInlineSwaggerDeployment88733439c5" + "Ref": "ApiWithInlineSwaggerDeployment74abcb3a5b" }, "RestApiId": { "Ref": "ApiWithInlineSwagger" @@ -47,15 +47,6 @@ } } }, - "ApiWithInlineSwaggerDeployment88733439c5": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ApiWithInlineSwagger" - }, - "Description": "RestApi deployment id: 88733439c55b6ebd05ddec6505b6d8647d145b50" - } - }, "GetHtmlFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -87,6 +78,15 @@ "StageName": "Stage" } }, + "ApiWithInlineSwaggerDeployment74abcb3a5b": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ApiWithInlineSwagger" + }, + "Description": "RestApi deployment id: 74abcb3a5bbe7ad58dfc543740af3be156736130" + } + }, "GetHtmlFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { From 509022891c76f0c121064053c1f6fbe00793ccd4 Mon Sep 17 00:00:00 2001 From: praneetap Date: Thu, 1 Aug 2019 15:57:08 -0700 Subject: [PATCH 26/31] feat: sam support to add resource policies to api properties (#1045) --- .../2016-10-31/api_resource_policy/README.md | 11 ++ .../api_resource_policy/template.yaml | 37 ++++ samtranslator/model/api/api_generator.py | 7 +- samtranslator/plugins/globals/globals.py | 2 +- samtranslator/swagger/swagger.py | 34 +++- .../input/api_with_resource_policy.yaml | 12 ++ .../api_with_resource_policy_global.yaml | 38 ++++ ..._with_resource_policy_global_implicit.yaml | 26 +++ .../output/api_with_resource_policy.json | 52 ++++++ .../api_with_resource_policy_global.json | 65 +++++++ ..._with_resource_policy_global_implicit.json | 160 +++++++++++++++++ .../aws-cn/api_with_resource_policy.json | 60 +++++++ .../api_with_resource_policy_global.json | 73 ++++++++ ..._with_resource_policy_global_implicit.json | 168 ++++++++++++++++++ .../aws-us-gov/api_with_resource_policy.json | 60 +++++++ .../api_with_resource_policy_global.json | 73 ++++++++ ..._with_resource_policy_global_implicit.json | 168 ++++++++++++++++++ tests/translator/test_translator.py | 3 + 18 files changed, 1045 insertions(+), 4 deletions(-) create mode 100644 examples/2016-10-31/api_resource_policy/README.md create mode 100644 examples/2016-10-31/api_resource_policy/template.yaml create mode 100644 tests/translator/input/api_with_resource_policy.yaml create mode 100644 tests/translator/input/api_with_resource_policy_global.yaml create mode 100644 tests/translator/input/api_with_resource_policy_global_implicit.yaml create mode 100644 tests/translator/output/api_with_resource_policy.json create mode 100644 tests/translator/output/api_with_resource_policy_global.json create mode 100644 tests/translator/output/api_with_resource_policy_global_implicit.json create mode 100644 tests/translator/output/aws-cn/api_with_resource_policy.json create mode 100644 tests/translator/output/aws-cn/api_with_resource_policy_global.json create mode 100644 tests/translator/output/aws-cn/api_with_resource_policy_global_implicit.json create mode 100644 tests/translator/output/aws-us-gov/api_with_resource_policy.json create mode 100644 tests/translator/output/aws-us-gov/api_with_resource_policy_global.json create mode 100644 tests/translator/output/aws-us-gov/api_with_resource_policy_global_implicit.json diff --git a/examples/2016-10-31/api_resource_policy/README.md b/examples/2016-10-31/api_resource_policy/README.md new file mode 100644 index 0000000000..7222c12908 --- /dev/null +++ b/examples/2016-10-31/api_resource_policy/README.md @@ -0,0 +1,11 @@ +# Api Resource Policy Event Source Example + +Example SAM template for adding Custom Resource Policy to Api. + +## Running the example + +```bash +# Replace YOUR_S3_ARTIFACTS_BUCKET +aws cloudformation package --template-file template.yaml --output-template-file cfn-transformed-template.yaml --s3-bucket YOUR_S3_ARTIFACTS_BUCKET +aws cloudformation deploy --template-file ./cfn-transformed-template.yaml --stack-name example-resource-policy --capabilities CAPABILITY_IAM +``` diff --git a/examples/2016-10-31/api_resource_policy/template.yaml b/examples/2016-10-31/api_resource_policy/template.yaml new file mode 100644 index 0000000000..ae8361477a --- /dev/null +++ b/examples/2016-10-31/api_resource_policy/template.yaml @@ -0,0 +1,37 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Globals: + Api: + Auth: + ResourcePolicy: + CustomStatements: [{ + "Effect": "Allow", + "Principal": "*", + "Action": "execute-api:Invoke", + "Resource": "execute-api:*/*/*", + "Condition": { + "IpAddress": { + "aws:SourceIp": "1.2.3.4" + } + } + }] +Resources: + MyFunction: + Type: AWS::Serverless::Function + Properties: + InlineCode: | + exports.handler = async (event) => { + const response = { + statusCode: 200, + body: JSON.stringify('Hello from Lambda!'), + }; + return response; + }; + Handler: index.handler + Runtime: nodejs8.10 + Events: + Api: + Type: Api + Properties: + Method: Put + Path: /get diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py index 9e21d314a0..56bd2aa303 100644 --- a/samtranslator/model/api/api_generator.py +++ b/samtranslator/model/api/api_generator.py @@ -23,8 +23,8 @@ AuthProperties = namedtuple("_AuthProperties", ["Authorizers", "DefaultAuthorizer", "InvokeRole", "AddDefaultAuthorizerToCorsPreflight", - "ApiKeyRequired"]) -AuthProperties.__new__.__defaults__ = (None, None, None, True, None) + "ApiKeyRequired", "ResourcePolicy"]) +AuthProperties.__new__.__defaults__ = (None, None, None, True, None, None) GatewayResponseProperties = ["ResponseParameters", "ResponseTemplates", "StatusCode"] @@ -325,6 +325,9 @@ def _add_auth(self): swagger_editor.add_apikey_security_definition() self._set_default_apikey_required(swagger_editor) + if auth_properties.ResourcePolicy: + swagger_editor.add_resource_policy(auth_properties.ResourcePolicy) + self.definition_body = self._openapi_postprocess(swagger_editor.swagger) def _add_gateway_responses(self): diff --git a/samtranslator/plugins/globals/globals.py b/samtranslator/plugins/globals/globals.py index f6b860bdc6..1e9f1f63f8 100644 --- a/samtranslator/plugins/globals/globals.py +++ b/samtranslator/plugins/globals/globals.py @@ -44,7 +44,7 @@ class Globals(object): # StageName: Because StageName cannot be overridden for Implicit APIs because of the current plugin # architecture SamResourceType.Api.value: [ - 'Auth', + "Auth", "Name", "DefinitionUri", "CacheClusterEnabled", diff --git a/samtranslator/swagger/swagger.py b/samtranslator/swagger/swagger.py index 38a5c3ea36..61f753dc81 100644 --- a/samtranslator/swagger/swagger.py +++ b/samtranslator/swagger/swagger.py @@ -21,6 +21,7 @@ class SwaggerEditor(object): _X_APIGW_BINARY_MEDIA_TYPES = 'x-amazon-apigateway-binary-media-types' _CONDITIONAL_IF = "Fn::If" _X_APIGW_GATEWAY_RESPONSES = 'x-amazon-apigateway-gateway-responses' + _X_APIGW_POLICY = 'x-amazon-apigateway-policy' _X_ANY_METHOD = 'x-amazon-apigateway-any-method' def __init__(self, doc): @@ -39,6 +40,7 @@ def __init__(self, doc): self.paths = self._doc["paths"] self.security_definitions = self._doc.get("securityDefinitions", {}) self.gateway_responses = self._doc.get(self._X_APIGW_GATEWAY_RESPONSES, {}) + self.resource_policy = self._doc.get(self._X_APIGW_POLICY, {}) self.definitions = self._doc.get('definitions', {}) def get_path(self, path): @@ -614,7 +616,6 @@ def add_auth_to_method(self, path, method_name, auth, api): :param string path: Path name :param string method_name: Method name :param dict auth: Auth configuration such as Authorizers, ApiKeyRequired, ResourcePolicy - (Authorizers and ApiKeyRequired supported currently) :param dict api: Reference to the related Api's properties as defined in the template. """ method_authorizer = auth and auth.get('Authorizer') @@ -788,6 +789,37 @@ def add_models(self, models): self.definitions[model_name.lower()] = schema + def add_resource_policy(self, resource_policy): + """ + Add resource policy definition to Swagger. + + :param dict resource_policy: Dictionary of resource_policy statements which gets translated + :return: + """ + if resource_policy is None: + return + + custom_statements = resource_policy.get('CustomStatements') + + if custom_statements is not None: + if not isinstance(custom_statements, list): + custom_statements = [custom_statements] + + self.resource_policy['Version'] = '2012-10-17' + if self.resource_policy.get('Statement') is None: + self.resource_policy['Statement'] = custom_statements + else: + statement = self.resource_policy['Statement'] + if isinstance(statement, list): + statement.extend(custom_statements) + else: + statement = [statement] + statement.extend(custom_statements) + + self.resource_policy['Statement'] = statement + + self._doc[self._X_APIGW_POLICY] = self.resource_policy + @property def swagger(self): """ diff --git a/tests/translator/input/api_with_resource_policy.yaml b/tests/translator/input/api_with_resource_policy.yaml new file mode 100644 index 0000000000..dac884c579 --- /dev/null +++ b/tests/translator/input/api_with_resource_policy.yaml @@ -0,0 +1,12 @@ +Resources: + ExplicitApi: + Type: AWS::Serverless::Api + Properties: + StageName: Prod + Auth: + ResourcePolicy: + CustomStatements: { + Action: 'execute-api:Invoke', + Resource: ['execute-api:/*/*/*'] + } + \ No newline at end of file diff --git a/tests/translator/input/api_with_resource_policy_global.yaml b/tests/translator/input/api_with_resource_policy_global.yaml new file mode 100644 index 0000000000..6585beb05b --- /dev/null +++ b/tests/translator/input/api_with_resource_policy_global.yaml @@ -0,0 +1,38 @@ +Globals: + Api: + Auth: + ResourcePolicy: + CustomStatements: [{ + Action: 'execute-api:Invoke', + Resource: ['execute-api:/*/*/*'] + }, + { + Action: 'execute-api:blah', + Resource: ['execute-api:/*/*/*'] + }] + +Resources: + ExplicitApi: + Type: AWS::Serverless::Api + Properties: + StageName: Prod + DefinitionBody: { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + } + } \ No newline at end of file diff --git a/tests/translator/input/api_with_resource_policy_global_implicit.yaml b/tests/translator/input/api_with_resource_policy_global_implicit.yaml new file mode 100644 index 0000000000..5ec9536e4b --- /dev/null +++ b/tests/translator/input/api_with_resource_policy_global_implicit.yaml @@ -0,0 +1,26 @@ +Globals: + Api: + Auth: + ResourcePolicy: + CustomStatements: [{ + Action: 'execute-api:Invoke', + Resource: ['execute-api:/*/*/*'] + }, + { + Action: 'execute-api:blah', + Resource: ['execute-api:/*/*/*'] + }] +Resources: + MinimalFunction: + Type: 'AWS::Serverless::Function' + Properties: + CodeUri: s3://sam-demo-bucket/hello.zip + Handler: hello.handler + Runtime: python2.7 + Events: + AddItem: + Type: Api + Properties: + Path: /add + Method: post + diff --git a/tests/translator/output/api_with_resource_policy.json b/tests/translator/output/api_with_resource_policy.json new file mode 100644 index 0000000000..ec4ca14cc9 --- /dev/null +++ b/tests/translator/output/api_with_resource_policy.json @@ -0,0 +1,52 @@ +{ + "Resources": { + "ExplicitApiDeploymente11dac9531": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: e11dac9531e1328d9249c42ac3e40044b4159d60", + "StageName": "Stage" + } + }, + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeploymente11dac9531" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } + }, + "ExplicitApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + } + } + } + } + } \ No newline at end of file diff --git a/tests/translator/output/api_with_resource_policy_global.json b/tests/translator/output/api_with_resource_policy_global.json new file mode 100644 index 0000000000..87ddea1469 --- /dev/null +++ b/tests/translator/output/api_with_resource_policy_global.json @@ -0,0 +1,65 @@ +{ + "Resources": { + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeployment8d22456d58" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } + }, + "ExplicitApiDeployment8d22456d58": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 8d22456d5883ad51c72f5d9be988d14f0a41182e", + "StageName": "Stage" + } + }, + "ExplicitApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + }, + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + }, + { + "Action": "execute-api:blah", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/api_with_resource_policy_global_implicit.json b/tests/translator/output/api_with_resource_policy_global_implicit.json new file mode 100644 index 0000000000..9be861c977 --- /dev/null +++ b/tests/translator/output/api_with_resource_policy_global_implicit.json @@ -0,0 +1,160 @@ +{ + "Resources": { + "MinimalFunctionAddItemPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MinimalFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/add", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "ServerlessRestApi" + } + } + ] + } + } + }, + "MinimalFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MinimalFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "hello.handler", + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Role": { + "Fn::GetAtt": [ + "MinimalFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "ServerlessRestApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment1ecad21e32" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + } + }, + "ServerlessRestApiDeployment1ecad21e32": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 1ecad21e325b9a3167fd5c2d6399ef59ccab0df9", + "StageName": "Stage" + } + }, + "MinimalFunctionAddItemPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MinimalFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/add", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "ServerlessRestApi" + } + } + ] + } + } + }, + "ServerlessRestApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/add": { + "post": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MinimalFunction.Arn}/invocations" + } + }, + "responses": {} + } + } + }, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + }, + { + "Action": "execute-api:blah", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + } + } + } + } +} diff --git a/tests/translator/output/aws-cn/api_with_resource_policy.json b/tests/translator/output/aws-cn/api_with_resource_policy.json new file mode 100644 index 0000000000..52961cf666 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_resource_policy.json @@ -0,0 +1,60 @@ +{ + "Resources": { + "ExplicitApiDeploymente11dac9531": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: e11dac9531e1328d9249c42ac3e40044b4159d60", + "StageName": "Stage" + } + }, + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeploymente11dac9531" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } + }, + "ExplicitApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_resource_policy_global.json b/tests/translator/output/aws-cn/api_with_resource_policy_global.json new file mode 100644 index 0000000000..2a34a70ce6 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_resource_policy_global.json @@ -0,0 +1,73 @@ +{ + "Resources": { + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeployment8d22456d58" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } + }, + "ExplicitApiDeployment8d22456d58": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 8d22456d5883ad51c72f5d9be988d14f0a41182e", + "StageName": "Stage" + } + }, + "ExplicitApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + }, + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + }, + { + "Action": "execute-api:blah", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/api_with_resource_policy_global_implicit.json b/tests/translator/output/aws-cn/api_with_resource_policy_global_implicit.json new file mode 100644 index 0000000000..c912f4dcc4 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_resource_policy_global_implicit.json @@ -0,0 +1,168 @@ +{ + "Resources": { + "MinimalFunctionAddItemPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MinimalFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/add", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "ServerlessRestApi" + } + } + ] + } + } + }, + "MinimalFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MinimalFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "hello.handler", + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Role": { + "Fn::GetAtt": [ + "MinimalFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "ServerlessRestApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment0ff9f5a989" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + } + }, + "ServerlessRestApiDeployment0ff9f5a989": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 0ff9f5a9899528e1cb050311c49f15a88071a275", + "StageName": "Stage" + } + }, + "MinimalFunctionAddItemPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MinimalFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/add", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "ServerlessRestApi" + } + } + ] + } + } + }, + "ServerlessRestApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/add": { + "post": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MinimalFunction.Arn}/invocations" + } + }, + "responses": {} + } + } + }, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + }, + { + "Action": "execute-api:blah", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_resource_policy.json b/tests/translator/output/aws-us-gov/api_with_resource_policy.json new file mode 100644 index 0000000000..52961cf666 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_resource_policy.json @@ -0,0 +1,60 @@ +{ + "Resources": { + "ExplicitApiDeploymente11dac9531": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: e11dac9531e1328d9249c42ac3e40044b4159d60", + "StageName": "Stage" + } + }, + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeploymente11dac9531" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } + }, + "ExplicitApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/api_with_resource_policy_global.json b/tests/translator/output/aws-us-gov/api_with_resource_policy_global.json new file mode 100644 index 0000000000..e74f826487 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_resource_policy_global.json @@ -0,0 +1,73 @@ +{ + "Resources": { + "ExplicitApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ExplicitApiDeployment8d22456d58" + }, + "RestApiId": { + "Ref": "ExplicitApi" + }, + "StageName": "Prod" + } + }, + "ExplicitApiDeployment8d22456d58": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 8d22456d5883ad51c72f5d9be988d14f0a41182e", + "StageName": "Stage" + } + }, + "ExplicitApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": {}, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + }, + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + }, + { + "Action": "execute-api:blah", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + } + } +} diff --git a/tests/translator/output/aws-us-gov/api_with_resource_policy_global_implicit.json b/tests/translator/output/aws-us-gov/api_with_resource_policy_global_implicit.json new file mode 100644 index 0000000000..c06c2188c8 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_resource_policy_global_implicit.json @@ -0,0 +1,168 @@ +{ + "Resources": { + "MinimalFunctionAddItemPermissionProd": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MinimalFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/add", + { + "__Stage__": "Prod", + "__ApiId__": { + "Ref": "ServerlessRestApi" + } + } + ] + } + } + }, + "MinimalFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + }, + "MinimalFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "hello.handler", + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Role": { + "Fn::GetAtt": [ + "MinimalFunctionRole", + "Arn" + ] + }, + "Runtime": "python2.7", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "ServerlessRestApiProdStage": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment9558094c1e" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + } + }, + "MinimalFunctionAddItemPermissionTest": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:invokeFunction", + "Principal": "apigateway.amazonaws.com", + "FunctionName": { + "Ref": "MinimalFunction" + }, + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/add", + { + "__Stage__": "*", + "__ApiId__": { + "Ref": "ServerlessRestApi" + } + } + ] + } + } + }, + "ServerlessRestApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Body": { + "info": { + "version": "1.0", + "title": { + "Ref": "AWS::StackName" + } + }, + "paths": { + "/add": { + "post": { + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MinimalFunction.Arn}/invocations" + } + }, + "responses": {} + } + } + }, + "swagger": "2.0", + "x-amazon-apigateway-policy": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "execute-api:Invoke", + "Resource": [ + "execute-api:/*/*/*" + ] + }, + { + "Action": "execute-api:blah", + "Resource": [ + "execute-api:/*/*/*" + ] + } + ] + } + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + } + }, + "ServerlessRestApiDeployment9558094c1e": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Description": "RestApi deployment id: 9558094c1ecacce5e02be40fdb03356118d9ccac", + "StageName": "Stage" + } + } + } +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index 957748715f..ebc88a7b0b 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -186,6 +186,9 @@ class TestTranslatorEndToEnd(TestCase): 'api_with_xray_tracing', 'api_request_model', 'api_with_stage_tags', + 'api_with_resource_policy', + 'api_with_resource_policy_global', + 'api_with_resource_policy_global_implicit', 's3', 's3_create_remove', 's3_existing_lambda_notification_configuration', From 738f7bf1d4bc7a14169f7218107ab743240278da Mon Sep 17 00:00:00 2001 From: gomi_ningen Date: Wed, 7 Aug 2019 02:31:51 +0900 Subject: [PATCH 27/31] fix: make sure ApplicationId is not null (#1062) --- .../plugins/application/serverless_app_plugin.py | 1 + tests/translator/input/error_null_application_id.yaml | 7 +++++++ tests/translator/output/error_null_application_id.json | 8 ++++++++ tests/translator/test_translator.py | 1 + 4 files changed, 17 insertions(+) create mode 100644 tests/translator/input/error_null_application_id.yaml create mode 100644 tests/translator/output/error_null_application_id.json diff --git a/samtranslator/plugins/application/serverless_app_plugin.py b/samtranslator/plugins/application/serverless_app_plugin.py index ac419d9baf..5058b98d7f 100644 --- a/samtranslator/plugins/application/serverless_app_plugin.py +++ b/samtranslator/plugins/application/serverless_app_plugin.py @@ -132,6 +132,7 @@ def _can_process_application(self, app): return (self.LOCATION_KEY in app.properties and isinstance(app.properties[self.LOCATION_KEY], dict) and self.APPLICATION_ID_KEY in app.properties[self.LOCATION_KEY] and + app.properties[self.LOCATION_KEY][self.APPLICATION_ID_KEY] is not None and self.SEMANTIC_VERSION_KEY in app.properties[self.LOCATION_KEY]) def _handle_get_application_request(self, app_id, semver, key, logical_id): diff --git a/tests/translator/input/error_null_application_id.yaml b/tests/translator/input/error_null_application_id.yaml new file mode 100644 index 0000000000..3985e3782c --- /dev/null +++ b/tests/translator/input/error_null_application_id.yaml @@ -0,0 +1,7 @@ +Resources: + Application: + Type: AWS::Serverless::Application + Properties: + Location: + ApplicationId: null + SemanticVersion: 1.0.0 diff --git a/tests/translator/output/error_null_application_id.json b/tests/translator/output/error_null_application_id.json new file mode 100644 index 0000000000..579a684c8f --- /dev/null +++ b/tests/translator/output/error_null_application_id.json @@ -0,0 +1,8 @@ +{ + "errors": [ + { + "errorMessage": "Resource with id [Application] is invalid. Property 'ApplicationId' cannot be blank." + } + ], + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [Application] is invalid. Property 'ApplicationId' cannot be blank." +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index ebc88a7b0b..fbc507b44f 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -458,6 +458,7 @@ def _generate_new_deployment_hash(self, logical_id, dict_to_hash, rest_api_to_sw 'error_missing_startingposition', 'error_missing_stream', 'error_multiple_resource_errors', + 'error_null_application_id', 'error_s3_not_in_template', 'error_table_invalid_attributetype', 'error_table_primary_key_missing_name', From 527c190d803d6578e2de011994403642b9b1a241 Mon Sep 17 00:00:00 2001 From: Mathias Schreck Date: Tue, 6 Aug 2019 19:47:31 +0200 Subject: [PATCH 28/31] docs: fix policy in safe deployments example and documentation (#1064) --- docs/safe_lambda_deployments.rst | 8 ++++---- examples/2016-10-31/lambda_safe_deployments/template.yaml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/safe_lambda_deployments.rst b/docs/safe_lambda_deployments.rst index 539d124242..6f0b741270 100644 --- a/docs/safe_lambda_deployments.rst +++ b/docs/safe_lambda_deployments.rst @@ -93,7 +93,7 @@ resource: Type: AWS::Serverless::Function Properties: Handler: index.handler - Runtime: nodejs6.10 + Runtime: nodejs8.10 AutoPublishAlias: live DeploymentPreference: Type: Linear10PercentEvery10Minutes @@ -162,8 +162,8 @@ resource: - Effect: "Allow" Action: - "lambda:InvokeFunction" - Resource: !Ref MyLambdaFunction.Version - Runtime: nodejs6.10 + Resource: !GetAtt MyLambdaFunction.Arn + Runtime: nodejs8.10 FunctionName: 'CodeDeployHook_preTrafficHook' DeploymentPreference: Enabled: false @@ -286,7 +286,7 @@ Hooks are extremely powerful because: - Effect: "Allow" Action: - "lambda:InvokeFunction" - Resource: !Ref MyLambdaFunction.Version + Resource: !GetAtt MyLambdaFunction.Arn Checkout the lambda_safe_deployments_ folder for an example for how to create SAM template that contains a hook function. diff --git a/examples/2016-10-31/lambda_safe_deployments/template.yaml b/examples/2016-10-31/lambda_safe_deployments/template.yaml index 211158fbca..49c31e7c7a 100644 --- a/examples/2016-10-31/lambda_safe_deployments/template.yaml +++ b/examples/2016-10-31/lambda_safe_deployments/template.yaml @@ -34,7 +34,7 @@ Resources: - Effect: "Allow" Action: - "lambda:InvokeFunction" - Resource: !Ref safeTest.Version + Resource: !GetAtt safeTest.Arn Runtime: nodejs8.10 FunctionName: 'CodeDeployHook_preTrafficHook' DeploymentPreference: From 90bfefd4e7c0e5421645269bd4a520cfa9dbb375 Mon Sep 17 00:00:00 2001 From: Keeton Hodgson Date: Tue, 13 Aug 2019 10:49:04 -0700 Subject: [PATCH 29/31] chore: V1.14.0 release patch (#1081) --- requirements/dev.txt | 2 +- tests/model/test_sam_resources.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 4c55168794..35279a22a7 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -3,7 +3,7 @@ flake8>=3.3.0 tox>=2.2.1 pytest-cov>=2.4.0 pylint>=1.7.2,<2.0 -pyyaml>=4.2b1 +pyyaml>=5.1 # Test requirements pytest>=3.0.7 diff --git a/tests/model/test_sam_resources.py b/tests/model/test_sam_resources.py index c38ce1a7bf..a2129d1eb7 100644 --- a/tests/model/test_sam_resources.py +++ b/tests/model/test_sam_resources.py @@ -132,6 +132,7 @@ class TestApiTags(TestCase): } } + @patch('boto3.session.Session.region_name', 'ap-southeast-1') def test_with_no_tags(self): api = SamApi("foo") api.Tags = {} @@ -142,6 +143,7 @@ def test_with_no_tags(self): self.assertEqual(deployment.__len__(), 1) self.assertEqual(deployment[0].Tags, []) + @patch('boto3.session.Session.region_name', 'ap-southeast-1') def test_with_tags(self): api = SamApi("foo") api.Tags = { From 3c8cef1ffe486115d1624f304598e59080297f9c Mon Sep 17 00:00:00 2001 From: Parimal Deshmukh Date: Tue, 13 Aug 2019 15:42:28 -0700 Subject: [PATCH 30/31] feat: add support for Fn::If in function policies (#988) --- samtranslator/model/function_policies.py | 45 +++++- samtranslator/model/intrinsics.py | 32 ++++ samtranslator/model/sam_resources.py | 33 ++++- .../policies/policy_templates_plugin.py | 67 ++++++--- tests/model/test_function_policies.py | 137 ++++++++++++++++++ ...ction_with_conditional_managed_policy.yaml | 17 +++ ...ional_managed_policy_and_ref_no_value.yaml | 17 +++ ...tion_with_conditional_policy_template.yaml | 19 +++ ...onal_policy_template_and_ref_no_value.yaml | 18 +++ ...ction_with_conditional_managed_policy.json | 71 +++++++++ ...ional_managed_policy_and_ref_no_value.json | 71 +++++++++ ...tion_with_conditional_policy_template.json | 126 ++++++++++++++++ ...onal_policy_template_and_ref_no_value.json | 91 ++++++++++++ ...ction_with_conditional_managed_policy.json | 71 +++++++++ ...ional_managed_policy_and_ref_no_value.json | 71 +++++++++ ...tion_with_conditional_policy_template.json | 126 ++++++++++++++++ ...onal_policy_template_and_ref_no_value.json | 91 ++++++++++++ ...ction_with_conditional_managed_policy.json | 71 +++++++++ ...ional_managed_policy_and_ref_no_value.json | 71 +++++++++ ...tion_with_conditional_policy_template.json | 126 ++++++++++++++++ ...onal_policy_template_and_ref_no_value.json | 91 ++++++++++++ tests/translator/test_translator.py | 4 + 22 files changed, 1442 insertions(+), 24 deletions(-) create mode 100644 tests/translator/input/function_with_conditional_managed_policy.yaml create mode 100644 tests/translator/input/function_with_conditional_managed_policy_and_ref_no_value.yaml create mode 100644 tests/translator/input/function_with_conditional_policy_template.yaml create mode 100644 tests/translator/input/function_with_conditional_policy_template_and_ref_no_value.yaml create mode 100644 tests/translator/output/aws-cn/function_with_conditional_managed_policy.json create mode 100644 tests/translator/output/aws-cn/function_with_conditional_managed_policy_and_ref_no_value.json create mode 100644 tests/translator/output/aws-cn/function_with_conditional_policy_template.json create mode 100644 tests/translator/output/aws-cn/function_with_conditional_policy_template_and_ref_no_value.json create mode 100644 tests/translator/output/aws-us-gov/function_with_conditional_managed_policy.json create mode 100644 tests/translator/output/aws-us-gov/function_with_conditional_managed_policy_and_ref_no_value.json create mode 100644 tests/translator/output/aws-us-gov/function_with_conditional_policy_template.json create mode 100644 tests/translator/output/aws-us-gov/function_with_conditional_policy_template_and_ref_no_value.json create mode 100644 tests/translator/output/function_with_conditional_managed_policy.json create mode 100644 tests/translator/output/function_with_conditional_managed_policy_and_ref_no_value.json create mode 100644 tests/translator/output/function_with_conditional_policy_template.json create mode 100644 tests/translator/output/function_with_conditional_policy_template_and_ref_no_value.json diff --git a/samtranslator/model/function_policies.py b/samtranslator/model/function_policies.py index c62e94d19d..843366e388 100644 --- a/samtranslator/model/function_policies.py +++ b/samtranslator/model/function_policies.py @@ -3,7 +3,8 @@ from six import string_types -from samtranslator.model.intrinsics import is_instrinsic +from samtranslator.model.intrinsics import is_instrinsic, is_intrinsic_if, is_intrinsic_no_value +from samtranslator.model.exceptions import InvalidTemplateException PolicyEntry = namedtuple("PolicyEntry", "data type") @@ -114,8 +115,16 @@ def _get_type(self, policy): # Must handle intrinsic functions. Policy could be a primitive type or an intrinsic function - # Managed policies are either string or an intrinsic function that resolves to a string - if isinstance(policy, string_types) or is_instrinsic(policy): + # Managed policies are of type string + if isinstance(policy, string_types): + return PolicyTypes.MANAGED_POLICY + + # Handle the special case for 'if' intrinsic function + if is_intrinsic_if(policy): + return self._get_type_from_intrinsic_if(policy) + + # Intrinsic functions are treated as managed policies by default + if is_instrinsic(policy): return PolicyTypes.MANAGED_POLICY # Policy statement is a dictionary with the key "Statement" in it @@ -143,6 +152,36 @@ def _is_policy_template(self, policy): len(policy) == 1 and \ self._policy_template_processor.has(list(policy.keys())[0]) is True + def _get_type_from_intrinsic_if(self, policy): + """ + Returns the type of the given policy assuming that it is an intrinsic if function + + :param policy: Input value to get type from + :return: PolicyTypes: Type of the given policy. PolicyTypes.UNKNOWN, if type could not be inferred + """ + intrinsic_if_value = policy["Fn::If"] + + if not len(intrinsic_if_value) == 3: + raise InvalidTemplateException("Fn::If requires 3 arguments") + + if_data = intrinsic_if_value[1] + else_data = intrinsic_if_value[2] + + if_data_type = self._get_type(if_data) + else_data_type = self._get_type(else_data) + + if if_data_type == else_data_type: + return if_data_type + + if is_intrinsic_no_value(if_data): + return else_data_type + + if is_intrinsic_no_value(else_data): + return if_data_type + + raise InvalidTemplateException("Different policy types within the same Fn::If statement is unsupported. " + "Separate different policy types into different Fn::If statements") + class PolicyTypes(Enum): """ diff --git a/samtranslator/model/intrinsics.py b/samtranslator/model/intrinsics.py index 720540b90e..11edd9dabf 100644 --- a/samtranslator/model/intrinsics.py +++ b/samtranslator/model/intrinsics.py @@ -138,3 +138,35 @@ def is_instrinsic(input): return key == "Ref" or key == "Condition" or key.startswith("Fn::") return False + + +def is_intrinsic_if(input): + """ + Is the given input an intrinsic if? Intrinsic function 'if' is a dictionary with single + key - if + + :param input: Input value to check if it is an intrinsic if + :return: True, if yes + """ + + if not is_instrinsic(input): + return False + + key = list(input.keys())[0] + return key == "Fn::If" + + +def is_intrinsic_no_value(input): + """ + Is the given input an intrinsic Ref: AWS::NoValue? Intrinsic function is a dictionary with single + key - Ref and value - AWS::NoValue + + :param input: Input value to check if it is an intrinsic if + :return: True, if yes + """ + + if not is_instrinsic(input): + return False + + key = list(input.keys())[0] + return key == "Ref" and input["Ref"] == "AWS::NoValue" diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py index dfacebbecc..91285a97f7 100644 --- a/samtranslator/model/sam_resources.py +++ b/samtranslator/model/sam_resources.py @@ -22,6 +22,7 @@ from samtranslator.model.types import dict_of, is_str, is_type, list_of, one_of, any_type from samtranslator.translator import logical_id_generator from samtranslator.translator.arn_generator import ArnGenerator +from samtranslator.model.intrinsics import is_intrinsic_if, is_intrinsic_no_value class SamFunction(SamResourceMacro): @@ -212,10 +213,34 @@ def _construct_role(self, managed_policy_map): if policy_entry.type is PolicyTypes.POLICY_STATEMENT: - policy_documents.append({ - 'PolicyName': execution_role.logical_id + 'Policy' + str(index), - 'PolicyDocument': policy_entry.data - }) + if is_intrinsic_if(policy_entry.data): + + intrinsic_if = policy_entry.data + then_statement = intrinsic_if["Fn::If"][1] + else_statement = intrinsic_if["Fn::If"][2] + + if not is_intrinsic_no_value(then_statement): + then_statement = { + 'PolicyName': execution_role.logical_id + 'Policy' + str(index), + 'PolicyDocument': then_statement + } + intrinsic_if["Fn::If"][1] = then_statement + + if not is_intrinsic_no_value(else_statement): + else_statement = { + 'PolicyName': execution_role.logical_id + 'Policy' + str(index), + 'PolicyDocument': else_statement + } + intrinsic_if["Fn::If"][2] = else_statement + + policy_documents.append(intrinsic_if) + + else: + policy_documents.append({ + 'PolicyName': execution_role.logical_id + 'Policy' + str(index), + 'PolicyDocument': policy_entry.data + }) + elif policy_entry.type is PolicyTypes.MANAGED_POLICY: # There are three options: diff --git a/samtranslator/plugins/policies/policy_templates_plugin.py b/samtranslator/plugins/policies/policy_templates_plugin.py index 9ae515ff2c..50aded6478 100644 --- a/samtranslator/plugins/policies/policy_templates_plugin.py +++ b/samtranslator/plugins/policies/policy_templates_plugin.py @@ -2,6 +2,7 @@ from samtranslator.model.function_policies import FunctionPolicies, PolicyTypes from samtranslator.model.exceptions import InvalidResourceException from samtranslator.policy_template_processor.exceptions import InsufficientParameterValues, InvalidParameterValues +from samtranslator.model.intrinsics import is_intrinsic_if, is_intrinsic_no_value class PolicyTemplatesForFunctionPlugin(BasePlugin): @@ -55,28 +56,60 @@ def on_before_transform_resource(self, logical_id, resource_type, resource_prope result.append(policy_entry.data) continue - # We are processing policy templates. We know they have a particular structure: - # {"templateName": { parameter_values_dict }} - template_data = policy_entry.data - template_name = list(template_data.keys())[0] - template_parameters = list(template_data.values())[0] - - try: - - # 'convert' will return a list of policy statements - result.append(self._policy_template_processor.convert(template_name, template_parameters)) + if is_intrinsic_if(policy_entry.data): + # If policy is an intrinsic if, we need to process each sub-statement separately + processed_intrinsic_if = self._process_intrinsic_if_policy_template(logical_id, policy_entry) + result.append(processed_intrinsic_if) + continue - except InsufficientParameterValues as ex: - # Exception's message will give lot of specific details - raise InvalidResourceException(logical_id, str(ex)) - except InvalidParameterValues: - raise InvalidResourceException(logical_id, - "Must specify valid parameter values for policy template '{}'" - .format(template_name)) + converted_policy = self._process_policy_template(logical_id, policy_entry.data) + result.append(converted_policy) # Save the modified policies list to the input resource_properties[FunctionPolicies.POLICIES_PROPERTY_NAME] = result + def _process_intrinsic_if_policy_template(self, logical_id, policy_entry): + intrinsic_if = policy_entry.data + then_statement = intrinsic_if["Fn::If"][1] + else_statement = intrinsic_if["Fn::If"][2] + + processed_then_statement = then_statement \ + if is_intrinsic_no_value(then_statement) \ + else self._process_policy_template(logical_id, then_statement) + + processed_else_statement = else_statement \ + if is_intrinsic_no_value(else_statement) \ + else self._process_policy_template(logical_id, else_statement) + + processed_intrinsic_if = { + "Fn::If": [ + policy_entry.data["Fn::If"][0], + processed_then_statement, + processed_else_statement + ] + } + + return processed_intrinsic_if + + def _process_policy_template(self, logical_id, template_data): + + # We are processing policy templates. We know they have a particular structure: + # {"templateName": { parameter_values_dict }} + template_name = list(template_data.keys())[0] + template_parameters = list(template_data.values())[0] + try: + + # 'convert' will return a list of policy statements + return self._policy_template_processor.convert(template_name, template_parameters) + + except InsufficientParameterValues as ex: + # Exception's message will give lot of specific details + raise InvalidResourceException(logical_id, str(ex)) + except InvalidParameterValues: + raise InvalidResourceException(logical_id, + "Must specify valid parameter values for policy template '{}'" + .format(template_name)) + def _is_supported(self, resource_type): """ Is this resource supported by this plugin? diff --git a/tests/model/test_function_policies.py b/tests/model/test_function_policies.py index 371ea70b18..a0a82b4bd9 100644 --- a/tests/model/test_function_policies.py +++ b/tests/model/test_function_policies.py @@ -2,6 +2,8 @@ from unittest import TestCase from samtranslator.model.function_policies import FunctionPolicies, PolicyTypes, PolicyEntry +from samtranslator.model.exceptions import InvalidTemplateException +from samtranslator.model.intrinsics import is_intrinsic_if, is_intrinsic_no_value class TestFunctionPolicies(TestCase): @@ -333,3 +335,138 @@ def test_is_policy_template_must_return_false_without_the_processor(self): self.assertFalse(function_policies_obj._is_policy_template(policy)) self.policy_template_processor_mock.has.assert_not_called() + + def test_is_intrinsic_if_must_return_true_for_if(self): + policy = { + "Fn::If": "some value" + } + + self.assertTrue(is_intrinsic_if(policy)) + + def test_is_intrinsic_if_must_return_false_for_others(self): + too_many_keys = { + "Fn::If": "some value", + "Fn::And": "other value" + } + + not_if = { + "Fn::Or": "some value" + } + + self.assertFalse(is_intrinsic_if(too_many_keys)) + self.assertFalse(is_intrinsic_if(not_if)) + self.assertFalse(is_intrinsic_if(None)) + + def test_is_intrinsic_no_value_must_return_true_for_no_value(self): + policy = { + "Ref": "AWS::NoValue" + } + + self.assertTrue(is_intrinsic_no_value(policy)) + + def test_is_intrinsic_no_value_must_return_false_for_other_value(self): + bad_key = { + "sRefs": "AWS::NoValue" + } + + bad_value = { + "Ref": "SWA::NoValue" + } + + too_many_keys = { + "Ref": "AWS::NoValue", + "feR": "SWA::NoValue" + } + + self.assertFalse(is_intrinsic_no_value(bad_key)) + self.assertFalse(is_intrinsic_no_value(bad_value)) + self.assertFalse(is_intrinsic_no_value(None)) + self.assertFalse(is_intrinsic_no_value(too_many_keys)) + + def test_get_type_with_intrinsic_if_must_return_managed_policy_type(self): + managed_policy = { + "Fn::If": ["SomeCondition", "some managed policy arn", "other managed policy arn"] + } + + no_value_if = { + "Fn::If": ["SomeCondition", {"Ref": "AWS::NoValue"}, "other managed policy arn"] + } + + no_value_else = { + "Fn::If": ["SomeCondition", "other managed policy arn", {"Ref": "AWS::NoValue"}] + } + + expected_managed_policy = PolicyTypes.MANAGED_POLICY + + self.assertTrue(expected_managed_policy, self.function_policies._get_type(managed_policy)) + self.assertTrue(expected_managed_policy, self.function_policies._get_type(no_value_if)) + self.assertTrue(expected_managed_policy, self.function_policies._get_type(no_value_else)) + + def test_get_type_with_intrinsic_if_must_return_policy_statement_type(self): + policy_statement = { + "Fn::If": ["SomeCondition", {"Statement": "then statement"}, {"Statement": "else statement"}] + } + + no_value_if = { + "Fn::If": ["SomeCondition", {"Ref": "AWS::NoValue"}, {"Statement": "else statement"}] + } + + no_value_else = { + "Fn::If": ["SomeCondition", {"Statement": "then statement"}, {"Ref": "AWS::NoValue"}] + } + expected_managed_policy = PolicyTypes.POLICY_STATEMENT + + self.assertTrue(expected_managed_policy, self.function_policies._get_type(policy_statement)) + self.assertTrue(expected_managed_policy, self.function_policies._get_type(no_value_if)) + self.assertTrue(expected_managed_policy, self.function_policies._get_type(no_value_else)) + + def test_get_type_with_intrinsic_if_must_return_policy_template_type(self): + policy_template = { + "Fn::If": [ "SomeCondition", + {"template_name_one": { "Param1": "foo"}}, + {"template_name_one": { "Param1": "foo"}} + ] + } + no_value_if = { + "Fn::If": [ "SomeCondition", + {"Ref": "AWS::NoValue"}, + {"template_name_one": { "Param1": "foo"}} + ] + } + no_value_else = { + "Fn::If": [ "SomeCondition", + {"template_name_one": { "Param1": "foo"}}, + {"Ref": "AWS::NoValue"} + ] + } + + expected_managed_policy = PolicyTypes.POLICY_TEMPLATE + self.policy_template_processor_mock.has.return_value = True + function_policies = FunctionPolicies({}, self.policy_template_processor_mock) + + self.assertTrue(expected_managed_policy, function_policies._get_type(policy_template)) + self.assertTrue(expected_managed_policy, function_policies._get_type(no_value_if)) + self.assertTrue(expected_managed_policy, function_policies._get_type(no_value_else)) + + def test_get_type_with_intrinsic_if_must_raise_exception_for_bad_policy(self): + policy_too_few_values = { + "Fn::If": ["condition", "then"] + } + + policy_too_many_values = { + "Fn::If": ["condition", "then", "else", "extra"] + } + + self.assertRaises(InvalidTemplateException, self.function_policies._get_type, policy_too_few_values) + self.assertRaises(InvalidTemplateException, self.function_policies._get_type, policy_too_many_values) + + def test_get_type_with_intrinsic_if_must_raise_exception_for_different_policy_types(self): + policy_one = { + "Fn::If": ["condition", "then", {"Statement": "else"}] + } + policy_two = { + "Fn::If": ["condition", {"Statement": "then"}, "else"] + } + + self.assertRaises(InvalidTemplateException, self.function_policies._get_type, policy_one) + self.assertRaises(InvalidTemplateException, self.function_policies._get_type, policy_two) \ No newline at end of file diff --git a/tests/translator/input/function_with_conditional_managed_policy.yaml b/tests/translator/input/function_with_conditional_managed_policy.yaml new file mode 100644 index 0000000000..6bfed9d071 --- /dev/null +++ b/tests/translator/input/function_with_conditional_managed_policy.yaml @@ -0,0 +1,17 @@ +Conditions: + DummyCondition: + !Equals ["", ""] + +Resources: + FunctionWithConditionalPolicy: + Type: AWS::Serverless::Function + Properties: + Description: A function that has Fn::If in the policies property + Handler: hello.handler + Runtime: python2.7 + CodeUri: s3://sam-demo-bucket/hello.zip + Policies: + - !If + - DummyCondition + - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess + - !Sub arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess \ No newline at end of file diff --git a/tests/translator/input/function_with_conditional_managed_policy_and_ref_no_value.yaml b/tests/translator/input/function_with_conditional_managed_policy_and_ref_no_value.yaml new file mode 100644 index 0000000000..62f9528016 --- /dev/null +++ b/tests/translator/input/function_with_conditional_managed_policy_and_ref_no_value.yaml @@ -0,0 +1,17 @@ +Conditions: + DummyCondition: + !Equals ["", ""] + +Resources: + FunctionWithConditionalPolicy: + Type: AWS::Serverless::Function + Properties: + Description: A function that has Fn::If in the policies property + Handler: hello.handler + Runtime: python2.7 + CodeUri: s3://sam-demo-bucket/hello.zip + Policies: + - !If + - DummyCondition + - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess + - !Ref "AWS::NoValue" \ No newline at end of file diff --git a/tests/translator/input/function_with_conditional_policy_template.yaml b/tests/translator/input/function_with_conditional_policy_template.yaml new file mode 100644 index 0000000000..4b7a0b8fe9 --- /dev/null +++ b/tests/translator/input/function_with_conditional_policy_template.yaml @@ -0,0 +1,19 @@ +Conditions: + DummyCondition: + !Equals ["", ""] + +Resources: + FunctionWithConditionalPolicy: + Type: AWS::Serverless::Function + Properties: + Description: A function that has Fn::If in the policies property + Handler: hello.handler + Runtime: python2.7 + CodeUri: s3://sam-demo-bucket/hello.zip + Policies: + - !If + - DummyCondition + - AWSSecretsManagerGetSecretValuePolicy: + SecretArn: "Dummy Secret Arn" + - AWSSecretsManagerRotationPolicy: + FunctionName: "Dummy Function Name" \ No newline at end of file diff --git a/tests/translator/input/function_with_conditional_policy_template_and_ref_no_value.yaml b/tests/translator/input/function_with_conditional_policy_template_and_ref_no_value.yaml new file mode 100644 index 0000000000..432b4db2ab --- /dev/null +++ b/tests/translator/input/function_with_conditional_policy_template_and_ref_no_value.yaml @@ -0,0 +1,18 @@ +Conditions: + DummyCondition: + !Equals ["", ""] + +Resources: + FunctionWithConditionalPolicy: + Type: AWS::Serverless::Function + Properties: + Description: A function that has Fn::If in the policies property + Handler: hello.handler + Runtime: python2.7 + CodeUri: s3://sam-demo-bucket/hello.zip + Policies: + - !If + - DummyCondition + - AWSSecretsManagerGetSecretValuePolicy: + SecretArn: "Dummy Secret Arn" + - !Ref "AWS::NoValue" \ No newline at end of file diff --git a/tests/translator/output/aws-cn/function_with_conditional_managed_policy.json b/tests/translator/output/aws-cn/function_with_conditional_managed_policy.json new file mode 100644 index 0000000000..f014353300 --- /dev/null +++ b/tests/translator/output/aws-cn/function_with_conditional_managed_policy.json @@ -0,0 +1,71 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + { + "Fn::If": [ + "DummyCondition", + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess" + }, + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/function_with_conditional_managed_policy_and_ref_no_value.json b/tests/translator/output/aws-cn/function_with_conditional_managed_policy_and_ref_no_value.json new file mode 100644 index 0000000000..bcd345bf35 --- /dev/null +++ b/tests/translator/output/aws-cn/function_with_conditional_managed_policy_and_ref_no_value.json @@ -0,0 +1,71 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + { + "Fn::If": [ + "DummyCondition", + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess" + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/function_with_conditional_policy_template.json b/tests/translator/output/aws-cn/function_with_conditional_policy_template.json new file mode 100644 index 0000000000..6cb4ad3aae --- /dev/null +++ b/tests/translator/output/aws-cn/function_with_conditional_policy_template.json @@ -0,0 +1,126 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Policies": [ + { + "Fn::If": [ + "DummyCondition", + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:GetSecretValue" + ], + "Resource": { + "Fn::Sub": [ + "${secretArn}", + { + "secretArn": "Dummy Secret Arn" + } + ] + }, + "Effect": "Allow" + } + ] + } + }, + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecretVersionStage" + ], + "Resource": { + "Fn::Sub": "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:*" + }, + "Effect": "Allow", + "Condition": { + "StringEquals": { + "secretsmanager:resource/AllowRotationLambdaArn": { + "Fn::Sub": [ + "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${functionName}", + { + "functionName": "Dummy Function Name" + } + ] + } + } + } + }, + { + "Action": [ + "secretsmanager:GetRandomPassword" + ], + "Resource": "*", + "Effect": "Allow" + } + ] + } + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-cn/function_with_conditional_policy_template_and_ref_no_value.json b/tests/translator/output/aws-cn/function_with_conditional_policy_template_and_ref_no_value.json new file mode 100644 index 0000000000..39be617ed1 --- /dev/null +++ b/tests/translator/output/aws-cn/function_with_conditional_policy_template_and_ref_no_value.json @@ -0,0 +1,91 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Policies": [ + { + "Fn::If": [ + "DummyCondition", + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:GetSecretValue" + ], + "Resource": { + "Fn::Sub": [ + "${secretArn}", + { + "secretArn": "Dummy Secret Arn" + } + ] + }, + "Effect": "Allow" + } + ] + } + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/function_with_conditional_managed_policy.json b/tests/translator/output/aws-us-gov/function_with_conditional_managed_policy.json new file mode 100644 index 0000000000..859c85a8a1 --- /dev/null +++ b/tests/translator/output/aws-us-gov/function_with_conditional_managed_policy.json @@ -0,0 +1,71 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + { + "Fn::If": [ + "DummyCondition", + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess" + }, + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/function_with_conditional_managed_policy_and_ref_no_value.json b/tests/translator/output/aws-us-gov/function_with_conditional_managed_policy_and_ref_no_value.json new file mode 100644 index 0000000000..ddcf43ff1a --- /dev/null +++ b/tests/translator/output/aws-us-gov/function_with_conditional_managed_policy_and_ref_no_value.json @@ -0,0 +1,71 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + { + "Fn::If": [ + "DummyCondition", + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess" + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/function_with_conditional_policy_template.json b/tests/translator/output/aws-us-gov/function_with_conditional_policy_template.json new file mode 100644 index 0000000000..7a9e12b898 --- /dev/null +++ b/tests/translator/output/aws-us-gov/function_with_conditional_policy_template.json @@ -0,0 +1,126 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Policies": [ + { + "Fn::If": [ + "DummyCondition", + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:GetSecretValue" + ], + "Resource": { + "Fn::Sub": [ + "${secretArn}", + { + "secretArn": "Dummy Secret Arn" + } + ] + }, + "Effect": "Allow" + } + ] + } + }, + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecretVersionStage" + ], + "Resource": { + "Fn::Sub": "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:*" + }, + "Effect": "Allow", + "Condition": { + "StringEquals": { + "secretsmanager:resource/AllowRotationLambdaArn": { + "Fn::Sub": [ + "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${functionName}", + { + "functionName": "Dummy Function Name" + } + ] + } + } + } + }, + { + "Action": [ + "secretsmanager:GetRandomPassword" + ], + "Resource": "*", + "Effect": "Allow" + } + ] + } + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/function_with_conditional_policy_template_and_ref_no_value.json b/tests/translator/output/aws-us-gov/function_with_conditional_policy_template_and_ref_no_value.json new file mode 100644 index 0000000000..f3d43297cb --- /dev/null +++ b/tests/translator/output/aws-us-gov/function_with_conditional_policy_template_and_ref_no_value.json @@ -0,0 +1,91 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Policies": [ + { + "Fn::If": [ + "DummyCondition", + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:GetSecretValue" + ], + "Resource": { + "Fn::Sub": [ + "${secretArn}", + { + "secretArn": "Dummy Secret Arn" + } + ] + }, + "Effect": "Allow" + } + ] + } + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/function_with_conditional_managed_policy.json b/tests/translator/output/function_with_conditional_managed_policy.json new file mode 100644 index 0000000000..a7aacc2839 --- /dev/null +++ b/tests/translator/output/function_with_conditional_managed_policy.json @@ -0,0 +1,71 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + { + "Fn::If": [ + "DummyCondition", + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess" + }, + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/function_with_conditional_managed_policy_and_ref_no_value.json b/tests/translator/output/function_with_conditional_managed_policy_and_ref_no_value.json new file mode 100644 index 0000000000..056fd49c55 --- /dev/null +++ b/tests/translator/output/function_with_conditional_managed_policy_and_ref_no_value.json @@ -0,0 +1,71 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + { + "Fn::If": [ + "DummyCondition", + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess" + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/function_with_conditional_policy_template.json b/tests/translator/output/function_with_conditional_policy_template.json new file mode 100644 index 0000000000..dd145ce751 --- /dev/null +++ b/tests/translator/output/function_with_conditional_policy_template.json @@ -0,0 +1,126 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Policies": [ + { + "Fn::If": [ + "DummyCondition", + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:GetSecretValue" + ], + "Resource": { + "Fn::Sub": [ + "${secretArn}", + { + "secretArn": "Dummy Secret Arn" + } + ] + }, + "Effect": "Allow" + } + ] + } + }, + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:DescribeSecret", + "secretsmanager:GetSecretValue", + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecretVersionStage" + ], + "Resource": { + "Fn::Sub": "arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:*" + }, + "Effect": "Allow", + "Condition": { + "StringEquals": { + "secretsmanager:resource/AllowRotationLambdaArn": { + "Fn::Sub": [ + "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${functionName}", + { + "functionName": "Dummy Function Name" + } + ] + } + } + } + }, + { + "Action": [ + "secretsmanager:GetRandomPassword" + ], + "Resource": "*", + "Effect": "Allow" + } + ] + } + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/output/function_with_conditional_policy_template_and_ref_no_value.json b/tests/translator/output/function_with_conditional_policy_template_and_ref_no_value.json new file mode 100644 index 0000000000..2d6b987c25 --- /dev/null +++ b/tests/translator/output/function_with_conditional_policy_template_and_ref_no_value.json @@ -0,0 +1,91 @@ +{ + "Conditions": { + "DummyCondition": { + "Fn::Equals": [ + "", + "" + ] + } + }, + "Resources": { + "FunctionWithConditionalPolicy": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "Description": "A function that has Fn::If in the policies property", + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithConditionalPolicyRole", + "Arn" + ] + }, + "Runtime": "python2.7" + } + }, + "FunctionWithConditionalPolicyRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Policies": [ + { + "Fn::If": [ + "DummyCondition", + { + "PolicyName": "FunctionWithConditionalPolicyRolePolicy0", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:GetSecretValue" + ], + "Resource": { + "Fn::Sub": [ + "${secretArn}", + { + "secretArn": "Dummy Secret Arn" + } + ] + }, + "Effect": "Allow" + } + ] + } + }, + { + "Ref": "AWS::NoValue" + } + ] + } + ], + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index fbc507b44f..532578da30 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -231,6 +231,10 @@ class TestTranslatorEndToEnd(TestCase): 'function_with_permissions_boundary', 'function_with_policy_templates', 'function_with_sns_event_source_all_parameters', + 'function_with_conditional_managed_policy', + 'function_with_conditional_managed_policy_and_ref_no_value', + 'function_with_conditional_policy_template', + 'function_with_conditional_policy_template_and_ref_no_value', 'global_handle_path_level_parameter', 'globals_for_function', 'globals_for_api', From e7d9ccf7a06865617607ef7c6ab03a7b0a066c36 Mon Sep 17 00:00:00 2001 From: Keeton Hodgson Date: Fri, 23 Aug 2019 19:36:22 -0700 Subject: [PATCH 31/31] fix: only remove extra stage when OpenApiVersion is set (#1093) --- samtranslator/model/api/api_generator.py | 9 ++++---- ..._with_openapi_definition_body_no_flag.json | 23 ++++++++++--------- ..._with_openapi_definition_body_no_flag.json | 23 ++++++++++--------- ..._with_openapi_definition_body_no_flag.json | 23 ++++++++++--------- 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py index 56bd2aa303..b9e02d538a 100644 --- a/samtranslator/model/api/api_generator.py +++ b/samtranslator/model/api/api_generator.py @@ -79,6 +79,7 @@ def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variab self.resource_attributes = resource_attributes self.passthrough_resource_attributes = passthrough_resource_attributes self.open_api_version = open_api_version + self.remove_extra_stage = open_api_version self.models = models def _construct_rest_api(self): @@ -158,7 +159,7 @@ def _construct_body_s3_dict(self): body_s3['Version'] = s3_pointer['Version'] return body_s3 - def _construct_deployment(self, rest_api, open_api_version): + def _construct_deployment(self, rest_api): """Constructs and returns the ApiGateway Deployment. :param model.apigateway.ApiGatewayRestApi rest_api: the RestApi for this Deployment @@ -168,7 +169,7 @@ def _construct_deployment(self, rest_api, open_api_version): deployment = ApiGatewayDeployment(self.logical_id + 'Deployment', attributes=self.passthrough_resource_attributes) deployment.RestApiId = rest_api.get_runtime_attr('rest_api_id') - if not self.open_api_version: + if not self.remove_extra_stage: deployment.StageName = 'Stage' return deployment @@ -199,7 +200,7 @@ def _construct_stage(self, deployment, swagger): stage.TracingEnabled = self.tracing_enabled if swagger is not None: - deployment.make_auto_deployable(stage, self.open_api_version, swagger) + deployment.make_auto_deployable(stage, self.remove_extra_stage, swagger) if self.tags is not None: stage.Tags = get_tag_list(self.tags) @@ -214,7 +215,7 @@ def to_cloudformation(self): """ rest_api = self._construct_rest_api() - deployment = self._construct_deployment(rest_api, self.open_api_version) + deployment = self._construct_deployment(rest_api) swagger = None if rest_api.Body is not None: diff --git a/tests/translator/output/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/api_with_openapi_definition_body_no_flag.json index 02ab6e4891..273a6e2d4a 100644 --- a/tests/translator/output/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/api_with_openapi_definition_body_no_flag.json @@ -47,6 +47,16 @@ } } }, + "ExplicitApiDeployment9252467a1e": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1", + "StageName": "Stage" + } + }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -68,15 +78,6 @@ } } }, - "ExplicitApiDeployment63a10e26af": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 63a10e26af7194aefd61ead891c470ed75ce20be" - } - }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -172,7 +173,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment63a10e26af" + "Ref": "ExplicitApiDeployment9252467a1e" } } }, @@ -272,4 +273,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json index 815e57e930..29180a0bcf 100644 --- a/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/aws-cn/api_with_openapi_definition_body_no_flag.json @@ -47,6 +47,16 @@ } } }, + "ExplicitApiDeployment9252467a1e": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1", + "StageName": "Stage" + } + }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -68,15 +78,6 @@ } } }, - "ExplicitApiDeployment63a10e26af": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 63a10e26af7194aefd61ead891c470ed75ce20be" - } - }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -180,7 +181,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment63a10e26af" + "Ref": "ExplicitApiDeployment9252467a1e" } } }, @@ -288,4 +289,4 @@ } } } -} \ No newline at end of file +} diff --git a/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json b/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json index f9513c92fe..976fac88b4 100644 --- a/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json +++ b/tests/translator/output/aws-us-gov/api_with_openapi_definition_body_no_flag.json @@ -47,6 +47,16 @@ } } }, + "ExplicitApiDeployment9252467a1e": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ExplicitApi" + }, + "Description": "RestApi deployment id: 9252467a1edc49ba35cb258640f5e3734cc9fab1", + "StageName": "Stage" + } + }, "ImplicitApiFunctionGetHtmlPermissionTest": { "Type": "AWS::Lambda::Permission", "Properties": { @@ -68,15 +78,6 @@ } } }, - "ExplicitApiDeployment63a10e26af": { - "Type": "AWS::ApiGateway::Deployment", - "Properties": { - "RestApiId": { - "Ref": "ExplicitApi" - }, - "Description": "RestApi deployment id: 63a10e26af7194aefd61ead891c470ed75ce20be" - } - }, "ExplicitApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { @@ -170,7 +171,7 @@ }, "CacheClusterEnabled": true, "DeploymentId": { - "Ref": "ExplicitApiDeployment63a10e26af" + "Ref": "ExplicitApiDeployment9252467a1e" } } }, @@ -288,4 +289,4 @@ } } } -} \ No newline at end of file +}