Skip to content

Commit b2fd0e7

Browse files
lightpriestjfuss
andauthored
feat: Add State Property to Schedule EventSource (#1666)
Co-authored-by: Or Cohen <[email protected]> Co-authored-by: Jacob Fuss <[email protected]>
1 parent 747cf34 commit b2fd0e7

8 files changed

+636
-1
lines changed

samtranslator/model/eventsources/push.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class Schedule(PushEventSource):
9696
"Schedule": PropertyType(True, is_str()),
9797
"Input": PropertyType(False, is_str()),
9898
"Enabled": PropertyType(False, is_type(bool)),
99+
"State": PropertyType(False, is_str()),
99100
"Name": PropertyType(False, is_str()),
100101
"Description": PropertyType(False, is_str()),
101102
"DeadLetterConfig": PropertyType(False, is_type(dict)),
@@ -122,8 +123,16 @@ def to_cloudformation(self, **kwargs):
122123
resources.append(events_rule)
123124

124125
events_rule.ScheduleExpression = self.Schedule
126+
127+
if self.State and self.Enabled is not None:
128+
raise InvalidEventException(self.relative_id, "State and Enabled Properties cannot both be specified.")
129+
130+
if self.State:
131+
events_rule.State = self.State
132+
125133
if self.Enabled is not None:
126134
events_rule.State = "ENABLED" if self.Enabled else "DISABLED"
135+
127136
events_rule.Name = self.Name
128137
events_rule.Description = self.Description
129138

tests/model/eventsources/test_schedule_event_source.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from unittest.mock import Mock, patch
21
from unittest import TestCase
32

43
from samtranslator.model.eventsources.push import Schedule
54
from samtranslator.model.lambda_ import LambdaFunction
65
from samtranslator.model.exceptions import InvalidEventException
6+
from parameterized import parameterized
77

88

99
class ScheduleEventSource(TestCase):
@@ -13,6 +13,27 @@ def setUp(self):
1313
self.schedule_event_source.Schedule = "rate(1 minute)"
1414
self.func = LambdaFunction("func")
1515

16+
def test_to_cloudformation_returns_permission_and_schedule_resources(self):
17+
resources = self.schedule_event_source.to_cloudformation(function=self.func)
18+
self.assertEqual(len(resources), 2)
19+
self.assertEqual(resources[0].resource_type, "AWS::Events::Rule")
20+
self.assertEqual(resources[1].resource_type, "AWS::Lambda::Permission")
21+
22+
schedule = resources[0]
23+
self.assertEqual(schedule.ScheduleExpression, "rate(1 minute)")
24+
self.assertIsNone(schedule.State)
25+
26+
def test_to_cloudformation_transforms_enabled_boolean_to_state(self):
27+
self.schedule_event_source.Enabled = True
28+
resources = self.schedule_event_source.to_cloudformation(function=self.func)
29+
schedule = resources[0]
30+
self.assertEqual(schedule.State, "ENABLED")
31+
32+
self.schedule_event_source.Enabled = False
33+
resources = self.schedule_event_source.to_cloudformation(function=self.func)
34+
schedule = resources[0]
35+
self.assertEqual(schedule.State, "DISABLED")
36+
1637
def test_to_cloudformation_with_retry_policy(self):
1738
retry_policy = {"MaximumRetryAttempts": "10", "MaximumEventAgeInSeconds": "300"}
1839
self.schedule_event_source.RetryPolicy = retry_policy
@@ -70,3 +91,19 @@ def test_to_cloudformation_with_dlq_generated_with_intrinsic_function_custom_log
7091
self.schedule_event_source.DeadLetterConfig = dead_letter_config
7192
with self.assertRaises(InvalidEventException):
7293
self.schedule_event_source.to_cloudformation(function=self.func)
94+
95+
@parameterized.expand(
96+
[
97+
(True, "Enabled"),
98+
(True, "Disabled"),
99+
(True, {"FN:FakeIntrinsic": "something"}),
100+
(False, "Enabled"),
101+
(False, "Disabled"),
102+
(False, {"FN:FakeIntrinsic": "something"}),
103+
]
104+
)
105+
def test_to_cloudformation_invalid_defined_both_enabled_and_state_provided(self, enabled_value, state_value):
106+
self.schedule_event_source.Enabled = enabled_value
107+
self.schedule_event_source.State = state_value
108+
with self.assertRaises(InvalidEventException):
109+
self.schedule_event_source.to_cloudformation(function=self.func)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Transform: "AWS::Serverless-2016-10-31"
2+
3+
Resources:
4+
ScheduledFunction:
5+
Type: 'AWS::Serverless::Function'
6+
Properties:
7+
CodeUri: s3://sam-demo-bucket/hello.zip?versionId=3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO
8+
Handler: hello.handler
9+
Runtime: python3.10
10+
Events:
11+
Schedule1:
12+
Type: Schedule
13+
Properties:
14+
Schedule: 'rate(1 minute)'
15+
Name: test-schedule
16+
Description: Test Schedule
17+
State: "Enabled"
18+
Enabled: True
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Transform: "AWS::Serverless-2016-10-31"
2+
Parameters:
3+
ScheduleState:
4+
Type: String
5+
Default: Disabled
6+
7+
Resources:
8+
ScheduledFunction:
9+
Type: 'AWS::Serverless::Function'
10+
Properties:
11+
CodeUri: s3://sam-demo-bucket/hello.zip?versionId=3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO
12+
Handler: hello.handler
13+
Runtime: python3.10
14+
Events:
15+
Schedule1:
16+
Type: Schedule
17+
Properties:
18+
Schedule: 'rate(1 minute)'
19+
Name: test-schedule
20+
Description: Test Schedule
21+
State: "Enabled"
22+
Schedule2:
23+
Type: Schedule
24+
Properties:
25+
Schedule: 'rate(1 minute)'
26+
Name: test-schedule
27+
Description: Test Schedule
28+
State: !Sub "Enabled"
29+
Schedule3:
30+
Type: Schedule
31+
Properties:
32+
Schedule: 'rate(1 minute)'
33+
Name: test-schedule
34+
Description: Test Schedule
35+
State: !Ref ScheduleState
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
{
2+
"Parameters": {
3+
"ScheduleState": {
4+
"Type": "String",
5+
"Default": "Disabled"
6+
}
7+
},
8+
"Resources": {
9+
"ScheduledFunction": {
10+
"Type": "AWS::Lambda::Function",
11+
"Properties": {
12+
"Code": {
13+
"S3Bucket": "sam-demo-bucket",
14+
"S3Key": "hello.zip",
15+
"S3ObjectVersion": "3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO"
16+
},
17+
"Handler": "hello.handler",
18+
"Role": {
19+
"Fn::GetAtt": [
20+
"ScheduledFunctionRole",
21+
"Arn"
22+
]
23+
},
24+
"Runtime": "python3.10",
25+
"Tags": [
26+
{
27+
"Key": "lambda:createdBy",
28+
"Value": "SAM"
29+
}
30+
]
31+
}
32+
},
33+
"ScheduledFunctionRole": {
34+
"Type": "AWS::IAM::Role",
35+
"Properties": {
36+
"AssumeRolePolicyDocument": {
37+
"Version": "2012-10-17",
38+
"Statement": [
39+
{
40+
"Action": [
41+
"sts:AssumeRole"
42+
],
43+
"Effect": "Allow",
44+
"Principal": {
45+
"Service": [
46+
"lambda.amazonaws.com"
47+
]
48+
}
49+
}
50+
]
51+
},
52+
"ManagedPolicyArns": [
53+
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
54+
],
55+
"Tags": [
56+
{
57+
"Key": "lambda:createdBy",
58+
"Value": "SAM"
59+
}
60+
]
61+
}
62+
},
63+
"ScheduledFunctionSchedule1": {
64+
"Type": "AWS::Events::Rule",
65+
"Properties": {
66+
"Description": "Test Schedule",
67+
"Name": "test-schedule",
68+
"ScheduleExpression": "rate(1 minute)",
69+
"State": "Enabled",
70+
"Targets": [
71+
{
72+
"Arn": {
73+
"Fn::GetAtt": [
74+
"ScheduledFunction",
75+
"Arn"
76+
]
77+
},
78+
"Id": "ScheduledFunctionSchedule1LambdaTarget"
79+
}
80+
]
81+
}
82+
},
83+
"ScheduledFunctionSchedule1Permission": {
84+
"Type": "AWS::Lambda::Permission",
85+
"Properties": {
86+
"Action": "lambda:InvokeFunction",
87+
"FunctionName": {
88+
"Ref": "ScheduledFunction"
89+
},
90+
"Principal": "events.amazonaws.com",
91+
"SourceArn": {
92+
"Fn::GetAtt": [
93+
"ScheduledFunctionSchedule1",
94+
"Arn"
95+
]
96+
}
97+
}
98+
},
99+
"ScheduledFunctionSchedule2": {
100+
"Type": "AWS::Events::Rule",
101+
"Properties": {
102+
"Description": "Test Schedule",
103+
"Name": "test-schedule",
104+
"ScheduleExpression": "rate(1 minute)",
105+
"State": {
106+
"Fn::Sub": "Enabled"
107+
},
108+
"Targets": [
109+
{
110+
"Arn": {
111+
"Fn::GetAtt": [
112+
"ScheduledFunction",
113+
"Arn"
114+
]
115+
},
116+
"Id": "ScheduledFunctionSchedule2LambdaTarget"
117+
}
118+
]
119+
}
120+
},
121+
"ScheduledFunctionSchedule2Permission": {
122+
"Type": "AWS::Lambda::Permission",
123+
"Properties": {
124+
"Action": "lambda:InvokeFunction",
125+
"FunctionName": {
126+
"Ref": "ScheduledFunction"
127+
},
128+
"Principal": "events.amazonaws.com",
129+
"SourceArn": {
130+
"Fn::GetAtt": [
131+
"ScheduledFunctionSchedule2",
132+
"Arn"
133+
]
134+
}
135+
}
136+
},
137+
"ScheduledFunctionSchedule3": {
138+
"Type": "AWS::Events::Rule",
139+
"Properties": {
140+
"Description": "Test Schedule",
141+
"Name": "test-schedule",
142+
"ScheduleExpression": "rate(1 minute)",
143+
"State": {
144+
"Ref": "ScheduleState"
145+
},
146+
"Targets": [
147+
{
148+
"Arn": {
149+
"Fn::GetAtt": [
150+
"ScheduledFunction",
151+
"Arn"
152+
]
153+
},
154+
"Id": "ScheduledFunctionSchedule3LambdaTarget"
155+
}
156+
]
157+
}
158+
},
159+
"ScheduledFunctionSchedule3Permission": {
160+
"Type": "AWS::Lambda::Permission",
161+
"Properties": {
162+
"Action": "lambda:InvokeFunction",
163+
"FunctionName": {
164+
"Ref": "ScheduledFunction"
165+
},
166+
"Principal": "events.amazonaws.com",
167+
"SourceArn": {
168+
"Fn::GetAtt": [
169+
"ScheduledFunctionSchedule3",
170+
"Arn"
171+
]
172+
}
173+
}
174+
}
175+
}
176+
}

0 commit comments

Comments
 (0)