lambda-live-debugger 1.12.2 → 1.12.3
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.
|
Binary file
|
package/dist/infraDeploy.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { Configuration } from './configuration.mjs';
|
|
|
7
7
|
import { AwsCredentials } from './awsCredentials.mjs';
|
|
8
8
|
import { getModuleDirname } from './getDirname.mjs';
|
|
9
9
|
import { Logger } from './logger.mjs';
|
|
10
|
+
import { runWithConcurrency } from './utils/runWithConcurrency.mjs';
|
|
10
11
|
import * as crypto from 'crypto';
|
|
11
12
|
let lambdaClient;
|
|
12
13
|
let iamClient;
|
|
@@ -46,6 +47,9 @@ function getLambdaClient() {
|
|
|
46
47
|
profile: Configuration.config.profile,
|
|
47
48
|
role: Configuration.config.role,
|
|
48
49
|
}),
|
|
50
|
+
// client-side rate limiting and generous retries to avoid TooManyRequestsException
|
|
51
|
+
retryMode: 'adaptive',
|
|
52
|
+
maxAttempts: 10,
|
|
49
53
|
});
|
|
50
54
|
}
|
|
51
55
|
return lambdaClient;
|
|
@@ -63,6 +67,9 @@ function getIAMClient() {
|
|
|
63
67
|
profile: Configuration.config.profile,
|
|
64
68
|
role: Configuration.config.role,
|
|
65
69
|
}),
|
|
70
|
+
// client-side rate limiting and generous retries to avoid TooManyRequestsException
|
|
71
|
+
retryMode: 'adaptive',
|
|
72
|
+
maxAttempts: 10,
|
|
66
73
|
});
|
|
67
74
|
}
|
|
68
75
|
return iamClient;
|
|
@@ -321,10 +328,10 @@ async function applyAddingInfra(changes) {
|
|
|
321
328
|
Logger.verbose(`Using existing layer version: ${changes.existingLayerVersionArn}`);
|
|
322
329
|
layerVersionArn = changes.existingLayerVersionArn;
|
|
323
330
|
}
|
|
324
|
-
const
|
|
331
|
+
const tasks = [];
|
|
325
332
|
// Add LLD to functions
|
|
326
333
|
for (const lambdaData of changes.lambdasToAdd) {
|
|
327
|
-
|
|
334
|
+
tasks.push(() => addLayerToLambda({
|
|
328
335
|
...lambdaData,
|
|
329
336
|
layers: [
|
|
330
337
|
layerVersionArn,
|
|
@@ -335,17 +342,17 @@ async function applyAddingInfra(changes) {
|
|
|
335
342
|
}
|
|
336
343
|
// Remove LLD from filtered functions
|
|
337
344
|
for (const lambdaData of changes.lambdasToRemove) {
|
|
338
|
-
|
|
345
|
+
tasks.push(() => removeLayerFromLambda(lambdaData));
|
|
339
346
|
}
|
|
340
347
|
// Add policies to roles
|
|
341
348
|
for (const roleName of changes.rolesToAdd) {
|
|
342
|
-
|
|
349
|
+
tasks.push(() => addPolicyToRole(roleName));
|
|
343
350
|
}
|
|
344
351
|
// Remove policies from roles
|
|
345
352
|
for (const roleName of changes.rolesToRemove) {
|
|
346
|
-
|
|
353
|
+
tasks.push(() => removePolicyFromLambdaRole(roleName));
|
|
347
354
|
}
|
|
348
|
-
await
|
|
355
|
+
await runWithConcurrency(tasks);
|
|
349
356
|
}
|
|
350
357
|
/**
|
|
351
358
|
* Get the planned infrastructure changes including removal from filtered functions
|
|
@@ -356,29 +363,27 @@ async function getInfraChangesForAdding() {
|
|
|
356
363
|
const configLambdasAll = Configuration.getLambdasAll();
|
|
357
364
|
const configLambdasUpdate = configLambdasAll.filter((l) => !(l.filteredOut === true));
|
|
358
365
|
const configLambdasRemove = configLambdasAll.filter((l) => l.filteredOut === true);
|
|
359
|
-
const lambdasToUpdatePromise =
|
|
366
|
+
const lambdasToUpdatePromise = runWithConcurrency(configLambdasUpdate.map((func) => async () => {
|
|
360
367
|
const lambdaUpdate = await analyzeLambdaAdd(func.functionName, existingLayer?.LayerVersionArn);
|
|
361
368
|
return lambdaUpdate;
|
|
362
369
|
}));
|
|
363
|
-
const lambdasToRemovePromise =
|
|
364
|
-
return analyzeLambdaRemove(func.functionName);
|
|
365
|
-
}));
|
|
370
|
+
const lambdasToRemovePromise = runWithConcurrency(configLambdasRemove.map((func) => () => analyzeLambdaRemove(func.functionName)));
|
|
366
371
|
// Get all role names for lambdas to update, ensure uniqueness, then analyze
|
|
367
372
|
const roleNamesToAddSet = new Set();
|
|
368
|
-
const roleNamesToAddPromise =
|
|
373
|
+
const roleNamesToAddPromise = runWithConcurrency(configLambdasUpdate.map((func) => async () => {
|
|
369
374
|
const roleName = await getRoleNameFromFunction(func.functionName);
|
|
370
375
|
roleNamesToAddSet.add(roleName);
|
|
371
376
|
}));
|
|
372
377
|
// Get all role names for lambdas to remove, ensure uniqueness, then analyze
|
|
373
378
|
const roleNamesToRemoveSet = new Set();
|
|
374
|
-
const roleNamesToRemovePromise =
|
|
379
|
+
const roleNamesToRemovePromise = runWithConcurrency(configLambdasRemove.map((func) => async () => {
|
|
375
380
|
const roleName = await getRoleNameFromFunction(func.functionName);
|
|
376
381
|
roleNamesToRemoveSet.add(roleName);
|
|
377
382
|
}));
|
|
378
383
|
// Analyze roles to add
|
|
379
384
|
await roleNamesToAddPromise;
|
|
380
385
|
const roleNamesToAdd = Array.from(roleNamesToAddSet);
|
|
381
|
-
const rolesToAddPromise =
|
|
386
|
+
const rolesToAddPromise = runWithConcurrency(roleNamesToAdd.map((roleName) => async () => {
|
|
382
387
|
const roleUpdate = await analyzeRoleAdd(roleName);
|
|
383
388
|
return roleUpdate.addPolicy ? roleUpdate.roleName : undefined;
|
|
384
389
|
}));
|
|
@@ -387,7 +392,7 @@ async function getInfraChangesForAdding() {
|
|
|
387
392
|
let roleNamesToRemove = Array.from(roleNamesToRemoveSet);
|
|
388
393
|
// make sure that roles removed are not in the list to add
|
|
389
394
|
roleNamesToRemove = roleNamesToRemove.filter((role) => !roleNamesToAdd.includes(role));
|
|
390
|
-
const rolesToRemovePromise =
|
|
395
|
+
const rolesToRemovePromise = runWithConcurrency(roleNamesToRemove.map((roleName) => async () => {
|
|
391
396
|
const roleRemoval = await analyzeRoleRemove(roleName);
|
|
392
397
|
return roleRemoval.needToRemovePolicy ? roleRemoval.roleName : undefined;
|
|
393
398
|
}));
|
|
@@ -488,17 +493,15 @@ async function analyzeLambdaRemove(functionName) {
|
|
|
488
493
|
async function getInfraChangesForRemoving() {
|
|
489
494
|
Logger.verbose('Analyzing infrastructure changes for removing Lambda Live Debugger');
|
|
490
495
|
const allLambdas = Configuration.getLambdasAll();
|
|
491
|
-
const lambdasToRemovePromise =
|
|
492
|
-
return analyzeLambdaRemove(func.functionName);
|
|
493
|
-
}));
|
|
496
|
+
const lambdasToRemovePromise = runWithConcurrency(allLambdas.map((func) => () => analyzeLambdaRemove(func.functionName)));
|
|
494
497
|
// Get all role names for lambdas to remove, ensure uniqueness, then analyze
|
|
495
498
|
const roleNamesToRemoveSet = new Set();
|
|
496
|
-
await
|
|
499
|
+
await runWithConcurrency(allLambdas.map((func) => async () => {
|
|
497
500
|
const roleName = await getRoleNameFromFunction(func.functionName);
|
|
498
501
|
roleNamesToRemoveSet.add(roleName);
|
|
499
502
|
}));
|
|
500
503
|
const roleNamesToRemove = Array.from(roleNamesToRemoveSet);
|
|
501
|
-
const rolesToRemovePromise =
|
|
504
|
+
const rolesToRemovePromise = runWithConcurrency(roleNamesToRemove.map((roleName) => async () => {
|
|
502
505
|
const roleRemoval = await analyzeRoleRemove(roleName);
|
|
503
506
|
return roleRemoval.needToRemovePolicy ? roleRemoval.roleName : undefined;
|
|
504
507
|
}));
|
|
@@ -516,14 +519,14 @@ async function getInfraChangesForRemoving() {
|
|
|
516
519
|
*/
|
|
517
520
|
async function applyRemoveInfra(changes) {
|
|
518
521
|
Logger.verbose('Starting infrastructure removal');
|
|
519
|
-
const
|
|
522
|
+
const tasks = [];
|
|
520
523
|
for (const lambdaData of changes.lambdasToRemove) {
|
|
521
|
-
|
|
524
|
+
tasks.push(() => removeLayerFromLambda(lambdaData));
|
|
522
525
|
}
|
|
523
526
|
for (const roleName of changes.rolesToRemove) {
|
|
524
|
-
|
|
527
|
+
tasks.push(() => removePolicyFromLambdaRole(roleName));
|
|
525
528
|
}
|
|
526
|
-
await
|
|
529
|
+
await runWithConcurrency(tasks);
|
|
527
530
|
}
|
|
528
531
|
/**
|
|
529
532
|
* Get the Lambda function configuration including layers, environment variables, and timeout
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run async tasks with a limited number of tasks running concurrently,
|
|
3
|
+
* for example to avoid hitting AWS API rate limits.
|
|
4
|
+
* @param tasks
|
|
5
|
+
* @param limit
|
|
6
|
+
* @returns results in the same order as the tasks
|
|
7
|
+
*/
|
|
8
|
+
export declare function runWithConcurrency<T>(tasks: (() => Promise<T>)[], limit?: number): Promise<T[]>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run async tasks with a limited number of tasks running concurrently,
|
|
3
|
+
* for example to avoid hitting AWS API rate limits.
|
|
4
|
+
* @param tasks
|
|
5
|
+
* @param limit
|
|
6
|
+
* @returns results in the same order as the tasks
|
|
7
|
+
*/
|
|
8
|
+
export async function runWithConcurrency(tasks, limit = 5) {
|
|
9
|
+
const results = new Array(tasks.length);
|
|
10
|
+
let nextTaskIndex = 0;
|
|
11
|
+
const workers = Array.from({ length: Math.min(limit, tasks.length) }, async () => {
|
|
12
|
+
while (nextTaskIndex < tasks.length) {
|
|
13
|
+
const taskIndex = nextTaskIndex++;
|
|
14
|
+
results[taskIndex] = await tasks[taskIndex]();
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
await Promise.all(workers);
|
|
18
|
+
return results;
|
|
19
|
+
}
|