@go-to-k/cdkd 0.284.78 → 0.284.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{asg-provider-R60Irey3.js → asg-provider-lbqsxGkM.js} +2 -2
- package/dist/{asg-provider-R60Irey3.js.map → asg-provider-lbqsxGkM.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-Cvkqa30x.js → deploy-engine-Dsd8oL2h.js} +266 -19
- package/dist/deploy-engine-Dsd8oL2h.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-DyZp744n.js → program-CQiB2tE5.js} +64 -9
- package/dist/{program-DyZp744n.js.map → program-CQiB2tE5.js.map} +1 -1
- package/dist/{version-GEIr41xq.js → version-CdU_rRxd.js} +2 -2
- package/dist/{version-GEIr41xq.js.map → version-CdU_rRxd.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-Cvkqa30x.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
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-C9-E73FI.js";
|
|
2
|
-
import { t as getCdkdVersion } from "./version-
|
|
2
|
+
import { t as getCdkdVersion } from "./version-CdU_rRxd.js";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
|
-
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
5
|
+
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
6
6
|
import { CloudControlClient, CreateResourceCommand, DeleteResourceCommand, GetResourceCommand, GetResourceRequestStatusCommand, ListResourcesCommand, UpdateResourceCommand } from "@aws-sdk/client-cloudcontrol";
|
|
7
7
|
import { AttachRolePolicyCommand, CreateRoleCommand, DeleteRoleCommand, DeleteRolePermissionsBoundaryCommand, DeleteRolePolicyCommand, DetachRolePolicyCommand, GetRoleCommand, GetRolePolicyCommand, IAMClient, ListAttachedRolePoliciesCommand, ListInstanceProfilesForRoleCommand, ListRolePoliciesCommand, ListRoleTagsCommand, NoSuchEntityException, PutRolePermissionsBoundaryCommand, PutRolePolicyCommand, RemoveRoleFromInstanceProfileCommand, TagRoleCommand, UntagRoleCommand, UpdateAssumeRolePolicyCommand, UpdateRoleCommand } from "@aws-sdk/client-iam";
|
|
8
8
|
import { SQSClient } from "@aws-sdk/client-sqs";
|
|
@@ -7524,6 +7524,145 @@ async function rebuildClientForBucketRegion(client, bucket, opts = {}) {
|
|
|
7524
7524
|
return replacement;
|
|
7525
7525
|
}
|
|
7526
7526
|
|
|
7527
|
+
//#endregion
|
|
7528
|
+
//#region src/state/s3-noncurrent-version-purge.ts
|
|
7529
|
+
/**
|
|
7530
|
+
* `DeleteObjects` is capped at 1000 entries per call.
|
|
7531
|
+
*
|
|
7532
|
+
* DEFENCE IN DEPTH, and unreachable today: `stale` is accumulated from a
|
|
7533
|
+
* SINGLE `ListObjectVersions` page, whose `Versions` + `DeleteMarkers` are
|
|
7534
|
+
* capped at 1000 COMBINED by `MaxKeys`, so the chunking below never takes its
|
|
7535
|
+
* second iteration. It is kept because the invariant it guards ("never hand
|
|
7536
|
+
* DeleteObjects more than 1000") is one a future change accumulating across
|
|
7537
|
+
* pages would silently break.
|
|
7538
|
+
*
|
|
7539
|
+
* Mutation coverage of this constant is ASYMMETRIC, which is worth stating
|
|
7540
|
+
* because the obvious summary is wrong in one direction: RAISING it is green
|
|
7541
|
+
* (nothing ever reaches the second chunk, so a bigger ceiling changes
|
|
7542
|
+
* nothing), while LOWERING it to 500 is RED — the multi-page fixture's
|
|
7543
|
+
* thousand-entry pages then split and the asserted batch shape changes. So the
|
|
7544
|
+
* value is fenced from below and not from above.
|
|
7545
|
+
*/
|
|
7546
|
+
const DELETE_BATCH_SIZE = 1e3;
|
|
7547
|
+
/** How many failing keys the warning names before it truncates. */
|
|
7548
|
+
const MAX_NAMED_FAILURES = 5;
|
|
7549
|
+
/**
|
|
7550
|
+
* Label for a `DeleteObjects` error entry that carries no `Key`.
|
|
7551
|
+
*
|
|
7552
|
+
* S3 always populates it in practice; the point is that an unnameable failure
|
|
7553
|
+
* must still COUNT, because the alternative measured here was `failed.size`
|
|
7554
|
+
* reaching 0 and the whole warning disappearing.
|
|
7555
|
+
*
|
|
7556
|
+
* Each keyless entry gets its OWN slot (`<unknown key #1>`, `#2`, ...) rather
|
|
7557
|
+
* than sharing one. Collapsing them was defended as "the honest reading", but
|
|
7558
|
+
* it is honest about NAMING and not about COUNTING: N keyless failures then
|
|
7559
|
+
* reported `1 key(s)`, which is the same prefixes-not-keys under-count this
|
|
7560
|
+
* change was raised to fix, arriving through the branch that fixed it. One
|
|
7561
|
+
* slot per failure can over-count if S3 ever returns two entries for one
|
|
7562
|
+
* object, which is the direction that errs toward reporting too much.
|
|
7563
|
+
*
|
|
7564
|
+
* The slot name is SYNTHETIC and its uniqueness is not enforced: a real key
|
|
7565
|
+
* literally called `<unknown key #1>` would merge with the first keyless
|
|
7566
|
+
* entry and under-count by one. Unreachable here — every caller passes
|
|
7567
|
+
* `custom-resource-responses/<requestId>.json` — and stated rather than left
|
|
7568
|
+
* implied, because "the name cannot collide" is the kind of unstated
|
|
7569
|
+
* invariant this module exists to stop asserting.
|
|
7570
|
+
*/
|
|
7571
|
+
const UNKNOWN_KEY_PREFIX = "<unknown key #";
|
|
7572
|
+
/** Reason recorded when a page says it is truncated but names no next key. */
|
|
7573
|
+
const TRUNCATED_NO_MARKER = "listing reported IsTruncated with no NextKeyMarker; the walk stopped early and versions may remain";
|
|
7574
|
+
/** Record a per-key failure reason without losing an earlier one. */
|
|
7575
|
+
function recordFailure(failed, key, reason) {
|
|
7576
|
+
const existing = failed.get(key);
|
|
7577
|
+
if (existing) existing.push(reason);
|
|
7578
|
+
else failed.set(key, [reason]);
|
|
7579
|
+
}
|
|
7580
|
+
const describe$1 = (error) => error instanceof Error ? error.message : String(error);
|
|
7581
|
+
async function purgeNoncurrentKeyVersions(s3Client, bucket, keys, options = {}) {
|
|
7582
|
+
if (keys.length === 0) return;
|
|
7583
|
+
const logger = options.logger ?? getLogger().child("s3-version-purge");
|
|
7584
|
+
const requestFields = options.requestFields ?? {};
|
|
7585
|
+
const wanted = new Set(keys);
|
|
7586
|
+
const prefixes = options.listPrefix !== void 0 ? [options.listPrefix] : keys;
|
|
7587
|
+
const failed = /* @__PURE__ */ new Map();
|
|
7588
|
+
const unknown = { n: 0 };
|
|
7589
|
+
for (const prefix of prefixes) try {
|
|
7590
|
+
await purgeUnderPrefix(s3Client, bucket, prefix, wanted, requestFields, failed, unknown);
|
|
7591
|
+
} catch (error) {
|
|
7592
|
+
const affected = options.listPrefix !== void 0 ? keys : [prefix];
|
|
7593
|
+
for (const key of affected) recordFailure(failed, key, describe$1(error));
|
|
7594
|
+
}
|
|
7595
|
+
if (failed.size > 0) {
|
|
7596
|
+
const named = [...failed.entries()].slice(0, MAX_NAMED_FAILURES).map(([key, reasons]) => `${key} (${reasons.join("; ")})`);
|
|
7597
|
+
const elided = failed.size - named.length;
|
|
7598
|
+
logger.warn(`Could not purge noncurrent versions of ${failed.size} key(s) in s3://${bucket}. Their previous versions survive and remain readable via GetObject with a VersionId (for a custom-resource response object that is the handler's full response body, including \`Data\`). Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the key(s) by hand. Failures: ${named.join(", ")}` + (elided > 0 ? ` (and ${elided} more)` : ""));
|
|
7599
|
+
}
|
|
7600
|
+
}
|
|
7601
|
+
/**
|
|
7602
|
+
* Paginate `ListObjectVersions` under one prefix and delete every returned
|
|
7603
|
+
* entry that is in `wanted` and is not the current version.
|
|
7604
|
+
*
|
|
7605
|
+
* Throws only when the LISTING fails; per-key delete failures are recorded in
|
|
7606
|
+
* `failed` and do not stop the walk.
|
|
7607
|
+
*
|
|
7608
|
+
* Safe on an UNVERSIONED bucket: S3 answers there with the single live object
|
|
7609
|
+
* carrying `VersionId: 'null'` and `IsLatest: true`, which the `IsLatest`
|
|
7610
|
+
* filter drops — so nothing is deleted and nothing throws. A `'null'` version
|
|
7611
|
+
* id is NOT filtered out on its own, because a bucket whose versioning was
|
|
7612
|
+
* SUSPENDED can carry a genuine noncurrent `'null'` version holding the body.
|
|
7613
|
+
*/
|
|
7614
|
+
async function purgeUnderPrefix(s3Client, bucket, prefix, wanted, requestFields, failed, unknown) {
|
|
7615
|
+
let keyMarker;
|
|
7616
|
+
let versionIdMarker;
|
|
7617
|
+
do {
|
|
7618
|
+
const resp = await s3Client.send(new ListObjectVersionsCommand({
|
|
7619
|
+
Bucket: bucket,
|
|
7620
|
+
...requestFields,
|
|
7621
|
+
Prefix: prefix,
|
|
7622
|
+
...keyMarker !== void 0 && { KeyMarker: keyMarker },
|
|
7623
|
+
...versionIdMarker !== void 0 && { VersionIdMarker: versionIdMarker }
|
|
7624
|
+
}));
|
|
7625
|
+
const stale = [];
|
|
7626
|
+
for (const entry of [...resp.Versions ?? [], ...resp.DeleteMarkers ?? []]) {
|
|
7627
|
+
if (entry.Key === void 0 || !wanted.has(entry.Key)) continue;
|
|
7628
|
+
if (entry.IsLatest !== false) continue;
|
|
7629
|
+
if (!entry.VersionId) continue;
|
|
7630
|
+
stale.push({
|
|
7631
|
+
Key: entry.Key,
|
|
7632
|
+
VersionId: entry.VersionId
|
|
7633
|
+
});
|
|
7634
|
+
}
|
|
7635
|
+
for (let i = 0; i < stale.length; i += DELETE_BATCH_SIZE) {
|
|
7636
|
+
const batch = stale.slice(i, i + DELETE_BATCH_SIZE);
|
|
7637
|
+
try {
|
|
7638
|
+
const deleted = await s3Client.send(new DeleteObjectsCommand({
|
|
7639
|
+
Bucket: bucket,
|
|
7640
|
+
...requestFields,
|
|
7641
|
+
Delete: {
|
|
7642
|
+
Objects: batch,
|
|
7643
|
+
Quiet: true
|
|
7644
|
+
}
|
|
7645
|
+
}));
|
|
7646
|
+
for (const err of deleted.Errors ?? []) {
|
|
7647
|
+
const reason = `version ${err.VersionId ?? "<unknown>"}: ${err.Code ?? "Error"}` + (err.Message ? ` - ${err.Message}` : "");
|
|
7648
|
+
if (err.Key !== void 0) recordFailure(failed, err.Key, reason);
|
|
7649
|
+
else {
|
|
7650
|
+
unknown.n += 1;
|
|
7651
|
+
recordFailure(failed, `${UNKNOWN_KEY_PREFIX}${unknown.n}>`, reason);
|
|
7652
|
+
}
|
|
7653
|
+
}
|
|
7654
|
+
} catch (error) {
|
|
7655
|
+
for (const object of batch) recordFailure(failed, object.Key, describe$1(error));
|
|
7656
|
+
}
|
|
7657
|
+
}
|
|
7658
|
+
if (resp.IsTruncated === true && resp.NextKeyMarker === void 0) {
|
|
7659
|
+
for (const key of wanted) if (key.startsWith(prefix)) recordFailure(failed, key, TRUNCATED_NO_MARKER);
|
|
7660
|
+
}
|
|
7661
|
+
keyMarker = resp.IsTruncated === true ? resp.NextKeyMarker : void 0;
|
|
7662
|
+
versionIdMarker = keyMarker !== void 0 ? resp.NextVersionIdMarker : void 0;
|
|
7663
|
+
} while (keyMarker !== void 0);
|
|
7664
|
+
}
|
|
7665
|
+
|
|
7527
7666
|
//#endregion
|
|
7528
7667
|
//#region src/state/s3-state-backend.ts
|
|
7529
7668
|
/**
|
|
@@ -8065,6 +8204,44 @@ var S3StateBackend = class {
|
|
|
8065
8204
|
if (failures.length > 0) throw new StateError(`Failed to delete ${failures.length} object(s) from bucket '${this.config.bucket}': ${failures.join("; ")}`);
|
|
8066
8205
|
}
|
|
8067
8206
|
/**
|
|
8207
|
+
* Delete the NONCURRENT versions of raw sidecar keys in the state bucket
|
|
8208
|
+
* (issue [#2340](https://github.com/go-to-k/cdkd/issues/2340)).
|
|
8209
|
+
*
|
|
8210
|
+
* The versioned-bucket companion to {@link deleteRawObjects}, and
|
|
8211
|
+
* deliberately NOT folded into it. `deleteRawObjects` has SIX call sites,
|
|
8212
|
+
* ENUMERATED rather than given as a grep so that a comment quoting the
|
|
8213
|
+
* command cannot end up matching itself and reporting seven:
|
|
8214
|
+
* `deployment-events-store.ts` x4, `gc.ts`, `bootstrap-destroy.ts`. Four of
|
|
8215
|
+
* the six are in `deployment-events-store.ts`, whose objects
|
|
8216
|
+
* `tests/integration/s3-versions.sh` records as deliberately surviving as
|
|
8217
|
+
* CURRENT objects; a blanket purge there would
|
|
8218
|
+
* change that behaviour AND widen the IAM every caller needs
|
|
8219
|
+
* (`s3:ListBucketVersions`, `s3:DeleteObjectVersion`). So the purge is
|
|
8220
|
+
* opt-in, and today `cdkd gc`'s custom-resource response sweep is the one
|
|
8221
|
+
* caller that opts in.
|
|
8222
|
+
*
|
|
8223
|
+
* NEVER THROWS, and the try/catch below is what makes that true rather than
|
|
8224
|
+
* the helper alone. `ensureClientForBucket()` and `ownerParam()` sit OUTSIDE
|
|
8225
|
+
* the helper's guarantee and both reach AWS — `GetBucketLocation` can be
|
|
8226
|
+
* denied or throttled. Without the wrap, that rejection escaped at
|
|
8227
|
+
* `gc.ts`'s call site and skipped the `✓ Deleted ...` line after the delete
|
|
8228
|
+
* had already succeeded, which is precisely the outcome the comment there
|
|
8229
|
+
* says is impossible.
|
|
8230
|
+
*/
|
|
8231
|
+
async purgeNoncurrentVersions(keys, options = {}) {
|
|
8232
|
+
if (keys.length === 0) return;
|
|
8233
|
+
try {
|
|
8234
|
+
await this.ensureClientForBucket();
|
|
8235
|
+
await purgeNoncurrentKeyVersions(this.s3Client, this.config.bucket, keys, {
|
|
8236
|
+
...options,
|
|
8237
|
+
requestFields: await this.ownerParam(),
|
|
8238
|
+
logger: this.logger
|
|
8239
|
+
});
|
|
8240
|
+
} catch (error) {
|
|
8241
|
+
this.logger.warn(`Could not purge noncurrent versions of ${keys.length} key(s) in bucket '${this.config.bucket}': the purge could not be started. Their previous versions survive and remain readable via GetObject with a VersionId. Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the key(s) by hand. Underlying error: ${error instanceof Error ? error.message : String(error)}`);
|
|
8242
|
+
}
|
|
8243
|
+
}
|
|
8244
|
+
/**
|
|
8068
8245
|
* Load the rollback journal for a stack (issue #1183). Returns `null` when
|
|
8069
8246
|
* no journal exists (the common case — a journal only lives between a
|
|
8070
8247
|
* failed/interrupted deploy and its `cdkd rollback`). Throws
|
|
@@ -16125,21 +16302,71 @@ function collectReferencedParameterNames(template) {
|
|
|
16125
16302
|
* all -- it has already failed.
|
|
16126
16303
|
* - {@link IntrinsicFunctionResolver.subPlaceholderNamesADeclaredTemplateEntity}
|
|
16127
16304
|
* answers for the callers that CATCH that error and resolve anyway.
|
|
16128
|
-
* `cdkd import
|
|
16129
|
-
*
|
|
16130
|
-
*
|
|
16131
|
-
*
|
|
16305
|
+
* `cdkd import` is the live one -- EVERY mode of it, not only
|
|
16306
|
+
* `--migrate-from-cloudformation`: `resolveImportedProperties` sits on
|
|
16307
|
+
* `importCommand`'s unconditional flow, so auto / selective / hybrid all
|
|
16308
|
+
* reach it. It logs the parameter-resolution failure, RETRIES over the
|
|
16309
|
+
* template's `Default`-carrying parameters alone (issue
|
|
16310
|
+
* [#2321](https://github.com/go-to-k/cdkd/issues/2321)), and resolves
|
|
16311
|
+
* against that partial bag on a context that is NOT `bestEffort`. The
|
|
16312
|
+
* retry binds every parameter it can, and a parameter with no `Default` is
|
|
16313
|
+
* exactly what it cannot bind -- so this population still arrives here,
|
|
16314
|
+
* and a `${Tier}` over such a parameter used to be written verbatim into
|
|
16315
|
+
* the imported resource's persisted properties, and from there into the
|
|
16132
16316
|
* next deploy's desired bag, which is how the literal reaches AWS.
|
|
16317
|
+
* (The fixtures spell that parameter `Stage`; this doc says `Tier` because
|
|
16318
|
+
* `import.ts`'s own #2321 comments use `Stage` for the opposite role -- the
|
|
16319
|
+
* parameter that DOES carry a `Default` -- and one name for both roles in
|
|
16320
|
+
* one change is how a reader mis-reads which population is which.)
|
|
16321
|
+
* Before #2321 that caller continued with an EMPTY bag instead; the note
|
|
16322
|
+
* below turns on the difference, and on what survives it.
|
|
16133
16323
|
*
|
|
16134
16324
|
* A key PRESENT with an `undefined` value is not a binding: `resolveParameters`
|
|
16135
16325
|
* falls through such a key to the `Default` check, so the predicate must too.
|
|
16136
16326
|
* That single edge is the reason this is shared code and not a paraphrase.
|
|
16137
16327
|
*
|
|
16138
16328
|
* A `Default`-carrying parameter the caller never merged is DELIBERATELY not
|
|
16139
|
-
* in this population
|
|
16140
|
-
*
|
|
16141
|
-
*
|
|
16142
|
-
*
|
|
16329
|
+
* in this population, and issue
|
|
16330
|
+
* [#2321](https://github.com/go-to-k/cdkd/issues/2321) NARROWED the population
|
|
16331
|
+
* that reaches here without emptying it. Both halves matter, and an earlier
|
|
16332
|
+
* revision of this paragraph shipped only the first, claiming the exclusion
|
|
16333
|
+
* "describes a population that no live path produces". That was FALSE, and the
|
|
16334
|
+
* counter-example is in the very change that prompted the rewrite.
|
|
16335
|
+
*
|
|
16336
|
+
* What #2321 fixed is `import`'s retry SUCCESS path. `resolveParameters`
|
|
16337
|
+
* merges every `Default` it sees on the path that succeeds; `import` is the
|
|
16338
|
+
* one caller that catches its throw on a non-`bestEffort` context, and it now
|
|
16339
|
+
* retries over exactly the `Default`-carrying parameters instead of continuing
|
|
16340
|
+
* with an empty bag, so a `Default`-carrying parameter reaching the refusing
|
|
16341
|
+
* site from THAT path arrives BOUND. (`diff-recursive` and `scrub` also catch,
|
|
16342
|
+
* but both set `bestEffort: true` and `rethrowStructuralSubFailure` returns on
|
|
16343
|
+
* that flag BEFORE consulting this predicate, so neither reaches the refusing
|
|
16344
|
+
* site at all; `deploy-engine` does not catch.)
|
|
16345
|
+
*
|
|
16346
|
+
* What SURVIVES is `import`'s retry FAILURE path, and it is a live producer,
|
|
16347
|
+
* not a hypothetical one. When the `Default`-only retry itself throws -- an
|
|
16348
|
+
* SSM-typed default whose `GetParameter` is rejected is the reachable case --
|
|
16349
|
+
* `resolveImportedProperties` falls back to an empty bag rather than aborting
|
|
16350
|
+
* an import that already succeeded against AWS, and `import.ts` omits the
|
|
16351
|
+
* `parameters` key entirely when the bag is empty, so the context arrives with
|
|
16352
|
+
* `parameters: undefined`. A `Default`-carrying parameter is then unbound at
|
|
16353
|
+
* the refusing site, and this exclusion is the ONLY thing standing between it
|
|
16354
|
+
* and a refusal.
|
|
16355
|
+
*
|
|
16356
|
+
* So the clause below is PRESENT-TENSE LOAD-BEARING, not a courtesy kept for
|
|
16357
|
+
* some future caller: that fallback path exists right now, and the clause is
|
|
16358
|
+
* what keeps a `Default`-carrying parameter off the refusing site on it.
|
|
16359
|
+
* What removing the clause would DO downstream is deliberately not asserted
|
|
16360
|
+
* here -- it was not probed, and the residual note below is what carries the
|
|
16361
|
+
* observable consequence. It is also what
|
|
16362
|
+
* {@link IntrinsicFunctionResolver.subPlaceholderNamesADeclaredTemplateEntity}
|
|
16363
|
+
* cross-references.
|
|
16364
|
+
*
|
|
16365
|
+
* The cost of that fallback is that the #2321 defect persists on it -- the
|
|
16366
|
+
* placeholder is kept and written verbatim -- which is a KNOWN residual rather
|
|
16367
|
+
* than an oversight; `import.ts` records it at the fallback, and
|
|
16368
|
+
* `tests/unit/cli/import.test.ts` pins it so the residual cannot widen
|
|
16369
|
+
* silently.
|
|
16143
16370
|
*/
|
|
16144
16371
|
function isUnboundTemplateParameter(name, template, boundParameters) {
|
|
16145
16372
|
const declaredParameters = template?.Parameters;
|
|
@@ -17616,12 +17843,11 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
17616
17843
|
* `Parameter <name> is required ...` for exactly the same population up
|
|
17617
17844
|
* front -- so on a plain `cdkd deploy` this arm is unreachable by
|
|
17618
17845
|
* construction, and what it actually covers is the caller that CATCHES that
|
|
17619
|
-
* error and resolves anyway (`cdkd import
|
|
17620
|
-
*
|
|
17846
|
+
* error and resolves anyway (`cdkd import`, in every mode, on a context that
|
|
17847
|
+
* is not `bestEffort`).
|
|
17621
17848
|
*
|
|
17622
17849
|
* A parameter carrying a `Default` the caller never merged stays OUT, for
|
|
17623
|
-
* the reason recorded on the shared predicate
|
|
17624
|
-
* hard-fail input cdkd accepts today.
|
|
17850
|
+
* the reason recorded on the shared predicate.
|
|
17625
17851
|
*
|
|
17626
17852
|
* An earlier revision excluded parameters WHOLESALE and justified that by
|
|
17627
17853
|
* "the routine `cdkd scrub` case (it takes no `--parameters`)". That reason
|
|
@@ -20009,7 +20235,7 @@ var CloudControlProvider = class {
|
|
|
20009
20235
|
await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
20010
20236
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
20011
20237
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
20012
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
20238
|
+
const { ASGProvider } = await import("./asg-provider-lbqsxGkM.js").then((n) => n.n);
|
|
20013
20239
|
return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
20014
20240
|
}
|
|
20015
20241
|
const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
|
|
@@ -22891,16 +23117,37 @@ var CustomResourceProvider = class CustomResourceProvider {
|
|
|
22891
23117
|
return `${this.responsePrefix}/${requestId}.json`;
|
|
22892
23118
|
}
|
|
22893
23119
|
/**
|
|
22894
|
-
* Cleanup response object from S3
|
|
23120
|
+
* Cleanup response object from S3.
|
|
23121
|
+
*
|
|
23122
|
+
* TWO steps, and the second one is not housekeeping (issue
|
|
23123
|
+
* [#2340](https://github.com/go-to-k/cdkd/issues/2340)). `cdkd bootstrap`
|
|
23124
|
+
* turns VERSIONING ON for the state bucket, so a bare `DeleteObject` writes
|
|
23125
|
+
* a DELETE MARKER and leaves every prior version readable through
|
|
23126
|
+
* `GetObject` with a `VersionId`. The object at this key is not a
|
|
23127
|
+
* placeholder by then: the handler replied through the pre-signed
|
|
23128
|
+
* ResponseURL and PUT its FULL cfn-response body there, `Data` included —
|
|
23129
|
+
* which is exactly where a handler-minted secret (a generated password, an
|
|
23130
|
+
* issued API key) lives. Delete-only cleanup therefore reports success while
|
|
23131
|
+
* the secret stays retrievable by anyone holding `s3:GetObjectVersion` on
|
|
23132
|
+
* the state bucket.
|
|
23133
|
+
*
|
|
23134
|
+
* The purge itself lives in `purgeNoncurrentKeyVersions`, SHARED with `cdkd
|
|
23135
|
+
* gc`'s sweep of the abandoned objects at this same prefix — see that
|
|
23136
|
+
* module for why it is scoped to the exact key and to what is not
|
|
23137
|
+
* `IsLatest`, and why it never throws.
|
|
22895
23138
|
*/
|
|
22896
23139
|
async cleanupResponseObject(responseKey) {
|
|
22897
23140
|
if (!this.responseBucket) return;
|
|
23141
|
+
const bucket = this.responseBucket;
|
|
22898
23142
|
try {
|
|
22899
23143
|
await this.s3Client.send(new DeleteObjectCommand({
|
|
22900
|
-
Bucket:
|
|
23144
|
+
Bucket: bucket,
|
|
22901
23145
|
Key: responseKey
|
|
22902
23146
|
}));
|
|
22903
|
-
} catch {
|
|
23147
|
+
} catch (error) {
|
|
23148
|
+
this.logger.debug(`Failed to delete custom-resource response object s3://${bucket}/${responseKey}; it remains as a current object. Underlying error: ${error instanceof Error ? error.message : String(error)}`);
|
|
23149
|
+
}
|
|
23150
|
+
await purgeNoncurrentKeyVersions(this.s3Client, bucket, [responseKey], { logger: this.logger });
|
|
22904
23151
|
}
|
|
22905
23152
|
/**
|
|
22906
23153
|
* Convert property values to strings for CloudFormation compatibility
|
|
@@ -31903,4 +32150,4 @@ var DeployEngine = class {
|
|
|
31903
32150
|
|
|
31904
32151
|
//#endregion
|
|
31905
32152
|
export { maskerOrIdentity as $, CFN_TEMPLATE_URL_LIMIT as $n, redactSecretsForState as $t, renderStatefulReason as A, buildDockerImage as An, ResourceTimeoutError as Ar, classifyReplaySecretRegion as At, exportAliasCollisionScrubWarning as B, synthesisStatusMessage as Bn, isMarkedNonRetryable as Br, describeTypeWithThrottleRetry as Bt, isFinalSnapshotError as C, isCrossRegionRedirect as Cn, LocalMigrateError as Cr, configBooleanRefusal as Ct, extractDeploymentEventError as D, validateContainerRepoName as Dn, NestedStackChildDirectDestroyError as Dr, requireConfigArray as Dt, makeCanonicalizePropertiesFn as E, validateAssetBucketName as En, MissingCdkCliError as Er, replayWarn as Et, green as F, runDockerForeground as Fn, SynthesisError as Fr, s3BucketRegionalDomainName as Ft, IAMRoleProvider as G, resolveCaptureObservedState as Gn, retryClassificationText as Gr, STATE_SOURCED_READBACK_RULES as Gt, secretBearingStateKeyWarning as H, getLegacyStateBucketName as Hn, isThrottlingError as Hr, DagBuilder as Ht, red as I, runDockerStreaming as In, formatError as Ir, s3BucketWebsiteUrl as It, ProviderRegistry as J, resolveStateBucketWithDefaultAndSource as Jn, dynamicReferenceTokens as Jt, collectInlinePolicyNamesManagedBySiblings as K, resolveSkipPrefix as Kn, __exportAll as Kr, TEMPLATE_SOURCED_RULES as Kt, yellow as L, AssetManifestLoader as Ln, isCdkdError as Lr, applyRoleArnIfSet as Lt, bold as M, formatDockerLoginError as Mn, StackHasActiveImportsError as Mr, s3BucketArn as Mt, cyan as N, getDockerCmd as Nn, StackTerminationProtectionError as Nr, s3BucketDomainName as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, buildDenyExternalAccessPolicy as On, PartialFailureError as Or, requireConfigObject as Ot, gray as P, partitionSensitiveEnv as Pn, StateError as Pr, s3BucketDualStackDomainName as Pt, maskDeep as Q, CFN_TEMPLATE_BODY_LIMIT as Qn, maskSecretsInText as Qt, collectDeclaredOutputNames as R, getDockerImageBySourceHash as Rn, normalizeAwsError as Rr, DiffCalculator as Rt, createPreDeleteFinalSnapshot as S, getBootstrapMarkerKey as Sn, LocalInvokeBuildError as Sr, coerceCfnBoolean as St, unsupportedFinalSnapshotError as T, readBootstrapMarkerBody as Tn, LockError as Tr, readConfigString as Tt, stateKeySecretExposure as U, resolveApp as Un, markNonRetryable as Ur, TemplateParser as Ut, isExportAliasCollision as V, getDefaultStateBucketName as Vn, isRetryableTransientError as Vr, withRetry as Vt, getCurrentResourceSecrets as W, resolveAutoAssetStorage as Wn, markRedactedCause as Wr, STATE_SOURCED_CROSS_GENERATION_RULES as Wt, findSilentDropProperties as X, stateBucketExistenceConfirmed as Xn, isSingleDynamicReferenceToken as Xt, findActionableSilentDrops as Y, resolveUseCdkBootstrapAssets as Yn, errorCauseChain as Yt, createMaskedRetryLogger as Z, warnDeprecatedNoPrefixCliFlag as Zn, maskSecretsInError as Zt, computeImplicitDeleteEdges as _, stripControlChars as _n, ConfigError as _r, refStateLookupFromResource as _t, DeploymentEventsStore as a, exportNamesCarriedFrom as an, canonicalizeRegion as ar, isInterruptedWaitError as at, buildFinalSnapshotIdentifier as b, assertAssetBucketRegion as bn, DeployCancelledError as br, resolveExplicitPhysicalId as bt, replayFailedOperations as c, shouldRetainResource as cn, processStackMessages as cr, slowCcOperationTimeoutMs as ct, updatePartialReason as d, WorkGraph as dn, AwsClients as dr, IntrinsicFunctionResolver as dt, scrubResourceRecord as en, MIGRATE_TMP_PREFIX as er, CUSTOM_RESOURCE_RESPONSE_PREFIX as et, UNSPECIFIED_SKIP_REASON as f, buildAssetRedirectMap as fn, getAwsClients as fr, carriesDynamicReference as ft, IMPLICIT_DELETE_DEPENDENCIES as g, escapeRegExp$1 as gn, CdkdError as gr, parameterTypeMayLoseSecretIdentity as gt, maskingRetryLogger as h, rewriteTemplateAssetReferences as hn, AssetError as hr, isUnboundTemplateParameter as ht, DeploymentEventsReader as i, rebuildClientForBucketRegion as in, PARTITION_TABLE as ir, interruptWatchListenerCount as it, formatResourceLine as j, dockerSpawnEnvWithSensitive as jn, ResourceUpdateNotSupportedError as jr, producerRegionsFromState as jt, isStatefulRecreateTargetSync as k, describeAwsFailure as kn, ProvisioningError as kr, requireConfigString as kt, replayRollback as l, AssetPublisher as ln, clearBucketRegionCache as lr, disableInstanceApiTermination as lt, withResourceDeadline as m, loadPublishableAssetManifest as mn, setAwsClients as mr, getAccountInfo as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, displaySafe as nn, uploadCfnTemplate as nr, beginCommandInterruptScope as nt, planFailedOps as o, importableOutputKeys as on, derivePartitionAndUrlSuffix as or, startInterruptWatch as ot, deleteSkipReason as p, createAssetRedirectResolver as pn, resetAwsClients as pr, cfnRefValueFromPhysicalId as pt, clearOnUpdateRemoval as q, resolveStateBucketWithDefault as qn, createSecretMasker as qt, DeployEngine as r, S3StateBackend as rn, expectedOwnerParam as rr, endCommandInterruptScope as rt, planRollback as s, importableOutputs as sn, AssemblyReader as sr, CloudControlProvider as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, LockManager as tn, findLargeInlineResources as tr, DEFAULT_STATE_PREFIX as tt, updatePartialMessage as u, stringifyValue as un, resolveBucketRegion as ur, isTerminationProtectionPropagationError as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, AssetModeResolver as vn, CrossAccountSecretRefusalError as vr, WAFv2WebACLProvider as vt, refusesFinalSnapshot as w, parseBootstrapMarker as wn, LocalStartServiceError as wr, configStringRefusal as wt, ccRoutedFinalSnapshotError as x, ensureAssetStorage as xn, DynamicReferenceRegionAmbiguousError as xr, assertRegionMatch as xt, PRE_DELETE_SNAPSHOT_TYPES as y, BOOTSTRAP_MARKER_PREFIX as yn, DependencyError as yr, normalizeAwsTagsToCfn as yt, collectPublishedOutputNames as z, Synthesizer as zn, withErrorHandling as zr, INTRINSIC_KEYS as zt };
|
|
31906
|
-
//# sourceMappingURL=deploy-engine-
|
|
32153
|
+
//# sourceMappingURL=deploy-engine-Dsd8oL2h.js.map
|