@go-to-k/cdkd 0.285.4 → 0.285.5
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 +10 -0
- package/dist/{asg-provider-sRJzRAe_.js → asg-provider-BBSPZtne.js} +2 -2
- package/dist/{asg-provider-sRJzRAe_.js.map → asg-provider-BBSPZtne.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-3EmPzxSN.js → deploy-engine-CSBoL-Az.js} +200 -86
- package/dist/{deploy-engine-3EmPzxSN.js.map → deploy-engine-CSBoL-Az.js.map} +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-DoauTYs2.js → program-Def0C7JX.js} +32 -8
- package/dist/{program-DoauTYs2.js.map → program-Def0C7JX.js.map} +1 -1
- package/dist/{version-Dlq6xZAQ.js → version-neBHYAq9.js} +2 -2
- package/dist/{version-Dlq6xZAQ.js.map → version-neBHYAq9.js.map} +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { d as generateResourceName, f as generateResourceNameWithFallback, g as withStackName, m as looksLikeCdkdGeneratedName, n as getLogger, o as getLiveRenderer, p as getCurrentStackName, u as applyDefaultNameForFallback } from "./logger-Dz3Le2Pw.js";
|
|
2
2
|
import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
|
|
3
|
-
import { t as getCdkdVersion } from "./version-
|
|
3
|
+
import { t as getCdkdVersion } from "./version-neBHYAq9.js";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
6
6
|
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -20218,6 +20218,151 @@ function isTerminationProtectionPropagationError(message) {
|
|
|
20218
20218
|
return /may not be terminated|disableApiTermination/i.test(message);
|
|
20219
20219
|
}
|
|
20220
20220
|
|
|
20221
|
+
//#endregion
|
|
20222
|
+
//#region src/deployment/delete-outcome.ts
|
|
20223
|
+
/**
|
|
20224
|
+
* Shared helpers over {@link ResourceDeleteResult} — originally the deploy-side
|
|
20225
|
+
* consumption of it (issue
|
|
20226
|
+
* [#1762](https://github.com/go-to-k/cdkd/issues/1762)), the twin of what
|
|
20227
|
+
* `src/cli/commands/destroy-runner.ts` does for `cdkd destroy`, and since issue
|
|
20228
|
+
* [#2301](https://github.com/go-to-k/cdkd/issues/2301) also the PRODUCER-side
|
|
20229
|
+
* `indeterminateGuards` constructor. Write and read live in one file on
|
|
20230
|
+
* purpose: the field's whole job is to survive a hop from a provider to a
|
|
20231
|
+
* recorder, and a sanitizer that does not sit beside its constructor is how
|
|
20232
|
+
* the two drift.
|
|
20233
|
+
*
|
|
20234
|
+
* Issue [#1752](https://github.com/go-to-k/cdkd/issues/1752) gave
|
|
20235
|
+
* `ResourceProvider.delete` an optional return value whose `'skipped'` arm
|
|
20236
|
+
* means **the resource this result names was NOT destroyed and may still be
|
|
20237
|
+
* ALIVE**, and taught the destroy runner to report it. Every OTHER
|
|
20238
|
+
* `provider.delete(...)` call site — the deploy engine's template-DELETE
|
|
20239
|
+
* branch, its four replacement / recreate delete sites, and the five
|
|
20240
|
+
* `rollback-executor.ts` delete arms — discarded the value, so the same skip
|
|
20241
|
+
* printed as `deleted`, counted as `deleted`, and dropped the state record.
|
|
20242
|
+
*
|
|
20243
|
+
* **The module must stay a LEAF — no imports beyond the type, ever.** Same
|
|
20244
|
+
* reason as `src/provisioning/nested-stack-messages.ts`: both the deploy
|
|
20245
|
+
* engine and the rollback executor consume it, and those two already sit on a
|
|
20246
|
+
* dense import ring (engine -> executor -> provider registry -> every
|
|
20247
|
+
* provider). A helper that pulled anything else in would close it.
|
|
20248
|
+
*/
|
|
20249
|
+
/**
|
|
20250
|
+
* The `reason` of a `'skipped'` delete outcome, or `undefined` when the
|
|
20251
|
+
* provider reported a delete (`{ outcome: 'deleted' }` or the back-compat
|
|
20252
|
+
* `void` return ~80 providers still use).
|
|
20253
|
+
*
|
|
20254
|
+
* A function rather than an inline `result?.outcome === 'skipped'` test at
|
|
20255
|
+
* ten call sites so the back-compat `void` reading lives in ONE place: the
|
|
20256
|
+
* signature is `Promise<void | ResourceDeleteResult>`, so a caller that awaits
|
|
20257
|
+
* it holds `void | ResourceDeleteResult`, which TypeScript will happily let
|
|
20258
|
+
* you compare against nothing useful.
|
|
20259
|
+
*/
|
|
20260
|
+
function deleteSkipReason(result) {
|
|
20261
|
+
if (!result || result.outcome !== "skipped") return void 0;
|
|
20262
|
+
if (typeof result.reason !== "string") return UNSPECIFIED_SKIP_REASON;
|
|
20263
|
+
const trimmed = result.reason.trim();
|
|
20264
|
+
return trimmed === "" ? UNSPECIFIED_SKIP_REASON : trimmed;
|
|
20265
|
+
}
|
|
20266
|
+
/**
|
|
20267
|
+
* Stand-in for a `'skipped'` outcome whose producer supplied no `reason`.
|
|
20268
|
+
*
|
|
20269
|
+
* Deliberately says the cause is unknown rather than inventing one: the line
|
|
20270
|
+
* it renders on is the user's only signal that the resource survived, and a
|
|
20271
|
+
* fabricated cause would send them looking in the wrong place.
|
|
20272
|
+
*/
|
|
20273
|
+
const UNSPECIFIED_SKIP_REASON = "no reason reported by the provider";
|
|
20274
|
+
/**
|
|
20275
|
+
* The sentence every deploy-side skip renders, in the log line AND in the
|
|
20276
|
+
* `Error` the sites that must FAIL the resource throw.
|
|
20277
|
+
*
|
|
20278
|
+
* Wording rules, both load-bearing:
|
|
20279
|
+
*
|
|
20280
|
+
* 1. It says the resource was NOT deleted and MAY STILL EXIST. A skip issued
|
|
20281
|
+
* no AWS call at every producer but `NestedStackProvider.delete`, so the
|
|
20282
|
+
* old resource is presumed alive — which is the whole reason a replacement
|
|
20283
|
+
* site cannot proceed to create its replacement beside it.
|
|
20284
|
+
* 2. It must NOT contain any phrase the callers' already-deleted classifiers
|
|
20285
|
+
* substring-match (`does not exist` / `was not found` / `not found` /
|
|
20286
|
+
* `No policy found` / `NoSuchEntity` / `NotFoundException` /
|
|
20287
|
+
* `ResourceNotFoundException`). Reading a skip as "already gone" is exactly
|
|
20288
|
+
* the mis-accounting this change exists to remove, and the deploy engine's
|
|
20289
|
+
* DELETE branch and its update-not-supported fallback each carry such a
|
|
20290
|
+
* classifier. The call sites additionally handle the skip OUTSIDE their
|
|
20291
|
+
* `catch`, so a future `reason` carrying one of those phrases still cannot
|
|
20292
|
+
* reach a classifier — belt and braces, because `reason` is provider text.
|
|
20293
|
+
*/
|
|
20294
|
+
function deleteSkippedMessage(logicalId, physicalId, reason, duringClause) {
|
|
20295
|
+
return `cdkd could not address ${logicalId} (${physicalId}) ${duringClause}, so it was NOT deleted and may still exist: ${reason}`;
|
|
20296
|
+
}
|
|
20297
|
+
/**
|
|
20298
|
+
* Attach an {@link IndeterminateGuard} to whatever a delete arm was about to
|
|
20299
|
+
* return (issue [#2301](https://github.com/go-to-k/cdkd/issues/2301)).
|
|
20300
|
+
*
|
|
20301
|
+
* `undefined` in, `undefined` out when there is no guard to carry — so a
|
|
20302
|
+
* provider whose guard reached a verdict keeps returning the back-compat
|
|
20303
|
+
* `void` the ~80 providers that return it use, and nothing about the
|
|
20304
|
+
* existing shape changes on the hot path.
|
|
20305
|
+
*
|
|
20306
|
+
* A `'skipped'` result keeps its outcome and its `reason`: a guard that could
|
|
20307
|
+
* not answer and a delete that could not be addressed are independent facts,
|
|
20308
|
+
* and collapsing either into the other loses one of them.
|
|
20309
|
+
*/
|
|
20310
|
+
function withIndeterminateGuard(result, guard) {
|
|
20311
|
+
if (!guard) return result;
|
|
20312
|
+
const indeterminateGuards = [...Array.isArray(result?.indeterminateGuards) ? result.indeterminateGuards : [], guard];
|
|
20313
|
+
if (result && result.outcome === "skipped") return {
|
|
20314
|
+
...result,
|
|
20315
|
+
indeterminateGuards
|
|
20316
|
+
};
|
|
20317
|
+
return {
|
|
20318
|
+
...result ?? {},
|
|
20319
|
+
outcome: "deleted",
|
|
20320
|
+
indeterminateGuards
|
|
20321
|
+
};
|
|
20322
|
+
}
|
|
20323
|
+
/**
|
|
20324
|
+
* The guards a delete result reports as INDETERMINATE — those that ran, could
|
|
20325
|
+
* not reach a verdict, and were therefore not enforced while cdkd proceeded
|
|
20326
|
+
* (issue [#2301](https://github.com/go-to-k/cdkd/issues/2301)). Empty for the
|
|
20327
|
+
* overwhelmingly common case, including the back-compat `void` return.
|
|
20328
|
+
*
|
|
20329
|
+
* Defensive in the same shape and for the same reason as
|
|
20330
|
+
* {@link deleteSkipReason}: the value crosses into a DURABLE record
|
|
20331
|
+
* (`deployments/*.jsonl`), providers are the least type-checked layer in the
|
|
20332
|
+
* repo (a hand-built test double, a future arm, a JS provider), and a
|
|
20333
|
+
* malformed entry must degrade to "not reported" rather than crash the delete
|
|
20334
|
+
* path or persist `guard: undefined`. `typeof` rather than `?.trim()` for the
|
|
20335
|
+
* same reason `deleteSkipReason` uses it — a non-string makes `.trim` itself
|
|
20336
|
+
* `undefined`, i.e. a TypeError thrown out of the very path this hardens.
|
|
20337
|
+
*
|
|
20338
|
+
* Entries whose `guard` or `reason` is missing / non-string / blank are
|
|
20339
|
+
* DROPPED rather than defaulted, which is the opposite of `deleteSkipReason`'s
|
|
20340
|
+
* choice and deliberately so: there a default is the user's only signal that a
|
|
20341
|
+
* live resource survived, so inventing `UNSPECIFIED_SKIP_REASON` beats
|
|
20342
|
+
* silence. Here a guard row with no guard id and no cause says only "something
|
|
20343
|
+
* somewhere was not checked", which cannot be acted on — and it would count
|
|
20344
|
+
* toward the destroy summary's tally, turning an unactionable row into a
|
|
20345
|
+
* number the operator has to chase.
|
|
20346
|
+
*/
|
|
20347
|
+
function deleteIndeterminateGuards(result) {
|
|
20348
|
+
const raw = result?.indeterminateGuards;
|
|
20349
|
+
if (!Array.isArray(raw)) return [];
|
|
20350
|
+
const out = [];
|
|
20351
|
+
for (const entry of raw) {
|
|
20352
|
+
if (!entry || typeof entry !== "object") continue;
|
|
20353
|
+
const { guard, reason } = entry;
|
|
20354
|
+
if (typeof guard !== "string" || typeof reason !== "string") continue;
|
|
20355
|
+
const trimmedGuard = guard.trim();
|
|
20356
|
+
const trimmedReason = reason.trim();
|
|
20357
|
+
if (trimmedGuard === "" || trimmedReason === "") continue;
|
|
20358
|
+
out.push({
|
|
20359
|
+
guard: trimmedGuard,
|
|
20360
|
+
reason: trimmedReason
|
|
20361
|
+
});
|
|
20362
|
+
}
|
|
20363
|
+
return out;
|
|
20364
|
+
}
|
|
20365
|
+
|
|
20221
20366
|
//#endregion
|
|
20222
20367
|
//#region src/provisioning/json-patch-generator.ts
|
|
20223
20368
|
/**
|
|
@@ -20941,6 +21086,19 @@ function requiresCcDeleteIdentityCheck(resourceType) {
|
|
|
20941
21086
|
return CC_DELETE_IDENTITY_CHECKED_TYPES.has(resourceType);
|
|
20942
21087
|
}
|
|
20943
21088
|
/**
|
|
21089
|
+
* `IndeterminateGuard.guard` for the pre-flight identity confirmation above
|
|
21090
|
+
* (issue [#2301](https://github.com/go-to-k/cdkd/issues/2301)).
|
|
21091
|
+
*
|
|
21092
|
+
* Named for the GUARD, not for the type or the API it happens to probe today:
|
|
21093
|
+
* the value is persisted into `deployments/*.jsonl` and is therefore a user
|
|
21094
|
+
* contract, and the set it fires for is
|
|
21095
|
+
* {@link CC_DELETE_IDENTITY_CHECKED_TYPES} — a set that is expected to grow to
|
|
21096
|
+
* any type whose physical id is globally unique while its resource is
|
|
21097
|
+
* regional. `s3` / `get-bucket-location` in the id would go stale on the first
|
|
21098
|
+
* such addition, and a stale id cannot be corrected without breaking readers.
|
|
21099
|
+
*/
|
|
21100
|
+
const CC_DELETE_REGION_IDENTITY_GUARD = "cc-delete-region-identity";
|
|
21101
|
+
/**
|
|
20944
21102
|
* The region a `GetBucketLocation` answer denotes, canonicalized.
|
|
20945
21103
|
*
|
|
20946
21104
|
* Two legacy wire shapes, both still returned, which is why this is a function
|
|
@@ -21152,11 +21310,11 @@ var CloudControlProvider = class {
|
|
|
21152
21310
|
this.logger.debug(`Deleting resource ${logicalId} (${resourceType}), physical ID: ${physicalId}`);
|
|
21153
21311
|
if (context?.finalSnapshotIdentifier !== void 0) throw new ProvisioningError(`${logicalId} (${resourceType}) requires a final snapshot (DeletionPolicy: Snapshot), but the Cloud Control API delete route has no final-snapshot parameter. Re-run with --skip-final-snapshot after snapshotting manually, or retain the resource.`, resourceType, logicalId, physicalId);
|
|
21154
21312
|
await this.assertRecordedRegionAgainstClient("pre-delete", context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
21155
|
-
await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
21313
|
+
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
21156
21314
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
21157
21315
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
21158
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
21159
|
-
return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
21316
|
+
const { ASGProvider } = await import("./asg-provider-BBSPZtne.js").then((n) => n.n);
|
|
21317
|
+
return withIndeterminateGuard(await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
|
|
21160
21318
|
}
|
|
21161
21319
|
const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
|
|
21162
21320
|
if (isProtectedEc2Instance) await disableInstanceApiTermination(getAwsClients().ec2, physicalId, this.logger);
|
|
@@ -21174,13 +21332,13 @@ var CloudControlProvider = class {
|
|
|
21174
21332
|
this.logger.debug(`Delete request submitted for ${logicalId}, token: ${deleteResponse.ProgressEvent.RequestToken}`);
|
|
21175
21333
|
await this.waitForOperation(deleteResponse.ProgressEvent.RequestToken, logicalId, "DELETE", resourceType);
|
|
21176
21334
|
this.logger.debug(`Deleted resource ${logicalId}`);
|
|
21177
|
-
return;
|
|
21335
|
+
return withIndeterminateGuard(void 0, indeterminateGuard);
|
|
21178
21336
|
} catch (error) {
|
|
21179
21337
|
const err = error;
|
|
21180
21338
|
if (error instanceof CloudControlOperationFailedError && error.ccOperation === "DELETE" && error.ccErrorCode === "NotFound" || err.name === "ResourceNotFoundException" || err.message?.includes("does not exist") || err.message?.includes("not found") || err.message?.includes("NotFound")) {
|
|
21181
21339
|
await this.assertRecordedRegionAgainstClient("not-found", context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
21182
21340
|
this.logger.debug(`Resource ${logicalId} already deleted (not found), treating as success`);
|
|
21183
|
-
return;
|
|
21341
|
+
return withIndeterminateGuard(void 0, indeterminateGuard);
|
|
21184
21342
|
}
|
|
21185
21343
|
if (isProtectedEc2Instance && isTerminationProtectionPropagationError(err.message ?? "") && attempt < maxAttempts) {
|
|
21186
21344
|
this.logger.debug(`Cloud Control delete of ${logicalId} raced the DisableApiTermination flip-off (attempt ${attempt}/${maxAttempts}); re-flipping and retrying`);
|
|
@@ -21316,21 +21474,43 @@ var CloudControlProvider = class {
|
|
|
21316
21474
|
* indeterminate arm, which PROCEEDS. `src/utils/aws-region-resolver.ts`
|
|
21317
21475
|
* records the same finding, and the SDK-side guard re-learned it the
|
|
21318
21476
|
* expensive way.
|
|
21477
|
+
*
|
|
21478
|
+
* RETURN VALUE (issue #2301 item 3). `undefined` means the guard reached a
|
|
21479
|
+
* verdict — it confirmed the region, or the type is unguarded, or the bucket
|
|
21480
|
+
* is absent (a fourth outcome, not an indeterminate one, per the paragraph
|
|
21481
|
+
* above). An {@link IndeterminateGuard} means it could NOT, and the caller
|
|
21482
|
+
* must carry it out through `ResourceDeleteResult` so the destroy runner can
|
|
21483
|
+
* persist a `RESOURCE_GUARD_INDETERMINATE` event. A MISMATCH still throws.
|
|
21484
|
+
*
|
|
21485
|
+
* The two indeterminate arms below produce THREE distinct `reason` texts,
|
|
21486
|
+
* not two, and that is deliberate: the region-resolution arm falls THROUGH
|
|
21487
|
+
* into the no-region warn, so before this change a client whose SDK region
|
|
21488
|
+
* chain REJECTED was reported identically to one that was never asked. The
|
|
21489
|
+
* remedies differ (fix the credential chain / pass `--region` vs. repair the
|
|
21490
|
+
* state record), so the durable record — and the warn beside it — names
|
|
21491
|
+
* which happened.
|
|
21319
21492
|
*/
|
|
21320
21493
|
async confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context) {
|
|
21321
|
-
if (!requiresCcDeleteIdentityCheck(resourceType)) return;
|
|
21494
|
+
if (!requiresCcDeleteIdentityCheck(resourceType)) return void 0;
|
|
21322
21495
|
const recordedRegion = context?.expectedRegion?.trim();
|
|
21323
21496
|
let expectedRegion = recordedRegion === void 0 || recordedRegion === "" ? void 0 : recordedRegion;
|
|
21497
|
+
let clientRegionError;
|
|
21324
21498
|
if (expectedRegion === void 0) try {
|
|
21325
21499
|
const clientRegion = (await this.cloudControlClient.config.region())?.trim();
|
|
21326
21500
|
expectedRegion = clientRegion === void 0 || clientRegion === "" ? void 0 : clientRegion;
|
|
21327
21501
|
} catch (error) {
|
|
21328
|
-
|
|
21502
|
+
const clientRegionFailure = describeAwsFailure(error);
|
|
21503
|
+
clientRegionError = clientRegionFailure.summary;
|
|
21504
|
+
this.logger.debug(`Could not resolve the Cloud Control client region while confirming ${physicalId}: ${clientRegionFailure.detail}`);
|
|
21329
21505
|
expectedRegion = void 0;
|
|
21330
21506
|
}
|
|
21331
21507
|
if (expectedRegion === void 0) {
|
|
21332
|
-
|
|
21333
|
-
|
|
21508
|
+
const reason = clientRegionError === void 0 ? `neither the stack state nor the AWS client reports a region` : `the stack state records no region and the AWS client's region could not be resolved: ${clientRegionError}`;
|
|
21509
|
+
this.logger.warn(`Could not confirm that ${resourceType} ${physicalId} (${logicalId}) is the resource this destroy targets: ${reason.replace(/[.\s]+$/, "")}. Proceeding with the delete.`);
|
|
21510
|
+
return {
|
|
21511
|
+
guard: CC_DELETE_REGION_IDENTITY_GUARD,
|
|
21512
|
+
reason
|
|
21513
|
+
};
|
|
21334
21514
|
}
|
|
21335
21515
|
const wantRegion = canonicalizeRegion(expectedRegion);
|
|
21336
21516
|
let actualRegion;
|
|
@@ -21341,9 +21521,14 @@ var CloudControlProvider = class {
|
|
|
21341
21521
|
this.logger.debug(`Bucket ${physicalId} (${logicalId}) is already absent; leaving the delete to the Cloud Control idempotency path`);
|
|
21342
21522
|
return;
|
|
21343
21523
|
}
|
|
21344
|
-
const
|
|
21345
|
-
this.logger.
|
|
21346
|
-
|
|
21524
|
+
const failure = describeAwsFailure(error);
|
|
21525
|
+
this.logger.debug(`s3:GetBucketLocation on ${physicalId} (${logicalId}) failed: ${failure.detail}`);
|
|
21526
|
+
const summarySentence = failure.summary.replace(/[.\s]+$/, "");
|
|
21527
|
+
this.logger.warn(`Could not confirm which region S3 bucket ${physicalId} (${logicalId}) lives in before deleting it: ${summarySentence}. S3 bucket names are globally unique, so cdkd cannot rule out that this name denotes a bucket in another region. Grant s3:GetBucketLocation on the bucket to enable the check. Proceeding with the delete.`);
|
|
21528
|
+
return {
|
|
21529
|
+
guard: CC_DELETE_REGION_IDENTITY_GUARD,
|
|
21530
|
+
reason: `s3:GetBucketLocation on ${physicalId} could not be answered: ${failure.summary}`
|
|
21531
|
+
};
|
|
21347
21532
|
}
|
|
21348
21533
|
if (actualRegion === wantRegion) {
|
|
21349
21534
|
this.logger.debug(`Confirmed S3 bucket ${physicalId} (${logicalId}) lives in ${wantRegion} before deleting it`);
|
|
@@ -29019,77 +29204,6 @@ async function withResourceDeadline(operation, opts) {
|
|
|
29019
29204
|
});
|
|
29020
29205
|
}
|
|
29021
29206
|
|
|
29022
|
-
//#endregion
|
|
29023
|
-
//#region src/deployment/delete-outcome.ts
|
|
29024
|
-
/**
|
|
29025
|
-
* Deploy-side consumption of {@link ResourceDeleteResult} (issue
|
|
29026
|
-
* [#1762](https://github.com/go-to-k/cdkd/issues/1762)) — the twin of what
|
|
29027
|
-
* `src/cli/commands/destroy-runner.ts` does for `cdkd destroy`.
|
|
29028
|
-
*
|
|
29029
|
-
* Issue [#1752](https://github.com/go-to-k/cdkd/issues/1752) gave
|
|
29030
|
-
* `ResourceProvider.delete` an optional return value whose `'skipped'` arm
|
|
29031
|
-
* means **the resource this result names was NOT destroyed and may still be
|
|
29032
|
-
* ALIVE**, and taught the destroy runner to report it. Every OTHER
|
|
29033
|
-
* `provider.delete(...)` call site — the deploy engine's template-DELETE
|
|
29034
|
-
* branch, its four replacement / recreate delete sites, and the five
|
|
29035
|
-
* `rollback-executor.ts` delete arms — discarded the value, so the same skip
|
|
29036
|
-
* printed as `deleted`, counted as `deleted`, and dropped the state record.
|
|
29037
|
-
*
|
|
29038
|
-
* **The module must stay a LEAF — no imports beyond the type, ever.** Same
|
|
29039
|
-
* reason as `src/provisioning/nested-stack-messages.ts`: both the deploy
|
|
29040
|
-
* engine and the rollback executor consume it, and those two already sit on a
|
|
29041
|
-
* dense import ring (engine -> executor -> provider registry -> every
|
|
29042
|
-
* provider). A helper that pulled anything else in would close it.
|
|
29043
|
-
*/
|
|
29044
|
-
/**
|
|
29045
|
-
* The `reason` of a `'skipped'` delete outcome, or `undefined` when the
|
|
29046
|
-
* provider reported a delete (`{ outcome: 'deleted' }` or the back-compat
|
|
29047
|
-
* `void` return ~80 providers still use).
|
|
29048
|
-
*
|
|
29049
|
-
* A function rather than an inline `result?.outcome === 'skipped'` test at
|
|
29050
|
-
* ten call sites so the back-compat `void` reading lives in ONE place: the
|
|
29051
|
-
* signature is `Promise<void | ResourceDeleteResult>`, so a caller that awaits
|
|
29052
|
-
* it holds `void | ResourceDeleteResult`, which TypeScript will happily let
|
|
29053
|
-
* you compare against nothing useful.
|
|
29054
|
-
*/
|
|
29055
|
-
function deleteSkipReason(result) {
|
|
29056
|
-
if (!result || result.outcome !== "skipped") return void 0;
|
|
29057
|
-
if (typeof result.reason !== "string") return UNSPECIFIED_SKIP_REASON;
|
|
29058
|
-
const trimmed = result.reason.trim();
|
|
29059
|
-
return trimmed === "" ? UNSPECIFIED_SKIP_REASON : trimmed;
|
|
29060
|
-
}
|
|
29061
|
-
/**
|
|
29062
|
-
* Stand-in for a `'skipped'` outcome whose producer supplied no `reason`.
|
|
29063
|
-
*
|
|
29064
|
-
* Deliberately says the cause is unknown rather than inventing one: the line
|
|
29065
|
-
* it renders on is the user's only signal that the resource survived, and a
|
|
29066
|
-
* fabricated cause would send them looking in the wrong place.
|
|
29067
|
-
*/
|
|
29068
|
-
const UNSPECIFIED_SKIP_REASON = "no reason reported by the provider";
|
|
29069
|
-
/**
|
|
29070
|
-
* The sentence every deploy-side skip renders, in the log line AND in the
|
|
29071
|
-
* `Error` the sites that must FAIL the resource throw.
|
|
29072
|
-
*
|
|
29073
|
-
* Wording rules, both load-bearing:
|
|
29074
|
-
*
|
|
29075
|
-
* 1. It says the resource was NOT deleted and MAY STILL EXIST. A skip issued
|
|
29076
|
-
* no AWS call at every producer but `NestedStackProvider.delete`, so the
|
|
29077
|
-
* old resource is presumed alive — which is the whole reason a replacement
|
|
29078
|
-
* site cannot proceed to create its replacement beside it.
|
|
29079
|
-
* 2. It must NOT contain any phrase the callers' already-deleted classifiers
|
|
29080
|
-
* substring-match (`does not exist` / `was not found` / `not found` /
|
|
29081
|
-
* `No policy found` / `NoSuchEntity` / `NotFoundException` /
|
|
29082
|
-
* `ResourceNotFoundException`). Reading a skip as "already gone" is exactly
|
|
29083
|
-
* the mis-accounting this change exists to remove, and the deploy engine's
|
|
29084
|
-
* DELETE branch and its update-not-supported fallback each carry such a
|
|
29085
|
-
* classifier. The call sites additionally handle the skip OUTSIDE their
|
|
29086
|
-
* `catch`, so a future `reason` carrying one of those phrases still cannot
|
|
29087
|
-
* reach a classifier — belt and braces, because `reason` is provider text.
|
|
29088
|
-
*/
|
|
29089
|
-
function deleteSkippedMessage(logicalId, physicalId, reason, duringClause) {
|
|
29090
|
-
return `cdkd could not address ${logicalId} (${physicalId}) ${duringClause}, so it was NOT deleted and may still exist: ${reason}`;
|
|
29091
|
-
}
|
|
29092
|
-
|
|
29093
29207
|
//#endregion
|
|
29094
29208
|
//#region src/deployment/update-outcome.ts
|
|
29095
29209
|
/**
|
|
@@ -33143,5 +33257,5 @@ var DeployEngine = class {
|
|
|
33143
33257
|
};
|
|
33144
33258
|
|
|
33145
33259
|
//#endregion
|
|
33146
|
-
export {
|
|
33147
|
-
//# sourceMappingURL=deploy-engine-
|
|
33260
|
+
export { DEFAULT_STATE_PREFIX as $, warnDeprecatedNoPrefixCliFlag as $n, maskSecretsInError as $t, bold as A, buildDenyExternalAccessPolicy as An, NestedStackChildDirectDestroyError as Ar, requireConfigObject as At, secretBearingStateKeyWarning as B, getDockerImageBySourceHash as Bn, isCdkdError as Br, DiffCalculator as Bt, unsupportedFinalSnapshotError as C, ensureAssetStorage as Cn, DeployCancelledError as Cr, assertRegionMatch as Ct, isStatefulRecreateTargetSync as D, readBootstrapMarkerBody as Dn, LocalStartServiceError as Dr, readConfigString as Dt, MULTI_REGION_RECREATE_BLOCKED_TYPES as E, parseBootstrapMarker as En, LocalMigrateError as Er, configStringRefusal as Et, yellow as F, getDockerCmd as Fn, StackHasActiveImportsError as Fr, s3BucketDomainName as Ft, clearOnUpdateRemoval as G, resolveApp as Gn, isThrottlingError as Gr, TemplateParser as Gt, getCurrentResourceSecrets as H, synthesisStatusMessage as Hn, withErrorHandling as Hr, describeTypeWithThrottleRetry as Ht, collectDeclaredOutputNames as I, partitionSensitiveEnv as In, StackTerminationProtectionError as Ir, s3BucketDualStackDomainName as It, findSilentDropProperties as J, resolveSkipPrefix as Jn, markRedactedCause as Jr, TEMPLATE_SOURCED_RULES as Jt, ProviderRegistry as K, resolveAutoAssetStorage as Kn, isTransientServerError as Kr, STATE_SOURCED_CROSS_GENERATION_RULES as Kt, collectPublishedOutputNames as L, runDockerForeground as Ln, StateError as Lr, s3BucketRegionalDomainName as Lt, gray as M, buildDockerImage as Mn, ProvisioningError as Mr, classifyReplaySecretRegion as Mt, green as N, dockerSpawnEnvWithSensitive as Nn, ResourceTimeoutError as Nr, producerRegionsFromState as Nt, renderStatefulReason as O, validateAssetBucketName as On, LockError as Or, replayWarn as Ot, red as P, formatDockerLoginError as Pn, ResourceUpdateNotSupportedError as Pr, s3BucketArn as Pt, CUSTOM_RESOURCE_RESPONSE_PREFIX as Q, stateBucketExistenceConfirmed as Qn, isSingleDynamicReferenceToken as Qt, exportAliasCollisionScrubWarning as R, runDockerStreaming as Rn, SynthesisError as Rr, s3BucketWebsiteUrl as Rt, refusesFinalSnapshot as S, assertAssetBucketRegion as Sn, DependencyError as Sr, resolveExplicitPhysicalId as St, extractDeploymentEventError as T, isCrossRegionRedirect as Tn, LocalInvokeBuildError as Tr, configBooleanRefusal as Tt, IAMRoleProvider as U, getDefaultStateBucketName as Un, isMarkedNonRetryable as Ur, withRetry as Ut, stateKeySecretExposure as V, Synthesizer as Vn, normalizeAwsError as Vr, INTRINSIC_KEYS as Vt, collectInlinePolicyNamesManagedBySiblings as W, getLegacyStateBucketName as Wn, isRetryableTransientError as Wr, DagBuilder as Wt, maskDeep as X, resolveStateBucketWithDefaultAndSource as Xn, __exportAll as Xr, dynamicReferenceTokens as Xt, createMaskedRetryLogger as Y, resolveStateBucketWithDefault as Yn, retryClassificationText as Yr, createSecretMasker as Yt, maskerOrIdentity as Z, resolveUseCdkBootstrapAssets as Zn, errorCauseChain as Zt, PRE_DELETE_SNAPSHOT_TYPES as _, rewriteTemplateAssetReferences as _n, setAwsClients as _r, isUnboundTemplateParameter as _t, DeploymentEventsStore as a, S3StateBackend as an, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as ar, CloudControlProvider as at, createPreDeleteFinalSnapshot as b, AssetModeResolver as bn, ConfigError as br, WAFv2WebACLProvider as bt, replayFailedOperations as c, importableOutputKeys as cn, canonicalizeRegion as cr, deleteIndeterminateGuards as ct, updatePartialReason as d, AssetPublisher as dn, processStackMessages as dr, isTerminationProtectionPropagationError as dt, maskSecretsInText as en, CFN_TEMPLATE_BODY_LIMIT as er, beginCommandInterruptScope as et, withResourceDeadline as f, stringifyValue as fn, clearBucketRegionCache as fr, IntrinsicFunctionResolver as ft, ATOMIC_FINAL_SNAPSHOT_TYPES as g, loadPublishableAssetManifest as gn, resetAwsClients as gr, getAccountInfo as gt, computeImplicitDeleteEdges as h, createAssetRedirectResolver as hn, getAwsClients as hr, coerceParameterTypedValue as ht, DeploymentEventsReader as i, displaySafe as in, uploadCfnTemplate as ir, startInterruptWatch as it, cyan as j, describeAwsFailure as jn, PartialFailureError as jr, requireConfigString as jt, formatResourceLine as k, validateContainerRepoName as kn, MissingCdkCliError as kr, requireConfigArray as kt, replayRollback as l, importableOutputs as ln, derivePartitionAndUrlSuffix as lr, deleteSkipReason as lt, IMPLICIT_DELETE_DEPENDENCIES as m, buildAssetRedirectMap as mn, AwsClients as mr, cfnRefValueFromPhysicalId as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, scrubResourceRecord as nn, MIGRATE_TMP_PREFIX as nr, interruptWatchListenerCount as nt, planFailedOps as o, rebuildClientForBucketRegion as on, expectedOwnerParam as or, slowCcOperationTimeoutMs as ot, maskingRetryLogger as p, WorkGraph as pn, resolveBucketRegion as pr, carriesDynamicReference as pt, findActionableSilentDrops as q, resolveCaptureObservedState as qn, markNonRetryable as qr, STATE_SOURCED_READBACK_RULES as qt, DeployEngine as r, LockManager as rn, findLargeInlineResources as rr, isInterruptedWaitError as rt, planRollback as s, exportNamesCarriedFrom as sn, PARTITION_TABLE as sr, UNSPECIFIED_SKIP_REASON as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, redactSecretsForState as tn, CFN_TEMPLATE_URL_LIMIT as tr, endCommandInterruptScope as tt, updatePartialMessage as u, shouldRetainResource as un, AssemblyReader as ur, disableInstanceApiTermination as ut, buildFinalSnapshotIdentifier as v, escapeRegExp$1 as vn, AssetError as vr, parameterTypeMayLoseSecretIdentity as vt, makeCanonicalizePropertiesFn as w, getBootstrapMarkerKey as wn, DynamicReferenceRegionAmbiguousError as wr, coerceCfnBoolean as wt, isFinalSnapshotError as x, BOOTSTRAP_MARKER_PREFIX as xn, CrossAccountSecretRefusalError as xr, normalizeAwsTagsToCfn as xt, ccRoutedFinalSnapshotError as y, stripControlChars as yn, CdkdError as yr, refStateLookupFromResource as yt, isExportAliasCollision as z, AssetManifestLoader as zn, formatError as zr, applyRoleArnIfSet as zt };
|
|
33261
|
+
//# sourceMappingURL=deploy-engine-CSBoL-Az.js.map
|