From 00b8a37bf2063d0276748692161b3b214bc58163 Mon Sep 17 00:00:00 2001 From: Connor Robertson Date: Tue, 5 Sep 2023 15:31:35 -0700 Subject: [PATCH] Adding InputTransformer Property (#3338) --- .../aws_serverless_statemachine.py | 1 + samtranslator/model/stepfunctions/events.py | 5 + samtranslator/schema/schema.json | 3 + schema_source/sam.schema.json | 3 + ...ventbridgerule_with_input_transformer.yaml | 45 +++++ ...ventbridgerule_with_input_transformer.json | 174 ++++++++++++++++++ ...ventbridgerule_with_input_transformer.json | 174 ++++++++++++++++++ ...ventbridgerule_with_input_transformer.json | 174 ++++++++++++++++++ 8 files changed, 579 insertions(+) create mode 100644 tests/translator/input/serverless_statemachine_eventbridgerule_with_input_transformer.yaml create mode 100644 tests/translator/output/aws-cn/serverless_statemachine_eventbridgerule_with_input_transformer.json create mode 100644 tests/translator/output/aws-us-gov/serverless_statemachine_eventbridgerule_with_input_transformer.json create mode 100644 tests/translator/output/serverless_statemachine_eventbridgerule_with_input_transformer.json diff --git a/samtranslator/internal/schema_source/aws_serverless_statemachine.py b/samtranslator/internal/schema_source/aws_serverless_statemachine.py index 31644e779..2d286243c 100644 --- a/samtranslator/internal/schema_source/aws_serverless_statemachine.py +++ b/samtranslator/internal/schema_source/aws_serverless_statemachine.py @@ -119,6 +119,7 @@ class EventBridgeRuleEventProperties(BaseModel): RetryPolicy: Optional[PassThroughProp] = eventbridgeruleeventproperties("RetryPolicy") Target: Optional[EventBridgeRuleTarget] = eventbridgeruleeventproperties("Target") RuleName: Optional[PassThroughProp] = eventbridgeruleeventproperties("RuleName") + InputTransformer: Optional[PassThroughProp] # TODO: add docs class EventBridgeRuleEvent(BaseModel): diff --git a/samtranslator/model/stepfunctions/events.py b/samtranslator/model/stepfunctions/events.py index 0d084e751..b8a248d3d 100644 --- a/samtranslator/model/stepfunctions/events.py +++ b/samtranslator/model/stepfunctions/events.py @@ -193,6 +193,7 @@ class CloudWatchEvent(EventSource): "RetryPolicy": PropertyType(False, IS_DICT), "State": PropertyType(False, IS_STR), "Target": Property(False, IS_DICT), + "InputTransformer": PropertyType(False, IS_DICT), } EventBusName: Optional[PassThrough] @@ -204,6 +205,7 @@ class CloudWatchEvent(EventSource): RetryPolicy: Optional[PassThrough] State: Optional[PassThrough] Target: Optional[PassThrough] + InputTransformer: Optional[PassThrough] @cw_timer(prefix=SFN_EVETSOURCE_METRIC_PREFIX) def to_cloudformation(self, resource, **kwargs): # type: ignore[no-untyped-def] @@ -273,6 +275,9 @@ def _construct_target(self, resource, role, dead_letter_queue_arn=None): # type if self.RetryPolicy is not None: target["RetryPolicy"] = self.RetryPolicy + if self.InputTransformer is not None: + target["InputTransformer"] = self.InputTransformer + return target diff --git a/samtranslator/schema/schema.json b/samtranslator/schema/schema.json index 954094fb8..ef896b6b5 100644 --- a/samtranslator/schema/schema.json +++ b/samtranslator/schema/schema.json @@ -254477,6 +254477,9 @@ "markdownDescription": "When you don't want to pass the entire matched event to the target, use the `InputPath` property to describe which part of the event to pass\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`InputPath`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-target.html#cfn-events-rule-target-inputpath) property of an `AWS::Events::Rule Target` resource\\.", "title": "InputPath" }, + "InputTransformer": { + "$ref": "#/definitions/PassThroughProp" + }, "Pattern": { "allOf": [ { diff --git a/schema_source/sam.schema.json b/schema_source/sam.schema.json index 9fa8244eb..3148fb567 100644 --- a/schema_source/sam.schema.json +++ b/schema_source/sam.schema.json @@ -7660,6 +7660,9 @@ "markdownDescription": "When you don't want to pass the entire matched event to the target, use the `InputPath` property to describe which part of the event to pass\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`InputPath`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-target.html#cfn-events-rule-target-inputpath) property of an `AWS::Events::Rule Target` resource\\.", "title": "InputPath" }, + "InputTransformer": { + "$ref": "#/definitions/PassThroughProp" + }, "Pattern": { "allOf": [ { diff --git a/tests/translator/input/serverless_statemachine_eventbridgerule_with_input_transformer.yaml b/tests/translator/input/serverless_statemachine_eventbridgerule_with_input_transformer.yaml new file mode 100644 index 000000000..5d079294e --- /dev/null +++ b/tests/translator/input/serverless_statemachine_eventbridgerule_with_input_transformer.yaml @@ -0,0 +1,45 @@ +Resources: + StateMachine: + Type: AWS::Serverless::StateMachine + Properties: + Name: !Sub ${AWS::StackName}-StateMachine + Definition: + Comment: A Hello World example of the Amazon States Language using Pass states + StartAt: Hello + States: + Hello: + Type: Pass + Result: Hello + Next: World + World: + Type: Pass + Result: World + End: true + Policies: + - Version: '2012-10-17' + Statement: + - Effect: Deny + Action: '*' + Resource: '*' + Events: + EventBridgeEvent: + Type: EventBridgeRule + Properties: + EventBusName: default + Pattern: + source: + - aws.s3 + detail-type: + - Object Created + detail: + bucket: + name: + - abc + object: + key: + - xyz + InputTransformer: + InputPathsMap: + bucket: $.detail.bucket.name + key: $.detail.object.key + InputTemplate: '{"bucket": , "key": }' diff --git a/tests/translator/output/aws-cn/serverless_statemachine_eventbridgerule_with_input_transformer.json b/tests/translator/output/aws-cn/serverless_statemachine_eventbridgerule_with_input_transformer.json new file mode 100644 index 000000000..d32ca6536 --- /dev/null +++ b/tests/translator/output/aws-cn/serverless_statemachine_eventbridgerule_with_input_transformer.json @@ -0,0 +1,174 @@ +{ + "Resources": { + "StateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRole", + "Arn" + ] + }, + "StateMachineName": { + "Fn::Sub": "${AWS::StackName}-StateMachine" + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "StateMachineEventBridgeEvent": { + "Properties": { + "EventBusName": "default", + "EventPattern": { + "detail": { + "bucket": { + "name": [ + "abc" + ] + }, + "object": { + "key": [ + "xyz" + ] + } + }, + "detail-type": [ + "Object Created" + ], + "source": [ + "aws.s3" + ] + }, + "Targets": [ + { + "Arn": { + "Ref": "StateMachine" + }, + "Id": "StateMachineEventBridgeEventStepFunctionsTarget", + "InputTransformer": { + "InputPathsMap": { + "bucket": "$.detail.bucket.name", + "key": "$.detail.object.key" + }, + "InputTemplate": "{\"bucket\": , \"key\": }" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineEventBridgeEventRole", + "Arn" + ] + } + } + ] + }, + "Type": "AWS::Events::Rule" + }, + "StateMachineEventBridgeEventRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "events.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "StateMachine" + } + } + ] + }, + "PolicyName": "StateMachineEventBridgeEventRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "StateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-us-gov/serverless_statemachine_eventbridgerule_with_input_transformer.json b/tests/translator/output/aws-us-gov/serverless_statemachine_eventbridgerule_with_input_transformer.json new file mode 100644 index 000000000..d32ca6536 --- /dev/null +++ b/tests/translator/output/aws-us-gov/serverless_statemachine_eventbridgerule_with_input_transformer.json @@ -0,0 +1,174 @@ +{ + "Resources": { + "StateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRole", + "Arn" + ] + }, + "StateMachineName": { + "Fn::Sub": "${AWS::StackName}-StateMachine" + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "StateMachineEventBridgeEvent": { + "Properties": { + "EventBusName": "default", + "EventPattern": { + "detail": { + "bucket": { + "name": [ + "abc" + ] + }, + "object": { + "key": [ + "xyz" + ] + } + }, + "detail-type": [ + "Object Created" + ], + "source": [ + "aws.s3" + ] + }, + "Targets": [ + { + "Arn": { + "Ref": "StateMachine" + }, + "Id": "StateMachineEventBridgeEventStepFunctionsTarget", + "InputTransformer": { + "InputPathsMap": { + "bucket": "$.detail.bucket.name", + "key": "$.detail.object.key" + }, + "InputTemplate": "{\"bucket\": , \"key\": }" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineEventBridgeEventRole", + "Arn" + ] + } + } + ] + }, + "Type": "AWS::Events::Rule" + }, + "StateMachineEventBridgeEventRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "events.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "StateMachine" + } + } + ] + }, + "PolicyName": "StateMachineEventBridgeEventRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "StateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/serverless_statemachine_eventbridgerule_with_input_transformer.json b/tests/translator/output/serverless_statemachine_eventbridgerule_with_input_transformer.json new file mode 100644 index 000000000..d32ca6536 --- /dev/null +++ b/tests/translator/output/serverless_statemachine_eventbridgerule_with_input_transformer.json @@ -0,0 +1,174 @@ +{ + "Resources": { + "StateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRole", + "Arn" + ] + }, + "StateMachineName": { + "Fn::Sub": "${AWS::StackName}-StateMachine" + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "StateMachineEventBridgeEvent": { + "Properties": { + "EventBusName": "default", + "EventPattern": { + "detail": { + "bucket": { + "name": [ + "abc" + ] + }, + "object": { + "key": [ + "xyz" + ] + } + }, + "detail-type": [ + "Object Created" + ], + "source": [ + "aws.s3" + ] + }, + "Targets": [ + { + "Arn": { + "Ref": "StateMachine" + }, + "Id": "StateMachineEventBridgeEventStepFunctionsTarget", + "InputTransformer": { + "InputPathsMap": { + "bucket": "$.detail.bucket.name", + "key": "$.detail.object.key" + }, + "InputTemplate": "{\"bucket\": , \"key\": }" + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineEventBridgeEventRole", + "Arn" + ] + } + } + ] + }, + "Type": "AWS::Events::Rule" + }, + "StateMachineEventBridgeEventRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "events.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "StateMachine" + } + } + ] + }, + "PolicyName": "StateMachineEventBridgeEventRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "StateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +}