@go-to-k/cdkd 0.7.0 → 0.9.0
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/README.md +27 -6
- package/dist/cli.js +1664 -389
- package/dist/cli.js.map +4 -4
- package/dist/go-to-k-cdkd-0.9.0.tgz +0 -0
- package/dist/index.js +491 -160
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.7.0.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -3205,6 +3205,14 @@ import {
|
|
|
3205
3205
|
ListObjectsV2Command,
|
|
3206
3206
|
NoSuchKey
|
|
3207
3207
|
} from "@aws-sdk/client-s3";
|
|
3208
|
+
|
|
3209
|
+
// src/types/state.ts
|
|
3210
|
+
var STATE_SCHEMA_VERSION_LEGACY = 1;
|
|
3211
|
+
var STATE_SCHEMA_VERSION_CURRENT = 2;
|
|
3212
|
+
|
|
3213
|
+
// src/state/s3-state-backend.ts
|
|
3214
|
+
var LEGACY_KEY_DEPTH = 2;
|
|
3215
|
+
var NEW_KEY_DEPTH = 3;
|
|
3208
3216
|
var S3StateBackend = class {
|
|
3209
3217
|
constructor(s3Client, config) {
|
|
3210
3218
|
this.s3Client = s3Client;
|
|
@@ -3212,9 +3220,16 @@ var S3StateBackend = class {
|
|
|
3212
3220
|
}
|
|
3213
3221
|
logger = getLogger().child("S3StateBackend");
|
|
3214
3222
|
/**
|
|
3215
|
-
* Get the S3 key for a stack's state file
|
|
3223
|
+
* Get the new (region-scoped) S3 key for a stack's state file.
|
|
3216
3224
|
*/
|
|
3217
|
-
getStateKey(stackName) {
|
|
3225
|
+
getStateKey(stackName, region) {
|
|
3226
|
+
return `${this.config.prefix}/${stackName}/${region}/state.json`;
|
|
3227
|
+
}
|
|
3228
|
+
/**
|
|
3229
|
+
* Get the legacy (pre-region-prefix) S3 key for a stack's state file.
|
|
3230
|
+
* Used for backwards-compatible reads and for the migration delete.
|
|
3231
|
+
*/
|
|
3232
|
+
getLegacyStateKey(stackName) {
|
|
3218
3233
|
return `${this.config.prefix}/${stackName}/state.json`;
|
|
3219
3234
|
}
|
|
3220
3235
|
/**
|
|
@@ -3240,101 +3255,143 @@ var S3StateBackend = class {
|
|
|
3240
3255
|
}
|
|
3241
3256
|
}
|
|
3242
3257
|
/**
|
|
3243
|
-
* Check if state exists for a stack
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
);
|
|
3258
|
+
* Check if state exists for a stack in the given region.
|
|
3259
|
+
*
|
|
3260
|
+
* Returns true for either layout: the new region-scoped key, or the legacy
|
|
3261
|
+
* key when its embedded `region` matches the requested region. This lets
|
|
3262
|
+
* `cdkd state rm <stack> --region X` and `cdkd destroy <stack>` see legacy
|
|
3263
|
+
* state without forcing a write-through migration first.
|
|
3264
|
+
*/
|
|
3265
|
+
async stateExists(stackName, region) {
|
|
3266
|
+
const newKey = this.getStateKey(stackName, region);
|
|
3267
|
+
if (await this.headObject(newKey)) {
|
|
3254
3268
|
return true;
|
|
3255
|
-
} catch (error) {
|
|
3256
|
-
if (error instanceof NoSuchKey || error.name === "NotFound") {
|
|
3257
|
-
return false;
|
|
3258
|
-
}
|
|
3259
|
-
throw new StateError(
|
|
3260
|
-
`Failed to check if state exists for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`,
|
|
3261
|
-
error instanceof Error ? error : void 0
|
|
3262
|
-
);
|
|
3263
3269
|
}
|
|
3270
|
+
return this.legacyMatchesRegion(stackName, region);
|
|
3264
3271
|
}
|
|
3265
3272
|
/**
|
|
3266
|
-
* Get state for a stack
|
|
3273
|
+
* Get state for a stack, transparently falling back to the legacy key.
|
|
3274
|
+
*
|
|
3275
|
+
* Lookup order:
|
|
3276
|
+
* 1. `{prefix}/{stackName}/{region}/state.json` (current `version: 2` key).
|
|
3277
|
+
* 2. `{prefix}/{stackName}/state.json` (legacy `version: 1` key) — only
|
|
3278
|
+
* accepted if its embedded `region` matches the requested region.
|
|
3267
3279
|
*
|
|
3268
|
-
*
|
|
3269
|
-
*
|
|
3280
|
+
* When a legacy hit is returned, `migrationPending` is `true`. Callers that
|
|
3281
|
+
* subsequently `saveState` automatically migrate by writing the new key and
|
|
3282
|
+
* deleting the legacy one (see `saveState`'s `legacyMigration` argument).
|
|
3283
|
+
*
|
|
3284
|
+
* Note: S3 returns ETag with surrounding quotes (e.g., `"abc123"`). We
|
|
3285
|
+
* preserve the quotes — they are required for `IfMatch` conditions.
|
|
3270
3286
|
*/
|
|
3271
|
-
async getState(stackName) {
|
|
3272
|
-
const
|
|
3287
|
+
async getState(stackName, region) {
|
|
3288
|
+
const newKey = this.getStateKey(stackName, region);
|
|
3273
3289
|
try {
|
|
3274
|
-
this.logger.debug(`Getting state for stack: ${stackName}`);
|
|
3290
|
+
this.logger.debug(`Getting state for stack: ${stackName} (${region})`);
|
|
3275
3291
|
const response = await this.s3Client.send(
|
|
3276
3292
|
new GetObjectCommand({
|
|
3277
3293
|
Bucket: this.config.bucket,
|
|
3278
|
-
Key:
|
|
3294
|
+
Key: newKey
|
|
3279
3295
|
})
|
|
3280
3296
|
);
|
|
3281
3297
|
if (!response.Body) {
|
|
3282
|
-
throw new StateError(`State file for stack '${stackName}' has no body`);
|
|
3298
|
+
throw new StateError(`State file for stack '${stackName}' (${region}) has no body`);
|
|
3283
3299
|
}
|
|
3284
3300
|
if (!response.ETag) {
|
|
3285
|
-
throw new StateError(`State file for stack '${stackName}' has no ETag`);
|
|
3301
|
+
throw new StateError(`State file for stack '${stackName}' (${region}) has no ETag`);
|
|
3286
3302
|
}
|
|
3287
3303
|
const bodyString = await response.Body.transformToString();
|
|
3288
|
-
const state =
|
|
3289
|
-
this.logger.debug(`Retrieved state
|
|
3290
|
-
return {
|
|
3291
|
-
state,
|
|
3292
|
-
etag: response.ETag
|
|
3293
|
-
};
|
|
3304
|
+
const state = this.parseStateBody(bodyString, stackName);
|
|
3305
|
+
this.logger.debug(`Retrieved state: ${stackName} (${region}), ETag: ${response.ETag}`);
|
|
3306
|
+
return { state, etag: response.ETag };
|
|
3294
3307
|
} catch (error) {
|
|
3295
|
-
if (error
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3308
|
+
if (!isNoSuchKey(error)) {
|
|
3309
|
+
if (error instanceof StateError)
|
|
3310
|
+
throw error;
|
|
3311
|
+
throw new StateError(
|
|
3312
|
+
`Failed to get state for stack '${stackName}' (${region}): ${error instanceof Error ? error.message : String(error)}`,
|
|
3313
|
+
error instanceof Error ? error : void 0
|
|
3314
|
+
);
|
|
3301
3315
|
}
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3316
|
+
this.logger.debug(`No state at new key for stack: ${stackName} (${region})`);
|
|
3317
|
+
}
|
|
3318
|
+
const legacy = await this.tryGetLegacy(stackName, region);
|
|
3319
|
+
if (legacy) {
|
|
3320
|
+
this.logger.warn(
|
|
3321
|
+
`Loaded legacy state for stack '${stackName}' from '${this.getLegacyStateKey(stackName)}'. It will be migrated to the region-scoped layout on next save.`
|
|
3305
3322
|
);
|
|
3323
|
+
return { ...legacy, migrationPending: true };
|
|
3306
3324
|
}
|
|
3325
|
+
return null;
|
|
3307
3326
|
}
|
|
3308
3327
|
/**
|
|
3309
|
-
* Save state for a stack with optimistic locking
|
|
3328
|
+
* Save state for a stack with optimistic locking.
|
|
3329
|
+
*
|
|
3330
|
+
* Always writes to the new region-scoped key. The state body is rewritten
|
|
3331
|
+
* with `version: 2` and the supplied region.
|
|
3332
|
+
*
|
|
3333
|
+
* If the caller observed `migrationPending: true` from `getState`, it
|
|
3334
|
+
* should pass the legacy ETag back via `expectedEtag` AND set
|
|
3335
|
+
* `migrateLegacy: true`. After the new key is written successfully, the
|
|
3336
|
+
* legacy key is deleted to complete migration. The legacy delete is a
|
|
3337
|
+
* best-effort follow-up — a failure is logged but does not unwind the new
|
|
3338
|
+
* write.
|
|
3310
3339
|
*
|
|
3311
3340
|
* @param stackName Stack name
|
|
3341
|
+
* @param region Target region (load-bearing — part of the S3 key)
|
|
3312
3342
|
* @param state State to save
|
|
3313
|
-
* @param
|
|
3314
|
-
*
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
const
|
|
3343
|
+
* @param options Optimistic-lock ETag + legacy-migration flag
|
|
3344
|
+
* @returns New ETag (with quotes, e.g., `"abc123"`)
|
|
3345
|
+
*/
|
|
3346
|
+
async saveState(stackName, region, state, options = {}) {
|
|
3347
|
+
const newKey = this.getStateKey(stackName, region);
|
|
3348
|
+
const { expectedEtag, migrateLegacy } = options;
|
|
3349
|
+
const body = {
|
|
3350
|
+
...state,
|
|
3351
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
3352
|
+
stackName,
|
|
3353
|
+
region
|
|
3354
|
+
};
|
|
3319
3355
|
try {
|
|
3320
3356
|
this.logger.debug(
|
|
3321
|
-
`Saving state
|
|
3357
|
+
`Saving state: ${stackName} (${region})${expectedEtag ? `, expected ETag: ${expectedEtag}` : ""}`
|
|
3322
3358
|
);
|
|
3323
|
-
const
|
|
3359
|
+
const bodyString = JSON.stringify(body, null, 2);
|
|
3324
3360
|
const response = await this.s3Client.send(
|
|
3325
3361
|
new PutObjectCommand2({
|
|
3326
3362
|
Bucket: this.config.bucket,
|
|
3327
|
-
Key:
|
|
3328
|
-
Body:
|
|
3329
|
-
ContentLength: Buffer.byteLength(
|
|
3363
|
+
Key: newKey,
|
|
3364
|
+
Body: bodyString,
|
|
3365
|
+
ContentLength: Buffer.byteLength(bodyString),
|
|
3330
3366
|
ContentType: "application/json",
|
|
3331
|
-
|
|
3367
|
+
// The legacy ETag is for a different key; only forward it when we're
|
|
3368
|
+
// updating in-place at the new key.
|
|
3369
|
+
...!migrateLegacy && expectedEtag && { IfMatch: expectedEtag }
|
|
3332
3370
|
})
|
|
3333
3371
|
);
|
|
3334
3372
|
if (!response.ETag) {
|
|
3335
|
-
throw new StateError(
|
|
3373
|
+
throw new StateError(
|
|
3374
|
+
`No ETag returned after saving state for stack '${stackName}' (${region})`
|
|
3375
|
+
);
|
|
3376
|
+
}
|
|
3377
|
+
this.logger.debug(`State saved: ${stackName} (${region}), new ETag: ${response.ETag}`);
|
|
3378
|
+
if (migrateLegacy) {
|
|
3379
|
+
try {
|
|
3380
|
+
await this.s3Client.send(
|
|
3381
|
+
new DeleteObjectCommand({
|
|
3382
|
+
Bucket: this.config.bucket,
|
|
3383
|
+
Key: this.getLegacyStateKey(stackName)
|
|
3384
|
+
})
|
|
3385
|
+
);
|
|
3386
|
+
this.logger.info(
|
|
3387
|
+
`Migrated state for stack '${stackName}' to region-scoped layout (${region})`
|
|
3388
|
+
);
|
|
3389
|
+
} catch (deleteError) {
|
|
3390
|
+
this.logger.warn(
|
|
3391
|
+
`Migrated stack '${stackName}' to new key, but failed to delete legacy key: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`
|
|
3392
|
+
);
|
|
3393
|
+
}
|
|
3336
3394
|
}
|
|
3337
|
-
this.logger.debug(`State saved for stack: ${stackName}, new ETag: ${response.ETag}`);
|
|
3338
3395
|
return response.ETag;
|
|
3339
3396
|
} catch (error) {
|
|
3340
3397
|
if (error.name === "PreconditionFailed") {
|
|
@@ -3343,63 +3400,230 @@ var S3StateBackend = class {
|
|
|
3343
3400
|
);
|
|
3344
3401
|
}
|
|
3345
3402
|
throw new StateError(
|
|
3346
|
-
`Failed to save state for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`,
|
|
3403
|
+
`Failed to save state for stack '${stackName}' (${region}): ${error instanceof Error ? error.message : String(error)}`,
|
|
3347
3404
|
error instanceof Error ? error : void 0
|
|
3348
3405
|
);
|
|
3349
3406
|
}
|
|
3350
3407
|
}
|
|
3351
3408
|
/**
|
|
3352
|
-
* Delete state for a stack
|
|
3409
|
+
* Delete state for a stack in the given region.
|
|
3410
|
+
*
|
|
3411
|
+
* Removes both the new key and the legacy key (if present). Legacy removal
|
|
3412
|
+
* is region-conditional: a legacy state file with a different `region`
|
|
3413
|
+
* field is left alone.
|
|
3353
3414
|
*/
|
|
3354
|
-
async deleteState(stackName) {
|
|
3355
|
-
const key = this.getStateKey(stackName);
|
|
3415
|
+
async deleteState(stackName, region) {
|
|
3356
3416
|
try {
|
|
3357
|
-
this.logger.debug(`Deleting state
|
|
3417
|
+
this.logger.debug(`Deleting state: ${stackName} (${region})`);
|
|
3358
3418
|
await this.s3Client.send(
|
|
3359
3419
|
new DeleteObjectCommand({
|
|
3360
3420
|
Bucket: this.config.bucket,
|
|
3361
|
-
Key:
|
|
3421
|
+
Key: this.getStateKey(stackName, region)
|
|
3362
3422
|
})
|
|
3363
3423
|
);
|
|
3364
|
-
this.
|
|
3424
|
+
if (await this.legacyMatchesRegion(stackName, region)) {
|
|
3425
|
+
await this.s3Client.send(
|
|
3426
|
+
new DeleteObjectCommand({
|
|
3427
|
+
Bucket: this.config.bucket,
|
|
3428
|
+
Key: this.getLegacyStateKey(stackName)
|
|
3429
|
+
})
|
|
3430
|
+
);
|
|
3431
|
+
this.logger.debug(`Deleted legacy state for stack: ${stackName}`);
|
|
3432
|
+
}
|
|
3433
|
+
this.logger.debug(`State deleted: ${stackName} (${region})`);
|
|
3365
3434
|
} catch (error) {
|
|
3366
3435
|
throw new StateError(
|
|
3367
|
-
`Failed to delete state for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`,
|
|
3436
|
+
`Failed to delete state for stack '${stackName}' (${region}): ${error instanceof Error ? error.message : String(error)}`,
|
|
3368
3437
|
error instanceof Error ? error : void 0
|
|
3369
3438
|
);
|
|
3370
3439
|
}
|
|
3371
3440
|
}
|
|
3372
3441
|
/**
|
|
3373
|
-
* List all stacks with state
|
|
3442
|
+
* List all stacks with state in the bucket.
|
|
3443
|
+
*
|
|
3444
|
+
* Returns one `{stackName, region}` pair per state file. Both layouts
|
|
3445
|
+
* are enumerated:
|
|
3446
|
+
*
|
|
3447
|
+
* - `{prefix}/{stackName}/{region}/state.json` (new) — `region` is the
|
|
3448
|
+
* path segment.
|
|
3449
|
+
* - `{prefix}/{stackName}/state.json` (legacy) — `region` is read from the
|
|
3450
|
+
* state body when present, otherwise `undefined`.
|
|
3451
|
+
*
|
|
3452
|
+
* Pairs are deduplicated by `(stackName, region)` so a stack mid-migration
|
|
3453
|
+
* shows up exactly once.
|
|
3374
3454
|
*/
|
|
3375
3455
|
async listStacks() {
|
|
3376
3456
|
try {
|
|
3377
3457
|
this.logger.debug("Listing all stacks");
|
|
3458
|
+
const prefix = `${this.config.prefix}/`;
|
|
3459
|
+
const refs = [];
|
|
3460
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3461
|
+
let continuationToken;
|
|
3462
|
+
do {
|
|
3463
|
+
const response = await this.s3Client.send(
|
|
3464
|
+
new ListObjectsV2Command({
|
|
3465
|
+
Bucket: this.config.bucket,
|
|
3466
|
+
Prefix: prefix,
|
|
3467
|
+
...continuationToken && { ContinuationToken: continuationToken }
|
|
3468
|
+
})
|
|
3469
|
+
);
|
|
3470
|
+
for (const obj of response.Contents ?? []) {
|
|
3471
|
+
const key = obj.Key;
|
|
3472
|
+
if (!key)
|
|
3473
|
+
continue;
|
|
3474
|
+
if (!key.endsWith("/state.json"))
|
|
3475
|
+
continue;
|
|
3476
|
+
const rest = key.slice(prefix.length);
|
|
3477
|
+
const segments = rest.split("/");
|
|
3478
|
+
if (segments.length === NEW_KEY_DEPTH) {
|
|
3479
|
+
const [stackName, region] = segments;
|
|
3480
|
+
if (!stackName || !region)
|
|
3481
|
+
continue;
|
|
3482
|
+
const dedupeKey = `${stackName}\0${region}`;
|
|
3483
|
+
if (!seen.has(dedupeKey)) {
|
|
3484
|
+
seen.add(dedupeKey);
|
|
3485
|
+
refs.push({ stackName, region });
|
|
3486
|
+
}
|
|
3487
|
+
continue;
|
|
3488
|
+
}
|
|
3489
|
+
if (segments.length === LEGACY_KEY_DEPTH) {
|
|
3490
|
+
const [stackName] = segments;
|
|
3491
|
+
if (!stackName)
|
|
3492
|
+
continue;
|
|
3493
|
+
const region = await this.readLegacyRegion(stackName);
|
|
3494
|
+
const dedupeKey = `${stackName}\0${region ?? ""}`;
|
|
3495
|
+
if (!seen.has(dedupeKey)) {
|
|
3496
|
+
seen.add(dedupeKey);
|
|
3497
|
+
refs.push({ stackName, ...region ? { region } : {} });
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
continuationToken = response.IsTruncated ? response.NextContinuationToken : void 0;
|
|
3502
|
+
} while (continuationToken);
|
|
3503
|
+
this.logger.debug(`Found ${refs.length} stack(s) across regions`);
|
|
3504
|
+
return refs;
|
|
3505
|
+
} catch (error) {
|
|
3506
|
+
throw new StateError(
|
|
3507
|
+
`Failed to list stacks: ${error instanceof Error ? error.message : String(error)}`,
|
|
3508
|
+
error instanceof Error ? error : void 0
|
|
3509
|
+
);
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
/**
|
|
3513
|
+
* HeadObject probe — returns true on 200, false on NotFound. Other errors
|
|
3514
|
+
* propagate so we don't accidentally swallow IAM denials.
|
|
3515
|
+
*/
|
|
3516
|
+
async headObject(key) {
|
|
3517
|
+
try {
|
|
3518
|
+
await this.s3Client.send(
|
|
3519
|
+
new HeadObjectCommand2({
|
|
3520
|
+
Bucket: this.config.bucket,
|
|
3521
|
+
Key: key
|
|
3522
|
+
})
|
|
3523
|
+
);
|
|
3524
|
+
return true;
|
|
3525
|
+
} catch (error) {
|
|
3526
|
+
if (isNoSuchKey(error) || error.name === "NotFound") {
|
|
3527
|
+
return false;
|
|
3528
|
+
}
|
|
3529
|
+
throw error;
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
/**
|
|
3533
|
+
* Read the legacy state's `region` field. Used for region matching during
|
|
3534
|
+
* `stateExists` / `deleteState` and for assigning a region to legacy
|
|
3535
|
+
* entries during `listStacks`.
|
|
3536
|
+
*/
|
|
3537
|
+
async readLegacyRegion(stackName) {
|
|
3538
|
+
try {
|
|
3378
3539
|
const response = await this.s3Client.send(
|
|
3379
|
-
new
|
|
3540
|
+
new GetObjectCommand({
|
|
3380
3541
|
Bucket: this.config.bucket,
|
|
3381
|
-
|
|
3382
|
-
Delimiter: "/"
|
|
3542
|
+
Key: this.getLegacyStateKey(stackName)
|
|
3383
3543
|
})
|
|
3384
3544
|
);
|
|
3385
|
-
if (!response.
|
|
3386
|
-
return
|
|
3545
|
+
if (!response.Body)
|
|
3546
|
+
return void 0;
|
|
3547
|
+
const bodyString = await response.Body.transformToString();
|
|
3548
|
+
const state = JSON.parse(bodyString);
|
|
3549
|
+
return typeof state.region === "string" ? state.region : void 0;
|
|
3550
|
+
} catch (error) {
|
|
3551
|
+
if (isNoSuchKey(error))
|
|
3552
|
+
return void 0;
|
|
3553
|
+
this.logger.debug(
|
|
3554
|
+
`Could not read legacy state region for '${stackName}': ${error instanceof Error ? error.message : String(error)}`
|
|
3555
|
+
);
|
|
3556
|
+
return void 0;
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
async legacyMatchesRegion(stackName, region) {
|
|
3560
|
+
const legacyRegion = await this.readLegacyRegion(stackName);
|
|
3561
|
+
return legacyRegion === region;
|
|
3562
|
+
}
|
|
3563
|
+
/**
|
|
3564
|
+
* Try to read the legacy `version: 1` state. Returns null when the legacy
|
|
3565
|
+
* key is missing or its embedded region does not match the caller's region.
|
|
3566
|
+
*/
|
|
3567
|
+
async tryGetLegacy(stackName, region) {
|
|
3568
|
+
try {
|
|
3569
|
+
const response = await this.s3Client.send(
|
|
3570
|
+
new GetObjectCommand({
|
|
3571
|
+
Bucket: this.config.bucket,
|
|
3572
|
+
Key: this.getLegacyStateKey(stackName)
|
|
3573
|
+
})
|
|
3574
|
+
);
|
|
3575
|
+
if (!response.Body || !response.ETag) {
|
|
3576
|
+
return null;
|
|
3577
|
+
}
|
|
3578
|
+
const bodyString = await response.Body.transformToString();
|
|
3579
|
+
const state = this.parseStateBody(bodyString, stackName);
|
|
3580
|
+
if (state.region && state.region !== region) {
|
|
3581
|
+
this.logger.debug(
|
|
3582
|
+
`Legacy state for stack '${stackName}' has region '${state.region}', not '${region}' \u2014 skipping legacy fallback.`
|
|
3583
|
+
);
|
|
3584
|
+
return null;
|
|
3387
3585
|
}
|
|
3388
|
-
|
|
3389
|
-
const prefixStr = prefix.Prefix || "";
|
|
3390
|
-
const parts = prefixStr.split("/");
|
|
3391
|
-
return parts[parts.length - 2];
|
|
3392
|
-
}).filter((name) => Boolean(name));
|
|
3393
|
-
this.logger.debug(`Found ${stackNames.length} stacks`);
|
|
3394
|
-
return stackNames;
|
|
3586
|
+
return { state, etag: response.ETag };
|
|
3395
3587
|
} catch (error) {
|
|
3588
|
+
if (isNoSuchKey(error))
|
|
3589
|
+
return null;
|
|
3396
3590
|
throw new StateError(
|
|
3397
|
-
`Failed to
|
|
3591
|
+
`Failed to get legacy state for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`,
|
|
3592
|
+
error instanceof Error ? error : void 0
|
|
3593
|
+
);
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
/**
|
|
3597
|
+
* Parse a state body and validate the schema version. Future-proofs against
|
|
3598
|
+
* a binary that predates schema version `N` reading a `version: N+1` blob:
|
|
3599
|
+
* the old binary would otherwise treat unknown fields as defaults and
|
|
3600
|
+
* silently lose data on the next save.
|
|
3601
|
+
*/
|
|
3602
|
+
parseStateBody(bodyString, stackName) {
|
|
3603
|
+
let parsed;
|
|
3604
|
+
try {
|
|
3605
|
+
parsed = JSON.parse(bodyString);
|
|
3606
|
+
} catch (error) {
|
|
3607
|
+
throw new StateError(
|
|
3608
|
+
`State file for stack '${stackName}' is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
3398
3609
|
error instanceof Error ? error : void 0
|
|
3399
3610
|
);
|
|
3400
3611
|
}
|
|
3612
|
+
const v = parsed.version;
|
|
3613
|
+
if (v !== STATE_SCHEMA_VERSION_LEGACY && v !== STATE_SCHEMA_VERSION_CURRENT && v !== void 0) {
|
|
3614
|
+
throw new StateError(
|
|
3615
|
+
`Unsupported state schema version ${String(v)} for stack '${stackName}'. This cdkd binary supports versions ${String(STATE_SCHEMA_VERSION_LEGACY)} and ${String(STATE_SCHEMA_VERSION_CURRENT)}. Upgrade cdkd to a version that supports schema ${String(v)}.`
|
|
3616
|
+
);
|
|
3617
|
+
}
|
|
3618
|
+
return parsed;
|
|
3401
3619
|
}
|
|
3402
3620
|
};
|
|
3621
|
+
function isNoSuchKey(error) {
|
|
3622
|
+
if (error instanceof NoSuchKey)
|
|
3623
|
+
return true;
|
|
3624
|
+
const name = error?.name;
|
|
3625
|
+
return name === "NoSuchKey";
|
|
3626
|
+
}
|
|
3403
3627
|
|
|
3404
3628
|
// src/state/lock-manager.ts
|
|
3405
3629
|
import {
|
|
@@ -3420,10 +3644,24 @@ var LockManager = class {
|
|
|
3420
3644
|
logger = getLogger().child("LockManager");
|
|
3421
3645
|
ttlMs;
|
|
3422
3646
|
/**
|
|
3423
|
-
* Get the S3 key for a stack's lock file
|
|
3647
|
+
* Get the S3 key for a stack's lock file.
|
|
3648
|
+
*
|
|
3649
|
+
* Locks are region-scoped, mirroring the state key layout
|
|
3650
|
+
* (`{prefix}/{stackName}/{region}/lock.json`). Two regions of the same
|
|
3651
|
+
* stackName can therefore be operated on in parallel without contention,
|
|
3652
|
+
* matching cdkd's parallel execution model.
|
|
3653
|
+
*
|
|
3654
|
+
* The `region` argument is required for new callers; for backwards
|
|
3655
|
+
* compatibility with `state list --long` (which only sees stack names),
|
|
3656
|
+
* passing `undefined` falls back to the legacy `{prefix}/{stackName}/lock.json`
|
|
3657
|
+
* key — that mode is purely for legacy lock cleanup and is NOT used by
|
|
3658
|
+
* deploy / destroy / diff anymore.
|
|
3424
3659
|
*/
|
|
3425
|
-
getLockKey(stackName) {
|
|
3426
|
-
|
|
3660
|
+
getLockKey(stackName, region) {
|
|
3661
|
+
if (region === void 0) {
|
|
3662
|
+
return `${this.config.prefix}/${stackName}/lock.json`;
|
|
3663
|
+
}
|
|
3664
|
+
return `${this.config.prefix}/${stackName}/${region}/lock.json`;
|
|
3427
3665
|
}
|
|
3428
3666
|
/**
|
|
3429
3667
|
* Get default lock owner identifier
|
|
@@ -3462,11 +3700,12 @@ var LockManager = class {
|
|
|
3462
3700
|
* If an expired lock exists, it will be cleaned up and re-acquired.
|
|
3463
3701
|
*
|
|
3464
3702
|
* @param stackName Stack name
|
|
3703
|
+
* @param region Target region (lock key is region-scoped)
|
|
3465
3704
|
* @param owner Lock owner identifier (defaults to user@hostname:pid)
|
|
3466
3705
|
* @param operation Operation being performed (e.g., "deploy", "destroy")
|
|
3467
3706
|
*/
|
|
3468
|
-
async acquireLock(stackName, owner, operation) {
|
|
3469
|
-
const key = this.getLockKey(stackName);
|
|
3707
|
+
async acquireLock(stackName, region, owner, operation) {
|
|
3708
|
+
const key = this.getLockKey(stackName, region);
|
|
3470
3709
|
const lockOwner = owner || this.getDefaultOwner();
|
|
3471
3710
|
const now = Date.now();
|
|
3472
3711
|
const lockInfo = {
|
|
@@ -3476,7 +3715,7 @@ var LockManager = class {
|
|
|
3476
3715
|
...operation && { operation }
|
|
3477
3716
|
};
|
|
3478
3717
|
try {
|
|
3479
|
-
this.logger.debug(`Attempting to acquire lock for stack: ${stackName}`);
|
|
3718
|
+
this.logger.debug(`Attempting to acquire lock for stack: ${stackName} (${region})`);
|
|
3480
3719
|
const lockBody = JSON.stringify(lockInfo, null, 2);
|
|
3481
3720
|
await this.s3Client.send(
|
|
3482
3721
|
new PutObjectCommand3({
|
|
@@ -3489,17 +3728,17 @@ var LockManager = class {
|
|
|
3489
3728
|
// Only succeed if object doesn't exist
|
|
3490
3729
|
})
|
|
3491
3730
|
);
|
|
3492
|
-
this.logger.debug(`Lock acquired for stack: ${stackName}, owner: ${lockOwner}`);
|
|
3731
|
+
this.logger.debug(`Lock acquired for stack: ${stackName} (${region}), owner: ${lockOwner}`);
|
|
3493
3732
|
return true;
|
|
3494
3733
|
} catch (error) {
|
|
3495
3734
|
if (error instanceof S3ServiceException && error.name === "PreconditionFailed") {
|
|
3496
|
-
this.logger.debug(`Lock already exists for stack: ${stackName}`);
|
|
3497
|
-
const existingLock = await this.getLockInfo(stackName);
|
|
3735
|
+
this.logger.debug(`Lock already exists for stack: ${stackName} (${region})`);
|
|
3736
|
+
const existingLock = await this.getLockInfo(stackName, region);
|
|
3498
3737
|
if (existingLock && this.isLockExpired(existingLock)) {
|
|
3499
3738
|
this.logger.info(
|
|
3500
|
-
`Expired lock detected for stack: ${stackName} (owner: ${existingLock.owner}, expired ${this.formatDuration(now - existingLock.expiresAt)} ago). Cleaning up...`
|
|
3739
|
+
`Expired lock detected for stack: ${stackName} (${region}, owner: ${existingLock.owner}, expired ${this.formatDuration(now - existingLock.expiresAt)} ago). Cleaning up...`
|
|
3501
3740
|
);
|
|
3502
|
-
await this.deleteLock(stackName);
|
|
3741
|
+
await this.deleteLock(stackName, region);
|
|
3503
3742
|
try {
|
|
3504
3743
|
const retryBody = JSON.stringify(lockInfo, null, 2);
|
|
3505
3744
|
await this.s3Client.send(
|
|
@@ -3513,13 +3752,13 @@ var LockManager = class {
|
|
|
3513
3752
|
})
|
|
3514
3753
|
);
|
|
3515
3754
|
this.logger.debug(
|
|
3516
|
-
`Lock acquired for stack: ${stackName} after expired lock cleanup, owner: ${lockOwner}`
|
|
3755
|
+
`Lock acquired for stack: ${stackName} (${region}) after expired lock cleanup, owner: ${lockOwner}`
|
|
3517
3756
|
);
|
|
3518
3757
|
return true;
|
|
3519
3758
|
} catch (retryError) {
|
|
3520
3759
|
if (retryError instanceof S3ServiceException && retryError.name === "PreconditionFailed") {
|
|
3521
3760
|
this.logger.debug(
|
|
3522
|
-
`Lock was acquired by another process during expired lock cleanup for stack: ${stackName}`
|
|
3761
|
+
`Lock was acquired by another process during expired lock cleanup for stack: ${stackName} (${region})`
|
|
3523
3762
|
);
|
|
3524
3763
|
return false;
|
|
3525
3764
|
}
|
|
@@ -3529,16 +3768,20 @@ var LockManager = class {
|
|
|
3529
3768
|
return false;
|
|
3530
3769
|
}
|
|
3531
3770
|
throw new LockError(
|
|
3532
|
-
`Failed to acquire lock for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`,
|
|
3771
|
+
`Failed to acquire lock for stack '${stackName}' (${region}): ${error instanceof Error ? error.message : String(error)}`,
|
|
3533
3772
|
error instanceof Error ? error : void 0
|
|
3534
3773
|
);
|
|
3535
3774
|
}
|
|
3536
3775
|
}
|
|
3537
3776
|
/**
|
|
3538
|
-
* Get current lock information
|
|
3777
|
+
* Get current lock information.
|
|
3778
|
+
*
|
|
3779
|
+
* `region` is required for the new region-scoped lock layout. Pass
|
|
3780
|
+
* `undefined` only to inspect a legacy `{prefix}/{stackName}/lock.json`
|
|
3781
|
+
* file (e.g. for state-listing tools that don't yet know the region).
|
|
3539
3782
|
*/
|
|
3540
|
-
async getLockInfo(stackName) {
|
|
3541
|
-
const key = this.getLockKey(stackName);
|
|
3783
|
+
async getLockInfo(stackName, region) {
|
|
3784
|
+
const key = this.getLockKey(stackName, region);
|
|
3542
3785
|
try {
|
|
3543
3786
|
this.logger.debug(`Getting lock info for stack: ${stackName}`);
|
|
3544
3787
|
const response = await this.s3Client.send(
|
|
@@ -3576,27 +3819,27 @@ var LockManager = class {
|
|
|
3576
3819
|
* not for acquisition decisions — use `acquireLock` for that, which has its
|
|
3577
3820
|
* own expired-lock cleanup logic.
|
|
3578
3821
|
*/
|
|
3579
|
-
async isLocked(stackName) {
|
|
3580
|
-
const lockInfo = await this.getLockInfo(stackName);
|
|
3822
|
+
async isLocked(stackName, region) {
|
|
3823
|
+
const lockInfo = await this.getLockInfo(stackName, region);
|
|
3581
3824
|
return lockInfo !== null;
|
|
3582
3825
|
}
|
|
3583
3826
|
/**
|
|
3584
3827
|
* Release a lock for a stack
|
|
3585
3828
|
*/
|
|
3586
|
-
async releaseLock(stackName) {
|
|
3587
|
-
const key = this.getLockKey(stackName);
|
|
3829
|
+
async releaseLock(stackName, region) {
|
|
3830
|
+
const key = this.getLockKey(stackName, region);
|
|
3588
3831
|
try {
|
|
3589
|
-
this.logger.debug(`Releasing lock for stack: ${stackName}`);
|
|
3832
|
+
this.logger.debug(`Releasing lock for stack: ${stackName} (${region})`);
|
|
3590
3833
|
await this.s3Client.send(
|
|
3591
3834
|
new DeleteObjectCommand2({
|
|
3592
3835
|
Bucket: this.config.bucket,
|
|
3593
3836
|
Key: key
|
|
3594
3837
|
})
|
|
3595
3838
|
);
|
|
3596
|
-
this.logger.debug(`Lock released for stack: ${stackName}`);
|
|
3839
|
+
this.logger.debug(`Lock released for stack: ${stackName} (${region})`);
|
|
3597
3840
|
} catch (error) {
|
|
3598
3841
|
throw new LockError(
|
|
3599
|
-
`Failed to release lock for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`,
|
|
3842
|
+
`Failed to release lock for stack '${stackName}' (${region}): ${error instanceof Error ? error.message : String(error)}`,
|
|
3600
3843
|
error instanceof Error ? error : void 0
|
|
3601
3844
|
);
|
|
3602
3845
|
}
|
|
@@ -3606,23 +3849,28 @@ var LockManager = class {
|
|
|
3606
3849
|
*
|
|
3607
3850
|
* This is intended for CLI usage (e.g., --force-unlock flag) when a lock
|
|
3608
3851
|
* is stuck and needs manual intervention.
|
|
3852
|
+
*
|
|
3853
|
+
* Pass `region: undefined` to operate on a legacy
|
|
3854
|
+
* `{prefix}/{stackName}/lock.json` file.
|
|
3609
3855
|
*/
|
|
3610
|
-
async forceReleaseLock(stackName) {
|
|
3611
|
-
const lockInfo = await this.getLockInfo(stackName);
|
|
3856
|
+
async forceReleaseLock(stackName, region) {
|
|
3857
|
+
const lockInfo = await this.getLockInfo(stackName, region);
|
|
3612
3858
|
if (!lockInfo) {
|
|
3613
|
-
this.logger.warn(
|
|
3859
|
+
this.logger.warn(
|
|
3860
|
+
`No lock to force release for stack: ${stackName}${region ? ` (${region})` : ""}`
|
|
3861
|
+
);
|
|
3614
3862
|
return;
|
|
3615
3863
|
}
|
|
3616
3864
|
this.logger.warn(
|
|
3617
|
-
`Force releasing lock for stack: ${stackName}, owner: ${lockInfo.owner}${lockInfo.operation ? `, operation: ${lockInfo.operation}` : ""}, expired: ${this.isLockExpired(lockInfo)}`
|
|
3865
|
+
`Force releasing lock for stack: ${stackName}${region ? ` (${region})` : ""}, owner: ${lockInfo.owner}${lockInfo.operation ? `, operation: ${lockInfo.operation}` : ""}, expired: ${this.isLockExpired(lockInfo)}`
|
|
3618
3866
|
);
|
|
3619
|
-
await this.deleteLock(stackName);
|
|
3867
|
+
await this.deleteLock(stackName, region);
|
|
3620
3868
|
}
|
|
3621
3869
|
/**
|
|
3622
3870
|
* Internal method to delete the lock file from S3
|
|
3623
3871
|
*/
|
|
3624
|
-
async deleteLock(stackName) {
|
|
3625
|
-
const key = this.getLockKey(stackName);
|
|
3872
|
+
async deleteLock(stackName, region) {
|
|
3873
|
+
const key = this.getLockKey(stackName, region);
|
|
3626
3874
|
await this.s3Client.send(
|
|
3627
3875
|
new DeleteObjectCommand2({
|
|
3628
3876
|
Bucket: this.config.bucket,
|
|
@@ -3643,28 +3891,28 @@ var LockManager = class {
|
|
|
3643
3891
|
* @param maxRetries Maximum number of retries (default: 3)
|
|
3644
3892
|
* @param retryDelay Delay between retries in milliseconds (default: 2000)
|
|
3645
3893
|
*/
|
|
3646
|
-
async acquireLockWithRetry(stackName, owner, operation, maxRetries = 3, retryDelay = 2e3) {
|
|
3894
|
+
async acquireLockWithRetry(stackName, region, owner, operation, maxRetries = 3, retryDelay = 2e3) {
|
|
3647
3895
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
3648
|
-
const acquired = await this.acquireLock(stackName, owner, operation);
|
|
3896
|
+
const acquired = await this.acquireLock(stackName, region, owner, operation);
|
|
3649
3897
|
if (acquired) {
|
|
3650
3898
|
return;
|
|
3651
3899
|
}
|
|
3652
|
-
const lockInfo2 = await this.getLockInfo(stackName);
|
|
3900
|
+
const lockInfo2 = await this.getLockInfo(stackName, region);
|
|
3653
3901
|
if (lockInfo2) {
|
|
3654
3902
|
const remainingMs = lockInfo2.expiresAt - Date.now();
|
|
3655
3903
|
if (attempt < maxRetries) {
|
|
3656
3904
|
this.logger.info(
|
|
3657
|
-
`Stack '${stackName}' is locked by ${lockInfo2.owner}${lockInfo2.operation ? ` (operation: ${lockInfo2.operation})` : ""}. Lock expires in ${this.formatDuration(remainingMs)}. Retrying in ${this.formatDuration(retryDelay)}... (attempt ${attempt + 1}/${maxRetries})`
|
|
3905
|
+
`Stack '${stackName}' (${region}) is locked by ${lockInfo2.owner}${lockInfo2.operation ? ` (operation: ${lockInfo2.operation})` : ""}. Lock expires in ${this.formatDuration(remainingMs)}. Retrying in ${this.formatDuration(retryDelay)}... (attempt ${attempt + 1}/${maxRetries})`
|
|
3658
3906
|
);
|
|
3659
3907
|
await new Promise((resolve4) => setTimeout(resolve4, retryDelay));
|
|
3660
3908
|
continue;
|
|
3661
3909
|
}
|
|
3662
3910
|
}
|
|
3663
3911
|
}
|
|
3664
|
-
const lockInfo = await this.getLockInfo(stackName);
|
|
3912
|
+
const lockInfo = await this.getLockInfo(stackName, region);
|
|
3665
3913
|
const expiresIn = lockInfo ? this.formatDuration(lockInfo.expiresAt - Date.now()) : "unknown";
|
|
3666
3914
|
throw new LockError(
|
|
3667
|
-
`Failed to acquire lock for stack '${stackName}' after ${maxRetries + 1} attempts. ` + (lockInfo ? `Locked by: ${lockInfo.owner}${lockInfo.operation ? `, operation: ${lockInfo.operation}` : ""}, expires in: ${expiresIn}. Use --force-unlock to manually release the lock.` : "Lock exists but could not read lock info.")
|
|
3915
|
+
`Failed to acquire lock for stack '${stackName}' (${region}) after ${maxRetries + 1} attempts. ` + (lockInfo ? `Locked by: ${lockInfo.owner}${lockInfo.operation ? `, operation: ${lockInfo.operation}` : ""}, expires in: ${expiresIn}. Use --force-unlock to manually release the lock.` : "Lock exists but could not read lock info.")
|
|
3668
3916
|
);
|
|
3669
3917
|
}
|
|
3670
3918
|
};
|
|
@@ -5447,35 +5695,45 @@ var IntrinsicFunctionResolver = class {
|
|
|
5447
5695
|
}
|
|
5448
5696
|
this.logger.debug(`Resolving Fn::ImportValue: ${exportName}`);
|
|
5449
5697
|
const allStacks = await context.stateBackend.listStacks();
|
|
5450
|
-
this.logger.debug(
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5698
|
+
this.logger.debug(
|
|
5699
|
+
`Found ${allStacks.length} state record(s) to search for export: ${exportName}`
|
|
5700
|
+
);
|
|
5701
|
+
for (const ref of allStacks) {
|
|
5702
|
+
const { stackName: refStack, region: refRegion } = ref;
|
|
5703
|
+
if (context.stackName && refStack === context.stackName) {
|
|
5704
|
+
this.logger.debug(`Skipping current stack: ${refStack}`);
|
|
5454
5705
|
continue;
|
|
5455
5706
|
}
|
|
5456
5707
|
try {
|
|
5457
|
-
const
|
|
5708
|
+
const lookupRegion = refRegion ?? this.resolverRegion ?? "";
|
|
5709
|
+
if (!lookupRegion) {
|
|
5710
|
+
this.logger.debug(
|
|
5711
|
+
`No region available for stack '${refStack}' \u2014 skipping (cdkd cannot read state without a region)`
|
|
5712
|
+
);
|
|
5713
|
+
continue;
|
|
5714
|
+
}
|
|
5715
|
+
const stateData = await context.stateBackend.getState(refStack, lookupRegion);
|
|
5458
5716
|
if (!stateData) {
|
|
5459
|
-
this.logger.debug(`No state found for stack: ${
|
|
5717
|
+
this.logger.debug(`No state found for stack: ${refStack} (${lookupRegion})`);
|
|
5460
5718
|
continue;
|
|
5461
5719
|
}
|
|
5462
5720
|
const { state } = stateData;
|
|
5463
5721
|
if (state.outputs && exportName in state.outputs) {
|
|
5464
5722
|
const value = state.outputs[exportName];
|
|
5465
5723
|
this.logger.info(
|
|
5466
|
-
`Resolved Fn::ImportValue: ${exportName} = ${JSON.stringify(value)} (from stack: ${
|
|
5724
|
+
`Resolved Fn::ImportValue: ${exportName} = ${JSON.stringify(value)} (from stack: ${refStack} / ${lookupRegion})`
|
|
5467
5725
|
);
|
|
5468
5726
|
return value;
|
|
5469
5727
|
}
|
|
5470
5728
|
} catch (error) {
|
|
5471
5729
|
this.logger.warn(
|
|
5472
|
-
`Failed to read state for stack ${
|
|
5730
|
+
`Failed to read state for stack ${refStack}: ${error instanceof Error ? error.message : String(error)}`
|
|
5473
5731
|
);
|
|
5474
5732
|
continue;
|
|
5475
5733
|
}
|
|
5476
5734
|
}
|
|
5477
5735
|
throw new Error(
|
|
5478
|
-
`Fn::ImportValue: export '${exportName}' not found in any stack. Searched ${allStacks.length}
|
|
5736
|
+
`Fn::ImportValue: export '${exportName}' not found in any stack. Searched ${allStacks.length} state record(s). Make sure the exporting stack has been deployed and the Output has an Export.Name property.`
|
|
5479
5737
|
);
|
|
5480
5738
|
}
|
|
5481
5739
|
/**
|
|
@@ -5938,6 +6196,29 @@ var JsonPatchGenerator = class {
|
|
|
5938
6196
|
}
|
|
5939
6197
|
};
|
|
5940
6198
|
|
|
6199
|
+
// src/provisioning/region-check.ts
|
|
6200
|
+
function assertRegionMatch(clientRegion, expectedRegion, resourceType, logicalId, physicalId) {
|
|
6201
|
+
if (!expectedRegion) {
|
|
6202
|
+
return;
|
|
6203
|
+
}
|
|
6204
|
+
if (!clientRegion) {
|
|
6205
|
+
throw new ProvisioningError(
|
|
6206
|
+
`Refusing to treat NotFound as idempotent delete success for ${logicalId} (${resourceType}): AWS client region is unknown but stack state expects ${expectedRegion}. The resource may exist in ${expectedRegion} and would be silently removed from state if this NotFound were trusted.`,
|
|
6207
|
+
resourceType,
|
|
6208
|
+
logicalId,
|
|
6209
|
+
physicalId
|
|
6210
|
+
);
|
|
6211
|
+
}
|
|
6212
|
+
if (clientRegion !== expectedRegion) {
|
|
6213
|
+
throw new ProvisioningError(
|
|
6214
|
+
`Refusing to treat NotFound as idempotent delete success for ${logicalId} (${resourceType}): AWS client region ${clientRegion} does not match stack state region ${expectedRegion}. The resource likely still exists in ${expectedRegion}; rerun the destroy with the correct region (e.g. --region ${expectedRegion}).`,
|
|
6215
|
+
resourceType,
|
|
6216
|
+
logicalId,
|
|
6217
|
+
physicalId
|
|
6218
|
+
);
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
|
|
5941
6222
|
// src/provisioning/cloud-control-provider.ts
|
|
5942
6223
|
var JSON_STRING_PROPERTIES = {
|
|
5943
6224
|
"AWS::Events::Rule": /* @__PURE__ */ new Set(["EventPattern"])
|
|
@@ -6113,7 +6394,7 @@ var CloudControlProvider = class {
|
|
|
6113
6394
|
/**
|
|
6114
6395
|
* Delete a resource using Cloud Control API
|
|
6115
6396
|
*/
|
|
6116
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
6397
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
6117
6398
|
this.logger.debug(
|
|
6118
6399
|
`Deleting resource ${logicalId} (${resourceType}), physical ID: ${physicalId}`
|
|
6119
6400
|
);
|
|
@@ -6140,6 +6421,14 @@ var CloudControlProvider = class {
|
|
|
6140
6421
|
} catch (error) {
|
|
6141
6422
|
const err = error;
|
|
6142
6423
|
if (err.name === "ResourceNotFoundException" || err.message?.includes("does not exist") || err.message?.includes("not found") || err.message?.includes("NotFound")) {
|
|
6424
|
+
const clientRegion = await this.cloudControlClient.config.region();
|
|
6425
|
+
assertRegionMatch(
|
|
6426
|
+
clientRegion,
|
|
6427
|
+
context?.expectedRegion,
|
|
6428
|
+
resourceType,
|
|
6429
|
+
logicalId,
|
|
6430
|
+
physicalId
|
|
6431
|
+
);
|
|
6143
6432
|
this.logger.debug(`Resource ${logicalId} already deleted (not found), treating as success`);
|
|
6144
6433
|
return;
|
|
6145
6434
|
}
|
|
@@ -6704,7 +6993,7 @@ var CustomResourceProvider = class _CustomResourceProvider {
|
|
|
6704
6993
|
/**
|
|
6705
6994
|
* Delete a custom resource by invoking its Lambda handler
|
|
6706
6995
|
*/
|
|
6707
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
6996
|
+
async delete(logicalId, physicalId, resourceType, properties, _context) {
|
|
6708
6997
|
this.logger.debug(`Deleting custom resource ${logicalId}: ${physicalId} (${resourceType})`);
|
|
6709
6998
|
if (!properties) {
|
|
6710
6999
|
this.logger.warn(
|
|
@@ -7526,13 +7815,21 @@ var IAMRoleProvider = class {
|
|
|
7526
7815
|
* 3. Remove role from all instance profiles
|
|
7527
7816
|
* 4. Delete the role itself
|
|
7528
7817
|
*/
|
|
7529
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
7818
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
7530
7819
|
this.logger.debug(`Deleting IAM role ${logicalId}: ${physicalId}`);
|
|
7531
7820
|
try {
|
|
7532
7821
|
try {
|
|
7533
7822
|
await this.iamClient.send(new GetRoleCommand({ RoleName: physicalId }));
|
|
7534
7823
|
} catch (error) {
|
|
7535
7824
|
if (error instanceof NoSuchEntityException) {
|
|
7825
|
+
const clientRegion = await this.iamClient.config.region();
|
|
7826
|
+
assertRegionMatch(
|
|
7827
|
+
clientRegion,
|
|
7828
|
+
context?.expectedRegion,
|
|
7829
|
+
resourceType,
|
|
7830
|
+
logicalId,
|
|
7831
|
+
physicalId
|
|
7832
|
+
);
|
|
7536
7833
|
this.logger.debug(`Role ${physicalId} does not exist, skipping deletion`);
|
|
7537
7834
|
return;
|
|
7538
7835
|
}
|
|
@@ -8027,13 +8324,23 @@ var IAMPolicyProvider = class {
|
|
|
8027
8324
|
/**
|
|
8028
8325
|
* Delete an IAM inline policy
|
|
8029
8326
|
*/
|
|
8030
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
8327
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
8031
8328
|
this.logger.debug(`Deleting IAM policy ${logicalId}: ${physicalId}`);
|
|
8032
8329
|
const policyName = physicalId.includes(":") ? physicalId.split(":")[0] : physicalId;
|
|
8033
8330
|
if (!policyName) {
|
|
8034
8331
|
this.logger.warn(`Invalid physical ID format: ${physicalId}, skipping deletion`);
|
|
8035
8332
|
return;
|
|
8036
8333
|
}
|
|
8334
|
+
const onNotFound = async (target) => {
|
|
8335
|
+
const clientRegion = await this.iamClient.config.region();
|
|
8336
|
+
assertRegionMatch(
|
|
8337
|
+
clientRegion,
|
|
8338
|
+
context?.expectedRegion,
|
|
8339
|
+
resourceType,
|
|
8340
|
+
logicalId,
|
|
8341
|
+
`${physicalId} (${target})`
|
|
8342
|
+
);
|
|
8343
|
+
};
|
|
8037
8344
|
try {
|
|
8038
8345
|
const roles = properties?.["Roles"];
|
|
8039
8346
|
const groups = properties?.["Groups"];
|
|
@@ -8050,7 +8357,9 @@ var IAMPolicyProvider = class {
|
|
|
8050
8357
|
);
|
|
8051
8358
|
this.logger.debug(`Deleted inline policy ${policyName} from role ${firstRole}`);
|
|
8052
8359
|
} catch (error) {
|
|
8053
|
-
if (
|
|
8360
|
+
if (error instanceof NoSuchEntityException2) {
|
|
8361
|
+
await onNotFound(`role ${firstRole}`);
|
|
8362
|
+
} else {
|
|
8054
8363
|
throw error;
|
|
8055
8364
|
}
|
|
8056
8365
|
}
|
|
@@ -8067,7 +8376,9 @@ var IAMPolicyProvider = class {
|
|
|
8067
8376
|
);
|
|
8068
8377
|
this.logger.debug(`Deleted inline policy ${policyName} from role ${roleName}`);
|
|
8069
8378
|
} catch (error) {
|
|
8070
|
-
if (
|
|
8379
|
+
if (error instanceof NoSuchEntityException2) {
|
|
8380
|
+
await onNotFound(`role ${roleName}`);
|
|
8381
|
+
} else {
|
|
8071
8382
|
throw error;
|
|
8072
8383
|
}
|
|
8073
8384
|
}
|
|
@@ -8084,7 +8395,9 @@ var IAMPolicyProvider = class {
|
|
|
8084
8395
|
);
|
|
8085
8396
|
this.logger.debug(`Deleted inline policy ${policyName} from group ${groupName}`);
|
|
8086
8397
|
} catch (error) {
|
|
8087
|
-
if (
|
|
8398
|
+
if (error instanceof NoSuchEntityException2) {
|
|
8399
|
+
await onNotFound(`group ${groupName}`);
|
|
8400
|
+
} else {
|
|
8088
8401
|
throw error;
|
|
8089
8402
|
}
|
|
8090
8403
|
}
|
|
@@ -8101,7 +8414,9 @@ var IAMPolicyProvider = class {
|
|
|
8101
8414
|
);
|
|
8102
8415
|
this.logger.debug(`Deleted inline policy ${policyName} from user ${userName}`);
|
|
8103
8416
|
} catch (error) {
|
|
8104
|
-
if (
|
|
8417
|
+
if (error instanceof NoSuchEntityException2) {
|
|
8418
|
+
await onNotFound(`user ${userName}`);
|
|
8419
|
+
} else {
|
|
8105
8420
|
throw error;
|
|
8106
8421
|
}
|
|
8107
8422
|
}
|
|
@@ -8259,7 +8574,7 @@ var IAMInstanceProfileProvider = class {
|
|
|
8259
8574
|
*
|
|
8260
8575
|
* Before deleting, removes all roles from the instance profile.
|
|
8261
8576
|
*/
|
|
8262
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
8577
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
8263
8578
|
this.logger.debug(`Deleting IAM instance profile ${logicalId}: ${physicalId}`);
|
|
8264
8579
|
try {
|
|
8265
8580
|
let roles = [];
|
|
@@ -8272,6 +8587,14 @@ var IAMInstanceProfileProvider = class {
|
|
|
8272
8587
|
) || [];
|
|
8273
8588
|
} catch (error) {
|
|
8274
8589
|
if (error instanceof NoSuchEntityException3) {
|
|
8590
|
+
const clientRegion = await this.iamClient.config.region();
|
|
8591
|
+
assertRegionMatch(
|
|
8592
|
+
clientRegion,
|
|
8593
|
+
context?.expectedRegion,
|
|
8594
|
+
resourceType,
|
|
8595
|
+
logicalId,
|
|
8596
|
+
physicalId
|
|
8597
|
+
);
|
|
8275
8598
|
this.logger.debug(`Instance profile ${physicalId} does not exist, skipping deletion`);
|
|
8276
8599
|
return;
|
|
8277
8600
|
}
|
|
@@ -8298,6 +8621,14 @@ var IAMInstanceProfileProvider = class {
|
|
|
8298
8621
|
this.logger.debug(`Successfully deleted IAM instance profile ${logicalId}`);
|
|
8299
8622
|
} catch (error) {
|
|
8300
8623
|
if (error instanceof NoSuchEntityException3) {
|
|
8624
|
+
const clientRegion = await this.iamClient.config.region();
|
|
8625
|
+
assertRegionMatch(
|
|
8626
|
+
clientRegion,
|
|
8627
|
+
context?.expectedRegion,
|
|
8628
|
+
resourceType,
|
|
8629
|
+
logicalId,
|
|
8630
|
+
physicalId
|
|
8631
|
+
);
|
|
8301
8632
|
this.logger.debug(`Instance profile ${physicalId} does not exist, skipping deletion`);
|
|
8302
8633
|
return;
|
|
8303
8634
|
}
|
|
@@ -8417,14 +8748,20 @@ var IAMUserGroupProvider = class {
|
|
|
8417
8748
|
);
|
|
8418
8749
|
}
|
|
8419
8750
|
}
|
|
8420
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
8751
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
8421
8752
|
switch (resourceType) {
|
|
8422
8753
|
case "AWS::IAM::User":
|
|
8423
|
-
return this.deleteUser(logicalId, physicalId, resourceType);
|
|
8754
|
+
return this.deleteUser(logicalId, physicalId, resourceType, context);
|
|
8424
8755
|
case "AWS::IAM::Group":
|
|
8425
|
-
return this.deleteGroup(logicalId, physicalId, resourceType);
|
|
8756
|
+
return this.deleteGroup(logicalId, physicalId, resourceType, context);
|
|
8426
8757
|
case "AWS::IAM::UserToGroupAddition":
|
|
8427
|
-
return this.deleteUserToGroupAddition(
|
|
8758
|
+
return this.deleteUserToGroupAddition(
|
|
8759
|
+
logicalId,
|
|
8760
|
+
physicalId,
|
|
8761
|
+
resourceType,
|
|
8762
|
+
properties,
|
|
8763
|
+
context
|
|
8764
|
+
);
|
|
8428
8765
|
default:
|
|
8429
8766
|
throw new ProvisioningError(
|
|
8430
8767
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -8627,13 +8964,21 @@ var IAMUserGroupProvider = class {
|
|
|
8627
8964
|
);
|
|
8628
8965
|
}
|
|
8629
8966
|
}
|
|
8630
|
-
async deleteUser(logicalId, physicalId, resourceType) {
|
|
8967
|
+
async deleteUser(logicalId, physicalId, resourceType, context) {
|
|
8631
8968
|
this.logger.debug(`Deleting IAM user ${logicalId}: ${physicalId}`);
|
|
8632
8969
|
try {
|
|
8633
8970
|
try {
|
|
8634
8971
|
await this.iamClient.send(new GetUserCommand({ UserName: physicalId }));
|
|
8635
8972
|
} catch (error) {
|
|
8636
8973
|
if (error instanceof NoSuchEntityException4) {
|
|
8974
|
+
const clientRegion = await this.iamClient.config.region();
|
|
8975
|
+
assertRegionMatch(
|
|
8976
|
+
clientRegion,
|
|
8977
|
+
context?.expectedRegion,
|
|
8978
|
+
resourceType,
|
|
8979
|
+
logicalId,
|
|
8980
|
+
physicalId
|
|
8981
|
+
);
|
|
8637
8982
|
this.logger.debug(`User ${physicalId} does not exist, skipping deletion`);
|
|
8638
8983
|
return;
|
|
8639
8984
|
}
|
|
@@ -8973,7 +9318,7 @@ var IAMUserGroupProvider = class {
|
|
|
8973
9318
|
);
|
|
8974
9319
|
}
|
|
8975
9320
|
}
|
|
8976
|
-
async deleteGroup(logicalId, physicalId, resourceType) {
|
|
9321
|
+
async deleteGroup(logicalId, physicalId, resourceType, context) {
|
|
8977
9322
|
this.logger.debug(`Deleting IAM group ${logicalId}: ${physicalId}`);
|
|
8978
9323
|
try {
|
|
8979
9324
|
await this.detachAllGroupPolicies(physicalId);
|
|
@@ -8983,6 +9328,14 @@ var IAMUserGroupProvider = class {
|
|
|
8983
9328
|
this.logger.debug(`Successfully deleted IAM group ${logicalId}`);
|
|
8984
9329
|
} catch (error) {
|
|
8985
9330
|
if (error instanceof NoSuchEntityException4) {
|
|
9331
|
+
const clientRegion = await this.iamClient.config.region();
|
|
9332
|
+
assertRegionMatch(
|
|
9333
|
+
clientRegion,
|
|
9334
|
+
context?.expectedRegion,
|
|
9335
|
+
resourceType,
|
|
9336
|
+
logicalId,
|
|
9337
|
+
physicalId
|
|
9338
|
+
);
|
|
8986
9339
|
this.logger.debug(`Group ${physicalId} does not exist, skipping deletion`);
|
|
8987
9340
|
return;
|
|
8988
9341
|
}
|
|
@@ -9257,7 +9610,7 @@ var IAMUserGroupProvider = class {
|
|
|
9257
9610
|
);
|
|
9258
9611
|
}
|
|
9259
9612
|
}
|
|
9260
|
-
async deleteUserToGroupAddition(logicalId, physicalId, resourceType, properties) {
|
|
9613
|
+
async deleteUserToGroupAddition(logicalId, physicalId, resourceType, properties, _context) {
|
|
9261
9614
|
this.logger.debug(`Deleting IAM UserToGroupAddition ${logicalId}`);
|
|
9262
9615
|
if (!properties) {
|
|
9263
9616
|
this.logger.debug(`No properties for UserToGroupAddition ${logicalId}, skipping deletion`);
|
|
@@ -10131,12 +10484,20 @@ var S3BucketProvider = class {
|
|
|
10131
10484
|
*
|
|
10132
10485
|
* Note: The bucket must be empty before deletion.
|
|
10133
10486
|
*/
|
|
10134
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
10487
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
10135
10488
|
this.logger.debug(`Deleting S3 bucket ${logicalId}: ${physicalId}`);
|
|
10136
10489
|
try {
|
|
10137
10490
|
await this.deleteBucketWithEmptyRetry(logicalId, physicalId);
|
|
10138
10491
|
} catch (error) {
|
|
10139
10492
|
if (error instanceof NoSuchBucket) {
|
|
10493
|
+
const clientRegion = await this.s3Client.config.region();
|
|
10494
|
+
assertRegionMatch(
|
|
10495
|
+
clientRegion,
|
|
10496
|
+
context?.expectedRegion,
|
|
10497
|
+
resourceType,
|
|
10498
|
+
logicalId,
|
|
10499
|
+
physicalId
|
|
10500
|
+
);
|
|
10140
10501
|
this.logger.debug(`Bucket ${physicalId} does not exist, skipping deletion`);
|
|
10141
10502
|
return;
|
|
10142
10503
|
}
|
|
@@ -10331,7 +10692,7 @@ var S3BucketPolicyProvider = class {
|
|
|
10331
10692
|
/**
|
|
10332
10693
|
* Delete an S3 bucket policy
|
|
10333
10694
|
*/
|
|
10334
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
10695
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
10335
10696
|
this.logger.debug(`Deleting S3 bucket policy ${logicalId}: ${physicalId}`);
|
|
10336
10697
|
try {
|
|
10337
10698
|
try {
|
|
@@ -10343,10 +10704,26 @@ var S3BucketPolicyProvider = class {
|
|
|
10343
10704
|
this.logger.debug(`Successfully deleted S3 bucket policy ${logicalId}`);
|
|
10344
10705
|
} catch (error) {
|
|
10345
10706
|
if (error instanceof NoSuchBucket2) {
|
|
10707
|
+
const clientRegion = await this.s3Client.config.region();
|
|
10708
|
+
assertRegionMatch(
|
|
10709
|
+
clientRegion,
|
|
10710
|
+
context?.expectedRegion,
|
|
10711
|
+
resourceType,
|
|
10712
|
+
logicalId,
|
|
10713
|
+
physicalId
|
|
10714
|
+
);
|
|
10346
10715
|
this.logger.debug(`Bucket ${physicalId} does not exist, skipping policy deletion`);
|
|
10347
10716
|
return;
|
|
10348
10717
|
}
|
|
10349
10718
|
if (error instanceof Error && (error.name === "NoSuchBucketPolicy" || error.message.includes("does not have"))) {
|
|
10719
|
+
const clientRegion = await this.s3Client.config.region();
|
|
10720
|
+
assertRegionMatch(
|
|
10721
|
+
clientRegion,
|
|
10722
|
+
context?.expectedRegion,
|
|
10723
|
+
resourceType,
|
|
10724
|
+
logicalId,
|
|
10725
|
+
physicalId
|
|
10726
|
+
);
|
|
10350
10727
|
this.logger.debug(`Bucket policy for ${physicalId} does not exist, skipping`);
|
|
10351
10728
|
return;
|
|
10352
10729
|
}
|
|
@@ -10536,13 +10913,21 @@ var SQSQueueProvider = class {
|
|
|
10536
10913
|
/**
|
|
10537
10914
|
* Delete an SQS queue
|
|
10538
10915
|
*/
|
|
10539
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
10916
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
10540
10917
|
this.logger.debug(`Deleting SQS queue ${logicalId}: ${physicalId}`);
|
|
10541
10918
|
try {
|
|
10542
10919
|
await this.sqsClient.send(new DeleteQueueCommand({ QueueUrl: physicalId }));
|
|
10543
10920
|
this.logger.debug(`Successfully deleted SQS queue ${logicalId}`);
|
|
10544
10921
|
} catch (error) {
|
|
10545
10922
|
if (error instanceof QueueDoesNotExist) {
|
|
10923
|
+
const clientRegion = await this.sqsClient.config.region();
|
|
10924
|
+
assertRegionMatch(
|
|
10925
|
+
clientRegion,
|
|
10926
|
+
context?.expectedRegion,
|
|
10927
|
+
resourceType,
|
|
10928
|
+
logicalId,
|
|
10929
|
+
physicalId
|
|
10930
|
+
);
|
|
10546
10931
|
this.logger.debug(`SQS queue ${physicalId} does not exist, skipping deletion`);
|
|
10547
10932
|
return;
|
|
10548
10933
|
}
|
|
@@ -10691,7 +11076,7 @@ var SQSQueuePolicyProvider = class {
|
|
|
10691
11076
|
/**
|
|
10692
11077
|
* Delete an SQS queue policy
|
|
10693
11078
|
*/
|
|
10694
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
11079
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
10695
11080
|
this.logger.debug(`Deleting SQS queue policy ${logicalId}: ${physicalId}`);
|
|
10696
11081
|
try {
|
|
10697
11082
|
await this.sqsClient.send(
|
|
@@ -10705,6 +11090,14 @@ var SQSQueuePolicyProvider = class {
|
|
|
10705
11090
|
this.logger.debug(`Successfully deleted SQS queue policy ${logicalId}`);
|
|
10706
11091
|
} catch (error) {
|
|
10707
11092
|
if (error instanceof Error && (error.name === "QueueDoesNotExist" || error.message.includes("does not exist"))) {
|
|
11093
|
+
const clientRegion = await this.sqsClient.config.region();
|
|
11094
|
+
assertRegionMatch(
|
|
11095
|
+
clientRegion,
|
|
11096
|
+
context?.expectedRegion,
|
|
11097
|
+
resourceType,
|
|
11098
|
+
logicalId,
|
|
11099
|
+
physicalId
|
|
11100
|
+
);
|
|
10708
11101
|
this.logger.debug(`Queue ${physicalId} does not exist, skipping policy deletion`);
|
|
10709
11102
|
return;
|
|
10710
11103
|
}
|
|
@@ -10985,13 +11378,21 @@ var SNSTopicProvider = class {
|
|
|
10985
11378
|
/**
|
|
10986
11379
|
* Delete an SNS topic
|
|
10987
11380
|
*/
|
|
10988
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
11381
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
10989
11382
|
this.logger.debug(`Deleting SNS topic ${logicalId}: ${physicalId}`);
|
|
10990
11383
|
try {
|
|
10991
11384
|
await this.snsClient.send(new DeleteTopicCommand({ TopicArn: physicalId }));
|
|
10992
11385
|
this.logger.debug(`Successfully deleted SNS topic ${logicalId}`);
|
|
10993
11386
|
} catch (error) {
|
|
10994
11387
|
if (error instanceof NotFoundException) {
|
|
11388
|
+
const clientRegion = await this.snsClient.config.region();
|
|
11389
|
+
assertRegionMatch(
|
|
11390
|
+
clientRegion,
|
|
11391
|
+
context?.expectedRegion,
|
|
11392
|
+
resourceType,
|
|
11393
|
+
logicalId,
|
|
11394
|
+
physicalId
|
|
11395
|
+
);
|
|
10995
11396
|
this.logger.debug(`SNS topic ${physicalId} does not exist, skipping deletion`);
|
|
10996
11397
|
return;
|
|
10997
11398
|
}
|
|
@@ -11110,7 +11511,7 @@ var SNSSubscriptionProvider = class {
|
|
|
11110
11511
|
/**
|
|
11111
11512
|
* Delete an SNS subscription
|
|
11112
11513
|
*/
|
|
11113
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
11514
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
11114
11515
|
this.logger.debug(`Deleting SNS subscription ${logicalId}: ${physicalId}`);
|
|
11115
11516
|
try {
|
|
11116
11517
|
await this.snsClient.send(
|
|
@@ -11121,6 +11522,14 @@ var SNSSubscriptionProvider = class {
|
|
|
11121
11522
|
this.logger.debug(`Successfully deleted SNS subscription ${logicalId}`);
|
|
11122
11523
|
} catch (error) {
|
|
11123
11524
|
if (error instanceof NotFoundException2) {
|
|
11525
|
+
const clientRegion = await this.snsClient.config.region();
|
|
11526
|
+
assertRegionMatch(
|
|
11527
|
+
clientRegion,
|
|
11528
|
+
context?.expectedRegion,
|
|
11529
|
+
resourceType,
|
|
11530
|
+
logicalId,
|
|
11531
|
+
physicalId
|
|
11532
|
+
);
|
|
11124
11533
|
this.logger.debug(`Subscription ${physicalId} does not exist, skipping deletion`);
|
|
11125
11534
|
return;
|
|
11126
11535
|
}
|
|
@@ -11241,7 +11650,7 @@ var SNSTopicPolicyProvider = class {
|
|
|
11241
11650
|
*
|
|
11242
11651
|
* Removes the policy from each topic by setting an empty policy.
|
|
11243
11652
|
*/
|
|
11244
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
11653
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
11245
11654
|
this.logger.debug(`Deleting SNS topic policy ${logicalId}: ${physicalId}`);
|
|
11246
11655
|
const topicArns = physicalId.split(",");
|
|
11247
11656
|
for (const topicArn of topicArns) {
|
|
@@ -11250,6 +11659,14 @@ var SNSTopicPolicyProvider = class {
|
|
|
11250
11659
|
this.logger.debug(`Removed policy from topic ${topicArn}`);
|
|
11251
11660
|
} catch (error) {
|
|
11252
11661
|
if (error instanceof Error && (error.name === "NotFoundException" || error.name === "NotFound" || error.message.includes("not found") || error.message.includes("does not exist") || error.message.includes("Invalid parameter"))) {
|
|
11662
|
+
const clientRegion = await getAwsClients().sns.config.region();
|
|
11663
|
+
assertRegionMatch(
|
|
11664
|
+
clientRegion,
|
|
11665
|
+
context?.expectedRegion,
|
|
11666
|
+
resourceType,
|
|
11667
|
+
logicalId,
|
|
11668
|
+
topicArn
|
|
11669
|
+
);
|
|
11253
11670
|
this.logger.debug(`Topic ${topicArn} not found or policy already removed, skipping`);
|
|
11254
11671
|
continue;
|
|
11255
11672
|
}
|
|
@@ -11514,7 +11931,7 @@ var LambdaFunctionProvider = class {
|
|
|
11514
11931
|
* security groups, we poll DescribeNetworkInterfaces for the function's
|
|
11515
11932
|
* managed ENIs and only return once they are gone (or the timeout elapses).
|
|
11516
11933
|
*/
|
|
11517
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
11934
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
11518
11935
|
this.logger.debug(`Deleting Lambda function ${logicalId}: ${physicalId}`);
|
|
11519
11936
|
const hasVpcConfig = this.hasVpcConfig(properties?.["VpcConfig"]);
|
|
11520
11937
|
if (hasVpcConfig) {
|
|
@@ -11528,6 +11945,14 @@ var LambdaFunctionProvider = class {
|
|
|
11528
11945
|
this.logger.debug(`Detached VPC config from Lambda ${physicalId} before deletion`);
|
|
11529
11946
|
} catch (error) {
|
|
11530
11947
|
if (error instanceof ResourceNotFoundException) {
|
|
11948
|
+
const clientRegion = await this.lambdaClient.config.region();
|
|
11949
|
+
assertRegionMatch(
|
|
11950
|
+
clientRegion,
|
|
11951
|
+
context?.expectedRegion,
|
|
11952
|
+
resourceType,
|
|
11953
|
+
logicalId,
|
|
11954
|
+
physicalId
|
|
11955
|
+
);
|
|
11531
11956
|
return;
|
|
11532
11957
|
}
|
|
11533
11958
|
this.logger.warn(
|
|
@@ -11541,6 +11966,14 @@ var LambdaFunctionProvider = class {
|
|
|
11541
11966
|
this.logger.debug(`Successfully deleted Lambda function ${logicalId}`);
|
|
11542
11967
|
} catch (error) {
|
|
11543
11968
|
if (error instanceof ResourceNotFoundException) {
|
|
11969
|
+
const clientRegion = await this.lambdaClient.config.region();
|
|
11970
|
+
assertRegionMatch(
|
|
11971
|
+
clientRegion,
|
|
11972
|
+
context?.expectedRegion,
|
|
11973
|
+
resourceType,
|
|
11974
|
+
logicalId,
|
|
11975
|
+
physicalId
|
|
11976
|
+
);
|
|
11544
11977
|
this.logger.debug(`Lambda function ${physicalId} does not exist, skipping deletion`);
|
|
11545
11978
|
return;
|
|
11546
11979
|
}
|
|
@@ -12007,7 +12440,7 @@ var LambdaPermissionProvider = class {
|
|
|
12007
12440
|
/**
|
|
12008
12441
|
* Delete a Lambda permission
|
|
12009
12442
|
*/
|
|
12010
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
12443
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
12011
12444
|
this.logger.debug(`Deleting Lambda permission ${logicalId}: ${physicalId}`);
|
|
12012
12445
|
const functionName = properties?.["FunctionName"];
|
|
12013
12446
|
if (!functionName) {
|
|
@@ -12030,6 +12463,14 @@ var LambdaPermissionProvider = class {
|
|
|
12030
12463
|
this.logger.debug(`Successfully deleted Lambda permission ${logicalId}`);
|
|
12031
12464
|
} catch (error) {
|
|
12032
12465
|
if (error instanceof ResourceNotFoundException2) {
|
|
12466
|
+
const clientRegion = await this.lambdaClient.config.region();
|
|
12467
|
+
assertRegionMatch(
|
|
12468
|
+
clientRegion,
|
|
12469
|
+
context?.expectedRegion,
|
|
12470
|
+
resourceType,
|
|
12471
|
+
logicalId,
|
|
12472
|
+
physicalId
|
|
12473
|
+
);
|
|
12033
12474
|
this.logger.debug(`Lambda permission ${physicalId} does not exist, skipping deletion`);
|
|
12034
12475
|
return;
|
|
12035
12476
|
}
|
|
@@ -12146,7 +12587,7 @@ var LambdaUrlProvider = class {
|
|
|
12146
12587
|
/**
|
|
12147
12588
|
* Delete a Lambda Function URL
|
|
12148
12589
|
*/
|
|
12149
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
12590
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
12150
12591
|
this.logger.debug(`Deleting Lambda URL ${logicalId}: ${physicalId}`);
|
|
12151
12592
|
try {
|
|
12152
12593
|
await this.lambdaClient.send(
|
|
@@ -12155,6 +12596,14 @@ var LambdaUrlProvider = class {
|
|
|
12155
12596
|
this.logger.debug(`Successfully deleted Lambda URL ${logicalId}`);
|
|
12156
12597
|
} catch (error) {
|
|
12157
12598
|
if (error instanceof ResourceNotFoundException3) {
|
|
12599
|
+
const clientRegion = await this.lambdaClient.config.region();
|
|
12600
|
+
assertRegionMatch(
|
|
12601
|
+
clientRegion,
|
|
12602
|
+
context?.expectedRegion,
|
|
12603
|
+
resourceType,
|
|
12604
|
+
logicalId,
|
|
12605
|
+
physicalId
|
|
12606
|
+
);
|
|
12158
12607
|
this.logger.debug(`Lambda URL ${physicalId} does not exist, skipping deletion`);
|
|
12159
12608
|
return;
|
|
12160
12609
|
}
|
|
@@ -12365,13 +12814,21 @@ var LambdaEventSourceMappingProvider = class {
|
|
|
12365
12814
|
/**
|
|
12366
12815
|
* Delete a Lambda Event Source Mapping
|
|
12367
12816
|
*/
|
|
12368
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
12817
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
12369
12818
|
this.logger.debug(`Deleting event source mapping ${logicalId}: ${physicalId}`);
|
|
12370
12819
|
try {
|
|
12371
12820
|
try {
|
|
12372
12821
|
await this.lambdaClient.send(new GetEventSourceMappingCommand({ UUID: physicalId }));
|
|
12373
12822
|
} catch (error) {
|
|
12374
12823
|
if (error instanceof ResourceNotFoundException4) {
|
|
12824
|
+
const clientRegion = await this.lambdaClient.config.region();
|
|
12825
|
+
assertRegionMatch(
|
|
12826
|
+
clientRegion,
|
|
12827
|
+
context?.expectedRegion,
|
|
12828
|
+
resourceType,
|
|
12829
|
+
logicalId,
|
|
12830
|
+
physicalId
|
|
12831
|
+
);
|
|
12375
12832
|
this.logger.debug(`Event source mapping ${physicalId} does not exist, skipping deletion`);
|
|
12376
12833
|
return;
|
|
12377
12834
|
}
|
|
@@ -12381,6 +12838,14 @@ var LambdaEventSourceMappingProvider = class {
|
|
|
12381
12838
|
this.logger.debug(`Successfully deleted event source mapping ${logicalId}`);
|
|
12382
12839
|
} catch (error) {
|
|
12383
12840
|
if (error instanceof ResourceNotFoundException4) {
|
|
12841
|
+
const clientRegion = await this.lambdaClient.config.region();
|
|
12842
|
+
assertRegionMatch(
|
|
12843
|
+
clientRegion,
|
|
12844
|
+
context?.expectedRegion,
|
|
12845
|
+
resourceType,
|
|
12846
|
+
logicalId,
|
|
12847
|
+
physicalId
|
|
12848
|
+
);
|
|
12384
12849
|
this.logger.debug(`Event source mapping ${physicalId} does not exist, skipping deletion`);
|
|
12385
12850
|
return;
|
|
12386
12851
|
}
|
|
@@ -12494,7 +12959,7 @@ var LambdaLayerVersionProvider = class {
|
|
|
12494
12959
|
/**
|
|
12495
12960
|
* Delete a Lambda layer version
|
|
12496
12961
|
*/
|
|
12497
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
12962
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
12498
12963
|
this.logger.debug(`Deleting Lambda layer version ${logicalId}: ${physicalId}`);
|
|
12499
12964
|
const arnParts = physicalId.split(":");
|
|
12500
12965
|
if (arnParts.length < 8) {
|
|
@@ -12517,6 +12982,14 @@ var LambdaLayerVersionProvider = class {
|
|
|
12517
12982
|
this.logger.debug(`Successfully deleted Lambda layer version ${logicalId}`);
|
|
12518
12983
|
} catch (error) {
|
|
12519
12984
|
if (error instanceof ResourceNotFoundException5) {
|
|
12985
|
+
const clientRegion = await this.lambdaClient.config.region();
|
|
12986
|
+
assertRegionMatch(
|
|
12987
|
+
clientRegion,
|
|
12988
|
+
context?.expectedRegion,
|
|
12989
|
+
resourceType,
|
|
12990
|
+
logicalId,
|
|
12991
|
+
physicalId
|
|
12992
|
+
);
|
|
12520
12993
|
this.logger.debug(`Lambda layer version ${physicalId} does not exist, skipping deletion`);
|
|
12521
12994
|
return;
|
|
12522
12995
|
}
|
|
@@ -12693,13 +13166,21 @@ var DynamoDBTableProvider = class {
|
|
|
12693
13166
|
/**
|
|
12694
13167
|
* Delete a DynamoDB table
|
|
12695
13168
|
*/
|
|
12696
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
13169
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
12697
13170
|
this.logger.debug(`Deleting DynamoDB table ${logicalId}: ${physicalId}`);
|
|
12698
13171
|
try {
|
|
12699
13172
|
await this.dynamoDBClient.send(new DeleteTableCommand({ TableName: physicalId }));
|
|
12700
13173
|
this.logger.debug(`Successfully deleted DynamoDB table ${logicalId}`);
|
|
12701
13174
|
} catch (error) {
|
|
12702
13175
|
if (error instanceof ResourceNotFoundException6) {
|
|
13176
|
+
const clientRegion = await this.dynamoDBClient.config.region();
|
|
13177
|
+
assertRegionMatch(
|
|
13178
|
+
clientRegion,
|
|
13179
|
+
context?.expectedRegion,
|
|
13180
|
+
resourceType,
|
|
13181
|
+
logicalId,
|
|
13182
|
+
physicalId
|
|
13183
|
+
);
|
|
12703
13184
|
this.logger.debug(`DynamoDB table ${physicalId} does not exist, skipping deletion`);
|
|
12704
13185
|
return;
|
|
12705
13186
|
}
|
|
@@ -12928,13 +13409,21 @@ var LogsLogGroupProvider = class {
|
|
|
12928
13409
|
/**
|
|
12929
13410
|
* Delete a CloudWatch Logs log group
|
|
12930
13411
|
*/
|
|
12931
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
13412
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
12932
13413
|
this.logger.debug(`Deleting log group ${logicalId}: ${physicalId}`);
|
|
12933
13414
|
try {
|
|
12934
13415
|
await this.logsClient.send(new DeleteLogGroupCommand({ logGroupName: physicalId }));
|
|
12935
13416
|
this.logger.debug(`Successfully deleted log group ${logicalId}`);
|
|
12936
13417
|
} catch (error) {
|
|
12937
13418
|
if (error instanceof ResourceNotFoundException7) {
|
|
13419
|
+
const clientRegion = await this.logsClient.config.region();
|
|
13420
|
+
assertRegionMatch(
|
|
13421
|
+
clientRegion,
|
|
13422
|
+
context?.expectedRegion,
|
|
13423
|
+
resourceType,
|
|
13424
|
+
logicalId,
|
|
13425
|
+
physicalId
|
|
13426
|
+
);
|
|
12938
13427
|
this.logger.debug(`Log group ${physicalId} does not exist, skipping deletion`);
|
|
12939
13428
|
return;
|
|
12940
13429
|
}
|
|
@@ -13065,7 +13554,7 @@ var CloudWatchAlarmProvider = class {
|
|
|
13065
13554
|
/**
|
|
13066
13555
|
* Delete a CloudWatch alarm
|
|
13067
13556
|
*/
|
|
13068
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
13557
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
13069
13558
|
this.logger.debug(`Deleting CloudWatch alarm ${logicalId}: ${physicalId}`);
|
|
13070
13559
|
try {
|
|
13071
13560
|
await this.cloudWatchClient.send(
|
|
@@ -13076,6 +13565,14 @@ var CloudWatchAlarmProvider = class {
|
|
|
13076
13565
|
this.logger.debug(`Successfully deleted CloudWatch alarm ${logicalId}`);
|
|
13077
13566
|
} catch (error) {
|
|
13078
13567
|
if (error instanceof Error && error.name === "ResourceNotFound") {
|
|
13568
|
+
const clientRegion = await this.cloudWatchClient.config.region();
|
|
13569
|
+
assertRegionMatch(
|
|
13570
|
+
clientRegion,
|
|
13571
|
+
context?.expectedRegion,
|
|
13572
|
+
resourceType,
|
|
13573
|
+
logicalId,
|
|
13574
|
+
physicalId
|
|
13575
|
+
);
|
|
13079
13576
|
this.logger.debug(`Alarm ${physicalId} does not exist, skipping deletion`);
|
|
13080
13577
|
return;
|
|
13081
13578
|
}
|
|
@@ -13369,7 +13866,7 @@ var SecretsManagerSecretProvider = class {
|
|
|
13369
13866
|
/**
|
|
13370
13867
|
* Delete a Secrets Manager secret
|
|
13371
13868
|
*/
|
|
13372
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
13869
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
13373
13870
|
this.logger.debug(`Deleting secret ${logicalId}: ${physicalId}`);
|
|
13374
13871
|
try {
|
|
13375
13872
|
await this.smClient.send(
|
|
@@ -13381,6 +13878,14 @@ var SecretsManagerSecretProvider = class {
|
|
|
13381
13878
|
this.logger.debug(`Successfully deleted secret ${logicalId}`);
|
|
13382
13879
|
} catch (error) {
|
|
13383
13880
|
if (error instanceof ResourceNotFoundException8) {
|
|
13881
|
+
const clientRegion = await this.smClient.config.region();
|
|
13882
|
+
assertRegionMatch(
|
|
13883
|
+
clientRegion,
|
|
13884
|
+
context?.expectedRegion,
|
|
13885
|
+
resourceType,
|
|
13886
|
+
logicalId,
|
|
13887
|
+
physicalId
|
|
13888
|
+
);
|
|
13384
13889
|
this.logger.debug(`Secret ${physicalId} does not exist, skipping deletion`);
|
|
13385
13890
|
return;
|
|
13386
13891
|
}
|
|
@@ -13625,7 +14130,7 @@ var SSMParameterProvider = class {
|
|
|
13625
14130
|
/**
|
|
13626
14131
|
* Delete an SSM parameter
|
|
13627
14132
|
*/
|
|
13628
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
14133
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
13629
14134
|
this.logger.debug(`Deleting SSM parameter ${logicalId}: ${physicalId}`);
|
|
13630
14135
|
try {
|
|
13631
14136
|
await this.ssmClient.send(
|
|
@@ -13636,6 +14141,14 @@ var SSMParameterProvider = class {
|
|
|
13636
14141
|
this.logger.debug(`Successfully deleted SSM parameter ${logicalId}`);
|
|
13637
14142
|
} catch (error) {
|
|
13638
14143
|
if (error instanceof ParameterNotFound) {
|
|
14144
|
+
const clientRegion = await this.ssmClient.config.region();
|
|
14145
|
+
assertRegionMatch(
|
|
14146
|
+
clientRegion,
|
|
14147
|
+
context?.expectedRegion,
|
|
14148
|
+
resourceType,
|
|
14149
|
+
logicalId,
|
|
14150
|
+
physicalId
|
|
14151
|
+
);
|
|
13639
14152
|
this.logger.debug(`Parameter ${physicalId} does not exist, skipping deletion`);
|
|
13640
14153
|
return;
|
|
13641
14154
|
}
|
|
@@ -13854,7 +14367,7 @@ var EventBridgeRuleProvider = class {
|
|
|
13854
14367
|
*
|
|
13855
14368
|
* Before deleting, removes all targets (required by EventBridge API).
|
|
13856
14369
|
*/
|
|
13857
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
14370
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
13858
14371
|
this.logger.debug(`Deleting EventBridge rule ${logicalId}: ${physicalId}`);
|
|
13859
14372
|
const ruleName = this.extractRuleNameFromArn(physicalId);
|
|
13860
14373
|
try {
|
|
@@ -13866,6 +14379,14 @@ var EventBridgeRuleProvider = class {
|
|
|
13866
14379
|
targetIds = (targetsResponse.Targets || []).map((t) => t.Id).filter((id) => id !== void 0);
|
|
13867
14380
|
} catch (error) {
|
|
13868
14381
|
if (error instanceof ResourceNotFoundException9) {
|
|
14382
|
+
const clientRegion = await this.eventBridgeClient.config.region();
|
|
14383
|
+
assertRegionMatch(
|
|
14384
|
+
clientRegion,
|
|
14385
|
+
context?.expectedRegion,
|
|
14386
|
+
resourceType,
|
|
14387
|
+
logicalId,
|
|
14388
|
+
physicalId
|
|
14389
|
+
);
|
|
13869
14390
|
this.logger.debug(`Rule ${ruleName} does not exist, skipping deletion`);
|
|
13870
14391
|
return;
|
|
13871
14392
|
}
|
|
@@ -13884,6 +14405,14 @@ var EventBridgeRuleProvider = class {
|
|
|
13884
14405
|
this.logger.debug(`Successfully deleted EventBridge rule ${logicalId}`);
|
|
13885
14406
|
} catch (error) {
|
|
13886
14407
|
if (error instanceof ResourceNotFoundException9) {
|
|
14408
|
+
const clientRegion = await this.eventBridgeClient.config.region();
|
|
14409
|
+
assertRegionMatch(
|
|
14410
|
+
clientRegion,
|
|
14411
|
+
context?.expectedRegion,
|
|
14412
|
+
resourceType,
|
|
14413
|
+
logicalId,
|
|
14414
|
+
physicalId
|
|
14415
|
+
);
|
|
13887
14416
|
this.logger.debug(`Rule ${ruleName} does not exist, skipping deletion`);
|
|
13888
14417
|
return;
|
|
13889
14418
|
}
|
|
@@ -14069,7 +14598,7 @@ var EventBridgeBusProvider = class {
|
|
|
14069
14598
|
}
|
|
14070
14599
|
return { physicalId, wasReplaced: false, attributes: {} };
|
|
14071
14600
|
}
|
|
14072
|
-
async delete(logicalId, physicalId, resourceType) {
|
|
14601
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
14073
14602
|
this.logger.debug(`Deleting EventBus ${logicalId}: ${physicalId}`);
|
|
14074
14603
|
try {
|
|
14075
14604
|
await this.cleanupRulesOnBus(physicalId);
|
|
@@ -14077,11 +14606,27 @@ var EventBridgeBusProvider = class {
|
|
|
14077
14606
|
this.logger.debug(`Successfully deleted EventBus ${logicalId}`);
|
|
14078
14607
|
} catch (error) {
|
|
14079
14608
|
if (error instanceof ResourceNotFoundException10) {
|
|
14609
|
+
const clientRegion = await this.eventBridgeClient.config.region();
|
|
14610
|
+
assertRegionMatch(
|
|
14611
|
+
clientRegion,
|
|
14612
|
+
context?.expectedRegion,
|
|
14613
|
+
resourceType,
|
|
14614
|
+
logicalId,
|
|
14615
|
+
physicalId
|
|
14616
|
+
);
|
|
14080
14617
|
this.logger.debug(`EventBus ${physicalId} does not exist, skipping`);
|
|
14081
14618
|
return;
|
|
14082
14619
|
}
|
|
14083
14620
|
const msg = error instanceof Error ? error.message : String(error);
|
|
14084
14621
|
if (msg.includes("does not exist")) {
|
|
14622
|
+
const clientRegion = await this.eventBridgeClient.config.region();
|
|
14623
|
+
assertRegionMatch(
|
|
14624
|
+
clientRegion,
|
|
14625
|
+
context?.expectedRegion,
|
|
14626
|
+
resourceType,
|
|
14627
|
+
logicalId,
|
|
14628
|
+
physicalId
|
|
14629
|
+
);
|
|
14085
14630
|
this.logger.debug(`EventBus ${physicalId} does not exist, skipping`);
|
|
14086
14631
|
return;
|
|
14087
14632
|
}
|
|
@@ -14381,32 +14926,38 @@ var EC2Provider = class {
|
|
|
14381
14926
|
);
|
|
14382
14927
|
}
|
|
14383
14928
|
}
|
|
14384
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
14929
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
14385
14930
|
switch (resourceType) {
|
|
14386
14931
|
case "AWS::EC2::VPC":
|
|
14387
|
-
return this.deleteVpc(logicalId, physicalId, resourceType);
|
|
14932
|
+
return this.deleteVpc(logicalId, physicalId, resourceType, context);
|
|
14388
14933
|
case "AWS::EC2::Subnet":
|
|
14389
|
-
return this.deleteSubnet(logicalId, physicalId, resourceType);
|
|
14934
|
+
return this.deleteSubnet(logicalId, physicalId, resourceType, context);
|
|
14390
14935
|
case "AWS::EC2::InternetGateway":
|
|
14391
|
-
return this.deleteInternetGateway(logicalId, physicalId, resourceType);
|
|
14936
|
+
return this.deleteInternetGateway(logicalId, physicalId, resourceType, context);
|
|
14392
14937
|
case "AWS::EC2::VPCGatewayAttachment":
|
|
14393
|
-
return this.deleteVpcGatewayAttachment(logicalId, physicalId, resourceType);
|
|
14938
|
+
return this.deleteVpcGatewayAttachment(logicalId, physicalId, resourceType, context);
|
|
14394
14939
|
case "AWS::EC2::RouteTable":
|
|
14395
|
-
return this.deleteRouteTable(logicalId, physicalId, resourceType);
|
|
14940
|
+
return this.deleteRouteTable(logicalId, physicalId, resourceType, context);
|
|
14396
14941
|
case "AWS::EC2::Route":
|
|
14397
|
-
return this.deleteRoute(logicalId, physicalId, resourceType);
|
|
14942
|
+
return this.deleteRoute(logicalId, physicalId, resourceType, context);
|
|
14398
14943
|
case "AWS::EC2::SubnetRouteTableAssociation":
|
|
14399
|
-
return this.deleteSubnetRouteTableAssociation(logicalId, physicalId, resourceType);
|
|
14944
|
+
return this.deleteSubnetRouteTableAssociation(logicalId, physicalId, resourceType, context);
|
|
14400
14945
|
case "AWS::EC2::SecurityGroup":
|
|
14401
|
-
return this.deleteSecurityGroup(logicalId, physicalId, resourceType);
|
|
14946
|
+
return this.deleteSecurityGroup(logicalId, physicalId, resourceType, context);
|
|
14402
14947
|
case "AWS::EC2::SecurityGroupIngress":
|
|
14403
|
-
return this.deleteSecurityGroupIngress(
|
|
14948
|
+
return this.deleteSecurityGroupIngress(
|
|
14949
|
+
logicalId,
|
|
14950
|
+
physicalId,
|
|
14951
|
+
resourceType,
|
|
14952
|
+
properties,
|
|
14953
|
+
context
|
|
14954
|
+
);
|
|
14404
14955
|
case "AWS::EC2::Instance":
|
|
14405
|
-
return this.deleteInstance(logicalId, physicalId, resourceType);
|
|
14956
|
+
return this.deleteInstance(logicalId, physicalId, resourceType, context);
|
|
14406
14957
|
case "AWS::EC2::NetworkAcl":
|
|
14407
|
-
return this.deleteNetworkAcl(logicalId, physicalId, resourceType);
|
|
14958
|
+
return this.deleteNetworkAcl(logicalId, physicalId, resourceType, context);
|
|
14408
14959
|
case "AWS::EC2::NetworkAclEntry":
|
|
14409
|
-
return this.deleteNetworkAclEntry(logicalId, physicalId, resourceType);
|
|
14960
|
+
return this.deleteNetworkAclEntry(logicalId, physicalId, resourceType, context);
|
|
14410
14961
|
case "AWS::EC2::SubnetNetworkAclAssociation":
|
|
14411
14962
|
this.logger.debug(`SubnetNetworkAclAssociation ${logicalId} delete is a no-op`);
|
|
14412
14963
|
return;
|
|
@@ -14547,7 +15098,7 @@ var EC2Provider = class {
|
|
|
14547
15098
|
);
|
|
14548
15099
|
}
|
|
14549
15100
|
}
|
|
14550
|
-
async deleteVpc(logicalId, physicalId, resourceType) {
|
|
15101
|
+
async deleteVpc(logicalId, physicalId, resourceType, context) {
|
|
14551
15102
|
this.logger.debug(`Deleting VPC ${logicalId}: ${physicalId}`);
|
|
14552
15103
|
const maxAttempts = 10;
|
|
14553
15104
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
@@ -14557,6 +15108,14 @@ var EC2Provider = class {
|
|
|
14557
15108
|
return;
|
|
14558
15109
|
} catch (error) {
|
|
14559
15110
|
if (this.isNotFoundError(error)) {
|
|
15111
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15112
|
+
assertRegionMatch(
|
|
15113
|
+
clientRegion,
|
|
15114
|
+
context?.expectedRegion,
|
|
15115
|
+
resourceType,
|
|
15116
|
+
logicalId,
|
|
15117
|
+
physicalId
|
|
15118
|
+
);
|
|
14560
15119
|
this.logger.debug(`VPC ${physicalId} does not exist, skipping deletion`);
|
|
14561
15120
|
return;
|
|
14562
15121
|
}
|
|
@@ -14662,7 +15221,7 @@ var EC2Provider = class {
|
|
|
14662
15221
|
this.logger.debug(`Updating Subnet ${logicalId}: ${physicalId} (no-op, immutable properties)`);
|
|
14663
15222
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
14664
15223
|
}
|
|
14665
|
-
async deleteSubnet(logicalId, physicalId, resourceType) {
|
|
15224
|
+
async deleteSubnet(logicalId, physicalId, resourceType, context) {
|
|
14666
15225
|
this.logger.debug(`Deleting Subnet ${logicalId}: ${physicalId}`);
|
|
14667
15226
|
const maxAttempts = 10;
|
|
14668
15227
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
@@ -14672,6 +15231,14 @@ var EC2Provider = class {
|
|
|
14672
15231
|
return;
|
|
14673
15232
|
} catch (error) {
|
|
14674
15233
|
if (this.isNotFoundError(error)) {
|
|
15234
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15235
|
+
assertRegionMatch(
|
|
15236
|
+
clientRegion,
|
|
15237
|
+
context?.expectedRegion,
|
|
15238
|
+
resourceType,
|
|
15239
|
+
logicalId,
|
|
15240
|
+
physicalId
|
|
15241
|
+
);
|
|
14675
15242
|
this.logger.debug(`Subnet ${physicalId} does not exist, skipping deletion`);
|
|
14676
15243
|
return;
|
|
14677
15244
|
}
|
|
@@ -14790,7 +15357,7 @@ var EC2Provider = class {
|
|
|
14790
15357
|
this.logger.debug(`Updating InternetGateway ${logicalId}: ${physicalId} (no-op)`);
|
|
14791
15358
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
14792
15359
|
}
|
|
14793
|
-
async deleteInternetGateway(logicalId, physicalId, resourceType) {
|
|
15360
|
+
async deleteInternetGateway(logicalId, physicalId, resourceType, context) {
|
|
14794
15361
|
this.logger.debug(`Deleting InternetGateway ${logicalId}: ${physicalId}`);
|
|
14795
15362
|
try {
|
|
14796
15363
|
await this.ec2Client.send(
|
|
@@ -14799,6 +15366,14 @@ var EC2Provider = class {
|
|
|
14799
15366
|
this.logger.debug(`Successfully deleted InternetGateway ${logicalId}`);
|
|
14800
15367
|
} catch (error) {
|
|
14801
15368
|
if (this.isNotFoundError(error)) {
|
|
15369
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15370
|
+
assertRegionMatch(
|
|
15371
|
+
clientRegion,
|
|
15372
|
+
context?.expectedRegion,
|
|
15373
|
+
resourceType,
|
|
15374
|
+
logicalId,
|
|
15375
|
+
physicalId
|
|
15376
|
+
);
|
|
14802
15377
|
this.logger.debug(`InternetGateway ${physicalId} does not exist, skipping deletion`);
|
|
14803
15378
|
return;
|
|
14804
15379
|
}
|
|
@@ -14852,7 +15427,7 @@ var EC2Provider = class {
|
|
|
14852
15427
|
this.logger.debug(`Updating VPCGatewayAttachment ${logicalId}: ${physicalId} (no-op)`);
|
|
14853
15428
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
14854
15429
|
}
|
|
14855
|
-
async deleteVpcGatewayAttachment(logicalId, physicalId, resourceType) {
|
|
15430
|
+
async deleteVpcGatewayAttachment(logicalId, physicalId, resourceType, context) {
|
|
14856
15431
|
this.logger.debug(`Deleting VPCGatewayAttachment ${logicalId}: ${physicalId}`);
|
|
14857
15432
|
const parts = physicalId.split("|");
|
|
14858
15433
|
if (parts.length !== 2) {
|
|
@@ -14874,6 +15449,14 @@ var EC2Provider = class {
|
|
|
14874
15449
|
this.logger.debug(`Successfully deleted VPCGatewayAttachment ${logicalId}`);
|
|
14875
15450
|
} catch (error) {
|
|
14876
15451
|
if (this.isNotFoundError(error)) {
|
|
15452
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15453
|
+
assertRegionMatch(
|
|
15454
|
+
clientRegion,
|
|
15455
|
+
context?.expectedRegion,
|
|
15456
|
+
resourceType,
|
|
15457
|
+
logicalId,
|
|
15458
|
+
physicalId
|
|
15459
|
+
);
|
|
14877
15460
|
this.logger.debug(`VPCGatewayAttachment ${physicalId} does not exist, skipping deletion`);
|
|
14878
15461
|
return;
|
|
14879
15462
|
}
|
|
@@ -14924,13 +15507,21 @@ var EC2Provider = class {
|
|
|
14924
15507
|
this.logger.debug(`Updating RouteTable ${logicalId}: ${physicalId} (no-op)`);
|
|
14925
15508
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
14926
15509
|
}
|
|
14927
|
-
async deleteRouteTable(logicalId, physicalId, resourceType) {
|
|
15510
|
+
async deleteRouteTable(logicalId, physicalId, resourceType, context) {
|
|
14928
15511
|
this.logger.debug(`Deleting RouteTable ${logicalId}: ${physicalId}`);
|
|
14929
15512
|
try {
|
|
14930
15513
|
await this.ec2Client.send(new DeleteRouteTableCommand({ RouteTableId: physicalId }));
|
|
14931
15514
|
this.logger.debug(`Successfully deleted RouteTable ${logicalId}`);
|
|
14932
15515
|
} catch (error) {
|
|
14933
15516
|
if (this.isNotFoundError(error)) {
|
|
15517
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15518
|
+
assertRegionMatch(
|
|
15519
|
+
clientRegion,
|
|
15520
|
+
context?.expectedRegion,
|
|
15521
|
+
resourceType,
|
|
15522
|
+
logicalId,
|
|
15523
|
+
physicalId
|
|
15524
|
+
);
|
|
14934
15525
|
this.logger.debug(`RouteTable ${physicalId} does not exist, skipping deletion`);
|
|
14935
15526
|
return;
|
|
14936
15527
|
}
|
|
@@ -15010,7 +15601,7 @@ var EC2Provider = class {
|
|
|
15010
15601
|
);
|
|
15011
15602
|
}
|
|
15012
15603
|
}
|
|
15013
|
-
async deleteRoute(logicalId, physicalId, resourceType) {
|
|
15604
|
+
async deleteRoute(logicalId, physicalId, resourceType, context) {
|
|
15014
15605
|
this.logger.debug(`Deleting Route ${logicalId}: ${physicalId}`);
|
|
15015
15606
|
const parts = physicalId.split("|");
|
|
15016
15607
|
if (parts.length !== 2) {
|
|
@@ -15033,6 +15624,14 @@ var EC2Provider = class {
|
|
|
15033
15624
|
this.logger.debug(`Successfully deleted Route ${logicalId}`);
|
|
15034
15625
|
} catch (error) {
|
|
15035
15626
|
if (this.isNotFoundError(error)) {
|
|
15627
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15628
|
+
assertRegionMatch(
|
|
15629
|
+
clientRegion,
|
|
15630
|
+
context?.expectedRegion,
|
|
15631
|
+
resourceType,
|
|
15632
|
+
logicalId,
|
|
15633
|
+
physicalId
|
|
15634
|
+
);
|
|
15036
15635
|
this.logger.debug(`Route ${physicalId} does not exist, skipping deletion`);
|
|
15037
15636
|
return;
|
|
15038
15637
|
}
|
|
@@ -15090,13 +15689,21 @@ var EC2Provider = class {
|
|
|
15090
15689
|
);
|
|
15091
15690
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
15092
15691
|
}
|
|
15093
|
-
async deleteSubnetRouteTableAssociation(logicalId, physicalId, resourceType) {
|
|
15692
|
+
async deleteSubnetRouteTableAssociation(logicalId, physicalId, resourceType, context) {
|
|
15094
15693
|
this.logger.debug(`Deleting SubnetRouteTableAssociation ${logicalId}: ${physicalId}`);
|
|
15095
15694
|
try {
|
|
15096
15695
|
await this.ec2Client.send(new DisassociateRouteTableCommand({ AssociationId: physicalId }));
|
|
15097
15696
|
this.logger.debug(`Successfully deleted SubnetRouteTableAssociation ${logicalId}`);
|
|
15098
15697
|
} catch (error) {
|
|
15099
15698
|
if (this.isNotFoundError(error)) {
|
|
15699
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15700
|
+
assertRegionMatch(
|
|
15701
|
+
clientRegion,
|
|
15702
|
+
context?.expectedRegion,
|
|
15703
|
+
resourceType,
|
|
15704
|
+
logicalId,
|
|
15705
|
+
physicalId
|
|
15706
|
+
);
|
|
15100
15707
|
this.logger.debug(
|
|
15101
15708
|
`SubnetRouteTableAssociation ${physicalId} does not exist, skipping deletion`
|
|
15102
15709
|
);
|
|
@@ -15227,7 +15834,7 @@ var EC2Provider = class {
|
|
|
15227
15834
|
);
|
|
15228
15835
|
}
|
|
15229
15836
|
}
|
|
15230
|
-
async deleteSecurityGroup(logicalId, physicalId, resourceType) {
|
|
15837
|
+
async deleteSecurityGroup(logicalId, physicalId, resourceType, context) {
|
|
15231
15838
|
this.logger.debug(`Deleting SecurityGroup ${logicalId}: ${physicalId}`);
|
|
15232
15839
|
const maxAttempts = 10;
|
|
15233
15840
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
@@ -15237,6 +15844,14 @@ var EC2Provider = class {
|
|
|
15237
15844
|
return;
|
|
15238
15845
|
} catch (error) {
|
|
15239
15846
|
if (this.isNotFoundError(error)) {
|
|
15847
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
15848
|
+
assertRegionMatch(
|
|
15849
|
+
clientRegion,
|
|
15850
|
+
context?.expectedRegion,
|
|
15851
|
+
resourceType,
|
|
15852
|
+
logicalId,
|
|
15853
|
+
physicalId
|
|
15854
|
+
);
|
|
15240
15855
|
this.logger.debug(`SecurityGroup ${physicalId} does not exist, skipping deletion`);
|
|
15241
15856
|
return;
|
|
15242
15857
|
}
|
|
@@ -15394,7 +16009,7 @@ var EC2Provider = class {
|
|
|
15394
16009
|
);
|
|
15395
16010
|
}
|
|
15396
16011
|
}
|
|
15397
|
-
async deleteSecurityGroupIngress(logicalId, physicalId, resourceType, properties) {
|
|
16012
|
+
async deleteSecurityGroupIngress(logicalId, physicalId, resourceType, properties, context) {
|
|
15398
16013
|
this.logger.debug(`Deleting SecurityGroupIngress ${logicalId}: ${physicalId}`);
|
|
15399
16014
|
const parts = physicalId.split("|");
|
|
15400
16015
|
if (parts.length !== 4) {
|
|
@@ -15421,6 +16036,14 @@ var EC2Provider = class {
|
|
|
15421
16036
|
this.logger.debug(`Successfully deleted SecurityGroupIngress ${logicalId}`);
|
|
15422
16037
|
} catch (error) {
|
|
15423
16038
|
if (this.isNotFoundError(error)) {
|
|
16039
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
16040
|
+
assertRegionMatch(
|
|
16041
|
+
clientRegion,
|
|
16042
|
+
context?.expectedRegion,
|
|
16043
|
+
resourceType,
|
|
16044
|
+
logicalId,
|
|
16045
|
+
physicalId
|
|
16046
|
+
);
|
|
15424
16047
|
this.logger.debug(`SecurityGroupIngress ${physicalId} does not exist, skipping deletion`);
|
|
15425
16048
|
return;
|
|
15426
16049
|
}
|
|
@@ -15537,7 +16160,7 @@ var EC2Provider = class {
|
|
|
15537
16160
|
);
|
|
15538
16161
|
}
|
|
15539
16162
|
}
|
|
15540
|
-
async deleteInstance(logicalId, physicalId, resourceType) {
|
|
16163
|
+
async deleteInstance(logicalId, physicalId, resourceType, context) {
|
|
15541
16164
|
this.logger.debug(`Terminating EC2 Instance ${logicalId}: ${physicalId}`);
|
|
15542
16165
|
try {
|
|
15543
16166
|
await this.ec2Client.send(new TerminateInstancesCommand({ InstanceIds: [physicalId] }));
|
|
@@ -15549,6 +16172,14 @@ var EC2Provider = class {
|
|
|
15549
16172
|
this.logger.debug(`EC2 Instance ${logicalId} terminated: ${physicalId}`);
|
|
15550
16173
|
} catch (error) {
|
|
15551
16174
|
if (this.isNotFoundError(error)) {
|
|
16175
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
16176
|
+
assertRegionMatch(
|
|
16177
|
+
clientRegion,
|
|
16178
|
+
context?.expectedRegion,
|
|
16179
|
+
resourceType,
|
|
16180
|
+
logicalId,
|
|
16181
|
+
physicalId
|
|
16182
|
+
);
|
|
15552
16183
|
this.logger.debug(
|
|
15553
16184
|
`EC2 Instance ${physicalId} already terminated (not found), treating as success`
|
|
15554
16185
|
);
|
|
@@ -15784,13 +16415,21 @@ var EC2Provider = class {
|
|
|
15784
16415
|
);
|
|
15785
16416
|
}
|
|
15786
16417
|
}
|
|
15787
|
-
async deleteNetworkAcl(logicalId, physicalId, resourceType) {
|
|
16418
|
+
async deleteNetworkAcl(logicalId, physicalId, resourceType, context) {
|
|
15788
16419
|
this.logger.debug(`Deleting NetworkAcl ${logicalId}: ${physicalId}`);
|
|
15789
16420
|
try {
|
|
15790
16421
|
await this.ec2Client.send(new DeleteNetworkAclCommand({ NetworkAclId: physicalId }));
|
|
15791
16422
|
this.logger.debug(`Successfully deleted NetworkAcl ${logicalId}`);
|
|
15792
16423
|
} catch (error) {
|
|
15793
16424
|
if (this.isNotFoundError(error)) {
|
|
16425
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
16426
|
+
assertRegionMatch(
|
|
16427
|
+
clientRegion,
|
|
16428
|
+
context?.expectedRegion,
|
|
16429
|
+
resourceType,
|
|
16430
|
+
logicalId,
|
|
16431
|
+
physicalId
|
|
16432
|
+
);
|
|
15794
16433
|
this.logger.debug(`NetworkAcl ${physicalId} does not exist, skipping deletion`);
|
|
15795
16434
|
return;
|
|
15796
16435
|
}
|
|
@@ -15860,7 +16499,7 @@ var EC2Provider = class {
|
|
|
15860
16499
|
);
|
|
15861
16500
|
}
|
|
15862
16501
|
}
|
|
15863
|
-
async deleteNetworkAclEntry(logicalId, physicalId, resourceType) {
|
|
16502
|
+
async deleteNetworkAclEntry(logicalId, physicalId, resourceType, context) {
|
|
15864
16503
|
this.logger.debug(`Deleting NetworkAclEntry ${logicalId}: ${physicalId}`);
|
|
15865
16504
|
const parts = physicalId.split("|");
|
|
15866
16505
|
if (parts.length < 3) {
|
|
@@ -15881,6 +16520,14 @@ var EC2Provider = class {
|
|
|
15881
16520
|
this.logger.debug(`Successfully deleted NetworkAclEntry ${logicalId}`);
|
|
15882
16521
|
} catch (error) {
|
|
15883
16522
|
if (this.isNotFoundError(error)) {
|
|
16523
|
+
const clientRegion = await this.ec2Client.config.region();
|
|
16524
|
+
assertRegionMatch(
|
|
16525
|
+
clientRegion,
|
|
16526
|
+
context?.expectedRegion,
|
|
16527
|
+
resourceType,
|
|
16528
|
+
logicalId,
|
|
16529
|
+
physicalId
|
|
16530
|
+
);
|
|
15884
16531
|
this.logger.debug(`NetworkAclEntry ${physicalId} does not exist, skipping deletion`);
|
|
15885
16532
|
return;
|
|
15886
16533
|
}
|
|
@@ -16123,20 +16770,20 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16123
16770
|
/**
|
|
16124
16771
|
* Delete a resource
|
|
16125
16772
|
*/
|
|
16126
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
16773
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
16127
16774
|
switch (resourceType) {
|
|
16128
16775
|
case "AWS::ApiGateway::Account":
|
|
16129
16776
|
return this.deleteAccount(logicalId, physicalId, resourceType);
|
|
16130
16777
|
case "AWS::ApiGateway::Authorizer":
|
|
16131
|
-
return this.deleteAuthorizer(logicalId, physicalId, resourceType, properties);
|
|
16778
|
+
return this.deleteAuthorizer(logicalId, physicalId, resourceType, properties, context);
|
|
16132
16779
|
case "AWS::ApiGateway::Resource":
|
|
16133
|
-
return this.deleteResource(logicalId, physicalId, resourceType, properties);
|
|
16780
|
+
return this.deleteResource(logicalId, physicalId, resourceType, properties, context);
|
|
16134
16781
|
case "AWS::ApiGateway::Deployment":
|
|
16135
|
-
return this.deleteDeployment(logicalId, physicalId, resourceType, properties);
|
|
16782
|
+
return this.deleteDeployment(logicalId, physicalId, resourceType, properties, context);
|
|
16136
16783
|
case "AWS::ApiGateway::Stage":
|
|
16137
|
-
return this.deleteStage(logicalId, physicalId, resourceType, properties);
|
|
16784
|
+
return this.deleteStage(logicalId, physicalId, resourceType, properties, context);
|
|
16138
16785
|
case "AWS::ApiGateway::Method":
|
|
16139
|
-
return this.deleteMethod(logicalId, physicalId, resourceType);
|
|
16786
|
+
return this.deleteMethod(logicalId, physicalId, resourceType, context);
|
|
16140
16787
|
default:
|
|
16141
16788
|
throw new ProvisioningError(
|
|
16142
16789
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -16358,7 +17005,7 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16358
17005
|
/**
|
|
16359
17006
|
* Delete an API Gateway Authorizer
|
|
16360
17007
|
*/
|
|
16361
|
-
async deleteAuthorizer(logicalId, physicalId, resourceType, properties) {
|
|
17008
|
+
async deleteAuthorizer(logicalId, physicalId, resourceType, properties, context) {
|
|
16362
17009
|
this.logger.debug(`Deleting API Gateway Authorizer ${logicalId}: ${physicalId}`);
|
|
16363
17010
|
const restApiId = properties?.["RestApiId"];
|
|
16364
17011
|
if (!restApiId) {
|
|
@@ -16379,6 +17026,14 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16379
17026
|
this.logger.debug(`Successfully deleted API Gateway Authorizer ${logicalId}`);
|
|
16380
17027
|
} catch (error) {
|
|
16381
17028
|
if (error instanceof NotFoundException3) {
|
|
17029
|
+
const clientRegion = await this.apiGatewayClient.config.region();
|
|
17030
|
+
assertRegionMatch(
|
|
17031
|
+
clientRegion,
|
|
17032
|
+
context?.expectedRegion,
|
|
17033
|
+
resourceType,
|
|
17034
|
+
logicalId,
|
|
17035
|
+
physicalId
|
|
17036
|
+
);
|
|
16382
17037
|
this.logger.debug(`API Gateway Authorizer ${physicalId} does not exist, skipping deletion`);
|
|
16383
17038
|
return;
|
|
16384
17039
|
}
|
|
@@ -16483,7 +17138,7 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16483
17138
|
/**
|
|
16484
17139
|
* Delete an API Gateway Resource
|
|
16485
17140
|
*/
|
|
16486
|
-
async deleteResource(logicalId, physicalId, resourceType, properties) {
|
|
17141
|
+
async deleteResource(logicalId, physicalId, resourceType, properties, context) {
|
|
16487
17142
|
this.logger.debug(`Deleting API Gateway Resource ${logicalId}: ${physicalId}`);
|
|
16488
17143
|
const restApiId = properties?.["RestApiId"];
|
|
16489
17144
|
if (!restApiId) {
|
|
@@ -16504,6 +17159,14 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16504
17159
|
this.logger.debug(`Successfully deleted API Gateway Resource ${logicalId}`);
|
|
16505
17160
|
} catch (error) {
|
|
16506
17161
|
if (error instanceof NotFoundException3) {
|
|
17162
|
+
const clientRegion = await this.apiGatewayClient.config.region();
|
|
17163
|
+
assertRegionMatch(
|
|
17164
|
+
clientRegion,
|
|
17165
|
+
context?.expectedRegion,
|
|
17166
|
+
resourceType,
|
|
17167
|
+
logicalId,
|
|
17168
|
+
physicalId
|
|
17169
|
+
);
|
|
16507
17170
|
this.logger.debug(`API Gateway Resource ${physicalId} does not exist, skipping deletion`);
|
|
16508
17171
|
return;
|
|
16509
17172
|
}
|
|
@@ -16587,7 +17250,7 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16587
17250
|
/**
|
|
16588
17251
|
* Delete an API Gateway Deployment
|
|
16589
17252
|
*/
|
|
16590
|
-
async deleteDeployment(logicalId, physicalId, resourceType, properties) {
|
|
17253
|
+
async deleteDeployment(logicalId, physicalId, resourceType, properties, context) {
|
|
16591
17254
|
this.logger.debug(`Deleting API Gateway Deployment ${logicalId}: ${physicalId}`);
|
|
16592
17255
|
const restApiId = properties?.["RestApiId"];
|
|
16593
17256
|
if (!restApiId) {
|
|
@@ -16608,6 +17271,14 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16608
17271
|
this.logger.debug(`Successfully deleted API Gateway Deployment ${logicalId}`);
|
|
16609
17272
|
} catch (error) {
|
|
16610
17273
|
if (error instanceof NotFoundException3) {
|
|
17274
|
+
const clientRegion = await this.apiGatewayClient.config.region();
|
|
17275
|
+
assertRegionMatch(
|
|
17276
|
+
clientRegion,
|
|
17277
|
+
context?.expectedRegion,
|
|
17278
|
+
resourceType,
|
|
17279
|
+
logicalId,
|
|
17280
|
+
physicalId
|
|
17281
|
+
);
|
|
16611
17282
|
this.logger.debug(`API Gateway Deployment ${physicalId} does not exist, skipping deletion`);
|
|
16612
17283
|
return;
|
|
16613
17284
|
}
|
|
@@ -16745,7 +17416,7 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16745
17416
|
/**
|
|
16746
17417
|
* Delete an API Gateway Stage
|
|
16747
17418
|
*/
|
|
16748
|
-
async deleteStage(logicalId, physicalId, resourceType, properties) {
|
|
17419
|
+
async deleteStage(logicalId, physicalId, resourceType, properties, context) {
|
|
16749
17420
|
this.logger.debug(`Deleting API Gateway Stage ${logicalId}: ${physicalId}`);
|
|
16750
17421
|
const restApiId = properties?.["RestApiId"];
|
|
16751
17422
|
if (!restApiId) {
|
|
@@ -16766,6 +17437,14 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16766
17437
|
this.logger.debug(`Successfully deleted API Gateway Stage ${logicalId}`);
|
|
16767
17438
|
} catch (error) {
|
|
16768
17439
|
if (error instanceof NotFoundException3) {
|
|
17440
|
+
const clientRegion = await this.apiGatewayClient.config.region();
|
|
17441
|
+
assertRegionMatch(
|
|
17442
|
+
clientRegion,
|
|
17443
|
+
context?.expectedRegion,
|
|
17444
|
+
resourceType,
|
|
17445
|
+
logicalId,
|
|
17446
|
+
physicalId
|
|
17447
|
+
);
|
|
16769
17448
|
this.logger.debug(`API Gateway Stage ${physicalId} does not exist, skipping deletion`);
|
|
16770
17449
|
return;
|
|
16771
17450
|
}
|
|
@@ -16885,7 +17564,7 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16885
17564
|
* Parses the composite physicalId (`restApiId|resourceId|httpMethod`) and
|
|
16886
17565
|
* calls DeleteMethodCommand. Handles NotFoundException gracefully.
|
|
16887
17566
|
*/
|
|
16888
|
-
async deleteMethod(logicalId, physicalId, resourceType) {
|
|
17567
|
+
async deleteMethod(logicalId, physicalId, resourceType, context) {
|
|
16889
17568
|
this.logger.debug(`Deleting API Gateway Method ${logicalId}: ${physicalId}`);
|
|
16890
17569
|
const parts = physicalId.split("|");
|
|
16891
17570
|
if (parts.length !== 3) {
|
|
@@ -16908,6 +17587,14 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
16908
17587
|
this.logger.debug(`Successfully deleted API Gateway Method ${logicalId}`);
|
|
16909
17588
|
} catch (error) {
|
|
16910
17589
|
if (error instanceof NotFoundException3) {
|
|
17590
|
+
const clientRegion = await this.apiGatewayClient.config.region();
|
|
17591
|
+
assertRegionMatch(
|
|
17592
|
+
clientRegion,
|
|
17593
|
+
context?.expectedRegion,
|
|
17594
|
+
resourceType,
|
|
17595
|
+
logicalId,
|
|
17596
|
+
physicalId
|
|
17597
|
+
);
|
|
16911
17598
|
this.logger.debug(`API Gateway Method ${physicalId} does not exist, skipping deletion`);
|
|
16912
17599
|
return;
|
|
16913
17600
|
}
|
|
@@ -17048,18 +17735,18 @@ var ApiGatewayV2Provider = class {
|
|
|
17048
17735
|
attributes: {}
|
|
17049
17736
|
});
|
|
17050
17737
|
}
|
|
17051
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
17738
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
17052
17739
|
switch (resourceType) {
|
|
17053
17740
|
case "AWS::ApiGatewayV2::Api":
|
|
17054
|
-
return this.deleteApi(logicalId, physicalId, resourceType);
|
|
17741
|
+
return this.deleteApi(logicalId, physicalId, resourceType, context);
|
|
17055
17742
|
case "AWS::ApiGatewayV2::Stage":
|
|
17056
|
-
return this.deleteStage(logicalId, physicalId, resourceType, properties);
|
|
17743
|
+
return this.deleteStage(logicalId, physicalId, resourceType, properties, context);
|
|
17057
17744
|
case "AWS::ApiGatewayV2::Integration":
|
|
17058
|
-
return this.deleteIntegration(logicalId, physicalId, resourceType, properties);
|
|
17745
|
+
return this.deleteIntegration(logicalId, physicalId, resourceType, properties, context);
|
|
17059
17746
|
case "AWS::ApiGatewayV2::Route":
|
|
17060
|
-
return this.deleteRoute(logicalId, physicalId, resourceType, properties);
|
|
17747
|
+
return this.deleteRoute(logicalId, physicalId, resourceType, properties, context);
|
|
17061
17748
|
case "AWS::ApiGatewayV2::Authorizer":
|
|
17062
|
-
return this.deleteAuthorizer(logicalId, physicalId, resourceType, properties);
|
|
17749
|
+
return this.deleteAuthorizer(logicalId, physicalId, resourceType, properties, context);
|
|
17063
17750
|
default:
|
|
17064
17751
|
throw new ProvisioningError(
|
|
17065
17752
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -17130,13 +17817,21 @@ var ApiGatewayV2Provider = class {
|
|
|
17130
17817
|
);
|
|
17131
17818
|
}
|
|
17132
17819
|
}
|
|
17133
|
-
async deleteApi(logicalId, physicalId, resourceType) {
|
|
17820
|
+
async deleteApi(logicalId, physicalId, resourceType, context) {
|
|
17134
17821
|
this.logger.debug(`Deleting API Gateway V2 Api ${logicalId}: ${physicalId}`);
|
|
17135
17822
|
try {
|
|
17136
17823
|
await this.getClient().send(new DeleteApiCommand({ ApiId: physicalId }));
|
|
17137
17824
|
this.logger.debug(`Successfully deleted API Gateway V2 Api ${logicalId}`);
|
|
17138
17825
|
} catch (error) {
|
|
17139
17826
|
if (error instanceof NotFoundException4) {
|
|
17827
|
+
const clientRegion = await this.getClient().config.region();
|
|
17828
|
+
assertRegionMatch(
|
|
17829
|
+
clientRegion,
|
|
17830
|
+
context?.expectedRegion,
|
|
17831
|
+
resourceType,
|
|
17832
|
+
logicalId,
|
|
17833
|
+
physicalId
|
|
17834
|
+
);
|
|
17140
17835
|
this.logger.debug(`API Gateway V2 Api ${physicalId} does not exist, skipping deletion`);
|
|
17141
17836
|
return;
|
|
17142
17837
|
}
|
|
@@ -17193,7 +17888,7 @@ var ApiGatewayV2Provider = class {
|
|
|
17193
17888
|
);
|
|
17194
17889
|
}
|
|
17195
17890
|
}
|
|
17196
|
-
async deleteStage(logicalId, physicalId, resourceType, properties) {
|
|
17891
|
+
async deleteStage(logicalId, physicalId, resourceType, properties, context) {
|
|
17197
17892
|
this.logger.debug(`Deleting API Gateway V2 Stage ${logicalId}: ${physicalId}`);
|
|
17198
17893
|
const apiId = properties?.["ApiId"];
|
|
17199
17894
|
if (!apiId) {
|
|
@@ -17209,6 +17904,14 @@ var ApiGatewayV2Provider = class {
|
|
|
17209
17904
|
this.logger.debug(`Successfully deleted API Gateway V2 Stage ${logicalId}`);
|
|
17210
17905
|
} catch (error) {
|
|
17211
17906
|
if (error instanceof NotFoundException4) {
|
|
17907
|
+
const clientRegion = await this.getClient().config.region();
|
|
17908
|
+
assertRegionMatch(
|
|
17909
|
+
clientRegion,
|
|
17910
|
+
context?.expectedRegion,
|
|
17911
|
+
resourceType,
|
|
17912
|
+
logicalId,
|
|
17913
|
+
physicalId
|
|
17914
|
+
);
|
|
17212
17915
|
this.logger.debug(`API Gateway V2 Stage ${physicalId} does not exist, skipping deletion`);
|
|
17213
17916
|
return;
|
|
17214
17917
|
}
|
|
@@ -17270,7 +17973,7 @@ var ApiGatewayV2Provider = class {
|
|
|
17270
17973
|
);
|
|
17271
17974
|
}
|
|
17272
17975
|
}
|
|
17273
|
-
async deleteIntegration(logicalId, physicalId, resourceType, properties) {
|
|
17976
|
+
async deleteIntegration(logicalId, physicalId, resourceType, properties, context) {
|
|
17274
17977
|
this.logger.debug(`Deleting API Gateway V2 Integration ${logicalId}: ${physicalId}`);
|
|
17275
17978
|
const apiId = properties?.["ApiId"];
|
|
17276
17979
|
if (!apiId) {
|
|
@@ -17288,6 +17991,14 @@ var ApiGatewayV2Provider = class {
|
|
|
17288
17991
|
this.logger.debug(`Successfully deleted API Gateway V2 Integration ${logicalId}`);
|
|
17289
17992
|
} catch (error) {
|
|
17290
17993
|
if (error instanceof NotFoundException4) {
|
|
17994
|
+
const clientRegion = await this.getClient().config.region();
|
|
17995
|
+
assertRegionMatch(
|
|
17996
|
+
clientRegion,
|
|
17997
|
+
context?.expectedRegion,
|
|
17998
|
+
resourceType,
|
|
17999
|
+
logicalId,
|
|
18000
|
+
physicalId
|
|
18001
|
+
);
|
|
17291
18002
|
this.logger.debug(
|
|
17292
18003
|
`API Gateway V2 Integration ${physicalId} does not exist, skipping deletion`
|
|
17293
18004
|
);
|
|
@@ -17349,7 +18060,7 @@ var ApiGatewayV2Provider = class {
|
|
|
17349
18060
|
);
|
|
17350
18061
|
}
|
|
17351
18062
|
}
|
|
17352
|
-
async deleteRoute(logicalId, physicalId, resourceType, properties) {
|
|
18063
|
+
async deleteRoute(logicalId, physicalId, resourceType, properties, context) {
|
|
17353
18064
|
this.logger.debug(`Deleting API Gateway V2 Route ${logicalId}: ${physicalId}`);
|
|
17354
18065
|
const apiId = properties?.["ApiId"];
|
|
17355
18066
|
if (!apiId) {
|
|
@@ -17365,6 +18076,14 @@ var ApiGatewayV2Provider = class {
|
|
|
17365
18076
|
this.logger.debug(`Successfully deleted API Gateway V2 Route ${logicalId}`);
|
|
17366
18077
|
} catch (error) {
|
|
17367
18078
|
if (error instanceof NotFoundException4) {
|
|
18079
|
+
const clientRegion = await this.getClient().config.region();
|
|
18080
|
+
assertRegionMatch(
|
|
18081
|
+
clientRegion,
|
|
18082
|
+
context?.expectedRegion,
|
|
18083
|
+
resourceType,
|
|
18084
|
+
logicalId,
|
|
18085
|
+
physicalId
|
|
18086
|
+
);
|
|
17368
18087
|
this.logger.debug(`API Gateway V2 Route ${physicalId} does not exist, skipping deletion`);
|
|
17369
18088
|
return;
|
|
17370
18089
|
}
|
|
@@ -17429,7 +18148,7 @@ var ApiGatewayV2Provider = class {
|
|
|
17429
18148
|
);
|
|
17430
18149
|
}
|
|
17431
18150
|
}
|
|
17432
|
-
async deleteAuthorizer(logicalId, physicalId, resourceType, properties) {
|
|
18151
|
+
async deleteAuthorizer(logicalId, physicalId, resourceType, properties, context) {
|
|
17433
18152
|
this.logger.debug(`Deleting API Gateway V2 Authorizer ${logicalId}: ${physicalId}`);
|
|
17434
18153
|
const apiId = properties?.["ApiId"];
|
|
17435
18154
|
if (!apiId) {
|
|
@@ -17447,6 +18166,14 @@ var ApiGatewayV2Provider = class {
|
|
|
17447
18166
|
this.logger.debug(`Successfully deleted API Gateway V2 Authorizer ${logicalId}`);
|
|
17448
18167
|
} catch (error) {
|
|
17449
18168
|
if (error instanceof NotFoundException4) {
|
|
18169
|
+
const clientRegion = await this.getClient().config.region();
|
|
18170
|
+
assertRegionMatch(
|
|
18171
|
+
clientRegion,
|
|
18172
|
+
context?.expectedRegion,
|
|
18173
|
+
resourceType,
|
|
18174
|
+
logicalId,
|
|
18175
|
+
physicalId
|
|
18176
|
+
);
|
|
17450
18177
|
this.logger.debug(
|
|
17451
18178
|
`API Gateway V2 Authorizer ${physicalId} does not exist, skipping deletion`
|
|
17452
18179
|
);
|
|
@@ -17554,7 +18281,7 @@ var CloudFrontOAIProvider = class {
|
|
|
17554
18281
|
*
|
|
17555
18282
|
* Requires fetching the ETag first, then passing it as IfMatch for deletion.
|
|
17556
18283
|
*/
|
|
17557
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
18284
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
17558
18285
|
this.logger.debug(`Deleting CloudFront OAI ${logicalId}: ${physicalId}`);
|
|
17559
18286
|
try {
|
|
17560
18287
|
let etag;
|
|
@@ -17565,6 +18292,14 @@ var CloudFrontOAIProvider = class {
|
|
|
17565
18292
|
etag = getResponse.ETag;
|
|
17566
18293
|
} catch (error) {
|
|
17567
18294
|
if (error instanceof NoSuchCloudFrontOriginAccessIdentity) {
|
|
18295
|
+
const clientRegion = await this.cloudFrontClient.config.region();
|
|
18296
|
+
assertRegionMatch(
|
|
18297
|
+
clientRegion,
|
|
18298
|
+
context?.expectedRegion,
|
|
18299
|
+
resourceType,
|
|
18300
|
+
logicalId,
|
|
18301
|
+
physicalId
|
|
18302
|
+
);
|
|
17568
18303
|
this.logger.debug(`OAI ${physicalId} does not exist, skipping deletion`);
|
|
17569
18304
|
return;
|
|
17570
18305
|
}
|
|
@@ -17579,6 +18314,14 @@ var CloudFrontOAIProvider = class {
|
|
|
17579
18314
|
this.logger.debug(`Successfully deleted CloudFront OAI ${logicalId}`);
|
|
17580
18315
|
} catch (error) {
|
|
17581
18316
|
if (error instanceof NoSuchCloudFrontOriginAccessIdentity) {
|
|
18317
|
+
const clientRegion = await this.cloudFrontClient.config.region();
|
|
18318
|
+
assertRegionMatch(
|
|
18319
|
+
clientRegion,
|
|
18320
|
+
context?.expectedRegion,
|
|
18321
|
+
resourceType,
|
|
18322
|
+
logicalId,
|
|
18323
|
+
physicalId
|
|
18324
|
+
);
|
|
17582
18325
|
this.logger.debug(`OAI ${physicalId} does not exist, skipping deletion`);
|
|
17583
18326
|
return;
|
|
17584
18327
|
}
|
|
@@ -17752,7 +18495,7 @@ var CloudFrontDistributionProvider = class {
|
|
|
17752
18495
|
* 2. If Enabled, update to Enabled=false and wait
|
|
17753
18496
|
* 3. Delete with the latest ETag
|
|
17754
18497
|
*/
|
|
17755
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
18498
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
17756
18499
|
this.logger.debug(`Deleting CloudFront Distribution ${logicalId}: ${physicalId}`);
|
|
17757
18500
|
try {
|
|
17758
18501
|
let etag;
|
|
@@ -17765,6 +18508,14 @@ var CloudFrontDistributionProvider = class {
|
|
|
17765
18508
|
config = getConfigResponse.DistributionConfig;
|
|
17766
18509
|
} catch (error) {
|
|
17767
18510
|
if (error instanceof NoSuchDistribution) {
|
|
18511
|
+
const clientRegion = await this.cloudFrontClient.config.region();
|
|
18512
|
+
assertRegionMatch(
|
|
18513
|
+
clientRegion,
|
|
18514
|
+
context?.expectedRegion,
|
|
18515
|
+
resourceType,
|
|
18516
|
+
logicalId,
|
|
18517
|
+
physicalId
|
|
18518
|
+
);
|
|
17768
18519
|
this.logger.debug(`Distribution ${physicalId} does not exist, skipping deletion`);
|
|
17769
18520
|
return;
|
|
17770
18521
|
}
|
|
@@ -17796,6 +18547,14 @@ var CloudFrontDistributionProvider = class {
|
|
|
17796
18547
|
this.logger.debug(`Successfully deleted CloudFront Distribution ${logicalId}`);
|
|
17797
18548
|
} catch (error) {
|
|
17798
18549
|
if (error instanceof NoSuchDistribution) {
|
|
18550
|
+
const clientRegion = await this.cloudFrontClient.config.region();
|
|
18551
|
+
assertRegionMatch(
|
|
18552
|
+
clientRegion,
|
|
18553
|
+
context?.expectedRegion,
|
|
18554
|
+
resourceType,
|
|
18555
|
+
logicalId,
|
|
18556
|
+
physicalId
|
|
18557
|
+
);
|
|
17799
18558
|
this.logger.debug(`Distribution ${physicalId} does not exist, skipping deletion`);
|
|
17800
18559
|
return;
|
|
17801
18560
|
}
|
|
@@ -18215,7 +18974,7 @@ var AgentCoreRuntimeProvider = class {
|
|
|
18215
18974
|
/**
|
|
18216
18975
|
* Delete a BedrockAgentCore Runtime
|
|
18217
18976
|
*/
|
|
18218
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
18977
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
18219
18978
|
this.logger.debug(`Deleting BedrockAgentCore Runtime ${logicalId}: ${physicalId}`);
|
|
18220
18979
|
try {
|
|
18221
18980
|
await this.client.send(
|
|
@@ -18226,6 +18985,14 @@ var AgentCoreRuntimeProvider = class {
|
|
|
18226
18985
|
this.logger.debug(`Successfully deleted BedrockAgentCore Runtime ${logicalId}`);
|
|
18227
18986
|
} catch (error) {
|
|
18228
18987
|
if (error instanceof ResourceNotFoundException11) {
|
|
18988
|
+
const clientRegion = await this.client.config.region();
|
|
18989
|
+
assertRegionMatch(
|
|
18990
|
+
clientRegion,
|
|
18991
|
+
context?.expectedRegion,
|
|
18992
|
+
resourceType,
|
|
18993
|
+
logicalId,
|
|
18994
|
+
physicalId
|
|
18995
|
+
);
|
|
18229
18996
|
this.logger.debug(`Runtime ${physicalId} does not exist, skipping deletion`);
|
|
18230
18997
|
return;
|
|
18231
18998
|
}
|
|
@@ -18421,13 +19188,21 @@ var StepFunctionsProvider = class {
|
|
|
18421
19188
|
/**
|
|
18422
19189
|
* Delete a Step Functions state machine
|
|
18423
19190
|
*/
|
|
18424
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
19191
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
18425
19192
|
this.logger.debug(`Deleting Step Functions state machine ${logicalId}: ${physicalId}`);
|
|
18426
19193
|
try {
|
|
18427
19194
|
await this.getClient().send(new DeleteStateMachineCommand({ stateMachineArn: physicalId }));
|
|
18428
19195
|
this.logger.debug(`Successfully deleted Step Functions state machine ${logicalId}`);
|
|
18429
19196
|
} catch (error) {
|
|
18430
19197
|
if (error instanceof StateMachineDoesNotExist) {
|
|
19198
|
+
const clientRegion = await this.getClient().config.region();
|
|
19199
|
+
assertRegionMatch(
|
|
19200
|
+
clientRegion,
|
|
19201
|
+
context?.expectedRegion,
|
|
19202
|
+
resourceType,
|
|
19203
|
+
logicalId,
|
|
19204
|
+
physicalId
|
|
19205
|
+
);
|
|
18431
19206
|
this.logger.debug(
|
|
18432
19207
|
`Step Functions state machine ${physicalId} does not exist, skipping deletion`
|
|
18433
19208
|
);
|
|
@@ -18594,14 +19369,14 @@ var ECSProvider = class {
|
|
|
18594
19369
|
);
|
|
18595
19370
|
}
|
|
18596
19371
|
}
|
|
18597
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
19372
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
18598
19373
|
switch (resourceType) {
|
|
18599
19374
|
case "AWS::ECS::Cluster":
|
|
18600
|
-
return this.deleteCluster(logicalId, physicalId, resourceType);
|
|
19375
|
+
return this.deleteCluster(logicalId, physicalId, resourceType, context);
|
|
18601
19376
|
case "AWS::ECS::TaskDefinition":
|
|
18602
|
-
return this.deleteTaskDefinition(logicalId, physicalId, resourceType);
|
|
19377
|
+
return this.deleteTaskDefinition(logicalId, physicalId, resourceType, context);
|
|
18603
19378
|
case "AWS::ECS::Service":
|
|
18604
|
-
return this.deleteService(logicalId, physicalId, resourceType, properties);
|
|
19379
|
+
return this.deleteService(logicalId, physicalId, resourceType, properties, context);
|
|
18605
19380
|
default:
|
|
18606
19381
|
throw new ProvisioningError(
|
|
18607
19382
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -18702,7 +19477,7 @@ var ECSProvider = class {
|
|
|
18702
19477
|
);
|
|
18703
19478
|
}
|
|
18704
19479
|
}
|
|
18705
|
-
async deleteCluster(logicalId, physicalId, resourceType) {
|
|
19480
|
+
async deleteCluster(logicalId, physicalId, resourceType, context) {
|
|
18706
19481
|
this.logger.debug(`Deleting ECS cluster ${logicalId}: ${physicalId}`);
|
|
18707
19482
|
const client = this.getClient();
|
|
18708
19483
|
try {
|
|
@@ -18710,6 +19485,14 @@ var ECSProvider = class {
|
|
|
18710
19485
|
this.logger.debug(`Successfully deleted ECS cluster ${logicalId}`);
|
|
18711
19486
|
} catch (error) {
|
|
18712
19487
|
if (this.isClusterNotFoundException(error)) {
|
|
19488
|
+
const clientRegion = await client.config.region();
|
|
19489
|
+
assertRegionMatch(
|
|
19490
|
+
clientRegion,
|
|
19491
|
+
context?.expectedRegion,
|
|
19492
|
+
resourceType,
|
|
19493
|
+
logicalId,
|
|
19494
|
+
physicalId
|
|
19495
|
+
);
|
|
18713
19496
|
this.logger.debug(`ECS cluster ${physicalId} not found, skipping deletion`);
|
|
18714
19497
|
return;
|
|
18715
19498
|
}
|
|
@@ -18809,7 +19592,7 @@ var ECSProvider = class {
|
|
|
18809
19592
|
attributes: result.attributes ?? {}
|
|
18810
19593
|
};
|
|
18811
19594
|
}
|
|
18812
|
-
async deleteTaskDefinition(logicalId, physicalId, resourceType) {
|
|
19595
|
+
async deleteTaskDefinition(logicalId, physicalId, resourceType, context) {
|
|
18813
19596
|
this.logger.debug(`Deleting ECS task definition ${logicalId}: ${physicalId}`);
|
|
18814
19597
|
const client = this.getClient();
|
|
18815
19598
|
try {
|
|
@@ -18817,6 +19600,14 @@ var ECSProvider = class {
|
|
|
18817
19600
|
this.logger.debug(`Successfully deregistered ECS task definition ${logicalId}`);
|
|
18818
19601
|
} catch (error) {
|
|
18819
19602
|
if (this.isNotFoundException(error)) {
|
|
19603
|
+
const clientRegion = await client.config.region();
|
|
19604
|
+
assertRegionMatch(
|
|
19605
|
+
clientRegion,
|
|
19606
|
+
context?.expectedRegion,
|
|
19607
|
+
resourceType,
|
|
19608
|
+
logicalId,
|
|
19609
|
+
physicalId
|
|
19610
|
+
);
|
|
18820
19611
|
this.logger.debug(`ECS task definition ${physicalId} not found, skipping deletion`);
|
|
18821
19612
|
return;
|
|
18822
19613
|
}
|
|
@@ -18955,7 +19746,7 @@ var ECSProvider = class {
|
|
|
18955
19746
|
);
|
|
18956
19747
|
}
|
|
18957
19748
|
}
|
|
18958
|
-
async deleteService(logicalId, physicalId, resourceType, properties) {
|
|
19749
|
+
async deleteService(logicalId, physicalId, resourceType, properties, context) {
|
|
18959
19750
|
this.logger.debug(`Deleting ECS service ${logicalId}: ${physicalId}`);
|
|
18960
19751
|
const client = this.getClient();
|
|
18961
19752
|
const cluster = properties?.["Cluster"];
|
|
@@ -18971,6 +19762,14 @@ var ECSProvider = class {
|
|
|
18971
19762
|
this.logger.debug(`Scaled down ECS service ${physicalId} to 0`);
|
|
18972
19763
|
} catch (error) {
|
|
18973
19764
|
if (this.isServiceNotFoundException(error)) {
|
|
19765
|
+
const clientRegion = await client.config.region();
|
|
19766
|
+
assertRegionMatch(
|
|
19767
|
+
clientRegion,
|
|
19768
|
+
context?.expectedRegion,
|
|
19769
|
+
resourceType,
|
|
19770
|
+
logicalId,
|
|
19771
|
+
physicalId
|
|
19772
|
+
);
|
|
18974
19773
|
this.logger.debug(
|
|
18975
19774
|
`ECS service ${physicalId} not found during scale down, skipping deletion`
|
|
18976
19775
|
);
|
|
@@ -18988,6 +19787,14 @@ var ECSProvider = class {
|
|
|
18988
19787
|
this.logger.debug(`Successfully deleted ECS service ${logicalId}`);
|
|
18989
19788
|
} catch (error) {
|
|
18990
19789
|
if (this.isServiceNotFoundException(error)) {
|
|
19790
|
+
const clientRegion = await client.config.region();
|
|
19791
|
+
assertRegionMatch(
|
|
19792
|
+
clientRegion,
|
|
19793
|
+
context?.expectedRegion,
|
|
19794
|
+
resourceType,
|
|
19795
|
+
logicalId,
|
|
19796
|
+
physicalId
|
|
19797
|
+
);
|
|
18991
19798
|
this.logger.debug(`ECS service ${physicalId} not found, skipping deletion`);
|
|
18992
19799
|
return;
|
|
18993
19800
|
}
|
|
@@ -19286,14 +20093,14 @@ var ELBv2Provider = class {
|
|
|
19286
20093
|
);
|
|
19287
20094
|
}
|
|
19288
20095
|
}
|
|
19289
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
20096
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
19290
20097
|
switch (resourceType) {
|
|
19291
20098
|
case "AWS::ElasticLoadBalancingV2::LoadBalancer":
|
|
19292
|
-
return this.deleteLoadBalancer(logicalId, physicalId, resourceType);
|
|
20099
|
+
return this.deleteLoadBalancer(logicalId, physicalId, resourceType, context);
|
|
19293
20100
|
case "AWS::ElasticLoadBalancingV2::TargetGroup":
|
|
19294
|
-
return this.deleteTargetGroup(logicalId, physicalId, resourceType);
|
|
20101
|
+
return this.deleteTargetGroup(logicalId, physicalId, resourceType, context);
|
|
19295
20102
|
case "AWS::ElasticLoadBalancingV2::Listener":
|
|
19296
|
-
return this.deleteListener(logicalId, physicalId, resourceType);
|
|
20103
|
+
return this.deleteListener(logicalId, physicalId, resourceType, context);
|
|
19297
20104
|
default:
|
|
19298
20105
|
throw new ProvisioningError(
|
|
19299
20106
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -19394,13 +20201,21 @@ var ELBv2Provider = class {
|
|
|
19394
20201
|
);
|
|
19395
20202
|
}
|
|
19396
20203
|
}
|
|
19397
|
-
async deleteLoadBalancer(logicalId, physicalId, resourceType) {
|
|
20204
|
+
async deleteLoadBalancer(logicalId, physicalId, resourceType, context) {
|
|
19398
20205
|
this.logger.debug(`Deleting LoadBalancer ${logicalId}: ${physicalId}`);
|
|
19399
20206
|
try {
|
|
19400
20207
|
await this.getClient().send(new DeleteLoadBalancerCommand({ LoadBalancerArn: physicalId }));
|
|
19401
20208
|
this.logger.debug(`Successfully deleted LoadBalancer ${logicalId}`);
|
|
19402
20209
|
} catch (error) {
|
|
19403
20210
|
if (this.isNotFoundError(error)) {
|
|
20211
|
+
const clientRegion = await this.getClient().config.region();
|
|
20212
|
+
assertRegionMatch(
|
|
20213
|
+
clientRegion,
|
|
20214
|
+
context?.expectedRegion,
|
|
20215
|
+
resourceType,
|
|
20216
|
+
logicalId,
|
|
20217
|
+
physicalId
|
|
20218
|
+
);
|
|
19404
20219
|
this.logger.debug(`LoadBalancer ${physicalId} does not exist, skipping deletion`);
|
|
19405
20220
|
return;
|
|
19406
20221
|
}
|
|
@@ -19510,13 +20325,21 @@ var ELBv2Provider = class {
|
|
|
19510
20325
|
);
|
|
19511
20326
|
}
|
|
19512
20327
|
}
|
|
19513
|
-
async deleteTargetGroup(logicalId, physicalId, resourceType) {
|
|
20328
|
+
async deleteTargetGroup(logicalId, physicalId, resourceType, context) {
|
|
19514
20329
|
this.logger.debug(`Deleting TargetGroup ${logicalId}: ${physicalId}`);
|
|
19515
20330
|
try {
|
|
19516
20331
|
await this.getClient().send(new DeleteTargetGroupCommand({ TargetGroupArn: physicalId }));
|
|
19517
20332
|
this.logger.debug(`Successfully deleted TargetGroup ${logicalId}`);
|
|
19518
20333
|
} catch (error) {
|
|
19519
20334
|
if (this.isNotFoundError(error)) {
|
|
20335
|
+
const clientRegion = await this.getClient().config.region();
|
|
20336
|
+
assertRegionMatch(
|
|
20337
|
+
clientRegion,
|
|
20338
|
+
context?.expectedRegion,
|
|
20339
|
+
resourceType,
|
|
20340
|
+
logicalId,
|
|
20341
|
+
physicalId
|
|
20342
|
+
);
|
|
19520
20343
|
this.logger.debug(`TargetGroup ${physicalId} does not exist, skipping deletion`);
|
|
19521
20344
|
return;
|
|
19522
20345
|
}
|
|
@@ -19612,13 +20435,21 @@ var ELBv2Provider = class {
|
|
|
19612
20435
|
);
|
|
19613
20436
|
}
|
|
19614
20437
|
}
|
|
19615
|
-
async deleteListener(logicalId, physicalId, resourceType) {
|
|
20438
|
+
async deleteListener(logicalId, physicalId, resourceType, context) {
|
|
19616
20439
|
this.logger.debug(`Deleting Listener ${logicalId}: ${physicalId}`);
|
|
19617
20440
|
try {
|
|
19618
20441
|
await this.getClient().send(new DeleteListenerCommand({ ListenerArn: physicalId }));
|
|
19619
20442
|
this.logger.debug(`Successfully deleted Listener ${logicalId}`);
|
|
19620
20443
|
} catch (error) {
|
|
19621
20444
|
if (this.isNotFoundError(error)) {
|
|
20445
|
+
const clientRegion = await this.getClient().config.region();
|
|
20446
|
+
assertRegionMatch(
|
|
20447
|
+
clientRegion,
|
|
20448
|
+
context?.expectedRegion,
|
|
20449
|
+
resourceType,
|
|
20450
|
+
logicalId,
|
|
20451
|
+
physicalId
|
|
20452
|
+
);
|
|
19622
20453
|
this.logger.debug(`Listener ${physicalId} does not exist, skipping deletion`);
|
|
19623
20454
|
return;
|
|
19624
20455
|
}
|
|
@@ -19768,14 +20599,14 @@ var RDSProvider = class {
|
|
|
19768
20599
|
);
|
|
19769
20600
|
}
|
|
19770
20601
|
}
|
|
19771
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
20602
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
19772
20603
|
switch (resourceType) {
|
|
19773
20604
|
case "AWS::RDS::DBSubnetGroup":
|
|
19774
|
-
return this.deleteDBSubnetGroup(logicalId, physicalId, resourceType);
|
|
20605
|
+
return this.deleteDBSubnetGroup(logicalId, physicalId, resourceType, context);
|
|
19775
20606
|
case "AWS::RDS::DBCluster":
|
|
19776
|
-
return this.deleteDBCluster(logicalId, physicalId, resourceType);
|
|
20607
|
+
return this.deleteDBCluster(logicalId, physicalId, resourceType, context);
|
|
19777
20608
|
case "AWS::RDS::DBInstance":
|
|
19778
|
-
return this.deleteDBInstance(logicalId, physicalId, resourceType);
|
|
20609
|
+
return this.deleteDBInstance(logicalId, physicalId, resourceType, context);
|
|
19779
20610
|
default:
|
|
19780
20611
|
throw new ProvisioningError(
|
|
19781
20612
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -19846,7 +20677,7 @@ var RDSProvider = class {
|
|
|
19846
20677
|
);
|
|
19847
20678
|
}
|
|
19848
20679
|
}
|
|
19849
|
-
async deleteDBSubnetGroup(logicalId, physicalId, resourceType) {
|
|
20680
|
+
async deleteDBSubnetGroup(logicalId, physicalId, resourceType, context) {
|
|
19850
20681
|
this.logger.debug(`Deleting DBSubnetGroup ${logicalId}: ${physicalId}`);
|
|
19851
20682
|
try {
|
|
19852
20683
|
await this.getClient().send(
|
|
@@ -19857,6 +20688,14 @@ var RDSProvider = class {
|
|
|
19857
20688
|
this.logger.debug(`Successfully deleted DBSubnetGroup ${logicalId}`);
|
|
19858
20689
|
} catch (error) {
|
|
19859
20690
|
if (this.isNotFoundError(error, "DBSubnetGroupNotFoundFault")) {
|
|
20691
|
+
const clientRegion = await this.getClient().config.region();
|
|
20692
|
+
assertRegionMatch(
|
|
20693
|
+
clientRegion,
|
|
20694
|
+
context?.expectedRegion,
|
|
20695
|
+
resourceType,
|
|
20696
|
+
logicalId,
|
|
20697
|
+
physicalId
|
|
20698
|
+
);
|
|
19860
20699
|
this.logger.debug(`DBSubnetGroup ${physicalId} does not exist, skipping deletion`);
|
|
19861
20700
|
return;
|
|
19862
20701
|
}
|
|
@@ -19979,7 +20818,7 @@ var RDSProvider = class {
|
|
|
19979
20818
|
);
|
|
19980
20819
|
}
|
|
19981
20820
|
}
|
|
19982
|
-
async deleteDBCluster(logicalId, physicalId, resourceType) {
|
|
20821
|
+
async deleteDBCluster(logicalId, physicalId, resourceType, context) {
|
|
19983
20822
|
this.logger.debug(`Deleting DBCluster ${logicalId}: ${physicalId}`);
|
|
19984
20823
|
try {
|
|
19985
20824
|
try {
|
|
@@ -20006,6 +20845,14 @@ var RDSProvider = class {
|
|
|
20006
20845
|
await this.waitForClusterDeleted(physicalId);
|
|
20007
20846
|
} catch (error) {
|
|
20008
20847
|
if (this.isNotFoundError(error, "DBClusterNotFoundFault")) {
|
|
20848
|
+
const clientRegion = await this.getClient().config.region();
|
|
20849
|
+
assertRegionMatch(
|
|
20850
|
+
clientRegion,
|
|
20851
|
+
context?.expectedRegion,
|
|
20852
|
+
resourceType,
|
|
20853
|
+
logicalId,
|
|
20854
|
+
physicalId
|
|
20855
|
+
);
|
|
20009
20856
|
this.logger.debug(`DBCluster ${physicalId} does not exist, skipping deletion`);
|
|
20010
20857
|
return;
|
|
20011
20858
|
}
|
|
@@ -20099,7 +20946,7 @@ var RDSProvider = class {
|
|
|
20099
20946
|
);
|
|
20100
20947
|
}
|
|
20101
20948
|
}
|
|
20102
|
-
async deleteDBInstance(logicalId, physicalId, resourceType) {
|
|
20949
|
+
async deleteDBInstance(logicalId, physicalId, resourceType, context) {
|
|
20103
20950
|
this.logger.debug(`Deleting DBInstance ${logicalId}: ${physicalId}`);
|
|
20104
20951
|
try {
|
|
20105
20952
|
try {
|
|
@@ -20127,6 +20974,14 @@ var RDSProvider = class {
|
|
|
20127
20974
|
await this.waitForInstanceDeleted(physicalId);
|
|
20128
20975
|
} catch (error) {
|
|
20129
20976
|
if (this.isNotFoundError(error, "DBInstanceNotFoundFault")) {
|
|
20977
|
+
const clientRegion = await this.getClient().config.region();
|
|
20978
|
+
assertRegionMatch(
|
|
20979
|
+
clientRegion,
|
|
20980
|
+
context?.expectedRegion,
|
|
20981
|
+
resourceType,
|
|
20982
|
+
logicalId,
|
|
20983
|
+
physicalId
|
|
20984
|
+
);
|
|
20130
20985
|
this.logger.debug(`DBInstance ${physicalId} does not exist, skipping deletion`);
|
|
20131
20986
|
return;
|
|
20132
20987
|
}
|
|
@@ -20340,12 +21195,12 @@ var Route53Provider = class {
|
|
|
20340
21195
|
);
|
|
20341
21196
|
}
|
|
20342
21197
|
}
|
|
20343
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
21198
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
20344
21199
|
switch (resourceType) {
|
|
20345
21200
|
case "AWS::Route53::HostedZone":
|
|
20346
|
-
return this.deleteHostedZone(logicalId, physicalId, resourceType);
|
|
21201
|
+
return this.deleteHostedZone(logicalId, physicalId, resourceType, context);
|
|
20347
21202
|
case "AWS::Route53::RecordSet":
|
|
20348
|
-
return this.deleteRecordSet(logicalId, physicalId, resourceType, properties);
|
|
21203
|
+
return this.deleteRecordSet(logicalId, physicalId, resourceType, properties, context);
|
|
20349
21204
|
default:
|
|
20350
21205
|
throw new ProvisioningError(
|
|
20351
21206
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -20479,7 +21334,7 @@ var Route53Provider = class {
|
|
|
20479
21334
|
);
|
|
20480
21335
|
}
|
|
20481
21336
|
}
|
|
20482
|
-
async deleteHostedZone(logicalId, physicalId, resourceType) {
|
|
21337
|
+
async deleteHostedZone(logicalId, physicalId, resourceType, context) {
|
|
20483
21338
|
this.logger.debug(`Deleting Route 53 hosted zone ${logicalId}: ${physicalId}`);
|
|
20484
21339
|
try {
|
|
20485
21340
|
await this.deleteQueryLoggingConfigForZone(physicalId, logicalId);
|
|
@@ -20487,6 +21342,14 @@ var Route53Provider = class {
|
|
|
20487
21342
|
this.logger.debug(`Successfully deleted hosted zone ${logicalId}`);
|
|
20488
21343
|
} catch (error) {
|
|
20489
21344
|
if (error instanceof Error && error.name === "NoSuchHostedZone") {
|
|
21345
|
+
const clientRegion = await this.getClient().config.region();
|
|
21346
|
+
assertRegionMatch(
|
|
21347
|
+
clientRegion,
|
|
21348
|
+
context?.expectedRegion,
|
|
21349
|
+
resourceType,
|
|
21350
|
+
logicalId,
|
|
21351
|
+
physicalId
|
|
21352
|
+
);
|
|
20490
21353
|
this.logger.debug(`Hosted zone ${physicalId} does not exist, skipping deletion`);
|
|
20491
21354
|
return;
|
|
20492
21355
|
}
|
|
@@ -20599,7 +21462,7 @@ var Route53Provider = class {
|
|
|
20599
21462
|
);
|
|
20600
21463
|
}
|
|
20601
21464
|
}
|
|
20602
|
-
async deleteRecordSet(logicalId, physicalId, resourceType, properties) {
|
|
21465
|
+
async deleteRecordSet(logicalId, physicalId, resourceType, properties, context) {
|
|
20603
21466
|
this.logger.debug(`Deleting Route 53 record set ${logicalId}: ${physicalId}`);
|
|
20604
21467
|
const parts = physicalId.split("|");
|
|
20605
21468
|
if (parts.length !== 3) {
|
|
@@ -20637,6 +21500,14 @@ var Route53Provider = class {
|
|
|
20637
21500
|
this.logger.debug(`Successfully deleted record set ${logicalId}`);
|
|
20638
21501
|
} catch (error) {
|
|
20639
21502
|
if (error instanceof Error && (error.name === "InvalidChangeBatch" || error.message.includes("it was not found"))) {
|
|
21503
|
+
const clientRegion = await this.getClient().config.region();
|
|
21504
|
+
assertRegionMatch(
|
|
21505
|
+
clientRegion,
|
|
21506
|
+
context?.expectedRegion,
|
|
21507
|
+
resourceType,
|
|
21508
|
+
logicalId,
|
|
21509
|
+
physicalId
|
|
21510
|
+
);
|
|
20640
21511
|
this.logger.debug(`Record set ${physicalId} does not exist, skipping deletion`);
|
|
20641
21512
|
return;
|
|
20642
21513
|
}
|
|
@@ -21077,7 +21948,7 @@ var WAFv2WebACLProvider = class {
|
|
|
21077
21948
|
* DeleteWebACL requires LockToken obtained from GetWebACL.
|
|
21078
21949
|
* WAFNonexistentItemException is treated as success (idempotent delete).
|
|
21079
21950
|
*/
|
|
21080
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
21951
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
21081
21952
|
this.logger.debug(`Deleting WAFv2 WebACL ${logicalId}: ${physicalId}`);
|
|
21082
21953
|
try {
|
|
21083
21954
|
const { id, name, scope } = parseWebACLArn(physicalId);
|
|
@@ -21103,6 +21974,14 @@ var WAFv2WebACLProvider = class {
|
|
|
21103
21974
|
this.logger.debug(`Successfully deleted WAFv2 WebACL ${logicalId}`);
|
|
21104
21975
|
} catch (error) {
|
|
21105
21976
|
if (error instanceof WAFNonexistentItemException) {
|
|
21977
|
+
const clientRegion = await this.getClient().config.region();
|
|
21978
|
+
assertRegionMatch(
|
|
21979
|
+
clientRegion,
|
|
21980
|
+
context?.expectedRegion,
|
|
21981
|
+
resourceType,
|
|
21982
|
+
logicalId,
|
|
21983
|
+
physicalId
|
|
21984
|
+
);
|
|
21106
21985
|
this.logger.debug(`WAFv2 WebACL ${physicalId} does not exist, skipping deletion`);
|
|
21107
21986
|
return;
|
|
21108
21987
|
}
|
|
@@ -21387,7 +22266,7 @@ var CognitoUserPoolProvider = class {
|
|
|
21387
22266
|
*
|
|
21388
22267
|
* If DeletionProtection is ACTIVE, it is automatically disabled before deletion.
|
|
21389
22268
|
*/
|
|
21390
|
-
async delete(logicalId, physicalId, resourceType, properties) {
|
|
22269
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
21391
22270
|
this.logger.debug(`Deleting Cognito User Pool ${logicalId}: ${physicalId}`);
|
|
21392
22271
|
try {
|
|
21393
22272
|
const deletionProtection = properties?.["DeletionProtection"];
|
|
@@ -21419,6 +22298,14 @@ var CognitoUserPoolProvider = class {
|
|
|
21419
22298
|
}
|
|
21420
22299
|
} catch (descError) {
|
|
21421
22300
|
if (descError instanceof ResourceNotFoundException12) {
|
|
22301
|
+
const clientRegion = await this.getClient().config.region();
|
|
22302
|
+
assertRegionMatch(
|
|
22303
|
+
clientRegion,
|
|
22304
|
+
context?.expectedRegion,
|
|
22305
|
+
resourceType,
|
|
22306
|
+
logicalId,
|
|
22307
|
+
physicalId
|
|
22308
|
+
);
|
|
21422
22309
|
this.logger.debug(`Cognito User Pool ${physicalId} does not exist, skipping deletion`);
|
|
21423
22310
|
return;
|
|
21424
22311
|
}
|
|
@@ -21431,6 +22318,14 @@ var CognitoUserPoolProvider = class {
|
|
|
21431
22318
|
this.logger.debug(`Successfully deleted Cognito User Pool ${logicalId}`);
|
|
21432
22319
|
} catch (error) {
|
|
21433
22320
|
if (error instanceof ResourceNotFoundException12) {
|
|
22321
|
+
const clientRegion = await this.getClient().config.region();
|
|
22322
|
+
assertRegionMatch(
|
|
22323
|
+
clientRegion,
|
|
22324
|
+
context?.expectedRegion,
|
|
22325
|
+
resourceType,
|
|
22326
|
+
logicalId,
|
|
22327
|
+
physicalId
|
|
22328
|
+
);
|
|
21434
22329
|
this.logger.debug(`Cognito User Pool ${physicalId} does not exist, skipping deletion`);
|
|
21435
22330
|
return;
|
|
21436
22331
|
}
|
|
@@ -21533,12 +22428,12 @@ var ElastiCacheProvider = class {
|
|
|
21533
22428
|
);
|
|
21534
22429
|
}
|
|
21535
22430
|
}
|
|
21536
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
22431
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
21537
22432
|
switch (resourceType) {
|
|
21538
22433
|
case "AWS::ElastiCache::SubnetGroup":
|
|
21539
|
-
return this.deleteSubnetGroup(logicalId, physicalId, resourceType);
|
|
22434
|
+
return this.deleteSubnetGroup(logicalId, physicalId, resourceType, context);
|
|
21540
22435
|
case "AWS::ElastiCache::CacheCluster":
|
|
21541
|
-
return this.deleteCacheCluster(logicalId, physicalId, resourceType);
|
|
22436
|
+
return this.deleteCacheCluster(logicalId, physicalId, resourceType, context);
|
|
21542
22437
|
default:
|
|
21543
22438
|
throw new ProvisioningError(
|
|
21544
22439
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -21609,7 +22504,7 @@ var ElastiCacheProvider = class {
|
|
|
21609
22504
|
);
|
|
21610
22505
|
}
|
|
21611
22506
|
}
|
|
21612
|
-
async deleteSubnetGroup(logicalId, physicalId, resourceType) {
|
|
22507
|
+
async deleteSubnetGroup(logicalId, physicalId, resourceType, context) {
|
|
21613
22508
|
this.logger.debug(`Deleting CacheSubnetGroup ${logicalId}: ${physicalId}`);
|
|
21614
22509
|
try {
|
|
21615
22510
|
await this.getClient().send(
|
|
@@ -21620,6 +22515,14 @@ var ElastiCacheProvider = class {
|
|
|
21620
22515
|
this.logger.debug(`Successfully deleted CacheSubnetGroup ${logicalId}`);
|
|
21621
22516
|
} catch (error) {
|
|
21622
22517
|
if (this.isNotFoundError(error, "CacheSubnetGroupNotFoundFault")) {
|
|
22518
|
+
const clientRegion = await this.getClient().config.region();
|
|
22519
|
+
assertRegionMatch(
|
|
22520
|
+
clientRegion,
|
|
22521
|
+
context?.expectedRegion,
|
|
22522
|
+
resourceType,
|
|
22523
|
+
logicalId,
|
|
22524
|
+
physicalId
|
|
22525
|
+
);
|
|
21623
22526
|
this.logger.debug(`CacheSubnetGroup ${physicalId} does not exist, skipping deletion`);
|
|
21624
22527
|
return;
|
|
21625
22528
|
}
|
|
@@ -21753,7 +22656,7 @@ var ElastiCacheProvider = class {
|
|
|
21753
22656
|
);
|
|
21754
22657
|
}
|
|
21755
22658
|
}
|
|
21756
|
-
async deleteCacheCluster(logicalId, physicalId, resourceType) {
|
|
22659
|
+
async deleteCacheCluster(logicalId, physicalId, resourceType, context) {
|
|
21757
22660
|
this.logger.debug(`Deleting CacheCluster ${logicalId}: ${physicalId}`);
|
|
21758
22661
|
try {
|
|
21759
22662
|
await this.getClient().send(
|
|
@@ -21765,6 +22668,14 @@ var ElastiCacheProvider = class {
|
|
|
21765
22668
|
await this.waitForClusterDeleted(physicalId);
|
|
21766
22669
|
} catch (error) {
|
|
21767
22670
|
if (this.isNotFoundError(error, "CacheClusterNotFoundFault")) {
|
|
22671
|
+
const clientRegion = await this.getClient().config.region();
|
|
22672
|
+
assertRegionMatch(
|
|
22673
|
+
clientRegion,
|
|
22674
|
+
context?.expectedRegion,
|
|
22675
|
+
resourceType,
|
|
22676
|
+
logicalId,
|
|
22677
|
+
physicalId
|
|
22678
|
+
);
|
|
21768
22679
|
this.logger.debug(`CacheCluster ${physicalId} does not exist, skipping deletion`);
|
|
21769
22680
|
return;
|
|
21770
22681
|
}
|
|
@@ -21923,12 +22834,12 @@ var ServiceDiscoveryProvider = class {
|
|
|
21923
22834
|
);
|
|
21924
22835
|
}
|
|
21925
22836
|
}
|
|
21926
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
22837
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
21927
22838
|
switch (resourceType) {
|
|
21928
22839
|
case "AWS::ServiceDiscovery::PrivateDnsNamespace":
|
|
21929
|
-
return this.deleteNamespace(logicalId, physicalId, resourceType);
|
|
22840
|
+
return this.deleteNamespace(logicalId, physicalId, resourceType, context);
|
|
21930
22841
|
case "AWS::ServiceDiscovery::Service":
|
|
21931
|
-
return this.deleteService(logicalId, physicalId, resourceType);
|
|
22842
|
+
return this.deleteService(logicalId, physicalId, resourceType, context);
|
|
21932
22843
|
default:
|
|
21933
22844
|
throw new ProvisioningError(
|
|
21934
22845
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -22006,7 +22917,7 @@ var ServiceDiscoveryProvider = class {
|
|
|
22006
22917
|
}
|
|
22007
22918
|
});
|
|
22008
22919
|
}
|
|
22009
|
-
async deleteNamespace(logicalId, physicalId, resourceType) {
|
|
22920
|
+
async deleteNamespace(logicalId, physicalId, resourceType, context) {
|
|
22010
22921
|
this.logger.debug(`Deleting private DNS namespace ${logicalId}: ${physicalId}`);
|
|
22011
22922
|
const client = this.getClient();
|
|
22012
22923
|
try {
|
|
@@ -22018,6 +22929,14 @@ var ServiceDiscoveryProvider = class {
|
|
|
22018
22929
|
this.logger.debug(`Successfully deleted private DNS namespace ${logicalId}`);
|
|
22019
22930
|
} catch (error) {
|
|
22020
22931
|
if (error instanceof NamespaceNotFound) {
|
|
22932
|
+
const clientRegion = await this.getClient().config.region();
|
|
22933
|
+
assertRegionMatch(
|
|
22934
|
+
clientRegion,
|
|
22935
|
+
context?.expectedRegion,
|
|
22936
|
+
resourceType,
|
|
22937
|
+
logicalId,
|
|
22938
|
+
physicalId
|
|
22939
|
+
);
|
|
22021
22940
|
this.logger.debug(`Namespace ${physicalId} does not exist, skipping deletion`);
|
|
22022
22941
|
return;
|
|
22023
22942
|
}
|
|
@@ -22101,7 +23020,7 @@ var ServiceDiscoveryProvider = class {
|
|
|
22101
23020
|
}
|
|
22102
23021
|
});
|
|
22103
23022
|
}
|
|
22104
|
-
async deleteService(logicalId, physicalId, resourceType) {
|
|
23023
|
+
async deleteService(logicalId, physicalId, resourceType, context) {
|
|
22105
23024
|
this.logger.debug(`Deleting service discovery service ${logicalId}: ${physicalId}`);
|
|
22106
23025
|
const client = this.getClient();
|
|
22107
23026
|
try {
|
|
@@ -22109,6 +23028,14 @@ var ServiceDiscoveryProvider = class {
|
|
|
22109
23028
|
this.logger.debug(`Successfully deleted service discovery service ${logicalId}`);
|
|
22110
23029
|
} catch (error) {
|
|
22111
23030
|
if (error instanceof ServiceNotFound) {
|
|
23031
|
+
const clientRegion = await this.getClient().config.region();
|
|
23032
|
+
assertRegionMatch(
|
|
23033
|
+
clientRegion,
|
|
23034
|
+
context?.expectedRegion,
|
|
23035
|
+
resourceType,
|
|
23036
|
+
logicalId,
|
|
23037
|
+
physicalId
|
|
23038
|
+
);
|
|
22112
23039
|
this.logger.debug(`Service ${physicalId} does not exist, skipping deletion`);
|
|
22113
23040
|
return;
|
|
22114
23041
|
}
|
|
@@ -22255,19 +23182,19 @@ var AppSyncProvider = class {
|
|
|
22255
23182
|
this.logger.debug(`Update for ${resourceType} ${logicalId} (${physicalId}) - no-op, immutable`);
|
|
22256
23183
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
22257
23184
|
}
|
|
22258
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
23185
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
22259
23186
|
switch (resourceType) {
|
|
22260
23187
|
case "AWS::AppSync::GraphQLApi":
|
|
22261
|
-
return this.deleteGraphQLApi(logicalId, physicalId, resourceType);
|
|
23188
|
+
return this.deleteGraphQLApi(logicalId, physicalId, resourceType, context);
|
|
22262
23189
|
case "AWS::AppSync::GraphQLSchema":
|
|
22263
23190
|
this.logger.debug(`Schema ${logicalId} is deleted with its API, skipping`);
|
|
22264
23191
|
return;
|
|
22265
23192
|
case "AWS::AppSync::DataSource":
|
|
22266
|
-
return this.deleteDataSource(logicalId, physicalId, resourceType);
|
|
23193
|
+
return this.deleteDataSource(logicalId, physicalId, resourceType, context);
|
|
22267
23194
|
case "AWS::AppSync::Resolver":
|
|
22268
|
-
return this.deleteResolver(logicalId, physicalId, resourceType);
|
|
23195
|
+
return this.deleteResolver(logicalId, physicalId, resourceType, context);
|
|
22269
23196
|
case "AWS::AppSync::ApiKey":
|
|
22270
|
-
return this.deleteApiKey(logicalId, physicalId, resourceType);
|
|
23197
|
+
return this.deleteApiKey(logicalId, physicalId, resourceType, context);
|
|
22271
23198
|
default:
|
|
22272
23199
|
throw new ProvisioningError(
|
|
22273
23200
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -22341,13 +23268,21 @@ var AppSyncProvider = class {
|
|
|
22341
23268
|
);
|
|
22342
23269
|
}
|
|
22343
23270
|
}
|
|
22344
|
-
async deleteGraphQLApi(logicalId, physicalId, resourceType) {
|
|
23271
|
+
async deleteGraphQLApi(logicalId, physicalId, resourceType, context) {
|
|
22345
23272
|
this.logger.debug(`Deleting GraphQL API ${logicalId}: ${physicalId}`);
|
|
22346
23273
|
try {
|
|
22347
23274
|
await this.getClient().send(new DeleteGraphqlApiCommand({ apiId: physicalId }));
|
|
22348
23275
|
this.logger.debug(`Successfully deleted GraphQL API ${logicalId}`);
|
|
22349
23276
|
} catch (error) {
|
|
22350
23277
|
if (this.isNotFoundError(error)) {
|
|
23278
|
+
const clientRegion = await this.getClient().config.region();
|
|
23279
|
+
assertRegionMatch(
|
|
23280
|
+
clientRegion,
|
|
23281
|
+
context?.expectedRegion,
|
|
23282
|
+
resourceType,
|
|
23283
|
+
logicalId,
|
|
23284
|
+
physicalId
|
|
23285
|
+
);
|
|
22351
23286
|
this.logger.debug(`GraphQL API ${physicalId} does not exist, skipping deletion`);
|
|
22352
23287
|
return;
|
|
22353
23288
|
}
|
|
@@ -22467,7 +23402,7 @@ var AppSyncProvider = class {
|
|
|
22467
23402
|
);
|
|
22468
23403
|
}
|
|
22469
23404
|
}
|
|
22470
|
-
async deleteDataSource(logicalId, physicalId, resourceType) {
|
|
23405
|
+
async deleteDataSource(logicalId, physicalId, resourceType, context) {
|
|
22471
23406
|
this.logger.debug(`Deleting DataSource ${logicalId}: ${physicalId}`);
|
|
22472
23407
|
const [apiId, name] = physicalId.split("|");
|
|
22473
23408
|
if (!apiId || !name) {
|
|
@@ -22479,6 +23414,14 @@ var AppSyncProvider = class {
|
|
|
22479
23414
|
this.logger.debug(`Successfully deleted DataSource ${logicalId}`);
|
|
22480
23415
|
} catch (error) {
|
|
22481
23416
|
if (this.isNotFoundError(error)) {
|
|
23417
|
+
const clientRegion = await this.getClient().config.region();
|
|
23418
|
+
assertRegionMatch(
|
|
23419
|
+
clientRegion,
|
|
23420
|
+
context?.expectedRegion,
|
|
23421
|
+
resourceType,
|
|
23422
|
+
logicalId,
|
|
23423
|
+
physicalId
|
|
23424
|
+
);
|
|
22482
23425
|
this.logger.debug(`DataSource ${physicalId} does not exist, skipping deletion`);
|
|
22483
23426
|
return;
|
|
22484
23427
|
}
|
|
@@ -22559,7 +23502,7 @@ var AppSyncProvider = class {
|
|
|
22559
23502
|
);
|
|
22560
23503
|
}
|
|
22561
23504
|
}
|
|
22562
|
-
async deleteResolver(logicalId, physicalId, resourceType) {
|
|
23505
|
+
async deleteResolver(logicalId, physicalId, resourceType, context) {
|
|
22563
23506
|
this.logger.debug(`Deleting Resolver ${logicalId}: ${physicalId}`);
|
|
22564
23507
|
const parts = physicalId.split("|");
|
|
22565
23508
|
if (parts.length < 3) {
|
|
@@ -22572,6 +23515,14 @@ var AppSyncProvider = class {
|
|
|
22572
23515
|
this.logger.debug(`Successfully deleted Resolver ${logicalId}`);
|
|
22573
23516
|
} catch (error) {
|
|
22574
23517
|
if (this.isNotFoundError(error)) {
|
|
23518
|
+
const clientRegion = await this.getClient().config.region();
|
|
23519
|
+
assertRegionMatch(
|
|
23520
|
+
clientRegion,
|
|
23521
|
+
context?.expectedRegion,
|
|
23522
|
+
resourceType,
|
|
23523
|
+
logicalId,
|
|
23524
|
+
physicalId
|
|
23525
|
+
);
|
|
22575
23526
|
this.logger.debug(`Resolver ${physicalId} does not exist, skipping deletion`);
|
|
22576
23527
|
return;
|
|
22577
23528
|
}
|
|
@@ -22625,7 +23576,7 @@ var AppSyncProvider = class {
|
|
|
22625
23576
|
);
|
|
22626
23577
|
}
|
|
22627
23578
|
}
|
|
22628
|
-
async deleteApiKey(logicalId, physicalId, resourceType) {
|
|
23579
|
+
async deleteApiKey(logicalId, physicalId, resourceType, context) {
|
|
22629
23580
|
this.logger.debug(`Deleting ApiKey ${logicalId}: ${physicalId}`);
|
|
22630
23581
|
const [apiId, apiKeyId] = physicalId.split("|");
|
|
22631
23582
|
if (!apiId || !apiKeyId) {
|
|
@@ -22637,6 +23588,14 @@ var AppSyncProvider = class {
|
|
|
22637
23588
|
this.logger.debug(`Successfully deleted ApiKey ${logicalId}`);
|
|
22638
23589
|
} catch (error) {
|
|
22639
23590
|
if (this.isNotFoundError(error)) {
|
|
23591
|
+
const clientRegion = await this.getClient().config.region();
|
|
23592
|
+
assertRegionMatch(
|
|
23593
|
+
clientRegion,
|
|
23594
|
+
context?.expectedRegion,
|
|
23595
|
+
resourceType,
|
|
23596
|
+
logicalId,
|
|
23597
|
+
physicalId
|
|
23598
|
+
);
|
|
22640
23599
|
this.logger.debug(`ApiKey ${physicalId} does not exist, skipping deletion`);
|
|
22641
23600
|
return;
|
|
22642
23601
|
}
|
|
@@ -22717,12 +23676,12 @@ var GlueProvider = class {
|
|
|
22717
23676
|
);
|
|
22718
23677
|
}
|
|
22719
23678
|
}
|
|
22720
|
-
async delete(logicalId, physicalId, resourceType,
|
|
23679
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
22721
23680
|
switch (resourceType) {
|
|
22722
23681
|
case "AWS::Glue::Database":
|
|
22723
|
-
return this.deleteDatabase(logicalId, physicalId, resourceType);
|
|
23682
|
+
return this.deleteDatabase(logicalId, physicalId, resourceType, properties, context);
|
|
22724
23683
|
case "AWS::Glue::Table":
|
|
22725
|
-
return this.deleteTable(logicalId, physicalId, resourceType);
|
|
23684
|
+
return this.deleteTable(logicalId, physicalId, resourceType, properties, context);
|
|
22726
23685
|
default:
|
|
22727
23686
|
throw new ProvisioningError(
|
|
22728
23687
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -22780,7 +23739,7 @@ var GlueProvider = class {
|
|
|
22780
23739
|
);
|
|
22781
23740
|
}
|
|
22782
23741
|
}
|
|
22783
|
-
async deleteDatabase(logicalId, physicalId, resourceType, properties) {
|
|
23742
|
+
async deleteDatabase(logicalId, physicalId, resourceType, properties, context) {
|
|
22784
23743
|
this.logger.debug(`Deleting Glue Database ${logicalId}: ${physicalId}`);
|
|
22785
23744
|
try {
|
|
22786
23745
|
const catalogId = properties?.["CatalogId"];
|
|
@@ -22793,6 +23752,14 @@ var GlueProvider = class {
|
|
|
22793
23752
|
this.logger.debug(`Successfully deleted Glue Database ${logicalId}`);
|
|
22794
23753
|
} catch (error) {
|
|
22795
23754
|
if (error instanceof EntityNotFoundException) {
|
|
23755
|
+
const clientRegion = await this.getClient().config.region();
|
|
23756
|
+
assertRegionMatch(
|
|
23757
|
+
clientRegion,
|
|
23758
|
+
context?.expectedRegion,
|
|
23759
|
+
resourceType,
|
|
23760
|
+
logicalId,
|
|
23761
|
+
physicalId
|
|
23762
|
+
);
|
|
22796
23763
|
this.logger.debug(`Glue Database ${physicalId} does not exist, skipping deletion`);
|
|
22797
23764
|
return;
|
|
22798
23765
|
}
|
|
@@ -22904,7 +23871,7 @@ var GlueProvider = class {
|
|
|
22904
23871
|
);
|
|
22905
23872
|
}
|
|
22906
23873
|
}
|
|
22907
|
-
async deleteTable(logicalId, physicalId, resourceType) {
|
|
23874
|
+
async deleteTable(logicalId, physicalId, resourceType, _properties, context) {
|
|
22908
23875
|
this.logger.debug(`Deleting Glue Table ${logicalId}: ${physicalId}`);
|
|
22909
23876
|
const [databaseName, tableName] = physicalId.split("|");
|
|
22910
23877
|
if (!databaseName || !tableName) {
|
|
@@ -22921,6 +23888,14 @@ var GlueProvider = class {
|
|
|
22921
23888
|
this.logger.debug(`Successfully deleted Glue Table ${logicalId}`);
|
|
22922
23889
|
} catch (error) {
|
|
22923
23890
|
if (error instanceof EntityNotFoundException) {
|
|
23891
|
+
const clientRegion = await this.getClient().config.region();
|
|
23892
|
+
assertRegionMatch(
|
|
23893
|
+
clientRegion,
|
|
23894
|
+
context?.expectedRegion,
|
|
23895
|
+
resourceType,
|
|
23896
|
+
logicalId,
|
|
23897
|
+
physicalId
|
|
23898
|
+
);
|
|
22924
23899
|
this.logger.debug(`Glue Table ${physicalId} does not exist, skipping deletion`);
|
|
22925
23900
|
return;
|
|
22926
23901
|
}
|
|
@@ -23106,12 +24081,12 @@ var KMSProvider = class {
|
|
|
23106
24081
|
);
|
|
23107
24082
|
}
|
|
23108
24083
|
}
|
|
23109
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
24084
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
23110
24085
|
switch (resourceType) {
|
|
23111
24086
|
case "AWS::KMS::Key":
|
|
23112
|
-
return this.deleteKey(logicalId, physicalId, resourceType, _properties);
|
|
24087
|
+
return this.deleteKey(logicalId, physicalId, resourceType, _properties, context);
|
|
23113
24088
|
case "AWS::KMS::Alias":
|
|
23114
|
-
return this.deleteAlias(logicalId, physicalId, resourceType);
|
|
24089
|
+
return this.deleteAlias(logicalId, physicalId, resourceType, context);
|
|
23115
24090
|
default:
|
|
23116
24091
|
throw new ProvisioningError(
|
|
23117
24092
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -23275,7 +24250,7 @@ var KMSProvider = class {
|
|
|
23275
24250
|
);
|
|
23276
24251
|
}
|
|
23277
24252
|
}
|
|
23278
|
-
async deleteKey(logicalId, physicalId, resourceType, properties) {
|
|
24253
|
+
async deleteKey(logicalId, physicalId, resourceType, properties, context) {
|
|
23279
24254
|
this.logger.debug(`Scheduling deletion for KMS Key ${logicalId}: ${physicalId}`);
|
|
23280
24255
|
const pendingWindowInDays = properties?.["PendingWindowInDays"] ?? 7;
|
|
23281
24256
|
try {
|
|
@@ -23288,6 +24263,14 @@ var KMSProvider = class {
|
|
|
23288
24263
|
this.logger.debug(`Successfully scheduled deletion for KMS Key ${logicalId}`);
|
|
23289
24264
|
} catch (error) {
|
|
23290
24265
|
if (error instanceof NotFoundException5) {
|
|
24266
|
+
const clientRegion = await this.getClient().config.region();
|
|
24267
|
+
assertRegionMatch(
|
|
24268
|
+
clientRegion,
|
|
24269
|
+
context?.expectedRegion,
|
|
24270
|
+
resourceType,
|
|
24271
|
+
logicalId,
|
|
24272
|
+
physicalId
|
|
24273
|
+
);
|
|
23291
24274
|
this.logger.debug(`KMS Key ${physicalId} does not exist, skipping deletion`);
|
|
23292
24275
|
return;
|
|
23293
24276
|
}
|
|
@@ -23374,7 +24357,7 @@ var KMSProvider = class {
|
|
|
23374
24357
|
);
|
|
23375
24358
|
}
|
|
23376
24359
|
}
|
|
23377
|
-
async deleteAlias(logicalId, physicalId, resourceType) {
|
|
24360
|
+
async deleteAlias(logicalId, physicalId, resourceType, context) {
|
|
23378
24361
|
this.logger.debug(`Deleting KMS Alias ${logicalId}: ${physicalId}`);
|
|
23379
24362
|
try {
|
|
23380
24363
|
await this.getClient().send(
|
|
@@ -23385,6 +24368,14 @@ var KMSProvider = class {
|
|
|
23385
24368
|
this.logger.debug(`Successfully deleted KMS Alias ${logicalId}`);
|
|
23386
24369
|
} catch (error) {
|
|
23387
24370
|
if (error instanceof NotFoundException5) {
|
|
24371
|
+
const clientRegion = await this.getClient().config.region();
|
|
24372
|
+
assertRegionMatch(
|
|
24373
|
+
clientRegion,
|
|
24374
|
+
context?.expectedRegion,
|
|
24375
|
+
resourceType,
|
|
24376
|
+
logicalId,
|
|
24377
|
+
physicalId
|
|
24378
|
+
);
|
|
23388
24379
|
this.logger.debug(`KMS Alias ${physicalId} does not exist, skipping deletion`);
|
|
23389
24380
|
return;
|
|
23390
24381
|
}
|
|
@@ -23631,7 +24622,7 @@ var KinesisStreamProvider = class {
|
|
|
23631
24622
|
/**
|
|
23632
24623
|
* Delete a Kinesis stream
|
|
23633
24624
|
*/
|
|
23634
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
24625
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
23635
24626
|
this.logger.debug(`Deleting Kinesis stream ${logicalId}: ${physicalId}`);
|
|
23636
24627
|
try {
|
|
23637
24628
|
await this.getClient().send(
|
|
@@ -23643,6 +24634,14 @@ var KinesisStreamProvider = class {
|
|
|
23643
24634
|
this.logger.debug(`Successfully deleted Kinesis stream ${logicalId}`);
|
|
23644
24635
|
} catch (error) {
|
|
23645
24636
|
if (error instanceof ResourceNotFoundException13) {
|
|
24637
|
+
const clientRegion = await this.getClient().config.region();
|
|
24638
|
+
assertRegionMatch(
|
|
24639
|
+
clientRegion,
|
|
24640
|
+
context?.expectedRegion,
|
|
24641
|
+
resourceType,
|
|
24642
|
+
logicalId,
|
|
24643
|
+
physicalId
|
|
24644
|
+
);
|
|
23646
24645
|
this.logger.debug(`Kinesis stream ${physicalId} does not exist, skipping deletion`);
|
|
23647
24646
|
return;
|
|
23648
24647
|
}
|
|
@@ -23759,14 +24758,14 @@ var EFSProvider = class {
|
|
|
23759
24758
|
}
|
|
23760
24759
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
23761
24760
|
}
|
|
23762
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
24761
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
23763
24762
|
switch (resourceType) {
|
|
23764
24763
|
case "AWS::EFS::FileSystem":
|
|
23765
|
-
return this.deleteFileSystem(logicalId, physicalId, resourceType);
|
|
24764
|
+
return this.deleteFileSystem(logicalId, physicalId, resourceType, context);
|
|
23766
24765
|
case "AWS::EFS::MountTarget":
|
|
23767
|
-
return this.deleteMountTarget(logicalId, physicalId, resourceType);
|
|
24766
|
+
return this.deleteMountTarget(logicalId, physicalId, resourceType, context);
|
|
23768
24767
|
case "AWS::EFS::AccessPoint":
|
|
23769
|
-
return this.deleteAccessPoint(logicalId, physicalId, resourceType);
|
|
24768
|
+
return this.deleteAccessPoint(logicalId, physicalId, resourceType, context);
|
|
23770
24769
|
default:
|
|
23771
24770
|
throw new ProvisioningError(
|
|
23772
24771
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -23815,7 +24814,7 @@ var EFSProvider = class {
|
|
|
23815
24814
|
);
|
|
23816
24815
|
}
|
|
23817
24816
|
}
|
|
23818
|
-
async deleteFileSystem(logicalId, physicalId, resourceType) {
|
|
24817
|
+
async deleteFileSystem(logicalId, physicalId, resourceType, context) {
|
|
23819
24818
|
this.logger.debug(`Deleting EFS FileSystem ${logicalId}: ${physicalId}`);
|
|
23820
24819
|
try {
|
|
23821
24820
|
await this.getClient().send(
|
|
@@ -23826,6 +24825,14 @@ var EFSProvider = class {
|
|
|
23826
24825
|
this.logger.debug(`Successfully deleted EFS FileSystem ${logicalId}`);
|
|
23827
24826
|
} catch (error) {
|
|
23828
24827
|
if (error instanceof FileSystemNotFound) {
|
|
24828
|
+
const clientRegion = await this.getClient().config.region();
|
|
24829
|
+
assertRegionMatch(
|
|
24830
|
+
clientRegion,
|
|
24831
|
+
context?.expectedRegion,
|
|
24832
|
+
resourceType,
|
|
24833
|
+
logicalId,
|
|
24834
|
+
physicalId
|
|
24835
|
+
);
|
|
23829
24836
|
this.logger.debug(`EFS FileSystem ${physicalId} does not exist, skipping deletion`);
|
|
23830
24837
|
return;
|
|
23831
24838
|
}
|
|
@@ -23941,7 +24948,7 @@ var EFSProvider = class {
|
|
|
23941
24948
|
mountTargetId
|
|
23942
24949
|
);
|
|
23943
24950
|
}
|
|
23944
|
-
async deleteMountTarget(logicalId, physicalId, resourceType) {
|
|
24951
|
+
async deleteMountTarget(logicalId, physicalId, resourceType, context) {
|
|
23945
24952
|
this.logger.debug(`Deleting EFS MountTarget ${logicalId}: ${physicalId}`);
|
|
23946
24953
|
try {
|
|
23947
24954
|
await this.getClient().send(
|
|
@@ -23953,6 +24960,14 @@ var EFSProvider = class {
|
|
|
23953
24960
|
this.logger.debug(`Successfully deleted EFS MountTarget ${logicalId}`);
|
|
23954
24961
|
} catch (error) {
|
|
23955
24962
|
if (error instanceof MountTargetNotFound) {
|
|
24963
|
+
const clientRegion = await this.getClient().config.region();
|
|
24964
|
+
assertRegionMatch(
|
|
24965
|
+
clientRegion,
|
|
24966
|
+
context?.expectedRegion,
|
|
24967
|
+
resourceType,
|
|
24968
|
+
logicalId,
|
|
24969
|
+
physicalId
|
|
24970
|
+
);
|
|
23956
24971
|
this.logger.debug(`EFS MountTarget ${physicalId} does not exist, skipping deletion`);
|
|
23957
24972
|
return;
|
|
23958
24973
|
}
|
|
@@ -24051,7 +25066,7 @@ var EFSProvider = class {
|
|
|
24051
25066
|
);
|
|
24052
25067
|
}
|
|
24053
25068
|
}
|
|
24054
|
-
async deleteAccessPoint(logicalId, physicalId, resourceType) {
|
|
25069
|
+
async deleteAccessPoint(logicalId, physicalId, resourceType, context) {
|
|
24055
25070
|
this.logger.debug(`Deleting EFS AccessPoint ${logicalId}: ${physicalId}`);
|
|
24056
25071
|
try {
|
|
24057
25072
|
await this.getClient().send(
|
|
@@ -24062,6 +25077,14 @@ var EFSProvider = class {
|
|
|
24062
25077
|
this.logger.debug(`Successfully deleted EFS AccessPoint ${logicalId}`);
|
|
24063
25078
|
} catch (error) {
|
|
24064
25079
|
if (error instanceof AccessPointNotFound) {
|
|
25080
|
+
const clientRegion = await this.getClient().config.region();
|
|
25081
|
+
assertRegionMatch(
|
|
25082
|
+
clientRegion,
|
|
25083
|
+
context?.expectedRegion,
|
|
25084
|
+
resourceType,
|
|
25085
|
+
logicalId,
|
|
25086
|
+
physicalId
|
|
25087
|
+
);
|
|
24065
25088
|
this.logger.debug(`EFS AccessPoint ${physicalId} does not exist, skipping deletion`);
|
|
24066
25089
|
return;
|
|
24067
25090
|
}
|
|
@@ -24299,7 +25322,7 @@ var FirehoseProvider = class {
|
|
|
24299
25322
|
/**
|
|
24300
25323
|
* Delete a Firehose delivery stream
|
|
24301
25324
|
*/
|
|
24302
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
25325
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
24303
25326
|
this.logger.debug(`Deleting Firehose delivery stream ${logicalId}: ${physicalId}`);
|
|
24304
25327
|
try {
|
|
24305
25328
|
await this.getClient().send(
|
|
@@ -24310,6 +25333,14 @@ var FirehoseProvider = class {
|
|
|
24310
25333
|
this.logger.debug(`Successfully deleted Firehose delivery stream ${logicalId}`);
|
|
24311
25334
|
} catch (error) {
|
|
24312
25335
|
if (error instanceof ResourceNotFoundException14) {
|
|
25336
|
+
const clientRegion = await this.getClient().config.region();
|
|
25337
|
+
assertRegionMatch(
|
|
25338
|
+
clientRegion,
|
|
25339
|
+
context?.expectedRegion,
|
|
25340
|
+
resourceType,
|
|
25341
|
+
logicalId,
|
|
25342
|
+
physicalId
|
|
25343
|
+
);
|
|
24313
25344
|
this.logger.debug(
|
|
24314
25345
|
`Firehose delivery stream ${physicalId} does not exist, skipping deletion`
|
|
24315
25346
|
);
|
|
@@ -24641,7 +25672,7 @@ var CloudTrailProvider = class {
|
|
|
24641
25672
|
);
|
|
24642
25673
|
}
|
|
24643
25674
|
}
|
|
24644
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
25675
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
24645
25676
|
this.logger.debug(`Deleting CloudTrail Trail ${logicalId}: ${physicalId}`);
|
|
24646
25677
|
try {
|
|
24647
25678
|
try {
|
|
@@ -24652,6 +25683,14 @@ var CloudTrailProvider = class {
|
|
|
24652
25683
|
this.logger.debug(`Successfully deleted CloudTrail Trail ${logicalId}`);
|
|
24653
25684
|
} catch (error) {
|
|
24654
25685
|
if (error instanceof TrailNotFoundException) {
|
|
25686
|
+
const clientRegion = await this.getClient().config.region();
|
|
25687
|
+
assertRegionMatch(
|
|
25688
|
+
clientRegion,
|
|
25689
|
+
context?.expectedRegion,
|
|
25690
|
+
resourceType,
|
|
25691
|
+
logicalId,
|
|
25692
|
+
physicalId
|
|
25693
|
+
);
|
|
24655
25694
|
this.logger.debug(`CloudTrail Trail ${physicalId} does not exist, skipping deletion`);
|
|
24656
25695
|
return;
|
|
24657
25696
|
}
|
|
@@ -24903,13 +25942,21 @@ var CodeBuildProvider = class {
|
|
|
24903
25942
|
);
|
|
24904
25943
|
}
|
|
24905
25944
|
}
|
|
24906
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
25945
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
24907
25946
|
this.logger.debug(`Deleting CodeBuild Project ${logicalId}: ${physicalId}`);
|
|
24908
25947
|
try {
|
|
24909
25948
|
await this.getClient().send(new DeleteProjectCommand({ name: physicalId }));
|
|
24910
25949
|
this.logger.debug(`Successfully deleted CodeBuild Project ${logicalId}`);
|
|
24911
25950
|
} catch (error) {
|
|
24912
25951
|
if (error instanceof ResourceNotFoundException15) {
|
|
25952
|
+
const clientRegion = await this.getClient().config.region();
|
|
25953
|
+
assertRegionMatch(
|
|
25954
|
+
clientRegion,
|
|
25955
|
+
context?.expectedRegion,
|
|
25956
|
+
resourceType,
|
|
25957
|
+
logicalId,
|
|
25958
|
+
physicalId
|
|
25959
|
+
);
|
|
24913
25960
|
this.logger.debug(`CodeBuild Project ${physicalId} does not exist, skipping deletion`);
|
|
24914
25961
|
return;
|
|
24915
25962
|
}
|
|
@@ -24975,10 +26022,10 @@ var S3VectorsProvider = class {
|
|
|
24975
26022
|
);
|
|
24976
26023
|
}
|
|
24977
26024
|
}
|
|
24978
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
26025
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
24979
26026
|
switch (resourceType) {
|
|
24980
26027
|
case "AWS::S3Vectors::VectorBucket":
|
|
24981
|
-
return this.deleteVectorBucket(logicalId, physicalId, resourceType);
|
|
26028
|
+
return this.deleteVectorBucket(logicalId, physicalId, resourceType, context);
|
|
24982
26029
|
default:
|
|
24983
26030
|
throw new ProvisioningError(
|
|
24984
26031
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -25029,7 +26076,7 @@ var S3VectorsProvider = class {
|
|
|
25029
26076
|
);
|
|
25030
26077
|
}
|
|
25031
26078
|
}
|
|
25032
|
-
async deleteVectorBucket(logicalId, physicalId, resourceType) {
|
|
26079
|
+
async deleteVectorBucket(logicalId, physicalId, resourceType, context) {
|
|
25033
26080
|
this.logger.debug(`Deleting S3 VectorBucket ${logicalId}: ${physicalId}`);
|
|
25034
26081
|
try {
|
|
25035
26082
|
await this.emptyVectorBucket(logicalId, physicalId);
|
|
@@ -25041,6 +26088,14 @@ var S3VectorsProvider = class {
|
|
|
25041
26088
|
this.logger.debug(`Successfully deleted S3 VectorBucket ${logicalId}`);
|
|
25042
26089
|
} catch (error) {
|
|
25043
26090
|
if (this.isNotFoundError(error)) {
|
|
26091
|
+
const clientRegion = await this.getClient().config.region();
|
|
26092
|
+
assertRegionMatch(
|
|
26093
|
+
clientRegion,
|
|
26094
|
+
context?.expectedRegion,
|
|
26095
|
+
resourceType,
|
|
26096
|
+
logicalId,
|
|
26097
|
+
physicalId
|
|
26098
|
+
);
|
|
25044
26099
|
this.logger.debug(`S3 VectorBucket ${physicalId} does not exist, skipping deletion`);
|
|
25045
26100
|
return;
|
|
25046
26101
|
}
|
|
@@ -25237,7 +26292,7 @@ var S3DirectoryBucketProvider = class {
|
|
|
25237
26292
|
* Must empty the bucket before deletion. Directory buckets do not support
|
|
25238
26293
|
* versioning, so only current objects need to be deleted.
|
|
25239
26294
|
*/
|
|
25240
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
26295
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
25241
26296
|
this.logger.debug(`Deleting S3 Express Directory Bucket ${logicalId}: ${physicalId}`);
|
|
25242
26297
|
try {
|
|
25243
26298
|
await this.emptyBucket(physicalId);
|
|
@@ -25249,6 +26304,14 @@ var S3DirectoryBucketProvider = class {
|
|
|
25249
26304
|
this.logger.debug(`Successfully deleted S3 Express Directory Bucket ${logicalId}`);
|
|
25250
26305
|
} catch (error) {
|
|
25251
26306
|
if (error instanceof Error && (error.name === "NoSuchBucket" || error.name === "BucketNotFound")) {
|
|
26307
|
+
const clientRegion = await this.s3Client.config.region();
|
|
26308
|
+
assertRegionMatch(
|
|
26309
|
+
clientRegion,
|
|
26310
|
+
context?.expectedRegion,
|
|
26311
|
+
resourceType,
|
|
26312
|
+
logicalId,
|
|
26313
|
+
physicalId
|
|
26314
|
+
);
|
|
25252
26315
|
this.logger.debug(`Bucket ${physicalId} does not exist, skipping deletion`);
|
|
25253
26316
|
return;
|
|
25254
26317
|
}
|
|
@@ -25343,14 +26406,14 @@ var S3TablesProvider = class {
|
|
|
25343
26406
|
this.logger.debug(`Update is no-op for ${resourceType} ${logicalId}`);
|
|
25344
26407
|
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
25345
26408
|
}
|
|
25346
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
26409
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
25347
26410
|
switch (resourceType) {
|
|
25348
26411
|
case "AWS::S3Tables::TableBucket":
|
|
25349
|
-
return this.deleteTableBucket(logicalId, physicalId, resourceType);
|
|
26412
|
+
return this.deleteTableBucket(logicalId, physicalId, resourceType, context);
|
|
25350
26413
|
case "AWS::S3Tables::Namespace":
|
|
25351
|
-
return this.deleteNamespace(logicalId, physicalId, resourceType);
|
|
26414
|
+
return this.deleteNamespace(logicalId, physicalId, resourceType, context);
|
|
25352
26415
|
case "AWS::S3Tables::Table":
|
|
25353
|
-
return this.deleteTable(logicalId, physicalId, resourceType);
|
|
26416
|
+
return this.deleteTable(logicalId, physicalId, resourceType, context);
|
|
25354
26417
|
default:
|
|
25355
26418
|
throw new ProvisioningError(
|
|
25356
26419
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -25396,7 +26459,7 @@ var S3TablesProvider = class {
|
|
|
25396
26459
|
);
|
|
25397
26460
|
}
|
|
25398
26461
|
}
|
|
25399
|
-
async deleteTableBucket(logicalId, physicalId, resourceType) {
|
|
26462
|
+
async deleteTableBucket(logicalId, physicalId, resourceType, context) {
|
|
25400
26463
|
this.logger.debug(`Deleting S3 Table Bucket ${logicalId}: ${physicalId}`);
|
|
25401
26464
|
try {
|
|
25402
26465
|
await this.emptyTableBucket(physicalId);
|
|
@@ -25408,6 +26471,14 @@ var S3TablesProvider = class {
|
|
|
25408
26471
|
this.logger.debug(`Successfully deleted S3 Table Bucket ${logicalId}`);
|
|
25409
26472
|
} catch (error) {
|
|
25410
26473
|
if (error instanceof NotFoundException6) {
|
|
26474
|
+
const clientRegion = await this.getClient().config.region();
|
|
26475
|
+
assertRegionMatch(
|
|
26476
|
+
clientRegion,
|
|
26477
|
+
context?.expectedRegion,
|
|
26478
|
+
resourceType,
|
|
26479
|
+
logicalId,
|
|
26480
|
+
physicalId
|
|
26481
|
+
);
|
|
25411
26482
|
this.logger.debug(`S3 Table Bucket ${physicalId} does not exist, skipping deletion`);
|
|
25412
26483
|
return;
|
|
25413
26484
|
}
|
|
@@ -25531,7 +26602,7 @@ var S3TablesProvider = class {
|
|
|
25531
26602
|
);
|
|
25532
26603
|
}
|
|
25533
26604
|
}
|
|
25534
|
-
async deleteNamespace(logicalId, physicalId, resourceType) {
|
|
26605
|
+
async deleteNamespace(logicalId, physicalId, resourceType, context) {
|
|
25535
26606
|
this.logger.debug(`Deleting S3 Tables Namespace ${logicalId}: ${physicalId}`);
|
|
25536
26607
|
const [tableBucketARN, namespaceName] = physicalId.split("|");
|
|
25537
26608
|
if (!tableBucketARN || !namespaceName) {
|
|
@@ -25552,6 +26623,14 @@ var S3TablesProvider = class {
|
|
|
25552
26623
|
this.logger.debug(`Successfully deleted S3 Tables Namespace ${logicalId}`);
|
|
25553
26624
|
} catch (error) {
|
|
25554
26625
|
if (error instanceof NotFoundException6) {
|
|
26626
|
+
const clientRegion = await this.getClient().config.region();
|
|
26627
|
+
assertRegionMatch(
|
|
26628
|
+
clientRegion,
|
|
26629
|
+
context?.expectedRegion,
|
|
26630
|
+
resourceType,
|
|
26631
|
+
logicalId,
|
|
26632
|
+
physicalId
|
|
26633
|
+
);
|
|
25555
26634
|
this.logger.debug(`S3 Tables Namespace ${physicalId} does not exist, skipping deletion`);
|
|
25556
26635
|
return;
|
|
25557
26636
|
}
|
|
@@ -25626,7 +26705,7 @@ var S3TablesProvider = class {
|
|
|
25626
26705
|
);
|
|
25627
26706
|
}
|
|
25628
26707
|
}
|
|
25629
|
-
async deleteTable(logicalId, physicalId, resourceType) {
|
|
26708
|
+
async deleteTable(logicalId, physicalId, resourceType, context) {
|
|
25630
26709
|
this.logger.debug(`Deleting S3 Tables Table ${logicalId}: ${physicalId}`);
|
|
25631
26710
|
const parts = physicalId.split("|");
|
|
25632
26711
|
if (parts.length < 3) {
|
|
@@ -25651,6 +26730,14 @@ var S3TablesProvider = class {
|
|
|
25651
26730
|
this.logger.debug(`Successfully deleted S3 Tables Table ${logicalId}`);
|
|
25652
26731
|
} catch (error) {
|
|
25653
26732
|
if (error instanceof NotFoundException6) {
|
|
26733
|
+
const clientRegion = await this.getClient().config.region();
|
|
26734
|
+
assertRegionMatch(
|
|
26735
|
+
clientRegion,
|
|
26736
|
+
context?.expectedRegion,
|
|
26737
|
+
resourceType,
|
|
26738
|
+
logicalId,
|
|
26739
|
+
physicalId
|
|
26740
|
+
);
|
|
25654
26741
|
this.logger.debug(`S3 Tables Table ${physicalId} does not exist, skipping deletion`);
|
|
25655
26742
|
return;
|
|
25656
26743
|
}
|
|
@@ -25877,7 +26964,7 @@ var ECRProvider = class {
|
|
|
25877
26964
|
* Uses `force: true` to delete the repository even if it contains images.
|
|
25878
26965
|
* This supports CDK's `emptyOnDelete: true` / `removalPolicy: DESTROY` pattern.
|
|
25879
26966
|
*/
|
|
25880
|
-
async delete(logicalId, physicalId, resourceType, _properties) {
|
|
26967
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
25881
26968
|
this.logger.debug(`Deleting ECR Repository ${logicalId}: ${physicalId}`);
|
|
25882
26969
|
try {
|
|
25883
26970
|
await this.getClient().send(
|
|
@@ -25889,6 +26976,14 @@ var ECRProvider = class {
|
|
|
25889
26976
|
this.logger.debug(`Successfully deleted ECR Repository ${logicalId}`);
|
|
25890
26977
|
} catch (error) {
|
|
25891
26978
|
if (error instanceof RepositoryNotFoundException) {
|
|
26979
|
+
const clientRegion = await this.getClient().config.region();
|
|
26980
|
+
assertRegionMatch(
|
|
26981
|
+
clientRegion,
|
|
26982
|
+
context?.expectedRegion,
|
|
26983
|
+
resourceType,
|
|
26984
|
+
logicalId,
|
|
26985
|
+
physicalId
|
|
26986
|
+
);
|
|
25892
26987
|
this.logger.debug(`ECR Repository ${physicalId} does not exist, skipping deletion`);
|
|
25893
26988
|
return;
|
|
25894
26989
|
}
|
|
@@ -26256,7 +27351,11 @@ var DeployEngine = class {
|
|
|
26256
27351
|
logger = getLogger().child("DeployEngine");
|
|
26257
27352
|
resolver;
|
|
26258
27353
|
interrupted = false;
|
|
26259
|
-
/**
|
|
27354
|
+
/**
|
|
27355
|
+
* Target region for this stack. Required — load-bearing for the
|
|
27356
|
+
* region-prefixed S3 state key and recorded in state.json for
|
|
27357
|
+
* cross-region destroy.
|
|
27358
|
+
*/
|
|
26260
27359
|
stackRegion;
|
|
26261
27360
|
/**
|
|
26262
27361
|
* Deploy a CloudFormation template
|
|
@@ -26265,7 +27364,7 @@ var DeployEngine = class {
|
|
|
26265
27364
|
const startTime = Date.now();
|
|
26266
27365
|
this.logger.debug(`Starting deployment for stack: ${stackName}`);
|
|
26267
27366
|
setCurrentStackName(stackName);
|
|
26268
|
-
await this.lockManager.acquireLockWithRetry(stackName, void 0, "deploy");
|
|
27367
|
+
await this.lockManager.acquireLockWithRetry(stackName, this.stackRegion, void 0, "deploy");
|
|
26269
27368
|
const renderer = getLiveRenderer();
|
|
26270
27369
|
renderer.start();
|
|
26271
27370
|
this.interrupted = false;
|
|
@@ -26279,16 +27378,17 @@ var DeployEngine = class {
|
|
|
26279
27378
|
};
|
|
26280
27379
|
process.on("SIGINT", sigintHandler);
|
|
26281
27380
|
try {
|
|
26282
|
-
const currentStateData = await this.stateBackend.getState(stackName);
|
|
27381
|
+
const currentStateData = await this.stateBackend.getState(stackName, this.stackRegion);
|
|
26283
27382
|
const currentState = currentStateData?.state ?? {
|
|
26284
|
-
version:
|
|
26285
|
-
|
|
27383
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
27384
|
+
region: this.stackRegion,
|
|
26286
27385
|
stackName,
|
|
26287
27386
|
resources: {},
|
|
26288
27387
|
outputs: {},
|
|
26289
27388
|
lastModified: Date.now()
|
|
26290
27389
|
};
|
|
26291
27390
|
const currentEtag = currentStateData?.etag;
|
|
27391
|
+
const migrationPending = currentStateData?.migrationPending ?? false;
|
|
26292
27392
|
this.logger.debug(
|
|
26293
27393
|
`Loaded current state: ${Object.keys(currentState.resources).length} resources`
|
|
26294
27394
|
);
|
|
@@ -26374,9 +27474,10 @@ var DeployEngine = class {
|
|
|
26374
27474
|
parameterValues,
|
|
26375
27475
|
conditions,
|
|
26376
27476
|
currentEtag,
|
|
26377
|
-
progress
|
|
27477
|
+
progress,
|
|
27478
|
+
migrationPending
|
|
26378
27479
|
);
|
|
26379
|
-
const newEtag = await this.stateBackend.saveState(stackName, newState);
|
|
27480
|
+
const newEtag = await this.stateBackend.saveState(stackName, this.stackRegion, newState);
|
|
26380
27481
|
this.logger.debug(`State saved (ETag: ${newEtag})`);
|
|
26381
27482
|
const durationMs = Date.now() - startTime;
|
|
26382
27483
|
const unchangedCount = this.diffCalculator.filterByType(changes, "NO_CHANGE").length + actualCounts.skipped;
|
|
@@ -26392,7 +27493,7 @@ var DeployEngine = class {
|
|
|
26392
27493
|
renderer.stop();
|
|
26393
27494
|
process.removeListener("SIGINT", sigintHandler);
|
|
26394
27495
|
try {
|
|
26395
|
-
await this.lockManager.releaseLock(stackName);
|
|
27496
|
+
await this.lockManager.releaseLock(stackName, this.stackRegion);
|
|
26396
27497
|
this.logger.debug("Lock released");
|
|
26397
27498
|
} catch (lockError) {
|
|
26398
27499
|
this.logger.warn(
|
|
@@ -26410,11 +27511,12 @@ var DeployEngine = class {
|
|
|
26410
27511
|
* - DELETE follows reverse dependency order (a node starts as soon as all
|
|
26411
27512
|
* resources that depend ON it have finished deleting)
|
|
26412
27513
|
*/
|
|
26413
|
-
async executeDeployment(template, currentState, changes, dag, executionLevels, stackName, parameterValues, conditions, currentEtag, progress) {
|
|
27514
|
+
async executeDeployment(template, currentState, changes, dag, executionLevels, stackName, parameterValues, conditions, currentEtag, progress, migrationPending = false) {
|
|
26414
27515
|
const concurrency = this.options.concurrency;
|
|
26415
27516
|
const newResources = { ...currentState.resources };
|
|
26416
27517
|
const actualCounts = { created: 0, updated: 0, deleted: 0, skipped: 0 };
|
|
26417
27518
|
const completedOperations = [];
|
|
27519
|
+
let pendingMigration = migrationPending;
|
|
26418
27520
|
let saveChain = Promise.resolve();
|
|
26419
27521
|
const saveStateAfterResource = (logicalId) => {
|
|
26420
27522
|
if (currentEtag === void 0)
|
|
@@ -26422,14 +27524,23 @@ var DeployEngine = class {
|
|
|
26422
27524
|
saveChain = saveChain.then(async () => {
|
|
26423
27525
|
try {
|
|
26424
27526
|
const partialState = {
|
|
26425
|
-
version:
|
|
26426
|
-
|
|
27527
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
27528
|
+
region: this.stackRegion,
|
|
26427
27529
|
stackName: currentState.stackName,
|
|
26428
27530
|
resources: newResources,
|
|
26429
27531
|
outputs: currentState.outputs,
|
|
26430
27532
|
lastModified: Date.now()
|
|
26431
27533
|
};
|
|
26432
|
-
|
|
27534
|
+
const migrate = pendingMigration;
|
|
27535
|
+
const expectedEtag = migrate ? void 0 : currentEtag;
|
|
27536
|
+
currentEtag = await this.stateBackend.saveState(
|
|
27537
|
+
stackName,
|
|
27538
|
+
this.stackRegion,
|
|
27539
|
+
partialState,
|
|
27540
|
+
{ ...expectedEtag !== void 0 && { expectedEtag }, migrateLegacy: migrate }
|
|
27541
|
+
);
|
|
27542
|
+
if (migrate)
|
|
27543
|
+
pendingMigration = false;
|
|
26433
27544
|
this.logger.debug(`State saved after ${logicalId}`);
|
|
26434
27545
|
} catch (error) {
|
|
26435
27546
|
this.logger.warn(
|
|
@@ -26563,14 +27674,23 @@ var DeployEngine = class {
|
|
|
26563
27674
|
} catch (error) {
|
|
26564
27675
|
try {
|
|
26565
27676
|
const preRollbackState = {
|
|
26566
|
-
version:
|
|
26567
|
-
|
|
27677
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
27678
|
+
region: this.stackRegion,
|
|
26568
27679
|
stackName: currentState.stackName,
|
|
26569
27680
|
resources: newResources,
|
|
26570
27681
|
outputs: currentState.outputs,
|
|
26571
27682
|
lastModified: Date.now()
|
|
26572
27683
|
};
|
|
26573
|
-
|
|
27684
|
+
const migrate = pendingMigration;
|
|
27685
|
+
const expectedEtag = migrate ? void 0 : currentEtag;
|
|
27686
|
+
currentEtag = await this.stateBackend.saveState(
|
|
27687
|
+
stackName,
|
|
27688
|
+
this.stackRegion,
|
|
27689
|
+
preRollbackState,
|
|
27690
|
+
{ ...expectedEtag !== void 0 && { expectedEtag }, migrateLegacy: migrate }
|
|
27691
|
+
);
|
|
27692
|
+
if (migrate)
|
|
27693
|
+
pendingMigration = false;
|
|
26574
27694
|
this.logger.debug("Partial state saved before rollback (orphaned resource tracking)");
|
|
26575
27695
|
} catch (saveError) {
|
|
26576
27696
|
this.logger.warn(
|
|
@@ -26591,31 +27711,35 @@ var DeployEngine = class {
|
|
|
26591
27711
|
}
|
|
26592
27712
|
try {
|
|
26593
27713
|
const postRollbackState = {
|
|
26594
|
-
version:
|
|
26595
|
-
|
|
27714
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
27715
|
+
region: this.stackRegion,
|
|
26596
27716
|
stackName: currentState.stackName,
|
|
26597
27717
|
resources: newResources,
|
|
26598
27718
|
outputs: currentState.outputs,
|
|
26599
27719
|
lastModified: Date.now()
|
|
26600
27720
|
};
|
|
26601
|
-
await this.stateBackend.saveState(stackName, postRollbackState,
|
|
27721
|
+
await this.stateBackend.saveState(stackName, this.stackRegion, postRollbackState, {
|
|
27722
|
+
...currentEtag !== void 0 && { expectedEtag: currentEtag }
|
|
27723
|
+
});
|
|
26602
27724
|
this.logger.debug("State saved after deployment failure");
|
|
26603
27725
|
} catch (saveError) {
|
|
26604
27726
|
this.logger.debug(
|
|
26605
27727
|
`Retrying state save after rollback (ETag mismatch): ${saveError instanceof Error ? saveError.message : String(saveError)}`
|
|
26606
27728
|
);
|
|
26607
27729
|
try {
|
|
26608
|
-
const freshState = await this.stateBackend.getState(stackName);
|
|
27730
|
+
const freshState = await this.stateBackend.getState(stackName, this.stackRegion);
|
|
26609
27731
|
const freshEtag = freshState?.etag;
|
|
26610
27732
|
const postRollbackState = {
|
|
26611
|
-
version:
|
|
26612
|
-
|
|
27733
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
27734
|
+
region: this.stackRegion,
|
|
26613
27735
|
stackName: currentState.stackName,
|
|
26614
27736
|
resources: newResources,
|
|
26615
27737
|
outputs: currentState.outputs,
|
|
26616
27738
|
lastModified: Date.now()
|
|
26617
27739
|
};
|
|
26618
|
-
await this.stateBackend.saveState(stackName, postRollbackState,
|
|
27740
|
+
await this.stateBackend.saveState(stackName, this.stackRegion, postRollbackState, {
|
|
27741
|
+
...freshEtag !== void 0 && { expectedEtag: freshEtag }
|
|
27742
|
+
});
|
|
26619
27743
|
this.logger.debug("State saved after deployment failure (retry succeeded)");
|
|
26620
27744
|
} catch (retryError) {
|
|
26621
27745
|
this.logger.warn(
|
|
@@ -26634,8 +27758,8 @@ var DeployEngine = class {
|
|
|
26634
27758
|
);
|
|
26635
27759
|
return {
|
|
26636
27760
|
state: {
|
|
26637
|
-
version:
|
|
26638
|
-
|
|
27761
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
27762
|
+
region: this.stackRegion,
|
|
26639
27763
|
stackName: currentState.stackName,
|
|
26640
27764
|
resources: newResources,
|
|
26641
27765
|
outputs,
|
|
@@ -26764,7 +27888,9 @@ var DeployEngine = class {
|
|
|
26764
27888
|
` Rollback: Deleting created resource ${op.logicalId} (${op.resourceType})`
|
|
26765
27889
|
);
|
|
26766
27890
|
const provider = this.providerRegistry.getProvider(op.resourceType);
|
|
26767
|
-
await provider.delete(op.logicalId, op.physicalId, op.resourceType, op.properties
|
|
27891
|
+
await provider.delete(op.logicalId, op.physicalId, op.resourceType, op.properties, {
|
|
27892
|
+
expectedRegion: this.stackRegion
|
|
27893
|
+
});
|
|
26768
27894
|
delete stateResources[op.logicalId];
|
|
26769
27895
|
this.logger.info(` Rollback: ${op.logicalId} deleted successfully`);
|
|
26770
27896
|
break;
|
|
@@ -26906,7 +28032,8 @@ var DeployEngine = class {
|
|
|
26906
28032
|
logicalId,
|
|
26907
28033
|
currentResource.physicalId,
|
|
26908
28034
|
resourceType,
|
|
26909
|
-
currentResource.properties
|
|
28035
|
+
currentResource.properties,
|
|
28036
|
+
{ expectedRegion: this.stackRegion }
|
|
26910
28037
|
);
|
|
26911
28038
|
this.logger.info(` \u2713 Old resource deleted`);
|
|
26912
28039
|
} catch (deleteError) {
|
|
@@ -26955,7 +28082,8 @@ var DeployEngine = class {
|
|
|
26955
28082
|
logicalId,
|
|
26956
28083
|
currentResource.physicalId,
|
|
26957
28084
|
resourceType,
|
|
26958
|
-
currentProps
|
|
28085
|
+
currentProps,
|
|
28086
|
+
{ expectedRegion: this.stackRegion }
|
|
26959
28087
|
);
|
|
26960
28088
|
} catch (deleteError) {
|
|
26961
28089
|
const deleteMsg = deleteError instanceof Error ? deleteError.message : String(deleteError);
|
|
@@ -27026,7 +28154,8 @@ var DeployEngine = class {
|
|
|
27026
28154
|
logicalId,
|
|
27027
28155
|
currentResource.physicalId,
|
|
27028
28156
|
resourceType,
|
|
27029
|
-
currentResource.properties
|
|
28157
|
+
currentResource.properties,
|
|
28158
|
+
{ expectedRegion: this.stackRegion }
|
|
27030
28159
|
),
|
|
27031
28160
|
logicalId,
|
|
27032
28161
|
3,
|
|
@@ -27642,19 +28771,18 @@ async function diffCommand(stacks, options) {
|
|
|
27642
28771
|
logger.info(`
|
|
27643
28772
|
Calculating diff for stack: ${stackInfo.stackName}`);
|
|
27644
28773
|
const template = stackInfo.template;
|
|
27645
|
-
|
|
27646
|
-
const stateResult = await stateBackend.getState(stackInfo.stackName);
|
|
27647
|
-
|
|
27648
|
-
|
|
27649
|
-
|
|
27650
|
-
|
|
27651
|
-
|
|
27652
|
-
|
|
27653
|
-
|
|
27654
|
-
|
|
27655
|
-
|
|
27656
|
-
|
|
27657
|
-
};
|
|
28774
|
+
const stackRegion = stackInfo.region || region;
|
|
28775
|
+
const stateResult = await stateBackend.getState(stackInfo.stackName, stackRegion);
|
|
28776
|
+
const currentState = stateResult ? stateResult.state : {
|
|
28777
|
+
stackName: stackInfo.stackName,
|
|
28778
|
+
region: stackRegion,
|
|
28779
|
+
resources: {},
|
|
28780
|
+
outputs: {},
|
|
28781
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
28782
|
+
lastModified: Date.now()
|
|
28783
|
+
};
|
|
28784
|
+
if (!stateResult) {
|
|
28785
|
+
logger.debug(`No existing state for ${stackInfo.stackName} (${stackRegion})`);
|
|
27658
28786
|
}
|
|
27659
28787
|
const diffResolveFn = (value) => intrinsicResolver.resolve(value, {
|
|
27660
28788
|
template,
|
|
@@ -27776,19 +28904,27 @@ async function destroyCommand(stackArgs, options) {
|
|
|
27776
28904
|
});
|
|
27777
28905
|
appStacks = result.stacks.map((s) => ({
|
|
27778
28906
|
stackName: s.stackName,
|
|
27779
|
-
displayName: s.displayName
|
|
28907
|
+
displayName: s.displayName,
|
|
28908
|
+
...s.region && { region: s.region }
|
|
27780
28909
|
}));
|
|
27781
28910
|
} catch {
|
|
27782
28911
|
logger.debug("Could not synthesize app, falling back to state-based stack list");
|
|
27783
28912
|
}
|
|
27784
28913
|
}
|
|
27785
|
-
const
|
|
28914
|
+
const allStateRefs = await stateBackend.listStacks();
|
|
27786
28915
|
let candidateStacks;
|
|
27787
28916
|
if (appStacks.length > 0) {
|
|
27788
|
-
const
|
|
27789
|
-
candidateStacks = appStacks.filter((s) =>
|
|
28917
|
+
const stateNames = new Set(allStateRefs.map((r) => r.stackName));
|
|
28918
|
+
candidateStacks = appStacks.filter((s) => stateNames.has(s.stackName));
|
|
27790
28919
|
} else if (stackArgs.length > 0 || options.stack || options.all) {
|
|
27791
|
-
|
|
28920
|
+
const seen = /* @__PURE__ */ new Set();
|
|
28921
|
+
candidateStacks = [];
|
|
28922
|
+
for (const ref of allStateRefs) {
|
|
28923
|
+
if (seen.has(ref.stackName))
|
|
28924
|
+
continue;
|
|
28925
|
+
seen.add(ref.stackName);
|
|
28926
|
+
candidateStacks.push({ stackName: ref.stackName });
|
|
28927
|
+
}
|
|
27792
28928
|
} else {
|
|
27793
28929
|
throw new Error(
|
|
27794
28930
|
"Could not determine which stacks belong to this app. Specify stack names explicitly, use --all, or ensure --app / cdk.json is configured."
|
|
@@ -27815,10 +28951,38 @@ async function destroyCommand(stackArgs, options) {
|
|
|
27815
28951
|
return;
|
|
27816
28952
|
}
|
|
27817
28953
|
logger.info(`Found ${stackNames.length} stack(s) to destroy: ${stackNames.join(", ")}`);
|
|
28954
|
+
const stateRefsByName = /* @__PURE__ */ new Map();
|
|
28955
|
+
for (const ref of allStateRefs) {
|
|
28956
|
+
const arr = stateRefsByName.get(ref.stackName) ?? [];
|
|
28957
|
+
arr.push(ref);
|
|
28958
|
+
stateRefsByName.set(ref.stackName, arr);
|
|
28959
|
+
}
|
|
27818
28960
|
for (const stackName of stackNames) {
|
|
27819
28961
|
logger.info(`
|
|
27820
28962
|
Preparing to destroy stack: ${stackName}`);
|
|
27821
|
-
const
|
|
28963
|
+
const refs = stateRefsByName.get(stackName) ?? [];
|
|
28964
|
+
const synthStack = appStacks.find((s) => s.stackName === stackName);
|
|
28965
|
+
const synthRegion = synthStack?.region;
|
|
28966
|
+
let stackTargetRegion;
|
|
28967
|
+
if (refs.length === 0) {
|
|
28968
|
+
logger.warn(`No state found for stack ${stackName}, skipping`);
|
|
28969
|
+
continue;
|
|
28970
|
+
} else if (refs.length === 1) {
|
|
28971
|
+
const onlyRegion = refs[0]?.region;
|
|
28972
|
+
if (!onlyRegion) {
|
|
28973
|
+
stackTargetRegion = region;
|
|
28974
|
+
} else {
|
|
28975
|
+
stackTargetRegion = onlyRegion;
|
|
28976
|
+
}
|
|
28977
|
+
} else if (synthRegion && refs.some((r) => r.region === synthRegion)) {
|
|
28978
|
+
stackTargetRegion = synthRegion;
|
|
28979
|
+
} else {
|
|
28980
|
+
const regions = refs.map((r) => r.region ?? "(legacy)").join(", ");
|
|
28981
|
+
throw new Error(
|
|
28982
|
+
`Stack '${stackName}' has state in multiple regions: ${regions}. Use 'cdkd state rm ${stackName} --region <region>' to remove cdkd's record for one region, or run destroy from a CDK app whose env.region matches one of them.`
|
|
28983
|
+
);
|
|
28984
|
+
}
|
|
28985
|
+
const stateResult = await stateBackend.getState(stackName, stackTargetRegion);
|
|
27822
28986
|
if (!stateResult) {
|
|
27823
28987
|
logger.warn(`No state found for stack ${stackName}, skipping`);
|
|
27824
28988
|
continue;
|
|
@@ -27827,7 +28991,7 @@ Preparing to destroy stack: ${stackName}`);
|
|
|
27827
28991
|
const resourceCount = Object.keys(currentState.resources).length;
|
|
27828
28992
|
if (resourceCount === 0) {
|
|
27829
28993
|
logger.info(`Stack ${stackName} has no resources, cleaning up state...`);
|
|
27830
|
-
await stateBackend.deleteState(stackName);
|
|
28994
|
+
await stateBackend.deleteState(stackName, stackTargetRegion);
|
|
27831
28995
|
logger.info("\u2713 State deleted");
|
|
27832
28996
|
continue;
|
|
27833
28997
|
}
|
|
@@ -27852,7 +29016,7 @@ Are you sure you want to destroy stack "${stackName}" and delete all ${resourceC
|
|
|
27852
29016
|
continue;
|
|
27853
29017
|
}
|
|
27854
29018
|
}
|
|
27855
|
-
const stackRegion =
|
|
29019
|
+
const stackRegion = stackTargetRegion;
|
|
27856
29020
|
let destroyProviderRegistry = providerRegistry;
|
|
27857
29021
|
let destroyAwsClients;
|
|
27858
29022
|
if (stackRegion && stackRegion !== region) {
|
|
@@ -27870,7 +29034,7 @@ Are you sure you want to destroy stack "${stackName}" and delete all ${resourceC
|
|
|
27870
29034
|
}
|
|
27871
29035
|
logger.info(`
|
|
27872
29036
|
Acquiring lock for stack ${stackName}...`);
|
|
27873
|
-
await lockManager.acquireLock(stackName, "destroy");
|
|
29037
|
+
await lockManager.acquireLock(stackName, stackRegion, void 0, "destroy");
|
|
27874
29038
|
const renderer = getLiveRenderer();
|
|
27875
29039
|
renderer.start();
|
|
27876
29040
|
try {
|
|
@@ -27946,7 +29110,8 @@ Acquiring lock for stack ${stackName}...`);
|
|
|
27946
29110
|
logicalId,
|
|
27947
29111
|
resource.physicalId,
|
|
27948
29112
|
resource.resourceType,
|
|
27949
|
-
resource.properties
|
|
29113
|
+
resource.properties,
|
|
29114
|
+
{ expectedRegion: currentState.region }
|
|
27950
29115
|
);
|
|
27951
29116
|
lastDeleteError = null;
|
|
27952
29117
|
break;
|
|
@@ -27985,7 +29150,7 @@ Acquiring lock for stack ${stackName}...`);
|
|
|
27985
29150
|
await Promise.all(deletePromises);
|
|
27986
29151
|
}
|
|
27987
29152
|
if (errorCount === 0) {
|
|
27988
|
-
await stateBackend.deleteState(stackName);
|
|
29153
|
+
await stateBackend.deleteState(stackName, stackRegion);
|
|
27989
29154
|
logger.debug("State deleted");
|
|
27990
29155
|
} else {
|
|
27991
29156
|
logger.warn(`${errorCount} resource(s) failed to delete. State preserved.`);
|
|
@@ -27997,7 +29162,7 @@ Acquiring lock for stack ${stackName}...`);
|
|
|
27997
29162
|
} finally {
|
|
27998
29163
|
renderer.stop();
|
|
27999
29164
|
logger.debug("Releasing lock...");
|
|
28000
|
-
await lockManager.releaseLock(stackName);
|
|
29165
|
+
await lockManager.releaseLock(stackName, stackRegion);
|
|
28001
29166
|
if (destroyAwsClients) {
|
|
28002
29167
|
destroyAwsClients.destroy();
|
|
28003
29168
|
process.env["AWS_REGION"] = region;
|
|
@@ -28058,7 +29223,7 @@ function createPublishAssetsCommand() {
|
|
|
28058
29223
|
}
|
|
28059
29224
|
|
|
28060
29225
|
// src/cli/commands/force-unlock.ts
|
|
28061
|
-
import { Command as Command8 } from "commander";
|
|
29226
|
+
import { Command as Command8, Option as Option3 } from "commander";
|
|
28062
29227
|
init_aws_clients();
|
|
28063
29228
|
async function forceUnlockCommand(stackArgs, options) {
|
|
28064
29229
|
const logger = getLogger();
|
|
@@ -28082,17 +29247,33 @@ async function forceUnlockCommand(stackArgs, options) {
|
|
|
28082
29247
|
prefix: options.statePrefix
|
|
28083
29248
|
};
|
|
28084
29249
|
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
29250
|
+
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig);
|
|
28085
29251
|
for (const stackName of stackPatterns) {
|
|
28086
|
-
|
|
28087
|
-
|
|
28088
|
-
|
|
28089
|
-
|
|
28090
|
-
|
|
28091
|
-
const
|
|
28092
|
-
if (
|
|
28093
|
-
|
|
29252
|
+
let regionsToTry;
|
|
29253
|
+
if (options.stackRegion) {
|
|
29254
|
+
regionsToTry = [options.stackRegion];
|
|
29255
|
+
} else {
|
|
29256
|
+
const refs = await stateBackend.listStacks();
|
|
29257
|
+
const matched = refs.filter((r) => r.stackName === stackName);
|
|
29258
|
+
if (matched.length === 0) {
|
|
29259
|
+
regionsToTry = [region];
|
|
28094
29260
|
} else {
|
|
28095
|
-
|
|
29261
|
+
regionsToTry = matched.map((r) => r.region);
|
|
29262
|
+
}
|
|
29263
|
+
}
|
|
29264
|
+
for (const r of regionsToTry) {
|
|
29265
|
+
const where = r ? `${stackName} (${r})` : `${stackName} (legacy lock key)`;
|
|
29266
|
+
logger.info(`Force-unlocking stack: ${where}`);
|
|
29267
|
+
try {
|
|
29268
|
+
await lockManager.forceReleaseLock(stackName, r);
|
|
29269
|
+
logger.info(`\u2713 Lock released for stack: ${where}`);
|
|
29270
|
+
} catch (error) {
|
|
29271
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
29272
|
+
if (message.includes("No lock found") || message.includes("NoSuchKey")) {
|
|
29273
|
+
logger.info(`No lock found for stack: ${where}`);
|
|
29274
|
+
} else {
|
|
29275
|
+
logger.error(`Failed to unlock stack ${where}: ${message}`);
|
|
29276
|
+
}
|
|
28096
29277
|
}
|
|
28097
29278
|
}
|
|
28098
29279
|
}
|
|
@@ -28101,15 +29282,47 @@ async function forceUnlockCommand(stackArgs, options) {
|
|
|
28101
29282
|
}
|
|
28102
29283
|
}
|
|
28103
29284
|
function createForceUnlockCommand() {
|
|
28104
|
-
const cmd = new Command8("force-unlock").description("Force-release a stale lock on a stack").argument("[stacks...]", "Stack name(s) to unlock").
|
|
29285
|
+
const cmd = new Command8("force-unlock").description("Force-release a stale lock on a stack").argument("[stacks...]", "Stack name(s) to unlock").addOption(
|
|
29286
|
+
new Option3(
|
|
29287
|
+
"--stack-region <region>",
|
|
29288
|
+
"Stack region whose lock to release (use when the same stack name has locks in multiple regions). Defaults to all regions where the stack has state."
|
|
29289
|
+
)
|
|
29290
|
+
).action(withErrorHandling(forceUnlockCommand));
|
|
28105
29291
|
[...commonOptions, ...stateOptions, ...stackOptions].forEach((opt) => cmd.addOption(opt));
|
|
28106
29292
|
return cmd;
|
|
28107
29293
|
}
|
|
28108
29294
|
|
|
28109
29295
|
// src/cli/commands/state.ts
|
|
28110
29296
|
import * as readline2 from "node:readline/promises";
|
|
28111
|
-
import { Command as Command9 } from "commander";
|
|
29297
|
+
import { Command as Command9, Option as Option4 } from "commander";
|
|
28112
29298
|
init_aws_clients();
|
|
29299
|
+
function formatStackRef(ref) {
|
|
29300
|
+
return ref.region ? `${ref.stackName} (${ref.region})` : ref.stackName;
|
|
29301
|
+
}
|
|
29302
|
+
function resolveSingleRegion(stackName, refs, requestedRegion) {
|
|
29303
|
+
const matches = refs.filter((r) => r.stackName === stackName);
|
|
29304
|
+
if (matches.length === 0) {
|
|
29305
|
+
throw new Error(
|
|
29306
|
+
`No state found for stack '${stackName}'. Run 'cdkd state list' to see available stacks.`
|
|
29307
|
+
);
|
|
29308
|
+
}
|
|
29309
|
+
if (requestedRegion) {
|
|
29310
|
+
const ref = matches.find((r) => r.region === requestedRegion);
|
|
29311
|
+
if (!ref) {
|
|
29312
|
+
const seen = matches.map((r) => r.region ?? "(legacy)").join(", ");
|
|
29313
|
+
throw new Error(
|
|
29314
|
+
`No state found for stack '${stackName}' in region '${requestedRegion}'. Available regions: ${seen}.`
|
|
29315
|
+
);
|
|
29316
|
+
}
|
|
29317
|
+
return ref;
|
|
29318
|
+
}
|
|
29319
|
+
if (matches.length === 1)
|
|
29320
|
+
return matches[0];
|
|
29321
|
+
const regions = matches.map((r) => r.region ?? "(legacy)").join(", ");
|
|
29322
|
+
throw new Error(
|
|
29323
|
+
`Stack '${stackName}' has state in multiple regions: ${regions}. Re-run with --region <region> to disambiguate.`
|
|
29324
|
+
);
|
|
29325
|
+
}
|
|
28113
29326
|
async function setupStateBackend(options) {
|
|
28114
29327
|
const awsClients = new AwsClients({
|
|
28115
29328
|
...options.region && { region: options.region },
|
|
@@ -28131,34 +29344,52 @@ async function setupStateBackend(options) {
|
|
|
28131
29344
|
dispose: () => awsClients.destroy()
|
|
28132
29345
|
};
|
|
28133
29346
|
}
|
|
29347
|
+
function sortRefs(refs) {
|
|
29348
|
+
return refs.slice().sort((a, b) => {
|
|
29349
|
+
if (a.stackName < b.stackName)
|
|
29350
|
+
return -1;
|
|
29351
|
+
if (a.stackName > b.stackName)
|
|
29352
|
+
return 1;
|
|
29353
|
+
const ar = a.region ?? "\uFFFF";
|
|
29354
|
+
const br = b.region ?? "\uFFFF";
|
|
29355
|
+
if (ar < br)
|
|
29356
|
+
return -1;
|
|
29357
|
+
if (ar > br)
|
|
29358
|
+
return 1;
|
|
29359
|
+
return 0;
|
|
29360
|
+
});
|
|
29361
|
+
}
|
|
28134
29362
|
async function stateListCommand(options) {
|
|
28135
29363
|
const logger = getLogger();
|
|
28136
29364
|
if (options.verbose)
|
|
28137
29365
|
logger.setLevel("debug");
|
|
28138
29366
|
const setup = await setupStateBackend(options);
|
|
28139
29367
|
try {
|
|
28140
|
-
const
|
|
29368
|
+
const refs = sortRefs(await setup.stateBackend.listStacks());
|
|
28141
29369
|
if (!options.long && !options.json) {
|
|
28142
|
-
for (const
|
|
28143
|
-
process.stdout.write(`${
|
|
29370
|
+
for (const ref of refs) {
|
|
29371
|
+
process.stdout.write(`${formatStackRef(ref)}
|
|
28144
29372
|
`);
|
|
28145
29373
|
}
|
|
28146
29374
|
return;
|
|
28147
29375
|
}
|
|
28148
29376
|
if (options.json && !options.long) {
|
|
28149
|
-
|
|
29377
|
+
const payload = refs.map((r) => ({ stackName: r.stackName, region: r.region ?? null }));
|
|
29378
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}
|
|
28150
29379
|
`);
|
|
28151
29380
|
return;
|
|
28152
29381
|
}
|
|
28153
29382
|
const details = await Promise.all(
|
|
28154
|
-
|
|
29383
|
+
refs.map(async (ref) => {
|
|
29384
|
+
const lookupRegion = ref.region ?? "";
|
|
28155
29385
|
const [stateResult, locked] = await Promise.all([
|
|
28156
|
-
setup.stateBackend.getState(stackName),
|
|
28157
|
-
setup.lockManager.isLocked(stackName)
|
|
29386
|
+
lookupRegion ? setup.stateBackend.getState(ref.stackName, lookupRegion) : Promise.resolve(null),
|
|
29387
|
+
setup.lockManager.isLocked(ref.stackName, ref.region)
|
|
28158
29388
|
]);
|
|
28159
29389
|
const state = stateResult?.state;
|
|
28160
29390
|
return {
|
|
28161
|
-
stackName,
|
|
29391
|
+
stackName: ref.stackName,
|
|
29392
|
+
region: ref.region ?? null,
|
|
28162
29393
|
resourceCount: state ? Object.keys(state.resources).length : 0,
|
|
28163
29394
|
lastModified: state && typeof state.lastModified === "number" ? new Date(state.lastModified).toISOString() : null,
|
|
28164
29395
|
locked
|
|
@@ -28172,7 +29403,13 @@ async function stateListCommand(options) {
|
|
|
28172
29403
|
}
|
|
28173
29404
|
const lines = [];
|
|
28174
29405
|
for (const detail of details) {
|
|
28175
|
-
lines.push(
|
|
29406
|
+
lines.push(
|
|
29407
|
+
formatStackRef({
|
|
29408
|
+
stackName: detail.stackName,
|
|
29409
|
+
...detail.region ? { region: detail.region } : {}
|
|
29410
|
+
})
|
|
29411
|
+
);
|
|
29412
|
+
lines.push(` Region: ${detail.region ?? "(legacy)"}`);
|
|
28176
29413
|
lines.push(` Resources: ${detail.resourceCount}`);
|
|
28177
29414
|
lines.push(` Last Modified: ${detail.lastModified ?? "unknown"}`);
|
|
28178
29415
|
lines.push(` Lock: ${detail.locked ? "locked" : "unlocked"}`);
|
|
@@ -28200,10 +29437,17 @@ async function stateResourcesCommand(stackName, options) {
|
|
|
28200
29437
|
logger.setLevel("debug");
|
|
28201
29438
|
const setup = await setupStateBackend(options);
|
|
28202
29439
|
try {
|
|
28203
|
-
const
|
|
29440
|
+
const refs = await setup.stateBackend.listStacks();
|
|
29441
|
+
const ref = resolveSingleRegion(stackName, refs, options.stackRegion);
|
|
29442
|
+
if (!ref.region) {
|
|
29443
|
+
throw new Error(
|
|
29444
|
+
`Stack '${stackName}' has only a legacy state record without a region. Run 'cdkd deploy ${stackName}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`
|
|
29445
|
+
);
|
|
29446
|
+
}
|
|
29447
|
+
const stateResult = await setup.stateBackend.getState(stackName, ref.region);
|
|
28204
29448
|
if (!stateResult) {
|
|
28205
29449
|
throw new Error(
|
|
28206
|
-
`No state found for stack '${stackName}' in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`
|
|
29450
|
+
`No state found for stack '${stackName}' (${ref.region}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`
|
|
28207
29451
|
);
|
|
28208
29452
|
}
|
|
28209
29453
|
const resources = stateResult.state.resources ?? {};
|
|
@@ -28286,7 +29530,7 @@ function formatLockSummary(lockInfo) {
|
|
|
28286
29530
|
return `locked by ${lockInfo.owner}${opStr}, ${expiresStr}`;
|
|
28287
29531
|
}
|
|
28288
29532
|
function createStateResourcesCommand() {
|
|
28289
|
-
const cmd = new Command9("resources").description("List resources recorded in a stack's state").argument("<stack>", "Stack name (physical CloudFormation name)").option("-l, --long", "Include dependencies and attributes per resource", false).option("--json", "Output as JSON", false).action(withErrorHandling(stateResourcesCommand));
|
|
29533
|
+
const cmd = new Command9("resources").description("List resources recorded in a stack's state").argument("<stack>", "Stack name (physical CloudFormation name)").option("-l, --long", "Include dependencies and attributes per resource", false).option("--json", "Output as JSON", false).addOption(stackRegionOption()).action(withErrorHandling(stateResourcesCommand));
|
|
28290
29534
|
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
28291
29535
|
return cmd;
|
|
28292
29536
|
}
|
|
@@ -28296,13 +29540,20 @@ async function stateShowCommand(stackName, options) {
|
|
|
28296
29540
|
logger.setLevel("debug");
|
|
28297
29541
|
const setup = await setupStateBackend(options);
|
|
28298
29542
|
try {
|
|
29543
|
+
const refs = await setup.stateBackend.listStacks();
|
|
29544
|
+
const ref = resolveSingleRegion(stackName, refs, options.stackRegion);
|
|
29545
|
+
if (!ref.region) {
|
|
29546
|
+
throw new Error(
|
|
29547
|
+
`Stack '${stackName}' has only a legacy state record without a region. Run 'cdkd deploy ${stackName}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`
|
|
29548
|
+
);
|
|
29549
|
+
}
|
|
28299
29550
|
const [stateResult, lockInfo] = await Promise.all([
|
|
28300
|
-
setup.stateBackend.getState(stackName),
|
|
28301
|
-
setup.lockManager.getLockInfo(stackName)
|
|
29551
|
+
setup.stateBackend.getState(stackName, ref.region),
|
|
29552
|
+
setup.lockManager.getLockInfo(stackName, ref.region)
|
|
28302
29553
|
]);
|
|
28303
29554
|
if (!stateResult) {
|
|
28304
29555
|
throw new Error(
|
|
28305
|
-
`No state found for stack '${stackName}' in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`
|
|
29556
|
+
`No state found for stack '${stackName}' (${ref.region}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`
|
|
28306
29557
|
);
|
|
28307
29558
|
}
|
|
28308
29559
|
if (options.json) {
|
|
@@ -28366,7 +29617,7 @@ async function stateShowCommand(stackName, options) {
|
|
|
28366
29617
|
}
|
|
28367
29618
|
}
|
|
28368
29619
|
function createStateShowCommand() {
|
|
28369
|
-
const cmd = new Command9("show").description("Show the full cdkd state record for a stack (metadata, outputs, resources)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--json", "Output the raw state and lock as JSON", false).action(withErrorHandling(stateShowCommand));
|
|
29620
|
+
const cmd = new Command9("show").description("Show the full cdkd state record for a stack (metadata, outputs, resources)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--json", "Output the raw state and lock as JSON", false).addOption(stackRegionOption()).action(withErrorHandling(stateShowCommand));
|
|
28370
29621
|
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
28371
29622
|
return cmd;
|
|
28372
29623
|
}
|
|
@@ -28379,24 +29630,36 @@ async function stateRmCommand(stackArgs, options) {
|
|
|
28379
29630
|
}
|
|
28380
29631
|
const setup = await setupStateBackend(options);
|
|
28381
29632
|
try {
|
|
29633
|
+
const refs = await setup.stateBackend.listStacks();
|
|
28382
29634
|
for (const stackName of stackArgs) {
|
|
28383
|
-
const
|
|
28384
|
-
if (
|
|
29635
|
+
const stackRefs = refs.filter((r) => r.stackName === stackName);
|
|
29636
|
+
if (stackRefs.length === 0) {
|
|
28385
29637
|
logger.info(`No state found for stack: ${stackName}, skipping`);
|
|
28386
29638
|
continue;
|
|
28387
29639
|
}
|
|
29640
|
+
const targets = options.stackRegion ? stackRefs.filter((r) => r.region === options.stackRegion) : stackRefs;
|
|
29641
|
+
if (targets.length === 0) {
|
|
29642
|
+
const seen = stackRefs.map((r) => r.region ?? "(legacy)").join(", ");
|
|
29643
|
+
throw new Error(
|
|
29644
|
+
`No state found for stack '${stackName}' in region '${options.stackRegion}'. Available regions: ${seen}.`
|
|
29645
|
+
);
|
|
29646
|
+
}
|
|
28388
29647
|
if (!options.force) {
|
|
28389
|
-
const
|
|
28390
|
-
|
|
28391
|
-
|
|
28392
|
-
|
|
28393
|
-
|
|
29648
|
+
for (const target of targets) {
|
|
29649
|
+
const locked = await setup.lockManager.isLocked(stackName, target.region);
|
|
29650
|
+
if (locked) {
|
|
29651
|
+
const where = target.region ?? "(legacy)";
|
|
29652
|
+
throw new Error(
|
|
29653
|
+
`Stack '${stackName}' (${where}) is locked. Run 'cdkd force-unlock ${stackName}${target.region ? ` --stack-region ${target.region}` : ""}' first, or pass --force to remove anyway.`
|
|
29654
|
+
);
|
|
29655
|
+
}
|
|
28394
29656
|
}
|
|
28395
29657
|
}
|
|
28396
29658
|
if (!options.yes && !options.force) {
|
|
29659
|
+
const targetList = targets.map((t) => formatStackRef(t)).join(", ");
|
|
28397
29660
|
process.stdout.write(
|
|
28398
29661
|
`
|
|
28399
|
-
WARNING: This removes cdkd's state record for
|
|
29662
|
+
WARNING: This removes cdkd's state record for [${targetList}] only. AWS resources will NOT be deleted.
|
|
28400
29663
|
Use 'cdkd destroy ${stackName}' if you want to delete the actual resources.
|
|
28401
29664
|
|
|
28402
29665
|
`
|
|
@@ -28406,7 +29669,7 @@ Use 'cdkd destroy ${stackName}' if you want to delete the actual resources.
|
|
|
28406
29669
|
output: process.stdout
|
|
28407
29670
|
});
|
|
28408
29671
|
const answer = await rl.question(
|
|
28409
|
-
`Remove state for
|
|
29672
|
+
`Remove state for ${targetList} from s3://${setup.bucket}/${setup.prefix}/? (y/N): `
|
|
28410
29673
|
);
|
|
28411
29674
|
rl.close();
|
|
28412
29675
|
const trimmed = answer.trim().toLowerCase();
|
|
@@ -28415,16 +29678,28 @@ Use 'cdkd destroy ${stackName}' if you want to delete the actual resources.
|
|
|
28415
29678
|
continue;
|
|
28416
29679
|
}
|
|
28417
29680
|
}
|
|
28418
|
-
|
|
28419
|
-
|
|
28420
|
-
|
|
29681
|
+
for (const target of targets) {
|
|
29682
|
+
if (target.region) {
|
|
29683
|
+
await setup.stateBackend.deleteState(stackName, target.region);
|
|
29684
|
+
await setup.lockManager.forceReleaseLock(stackName, target.region);
|
|
29685
|
+
} else {
|
|
29686
|
+
await setup.lockManager.forceReleaseLock(stackName, void 0);
|
|
29687
|
+
}
|
|
29688
|
+
logger.info(`\u2713 Removed state for stack: ${formatStackRef(target)}`);
|
|
29689
|
+
}
|
|
28421
29690
|
}
|
|
28422
29691
|
} finally {
|
|
28423
29692
|
setup.dispose();
|
|
28424
29693
|
}
|
|
28425
29694
|
}
|
|
29695
|
+
function stackRegionOption() {
|
|
29696
|
+
return new Option4(
|
|
29697
|
+
"--stack-region <region>",
|
|
29698
|
+
"Region of the stack record to operate on. Required when the same stack name has state in multiple regions."
|
|
29699
|
+
);
|
|
29700
|
+
}
|
|
28426
29701
|
function createStateRmCommand() {
|
|
28427
|
-
const cmd = new Command9("rm").description("Remove cdkd state for one or more stacks (does NOT delete AWS resources)").argument("<stacks...>", "Stack name(s) to remove from state").option("-f, --force", "Skip confirmation and remove even if the stack is locked", false).action(withErrorHandling(stateRmCommand));
|
|
29702
|
+
const cmd = new Command9("rm").description("Remove cdkd state for one or more stacks (does NOT delete AWS resources)").argument("<stacks...>", "Stack name(s) to remove from state").option("-f, --force", "Skip confirmation and remove even if the stack is locked", false).addOption(stackRegionOption()).action(withErrorHandling(stateRmCommand));
|
|
28428
29703
|
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
28429
29704
|
return cmd;
|
|
28430
29705
|
}
|
|
@@ -28462,7 +29737,7 @@ function reorderArgs(argv) {
|
|
|
28462
29737
|
}
|
|
28463
29738
|
async function main() {
|
|
28464
29739
|
const program = new Command10();
|
|
28465
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
29740
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.9.0");
|
|
28466
29741
|
program.addCommand(createBootstrapCommand());
|
|
28467
29742
|
program.addCommand(createSynthCommand());
|
|
28468
29743
|
program.addCommand(createListCommand());
|