diff --git a/docs/cloudformation_compatibility.rst b/docs/cloudformation_compatibility.rst index 9118c3395..a89430e70 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 14217806f..20c2736a9 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 8fa499b9e..b6675be79 100644 --- a/samtranslator/validator/sam_schema/schema.json +++ b/samtranslator/validator/sam_schema/schema.json @@ -649,7 +649,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 000000000..72a612034 --- /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 e7b0bd8f3..64003f557 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 000000000..c947e4bc2 --- /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 cec52175a..75979c84b 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 000000000..3913b5c72 --- /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 afe566a03..53b58bb37 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 000000000..5737fa5e6 --- /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 89402cfbf..623c7f48b 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 9493abade..6c42646b5 100644 --- a/versions/2016-10-31.md +++ b/versions/2016-10-31.md @@ -548,6 +548,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 @@ -555,6 +558,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