@izara_project/izara-core-generate-service-code 1.0.83 → 1.0.85
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/package.json +4 -4
- package/src/compile/flowValidator.js +13 -2
- package/src/compile/loadSchemas.js +116 -7
- package/src/emit/attributeTree/emitAttributeTreeSchemas.js +388 -0
- package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +34 -1
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +29 -7
- package/src/emit/crud/crudActionPlan.js +41 -6
- package/src/emit/crud/emitCrudApplicationArtifacts.js +56 -8
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +153 -27
- package/src/emit/crud/generateCrudApplicationArtifacts.js +3 -2
- package/src/emit/crud/generateDynamicCrudFlowSchemas.js +3 -2
- package/src/emit/crud/loadLocalSchemaArrays.js +3 -3
- package/src/emit/crud/templates/CreateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/CreateConfirmComplete_Main.ejs +54 -0
- package/src/emit/crud/templates/CreateEndpoint_Main.ejs +252 -154
- package/src/emit/crud/templates/CreateLogicalLib.ejs +1163 -236
- package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +221 -0
- package/src/emit/crud/templates/DeleteComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +33 -8
- package/src/emit/crud/templates/DeleteLogicalLib.ejs +6 -3
- package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +20 -120
- package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +79 -10
- package/src/emit/crud/templates/FlowMain_Wbs.ejs +31 -35
- package/src/emit/crud/templates/GetEndpoint_Main.ejs +13 -0
- package/src/emit/crud/templates/UpdateComplete_Main.ejs +1 -1
- package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +52 -3
- package/src/emit/crud/templates/UpdateLogicalLib.ejs +4 -3
- package/src/emit/custom/customFlows.js +47 -0
- package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +168 -49
- package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +1 -1
- package/src/emit/custom/templates/FlowEndpointRbacCallback_Main.ejs +194 -0
- package/src/emit/custom/templates/FlowEndpoint_Main.ejs +14 -22
- package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
- package/src/emit/function/templates/WbsFunction_Yaml.ejs +0 -2
- package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +33 -8
- package/src/emit/rbac/emitRbacApplicationArtifacts.js +204 -7
- package/src/emit/rbac/templates/CancelUsage_Main.ejs +163 -0
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +187 -0
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +68 -6
- package/src/emit/rbac/templates/ListRbac_Main.ejs +9 -3
- package/src/emit/rbac/templates/RbacMutation_Main.ejs +1 -1
- package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +166 -0
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +84 -23
- package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +11 -8
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +4 -4
- package/src/emit/resource/emitResourceArtifacts.js +351 -108
- package/src/emit/resource/templates/GeneratedLambdaRoleServiceConfig.ejs +3 -1
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +55 -2
- package/src/emit/shared/templates/FlowHandler_HdrSqs.ejs +1 -1
- package/src/emit/system/emitSystemWebSocketArtifacts.js +6 -5
- package/src/emit/system/templates/WebSocketConnect.ejs +71 -12
- package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +6 -0
- package/src/emit/systemText/emitSystemTextSchemas.js +1 -1
- package/src/generate.js +41 -10
- package/test/attributeTreeSchemas.test.js +219 -0
- package/test/createTargetRoleHandler.test.js +59 -4
- package/test/crudApplicationArtifacts.test.js +20 -3
- package/test/customFlowApplicationArtifacts.test.js +5 -5
- package/test/dynamicCrudFlowSchemas.test.js +107 -6
- package/test/dynamicRbacFlowSchemas.test.js +15 -2
- package/test/publicApi.test.js +6 -6
- package/test/resourceArtifacts.test.js +89 -27
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
flowExtTopicSteps,
|
|
8
8
|
generatedDsqFlows,
|
|
9
9
|
generatedOwnTopicFlows,
|
|
10
|
-
supportedCustomFlows
|
|
10
|
+
supportedCustomFlows,
|
|
11
|
+
flowHasRbac
|
|
11
12
|
} from '../custom/customFlows.js';
|
|
12
13
|
import { hasSystemWebSocket } from '../system/emitSystemWebSocketArtifacts.js';
|
|
13
14
|
import { rbacFlowTag } from '../rbac/rbacFlowTag.js';
|
|
@@ -38,7 +39,13 @@ const RBAC_ACTIONS = [
|
|
|
38
39
|
'CreateUserRole',
|
|
39
40
|
'ListUserInRoles',
|
|
40
41
|
'DeleteUserFromRole',
|
|
41
|
-
'ValidatorRbac'
|
|
42
|
+
'ValidatorRbac',
|
|
43
|
+
'CreateRoleLimit',
|
|
44
|
+
'ListRoleLimits',
|
|
45
|
+
'DeleteRoleLimit',
|
|
46
|
+
'ReservedDynamicUsage',
|
|
47
|
+
'ConfirmUsage',
|
|
48
|
+
'CancelUsage'
|
|
42
49
|
];
|
|
43
50
|
const SYSTEM_TABLES = [
|
|
44
51
|
'WebSocketTask',
|
|
@@ -57,6 +64,9 @@ const RBAC_TABLES = [
|
|
|
57
64
|
'RoleUsers',
|
|
58
65
|
'UserRoles',
|
|
59
66
|
'RbacPermissionCaches',
|
|
67
|
+
'RoleLimit',
|
|
68
|
+
'RunningTotalUsage',
|
|
69
|
+
'RunningTotalReservedUsage',
|
|
60
70
|
'WebSocketTask'
|
|
61
71
|
];
|
|
62
72
|
const LEGACY_PROCESS_QUEUES = [
|
|
@@ -93,8 +103,23 @@ export async function emitResourceArtifacts({
|
|
|
93
103
|
throw new TypeError('objects, relationships, and flows must be arrays');
|
|
94
104
|
}
|
|
95
105
|
const state = createResourceState({ objects, relationships, flows });
|
|
96
|
-
const [
|
|
97
|
-
|
|
106
|
+
const [
|
|
107
|
+
crudInSqs,
|
|
108
|
+
relationshipInSqs,
|
|
109
|
+
rbacInSqs,
|
|
110
|
+
customFlowInSqs,
|
|
111
|
+
systemInSqs,
|
|
112
|
+
out,
|
|
113
|
+
dynamo,
|
|
114
|
+
iam,
|
|
115
|
+
lambdaRoleConfig,
|
|
116
|
+
s3
|
|
117
|
+
] = await Promise.all([
|
|
118
|
+
renderCrudInSqs(state),
|
|
119
|
+
renderRelationshipInSqs(state),
|
|
120
|
+
renderRbacInSqs(state),
|
|
121
|
+
renderCustomFlowInSqs(state),
|
|
122
|
+
renderSystemInSqs(state),
|
|
98
123
|
renderOut(state),
|
|
99
124
|
renderDynamo(state),
|
|
100
125
|
renderIam(state),
|
|
@@ -102,10 +127,6 @@ export async function emitResourceArtifacts({
|
|
|
102
127
|
renderS3(state)
|
|
103
128
|
]);
|
|
104
129
|
const artifacts = [
|
|
105
|
-
{
|
|
106
|
-
path: `${RESOURCE_ROOT}/generated-sns-in-sqs.yml`,
|
|
107
|
-
content: normalizeYaml(inSqs)
|
|
108
|
-
},
|
|
109
130
|
{
|
|
110
131
|
path: `${RESOURCE_ROOT}/generated-sns-out.yml`,
|
|
111
132
|
content: normalizeYaml(out)
|
|
@@ -123,6 +144,36 @@ export async function emitResourceArtifacts({
|
|
|
123
144
|
content: normalizeYaml(iam.roleNameConfigContent)
|
|
124
145
|
}
|
|
125
146
|
];
|
|
147
|
+
if (crudInSqs) {
|
|
148
|
+
artifacts.push({
|
|
149
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-crud.yml`,
|
|
150
|
+
content: normalizeYaml(crudInSqs)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (relationshipInSqs) {
|
|
154
|
+
artifacts.push({
|
|
155
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-relationship.yml`,
|
|
156
|
+
content: normalizeYaml(relationshipInSqs)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (rbacInSqs) {
|
|
160
|
+
artifacts.push({
|
|
161
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-rbac.yml`,
|
|
162
|
+
content: normalizeYaml(rbacInSqs)
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (customFlowInSqs) {
|
|
166
|
+
artifacts.push({
|
|
167
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-custom-flows.yml`,
|
|
168
|
+
content: normalizeYaml(customFlowInSqs)
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (systemInSqs) {
|
|
172
|
+
artifacts.push({
|
|
173
|
+
path: `${RESOURCE_ROOT}/generated-sns-sqs-system.yml`,
|
|
174
|
+
content: normalizeYaml(systemInSqs)
|
|
175
|
+
});
|
|
176
|
+
}
|
|
126
177
|
if (state.s3Buckets.length > 0) {
|
|
127
178
|
artifacts.push({
|
|
128
179
|
path: `${RESOURCE_ROOT}/generated-s3.yml`,
|
|
@@ -140,6 +191,11 @@ export async function emitResourceArtifacts({
|
|
|
140
191
|
|
|
141
192
|
export const resourceArtifactPaths = [
|
|
142
193
|
`${RESOURCE_ROOT}/generated-sns-in-sqs.yml`,
|
|
194
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-crud.yml`,
|
|
195
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-relationship.yml`,
|
|
196
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-rbac.yml`,
|
|
197
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-custom-flows.yml`,
|
|
198
|
+
`${RESOURCE_ROOT}/generated-sns-sqs-system.yml`,
|
|
143
199
|
`${RESOURCE_ROOT}/generated-sns-out.yml`,
|
|
144
200
|
`${RESOURCE_ROOT}/generated-dynamoDB-table.yml`,
|
|
145
201
|
`${RESOURCE_ROOT}/generated-s3.yml`,
|
|
@@ -153,65 +209,37 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
153
209
|
const selfRbac = objects.some(hasSelfRbacAddOn);
|
|
154
210
|
const rbac = objects.some(hasSelfRbacAddOn);
|
|
155
211
|
const crudActionPlans = createCrudActionPlans(objects);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
...flows
|
|
160
|
-
.filter((flow) => includesEvent(flow, 'ownTopic'))
|
|
161
|
-
.map((flow) => upperFirst(flow.flowTag))
|
|
162
|
-
]);
|
|
163
|
-
const sqsQueues = new Set([
|
|
164
|
-
'PaginateProcessLogicalHdrDsq',
|
|
165
|
-
'PaginateProcessLogicalHdrSqs',
|
|
166
|
-
...flows
|
|
167
|
-
.filter((flow) => includesEvent(flow, 'extTopic'))
|
|
168
|
-
.map((flow) => `Process${upperFirst(flow.flowTag)}HdrSqs`),
|
|
169
|
-
...flows
|
|
170
|
-
.filter((flow) => flow?.outputTopic && !flow?.generatedCodeConfig && upperFirst(flow.flowTag))
|
|
171
|
-
.map((flow) => `${upperFirst(flow.flowTag)}CompleteHdrSqs`)
|
|
172
|
-
]);
|
|
173
|
-
for (const { flowTag, stepName } of flowExtTopicSteps(flows)) {
|
|
174
|
-
sqsQueues.add(`${flowTag}${stepName}HdrSqs`);
|
|
175
|
-
}
|
|
176
|
-
for (const flow of flows.filter((flow) => includesEvent(flow, 's3'))) {
|
|
177
|
-
const tag = upperFirst(flow.flowTag);
|
|
178
|
-
sqsQueues.add(`${tag}CreatePreSignUrlHdrSqs`);
|
|
179
|
-
sqsQueues.add(`${tag}ReservedLimitHdrSqs`);
|
|
180
|
-
sqsQueues.add(`${tag}ConfirmAfterUploadHdrSqs`);
|
|
181
|
-
}
|
|
182
|
-
const dsqQueues = new Set(
|
|
183
|
-
flows
|
|
184
|
-
.filter((flow) => includesEvent(flow, 'dsq'))
|
|
185
|
-
.map((flow) => `${upperFirst(flow.flowTag)}HdrDsq`)
|
|
186
|
-
);
|
|
187
|
-
for (const { flowTag, stepName } of flowDsqSteps(flows)) {
|
|
188
|
-
dsqQueues.add(`${flowTag}${stepName}HdrDsq`);
|
|
189
|
-
}
|
|
212
|
+
|
|
213
|
+
const crudOwnTopics = crud ? [...CRUD_ACTIONS] : [];
|
|
214
|
+
const crudSqsQueues = [];
|
|
190
215
|
if (crud) {
|
|
191
|
-
for (const action of CRUD_ACTIONS) {
|
|
192
|
-
ownTopics.add(action);
|
|
193
|
-
}
|
|
194
216
|
for (const action of ['Create', 'Update', 'Delete']) {
|
|
195
217
|
const plan = crudActionPlans[action];
|
|
196
|
-
if (plan.
|
|
197
|
-
|
|
218
|
+
if (plan.hasCreateNodeCallback) {
|
|
219
|
+
crudSqsQueues.push(`${action}NodeCallbackHdrSqs`);
|
|
198
220
|
}
|
|
199
|
-
if (plan.
|
|
200
|
-
|
|
221
|
+
if (plan.hasComplete) {
|
|
222
|
+
crudSqsQueues.push(`${action}CompleteHdrSqs`);
|
|
201
223
|
}
|
|
202
224
|
}
|
|
203
225
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
226
|
+
|
|
227
|
+
const relationshipOwnTopics = relationships.length > 0
|
|
228
|
+
? [...RELATIONSHIP_ACTIONS]
|
|
229
|
+
: [];
|
|
230
|
+
const relationshipSqsQueues = relationships.length > 0
|
|
231
|
+
? RELATIONSHIP_ACTIONS.map((action) => `${action}CompleteHdrSqs`)
|
|
232
|
+
: [];
|
|
233
|
+
const relationshipDsqQueues = relationships.length > 0
|
|
234
|
+
? ['GetRelationshipHdrDsq']
|
|
235
|
+
: [];
|
|
236
|
+
|
|
237
|
+
const rbacOwnTopics = [];
|
|
238
|
+
const rbacSqsQueues = [];
|
|
211
239
|
if (selfRbac) {
|
|
212
240
|
for (const action of RBAC_ACTIONS) {
|
|
213
|
-
|
|
214
|
-
|
|
241
|
+
rbacOwnTopics.push(action);
|
|
242
|
+
rbacSqsQueues.push(`Process${action}HdrSqs`);
|
|
215
243
|
}
|
|
216
244
|
}
|
|
217
245
|
if (rbac) {
|
|
@@ -219,9 +247,93 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
219
247
|
...new Set(objects.filter(hasRbacAddOn).map(rbacFlowTag))
|
|
220
248
|
];
|
|
221
249
|
for (const flowTag of flowTags) {
|
|
222
|
-
|
|
250
|
+
rbacOwnTopics.push(flowTag);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (crud) {
|
|
254
|
+
for (const action of ['Create', 'Update', 'Delete']) {
|
|
255
|
+
const plan = crudActionPlans[action];
|
|
256
|
+
if (plan.hasRbacCallback) {
|
|
257
|
+
rbacSqsQueues.push(`${action}RbacCallbackHdrSqs`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const customOwnTopics = flows
|
|
263
|
+
.filter((flow) => includesEvent(flow, 'ownTopic'))
|
|
264
|
+
.map((flow) => upperFirst(flow.flowTag));
|
|
265
|
+
|
|
266
|
+
const customSqsQueues = [
|
|
267
|
+
...flows
|
|
268
|
+
.filter((flow) => includesEvent(flow, 'extTopic'))
|
|
269
|
+
.map((flow) => `Process${upperFirst(flow.flowTag)}HdrSqs`),
|
|
270
|
+
...flows
|
|
271
|
+
.filter(
|
|
272
|
+
(flow) =>
|
|
273
|
+
flow?.outputTopic &&
|
|
274
|
+
!flow?.generatedCodeConfig &&
|
|
275
|
+
upperFirst(flow.flowTag)
|
|
276
|
+
)
|
|
277
|
+
.map((flow) => `${upperFirst(flow.flowTag)}CompleteHdrSqs`)
|
|
278
|
+
];
|
|
279
|
+
for (const { flowTag, stepName } of flowExtTopicSteps(flows)) {
|
|
280
|
+
customSqsQueues.push(`${flowTag}${stepName}HdrSqs`);
|
|
281
|
+
}
|
|
282
|
+
for (const flow of flows) {
|
|
283
|
+
if (flowHasRbac(flow, objects)) {
|
|
284
|
+
const tag = upperFirst(flow.flowTag);
|
|
285
|
+
customSqsQueues.push(`${tag}RbacCallbackHdrSqs`);
|
|
223
286
|
}
|
|
224
287
|
}
|
|
288
|
+
for (const flow of flows.filter((flow) => includesEvent(flow, 's3'))) {
|
|
289
|
+
const tag = upperFirst(flow.flowTag);
|
|
290
|
+
customSqsQueues.push(`${tag}CreatePreSignUrlHdrSqs`);
|
|
291
|
+
customSqsQueues.push(`${tag}ReservedLimitHdrSqs`);
|
|
292
|
+
customSqsQueues.push(`${tag}ConfirmAfterUploadHdrSqs`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const customDsqQueues = flows
|
|
296
|
+
.filter((flow) => includesEvent(flow, 'dsq'))
|
|
297
|
+
.map((flow) => `${upperFirst(flow.flowTag)}HdrDsq`);
|
|
298
|
+
for (const { flowTag, stepName } of flowDsqSteps(flows)) {
|
|
299
|
+
customDsqQueues.push(`${flowTag}${stepName}HdrDsq`);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const websocket = hasSystemWebSocket(flows, {
|
|
303
|
+
includeRelationshipOwnTopic: true,
|
|
304
|
+
objects,
|
|
305
|
+
relationships
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const systemOwnTopics = ['ProcessLogical', 'FindData'];
|
|
309
|
+
const systemSqsQueues = [
|
|
310
|
+
'PaginateProcessLogicalHdrSqs',
|
|
311
|
+
...(websocket
|
|
312
|
+
? ['WebSocketCompleteHdrSqs', 'RegisterCompleteHdrSqs']
|
|
313
|
+
: [])
|
|
314
|
+
];
|
|
315
|
+
const systemDsqQueues = ['PaginateProcessLogicalHdrDsq'];
|
|
316
|
+
|
|
317
|
+
const ownTopics = new Set([
|
|
318
|
+
...systemOwnTopics,
|
|
319
|
+
...crudOwnTopics,
|
|
320
|
+
...relationshipOwnTopics,
|
|
321
|
+
...rbacOwnTopics,
|
|
322
|
+
...customOwnTopics
|
|
323
|
+
]);
|
|
324
|
+
const sqsQueues = new Set([
|
|
325
|
+
...systemSqsQueues,
|
|
326
|
+
...crudSqsQueues,
|
|
327
|
+
...relationshipSqsQueues,
|
|
328
|
+
...rbacSqsQueues,
|
|
329
|
+
...customSqsQueues
|
|
330
|
+
]);
|
|
331
|
+
const dsqQueues = new Set([
|
|
332
|
+
...systemDsqQueues,
|
|
333
|
+
...relationshipDsqQueues,
|
|
334
|
+
...customDsqQueues
|
|
335
|
+
]);
|
|
336
|
+
|
|
225
337
|
const customRoles = [
|
|
226
338
|
...new Set([
|
|
227
339
|
...supportedCustomFlows(flows).map((flow) =>
|
|
@@ -236,12 +348,11 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
236
348
|
...flowExtTopicSteps(flows).map(({ flow }) =>
|
|
237
349
|
customFlowRoleName(flow.flowTag)
|
|
238
350
|
),
|
|
239
|
-
...flowDsqSteps(flows).map(({ flow }) =>
|
|
351
|
+
...flowDsqSteps(flows).map(({ flow }) =>
|
|
352
|
+
customFlowRoleName(flow.flowTag)
|
|
353
|
+
)
|
|
240
354
|
])
|
|
241
355
|
];
|
|
242
|
-
const websocket = hasSystemWebSocket(flows, {
|
|
243
|
-
includeRelationshipOwnTopic: true
|
|
244
|
-
});
|
|
245
356
|
const webSocketRoles = new Set();
|
|
246
357
|
if (websocket) {
|
|
247
358
|
webSocketRoles.add('WebSocketMainRole');
|
|
@@ -286,7 +397,8 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
286
397
|
.filter((flow) => includesEvent(flow, 's3'))
|
|
287
398
|
.map((flow) => {
|
|
288
399
|
const tag = upperFirst(flow.flowTag);
|
|
289
|
-
const outputTopicStr =
|
|
400
|
+
const outputTopicStr =
|
|
401
|
+
typeof flow.outputTopic === 'string' ? flow.outputTopic : null;
|
|
290
402
|
const topicName = outputTopicStr
|
|
291
403
|
? (outputTopicStr.startsWith('Out')
|
|
292
404
|
? outputTopicStr
|
|
@@ -301,7 +413,16 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
301
413
|
});
|
|
302
414
|
const systemTables = [...SYSTEM_TABLES];
|
|
303
415
|
if (rbac) {
|
|
304
|
-
systemTables.push(
|
|
416
|
+
systemTables.push(
|
|
417
|
+
'TargetRoles',
|
|
418
|
+
'RolePermissions',
|
|
419
|
+
'RoleUsers',
|
|
420
|
+
'UserRoles',
|
|
421
|
+
'RbacPermissionCaches',
|
|
422
|
+
'RoleLimit',
|
|
423
|
+
'RunningTotalUsage',
|
|
424
|
+
'RunningTotalReservedUsage'
|
|
425
|
+
);
|
|
305
426
|
}
|
|
306
427
|
if (s3FlowTags.length > 0) {
|
|
307
428
|
systemTables.push('ReservedDataMain');
|
|
@@ -315,6 +436,25 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
315
436
|
crud,
|
|
316
437
|
rbac,
|
|
317
438
|
crudActionPlans,
|
|
439
|
+
crudOwnTopics: [...new Set(crudOwnTopics)].filter(Boolean).sort(),
|
|
440
|
+
crudSqsQueues: [...new Set(crudSqsQueues)].filter(Boolean).sort(),
|
|
441
|
+
relationshipOwnTopics: [...new Set(relationshipOwnTopics)]
|
|
442
|
+
.filter(Boolean)
|
|
443
|
+
.sort(),
|
|
444
|
+
relationshipSqsQueues: [...new Set(relationshipSqsQueues)]
|
|
445
|
+
.filter(Boolean)
|
|
446
|
+
.sort(),
|
|
447
|
+
relationshipDsqQueues: [...new Set(relationshipDsqQueues)]
|
|
448
|
+
.filter(Boolean)
|
|
449
|
+
.sort(),
|
|
450
|
+
rbacOwnTopics: [...new Set(rbacOwnTopics)].filter(Boolean).sort(),
|
|
451
|
+
rbacSqsQueues: [...new Set(rbacSqsQueues)].filter(Boolean).sort(),
|
|
452
|
+
customOwnTopics: [...new Set(customOwnTopics)].filter(Boolean).sort(),
|
|
453
|
+
customSqsQueues: [...new Set(customSqsQueues)].filter(Boolean).sort(),
|
|
454
|
+
customDsqQueues: [...new Set(customDsqQueues)].filter(Boolean).sort(),
|
|
455
|
+
systemOwnTopics: [...new Set(systemOwnTopics)].filter(Boolean).sort(),
|
|
456
|
+
systemSqsQueues: [...new Set(systemSqsQueues)].filter(Boolean).sort(),
|
|
457
|
+
systemDsqQueues: [...new Set(systemDsqQueues)].filter(Boolean).sort(),
|
|
318
458
|
s3Subscriptions,
|
|
319
459
|
s3FlowTags,
|
|
320
460
|
hasHttpApi,
|
|
@@ -337,6 +477,9 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
337
477
|
flow.initiateBy === 'systemWithUser'))) &&
|
|
338
478
|
upperFirst(flow.flowTag) === topic
|
|
339
479
|
) ||
|
|
480
|
+
(objects.length > 0 &&
|
|
481
|
+
topic !== 'Get' &&
|
|
482
|
+
CRUD_ACTIONS.includes(topic)) ||
|
|
340
483
|
(relationships.length > 0 &&
|
|
341
484
|
topic !== 'GetRelationship' &&
|
|
342
485
|
RELATIONSHIP_ACTIONS.includes(topic))
|
|
@@ -396,35 +539,39 @@ async function renderS3(state) {
|
|
|
396
539
|
return `Resources:\n${indentYaml(chunks.join('\n'), 2)}`;
|
|
397
540
|
}
|
|
398
541
|
|
|
399
|
-
async function
|
|
542
|
+
async function renderResourceGroup({
|
|
543
|
+
ownTopics = [],
|
|
544
|
+
sqsQueues = [],
|
|
545
|
+
dsqQueues = [],
|
|
546
|
+
webSocketSubscriptions = [],
|
|
547
|
+
s3Subscriptions = []
|
|
548
|
+
}) {
|
|
549
|
+
const hasResources =
|
|
550
|
+
ownTopics.length > 0 ||
|
|
551
|
+
sqsQueues.length > 0 ||
|
|
552
|
+
dsqQueues.length > 0 ||
|
|
553
|
+
webSocketSubscriptions.length > 0 ||
|
|
554
|
+
s3Subscriptions.length > 0;
|
|
555
|
+
if (!hasResources) return '';
|
|
556
|
+
|
|
400
557
|
const chunks = await Promise.all([
|
|
401
|
-
...
|
|
558
|
+
...ownTopics.map((queueName) =>
|
|
402
559
|
render('ResourceYaml.ejs', { queueName })
|
|
403
560
|
),
|
|
404
|
-
...
|
|
561
|
+
...sqsQueues.map((queueName) =>
|
|
405
562
|
render('ResourceSqsYaml.ejs', { queueName })
|
|
406
563
|
),
|
|
407
|
-
...
|
|
564
|
+
...dsqQueues.map((queueName) =>
|
|
408
565
|
render('ResourceSqsYaml.ejs', { queueName })
|
|
409
|
-
)
|
|
410
|
-
...(state.websocket
|
|
411
|
-
? [
|
|
412
|
-
render('ResourceSqsYaml.ejs', {
|
|
413
|
-
queueName: 'WebSocketCompleteHdrSqs'
|
|
414
|
-
}),
|
|
415
|
-
render('ResourceSqsYaml.ejs', {
|
|
416
|
-
queueName: 'RegisterCompleteHdrSqs'
|
|
417
|
-
})
|
|
418
|
-
]
|
|
419
|
-
: [])
|
|
566
|
+
)
|
|
420
567
|
]);
|
|
421
|
-
const
|
|
422
|
-
|
|
568
|
+
const wsSubs = await Promise.all(
|
|
569
|
+
webSocketSubscriptions.map((topicName) =>
|
|
423
570
|
renderWebSocketSubscription(topicName)
|
|
424
571
|
)
|
|
425
572
|
);
|
|
426
|
-
const
|
|
427
|
-
|
|
573
|
+
const s3Subs = await Promise.all(
|
|
574
|
+
s3Subscriptions.map(
|
|
428
575
|
({ subscriptionName, topicName, queueName }) =>
|
|
429
576
|
render('S3Subscription_Yaml.ejs', {
|
|
430
577
|
subscriptionName,
|
|
@@ -434,16 +581,53 @@ async function renderInSqs(state) {
|
|
|
434
581
|
)
|
|
435
582
|
);
|
|
436
583
|
const parts = [chunks.join('\n')];
|
|
437
|
-
if (
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if (
|
|
441
|
-
parts.push(s3Subscriptions.join('\n'));
|
|
442
|
-
}
|
|
443
|
-
const body = parts.join('\n');
|
|
584
|
+
if (wsSubs.length > 0) parts.push(wsSubs.join('\n'));
|
|
585
|
+
if (s3Subs.length > 0) parts.push(s3Subs.join('\n'));
|
|
586
|
+
const body = parts.filter(Boolean).join('\n');
|
|
587
|
+
if (!body.trim()) return '';
|
|
444
588
|
return `Resources:\n${indentYaml(body, 2)}`;
|
|
445
589
|
}
|
|
446
590
|
|
|
591
|
+
async function renderCrudInSqs(state) {
|
|
592
|
+
return renderResourceGroup({
|
|
593
|
+
ownTopics: state.crudOwnTopics,
|
|
594
|
+
sqsQueues: state.crudSqsQueues
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
async function renderRelationshipInSqs(state) {
|
|
599
|
+
return renderResourceGroup({
|
|
600
|
+
ownTopics: state.relationshipOwnTopics,
|
|
601
|
+
sqsQueues: state.relationshipSqsQueues,
|
|
602
|
+
dsqQueues: state.relationshipDsqQueues
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
async function renderRbacInSqs(state) {
|
|
607
|
+
return renderResourceGroup({
|
|
608
|
+
ownTopics: state.rbacOwnTopics,
|
|
609
|
+
sqsQueues: state.rbacSqsQueues
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
async function renderCustomFlowInSqs(state) {
|
|
614
|
+
return renderResourceGroup({
|
|
615
|
+
ownTopics: state.customOwnTopics,
|
|
616
|
+
sqsQueues: state.customSqsQueues,
|
|
617
|
+
dsqQueues: state.customDsqQueues,
|
|
618
|
+
s3Subscriptions: state.s3Subscriptions
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
async function renderSystemInSqs(state) {
|
|
623
|
+
return renderResourceGroup({
|
|
624
|
+
ownTopics: state.systemOwnTopics,
|
|
625
|
+
sqsQueues: state.systemSqsQueues,
|
|
626
|
+
dsqQueues: state.systemDsqQueues,
|
|
627
|
+
webSocketSubscriptions: state.webSocketSubscriptions
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
|
|
447
631
|
async function renderOut(state) {
|
|
448
632
|
const body = (
|
|
449
633
|
await Promise.all(
|
|
@@ -517,7 +701,13 @@ function roleStatements(state, roleName) {
|
|
|
517
701
|
statements.push({
|
|
518
702
|
action: ['s3:GetObject'],
|
|
519
703
|
resource: [
|
|
520
|
-
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}
|
|
704
|
+
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}/*'
|
|
705
|
+
]
|
|
706
|
+
});
|
|
707
|
+
statements.push({
|
|
708
|
+
action: ['s3:ListBucket'],
|
|
709
|
+
resource: [
|
|
710
|
+
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}'
|
|
521
711
|
]
|
|
522
712
|
});
|
|
523
713
|
}
|
|
@@ -572,7 +762,17 @@ function roleTableNames(state, roleName) {
|
|
|
572
762
|
...state.objectTableNames,
|
|
573
763
|
'AwaitingMultipleSteps',
|
|
574
764
|
'AwaitingMultipleStepByPending',
|
|
575
|
-
'WebSocketTask'
|
|
765
|
+
'WebSocketTask',
|
|
766
|
+
...(state.rbac
|
|
767
|
+
? [
|
|
768
|
+
'TargetRoles',
|
|
769
|
+
'RoleUsers',
|
|
770
|
+
'UserRoles',
|
|
771
|
+
'RoleLimit',
|
|
772
|
+
'RunningTotalUsage',
|
|
773
|
+
'RunningTotalReservedUsage'
|
|
774
|
+
]
|
|
775
|
+
: [])
|
|
576
776
|
];
|
|
577
777
|
if (roleName === 'FlowRelationshipRole')
|
|
578
778
|
return [
|
|
@@ -611,7 +811,7 @@ function dynamoActionsForRole(roleName) {
|
|
|
611
811
|
return ['dynamodb:GetItem', 'dynamodb:Query', 'dynamodb:UpdateItem'];
|
|
612
812
|
if (roleName === 'WebSocketMainRole')
|
|
613
813
|
return ['dynamodb:DeleteItem', 'dynamodb:PutItem', 'dynamodb:Query'];
|
|
614
|
-
if (roleName === 'FlowRbacRole')
|
|
814
|
+
if (roleName === 'FlowRbacRole' || roleName === 'FlowObjectsRole')
|
|
615
815
|
return [...DYNAMO_ACTIONS, 'dynamodb:TransactWriteItems'];
|
|
616
816
|
return DYNAMO_ACTIONS;
|
|
617
817
|
}
|
|
@@ -638,6 +838,9 @@ function roleQueueNames(state, roleName) {
|
|
|
638
838
|
if (!plan.outputTopic) return [];
|
|
639
839
|
return [
|
|
640
840
|
`${action}HdrSqs`,
|
|
841
|
+
...(plan.hasCreateNodeCallback
|
|
842
|
+
? [`${action}NodeCallbackHdrSqs`]
|
|
843
|
+
: []),
|
|
641
844
|
...(plan.hasRbacCallback
|
|
642
845
|
? [`${action}RbacCallbackHdrSqs`]
|
|
643
846
|
: []),
|
|
@@ -677,6 +880,9 @@ function roleQueueNames(state, roleName) {
|
|
|
677
880
|
if (includesEvent(flow, 'dsq')) {
|
|
678
881
|
queueList.push(`${tag}HdrDsq`);
|
|
679
882
|
}
|
|
883
|
+
if (flowHasRbac(flow, state.objects)) {
|
|
884
|
+
queueList.push(`${tag}RbacCallbackHdrSqs`);
|
|
885
|
+
}
|
|
680
886
|
queueList.push(
|
|
681
887
|
...flowExtTopicSteps([flow]).map(
|
|
682
888
|
({ flowTag, stepName }) => `${flowTag}${stepName}HdrSqs`
|
|
@@ -708,21 +914,58 @@ function roleDlqQueueNames(state, roleName) {
|
|
|
708
914
|
|
|
709
915
|
function roleTopicNames(state, roleName) {
|
|
710
916
|
if (roleName === 'ProcFindDataRole')
|
|
711
|
-
return state.outTopics.filter((topic) => topic === 'FindData');
|
|
712
|
-
if (roleName === 'FlowObjectsRole')
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
917
|
+
return state.outTopics.filter((topic) => topic === 'FindData').map((t) => `${t}_Out`);
|
|
918
|
+
if (roleName === 'FlowObjectsRole') {
|
|
919
|
+
const actions = state.outTopics.filter((topic) => CRUD_ACTIONS.includes(topic));
|
|
920
|
+
const topics = [];
|
|
921
|
+
for (const action of actions) {
|
|
922
|
+
if (action === 'Get') {
|
|
923
|
+
topics.push(`${action}_Out`);
|
|
924
|
+
} else {
|
|
925
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return topics;
|
|
929
|
+
}
|
|
930
|
+
if (roleName === 'FlowRelationshipRole') {
|
|
931
|
+
const actions = state.outTopics.filter((topic) => RELATIONSHIP_ACTIONS.includes(topic));
|
|
932
|
+
const topics = [];
|
|
933
|
+
for (const action of actions) {
|
|
934
|
+
if (action === 'GetRelationship') {
|
|
935
|
+
topics.push(`${action}_Out`);
|
|
936
|
+
} else {
|
|
937
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
return topics;
|
|
941
|
+
}
|
|
942
|
+
if (roleName === 'FlowRbacRole') {
|
|
943
|
+
const actions = state.outTopics.filter((topic) => RBAC_ACTIONS.includes(topic));
|
|
944
|
+
const topics = [];
|
|
945
|
+
for (const action of actions) {
|
|
946
|
+
if (action.startsWith('List')) {
|
|
947
|
+
topics.push(`${action}_Out`);
|
|
948
|
+
} else {
|
|
949
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
return topics;
|
|
953
|
+
}
|
|
720
954
|
const flow = state.flows.find(
|
|
721
955
|
(candidate) => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
722
956
|
);
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
957
|
+
if (flow && flow.flowTag) {
|
|
958
|
+
const name = upperFirst(flow.flowTag);
|
|
959
|
+
const topics = [];
|
|
960
|
+
if (state.outTopics.includes(name)) {
|
|
961
|
+
topics.push(`${name}_Out`);
|
|
962
|
+
}
|
|
963
|
+
if (includesEvent(flow, 'ownTopic')) {
|
|
964
|
+
topics.push(`${name}_In`);
|
|
965
|
+
}
|
|
966
|
+
return topics;
|
|
967
|
+
}
|
|
968
|
+
return [];
|
|
726
969
|
}
|
|
727
970
|
|
|
728
971
|
function dynamoArns(tableNames) {
|
|
@@ -794,7 +1037,7 @@ function topicArns(topicNames) {
|
|
|
794
1037
|
.sort()
|
|
795
1038
|
.map(
|
|
796
1039
|
(topic) =>
|
|
797
|
-
`arn:aws:sns:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_serviceTag}'}_${'${self:custom.iz_stage}'}_${topic}
|
|
1040
|
+
`arn:aws:sns:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_serviceTag}'}_${'${self:custom.iz_stage}'}_${topic}`
|
|
798
1041
|
);
|
|
799
1042
|
}
|
|
800
1043
|
|
|
@@ -903,7 +1146,7 @@ function keyName(identifier) {
|
|
|
903
1146
|
const VALID_CRUD_GENERATED_BY = new Set([
|
|
904
1147
|
'user',
|
|
905
1148
|
'systemWithUser',
|
|
906
|
-
'
|
|
1149
|
+
'systemNoUser'
|
|
907
1150
|
]);
|
|
908
1151
|
|
|
909
1152
|
function isCrudObject(object) {
|
|
@@ -56,7 +56,9 @@ export function generatedLambdaRole() {
|
|
|
56
56
|
Effect: 'Allow',
|
|
57
57
|
Action: ['sns:Publish'],
|
|
58
58
|
Resource: [
|
|
59
|
-
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', 'Rbac')}
|
|
59
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', 'Rbac')}`,
|
|
60
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ConfirmUsage_In', 'Rbac')}`,
|
|
61
|
+
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'CancelUsage_In', 'Rbac')}`<% (rbacValidatorServiceTags || []).forEach(function(tag) { %>,
|
|
60
62
|
`arn:aws:sns:${process.env.iz_region}:${process.env.iz_accountId}:${snsSharedLib.snsTopicNameByFlowSchema(_izContext, 'ValidatorRbac_In', '<%= tag %>')}`<% }); %>
|
|
61
63
|
]
|
|
62
64
|
}<% } %>
|