From 6e60731164fbaa3e0df841d84b416b67f97da960 Mon Sep 17 00:00:00 2001 From: Aayush Thapa Date: Wed, 22 Feb 2023 13:46:41 -0800 Subject: [PATCH 1/7] SESBulkTemplatedCrudPolicy_v2 policy --- .../policy_templates.json | 48 +++++++++++++++++++ .../policy_templates_data/schema.json | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/samtranslator/policy_templates_data/policy_templates.json b/samtranslator/policy_templates_data/policy_templates.json index 3299c1edd..dda455950 100644 --- a/samtranslator/policy_templates_data/policy_templates.json +++ b/samtranslator/policy_templates_data/policy_templates.json @@ -1920,6 +1920,54 @@ } } }, + "SESBulkTemplatedCrudPolicy_v2": { + "Definition": { + "Statement": [ + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:SendEmail", + "ses:SendRawEmail", + "ses:SendTemplatedEmail", + "ses:SendBulkTemplatedEmail", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:identity/${identityName}", + { + "identityName": { + "Ref": "IdentityName" + } + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:template/${templateName}", + { + "templateName": { + "Ref": "TemplateName" + } + } + ] + } + ] + } + ] + }, + "Description": "Gives permission to send email, templated email, templated bulk emails and verify identity", + "Parameters": { + "IdentityName": { + "Description": "Identity to give permissions to" + }, + "TemplateName": { + "Description": "Template of the email" + } + } + }, "SESCrudPolicy": { "Definition": { "Statement": [ diff --git a/samtranslator/policy_templates_data/schema.json b/samtranslator/policy_templates_data/schema.json index aec9f99f1..1bae71add 100644 --- a/samtranslator/policy_templates_data/schema.json +++ b/samtranslator/policy_templates_data/schema.json @@ -69,7 +69,7 @@ "Templates": { "additionalProperties": false, "patternProperties": { - "^[a-zA-Z0-9]+Policy$": { + "^[a-zA-Z0-9]+Policy(_v[0-9])?$": { "$ref": "#/definitions/template" } }, From 7b3ce4e9fe589ff7a52413733879c692a3c0aee8 Mon Sep 17 00:00:00 2001 From: Aayush Thapa Date: Wed, 22 Feb 2023 13:47:10 -0800 Subject: [PATCH 2/7] tests --- .../input/all_policy_templates.yaml | 4 +++ .../output/all_policy_templates.json | 36 +++++++++++++++++++ .../output/aws-cn/all_policy_templates.json | 36 +++++++++++++++++++ .../aws-us-gov/all_policy_templates.json | 36 +++++++++++++++++++ 4 files changed, 112 insertions(+) diff --git a/tests/translator/input/all_policy_templates.yaml b/tests/translator/input/all_policy_templates.yaml index ca3fb207a..ac4f3bf34 100644 --- a/tests/translator/input/all_policy_templates.yaml +++ b/tests/translator/input/all_policy_templates.yaml @@ -177,3 +177,7 @@ Resources: - SSMParameterWithSlashPrefixReadPolicy: ParameterName: /name + + - SESBulkTemplatedCrudPolicy_v2: + IdentityName: name + TemplateName: template_name diff --git a/tests/translator/output/all_policy_templates.json b/tests/translator/output/all_policy_templates.json index 6439f3842..7fe9e1121 100644 --- a/tests/translator/output/all_policy_templates.json +++ b/tests/translator/output/all_policy_templates.json @@ -1639,6 +1639,42 @@ ] }, "PolicyName": "KitchenSinkFunctionRolePolicy60" + }, + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:SendEmail", + "ses:SendRawEmail", + "ses:SendTemplatedEmail", + "ses:SendBulkTemplatedEmail", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:identity/${identityName}", + { + "identityName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:template/${templateName}", + { + "templateName": "template_name" + } + ] + } + ] + } + ] + }, + "PolicyName": "KitchenSinkFunctionRolePolicy61" } ], "Tags": [ diff --git a/tests/translator/output/aws-cn/all_policy_templates.json b/tests/translator/output/aws-cn/all_policy_templates.json index 17f350672..f6be05c50 100644 --- a/tests/translator/output/aws-cn/all_policy_templates.json +++ b/tests/translator/output/aws-cn/all_policy_templates.json @@ -1639,6 +1639,42 @@ ] }, "PolicyName": "KitchenSinkFunctionRolePolicy60" + }, + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:SendEmail", + "ses:SendRawEmail", + "ses:SendTemplatedEmail", + "ses:SendBulkTemplatedEmail", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:identity/${identityName}", + { + "identityName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:template/${templateName}", + { + "templateName": "template_name" + } + ] + } + ] + } + ] + }, + "PolicyName": "KitchenSinkFunctionRolePolicy61" } ], "Tags": [ 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 481d9bf3b..9e5a37e28 100644 --- a/tests/translator/output/aws-us-gov/all_policy_templates.json +++ b/tests/translator/output/aws-us-gov/all_policy_templates.json @@ -1639,6 +1639,42 @@ ] }, "PolicyName": "KitchenSinkFunctionRolePolicy60" + }, + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:SendEmail", + "ses:SendRawEmail", + "ses:SendTemplatedEmail", + "ses:SendBulkTemplatedEmail", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:identity/${identityName}", + { + "identityName": "name" + } + ] + }, + { + "Fn::Sub": [ + "arn:${AWS::Partition}:ses:${AWS::Region}:${AWS::AccountId}:template/${templateName}", + { + "templateName": "template_name" + } + ] + } + ] + } + ] + }, + "PolicyName": "KitchenSinkFunctionRolePolicy61" } ], "Tags": [ From 8f22dc2df3ff512199c0e924510b49e59a06972b Mon Sep 17 00:00:00 2001 From: Aayush Thapa Date: Wed, 22 Feb 2023 13:56:28 -0800 Subject: [PATCH 3/7] description --- samtranslator/policy_templates_data/policy_templates.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samtranslator/policy_templates_data/policy_templates.json b/samtranslator/policy_templates_data/policy_templates.json index dda455950..87c4691ee 100644 --- a/samtranslator/policy_templates_data/policy_templates.json +++ b/samtranslator/policy_templates_data/policy_templates.json @@ -1964,7 +1964,7 @@ "Description": "Identity to give permissions to" }, "TemplateName": { - "Description": "Template of the email" + "Description": "Name of the email template" } } }, From 1cbd96dbc7e69aa1d5b2af9f91dbfb7bddfa8507 Mon Sep 17 00:00:00 2001 From: Aayush Thapa Date: Thu, 23 Feb 2023 11:33:52 -0800 Subject: [PATCH 4/7] update statement --- .../policy_templates_data/policy_templates.json | 12 +++++++++--- tests/translator/output/all_policy_templates.json | 12 +++++++++--- .../output/aws-cn/all_policy_templates.json | 12 +++++++++--- .../output/aws-us-gov/all_policy_templates.json | 12 +++++++++--- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/samtranslator/policy_templates_data/policy_templates.json b/samtranslator/policy_templates_data/policy_templates.json index 87c4691ee..097566001 100644 --- a/samtranslator/policy_templates_data/policy_templates.json +++ b/samtranslator/policy_templates_data/policy_templates.json @@ -1925,12 +1925,10 @@ "Statement": [ { "Action": [ - "ses:GetIdentityVerificationAttributes", "ses:SendEmail", "ses:SendRawEmail", "ses:SendTemplatedEmail", - "ses:SendBulkTemplatedEmail", - "ses:VerifyEmailIdentity" + "ses:SendBulkTemplatedEmail" ], "Effect": "Allow", "Resource": [ @@ -1955,6 +1953,14 @@ ] } ] + }, + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": "*" } ] }, diff --git a/tests/translator/output/all_policy_templates.json b/tests/translator/output/all_policy_templates.json index 7fe9e1121..bfa0e4e08 100644 --- a/tests/translator/output/all_policy_templates.json +++ b/tests/translator/output/all_policy_templates.json @@ -1645,12 +1645,10 @@ "Statement": [ { "Action": [ - "ses:GetIdentityVerificationAttributes", "ses:SendEmail", "ses:SendRawEmail", "ses:SendTemplatedEmail", - "ses:SendBulkTemplatedEmail", - "ses:VerifyEmailIdentity" + "ses:SendBulkTemplatedEmail" ], "Effect": "Allow", "Resource": [ @@ -1671,6 +1669,14 @@ ] } ] + }, + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": "*" } ] }, diff --git a/tests/translator/output/aws-cn/all_policy_templates.json b/tests/translator/output/aws-cn/all_policy_templates.json index f6be05c50..9796cd090 100644 --- a/tests/translator/output/aws-cn/all_policy_templates.json +++ b/tests/translator/output/aws-cn/all_policy_templates.json @@ -1645,12 +1645,10 @@ "Statement": [ { "Action": [ - "ses:GetIdentityVerificationAttributes", "ses:SendEmail", "ses:SendRawEmail", "ses:SendTemplatedEmail", - "ses:SendBulkTemplatedEmail", - "ses:VerifyEmailIdentity" + "ses:SendBulkTemplatedEmail" ], "Effect": "Allow", "Resource": [ @@ -1671,6 +1669,14 @@ ] } ] + }, + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": "*" } ] }, 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 9e5a37e28..2e87ab0a4 100644 --- a/tests/translator/output/aws-us-gov/all_policy_templates.json +++ b/tests/translator/output/aws-us-gov/all_policy_templates.json @@ -1645,12 +1645,10 @@ "Statement": [ { "Action": [ - "ses:GetIdentityVerificationAttributes", "ses:SendEmail", "ses:SendRawEmail", "ses:SendTemplatedEmail", - "ses:SendBulkTemplatedEmail", - "ses:VerifyEmailIdentity" + "ses:SendBulkTemplatedEmail" ], "Effect": "Allow", "Resource": [ @@ -1671,6 +1669,14 @@ ] } ] + }, + { + "Action": [ + "ses:GetIdentityVerificationAttributes", + "ses:VerifyEmailIdentity" + ], + "Effect": "Allow", + "Resource": "*" } ] }, From ddd61cb162b2e32780601369117301af3d3d7b77 Mon Sep 17 00:00:00 2001 From: Aayush Thapa Date: Thu, 2 Mar 2023 09:29:51 -0800 Subject: [PATCH 5/7] format changes --- tests/translator/input/all_policy_templates.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/translator/input/all_policy_templates.yaml b/tests/translator/input/all_policy_templates.yaml index dde2f69cc..e39ffd4e9 100644 --- a/tests/translator/input/all_policy_templates.yaml +++ b/tests/translator/input/all_policy_templates.yaml @@ -177,10 +177,10 @@ Resources: - SSMParameterWithSlashPrefixReadPolicy: ParameterName: /name - + - StepFunctionsExecutionPolicy_v2: StateMachineName: name - + - SESBulkTemplatedCrudPolicy_v2: IdentityName: name - TemplateName: template_name \ No newline at end of file + TemplateName: template_name From acfb6d2e88d6c6eb1d26ad93c705484a20e1491e Mon Sep 17 00:00:00 2001 From: Aayush Thapa Date: Mon, 13 Mar 2023 12:15:40 -0700 Subject: [PATCH 6/7] dip fix --- samtranslator/translator/translator.py | 44 +++++++++---------- .../input/error_embedded_connectors.yaml | 8 ++++ .../output/error_embedded_connectors.json | 6 ++- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/samtranslator/translator/translator.py b/samtranslator/translator/translator.py index 5d96f0d34..dac9243af 100644 --- a/samtranslator/translator/translator.py +++ b/samtranslator/translator/translator.py @@ -326,31 +326,31 @@ def _get_embedded_connectors(self, resources: Dict[str, Any]) -> List[Resource]: ).to_be_a_map() except InvalidResourceException as e: self.document_errors.append(e) - - for connector_logical_id, connector_dict in resource["Connectors"].items(): - try: - full_connector_logical_id = source_logical_id + connector_logical_id - # can't use sam_expect since this is neither a property nor a resource attribute - if not isinstance(connector_dict, dict): - raise InvalidResourceException( + else: + for connector_logical_id, connector_dict in resource["Connectors"].items(): + try: + full_connector_logical_id = source_logical_id + connector_logical_id + # can't use sam_expect since this is neither a property nor a resource attribute + if not isinstance(connector_dict, dict): + raise InvalidResourceException( + full_connector_logical_id, + f"{source_logical_id}.{full_connector_logical_id} should be a map.", + ) + + generated_connector = self._get_generated_connector( + source_logical_id, full_connector_logical_id, - f"{source_logical_id}.{full_connector_logical_id} should be a map.", + connector_logical_id, + connector_dict, ) - generated_connector = self._get_generated_connector( - source_logical_id, - full_connector_logical_id, - connector_logical_id, - connector_dict, - ) - - if not verify_unique_logical_id(generated_connector, resources): - raise DuplicateLogicalIdException( - source_logical_id, full_connector_logical_id, generated_connector.resource_type - ) - connectors.append(generated_connector) - except (InvalidResourceException, DuplicateLogicalIdException) as e: - self.document_errors.append(e) + if not verify_unique_logical_id(generated_connector, resources): + raise DuplicateLogicalIdException( + source_logical_id, full_connector_logical_id, generated_connector.resource_type + ) + connectors.append(generated_connector) + except (InvalidResourceException, DuplicateLogicalIdException) as e: + self.document_errors.append(e) return connectors diff --git a/tests/translator/input/error_embedded_connectors.yaml b/tests/translator/input/error_embedded_connectors.yaml index b110130a7..9582d4897 100644 --- a/tests/translator/input/error_embedded_connectors.yaml +++ b/tests/translator/input/error_embedded_connectors.yaml @@ -181,3 +181,11 @@ Resources: Runtime: python3.9 InlineCode: foo Handler: foo + + NoneTypeConnector: + Connectors: + Type: AWS::Serverless::Function + Properties: + Runtime: python3.9 + InlineCode: foo + Handler: foo diff --git a/tests/translator/output/error_embedded_connectors.json b/tests/translator/output/error_embedded_connectors.json index 397e469e9..bcf69c392 100644 --- a/tests/translator/output/error_embedded_connectors.json +++ b/tests/translator/output/error_embedded_connectors.json @@ -1,7 +1,7 @@ { "_autoGeneratedBreakdownErrorMessage": [ "Invalid Serverless Application Specification document. ", - "Number of errors found: 24. ", + "Number of errors found: 25. ", "Transforming resource with id [DuplicateTest] attempts to create a new resource with id [DuplicateTestDuplicateId] and type \"AWS::Serverless::Connector\". ", "A resource with that id already exists within this template. ", "Please use a different id for that resource. ", @@ -49,8 +49,10 @@ "Unsupported 'Permissions' provided for connector from AWS::SQS::Queue to AWS::Lambda::Function; valid combinations are: Read + Write. ", "Resource with id [MyResourceWithoutTypeResourceWithoutType] is invalid. ", "'Type' is missing or not a string. ", + "Resource with id [NoneTypeConnector] is invalid. ", + "Attribute 'NoneTypeConnector.Connectors' should be a map. ", "Resource with id [TestSourceReferenceId] is invalid. ", "'Id' shouldn't be defined in 'SourceReference'." ], - "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 24. Transforming resource with id [DuplicateTest] attempts to create a new resource with id [DuplicateTestDuplicateId] and type \"AWS::Serverless::Connector\". A resource with that id already exists within this template. Please use a different id for that resource. Resource with id [EventsRuleMissingLambdaFunctionArn] is invalid. Unable to get Lambda function ARN from 'Destination' resource. Resource with id [EventsRuleMissingSnsTopicArn] is invalid. Destination.Arn is missing. Resource with id [EventsRuleMissingSqsQueueUrl] is invalid. Unable to create connector from AWS::Events::Rule to AWS::SQS:Queue; it's not supported or the template is invalid. Resource with id [MyFunction] is invalid. Attribute 'Connectors.NoProperties.Properties' should be a map. Resource with id [MyFunction] is invalid. Attribute 'Connectors.NonDictProperties.Properties' should be a map. Resource with id [MyFunction] is invalid. Attribute 'Connectors.EmptyProperties.Properties' should be a map. Resource with id [MyFunction] is invalid. Property 'Connectors.NonDictSourceReference.Properties.SourceReference' should be a map. Resource with id [MyFunctionBothIdAndOtherProps] is invalid. Must provide 'Id' (with optional 'Qualifier') or a supported combination of other properties. Resource with id [MyFunctionEmptyDestination] is invalid. Missing required property 'Destination'. Resource with id [MyFunctionEmptyPermissions] is invalid. Missing required property 'Permissions'. Resource with id [MyFunctionEmptyPermissionsList] is invalid. 'Permissions' cannot be empty; valid values are: Read, Write. Resource with id [MyFunctionMissingRoleMissingRole] is invalid. Unable to get IAM role name from 'Source' resource. Resource with id [MyFunctionNoDestination] is invalid. Missing required property 'Destination'. Resource with id [MyFunctionNoDictConnectorNonDictConnector] is invalid. MyFunctionNoDictConnector.MyFunctionNoDictConnectorNonDictConnector should be a map. Resource with id [MyFunctionNoIdMissingType] is invalid. 'Type' is missing or not a string. Resource with id [MyFunctionNoPermissions] is invalid. Missing required property 'Permissions'. Resource with id [MyFunctionNoStrId] is invalid. 'Id' is missing or not a string. Resource with id [MyFunctionNonExistentId] is invalid. Unable to find resource with logical ID 'ThisDoesntExist'. Resource with id [MyFunctionUnsupportedAccessCategory] is invalid. Unsupported 'Permissions' provided for connector from AWS::Lambda::Function to AWS::SQS::Queue; valid values are: Read, Write. Resource with id [MyQueueMissingRoleDestination] is invalid. Unable to get IAM role name from 'Destination' resource. Resource with id [MyQueueUnsupportedAccessCategoryCombination] is invalid. Unsupported 'Permissions' provided for connector from AWS::SQS::Queue to AWS::Lambda::Function; valid combinations are: Read + Write. Resource with id [MyResourceWithoutTypeResourceWithoutType] is invalid. 'Type' is missing or not a string. Resource with id [TestSourceReferenceId] is invalid. 'Id' shouldn't be defined in 'SourceReference'." + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 25. Transforming resource with id [DuplicateTest] attempts to create a new resource with id [DuplicateTestDuplicateId] and type \"AWS::Serverless::Connector\". A resource with that id already exists within this template. Please use a different id for that resource. Resource with id [EventsRuleMissingLambdaFunctionArn] is invalid. Unable to get Lambda function ARN from 'Destination' resource. Resource with id [EventsRuleMissingSnsTopicArn] is invalid. Destination.Arn is missing. Resource with id [EventsRuleMissingSqsQueueUrl] is invalid. Unable to create connector from AWS::Events::Rule to AWS::SQS:Queue; it's not supported or the template is invalid. Resource with id [MyFunction] is invalid. Attribute 'Connectors.NoProperties.Properties' should be a map. Resource with id [MyFunction] is invalid. Attribute 'Connectors.NonDictProperties.Properties' should be a map. Resource with id [MyFunction] is invalid. Attribute 'Connectors.EmptyProperties.Properties' should be a map. Resource with id [MyFunction] is invalid. Property 'Connectors.NonDictSourceReference.Properties.SourceReference' should be a map. Resource with id [MyFunctionBothIdAndOtherProps] is invalid. Must provide 'Id' (with optional 'Qualifier') or a supported combination of other properties. Resource with id [MyFunctionEmptyDestination] is invalid. Missing required property 'Destination'. Resource with id [MyFunctionEmptyPermissions] is invalid. Missing required property 'Permissions'. Resource with id [MyFunctionEmptyPermissionsList] is invalid. 'Permissions' cannot be empty; valid values are: Read, Write. Resource with id [MyFunctionMissingRoleMissingRole] is invalid. Unable to get IAM role name from 'Source' resource. Resource with id [MyFunctionNoDestination] is invalid. Missing required property 'Destination'. Resource with id [MyFunctionNoDictConnectorNonDictConnector] is invalid. MyFunctionNoDictConnector.MyFunctionNoDictConnectorNonDictConnector should be a map. Resource with id [MyFunctionNoIdMissingType] is invalid. 'Type' is missing or not a string. Resource with id [MyFunctionNoPermissions] is invalid. Missing required property 'Permissions'. Resource with id [MyFunctionNoStrId] is invalid. 'Id' is missing or not a string. Resource with id [MyFunctionNonExistentId] is invalid. Unable to find resource with logical ID 'ThisDoesntExist'. Resource with id [MyFunctionUnsupportedAccessCategory] is invalid. Unsupported 'Permissions' provided for connector from AWS::Lambda::Function to AWS::SQS::Queue; valid values are: Read, Write. Resource with id [MyQueueMissingRoleDestination] is invalid. Unable to get IAM role name from 'Destination' resource. Resource with id [MyQueueUnsupportedAccessCategoryCombination] is invalid. Unsupported 'Permissions' provided for connector from AWS::SQS::Queue to AWS::Lambda::Function; valid combinations are: Read + Write. Resource with id [MyResourceWithoutTypeResourceWithoutType] is invalid. 'Type' is missing or not a string. Resource with id [NoneTypeConnector] is invalid. Attribute 'NoneTypeConnector.Connectors' should be a map. Resource with id [TestSourceReferenceId] is invalid. 'Id' shouldn't be defined in 'SourceReference'." } From 1d0498b651f1c37cb296c88b4c6bb3019365c142 Mon Sep 17 00:00:00 2001 From: Aayush Thapa Date: Mon, 13 Mar 2023 14:24:29 -0700 Subject: [PATCH 7/7] use continue instead --- samtranslator/translator/translator.py | 44 +++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/samtranslator/translator/translator.py b/samtranslator/translator/translator.py index dac9243af..05a1d6fb5 100644 --- a/samtranslator/translator/translator.py +++ b/samtranslator/translator/translator.py @@ -326,31 +326,31 @@ def _get_embedded_connectors(self, resources: Dict[str, Any]) -> List[Resource]: ).to_be_a_map() except InvalidResourceException as e: self.document_errors.append(e) - else: - for connector_logical_id, connector_dict in resource["Connectors"].items(): - try: - full_connector_logical_id = source_logical_id + connector_logical_id - # can't use sam_expect since this is neither a property nor a resource attribute - if not isinstance(connector_dict, dict): - raise InvalidResourceException( - full_connector_logical_id, - f"{source_logical_id}.{full_connector_logical_id} should be a map.", - ) - - generated_connector = self._get_generated_connector( - source_logical_id, + continue + for connector_logical_id, connector_dict in resource["Connectors"].items(): + try: + full_connector_logical_id = source_logical_id + connector_logical_id + # can't use sam_expect since this is neither a property nor a resource attribute + if not isinstance(connector_dict, dict): + raise InvalidResourceException( full_connector_logical_id, - connector_logical_id, - connector_dict, + f"{source_logical_id}.{full_connector_logical_id} should be a map.", ) - if not verify_unique_logical_id(generated_connector, resources): - raise DuplicateLogicalIdException( - source_logical_id, full_connector_logical_id, generated_connector.resource_type - ) - connectors.append(generated_connector) - except (InvalidResourceException, DuplicateLogicalIdException) as e: - self.document_errors.append(e) + generated_connector = self._get_generated_connector( + source_logical_id, + full_connector_logical_id, + connector_logical_id, + connector_dict, + ) + + if not verify_unique_logical_id(generated_connector, resources): + raise DuplicateLogicalIdException( + source_logical_id, full_connector_logical_id, generated_connector.resource_type + ) + connectors.append(generated_connector) + except (InvalidResourceException, DuplicateLogicalIdException) as e: + self.document_errors.append(e) return connectors