@izara_project/izara-core-generate-service-code 1.0.83 → 1.0.84
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 +29 -1
- package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +16 -3
- package/src/emit/crud/crudActionPlan.js +38 -5
- package/src/emit/crud/emitCrudApplicationArtifacts.js +19 -4
- package/src/emit/crud/emitDynamicCrudFlowSchemas.js +27 -6
- 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/CreateEndpoint_Main.ejs +50 -19
- package/src/emit/crud/templates/CreateLogicalLib.ejs +73 -8
- 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 +2 -2
- package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -0
- package/src/emit/crud/templates/FlowMain_Wbs.ejs +1 -1
- 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 +103 -0
- package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +71 -0
- package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +49 -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 +147 -0
- package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +59 -23
- package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +1 -1
- package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
- package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +4 -4
- package/src/emit/resource/emitResourceArtifacts.js +342 -108
- package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +53 -2
- 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 +7 -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 +91 -4
- package/test/dynamicRbacFlowSchemas.test.js +15 -2
- package/test/publicApi.test.js +6 -6
- package/test/resourceArtifacts.test.js +68 -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,34 @@ 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
218
|
if (plan.hasComplete) {
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
if (plan.hasRbacCallback) {
|
|
200
|
-
sqsQueues.add(`${action}RbacCallbackHdrSqs`);
|
|
219
|
+
crudSqsQueues.push(`${action}CompleteHdrSqs`);
|
|
201
220
|
}
|
|
202
221
|
}
|
|
203
222
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
223
|
+
|
|
224
|
+
const relationshipOwnTopics = relationships.length > 0
|
|
225
|
+
? [...RELATIONSHIP_ACTIONS]
|
|
226
|
+
: [];
|
|
227
|
+
const relationshipSqsQueues = relationships.length > 0
|
|
228
|
+
? RELATIONSHIP_ACTIONS.map((action) => `${action}CompleteHdrSqs`)
|
|
229
|
+
: [];
|
|
230
|
+
const relationshipDsqQueues = relationships.length > 0
|
|
231
|
+
? ['GetRelationshipHdrDsq']
|
|
232
|
+
: [];
|
|
233
|
+
|
|
234
|
+
const rbacOwnTopics = [];
|
|
235
|
+
const rbacSqsQueues = [];
|
|
211
236
|
if (selfRbac) {
|
|
212
237
|
for (const action of RBAC_ACTIONS) {
|
|
213
|
-
|
|
214
|
-
|
|
238
|
+
rbacOwnTopics.push(action);
|
|
239
|
+
rbacSqsQueues.push(`Process${action}HdrSqs`);
|
|
215
240
|
}
|
|
216
241
|
}
|
|
217
242
|
if (rbac) {
|
|
@@ -219,9 +244,93 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
219
244
|
...new Set(objects.filter(hasRbacAddOn).map(rbacFlowTag))
|
|
220
245
|
];
|
|
221
246
|
for (const flowTag of flowTags) {
|
|
222
|
-
|
|
247
|
+
rbacOwnTopics.push(flowTag);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (crud) {
|
|
251
|
+
for (const action of ['Create', 'Update', 'Delete']) {
|
|
252
|
+
const plan = crudActionPlans[action];
|
|
253
|
+
if (plan.hasRbacCallback) {
|
|
254
|
+
rbacSqsQueues.push(`${action}RbacCallbackHdrSqs`);
|
|
255
|
+
}
|
|
223
256
|
}
|
|
224
257
|
}
|
|
258
|
+
|
|
259
|
+
const customOwnTopics = flows
|
|
260
|
+
.filter((flow) => includesEvent(flow, 'ownTopic'))
|
|
261
|
+
.map((flow) => upperFirst(flow.flowTag));
|
|
262
|
+
|
|
263
|
+
const customSqsQueues = [
|
|
264
|
+
...flows
|
|
265
|
+
.filter((flow) => includesEvent(flow, 'extTopic'))
|
|
266
|
+
.map((flow) => `Process${upperFirst(flow.flowTag)}HdrSqs`),
|
|
267
|
+
...flows
|
|
268
|
+
.filter(
|
|
269
|
+
(flow) =>
|
|
270
|
+
flow?.outputTopic &&
|
|
271
|
+
!flow?.generatedCodeConfig &&
|
|
272
|
+
upperFirst(flow.flowTag)
|
|
273
|
+
)
|
|
274
|
+
.map((flow) => `${upperFirst(flow.flowTag)}CompleteHdrSqs`)
|
|
275
|
+
];
|
|
276
|
+
for (const { flowTag, stepName } of flowExtTopicSteps(flows)) {
|
|
277
|
+
customSqsQueues.push(`${flowTag}${stepName}HdrSqs`);
|
|
278
|
+
}
|
|
279
|
+
for (const flow of flows) {
|
|
280
|
+
if (flowHasRbac(flow, objects)) {
|
|
281
|
+
const tag = upperFirst(flow.flowTag);
|
|
282
|
+
customSqsQueues.push(`${tag}RbacCallbackHdrSqs`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
for (const flow of flows.filter((flow) => includesEvent(flow, 's3'))) {
|
|
286
|
+
const tag = upperFirst(flow.flowTag);
|
|
287
|
+
customSqsQueues.push(`${tag}CreatePreSignUrlHdrSqs`);
|
|
288
|
+
customSqsQueues.push(`${tag}ReservedLimitHdrSqs`);
|
|
289
|
+
customSqsQueues.push(`${tag}ConfirmAfterUploadHdrSqs`);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const customDsqQueues = flows
|
|
293
|
+
.filter((flow) => includesEvent(flow, 'dsq'))
|
|
294
|
+
.map((flow) => `${upperFirst(flow.flowTag)}HdrDsq`);
|
|
295
|
+
for (const { flowTag, stepName } of flowDsqSteps(flows)) {
|
|
296
|
+
customDsqQueues.push(`${flowTag}${stepName}HdrDsq`);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const websocket = hasSystemWebSocket(flows, {
|
|
300
|
+
includeRelationshipOwnTopic: true,
|
|
301
|
+
objects,
|
|
302
|
+
relationships
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const systemOwnTopics = ['ProcessLogical', 'FindData'];
|
|
306
|
+
const systemSqsQueues = [
|
|
307
|
+
'PaginateProcessLogicalHdrSqs',
|
|
308
|
+
...(websocket
|
|
309
|
+
? ['WebSocketCompleteHdrSqs', 'RegisterCompleteHdrSqs']
|
|
310
|
+
: [])
|
|
311
|
+
];
|
|
312
|
+
const systemDsqQueues = ['PaginateProcessLogicalHdrDsq'];
|
|
313
|
+
|
|
314
|
+
const ownTopics = new Set([
|
|
315
|
+
...systemOwnTopics,
|
|
316
|
+
...crudOwnTopics,
|
|
317
|
+
...relationshipOwnTopics,
|
|
318
|
+
...rbacOwnTopics,
|
|
319
|
+
...customOwnTopics
|
|
320
|
+
]);
|
|
321
|
+
const sqsQueues = new Set([
|
|
322
|
+
...systemSqsQueues,
|
|
323
|
+
...crudSqsQueues,
|
|
324
|
+
...relationshipSqsQueues,
|
|
325
|
+
...rbacSqsQueues,
|
|
326
|
+
...customSqsQueues
|
|
327
|
+
]);
|
|
328
|
+
const dsqQueues = new Set([
|
|
329
|
+
...systemDsqQueues,
|
|
330
|
+
...relationshipDsqQueues,
|
|
331
|
+
...customDsqQueues
|
|
332
|
+
]);
|
|
333
|
+
|
|
225
334
|
const customRoles = [
|
|
226
335
|
...new Set([
|
|
227
336
|
...supportedCustomFlows(flows).map((flow) =>
|
|
@@ -236,12 +345,11 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
236
345
|
...flowExtTopicSteps(flows).map(({ flow }) =>
|
|
237
346
|
customFlowRoleName(flow.flowTag)
|
|
238
347
|
),
|
|
239
|
-
...flowDsqSteps(flows).map(({ flow }) =>
|
|
348
|
+
...flowDsqSteps(flows).map(({ flow }) =>
|
|
349
|
+
customFlowRoleName(flow.flowTag)
|
|
350
|
+
)
|
|
240
351
|
])
|
|
241
352
|
];
|
|
242
|
-
const websocket = hasSystemWebSocket(flows, {
|
|
243
|
-
includeRelationshipOwnTopic: true
|
|
244
|
-
});
|
|
245
353
|
const webSocketRoles = new Set();
|
|
246
354
|
if (websocket) {
|
|
247
355
|
webSocketRoles.add('WebSocketMainRole');
|
|
@@ -286,7 +394,8 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
286
394
|
.filter((flow) => includesEvent(flow, 's3'))
|
|
287
395
|
.map((flow) => {
|
|
288
396
|
const tag = upperFirst(flow.flowTag);
|
|
289
|
-
const outputTopicStr =
|
|
397
|
+
const outputTopicStr =
|
|
398
|
+
typeof flow.outputTopic === 'string' ? flow.outputTopic : null;
|
|
290
399
|
const topicName = outputTopicStr
|
|
291
400
|
? (outputTopicStr.startsWith('Out')
|
|
292
401
|
? outputTopicStr
|
|
@@ -301,7 +410,16 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
301
410
|
});
|
|
302
411
|
const systemTables = [...SYSTEM_TABLES];
|
|
303
412
|
if (rbac) {
|
|
304
|
-
systemTables.push(
|
|
413
|
+
systemTables.push(
|
|
414
|
+
'TargetRoles',
|
|
415
|
+
'RolePermissions',
|
|
416
|
+
'RoleUsers',
|
|
417
|
+
'UserRoles',
|
|
418
|
+
'RbacPermissionCaches',
|
|
419
|
+
'RoleLimit',
|
|
420
|
+
'RunningTotalUsage',
|
|
421
|
+
'RunningTotalReservedUsage'
|
|
422
|
+
);
|
|
305
423
|
}
|
|
306
424
|
if (s3FlowTags.length > 0) {
|
|
307
425
|
systemTables.push('ReservedDataMain');
|
|
@@ -315,6 +433,25 @@ function createResourceState({ objects, relationships, flows }) {
|
|
|
315
433
|
crud,
|
|
316
434
|
rbac,
|
|
317
435
|
crudActionPlans,
|
|
436
|
+
crudOwnTopics: [...new Set(crudOwnTopics)].filter(Boolean).sort(),
|
|
437
|
+
crudSqsQueues: [...new Set(crudSqsQueues)].filter(Boolean).sort(),
|
|
438
|
+
relationshipOwnTopics: [...new Set(relationshipOwnTopics)]
|
|
439
|
+
.filter(Boolean)
|
|
440
|
+
.sort(),
|
|
441
|
+
relationshipSqsQueues: [...new Set(relationshipSqsQueues)]
|
|
442
|
+
.filter(Boolean)
|
|
443
|
+
.sort(),
|
|
444
|
+
relationshipDsqQueues: [...new Set(relationshipDsqQueues)]
|
|
445
|
+
.filter(Boolean)
|
|
446
|
+
.sort(),
|
|
447
|
+
rbacOwnTopics: [...new Set(rbacOwnTopics)].filter(Boolean).sort(),
|
|
448
|
+
rbacSqsQueues: [...new Set(rbacSqsQueues)].filter(Boolean).sort(),
|
|
449
|
+
customOwnTopics: [...new Set(customOwnTopics)].filter(Boolean).sort(),
|
|
450
|
+
customSqsQueues: [...new Set(customSqsQueues)].filter(Boolean).sort(),
|
|
451
|
+
customDsqQueues: [...new Set(customDsqQueues)].filter(Boolean).sort(),
|
|
452
|
+
systemOwnTopics: [...new Set(systemOwnTopics)].filter(Boolean).sort(),
|
|
453
|
+
systemSqsQueues: [...new Set(systemSqsQueues)].filter(Boolean).sort(),
|
|
454
|
+
systemDsqQueues: [...new Set(systemDsqQueues)].filter(Boolean).sort(),
|
|
318
455
|
s3Subscriptions,
|
|
319
456
|
s3FlowTags,
|
|
320
457
|
hasHttpApi,
|
|
@@ -396,35 +533,39 @@ async function renderS3(state) {
|
|
|
396
533
|
return `Resources:\n${indentYaml(chunks.join('\n'), 2)}`;
|
|
397
534
|
}
|
|
398
535
|
|
|
399
|
-
async function
|
|
536
|
+
async function renderResourceGroup({
|
|
537
|
+
ownTopics = [],
|
|
538
|
+
sqsQueues = [],
|
|
539
|
+
dsqQueues = [],
|
|
540
|
+
webSocketSubscriptions = [],
|
|
541
|
+
s3Subscriptions = []
|
|
542
|
+
}) {
|
|
543
|
+
const hasResources =
|
|
544
|
+
ownTopics.length > 0 ||
|
|
545
|
+
sqsQueues.length > 0 ||
|
|
546
|
+
dsqQueues.length > 0 ||
|
|
547
|
+
webSocketSubscriptions.length > 0 ||
|
|
548
|
+
s3Subscriptions.length > 0;
|
|
549
|
+
if (!hasResources) return '';
|
|
550
|
+
|
|
400
551
|
const chunks = await Promise.all([
|
|
401
|
-
...
|
|
552
|
+
...ownTopics.map((queueName) =>
|
|
402
553
|
render('ResourceYaml.ejs', { queueName })
|
|
403
554
|
),
|
|
404
|
-
...
|
|
555
|
+
...sqsQueues.map((queueName) =>
|
|
405
556
|
render('ResourceSqsYaml.ejs', { queueName })
|
|
406
557
|
),
|
|
407
|
-
...
|
|
558
|
+
...dsqQueues.map((queueName) =>
|
|
408
559
|
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
|
-
: [])
|
|
560
|
+
)
|
|
420
561
|
]);
|
|
421
|
-
const
|
|
422
|
-
|
|
562
|
+
const wsSubs = await Promise.all(
|
|
563
|
+
webSocketSubscriptions.map((topicName) =>
|
|
423
564
|
renderWebSocketSubscription(topicName)
|
|
424
565
|
)
|
|
425
566
|
);
|
|
426
|
-
const
|
|
427
|
-
|
|
567
|
+
const s3Subs = await Promise.all(
|
|
568
|
+
s3Subscriptions.map(
|
|
428
569
|
({ subscriptionName, topicName, queueName }) =>
|
|
429
570
|
render('S3Subscription_Yaml.ejs', {
|
|
430
571
|
subscriptionName,
|
|
@@ -434,16 +575,53 @@ async function renderInSqs(state) {
|
|
|
434
575
|
)
|
|
435
576
|
);
|
|
436
577
|
const parts = [chunks.join('\n')];
|
|
437
|
-
if (
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if (
|
|
441
|
-
parts.push(s3Subscriptions.join('\n'));
|
|
442
|
-
}
|
|
443
|
-
const body = parts.join('\n');
|
|
578
|
+
if (wsSubs.length > 0) parts.push(wsSubs.join('\n'));
|
|
579
|
+
if (s3Subs.length > 0) parts.push(s3Subs.join('\n'));
|
|
580
|
+
const body = parts.filter(Boolean).join('\n');
|
|
581
|
+
if (!body.trim()) return '';
|
|
444
582
|
return `Resources:\n${indentYaml(body, 2)}`;
|
|
445
583
|
}
|
|
446
584
|
|
|
585
|
+
async function renderCrudInSqs(state) {
|
|
586
|
+
return renderResourceGroup({
|
|
587
|
+
ownTopics: state.crudOwnTopics,
|
|
588
|
+
sqsQueues: state.crudSqsQueues
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
async function renderRelationshipInSqs(state) {
|
|
593
|
+
return renderResourceGroup({
|
|
594
|
+
ownTopics: state.relationshipOwnTopics,
|
|
595
|
+
sqsQueues: state.relationshipSqsQueues,
|
|
596
|
+
dsqQueues: state.relationshipDsqQueues
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
async function renderRbacInSqs(state) {
|
|
601
|
+
return renderResourceGroup({
|
|
602
|
+
ownTopics: state.rbacOwnTopics,
|
|
603
|
+
sqsQueues: state.rbacSqsQueues
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
async function renderCustomFlowInSqs(state) {
|
|
608
|
+
return renderResourceGroup({
|
|
609
|
+
ownTopics: state.customOwnTopics,
|
|
610
|
+
sqsQueues: state.customSqsQueues,
|
|
611
|
+
dsqQueues: state.customDsqQueues,
|
|
612
|
+
s3Subscriptions: state.s3Subscriptions
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
async function renderSystemInSqs(state) {
|
|
617
|
+
return renderResourceGroup({
|
|
618
|
+
ownTopics: state.systemOwnTopics,
|
|
619
|
+
sqsQueues: state.systemSqsQueues,
|
|
620
|
+
dsqQueues: state.systemDsqQueues,
|
|
621
|
+
webSocketSubscriptions: state.webSocketSubscriptions
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
|
|
447
625
|
async function renderOut(state) {
|
|
448
626
|
const body = (
|
|
449
627
|
await Promise.all(
|
|
@@ -517,7 +695,13 @@ function roleStatements(state, roleName) {
|
|
|
517
695
|
statements.push({
|
|
518
696
|
action: ['s3:GetObject'],
|
|
519
697
|
resource: [
|
|
520
|
-
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}
|
|
698
|
+
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}/*'
|
|
699
|
+
]
|
|
700
|
+
});
|
|
701
|
+
statements.push({
|
|
702
|
+
action: ['s3:ListBucket'],
|
|
703
|
+
resource: [
|
|
704
|
+
'arn:aws:s3:::${self:custom.iz_serviceSchemaBucketName}'
|
|
521
705
|
]
|
|
522
706
|
});
|
|
523
707
|
}
|
|
@@ -572,7 +756,17 @@ function roleTableNames(state, roleName) {
|
|
|
572
756
|
...state.objectTableNames,
|
|
573
757
|
'AwaitingMultipleSteps',
|
|
574
758
|
'AwaitingMultipleStepByPending',
|
|
575
|
-
'WebSocketTask'
|
|
759
|
+
'WebSocketTask',
|
|
760
|
+
...(state.rbac
|
|
761
|
+
? [
|
|
762
|
+
'TargetRoles',
|
|
763
|
+
'RoleUsers',
|
|
764
|
+
'UserRoles',
|
|
765
|
+
'RoleLimit',
|
|
766
|
+
'RunningTotalUsage',
|
|
767
|
+
'RunningTotalReservedUsage'
|
|
768
|
+
]
|
|
769
|
+
: [])
|
|
576
770
|
];
|
|
577
771
|
if (roleName === 'FlowRelationshipRole')
|
|
578
772
|
return [
|
|
@@ -611,7 +805,7 @@ function dynamoActionsForRole(roleName) {
|
|
|
611
805
|
return ['dynamodb:GetItem', 'dynamodb:Query', 'dynamodb:UpdateItem'];
|
|
612
806
|
if (roleName === 'WebSocketMainRole')
|
|
613
807
|
return ['dynamodb:DeleteItem', 'dynamodb:PutItem', 'dynamodb:Query'];
|
|
614
|
-
if (roleName === 'FlowRbacRole')
|
|
808
|
+
if (roleName === 'FlowRbacRole' || roleName === 'FlowObjectsRole')
|
|
615
809
|
return [...DYNAMO_ACTIONS, 'dynamodb:TransactWriteItems'];
|
|
616
810
|
return DYNAMO_ACTIONS;
|
|
617
811
|
}
|
|
@@ -677,6 +871,9 @@ function roleQueueNames(state, roleName) {
|
|
|
677
871
|
if (includesEvent(flow, 'dsq')) {
|
|
678
872
|
queueList.push(`${tag}HdrDsq`);
|
|
679
873
|
}
|
|
874
|
+
if (flowHasRbac(flow, state.objects)) {
|
|
875
|
+
queueList.push(`${tag}RbacCallbackHdrSqs`);
|
|
876
|
+
}
|
|
680
877
|
queueList.push(
|
|
681
878
|
...flowExtTopicSteps([flow]).map(
|
|
682
879
|
({ flowTag, stepName }) => `${flowTag}${stepName}HdrSqs`
|
|
@@ -708,21 +905,58 @@ function roleDlqQueueNames(state, roleName) {
|
|
|
708
905
|
|
|
709
906
|
function roleTopicNames(state, roleName) {
|
|
710
907
|
if (roleName === 'ProcFindDataRole')
|
|
711
|
-
return state.outTopics.filter((topic) => topic === 'FindData');
|
|
712
|
-
if (roleName === 'FlowObjectsRole')
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
908
|
+
return state.outTopics.filter((topic) => topic === 'FindData').map((t) => `${t}_Out`);
|
|
909
|
+
if (roleName === 'FlowObjectsRole') {
|
|
910
|
+
const actions = state.outTopics.filter((topic) => CRUD_ACTIONS.includes(topic));
|
|
911
|
+
const topics = [];
|
|
912
|
+
for (const action of actions) {
|
|
913
|
+
if (action === 'Get') {
|
|
914
|
+
topics.push(`${action}_Out`);
|
|
915
|
+
} else {
|
|
916
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return topics;
|
|
920
|
+
}
|
|
921
|
+
if (roleName === 'FlowRelationshipRole') {
|
|
922
|
+
const actions = state.outTopics.filter((topic) => RELATIONSHIP_ACTIONS.includes(topic));
|
|
923
|
+
const topics = [];
|
|
924
|
+
for (const action of actions) {
|
|
925
|
+
if (action === 'GetRelationship') {
|
|
926
|
+
topics.push(`${action}_Out`);
|
|
927
|
+
} else {
|
|
928
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return topics;
|
|
932
|
+
}
|
|
933
|
+
if (roleName === 'FlowRbacRole') {
|
|
934
|
+
const actions = state.outTopics.filter((topic) => RBAC_ACTIONS.includes(topic));
|
|
935
|
+
const topics = [];
|
|
936
|
+
for (const action of actions) {
|
|
937
|
+
if (action.startsWith('List')) {
|
|
938
|
+
topics.push(`${action}_Out`);
|
|
939
|
+
} else {
|
|
940
|
+
topics.push(`${action}_In`, `${action}_Out`);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
return topics;
|
|
944
|
+
}
|
|
720
945
|
const flow = state.flows.find(
|
|
721
946
|
(candidate) => customFlowRoleName(candidate?.flowTag ?? '') === roleName
|
|
722
947
|
);
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
948
|
+
if (flow && flow.flowTag) {
|
|
949
|
+
const name = upperFirst(flow.flowTag);
|
|
950
|
+
const topics = [];
|
|
951
|
+
if (state.outTopics.includes(name)) {
|
|
952
|
+
topics.push(`${name}_Out`);
|
|
953
|
+
}
|
|
954
|
+
if (includesEvent(flow, 'ownTopic')) {
|
|
955
|
+
topics.push(`${name}_In`);
|
|
956
|
+
}
|
|
957
|
+
return topics;
|
|
958
|
+
}
|
|
959
|
+
return [];
|
|
726
960
|
}
|
|
727
961
|
|
|
728
962
|
function dynamoArns(tableNames) {
|
|
@@ -794,7 +1028,7 @@ function topicArns(topicNames) {
|
|
|
794
1028
|
.sort()
|
|
795
1029
|
.map(
|
|
796
1030
|
(topic) =>
|
|
797
|
-
`arn:aws:sns:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_serviceTag}'}_${'${self:custom.iz_stage}'}_${topic}
|
|
1031
|
+
`arn:aws:sns:${'${self:custom.iz_region}'}:${'${self:custom.iz_accountId}'}:${'${self:custom.iz_serviceTag}'}_${'${self:custom.iz_stage}'}_${topic}`
|
|
798
1032
|
);
|
|
799
1033
|
}
|
|
800
1034
|
|
|
@@ -903,7 +1137,7 @@ function keyName(identifier) {
|
|
|
903
1137
|
const VALID_CRUD_GENERATED_BY = new Set([
|
|
904
1138
|
'user',
|
|
905
1139
|
'systemWithUser',
|
|
906
|
-
'
|
|
1140
|
+
'systemNoUser'
|
|
907
1141
|
]);
|
|
908
1142
|
|
|
909
1143
|
function isCrudObject(object) {
|
|
@@ -144,12 +144,12 @@ Resources:
|
|
|
144
144
|
TableName: ${self:custom.iz_resourcePrefix}TargetRoles
|
|
145
145
|
BillingMode: PAY_PER_REQUEST
|
|
146
146
|
AttributeDefinitions:
|
|
147
|
-
- AttributeName:
|
|
147
|
+
- AttributeName: identifiersConcat
|
|
148
148
|
AttributeType: S
|
|
149
149
|
- AttributeName: roleIdKey
|
|
150
150
|
AttributeType: S
|
|
151
151
|
KeySchema:
|
|
152
|
-
- AttributeName:
|
|
152
|
+
- AttributeName: identifiersConcat
|
|
153
153
|
KeyType: HASH
|
|
154
154
|
- AttributeName: roleIdKey
|
|
155
155
|
KeyType: RANGE
|
|
@@ -220,6 +220,57 @@ Resources:
|
|
|
220
220
|
TimeToLiveSpecification:
|
|
221
221
|
AttributeName: ttlTimestamp
|
|
222
222
|
Enabled: true
|
|
223
|
+
|
|
224
|
+
RoleLimitTable:
|
|
225
|
+
Type: 'AWS::DynamoDB::Table'
|
|
226
|
+
Properties:
|
|
227
|
+
TableName: ${self:custom.iz_resourcePrefix}RoleLimit
|
|
228
|
+
BillingMode: PAY_PER_REQUEST
|
|
229
|
+
AttributeDefinitions:
|
|
230
|
+
- AttributeName: roleLimitId
|
|
231
|
+
AttributeType: S
|
|
232
|
+
- AttributeName: limitType
|
|
233
|
+
AttributeType: S
|
|
234
|
+
KeySchema:
|
|
235
|
+
- AttributeName: roleLimitId
|
|
236
|
+
KeyType: HASH
|
|
237
|
+
- AttributeName: limitType
|
|
238
|
+
KeyType: RANGE
|
|
239
|
+
|
|
240
|
+
RunningTotalUsageTable:
|
|
241
|
+
Type: 'AWS::DynamoDB::Table'
|
|
242
|
+
Properties:
|
|
243
|
+
TableName: ${self:custom.iz_resourcePrefix}RunningTotalUsage
|
|
244
|
+
BillingMode: PAY_PER_REQUEST
|
|
245
|
+
AttributeDefinitions:
|
|
246
|
+
- AttributeName: identifiersConcat
|
|
247
|
+
AttributeType: S
|
|
248
|
+
- AttributeName: limitTag
|
|
249
|
+
AttributeType: S
|
|
250
|
+
KeySchema:
|
|
251
|
+
- AttributeName: identifiersConcat
|
|
252
|
+
KeyType: HASH
|
|
253
|
+
- AttributeName: limitTag
|
|
254
|
+
KeyType: RANGE
|
|
255
|
+
|
|
256
|
+
RunningTotalReservedUsageTable:
|
|
257
|
+
Type: 'AWS::DynamoDB::Table'
|
|
258
|
+
Properties:
|
|
259
|
+
TableName: ${self:custom.iz_resourcePrefix}RunningTotalReservedUsage
|
|
260
|
+
BillingMode: PAY_PER_REQUEST
|
|
261
|
+
AttributeDefinitions:
|
|
262
|
+
- AttributeName: runningTotalReservedId
|
|
263
|
+
AttributeType: S
|
|
264
|
+
- AttributeName: usedTimestampId
|
|
265
|
+
AttributeType: S
|
|
266
|
+
KeySchema:
|
|
267
|
+
- AttributeName: runningTotalReservedId
|
|
268
|
+
KeyType: HASH
|
|
269
|
+
- AttributeName: usedTimestampId
|
|
270
|
+
KeyType: RANGE
|
|
271
|
+
TimeToLiveSpecification:
|
|
272
|
+
AttributeName: ttlTimestamp
|
|
273
|
+
Enabled: true
|
|
223
274
|
<% } %>
|
|
224
275
|
<% if (hasS3) { %>
|
|
225
276
|
ReservedDataMainTable:
|