@go-to-k/cdkd 0.284.18 → 0.284.20
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-IPF2MfAC.js → asg-provider-Cq-oDB62.js} +2 -2
- package/dist/{asg-provider-IPF2MfAC.js.map → asg-provider-Cq-oDB62.js.map} +1 -1
- package/dist/cli.js +16 -55
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-HK-oROJf.js → deploy-engine-C6gt7NcL.js} +237 -23
- package/dist/deploy-engine-C6gt7NcL.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-HK-oROJf.js.map +0 -1
|
@@ -5450,6 +5450,68 @@ function getBootstrapMarkerKey(region) {
|
|
|
5450
5450
|
return `${BOOTSTRAP_MARKER_PREFIX}${region}.json`;
|
|
5451
5451
|
}
|
|
5452
5452
|
/**
|
|
5453
|
+
* Read a region's bootstrap marker, probing the CANONICAL key first and the
|
|
5454
|
+
* region's RAW spelling second (issues #1836 / #1995 / #2021).
|
|
5455
|
+
*
|
|
5456
|
+
* Why two probes: the READ side folds region case (SDK endpoint resolution is
|
|
5457
|
+
* case-sensitive, and folding also keeps one region from occupying two cache
|
|
5458
|
+
* slots), but the WRITE side does not — `cdkd bootstrap` derives its region as
|
|
5459
|
+
* `options.region || AWS_REGION || 'us-east-1'` verbatim and uses that spelling
|
|
5460
|
+
* for {@link getBootstrapMarkerKey}. Aligning the write side is issue #1820's
|
|
5461
|
+
* lane; until then this read is independent of it.
|
|
5462
|
+
*
|
|
5463
|
+
* HOW REACHABLE the raw key actually is (measured for #2021, because this PR
|
|
5464
|
+
* turns the probe into a SHARED contract for four callers and the earlier
|
|
5465
|
+
* per-caller comments overstated it). A plain `AWS_REGION=US-EAST-1 cdkd
|
|
5466
|
+
* bootstrap` CANNOT write `cdkd-bootstrap/US-EAST-1.json`: the marker is
|
|
5467
|
+
* written LAST, and both resources have to be created first with names derived
|
|
5468
|
+
* from that same raw region — `getCdkdAssetBucketName` yields
|
|
5469
|
+
* `cdkd-assets-<acct>-US-EAST-1`, which S3 rejects as a bucket name, and
|
|
5470
|
+
* `region !== 'us-east-1'` is true for `US-EAST-1` so `CreateBucket` is also
|
|
5471
|
+
* handed `LocationConstraint: 'US-EAST-1'`, an invalid enum value. The
|
|
5472
|
+
* conventional name is never run through `validateAssetBucketName` (that guards
|
|
5473
|
+
* only `--asset-bucket`), so it fails at S3 rather than earlier. The raw key is
|
|
5474
|
+
* therefore reachable only when ALL of these hold:
|
|
5475
|
+
*
|
|
5476
|
+
* 1. both `--asset-bucket` and `--container-repo` are given as valid lowercase
|
|
5477
|
+
* names, so neither conventional name is derived from the raw region; AND
|
|
5478
|
+
* 2. the asset bucket ALREADY EXISTS and is owned by this account, so the
|
|
5479
|
+
* `CreateBucket` carrying the bad `LocationConstraint` is never issued;
|
|
5480
|
+
*
|
|
5481
|
+
* plus, outside that flow, a marker written by hand or by a cdkd predating
|
|
5482
|
+
* those guards. Probe 2 is kept rather than dropped because that state is real
|
|
5483
|
+
* and losing it silently re-points a bootstrapped region at `cdk gc`-collectable
|
|
5484
|
+
* storage — the exact #2021 failure — while the cost is one extra `GetObject`
|
|
5485
|
+
* on a non-canonical region only. It is skipped entirely when the region was
|
|
5486
|
+
* already canonical, so the common path still costs exactly one `GetObject`.
|
|
5487
|
+
* Both conditions are pinned by tests, so this claim cannot rot silently.
|
|
5488
|
+
*
|
|
5489
|
+
* This helper deliberately does NOT catch: each caller keeps its own policy on
|
|
5490
|
+
* top (`cdkd gc` / `cdkd bootstrap --destroy` translate `NoSuchBucket` into a
|
|
5491
|
+
* "never bootstrapped" message and hard-error on anything else;
|
|
5492
|
+
* `loadBootstrapContainerRepo` is best-effort and warns-and-falls-back).
|
|
5493
|
+
*/
|
|
5494
|
+
async function readBootstrapMarkerBody(stateBackend, rawRegion, opts = {}) {
|
|
5495
|
+
const canonicalKey = getBootstrapMarkerKey(canonicalizeRegion(rawRegion));
|
|
5496
|
+
const rawKey = getBootstrapMarkerKey(rawRegion);
|
|
5497
|
+
const body = await stateBackend.getRawObject(canonicalKey);
|
|
5498
|
+
if (body !== null || rawKey === canonicalKey) return {
|
|
5499
|
+
body,
|
|
5500
|
+
resolvedKey: canonicalKey
|
|
5501
|
+
};
|
|
5502
|
+
const rawBody = await stateBackend.getRawObject(rawKey);
|
|
5503
|
+
if (rawBody === null) return {
|
|
5504
|
+
body: null,
|
|
5505
|
+
resolvedKey: canonicalKey
|
|
5506
|
+
};
|
|
5507
|
+
const subject = opts.logPrefix ? `${opts.logPrefix}: bootstrap marker` : "Bootstrap marker";
|
|
5508
|
+
getLogger().debug(`${subject} found at the un-folded key '${rawKey}' (none at '${canonicalKey}') — an upper-cased region was used at 'cdkd bootstrap' time.`);
|
|
5509
|
+
return {
|
|
5510
|
+
body: rawBody,
|
|
5511
|
+
resolvedKey: rawKey
|
|
5512
|
+
};
|
|
5513
|
+
}
|
|
5514
|
+
/**
|
|
5453
5515
|
* Pragmatic S3 bucket-name check for `cdkd bootstrap --asset-bucket`
|
|
5454
5516
|
* (issue #1011): 3-63 chars, lowercase letters / digits / dots / hyphens,
|
|
5455
5517
|
* starting and ending with a letter or digit. Rejecting before any AWS call
|
|
@@ -5705,6 +5767,15 @@ async function ensureAssetStorage(options) {
|
|
|
5705
5767
|
var AssetModeResolver = class {
|
|
5706
5768
|
logger = getLogger().child("AssetMode");
|
|
5707
5769
|
cache = /* @__PURE__ */ new Map();
|
|
5770
|
+
/**
|
|
5771
|
+
* NOT load-bearing today — defense-in-depth only. `resolve` sets `cache`
|
|
5772
|
+
* synchronously before the first await, so `doResolve` runs at most once per
|
|
5773
|
+
* canonical region, and the notice arm always returns successfully so the
|
|
5774
|
+
* failure-eviction path cannot re-enter it. This Set was already ineffective
|
|
5775
|
+
* BEFORE the issue #2021 fold (two spellings simply made two entries), so it
|
|
5776
|
+
* is not a regression that fold introduced. Kept so removing or bypassing the
|
|
5777
|
+
* cache cannot silently turn the notice into one line per resolve.
|
|
5778
|
+
*/
|
|
5708
5779
|
legacyNoticeShownRegions = /* @__PURE__ */ new Set();
|
|
5709
5780
|
stateBackend;
|
|
5710
5781
|
accountId;
|
|
@@ -5723,24 +5794,37 @@ var AssetModeResolver = class {
|
|
|
5723
5794
|
/**
|
|
5724
5795
|
* Resolve the asset mode for a deploy region. Concurrent callers for the
|
|
5725
5796
|
* same region share one in-flight resolution.
|
|
5797
|
+
*
|
|
5798
|
+
* The region arrives UNFOLDED (issue #2021): both deploy-time callers derive
|
|
5799
|
+
* it as `options.region || AWS_REGION || 'us-east-1'` and then
|
|
5800
|
+
* `stack.region || baseRegion`, so an env-agnostic stack under
|
|
5801
|
+
* `--region US-EAST-1` (or `AWS_REGION=US-EAST-1`) hands an upper-cased
|
|
5802
|
+
* spelling straight through. A stack whose `env.region` is pinned in CDK is
|
|
5803
|
+
* unaffected — `stack.region` comes from the Cloud Assembly and is canonical.
|
|
5804
|
+
*
|
|
5805
|
+
* Folding at THIS boundary rather than at each caller fixes two things at
|
|
5806
|
+
* once: the marker read below (which used to miss `cdkd-bootstrap/
|
|
5807
|
+
* us-east-1.json` and silently downgrade the whole region to LEGACY —
|
|
5808
|
+
* `cdk gc`-collectable — storage), and the CACHE, where `us-east-1` and
|
|
5809
|
+
* `US-EAST-1` occupied two slots and each re-probed S3.
|
|
5726
5810
|
*/
|
|
5727
|
-
resolve(
|
|
5811
|
+
resolve(rawRegion) {
|
|
5728
5812
|
if (this.useCdkBootstrapAssets) return Promise.resolve({ mode: "legacy" });
|
|
5813
|
+
const region = canonicalizeRegion(rawRegion);
|
|
5729
5814
|
const cached = this.cache.get(region);
|
|
5730
5815
|
if (cached) return cached;
|
|
5731
|
-
const inFlight = this.doResolve(region).catch((error) => {
|
|
5816
|
+
const inFlight = this.doResolve(region, rawRegion).catch((error) => {
|
|
5732
5817
|
this.cache.delete(region);
|
|
5733
5818
|
throw error;
|
|
5734
5819
|
});
|
|
5735
5820
|
this.cache.set(region, inFlight);
|
|
5736
5821
|
return inFlight;
|
|
5737
5822
|
}
|
|
5738
|
-
async doResolve(region) {
|
|
5739
|
-
const
|
|
5740
|
-
const body = await this.stateBackend.getRawObject(markerKey);
|
|
5823
|
+
async doResolve(region, rawRegion) {
|
|
5824
|
+
const { body, resolvedKey } = await readBootstrapMarkerBody(this.stateBackend, rawRegion);
|
|
5741
5825
|
if (body === null) {
|
|
5742
5826
|
if (this.autoCreate) {
|
|
5743
|
-
const created = await this.tryAutoCreate(region,
|
|
5827
|
+
const created = await this.tryAutoCreate(region, getBootstrapMarkerKey(region));
|
|
5744
5828
|
if (created) return created;
|
|
5745
5829
|
}
|
|
5746
5830
|
if (!this.legacyNoticeShownRegions.has(region) && !this.suppressLegacyNotice) {
|
|
@@ -5749,7 +5833,7 @@ var AssetModeResolver = class {
|
|
|
5749
5833
|
}
|
|
5750
5834
|
return { mode: "legacy" };
|
|
5751
5835
|
}
|
|
5752
|
-
const marker = parseBootstrapMarker(body,
|
|
5836
|
+
const marker = parseBootstrapMarker(body, resolvedKey);
|
|
5753
5837
|
await verifyAssetStorageExists(marker, this.accountId, region, { ...this.profile && { profile: this.profile } });
|
|
5754
5838
|
this.logger.debug(`cdkd asset storage active for region '${region}': ${marker.assetBucket} / ${marker.containerRepo}`);
|
|
5755
5839
|
return {
|
|
@@ -10380,8 +10464,86 @@ function isKnownSecretExpression(expression, secretExpressions) {
|
|
|
10380
10464
|
return expression.startsWith("{{resolve:secretsmanager:") || secretExpressions.has(expression) || isRecordedSecretExpression(expression);
|
|
10381
10465
|
}
|
|
10382
10466
|
/**
|
|
10383
|
-
*
|
|
10384
|
-
*
|
|
10467
|
+
* The character class a `{{resolve:...}}` reference's INNER text is built from,
|
|
10468
|
+
* and the SINGLE SOURCE OF TRUTH every dynamic-reference predicate in cdkd
|
|
10469
|
+
* derives from (issue
|
|
10470
|
+
* [#1936](https://github.com/go-to-k/cdkd/issues/1936)).
|
|
10471
|
+
*
|
|
10472
|
+
* **THE AUTHORITY IS THE RESOLVER.**
|
|
10473
|
+
* `IntrinsicFunctionResolver.resolveDynamicReferences`
|
|
10474
|
+
* (`src/deployment/intrinsic-function-resolver.ts`) scans with
|
|
10475
|
+
* `/\{\{resolve:([^}]+)\}\}/g`, so what cdkd will actually RESOLVE is exactly
|
|
10476
|
+
* `{{resolve:` followed by one or more non-`}` characters followed by `}}`.
|
|
10477
|
+
* A predicate that answers a different question than that scan is answering
|
|
10478
|
+
* about a string the resolver already substituted a value INTO, which is how a
|
|
10479
|
+
* leaf ends up classified as "not a token" while holding the plaintext the
|
|
10480
|
+
* resolver put there.
|
|
10481
|
+
*
|
|
10482
|
+
* Three sites disagreed before this constant existed, and the STRICTEST of them
|
|
10483
|
+
* was the one that persisted plaintext. `isSingleDynamicReferenceToken` here and
|
|
10484
|
+
* `isWholeDynamicReference` in `src/cli/commands/drift.ts` both spelled the
|
|
10485
|
+
* inner class `[^{}]*`, while `survivingDynamicReferences` (same file) spelled
|
|
10486
|
+
* it `[^}]+` to match the resolver. For a reference whose inner text contains a
|
|
10487
|
+
* `{` — a Secrets Manager JSON key or a secret name, e.g.
|
|
10488
|
+
* `{{resolve:secretsmanager:app/db:SecretString:my{key}}` — the resolver
|
|
10489
|
+
* resolves it fine, but the strict spelling said it was not a single token, so
|
|
10490
|
+
* `redactByPath`'s source arm refused it and on an EMPTY-map path the RESOLVED
|
|
10491
|
+
* PLAINTEXT was persisted verbatim. A disclosure, narrow and pre-existing.
|
|
10492
|
+
*
|
|
10493
|
+
* `cdkd scrub` is the only leaking command, and it leaks on BOTH of its walks
|
|
10494
|
+
* -- the second one named after the issue #2088 security review, which found
|
|
10495
|
+
* the first draft of this note incomplete:
|
|
10496
|
+
*
|
|
10497
|
+
* - the `properties` walk under `TEMPLATE_SOURCED_RULES`, where
|
|
10498
|
+
* `isKnownSecretExpression` answers true by SPELLING but the strict
|
|
10499
|
+
* predicate refused the leaf before it could; and
|
|
10500
|
+
* - the cross-generation `observedProperties` walk, whose value scan has no
|
|
10501
|
+
* needles (issue #1900).
|
|
10502
|
+
*
|
|
10503
|
+
* The empty map is reachable on both because `scrub.ts` resolves BEST-EFFORT
|
|
10504
|
+
* (a deleted secret, or a role lacking read permission on it, leaves
|
|
10505
|
+
* `recordedSecretValues` empty) and then records `perResourceTemplateProps`
|
|
10506
|
+
* UNCONDITIONALLY while recording `perResourceSecrets` only when non-empty --
|
|
10507
|
+
* so the position source is present with no map beside it.
|
|
10508
|
+
*
|
|
10509
|
+
* `cdkd state refresh-observed` and the deploy's `drainObservedCaptures` are
|
|
10510
|
+
* NOT affected: they take `STATE_SOURCED_READBACK_RULES`, which sets
|
|
10511
|
+
* `sourceIsSameGeneration`, so {@link refuseUncertifiedReadbackPositions}
|
|
10512
|
+
* restores the source even under the old strict class.
|
|
10513
|
+
*
|
|
10514
|
+
* Excluding `{` bought nothing. The mangled / concatenated shapes it might seem
|
|
10515
|
+
* to guard — `{{resolve:a}}{{resolve:b}}`, a spliced token — are already
|
|
10516
|
+
* rejected by `[^}]+` under an ANCHORED pattern, because the class cannot cross
|
|
10517
|
+
* the first `}`. (A claim that `[^}]+` would let `{{resolve:a}}{{resolve:b}}`
|
|
10518
|
+
* through circulated in review and is FALSE: that string does not match
|
|
10519
|
+
* `^\{\{resolve:[^}]+\}\}$` either.) The only strings the two spellings
|
|
10520
|
+
* classify differently are the ones with a `{` inside a single token, i.e.
|
|
10521
|
+
* exactly the disclosure above.
|
|
10522
|
+
*
|
|
10523
|
+
* `+` rather than `*` for the same reason: `{{resolve:}}` is not something the
|
|
10524
|
+
* resolver would try to resolve, so nothing here may call it a token.
|
|
10525
|
+
*
|
|
10526
|
+
* The class is exported as a STRING rather than as a finished `RegExp` because
|
|
10527
|
+
* three different pattern shapes are built from it — anchored, global, and
|
|
10528
|
+
* {@link SKELETON_WILDCARD}'s zero-or-more form — and a shared global `RegExp`
|
|
10529
|
+
* instance would carry `lastIndex` across callers.
|
|
10530
|
+
*/
|
|
10531
|
+
const DYNAMIC_REFERENCE_INNER_CHAR = "[^}]";
|
|
10532
|
+
/**
|
|
10533
|
+
* The inner-text pattern fragment of a complete `{{resolve:...}}` reference,
|
|
10534
|
+
* byte-identical to the resolver's own `([^}]+)` capture. See
|
|
10535
|
+
* {@link DYNAMIC_REFERENCE_INNER_CHAR} for why this is one constant.
|
|
10536
|
+
*/
|
|
10537
|
+
const DYNAMIC_REFERENCE_INNER = `${DYNAMIC_REFERENCE_INNER_CHAR}+`;
|
|
10538
|
+
/**
|
|
10539
|
+
* Anchored: the WHOLE string is one complete `{{resolve:...}}` token.
|
|
10540
|
+
*
|
|
10541
|
+
* A non-global `RegExp`, so `.test` carries no `lastIndex` state and the shared
|
|
10542
|
+
* instance is safe to reuse.
|
|
10543
|
+
*/
|
|
10544
|
+
const WHOLE_DYNAMIC_REFERENCE_PATTERN = new RegExp(`^\\{\\{resolve:${DYNAMIC_REFERENCE_INNER}\\}\\}$`);
|
|
10545
|
+
/**
|
|
10546
|
+
* Is this leaf a SINGLE complete `{{resolve:...}}` token and nothing else?
|
|
10385
10547
|
*
|
|
10386
10548
|
* Whole-leaf substitution is only correct for that shape. A MIXED leaf --
|
|
10387
10549
|
* `pre{{resolve:ssm:/public}}-{{resolve:secretsmanager:x}}post`, i.e. anything
|
|
@@ -10389,9 +10551,15 @@ function isKnownSecretExpression(expression, secretExpressions) {
|
|
|
10389
10551
|
* scan, which rewrites just the secret substring. Substituting the whole leaf
|
|
10390
10552
|
* there would re-introduce every other token in it, including a public ssm
|
|
10391
10553
|
* reference the resolver deliberately left resolved (issue #1901).
|
|
10554
|
+
*
|
|
10555
|
+
* EXPORTED since issue #1936 so `src/cli/commands/drift.ts` can consume this
|
|
10556
|
+
* one definition instead of carrying a hand-copied twin. Its copy's own comment
|
|
10557
|
+
* said "copied rather than imported because that helper is module-private and
|
|
10558
|
+
* this file may not widen that module's exports" — widening the exports is the
|
|
10559
|
+
* cheaper half of that trade once the copies have provably disagreed.
|
|
10392
10560
|
*/
|
|
10393
10561
|
function isSingleDynamicReferenceToken(value) {
|
|
10394
|
-
return
|
|
10562
|
+
return WHOLE_DYNAMIC_REFERENCE_PATTERN.test(value);
|
|
10395
10563
|
}
|
|
10396
10564
|
function isPlainObject$2(value) {
|
|
10397
10565
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -10400,14 +10568,18 @@ function isPlainObject$2(value) {
|
|
|
10400
10568
|
* Stands in for a source part the skeleton cannot know — an `Fn::Join` element
|
|
10401
10569
|
* that is itself an intrinsic, or an `Fn::Sub` `${...}` variable.
|
|
10402
10570
|
*
|
|
10403
|
-
*
|
|
10404
|
-
* contains `}`: the resolver matches
|
|
10405
|
-
* the first `}` after `{{resolve:` is
|
|
10406
|
-
* means a wildcard can never swallow one
|
|
10407
|
-
* next, so a skeleton for ONE reference
|
|
10408
|
-
* different one.
|
|
10571
|
+
* Built from {@link DYNAMIC_REFERENCE_INNER_CHAR} rather than `.` because a
|
|
10572
|
+
* recorded expression's INNER text never contains `}`: the resolver matches
|
|
10573
|
+
* them with `/\{\{resolve:([^}]+)\}\}/`, so the first `}` after `{{resolve:` is
|
|
10574
|
+
* already the terminator. Excluding it means a wildcard can never swallow one
|
|
10575
|
+
* token's terminator and run into the next, so a skeleton for ONE reference
|
|
10576
|
+
* cannot match a candidate built from a different one.
|
|
10577
|
+
*
|
|
10578
|
+
* Zero-or-more here, unlike {@link DYNAMIC_REFERENCE_INNER}: this stands in for
|
|
10579
|
+
* an unknown SPAN, which may legitimately be empty (an `Fn::Join` part that
|
|
10580
|
+
* resolved to `''`), whereas a token with no inner text is not a token.
|
|
10409
10581
|
*/
|
|
10410
|
-
const SKELETON_WILDCARD =
|
|
10582
|
+
const SKELETON_WILDCARD = `${DYNAMIC_REFERENCE_INNER_CHAR}*`;
|
|
10411
10583
|
/**
|
|
10412
10584
|
* More wildcards than this and the skeleton is REFUSED outright.
|
|
10413
10585
|
*
|
|
@@ -10863,9 +11035,51 @@ function subtreeHasDynamicReference(value) {
|
|
|
10863
11035
|
if (isPlainObject$2(value)) return Object.values(value).some(subtreeHasDynamicReference);
|
|
10864
11036
|
return false;
|
|
10865
11037
|
}
|
|
10866
|
-
/**
|
|
11038
|
+
/**
|
|
11039
|
+
* Every complete `{{resolve:...}}` token inside a string.
|
|
11040
|
+
*
|
|
11041
|
+
* This was a FOURTH spelling of the token pattern (`[^{}]*`, global) and is
|
|
11042
|
+
* built from {@link DYNAMIC_REFERENCE_INNER} since issue #1936, so it agrees
|
|
11043
|
+
* with the resolver like every other predicate here.
|
|
11044
|
+
*
|
|
11045
|
+
* EXPORTED, and `drift.ts`'s `survivingDynamicReferences` calls it rather than
|
|
11046
|
+
* re-spelling the scan (issue #2088 review). The character CLASS was shared
|
|
11047
|
+
* from #1936, but the assembled PATTERN was still byte-duplicated in the two
|
|
11048
|
+
* files — which is how a later flag or anchor change re-forks exactly the way
|
|
11049
|
+
* the four spellings did.
|
|
11050
|
+
*
|
|
11051
|
+
* The pattern is a module-level constant. An earlier revision built a fresh
|
|
11052
|
+
* `RegExp` per call, justified as "a shared global instance carries
|
|
11053
|
+
* `lastIndex` between callers" — that is FALSE for this use and was measured:
|
|
11054
|
+
* `String.prototype.match` with a `/g` pattern sets `lastIndex` to 0 on entry
|
|
11055
|
+
* and leaves it 0, so no state crosses callers. The per-call construction was
|
|
11056
|
+
* compiling a pattern per string leaf at the persist choke point, which walks
|
|
11057
|
+
* every record. Do NOT call `.exec` / `.test` on this constant — those DO
|
|
11058
|
+
* advance `lastIndex`, which is exactly why the shared instance is safe only
|
|
11059
|
+
* for `.match`.
|
|
11060
|
+
*
|
|
11061
|
+
* Widening it changes one answer, in the SAFE direction for BOTH readers.
|
|
11062
|
+
*
|
|
11063
|
+
* `drift.ts`'s `survivingDynamicReferences` is the reader that is easy to
|
|
11064
|
+
* forget, because it lives in another file — it feeds `isSecretBySpelling`,
|
|
11065
|
+
* so seeing MORE tokens can only mask more, never less. Do not shorten this
|
|
11066
|
+
* to "the only reader": that sentence is what a later editor uses to bound
|
|
11067
|
+
* the blast radius of touching the class, and getting it wrong points them
|
|
11068
|
+
* away from the report / `--json` / `--accept` path where an unmasked
|
|
11069
|
+
* `ssm-secure` survivor would surface.
|
|
11070
|
+
*
|
|
11071
|
+
* The other reader is the DECLARED direction for issue #1901:
|
|
11072
|
+
* {@link mixedLeafMayCarryPublicReference}, which asks whether a MIXED leaf
|
|
11073
|
+
* embeds a `{{resolve:ssm:` token the verdict store does not know. A token
|
|
11074
|
+
* carrying a `{` inside it used to be INVISIBLE here, so such a leaf was
|
|
11075
|
+
* always treated as secret-bearing and the source expression was substituted
|
|
11076
|
+
* over the resolved value. Now it is seen and classified by the same rule as
|
|
11077
|
+
* every other token — which, on a POPULATED map, means a genuinely public ssm
|
|
11078
|
+
* parameter keeps the resolved value it is supposed to keep.
|
|
11079
|
+
*/
|
|
11080
|
+
const DYNAMIC_REFERENCE_TOKEN_SCAN = new RegExp(`\\{\\{resolve:${DYNAMIC_REFERENCE_INNER}\\}\\}`, "g");
|
|
10867
11081
|
function dynamicReferenceTokens(value) {
|
|
10868
|
-
return value.match(
|
|
11082
|
+
return value.match(DYNAMIC_REFERENCE_TOKEN_SCAN) ?? [];
|
|
10869
11083
|
}
|
|
10870
11084
|
/**
|
|
10871
11085
|
* Does this MIXED leaf embed a reference that may be PUBLIC config?
|
|
@@ -16514,7 +16728,7 @@ var CloudControlProvider = class {
|
|
|
16514
16728
|
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);
|
|
16515
16729
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
16516
16730
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
16517
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
16731
|
+
const { ASGProvider } = await import("./asg-provider-Cq-oDB62.js").then((n) => n.n);
|
|
16518
16732
|
return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
16519
16733
|
}
|
|
16520
16734
|
const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
|
|
@@ -24687,7 +24901,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
24687
24901
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
24688
24902
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
24689
24903
|
function getCdkdVersion() {
|
|
24690
|
-
return "0.284.
|
|
24904
|
+
return "0.284.20";
|
|
24691
24905
|
}
|
|
24692
24906
|
/**
|
|
24693
24907
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -27226,5 +27440,5 @@ var DeployEngine = class {
|
|
|
27226
27440
|
};
|
|
27227
27441
|
|
|
27228
27442
|
//#endregion
|
|
27229
|
-
export { isTerminationProtectionPropagationError as $,
|
|
27230
|
-
//# sourceMappingURL=deploy-engine-
|
|
27443
|
+
export { isTerminationProtectionPropagationError as $, PartialFailureError as $n, getBootstrapMarkerKey as $t, renderStatefulReason as A, expectedOwnerParam as An, applyRoleArnIfSet as At, exportAliasCollisionScrubWarning as B, resetAwsClients as Bn, shouldRetainResource as Bt, isFinalSnapshotError as C, stateBucketExistenceConfirmed as Cn, redactSecretsForState as Ct, extractDeploymentEventError as D, MIGRATE_TMP_PREFIX as Dn, s3BucketDualStackDomainName as Dt, makeCanonicalizePropertiesFn as E, CFN_TEMPLATE_URL_LIMIT as En, s3BucketDomainName as Et, green as F, processStackMessages as Fn, DagBuilder as Ft, collectInlinePolicyNamesManagedBySiblings as G, DependencyError as Gn, createAssetRedirectResolver as Gt, secretBearingStateKeyWarning as H, AssetError as Hn, stringifyValue as Ht, red as I, clearBucketRegionCache as In, TemplateParser as It, findActionableSilentDrops as J, LocalMigrateError as Jn, escapeRegExp$1 as Jt, clearOnUpdateRemoval as K, DeployCancelledError as Kn, loadPublishableAssetManifest as Kt, yellow as L, resolveBucketRegion as Ln, LockManager as Lt, bold as M, canonicalizeRegion as Mn, INTRINSIC_KEYS as Mt, cyan as N, derivePartitionAndUrlSuffix as Nn, describeTypeWithThrottleRetry as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, findLargeInlineResources as On, s3BucketRegionalDomainName as Ot, gray as P, AssemblyReader as Pn, withRetry as Pt, disableInstanceApiTermination as Q, NestedStackChildDirectDestroyError as Qn, ensureAssetStorage as Qt, collectDeclaredOutputNames as R, AwsClients as Rn, S3StateBackend as Rt, createPreDeleteFinalSnapshot as S, resolveUseCdkBootstrapAssets as Sn, maskSecretsInText as St, unsupportedFinalSnapshotError as T, CFN_TEMPLATE_BODY_LIMIT as Tn, s3BucketArn as Tt, stateKeySecretExposure as U, CdkdError as Un, WorkGraph as Ut, isExportAliasCollision as V, setAwsClients as Vn, AssetPublisher as Vt, IAMRoleProvider as W, ConfigError as Wn, buildAssetRedirectMap as Wt, CloudControlProvider as X, LockError as Xn, AssetModeResolver as Xt, findSilentDropProperties as Y, LocalStartServiceError as Yn, stripControlChars as Yt, slowCcOperationTimeoutMs as Z, MissingCdkCliError as Zn, BOOTSTRAP_MARKER_PREFIX as Zt, computeImplicitDeleteEdges as _, resolveAutoAssetStorage as _n, STATE_SOURCED_READBACK_RULES as _t, DeploymentEventsStore as a, buildDockerImage as an, StateError as ar, normalizeAwsTagsToCfn as at, buildFinalSnapshotIdentifier as b, resolveStateBucketWithDefault as bn, dynamicReferenceTokens as bt, replayFailedOperations as c, runDockerForeground as cn, isCdkdError as cr, coerceCfnBoolean as ct, updatePartialReason as d, getDockerImageBySourceHash as dn, isMarkedNonRetryable as dr, readConfigString as dt, parseBootstrapMarker as en, ProvisioningError as er, IntrinsicFunctionResolver as et, UNSPECIFIED_SKIP_REASON as f, Synthesizer as fn, isRetryableTransientError as fr, replayWarn as ft, IMPLICIT_DELETE_DEPENDENCIES as g, resolveApp as gn, STATE_SOURCED_CROSS_GENERATION_RULES as gt, maskingRetryLogger as h, getLegacyStateBucketName as hn, __exportAll as hr, requireConfigString as ht, DeploymentEventsReader as i, buildDenyExternalAccessPolicy as in, StackTerminationProtectionError as ir, WAFv2WebACLProvider as it, formatResourceLine as j, PARTITION_TABLE as jn, DiffCalculator as jt, isStatefulRecreateTargetSync as k, uploadCfnTemplate as kn, s3BucketWebsiteUrl as kt, replayRollback as l, runDockerStreaming as ln, normalizeAwsError as lr, configBooleanRefusal as lt, withResourceDeadline as m, getDefaultStateBucketName as mn, markNonRetryable as mr, requireConfigObject as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, validateAssetBucketName as nn, ResourceUpdateNotSupportedError as nr, getAccountInfo as nt, planFailedOps as o, formatDockerLoginError as on, SynthesisError as or, resolveExplicitPhysicalId as ot, deleteSkipReason as p, synthesisStatusMessage as pn, isThrottlingError as pr, requireConfigArray as pt, ProviderRegistry as q, LocalInvokeBuildError as qn, rewriteTemplateAssetReferences as qt, DeployEngine as r, validateContainerRepoName as rn, StackHasActiveImportsError as rr, refStateLookupFromResource as rt, planRollback as s, getDockerCmd as sn, formatError as sr, assertRegionMatch as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, readBootstrapMarkerBody as tn, ResourceTimeoutError as tr, cfnRefValueFromPhysicalId as tt, updatePartialMessage as u, AssetManifestLoader as un, withErrorHandling as ur, configStringRefusal as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, resolveCaptureObservedState as vn, TEMPLATE_SOURCED_RULES as vt, refusesFinalSnapshot as w, warnDeprecatedNoPrefixCliFlag as wn, scrubResourceRecord as wt, ccRoutedFinalSnapshotError as x, resolveStateBucketWithDefaultAndSource as xn, isSingleDynamicReferenceToken as xt, PRE_DELETE_SNAPSHOT_TYPES as y, resolveSkipPrefix as yn, createSecretMasker as yt, collectPublishedOutputNames as z, getAwsClients as zn, rebuildClientForBucketRegion as zt };
|
|
27444
|
+
//# sourceMappingURL=deploy-engine-C6gt7NcL.js.map
|