@go-to-k/cdkd 0.3.1 → 0.3.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.
package/dist/cli.js CHANGED
@@ -11216,6 +11216,7 @@ var LambdaFunctionProvider = class {
11216
11216
  `Pre-delete VPC detach failed for ${physicalId}: ${error instanceof Error ? error.message : String(error)} \u2014 continuing with delete`
11217
11217
  );
11218
11218
  }
11219
+ await this.waitForLambdaUpdateCompleted(physicalId);
11219
11220
  }
11220
11221
  try {
11221
11222
  await this.lambdaClient.send(new DeleteFunctionCommand({ FunctionName: physicalId }));
@@ -11323,6 +11324,56 @@ var LambdaFunctionProvider = class {
11323
11324
  * Timeout is a soft warning — downstream Subnet/SG deletion has its own
11324
11325
  * retries.
11325
11326
  */
11327
+ /**
11328
+ * Poll GetFunction until LastUpdateStatus is no longer `InProgress`.
11329
+ *
11330
+ * After UpdateFunctionConfiguration the Lambda service processes the
11331
+ * change (including VPC detach + hyperplane ENI release) asynchronously.
11332
+ * Returning early — i.e. calling DeleteFunction while the update is still
11333
+ * `InProgress` — aborts the detach, leaving ENIs attached and blocking
11334
+ * downstream Subnet / SG deletion.
11335
+ *
11336
+ * Bounded by eniWaitTimeoutMs (10min) and treated as a soft warning on
11337
+ * timeout: the subsequent ENI cleanup loop and downstream retries cover
11338
+ * the residual edge case.
11339
+ */
11340
+ async waitForLambdaUpdateCompleted(functionName) {
11341
+ const start = Date.now();
11342
+ let delay = this.eniWaitInitialDelayMs;
11343
+ for (; ; ) {
11344
+ let status;
11345
+ try {
11346
+ const resp = await this.lambdaClient.send(
11347
+ new GetFunctionCommand({ FunctionName: functionName })
11348
+ );
11349
+ status = resp.Configuration?.LastUpdateStatus;
11350
+ } catch (error) {
11351
+ if (error instanceof ResourceNotFoundException) {
11352
+ return;
11353
+ }
11354
+ this.logger.debug(
11355
+ `GetFunction failed while waiting for ${functionName} update: ${error instanceof Error ? error.message : String(error)}`
11356
+ );
11357
+ }
11358
+ if (status && status !== "InProgress") {
11359
+ this.logger.debug(
11360
+ `Lambda ${functionName} update completed (LastUpdateStatus=${status}) after ${Date.now() - start}ms`
11361
+ );
11362
+ return;
11363
+ }
11364
+ const elapsed = Date.now() - start;
11365
+ if (elapsed >= this.eniWaitTimeoutMs) {
11366
+ this.logger.warn(
11367
+ `Timeout (${this.eniWaitTimeoutMs}ms) waiting for Lambda ${functionName} update to complete; proceeding with delete`
11368
+ );
11369
+ return;
11370
+ }
11371
+ const remaining = this.eniWaitTimeoutMs - elapsed;
11372
+ const sleepMs = Math.min(delay, remaining);
11373
+ await this.sleep(sleepMs);
11374
+ delay = Math.min(delay * 2, this.eniWaitMaxDelayMs);
11375
+ }
11376
+ }
11326
11377
  async cleanupLambdaEnis(functionName) {
11327
11378
  const start = Date.now();
11328
11379
  let delay = this.eniWaitInitialDelayMs;
@@ -11330,14 +11381,12 @@ var LambdaFunctionProvider = class {
11330
11381
  this.logger.debug(
11331
11382
  `Cleaning up Lambda VPC ENIs for function ${functionName} (timeout ${this.eniWaitTimeoutMs}ms)`
11332
11383
  );
11333
- const descriptionNeedle = `AWS Lambda VPC ENI`;
11334
- const functionNamePattern = new RegExp(`(^|-)${escapeRegExp(functionName)}(-|$)`);
11335
11384
  for (; ; ) {
11336
11385
  attempt++;
11337
11386
  let enis = [];
11338
11387
  let listFailed = false;
11339
11388
  try {
11340
- enis = await this.listLambdaEnis(descriptionNeedle, functionNamePattern);
11389
+ enis = await this.listLambdaEnis(functionName);
11341
11390
  } catch (error) {
11342
11391
  this.logger.warn(
11343
11392
  `DescribeNetworkInterfaces failed while cleaning up Lambda ENIs of ${functionName}: ${error instanceof Error ? error.message : String(error)}`
@@ -11386,8 +11435,9 @@ var LambdaFunctionProvider = class {
11386
11435
  * Server-side filter (`description`) does not support wildcards on this
11387
11436
  * API, so we narrow with `requester-id` + match Description client-side.
11388
11437
  */
11389
- async listLambdaEnis(descriptionNeedle, functionNamePattern) {
11438
+ async listLambdaEnis(functionName) {
11390
11439
  const enis = [];
11440
+ const descriptionPrefix = "AWS Lambda VPC ENI-";
11391
11441
  let nextToken;
11392
11442
  do {
11393
11443
  const resp = await this.ec2Client.send(
@@ -11401,7 +11451,11 @@ var LambdaFunctionProvider = class {
11401
11451
  );
11402
11452
  for (const ni of resp.NetworkInterfaces ?? []) {
11403
11453
  const desc = ni.Description ?? "";
11404
- if (ni.NetworkInterfaceId && desc.includes(descriptionNeedle) && functionNamePattern.test(desc)) {
11454
+ if (!ni.NetworkInterfaceId || !desc.startsWith(descriptionPrefix)) {
11455
+ continue;
11456
+ }
11457
+ const token = desc.slice(descriptionPrefix.length);
11458
+ if (functionName === token || functionName.startsWith(`${token}-`)) {
11405
11459
  enis.push({ id: ni.NetworkInterfaceId, status: ni.Status ?? "unknown" });
11406
11460
  }
11407
11461
  }
@@ -11497,9 +11551,6 @@ var LambdaFunctionProvider = class {
11497
11551
  return (crc ^ 4294967295) >>> 0;
11498
11552
  }
11499
11553
  };
11500
- function escapeRegExp(input) {
11501
- return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11502
- }
11503
11554
 
11504
11555
  // src/provisioning/providers/lambda-permission-provider.ts
11505
11556
  import {
@@ -27605,7 +27656,7 @@ function reorderArgs(argv) {
27605
27656
  }
27606
27657
  async function main() {
27607
27658
  const program = new Command8();
27608
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.3.1");
27659
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.3.3");
27609
27660
  program.addCommand(createBootstrapCommand());
27610
27661
  program.addCommand(createSynthCommand());
27611
27662
  program.addCommand(createDeployCommand());