@reventlessdev/reventless-aws 3.0.0-alpha.380 → 3.0.0-alpha.382
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/package.json +11 -11
- package/src/Platform.res +3 -3
- package/src/adapter/AWS.res +7 -0
- package/src/adapter/AWS.res.mjs +17 -3
- package/src/adapter/AWS_Tags.res +8 -0
- package/src/adapter/AWS_Tags.res.mjs +5 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res +20 -40
- package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res.mjs +14 -39
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +4 -2
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res.mjs +3 -3
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.res +5 -4
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.res.mjs +7 -3
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +10 -12
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res.mjs +3 -3
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +8 -6
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +4 -3
- package/src/adapter/ScheduledPublisher/ScheduledPublisher.res +2 -2
- package/src/adapter/ScheduledPublisher/ScheduledPublisher.res.mjs +4 -4
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler.res +73 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler.res.mjs +40 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res +89 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res.mjs +126 -0
- package/src/components/Scheduler.res +1 -1
- package/src/components/Scheduler.res.mjs +2 -2
- package/tests/CommandTopicQueuePolicyTest.res +12 -25
- package/tests/CommandTopicQueuePolicyTest.res.mjs +5 -10
- package/tests/ScheduledPublisher_EventBridgeSchedulerTest.res +65 -0
- package/tests/ScheduledPublisher_EventBridgeSchedulerTest.res.mjs +115 -0
- package/tests/TaskBucketEntryPoint_OpsTest.res +1 -1
- package/tests/TaskBucketEntryPoint_OpsTest.res.mjs +6 -3
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +0 -64
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res.mjs +0 -43
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res +0 -93
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res.mjs +0 -85
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.382 (2026-10-16)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **aws:** a schedule group carries no empty tag value ([f7c5074](https://github.com/ReventlessDev/reventless-core/commit/f7c507474ee5a31555e2af7fb8c87d58fb75ed54))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 3.0.0-alpha.381 (2026-10-15)
|
|
14
|
+
|
|
15
|
+
* feat!: schedules take a Schedule.time, run on EventBridge Scheduler on AWS ([2d74557](https://github.com/ReventlessDev/reventless-core/commit/2d74557a6304917ded8f2b9f4107af9298c91ac0))
|
|
16
|
+
|
|
17
|
+
### BREAKING CHANGES
|
|
18
|
+
|
|
19
|
+
* Schedule.rate is replaced by Schedule.time, and a
|
|
20
|
+
schedule's `rate` field is now `time`. A once-only time already past
|
|
21
|
+
never fires, locally as on AWS.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
# 3.0.0-alpha.380 (2026-10-12)
|
|
7
26
|
|
|
8
27
|
**Note:** Version bump only for package @reventlessdev/reventless-aws
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-aws",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.382",
|
|
4
4
|
"description": "AWS adapters for Reventless",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
"sury": "11.0.0",
|
|
23
23
|
"uuid": "^13.0.0",
|
|
24
24
|
"yaml": "^2.8.3",
|
|
25
|
-
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.
|
|
25
|
+
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.31",
|
|
26
26
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.12",
|
|
27
|
-
"@reventlessdev/rescript-
|
|
27
|
+
"@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.28",
|
|
28
28
|
"@reventlessdev/rescript-node": "2.0.0-alpha.22",
|
|
29
|
-
"@reventlessdev/rescript-
|
|
30
|
-
"@reventlessdev/rescript-
|
|
31
|
-
"@reventlessdev/reventless-core": "3.0.0-alpha.294",
|
|
29
|
+
"@reventlessdev/rescript-effect": "1.0.0-alpha.0",
|
|
30
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.23",
|
|
32
31
|
"@reventlessdev/rescript-web": "1.0.0-alpha.7",
|
|
33
|
-
"@reventlessdev/reventless-
|
|
34
|
-
"@reventlessdev/
|
|
35
|
-
"@reventlessdev/reventless-
|
|
36
|
-
"@reventlessdev/reventless-
|
|
37
|
-
"@reventlessdev/
|
|
32
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.295",
|
|
33
|
+
"@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
|
|
34
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.192",
|
|
35
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.159",
|
|
36
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.164",
|
|
37
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.40"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"rescript": "12.3.1",
|
package/src/Platform.res
CHANGED
|
@@ -1108,9 +1108,9 @@ module MakeWithConfig = (
|
|
|
1108
1108
|
|
|
1109
1109
|
let makeScheduler = () => {
|
|
1110
1110
|
let component = Scheduler.make()
|
|
1111
|
-
// Surface the
|
|
1112
|
-
//
|
|
1113
|
-
// `outputs.resource.urn` (no dedicated field on Scheduler.outputs).
|
|
1111
|
+
// Surface the scheduler role ARN, which also names the schedule group, so
|
|
1112
|
+
// bundled Lambdas can create schedules. ScheduledPublisher_EventBridgeScheduler
|
|
1113
|
+
// stashes it as `outputs.resource.urn` (no dedicated field on Scheduler.outputs).
|
|
1114
1114
|
let outputs = component->ReventlessCore.Component.outputs
|
|
1115
1115
|
hooks.schedulerRoleUrn := outputs.resource.urn
|
|
1116
1116
|
component->ReventlessCore.Component.operations
|
package/src/adapter/AWS.res
CHANGED
|
@@ -4,6 +4,7 @@ type service =
|
|
|
4
4
|
| AppSync
|
|
5
5
|
| IAM
|
|
6
6
|
| CloudwatchEventRule
|
|
7
|
+
| EventBridgeScheduler
|
|
7
8
|
| DynamoDb
|
|
8
9
|
| DynamoDbStream
|
|
9
10
|
| SQS
|
|
@@ -27,6 +28,7 @@ let toString: service => string = service =>
|
|
|
27
28
|
| AppSync => "aws:AppSync"
|
|
28
29
|
| IAM => "aws:IAM"
|
|
29
30
|
| CloudwatchEventRule => "aws:CloudwatchEventRule"
|
|
31
|
+
| EventBridgeScheduler => "aws:EventBridgeScheduler"
|
|
30
32
|
| S3 => "aws:S3"
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -43,6 +45,7 @@ let toPrincipal: service => string = service =>
|
|
|
43
45
|
| AppSync => "appsync.amazonaws.com"
|
|
44
46
|
| IAM => "iam.amazonaws.com"
|
|
45
47
|
| CloudwatchEventRule => "events.amazonaws.com"
|
|
48
|
+
| EventBridgeScheduler => "scheduler.amazonaws.com"
|
|
46
49
|
| S3 => "s3.amazonaws.com"
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -90,6 +93,10 @@ module CloudwatchEventRule = {
|
|
|
90
93
|
let service = CloudwatchEventRule->toString
|
|
91
94
|
let principal = CloudwatchEventRule->toPrincipal
|
|
92
95
|
}
|
|
96
|
+
module EventBridgeScheduler = {
|
|
97
|
+
let service = EventBridgeScheduler->toString
|
|
98
|
+
let principal = EventBridgeScheduler->toPrincipal
|
|
99
|
+
}
|
|
93
100
|
module S3 = {
|
|
94
101
|
let service = S3->toString
|
|
95
102
|
let principal = S3->toPrincipal
|
package/src/adapter/AWS.res.mjs
CHANGED
|
@@ -9,6 +9,8 @@ function toString(service) {
|
|
|
9
9
|
return "aws:IAM";
|
|
10
10
|
case "CloudwatchEventRule" :
|
|
11
11
|
return "aws:CloudwatchEventRule";
|
|
12
|
+
case "EventBridgeScheduler" :
|
|
13
|
+
return "aws:EventBridgeScheduler";
|
|
12
14
|
case "DynamoDb" :
|
|
13
15
|
return "aws:DynamoDb";
|
|
14
16
|
case "DynamoDbStream" :
|
|
@@ -38,6 +40,8 @@ function toPrincipal(service) {
|
|
|
38
40
|
return "iam.amazonaws.com";
|
|
39
41
|
case "CloudwatchEventRule" :
|
|
40
42
|
return "events.amazonaws.com";
|
|
43
|
+
case "EventBridgeScheduler" :
|
|
44
|
+
return "scheduler.amazonaws.com";
|
|
41
45
|
case "DynamoDb" :
|
|
42
46
|
case "DynamoDbStream" :
|
|
43
47
|
return "dynamodb.amazonaws.com";
|
|
@@ -155,15 +159,24 @@ let CloudwatchEventRule = {
|
|
|
155
159
|
principal: principal$10
|
|
156
160
|
};
|
|
157
161
|
|
|
158
|
-
let service$11 = "aws:
|
|
162
|
+
let service$11 = "aws:EventBridgeScheduler";
|
|
159
163
|
|
|
160
|
-
let principal$11 = "
|
|
164
|
+
let principal$11 = "scheduler.amazonaws.com";
|
|
161
165
|
|
|
162
|
-
let
|
|
166
|
+
let EventBridgeScheduler = {
|
|
163
167
|
service: service$11,
|
|
164
168
|
principal: principal$11
|
|
165
169
|
};
|
|
166
170
|
|
|
171
|
+
let service$12 = "aws:S3";
|
|
172
|
+
|
|
173
|
+
let principal$12 = "s3.amazonaws.com";
|
|
174
|
+
|
|
175
|
+
let S3 = {
|
|
176
|
+
service: service$12,
|
|
177
|
+
principal: principal$12
|
|
178
|
+
};
|
|
179
|
+
|
|
167
180
|
let Tags;
|
|
168
181
|
|
|
169
182
|
export {
|
|
@@ -181,6 +194,7 @@ export {
|
|
|
181
194
|
AppSync,
|
|
182
195
|
IAM,
|
|
183
196
|
CloudwatchEventRule,
|
|
197
|
+
EventBridgeScheduler,
|
|
184
198
|
S3,
|
|
185
199
|
}
|
|
186
200
|
/* No side effect */
|
package/src/adapter/AWS_Tags.res
CHANGED
|
@@ -103,6 +103,14 @@ let makeDict = (
|
|
|
103
103
|
]->Dict.fromArray
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
`tags` without the empty values, for the resource types that refuse a tag whose
|
|
108
|
+
value is empty: an EventBridge Scheduler schedule group fails to create with one
|
|
109
|
+
(`reventless:plugin` and `reventless:component` are empty at platform scope).
|
|
110
|
+
*/
|
|
111
|
+
let withoutEmpty = (tags: dict<string>) =>
|
|
112
|
+
tags->Dict.toArray->Array.filter(((_, value)) => value != "")->Dict.fromArray
|
|
113
|
+
|
|
106
114
|
/***
|
|
107
115
|
Framework-created AWS resource types that carry NO attribution tags, and why.
|
|
108
116
|
Keep this list here rather than in a plan: it is what tells a coverage audit
|
|
@@ -74,6 +74,10 @@ function makeDict(name, kind, role, scopeOpt, component, owner, plugin, platform
|
|
|
74
74
|
]);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
function withoutEmpty(tags) {
|
|
78
|
+
return Object.fromEntries(Object.entries(tags).filter(param => param[1] !== ""));
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
function make(name, kind, role, scopeOpt, component, owner, plugin, platform) {
|
|
78
82
|
let scope = scopeOpt !== undefined ? scopeOpt : "Component";
|
|
79
83
|
return makeDict(name, kind, role, scope, component, owner, plugin, platform);
|
|
@@ -84,6 +88,7 @@ let Attribution;
|
|
|
84
88
|
export {
|
|
85
89
|
Attribution,
|
|
86
90
|
makeDict,
|
|
91
|
+
withoutEmpty,
|
|
87
92
|
make,
|
|
88
93
|
}
|
|
89
94
|
/* @pulumi/pulumi Not a pure module */
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
open PulumiAws.PolicyDocument
|
|
2
2
|
open Adapter_Helpers
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
// EventBridge Scheduler delivers to the queue as the scheduler role, which holds
|
|
5
|
+
// sqs:SendMessage itself, so the queue's own policy admits only its Lambda.
|
|
6
|
+
let createQueuePolicyDocument = (~name, ~queueArn: string, ~lambdaArn: string) =>
|
|
6
7
|
PulumiAws.PolicyDocument.make(
|
|
7
8
|
~id=name ++ "QueuePolicy",
|
|
8
9
|
~statements=[
|
|
@@ -18,30 +19,8 @@ let createQueuePolicyDocument = (~name, ~queueArn: string, ~lambdaArn: string) =
|
|
|
18
19
|
arnEquals: [("AWS:SourceArn", ConditionValue(lambdaArn))]->Dict.fromArray,
|
|
19
20
|
},
|
|
20
21
|
},
|
|
21
|
-
{
|
|
22
|
-
// ScheduledPublisher creates EventBridge rules at runtime
|
|
23
|
-
// (PutRule/PutTargets) targeting this queue directly, and EventBridge
|
|
24
|
-
// authorises SQS targets against the queue's resource policy — so the
|
|
25
|
-
// grant cannot name a single rule ARN. Scope it to rules in this
|
|
26
|
-
// account instead: SourceAccount closes the cross-account hole,
|
|
27
|
-
// ArnLike narrows the in-account surface to Events rules.
|
|
28
|
-
sid: "AllowCloudWatchEventsToSendToQueue",
|
|
29
|
-
effect: Allow,
|
|
30
|
-
principal: Principals({
|
|
31
|
-
service: PrincipalId(AWS.CloudwatchEventRule.principal),
|
|
32
|
-
}),
|
|
33
|
-
actions: Actions(["sqs:SendMessage"]),
|
|
34
|
-
resources: Resource(queueArn),
|
|
35
|
-
conditions: {
|
|
36
|
-
stringEquals: [("aws:SourceAccount", ConditionValue(accountId))]->Dict.fromArray,
|
|
37
|
-
arnLike: [
|
|
38
|
-
("aws:SourceArn", ConditionValue(`arn:aws:events:*:${accountId}:rule/*`)),
|
|
39
|
-
]->Dict.fromArray,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
22
|
],
|
|
43
23
|
)->toJsonString
|
|
44
|
-
}
|
|
45
24
|
|
|
46
25
|
let createQueuePolicy = (
|
|
47
26
|
queue: PulumiAws.SQS.Queue.t,
|
|
@@ -138,19 +117,20 @@ let createLambdaPolicy = (
|
|
|
138
117
|
)
|
|
139
118
|
: None
|
|
140
119
|
|
|
141
|
-
|
|
142
|
-
|
|
120
|
+
// The scheduler role is not known here, so the grant names every
|
|
121
|
+
// scheduler group in the account rather than this platform's one.
|
|
122
|
+
let allowLambdaManageSchedules = PulumiAws.PolicyDocument.make(
|
|
123
|
+
~id=name ++ "LambdaSchedulerPolicy",
|
|
143
124
|
~statements=[
|
|
144
125
|
{
|
|
145
|
-
sid: "
|
|
126
|
+
sid: "AllowLambdaManageSchedules",
|
|
146
127
|
effect: Allow,
|
|
147
|
-
actions: Actions(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
resources: Resource("*"),
|
|
128
|
+
actions: Actions(ScheduledPublisher_EventBridgeScheduler_Runtime.manageActions),
|
|
129
|
+
resources: Resource(
|
|
130
|
+
queueArn
|
|
131
|
+
->accountIdOfQueueArn
|
|
132
|
+
->ScheduledPublisher_EventBridgeScheduler_Runtime.schedulesOfAccount,
|
|
133
|
+
),
|
|
154
134
|
},
|
|
155
135
|
],
|
|
156
136
|
)
|
|
@@ -172,17 +152,17 @@ let createLambdaPolicy = (
|
|
|
172
152
|
],
|
|
173
153
|
)
|
|
174
154
|
|
|
175
|
-
let
|
|
176
|
-
~id=name ++ "
|
|
155
|
+
let allowLambdaPassRoleToScheduler = PulumiAws.PolicyDocument.make(
|
|
156
|
+
~id=name ++ "LambdaPassRoleToScheduler",
|
|
177
157
|
~statements=[
|
|
178
158
|
{
|
|
179
|
-
sid: "
|
|
159
|
+
sid: "AllowLambdaPassRoleToScheduler",
|
|
180
160
|
effect: Allow,
|
|
181
161
|
actions: Action("iam:PassRole"),
|
|
182
162
|
resources: Resource("*"),
|
|
183
163
|
conditions: {
|
|
184
164
|
stringEquals: Dict.fromArray([
|
|
185
|
-
("iam:PassedToService", ConditionValue(
|
|
165
|
+
("iam:PassedToService", ConditionValue(AWS.EventBridgeScheduler.principal)),
|
|
186
166
|
]),
|
|
187
167
|
},
|
|
188
168
|
},
|
|
@@ -197,8 +177,8 @@ let createLambdaPolicy = (
|
|
|
197
177
|
[
|
|
198
178
|
Some(PulumiAws.Lambda.defaultLoggingPolicyDocument),
|
|
199
179
|
Some(allowLambdaReceiveSQS),
|
|
200
|
-
Some(
|
|
201
|
-
Some(
|
|
180
|
+
Some(allowLambdaManageSchedules),
|
|
181
|
+
Some(allowLambdaPassRoleToScheduler),
|
|
202
182
|
allowLambdaReadWriteDynamoDb,
|
|
203
183
|
allowSQSSendLambda,
|
|
204
184
|
]->Array.keepSome,
|
|
@@ -12,11 +12,10 @@ import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/sr
|
|
|
12
12
|
import * as CommandTopic$ReventlessCore from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic.res.mjs";
|
|
13
13
|
import * as Adapter_Helpers$ReventlessAws from "../Adapter_Helpers.res.mjs";
|
|
14
14
|
import * as Util_EventSourceMapping$ReventlessAws from "../../util/Util_EventSourceMapping.res.mjs";
|
|
15
|
+
import * as ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws from "../ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res.mjs";
|
|
15
16
|
|
|
16
17
|
function createQueuePolicyDocument(name, queueArn, lambdaArn) {
|
|
17
|
-
|
|
18
|
-
return PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, name + "QueuePolicy", [
|
|
19
|
-
{
|
|
18
|
+
return PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, name + "QueuePolicy", [{
|
|
20
19
|
Sid: "AllowLambdaToAccessQueue",
|
|
21
20
|
Principal: {
|
|
22
21
|
Service: AWS$ReventlessAws.Lambda.principal
|
|
@@ -34,27 +33,7 @@ function createQueuePolicyDocument(name, queueArn, lambdaArn) {
|
|
|
34
33
|
lambdaArn
|
|
35
34
|
]])
|
|
36
35
|
}
|
|
37
|
-
}
|
|
38
|
-
{
|
|
39
|
-
Sid: "AllowCloudWatchEventsToSendToQueue",
|
|
40
|
-
Principal: {
|
|
41
|
-
Service: AWS$ReventlessAws.CloudwatchEventRule.principal
|
|
42
|
-
},
|
|
43
|
-
Effect: "Allow",
|
|
44
|
-
Action: ["sqs:SendMessage"],
|
|
45
|
-
Resource: queueArn,
|
|
46
|
-
Condition: {
|
|
47
|
-
StringEquals: Object.fromEntries([[
|
|
48
|
-
"aws:SourceAccount",
|
|
49
|
-
accountId
|
|
50
|
-
]]),
|
|
51
|
-
ArnLike: Object.fromEntries([[
|
|
52
|
-
"aws:SourceArn",
|
|
53
|
-
`arn:aws:events:*:` + accountId + `:rule/*`
|
|
54
|
-
]])
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
]));
|
|
36
|
+
}]));
|
|
58
37
|
}
|
|
59
38
|
|
|
60
39
|
function createQueuePolicy(queue, name, lambda, opts) {
|
|
@@ -74,6 +53,7 @@ function createLambdaPolicy(lambdaRole, name, queue, resources, opts) {
|
|
|
74
53
|
Adapter$ReventlessCore.resourcesToResolvedOutput(resources)
|
|
75
54
|
]).apply(param => {
|
|
76
55
|
let resources = param[1];
|
|
56
|
+
let queueArn = param[0];
|
|
77
57
|
let allowSQSSendLambda = Adapter_Helpers$ReventlessAws.sqsResources(resources).length !== 0 ? PolicyDocument$PulumiAws.make(undefined, name + "RemoteSQSLambdaPolicy", [{
|
|
78
58
|
Sid: "AllowLambdaSendMessageSQS",
|
|
79
59
|
Effect: "Allow",
|
|
@@ -99,16 +79,11 @@ function createLambdaPolicy(lambdaRole, name, queue, resources, opts) {
|
|
|
99
79
|
dynamoDbResource.urn + "/index/*"
|
|
100
80
|
])
|
|
101
81
|
}]) : undefined;
|
|
102
|
-
let
|
|
103
|
-
Sid: "
|
|
82
|
+
let allowLambdaManageSchedules = PolicyDocument$PulumiAws.make(undefined, name + "LambdaSchedulerPolicy", [{
|
|
83
|
+
Sid: "AllowLambdaManageSchedules",
|
|
104
84
|
Effect: "Allow",
|
|
105
|
-
Action:
|
|
106
|
-
|
|
107
|
-
"events:PutTargets",
|
|
108
|
-
"events:DeleteRule",
|
|
109
|
-
"events:RemoveTargets"
|
|
110
|
-
],
|
|
111
|
-
Resource: "*"
|
|
85
|
+
Action: ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.manageActions,
|
|
86
|
+
Resource: ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.schedulesOfAccount(Adapter_Helpers$ReventlessAws.accountIdOfQueueArn(queueArn))
|
|
112
87
|
}]);
|
|
113
88
|
let allowLambdaReceiveSQS = PolicyDocument$PulumiAws.make(undefined, name + "SQSLambdaPolicy", [{
|
|
114
89
|
Sid: "AllowLambdaReceiveSQS",
|
|
@@ -119,17 +94,17 @@ function createLambdaPolicy(lambdaRole, name, queue, resources, opts) {
|
|
|
119
94
|
"sqs:GetQueueAttributes",
|
|
120
95
|
"sqs:ChangeMessageVisibility"
|
|
121
96
|
],
|
|
122
|
-
Resource:
|
|
97
|
+
Resource: queueArn
|
|
123
98
|
}]);
|
|
124
|
-
let
|
|
125
|
-
Sid: "
|
|
99
|
+
let allowLambdaPassRoleToScheduler = PolicyDocument$PulumiAws.make(undefined, name + "LambdaPassRoleToScheduler", [{
|
|
100
|
+
Sid: "AllowLambdaPassRoleToScheduler",
|
|
126
101
|
Effect: "Allow",
|
|
127
102
|
Action: "iam:PassRole",
|
|
128
103
|
Resource: "*",
|
|
129
104
|
Condition: {
|
|
130
105
|
StringEquals: Object.fromEntries([[
|
|
131
106
|
"iam:PassedToService",
|
|
132
|
-
|
|
107
|
+
AWS$ReventlessAws.EventBridgeScheduler.principal
|
|
133
108
|
]])
|
|
134
109
|
}
|
|
135
110
|
}]);
|
|
@@ -137,8 +112,8 @@ function createLambdaPolicy(lambdaRole, name, queue, resources, opts) {
|
|
|
137
112
|
policy: PolicyDocument$PulumiAws.mergePolicyDocuments(name + "LambdaPolicy", Stdlib_Array.keepSome([
|
|
138
113
|
Lambda$PulumiAws.defaultLoggingPolicyDocument,
|
|
139
114
|
allowLambdaReceiveSQS,
|
|
140
|
-
|
|
141
|
-
|
|
115
|
+
allowLambdaManageSchedules,
|
|
116
|
+
allowLambdaPassRoleToScheduler,
|
|
142
117
|
allowLambdaReadWriteDynamoDb,
|
|
143
118
|
allowSQSSendLambda
|
|
144
119
|
])),
|
|
@@ -575,10 +575,12 @@ let makeQueryEngine = (pluginReadModelTableName: string): Reventless.QueryEngine
|
|
|
575
575
|
}
|
|
576
576
|
|
|
577
577
|
let makeScheduler = (schedulerRoleArn: string): ReventlessCore.Scheduler.operations => {
|
|
578
|
-
createSchedule:
|
|
578
|
+
createSchedule: ScheduledPublisher_EventBridgeScheduler_Runtime.createSchedule(
|
|
579
|
+
~roleArn=schedulerRoleArn,
|
|
580
|
+
),
|
|
581
|
+
deleteSchedule: ScheduledPublisher_EventBridgeScheduler_Runtime.deleteSchedule(
|
|
579
582
|
~roleArn=schedulerRoleArn,
|
|
580
583
|
),
|
|
581
|
-
deleteSchedule: ScheduledPublisher_CloudWatchEvents_Runtime.deleteSchedule,
|
|
582
584
|
}
|
|
583
585
|
|
|
584
586
|
let makeCommandTopicResources = (config: handlerConfig): array<
|
|
@@ -18,7 +18,7 @@ import * as Util_PluginMessage_Runtime$ReventlessAws from "../../plugin/runtime/
|
|
|
18
18
|
import * as CommandTopicChannel_SQS_Runtime$ReventlessAws from "../CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs";
|
|
19
19
|
import * as EventTopicPublisher_SNS_Runtime$ReventlessAws from "../EventTopic/EventTopicPublisher_SNS_Runtime.res.mjs";
|
|
20
20
|
import * as EventCollectorChannel_SQS_Runtime$ReventlessAws from "../EventCollector/EventCollectorChannel_SQS_Runtime.res.mjs";
|
|
21
|
-
import * as
|
|
21
|
+
import * as ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws from "../ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res.mjs";
|
|
22
22
|
|
|
23
23
|
function setRequestId(prim) {
|
|
24
24
|
HandlerFactoryHelpersMjs.setRequestId(prim);
|
|
@@ -445,8 +445,8 @@ function makeQueryEngine(pluginReadModelTableName) {
|
|
|
445
445
|
|
|
446
446
|
function makeScheduler(schedulerRoleArn) {
|
|
447
447
|
return {
|
|
448
|
-
createSchedule:
|
|
449
|
-
deleteSchedule:
|
|
448
|
+
createSchedule: ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.createSchedule(schedulerRoleArn),
|
|
449
|
+
deleteSchedule: ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.deleteSchedule(schedulerRoleArn)
|
|
450
450
|
};
|
|
451
451
|
}
|
|
452
452
|
|
|
@@ -131,10 +131,11 @@ let queryEngine: Reventless.QueryEngine.operations = {
|
|
|
131
131
|
|
|
132
132
|
// Reconstruct scheduler
|
|
133
133
|
let scheduler: ReventlessCore.Scheduler.operations = {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
let roleArn = config.schedulerRoleArn->Option.getOr("")
|
|
135
|
+
{
|
|
136
|
+
createSchedule: ScheduledPublisher_EventBridgeScheduler_Runtime.createSchedule(~roleArn),
|
|
137
|
+
deleteSchedule: ScheduledPublisher_EventBridgeScheduler_Runtime.deleteSchedule(~roleArn),
|
|
138
|
+
}
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
// CommandTopic resources for scheduler targets
|
|
@@ -10,7 +10,7 @@ import * as PluginExtensionPointSpec$ReventlessInfra from "@reventlessdev/revent
|
|
|
10
10
|
import * as Util_PluginMessage_Runtime$ReventlessAws from "../../plugin/runtime/Util_PluginMessage_Runtime.res.mjs";
|
|
11
11
|
import * as PluginExtensionPoint_Plugin$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs";
|
|
12
12
|
import * as CommandTopicChannel_SQS_Runtime$ReventlessAws from "../CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs";
|
|
13
|
-
import * as
|
|
13
|
+
import * as ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws from "../ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res.mjs";
|
|
14
14
|
|
|
15
15
|
function setRequestId(prim) {
|
|
16
16
|
HandlerFactoryHelpersMjs.setRequestId(prim);
|
|
@@ -93,11 +93,15 @@ let queryEngine = {
|
|
|
93
93
|
query: queryEngine_query
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
let
|
|
96
|
+
let roleArn = Stdlib_Option.getOr(config.schedulerRoleArn, "");
|
|
97
|
+
|
|
98
|
+
let scheduler_createSchedule = ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.createSchedule(roleArn);
|
|
99
|
+
|
|
100
|
+
let scheduler_deleteSchedule = ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.deleteSchedule(roleArn);
|
|
97
101
|
|
|
98
102
|
let scheduler = {
|
|
99
103
|
createSchedule: scheduler_createSchedule,
|
|
100
|
-
deleteSchedule:
|
|
104
|
+
deleteSchedule: scheduler_deleteSchedule
|
|
101
105
|
};
|
|
102
106
|
|
|
103
107
|
let schedulerQueueArn = Stdlib_Option.getOr(config.schedulerQueueArn, "");
|
|
@@ -6,13 +6,8 @@
|
|
|
6
6
|
// the read of its `callback` export. HANDLER_CONFIG parsing, the S3-event →
|
|
7
7
|
// task-action dispatch (an exhaustive match over Reventless.Task.taskAction —
|
|
8
8
|
// the former JS `switch (action.TAG)` with its unreachable "unknown TAG" arm), the
|
|
9
|
-
// per-aggregate command publishing, and the
|
|
9
|
+
// per-aggregate command publishing, and the EventBridge Scheduler ops
|
|
10
10
|
// live here, fully type-checked.
|
|
11
|
-
//
|
|
12
|
-
// The former `.mjs` carried a hand-maintained mirror of
|
|
13
|
-
// `toScheduleExpression` ("kept in sync manually"); typed code calls
|
|
14
|
-
// ScheduledPublisher_CloudWatchEvents_Runtime directly — the layer ships it —
|
|
15
|
-
// so the mirror is gone.
|
|
16
11
|
|
|
17
12
|
@module("./HandlerFactoryHelpers.mjs") @scope("log")
|
|
18
13
|
external logWarn: (string, StreamRoutedEntryPoint_Ops.dispatchOpts) => unit = "warn"
|
|
@@ -80,9 +75,9 @@ let buildPublishCommands = (map: dict<string>): dict<ReventlessCore.CommandTopic
|
|
|
80
75
|
)
|
|
81
76
|
->Dict.fromArray
|
|
82
77
|
|
|
83
|
-
// ── Scheduler ops (
|
|
78
|
+
// ── Scheduler ops (EventBridge Scheduler) ───────────────────────────────────────
|
|
84
79
|
// Resolved lazily on the first schedule action (tasks without schedules never
|
|
85
|
-
// touch the
|
|
80
|
+
// touch the Scheduler client) and cached for the container lifetime.
|
|
86
81
|
|
|
87
82
|
type schedulerOps = {
|
|
88
83
|
createSchedule: Reventless.Schedule.schedule => promise<unit>,
|
|
@@ -103,8 +98,8 @@ let makeSchedulerOps = (config: option<schedulerEnvConfig>): option<schedulerOps
|
|
|
103
98
|
) {
|
|
104
99
|
| (Some(roleArn), Some(targetArn), Some(targetName))
|
|
105
100
|
if roleArn != "" && targetArn != "" && targetName != "" =>
|
|
106
|
-
// The single resolved resource the shared
|
|
107
|
-
// targets: `urn` is the
|
|
101
|
+
// The single resolved resource the shared scheduler runtime
|
|
102
|
+
// targets: `urn` is the target queue ARN.
|
|
108
103
|
let resources: array<ReventlessInfra.Adapter.resolvedResource> = [
|
|
109
104
|
{
|
|
110
105
|
name: targetName,
|
|
@@ -121,9 +116,12 @@ let makeSchedulerOps = (config: option<schedulerEnvConfig>): option<schedulerOps
|
|
|
121
116
|
]
|
|
122
117
|
let ops = {
|
|
123
118
|
createSchedule: schedule =>
|
|
124
|
-
|
|
119
|
+
ScheduledPublisher_EventBridgeScheduler_Runtime.createSchedule(~roleArn)(
|
|
120
|
+
resources,
|
|
121
|
+
schedule,
|
|
122
|
+
),
|
|
125
123
|
deleteSchedule: name =>
|
|
126
|
-
|
|
124
|
+
ScheduledPublisher_EventBridgeScheduler_Runtime.deleteSchedule(~roleArn)(resources, name),
|
|
127
125
|
}
|
|
128
126
|
schedulerOpsCache := Some(ops)
|
|
129
127
|
Some(ops)
|
|
@@ -6,7 +6,7 @@ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
|
6
6
|
import * as HandlerFactoryHelpersMjs from "./HandlerFactoryHelpers.mjs";
|
|
7
7
|
import * as TaskBucket_S3_Runtime$ReventlessAws from "../Task/TaskBucket_S3_Runtime.res.mjs";
|
|
8
8
|
import * as CommandTopicChannel_SQS_Runtime$ReventlessAws from "../CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs";
|
|
9
|
-
import * as
|
|
9
|
+
import * as ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws from "../ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res.mjs";
|
|
10
10
|
|
|
11
11
|
function logWarn(prim0, prim1) {
|
|
12
12
|
HandlerFactoryHelpersMjs.log.warn(prim0, prim1);
|
|
@@ -80,8 +80,8 @@ function makeSchedulerOps(config) {
|
|
|
80
80
|
configuration: {},
|
|
81
81
|
tags: {}
|
|
82
82
|
}];
|
|
83
|
-
let ops_createSchedule = schedule =>
|
|
84
|
-
let ops_deleteSchedule = name =>
|
|
83
|
+
let ops_createSchedule = schedule => ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.createSchedule(match$1)(resources, schedule);
|
|
84
|
+
let ops_deleteSchedule = name => ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.deleteSchedule(match$1)(resources, name);
|
|
85
85
|
let ops = {
|
|
86
86
|
createSchedule: ops_createSchedule,
|
|
87
87
|
deleteSchedule: ops_deleteSchedule
|
|
@@ -82,9 +82,9 @@ let forBucketCallback = (
|
|
|
82
82
|
~opts={Pulumi.ComponentResource.parent: resource},
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
// Grant the Task Lambda role permission to manage
|
|
86
|
-
// and pass the scheduler role to
|
|
87
|
-
// is present (Tasks with side effects).
|
|
85
|
+
// Grant the Task Lambda role permission to manage the schedules in the
|
|
86
|
+
// scheduler's group and pass the scheduler role to them. Only needed when a
|
|
87
|
+
// schedulerConfig is present (Tasks with side effects).
|
|
88
88
|
switch schedulerConfig {
|
|
89
89
|
| None => ()
|
|
90
90
|
| Some({schedulerRoleUrn}) =>
|
|
@@ -97,10 +97,12 @@ let forBucketCallback = (
|
|
|
97
97
|
~id=`${fullName}SchedulerPolicy`,
|
|
98
98
|
~statements=[
|
|
99
99
|
{
|
|
100
|
-
sid: "
|
|
100
|
+
sid: "AllowManageSchedules",
|
|
101
101
|
effect: Allow,
|
|
102
|
-
actions:
|
|
103
|
-
resources:
|
|
102
|
+
actions: Actions(ScheduledPublisher_EventBridgeScheduler_Runtime.manageActions),
|
|
103
|
+
resources: Resource(
|
|
104
|
+
arn->ScheduledPublisher_EventBridgeScheduler_Runtime.schedulesOfRoleArn,
|
|
105
|
+
),
|
|
104
106
|
},
|
|
105
107
|
{
|
|
106
108
|
sid: "AllowPassSchedulerRole",
|
|
@@ -8,6 +8,7 @@ import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/co
|
|
|
8
8
|
import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/src/IAM/PolicyDocument.res.mjs";
|
|
9
9
|
import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
|
|
10
10
|
import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
|
|
11
|
+
import * as ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws from "../ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res.mjs";
|
|
11
12
|
|
|
12
13
|
function forBucketCallback(param, connect, memorySizeOpt, timeoutOpt, name, callbackModulePath, publishToAggregatesQueueUrls, schedulerConfig, task) {
|
|
13
14
|
let memorySize = memorySizeOpt !== undefined ? memorySizeOpt : 4096;
|
|
@@ -38,10 +39,10 @@ function forBucketCallback(param, connect, memorySizeOpt, timeoutOpt, name, call
|
|
|
38
39
|
new (Aws.iam.RolePolicy)(fullName + `SchedulerPolicy`, {
|
|
39
40
|
policy: PolicyDocument$PulumiAws.toJsonString(PolicyDocument$PulumiAws.make(undefined, fullName + `SchedulerPolicy`, [
|
|
40
41
|
{
|
|
41
|
-
Sid: "
|
|
42
|
+
Sid: "AllowManageSchedules",
|
|
42
43
|
Effect: "Allow",
|
|
43
|
-
Action:
|
|
44
|
-
Resource:
|
|
44
|
+
Action: ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.manageActions,
|
|
45
|
+
Resource: ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.schedulesOfRoleArn(arn)
|
|
45
46
|
},
|
|
46
47
|
{
|
|
47
48
|
Sid: "AllowPassSchedulerRole",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
module
|
|
2
|
-
module
|
|
1
|
+
module EventBridgeScheduler = ScheduledPublisher_EventBridgeScheduler
|
|
2
|
+
module EventBridgeScheduler_Runtime = ScheduledPublisher_EventBridgeScheduler_Runtime
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
let
|
|
4
|
+
let EventBridgeScheduler;
|
|
5
5
|
|
|
6
|
-
let
|
|
6
|
+
let EventBridgeScheduler_Runtime;
|
|
7
7
|
|
|
8
8
|
export {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
EventBridgeScheduler,
|
|
10
|
+
EventBridgeScheduler_Runtime,
|
|
11
11
|
}
|
|
12
12
|
/* No side effect */
|