@go-to-k/cdkd 0.294.9 → 0.294.11
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-3uLGAhIx.js → asg-provider-CbHiTBaE.js} +2 -2
- package/dist/{asg-provider-3uLGAhIx.js.map → asg-provider-CbHiTBaE.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-BTOCDCWf.js → deploy-engine-CMRU0DTu.js} +1877 -270
- package/dist/deploy-engine-CMRU0DTu.js.map +1 -0
- package/dist/{iam-role-provider-CBT2LPe1.js → iam-role-provider-DOKKlLrC.js} +2 -2
- package/dist/{iam-role-provider-CBT2LPe1.js.map → iam-role-provider-DOKKlLrC.js.map} +1 -1
- package/dist/index.d.ts +43 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{neptune-provider-BQ-CGoYJ.js → neptune-provider-CS-r4Ufj.js} +2 -2
- package/dist/{neptune-provider-BQ-CGoYJ.js.map → neptune-provider-CS-r4Ufj.js.map} +1 -1
- package/dist/{program-DMJnrQOG.js → program-dQFaGjL1.js} +234 -190
- package/dist/program-dQFaGjL1.js.map +1 -0
- package/dist/{provider-classes-DCbt28RB.js → provider-classes-5NUmLSTV.js} +182 -60
- package/dist/provider-classes-5NUmLSTV.js.map +1 -0
- package/dist/{rds-provider-J6zl27x3.js → rds-provider-l9F4Y8YY.js} +2 -2
- package/dist/{rds-provider-J6zl27x3.js.map → rds-provider-l9F4Y8YY.js.map} +1 -1
- package/dist/{version-QrNvZCe0.js → version-DIQcU8CA.js} +2 -2
- package/dist/{version-QrNvZCe0.js.map → version-DIQcU8CA.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BTOCDCWf.js.map +0 -1
- package/dist/program-DMJnrQOG.js.map +0 -1
- package/dist/provider-classes-DCbt28RB.js.map +0 -1
|
@@ -2,7 +2,7 @@ import { r as getAwsClients, s as __exportAll } from "./aws-clients-CnmtbrxD.js"
|
|
|
2
2
|
import { A as displaySafe, E as UNRENDERABLE, F as safeMsg, L as truncateCodePoints, M as isPasteableIdent, O as displayAwsMessage, P as plainIdentOr, S as withoutGeneratedFallbackName, T as STACK_REF_MAX_CODE_POINTS, _ as getCurrentSkipPrefix, b as withSkipPrefix, c as getLiveRenderer, f as applyDefaultNameForFallback, g as generateResourceNameWithFallback, h as generateResourceName, j as displayStackName, k as displayIdent, m as explicitNamePropertyFor, n as getLogger, r as isStdoutReservedForPayload, s as installLogLineMaskerSource, v as getCurrentStackName, w as SECRET_REF_MAX_CODE_POINTS, x as withStackName, y as looksLikeCdkdGeneratedName } from "./logger-B46YMG0h.js";
|
|
3
3
|
import { $t as StateError, A as isTerminalDeleteFailure, An as isAmbiguousCcHandlerErrorCode, At as clientDefaultsFor, Bn as isMarkedNonRetryable, Bt as IntrinsicResolutionRefusalError, C as refusalTypeShown, Cn as isNameCollisionErrorFrom, D as ProtectionFlipRegistry, Dt as withPasteableAwsProfile, En as isReplayedNameCollisionFrom, Fn as retryClassificationText, Gt as MalformedProducerRecordRefusalError, H as pasteableAwsCommand, Hn as markNonRetryable, In as describeAwsFailure, It as CrossAccountSecretRefusalError, J as isInterruptedWaitError, Jt as ProvisioningError, Lt as DependencyError, M as observeThenDisableProtection, Mn as isIamPropagationError, Mt as AccountIdUnavailableError, N as protectionFlipKey, Nn as isRetryableTransientError, Nt as AssetError, O as compensateProtectionFlip, On as markReplayMayCollide, Ot as ambientClientDefaults, Pn as isTransientServerError, Pt as CdkdError, Q as canonicalizeRoute53QueryName, R as DELETION_PROTECTION_DOC_POINTER, Rn as safeStringify$1, S as quotedRemedyLogicalId, Sn as hasReplayMayCollide, St as injectiveKey, T as resolveExplicitPhysicalId, Tn as isRecreateRetryableError, Tt as producerRecordKey, U as protectedReplacementAdvice, Un as markRedactedCause, Ut as LockError, Vn as isThrottlingError, Wn as wrapMaskedAwsError, Wt as MacroExpansionError, X as ElapsedBudgetRegistry, Xt as ResourceUpdateNotSupportedError, Y as startInterruptWatch, Yt as ResourceTimeoutError, Z as monotonicNowMs, _n as shellQuote, _t as formatLockOperation, at as segmentAfterAnchor, b as isQuotableImportValue, bt as CUSTOM_RESOURCE_RESPONSE_PREFIX, cn as UNSHOWABLE_VALUE, ct as isSecretDerivedValue, d as prepareRemovalForUpdate, dn as isInertUnquoted, dt as withDerivedNameMasks, en as SynthesisError, et as compositeIdSeparatorRefusal, f as removalWarning, fn as pasteableCommand, ft as UNREPRODUCIBLE_LOCK_CLAUSE, g as assertRegionMatch, gn as shellBoundedDisplay, gt as formatLockExpiry, h as RESOURCE_NOT_FOUND, hn as quotedOrDescribed, i as holdsSecretDerivedEntry, it as resourceTypeShown, jn as isAmbiguousOutcomeError, jt as credentialFingerprint, k as deleteWithProtectionCompensation, kn as formatRetryClassificationSignals, kt as ambientCredentialConfig, l as withUnchangedSecretPrincipalLists, ln as commandHole, lt as maskDeep, m as withoutInjectedRemovals, mn as plainOrDescribed, nt as logicalIdShown, on as SHELL_ACTIVE, ot as createMaskedLogSinks, pn as physicalIdShownBesideCommand, pt as buildForceUnlockCommand, rn as normalizeAwsError, sn as SHELL_ACTIVE_WHY, st as createMaskedRetryLogger, ut as maskerOrIdentity, vn as withheldTargetClause, vt as formatLockOwner, wn as isNameCooldownError, x as normalizeAwsTagsToCfn, xn as isUpdateUnsupportedError, xt as DEFAULT_STATE_PREFIX, yt as sanitizeRecoveryValue, zt as DynamicReferenceRegionAmbiguousError } from "./iam-policy-targets-CMSQGQnm.js";
|
|
4
4
|
import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as ambientRegion, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-D0q0z4dG.js";
|
|
5
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
+
import { t as getCdkdVersion } from "./version-DIQcU8CA.js";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
8
|
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -4683,6 +4683,41 @@ function orphansAfterRollback(previous, newlyOrphaned) {
|
|
|
4683
4683
|
//#endregion
|
|
4684
4684
|
//#region src/types/rollback-journal.ts
|
|
4685
4685
|
const ROLLBACK_JOURNAL_VERSION = 1;
|
|
4686
|
+
function splitImportedOps(ops, segment, except = /* @__PURE__ */ new Set()) {
|
|
4687
|
+
const marks = segment.importedResources ?? [];
|
|
4688
|
+
const replay = [];
|
|
4689
|
+
const imported = [];
|
|
4690
|
+
const displaced = [];
|
|
4691
|
+
for (const op of ops) {
|
|
4692
|
+
const ofId = except.has(op.logicalId) ? [] : marks.filter((m) => m.logicalId === op.logicalId);
|
|
4693
|
+
if (ofId.length === 0) replay.push(op);
|
|
4694
|
+
else if (ofId.some((m) => isMarkFor(m, op)) && retainedOldPhysicalId(op) === void 0) imported.push(op);
|
|
4695
|
+
else displaced.push(op);
|
|
4696
|
+
}
|
|
4697
|
+
return {
|
|
4698
|
+
replay,
|
|
4699
|
+
imported,
|
|
4700
|
+
displaced
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4703
|
+
function journalOpPhysicalId(op) {
|
|
4704
|
+
if (op.physicalId !== void 0) return op.physicalId;
|
|
4705
|
+
const prev = op.previousState?.physicalId;
|
|
4706
|
+
return op.changeType === "DELETE" && typeof prev === "string" && prev !== "" ? prev : void 0;
|
|
4707
|
+
}
|
|
4708
|
+
function retainedOldPhysicalId(op) {
|
|
4709
|
+
if (op.changeType !== "UPDATE") return void 0;
|
|
4710
|
+
const prev = op.previousState?.physicalId;
|
|
4711
|
+
if (typeof prev !== "string" || prev === "") return void 0;
|
|
4712
|
+
const prevType = op.previousState?.resourceType;
|
|
4713
|
+
const oldType = op.previousResourceType ?? (typeof prevType === "string" && prevType !== "" ? prevType : void 0);
|
|
4714
|
+
if (!(prev !== journalOpPhysicalId(op) || oldType !== void 0 && oldType !== op.resourceType)) return void 0;
|
|
4715
|
+
return op.oldResourceRetained !== false ? prev : void 0;
|
|
4716
|
+
}
|
|
4717
|
+
function isMarkFor(mark, op) {
|
|
4718
|
+
const own = journalOpPhysicalId(op);
|
|
4719
|
+
return own !== void 0 && mark.logicalId === op.logicalId && mark.physicalId === own && mark.resourceType === op.resourceType;
|
|
4720
|
+
}
|
|
4686
4721
|
var UnknownRollbackJournalVersionError = class extends Error {
|
|
4687
4722
|
foundVersion;
|
|
4688
4723
|
stackName;
|
|
@@ -4753,6 +4788,7 @@ function parseRollbackJournal(bodyString, stackName) {
|
|
|
4753
4788
|
seg["failedOperations"].forEach((op, i) => refuseMalformedOperation(shownStack, `segments[${s}].failedOperations[${i}]`, op));
|
|
4754
4789
|
}
|
|
4755
4790
|
if (seg["supersededLogicalIds"] !== void 0 && (!Array.isArray(seg["supersededLogicalIds"]) || !seg["supersededLogicalIds"].every((id) => typeof id === "string"))) refuseMalformed(shownStack, `segments[${s}].supersededLogicalIds must be an array of strings when present.`);
|
|
4791
|
+
if (seg["importedResources"] !== void 0 && (!Array.isArray(seg["importedResources"]) || !seg["importedResources"].every((m) => typeof m === "object" && m !== null && typeof m["logicalId"] === "string" && typeof m["physicalId"] === "string" && typeof m["resourceType"] === "string"))) refuseMalformed(shownStack, `segments[${s}].importedResources must be an array of { logicalId, physicalId, resourceType } strings when present.`);
|
|
4756
4792
|
if (seg["runId"] !== void 0 && typeof seg["runId"] !== "string") refuseMalformed(shownStack, `segments[${s}].runId must be a string when present (got ${kind(seg["runId"])}).`);
|
|
4757
4793
|
if (seg["skipPrefix"] !== void 0 && typeof seg["skipPrefix"] !== "boolean") refuseMalformed(shownStack, `segments[${s}].skipPrefix must be a boolean when present (got ${kind(seg["skipPrefix"])}).`);
|
|
4758
4794
|
const reads = seg["previousCrossStackReads"];
|
|
@@ -5370,6 +5406,23 @@ var S3StateBackend = class {
|
|
|
5370
5406
|
addSupersededIds(newest, logicalIds);
|
|
5371
5407
|
await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
|
|
5372
5408
|
}
|
|
5409
|
+
async markRollbackJournalImported(stackName, region, marks) {
|
|
5410
|
+
if (marks.length === 0) return [];
|
|
5411
|
+
const journal = await this.loadRollbackJournal(stackName, region);
|
|
5412
|
+
if (!journal) return [];
|
|
5413
|
+
const marked = /* @__PURE__ */ new Set();
|
|
5414
|
+
for (const segment of journal.segments) {
|
|
5415
|
+
const named = new Set([...segment.operations, ...segment.failedOperations ?? []].map((op) => op.logicalId));
|
|
5416
|
+
const hits = marks.filter((m) => named.has(m.logicalId));
|
|
5417
|
+
if (hits.length === 0) continue;
|
|
5418
|
+
segment.importedResources = [...(segment.importedResources ?? []).filter((k) => !hits.some((m) => m.logicalId === k.logicalId)), ...hits.map((m) => ({ ...m }))];
|
|
5419
|
+
for (const m of hits) marked.add(m.logicalId);
|
|
5420
|
+
}
|
|
5421
|
+
if (marked.size === 0) return [];
|
|
5422
|
+
addSupersededIds(journal.segments[journal.segments.length - 1], [...marked]);
|
|
5423
|
+
await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
|
|
5424
|
+
return [...marked];
|
|
5425
|
+
}
|
|
5373
5426
|
async dropRollbackJournalSegments(stackName, region, drop) {
|
|
5374
5427
|
const journal = await this.loadRollbackJournal(stackName, region);
|
|
5375
5428
|
if (!journal) return 0;
|
|
@@ -6077,7 +6130,7 @@ const WHOLE_DYNAMIC_REFERENCE_PATTERN = new RegExp(`^\\{\\{resolve:${DYNAMIC_REF
|
|
|
6077
6130
|
function isSingleDynamicReferenceToken(value) {
|
|
6078
6131
|
return WHOLE_DYNAMIC_REFERENCE_PATTERN.test(value);
|
|
6079
6132
|
}
|
|
6080
|
-
function isPlainObject$
|
|
6133
|
+
function isPlainObject$4(value) {
|
|
6081
6134
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6082
6135
|
}
|
|
6083
6136
|
|
|
@@ -6262,7 +6315,7 @@ function crossStackSourceKey(source) {
|
|
|
6262
6315
|
}
|
|
6263
6316
|
if (key === "Fn::GetStackOutput") {
|
|
6264
6317
|
const args = source[key];
|
|
6265
|
-
if (!isPlainObject$
|
|
6318
|
+
if (!isPlainObject$4(args)) return void 0;
|
|
6266
6319
|
const stackName = Object.hasOwn(args, "StackName") ? literalStringOrUndefined(args["StackName"]) : void 0;
|
|
6267
6320
|
const outputName = Object.hasOwn(args, "OutputName") ? literalStringOrUndefined(args["OutputName"]) : void 0;
|
|
6268
6321
|
if (stackName === void 0 || outputName === void 0) return void 0;
|
|
@@ -6308,7 +6361,7 @@ function crossStackSourceKey(source) {
|
|
|
6308
6361
|
let template;
|
|
6309
6362
|
let variables;
|
|
6310
6363
|
if (typeof raw === "string") template = raw;
|
|
6311
|
-
else if (Array.isArray(raw) && raw.length === 2 && isPlainObject$
|
|
6364
|
+
else if (Array.isArray(raw) && raw.length === 2 && isPlainObject$4(raw[1])) {
|
|
6312
6365
|
if (typeof raw[0] !== "string") return void 0;
|
|
6313
6366
|
template = raw[0];
|
|
6314
6367
|
variables = raw[1];
|
|
@@ -6408,7 +6461,7 @@ function appendValuePlaceholderParts(value, out, budget, depth) {
|
|
|
6408
6461
|
if (budget.exhausted) return;
|
|
6409
6462
|
const literal = joinPartLiteralText(value);
|
|
6410
6463
|
if (literal !== void 0) return pushPlaceholderPart(out, literal, budget);
|
|
6411
|
-
if (isPlainObject$
|
|
6464
|
+
if (isPlainObject$4(value) && Object.keys(value).length === 1) {
|
|
6412
6465
|
const ref = value["Ref"];
|
|
6413
6466
|
if (typeof ref === "string" && ref !== "") return pushPlaceholderPart(out, keyedPart({ Ref: ref }), budget);
|
|
6414
6467
|
if (depth >= MAX_PLACEHOLDER_DEPTH) {
|
|
@@ -6440,7 +6493,7 @@ function appendParameterPlaceholderParts(source, out, budget, depth) {
|
|
|
6440
6493
|
let template;
|
|
6441
6494
|
let variables = {};
|
|
6442
6495
|
if (typeof args === "string") template = args;
|
|
6443
|
-
else if (Array.isArray(args) && args.length === 2 && isPlainObject$
|
|
6496
|
+
else if (Array.isArray(args) && args.length === 2 && isPlainObject$4(args[1])) {
|
|
6444
6497
|
template = args[0];
|
|
6445
6498
|
variables = args[1];
|
|
6446
6499
|
} else return false;
|
|
@@ -6583,7 +6636,7 @@ function isUniquelyKeyedBy(items, key) {
|
|
|
6583
6636
|
if (items.length === 0) return false;
|
|
6584
6637
|
const seen = /* @__PURE__ */ new Set();
|
|
6585
6638
|
for (const item of items) {
|
|
6586
|
-
if (!isPlainObject$
|
|
6639
|
+
if (!isPlainObject$4(item) || !Object.hasOwn(item, key)) return false;
|
|
6587
6640
|
const id = item[key];
|
|
6588
6641
|
if (typeof id !== "string" || id === "") return false;
|
|
6589
6642
|
if (seen.has(id)) return false;
|
|
@@ -6613,7 +6666,7 @@ function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameG
|
|
|
6613
6666
|
}
|
|
6614
6667
|
return positionByEmbeddedSpan(bag, source, secrets, bagIsSameGeneration);
|
|
6615
6668
|
}
|
|
6616
|
-
if (typeof bag === "string" && isPlainObject$
|
|
6669
|
+
if (typeof bag === "string" && isPlainObject$4(source)) {
|
|
6617
6670
|
const certified = positionByCrossStackSource(bag, source, secrets);
|
|
6618
6671
|
if (certified !== void 0) return certified;
|
|
6619
6672
|
const placeheld = positionByParameterPlaceholders(bag, source, secrets);
|
|
@@ -6623,7 +6676,7 @@ function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameG
|
|
|
6623
6676
|
const framed = positionByIntrinsicFrame(bag, source, secrets, secretExpressions, bagIsSameGeneration);
|
|
6624
6677
|
if (framed !== void 0) return framed;
|
|
6625
6678
|
}
|
|
6626
|
-
if (Array.isArray(bag) && isPlainObject$
|
|
6679
|
+
if (Array.isArray(bag) && isPlainObject$4(source)) {
|
|
6627
6680
|
const positionedList = positionListByCrossStackSource(bag, source, secrets);
|
|
6628
6681
|
if (positionedList !== void 0) return positionedList;
|
|
6629
6682
|
}
|
|
@@ -6651,7 +6704,7 @@ function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameG
|
|
|
6651
6704
|
}
|
|
6652
6705
|
if (rules.descendArrays && bag.length === source.length) return bag.map((item, i) => redactByPath(item, source[i], secrets, rules, secretExpressions, bagIsSameGeneration));
|
|
6653
6706
|
}
|
|
6654
|
-
if (isPlainObject$
|
|
6707
|
+
if (isPlainObject$4(bag) && hasPlainPrototype(bag) && isPlainObject$4(source)) {
|
|
6655
6708
|
const out = Object.create(null);
|
|
6656
6709
|
for (const [k, v] of Object.entries(bag)) out[k] = Object.hasOwn(source, k) ? redactByPath(v, source[k], secrets, rules, secretExpressions, bagIsSameGeneration) : redactSecretsForState(v, secrets);
|
|
6657
6710
|
return out;
|
|
@@ -6664,7 +6717,7 @@ function isReadbackProjectedFromState(rules) {
|
|
|
6664
6717
|
function subtreeHasDynamicReference(value) {
|
|
6665
6718
|
if (isDynamicReferenceString(value)) return true;
|
|
6666
6719
|
if (Array.isArray(value)) return value.some(subtreeHasDynamicReference);
|
|
6667
|
-
if (isPlainObject$
|
|
6720
|
+
if (isPlainObject$4(value)) return Object.values(value).some(subtreeHasDynamicReference);
|
|
6668
6721
|
return false;
|
|
6669
6722
|
}
|
|
6670
6723
|
function pathCrossesDottedKey(bag, path) {
|
|
@@ -6726,8 +6779,8 @@ function deepEqualJsonValue(a, b) {
|
|
|
6726
6779
|
if (!Array.isArray(b) || a.length !== b.length) return false;
|
|
6727
6780
|
return a.every((item, i) => deepEqualJsonValue(item, b[i]));
|
|
6728
6781
|
}
|
|
6729
|
-
if (isPlainObject$
|
|
6730
|
-
if (!isPlainObject$
|
|
6782
|
+
if (isPlainObject$4(a)) {
|
|
6783
|
+
if (!isPlainObject$4(b)) return false;
|
|
6731
6784
|
if (!hasPlainPrototype(a) || !hasPlainPrototype(b)) return false;
|
|
6732
6785
|
const keys = Object.keys(a);
|
|
6733
6786
|
if (keys.length !== Object.keys(b).length) return false;
|
|
@@ -6753,7 +6806,7 @@ function refuseUncertifiedSubtree(value, sourceLiterals, mark, seen = /* @__PURE
|
|
|
6753
6806
|
for (const item of value) out.push(refuseUncertifiedSubtree(item, sourceLiterals, mark, seen));
|
|
6754
6807
|
return out;
|
|
6755
6808
|
}
|
|
6756
|
-
if (isPlainObject$
|
|
6809
|
+
if (isPlainObject$4(value) && hasPlainPrototype(value)) {
|
|
6757
6810
|
const out = Object.create(null);
|
|
6758
6811
|
seen.set(value, out);
|
|
6759
6812
|
for (const [k, v] of Object.entries(value)) out[k] = refuseUncertifiedSubtree(v, sourceLiterals, mark, seen);
|
|
@@ -6781,7 +6834,7 @@ function refuseUncertifiedReadbackPositions(bag, source, secrets, failClosed, le
|
|
|
6781
6834
|
return mark ? POSITION_DECIDED : source;
|
|
6782
6835
|
}
|
|
6783
6836
|
if (!subtreeHasDynamicReference(source)) return bag;
|
|
6784
|
-
if (isPlainObject$
|
|
6837
|
+
if (isPlainObject$4(bag) && hasPlainPrototype(bag) && isPlainObject$4(source)) {
|
|
6785
6838
|
const out = Object.create(null);
|
|
6786
6839
|
for (const [k, v] of Object.entries(bag)) out[k] = Object.hasOwn(source, k) ? refuseUncertifiedReadbackPositions(v, source[k], secrets, failClosed, learn, mark) : v;
|
|
6787
6840
|
return out;
|
|
@@ -6808,14 +6861,14 @@ function refuseUncertifiedReadbackPositions(bag, source, secrets, failClosed, le
|
|
|
6808
6861
|
function isDistinguishingAnchor(value) {
|
|
6809
6862
|
if (typeof value === "string") return value !== "";
|
|
6810
6863
|
if (Array.isArray(value)) return value.some(isDistinguishingAnchor);
|
|
6811
|
-
if (isPlainObject$
|
|
6864
|
+
if (isPlainObject$4(value)) return Object.values(value).some(isDistinguishingAnchor);
|
|
6812
6865
|
return false;
|
|
6813
6866
|
}
|
|
6814
6867
|
const ANCHOR_REFERENCE_MASK = "<ref>";
|
|
6815
6868
|
function anchorSignature(source) {
|
|
6816
6869
|
if (isDynamicReferenceString(source)) return ANCHOR_REFERENCE_MASK;
|
|
6817
6870
|
if (Array.isArray(source)) return `[${source.map(anchorSignature).sort().join(",")}]`;
|
|
6818
|
-
if (isPlainObject$
|
|
6871
|
+
if (isPlainObject$4(source)) return `{${Object.keys(source).sort().map((k) => `${JSON.stringify(k)}:${anchorSignature(source[k])}`).join(",")}}`;
|
|
6819
6872
|
return JSON.stringify(source) ?? "undefined";
|
|
6820
6873
|
}
|
|
6821
6874
|
function anchorsCorroboratePairing(bag, source, anchors) {
|
|
@@ -6825,8 +6878,8 @@ function anchorsCorroboratePairing(bag, source, anchors) {
|
|
|
6825
6878
|
return true;
|
|
6826
6879
|
}
|
|
6827
6880
|
if (isDynamicReferenceString(source)) return typeof bag === "string";
|
|
6828
|
-
if (isPlainObject$
|
|
6829
|
-
if (!isPlainObject$
|
|
6881
|
+
if (isPlainObject$4(source)) {
|
|
6882
|
+
if (!isPlainObject$4(bag)) return false;
|
|
6830
6883
|
return Object.keys(source).every((k) => Object.hasOwn(bag, k) && anchorsCorroboratePairing(bag[k], source[k], anchors));
|
|
6831
6884
|
}
|
|
6832
6885
|
if (Array.isArray(source)) {
|
|
@@ -6917,13 +6970,13 @@ function learnMixedLeafNeedle(collector, bag, source) {
|
|
|
6917
6970
|
learnNeedle(collector, plaintext, token);
|
|
6918
6971
|
}
|
|
6919
6972
|
function asChild(marks, key) {
|
|
6920
|
-
return isPlainObject$
|
|
6973
|
+
return isPlainObject$4(marks) && hasPlainPrototype(marks) ? marks[key] : void 0;
|
|
6921
6974
|
}
|
|
6922
6975
|
function asIndex(marks, index) {
|
|
6923
6976
|
return Array.isArray(marks) ? marks[index] : void 0;
|
|
6924
6977
|
}
|
|
6925
6978
|
function preferPositionDecisions(scanned, refused, bag, marks, inferred) {
|
|
6926
|
-
if (isPlainObject$
|
|
6979
|
+
if (isPlainObject$4(bag) && hasPlainPrototype(bag) && isPlainObject$4(refused) && isPlainObject$4(scanned)) {
|
|
6927
6980
|
const out = Object.create(null);
|
|
6928
6981
|
for (const [k, v] of Object.entries(refused)) out[k] = preferPositionDecisions(scanned[k], v, bag[k], asChild(marks, k), inferred);
|
|
6929
6982
|
return out;
|
|
@@ -7792,12 +7845,12 @@ const UNFRAMED_SPELLING = Symbol("cdkd.nested-parameter.unframed-spelling");
|
|
|
7792
7845
|
function recordNestedStackParameterExpressions(secrets, resourceType, resolvedProperties, sourceProperties, rules = TEMPLATE_DERIVED_RULES) {
|
|
7793
7846
|
if (resourceType !== NESTED_STACK_RESOURCE_TYPE$4) return;
|
|
7794
7847
|
if (secrets.size === 0) return;
|
|
7795
|
-
if (!isPlainObject$
|
|
7848
|
+
if (!isPlainObject$4(resolvedProperties) || !isPlainObject$4(sourceProperties)) return;
|
|
7796
7849
|
if (!Object.hasOwn(resolvedProperties, "Parameters")) return;
|
|
7797
7850
|
if (!Object.hasOwn(sourceProperties, "Parameters")) return;
|
|
7798
7851
|
const resolvedParameters = resolvedProperties["Parameters"];
|
|
7799
7852
|
const sourceParameters = sourceProperties["Parameters"];
|
|
7800
|
-
if (!isPlainObject$
|
|
7853
|
+
if (!isPlainObject$4(resolvedParameters) || !isPlainObject$4(sourceParameters)) return;
|
|
7801
7854
|
const positioned = redactSecretsForState(markSameGenerationBag({ ...resolvedParameters }), secrets, sourceParameters, rules);
|
|
7802
7855
|
let table = nestedStackParameterExpressions.get(secrets);
|
|
7803
7856
|
for (const [name, resolvedValue] of Object.entries(resolvedParameters)) {
|
|
@@ -7829,7 +7882,7 @@ function recordNestedStackParameterExpressions(secrets, resourceType, resolvedPr
|
|
|
7829
7882
|
if (typeof resolvedValue !== "string") return void 0;
|
|
7830
7883
|
const sourceLeaf = sourceParameters[name];
|
|
7831
7884
|
if (typeof sourceLeaf === "string") return sourceLeaf;
|
|
7832
|
-
if (!isPlainObject$
|
|
7885
|
+
if (!isPlainObject$4(sourceLeaf)) return void 0;
|
|
7833
7886
|
const written = positioned[name];
|
|
7834
7887
|
if (typeof written !== "string") return void 0;
|
|
7835
7888
|
const rendered = intrinsicSkeletonSegments(sourceLeaf)?.map((s) => s === UNKNOWN_PART ? "\0" : s).join("");
|
|
@@ -10787,7 +10840,7 @@ function probeFoundSameId(resourceType, a, b) {
|
|
|
10787
10840
|
//#region src/provisioning/config-shape.ts
|
|
10788
10841
|
function readConfigString(container, key, fallback, containerPath, options) {
|
|
10789
10842
|
if (container === void 0 || container === null) return fallback;
|
|
10790
|
-
if (!isPlainObject$
|
|
10843
|
+
if (!isPlainObject$3(container) || isUnresolvedIntrinsicContainer(container)) {
|
|
10791
10844
|
const detail = malformedShapeDetail(container);
|
|
10792
10845
|
if (options?.onUnusable) {
|
|
10793
10846
|
const named = fallback === "" ? "" : ` (${fallback})`;
|
|
@@ -10827,7 +10880,7 @@ function requireConfigArray(value, path, options) {
|
|
|
10827
10880
|
return value;
|
|
10828
10881
|
}
|
|
10829
10882
|
function requireConfigObject(value, path, options) {
|
|
10830
|
-
if (!isPlainObject$
|
|
10883
|
+
if (!isPlainObject$3(value) || isUnresolvedIntrinsicContainer(value)) {
|
|
10831
10884
|
const detail = malformedShapeDetail(value);
|
|
10832
10885
|
if (options?.onUnusable) {
|
|
10833
10886
|
options.onUnusable(`${path} must be an object ${detail}. Leaving this configuration unapplied here; the same value is REFUSED on a template-path create.`);
|
|
@@ -10839,7 +10892,7 @@ function requireConfigObject(value, path, options) {
|
|
|
10839
10892
|
}
|
|
10840
10893
|
function configStringRefusal(container, key, fallback, containerPath, options) {
|
|
10841
10894
|
if (container === void 0 || container === null) return void 0;
|
|
10842
|
-
if (!isPlainObject$
|
|
10895
|
+
if (!isPlainObject$3(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
|
|
10843
10896
|
return configValueRefusal(container[key], fallback, `${containerPath}.${key}`, options);
|
|
10844
10897
|
}
|
|
10845
10898
|
function coerceCfnBoolean(value) {
|
|
@@ -10852,7 +10905,7 @@ function coerceCfnBoolean(value) {
|
|
|
10852
10905
|
}
|
|
10853
10906
|
function configBooleanRefusal(container, key, containerPath) {
|
|
10854
10907
|
if (container === void 0 || container === null) return void 0;
|
|
10855
|
-
if (!isPlainObject$
|
|
10908
|
+
if (!isPlainObject$3(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
|
|
10856
10909
|
const value = container[key];
|
|
10857
10910
|
if (value === void 0) return void 0;
|
|
10858
10911
|
if (coerceCfnBoolean(value) !== void 0) return void 0;
|
|
@@ -10866,7 +10919,7 @@ function coerceCfnInteger(value) {
|
|
|
10866
10919
|
}
|
|
10867
10920
|
function configIntegerRefusal(container, key, containerPath, min, max) {
|
|
10868
10921
|
if (container === void 0 || container === null) return void 0;
|
|
10869
|
-
if (!isPlainObject$
|
|
10922
|
+
if (!isPlainObject$3(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
|
|
10870
10923
|
const value = container[key];
|
|
10871
10924
|
if (value === void 0) return void 0;
|
|
10872
10925
|
const n = coerceCfnInteger(value);
|
|
@@ -10880,10 +10933,10 @@ function configValueRefusal(value, fallback, path, options) {
|
|
|
10880
10933
|
if (typeof value !== "string" || value.trim() === "") return `${path} must be a non-empty string ${malformedShapeDetail(value)}`;
|
|
10881
10934
|
}
|
|
10882
10935
|
function malformedShapeDetail(value) {
|
|
10883
|
-
if (isPlainObject$
|
|
10936
|
+
if (isPlainObject$3(value) && isUnresolvedIntrinsicContainer(value)) return `(got ${describe(value)} — nothing substituted it before this call)`;
|
|
10884
10937
|
return `(got ${describe(value)}) — check for an unresolved intrinsic or a mis-nested template value`;
|
|
10885
10938
|
}
|
|
10886
|
-
function isPlainObject$
|
|
10939
|
+
function isPlainObject$3(value) {
|
|
10887
10940
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10888
10941
|
}
|
|
10889
10942
|
const NAMEABLE_INTRINSIC_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -10910,7 +10963,7 @@ function describe(value) {
|
|
|
10910
10963
|
if (value === null) return "null";
|
|
10911
10964
|
if (Array.isArray(value)) return "an array";
|
|
10912
10965
|
if (typeof value === "string") return value.trim() === "" ? "a blank string" : "a string";
|
|
10913
|
-
if (isPlainObject$
|
|
10966
|
+
if (isPlainObject$3(value) && isUnresolvedIntrinsicContainer(value)) {
|
|
10914
10967
|
const key = Object.keys(value)[0];
|
|
10915
10968
|
return NAMEABLE_INTRINSIC_KEYS.has(key) ? `an unresolved ${key} intrinsic` : "an unresolved intrinsic";
|
|
10916
10969
|
}
|
|
@@ -15683,6 +15736,927 @@ function malformedOrphansForOrphanRefusalMessage(rawStackName, rawRegion, logica
|
|
|
15683
15736
|
return orphanRefusal(stackName, region, recovery, `${stackClause(stackName, region)} holds ${logicalIds.length} rollback-orphan record(s) in 'orphans' that cannot be read — ${namedOrphanRows(logicalIds)} — because the record has no string 'logicalId' or shares it with another row, or its 'state' is not an object, names no resource type, has no non-empty string 'physicalId', or holds a 'properties' or 'attributes' map that is not an object. The record is malformed or truncated. ${verbatim} Those records are not inert: they are what the next 'cdkd deploy' may re-adopt into 'resources' and what 'cdkd diff' previews for adoption, so continuing would report success over damage the next command meets.`, "'cdkd orphan' cannot remove such a record itself: it is not in 'resources', so it has no construct path. Repair the record by hand rather than deleting it — it is the only record that an earlier failed deploy left its resource live in AWS.", ORPHANS_DROP_CAVEAT);
|
|
15684
15737
|
}
|
|
15685
15738
|
|
|
15739
|
+
//#endregion
|
|
15740
|
+
//#region src/deployment/assumed-conditions.ts
|
|
15741
|
+
const assumedConditionNames = /* @__PURE__ */ new WeakMap();
|
|
15742
|
+
function recordAssumedConditions(conditions, assumed) {
|
|
15743
|
+
assumedConditionNames.set(conditions, assumed);
|
|
15744
|
+
}
|
|
15745
|
+
function conditionsAssumedFalse(conditions) {
|
|
15746
|
+
return assumedConditionNames.get(conditions) ?? /* @__PURE__ */ new Set();
|
|
15747
|
+
}
|
|
15748
|
+
|
|
15749
|
+
//#endregion
|
|
15750
|
+
//#region src/deployment/masked-property-fingerprints.ts
|
|
15751
|
+
const FINGERPRINT_LAYOUT$1 = 1;
|
|
15752
|
+
const INPUT_FINGERPRINT_LAYOUT = 2;
|
|
15753
|
+
function canonicalJson$2(value) {
|
|
15754
|
+
if (value === void 0) return "null";
|
|
15755
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson$2).join(",")}]`;
|
|
15756
|
+
if (value !== null && typeof value === "object") {
|
|
15757
|
+
const record = value;
|
|
15758
|
+
return `{${Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson$2(record[key])}`).join(",")}}`;
|
|
15759
|
+
}
|
|
15760
|
+
return JSON.stringify(value) ?? "null";
|
|
15761
|
+
}
|
|
15762
|
+
const REFUSED_FINGERPRINT = "refused:secret-in-template";
|
|
15763
|
+
const FINGERPRINT_PREFIX = "sha256:";
|
|
15764
|
+
const INPUT_FINGERPRINT_PREFIX = "inputs-sha256:";
|
|
15765
|
+
const TEXT_HALF_SEPARATOR = "+";
|
|
15766
|
+
function splitInputFingerprint(entry) {
|
|
15767
|
+
const at = entry.indexOf(TEXT_HALF_SEPARATOR);
|
|
15768
|
+
if (at < 0) return {
|
|
15769
|
+
input: entry,
|
|
15770
|
+
text: void 0
|
|
15771
|
+
};
|
|
15772
|
+
const text = entry.slice(at + 1);
|
|
15773
|
+
return {
|
|
15774
|
+
input: entry.slice(0, at),
|
|
15775
|
+
text: text.startsWith(FINGERPRINT_PREFIX) ? text : void 0
|
|
15776
|
+
};
|
|
15777
|
+
}
|
|
15778
|
+
function templateCarriesNeedle(templateValue, secrets) {
|
|
15779
|
+
const text = canonicalJson$2(templateValue);
|
|
15780
|
+
for (const needle of printingCorpusOf(secrets).keys()) {
|
|
15781
|
+
if (needle.length < 4) continue;
|
|
15782
|
+
if (text.includes(needle) || text.includes(JSON.stringify(needle).slice(1, -1))) return true;
|
|
15783
|
+
}
|
|
15784
|
+
return false;
|
|
15785
|
+
}
|
|
15786
|
+
function maskedPropertyFingerprint(templateValue) {
|
|
15787
|
+
const digest = createHash("sha256").update(canonicalJson$2({
|
|
15788
|
+
layout: FINGERPRINT_LAYOUT$1,
|
|
15789
|
+
value: templateValue
|
|
15790
|
+
})).digest("hex");
|
|
15791
|
+
return `${FINGERPRINT_PREFIX}${digest}`;
|
|
15792
|
+
}
|
|
15793
|
+
var UnknownInput = class extends Error {};
|
|
15794
|
+
function isPlainObject$2(value) {
|
|
15795
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
15796
|
+
}
|
|
15797
|
+
const DYNAMIC_REFERENCE_OPEN = "{{resolve:";
|
|
15798
|
+
const NESTED_STACK_TYPE$2 = "AWS::CloudFormation::Stack";
|
|
15799
|
+
const NESTED_OUTPUT_PREFIX = "Outputs.";
|
|
15800
|
+
function carriesSecretValue(value, corpora) {
|
|
15801
|
+
if (carriesSecretMask(value)) return true;
|
|
15802
|
+
const text = canonicalJson$2(value);
|
|
15803
|
+
if (text.includes(DYNAMIC_REFERENCE_OPEN)) return true;
|
|
15804
|
+
for (const corpus of corpora) {
|
|
15805
|
+
if (corpus === void 0) continue;
|
|
15806
|
+
for (const needle of printingCorpusOf(corpus).keys()) {
|
|
15807
|
+
if (needle.length === 0) continue;
|
|
15808
|
+
if (text.includes(needle) || text.includes(JSON.stringify(needle).slice(1, -1))) return true;
|
|
15809
|
+
}
|
|
15810
|
+
}
|
|
15811
|
+
return false;
|
|
15812
|
+
}
|
|
15813
|
+
function parameterInputsFor(args) {
|
|
15814
|
+
const declared = isPlainObject$2(args.template.Parameters) ? args.template.Parameters : {};
|
|
15815
|
+
const values = args.values ?? {};
|
|
15816
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
15817
|
+
const bound = {};
|
|
15818
|
+
for (const name of Object.keys(declared)) {
|
|
15819
|
+
const definition = declared[name];
|
|
15820
|
+
if (args.unbound?.has(name) || !Object.hasOwn(values, name)) {
|
|
15821
|
+
inputs.set(name, { kind: "unknown" });
|
|
15822
|
+
continue;
|
|
15823
|
+
}
|
|
15824
|
+
const value = values[name];
|
|
15825
|
+
let secret = isPlainObject$2(definition) && (definition["NoEcho"] === true || definition["NoEcho"] === "true") || carriesSecretValue(value, []);
|
|
15826
|
+
if (!secret && args.nestedChild === true && args.supplied !== void 0) {
|
|
15827
|
+
if (Object.hasOwn(args.supplied, name)) {
|
|
15828
|
+
const passed = args.passedClasses?.get(name);
|
|
15829
|
+
if (passed === "unknown") {
|
|
15830
|
+
inputs.set(name, { kind: "unknown" });
|
|
15831
|
+
continue;
|
|
15832
|
+
}
|
|
15833
|
+
if (passed !== "clean") secret = true;
|
|
15834
|
+
}
|
|
15835
|
+
}
|
|
15836
|
+
if (secret) inputs.set(name, { kind: "secret" });
|
|
15837
|
+
else {
|
|
15838
|
+
inputs.set(name, {
|
|
15839
|
+
kind: "value",
|
|
15840
|
+
value
|
|
15841
|
+
});
|
|
15842
|
+
bound[name] = value;
|
|
15843
|
+
}
|
|
15844
|
+
}
|
|
15845
|
+
return {
|
|
15846
|
+
parameterInput: (name) => inputs.get(name) ?? { kind: "unknown" },
|
|
15847
|
+
bound
|
|
15848
|
+
};
|
|
15849
|
+
}
|
|
15850
|
+
function newShared() {
|
|
15851
|
+
return {
|
|
15852
|
+
steps: 0,
|
|
15853
|
+
passed: /* @__PURE__ */ new Map(),
|
|
15854
|
+
outputs: /* @__PURE__ */ new Map(),
|
|
15855
|
+
rowsPassed: /* @__PURE__ */ new Map()
|
|
15856
|
+
};
|
|
15857
|
+
}
|
|
15858
|
+
function subPlaceholders(text) {
|
|
15859
|
+
const names = [];
|
|
15860
|
+
for (const match of text.matchAll(/\$\{([^}]*)\}/g)) {
|
|
15861
|
+
const body = match[1] ?? "";
|
|
15862
|
+
if (body.startsWith("!") || body.length === 0) continue;
|
|
15863
|
+
if (!names.includes(body)) names.push(body);
|
|
15864
|
+
}
|
|
15865
|
+
return names;
|
|
15866
|
+
}
|
|
15867
|
+
function intrinsicKey(value) {
|
|
15868
|
+
const keys = Object.keys(value);
|
|
15869
|
+
if (keys.length !== 1) return void 0;
|
|
15870
|
+
const key = keys[0];
|
|
15871
|
+
return key === "Ref" || key.startsWith("Fn::") ? key : void 0;
|
|
15872
|
+
}
|
|
15873
|
+
const OPAQUE_ATTRIBUTE_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::CustomResource", NESTED_STACK_TYPE$2]);
|
|
15874
|
+
function hasOpaqueAttributes(logicalId, walk) {
|
|
15875
|
+
const definition = walk.resources[logicalId];
|
|
15876
|
+
const type = isPlainObject$2(definition) ? definition["Type"] : void 0;
|
|
15877
|
+
return typeof type === "string" && (type.startsWith("Custom::") || OPAQUE_ATTRIBUTE_TYPES.has(type));
|
|
15878
|
+
}
|
|
15879
|
+
function getAttTarget(operand) {
|
|
15880
|
+
if (Array.isArray(operand) && typeof operand[0] === "string") return operand[0];
|
|
15881
|
+
if (typeof operand === "string" && operand.includes(".")) return operand.split(".")[0];
|
|
15882
|
+
}
|
|
15883
|
+
function taintOf(logicalId, walk) {
|
|
15884
|
+
const cached = walk.taint.get(logicalId);
|
|
15885
|
+
if (cached !== void 0) return cached;
|
|
15886
|
+
if (walk.inProgress.has(logicalId)) return "tainted";
|
|
15887
|
+
walk.inProgress.add(logicalId);
|
|
15888
|
+
let unknown = false;
|
|
15889
|
+
const nameTaint = (name) => {
|
|
15890
|
+
if (name.startsWith("AWS::")) return "clean";
|
|
15891
|
+
if (Object.hasOwn(walk.resources, name)) return taintOf(name, walk);
|
|
15892
|
+
if (Object.hasOwn(walk.parameters, name)) {
|
|
15893
|
+
const input = walk.sources.parameterInput(name);
|
|
15894
|
+
return input.kind === "value" ? "clean" : input.kind === "secret" ? "tainted" : "unknown";
|
|
15895
|
+
}
|
|
15896
|
+
return "tainted";
|
|
15897
|
+
};
|
|
15898
|
+
const visit = (value) => {
|
|
15899
|
+
if (typeof value === "string") return value.includes(DYNAMIC_REFERENCE_OPEN);
|
|
15900
|
+
if (Array.isArray(value)) return value.some(visit);
|
|
15901
|
+
if (!isPlainObject$2(value)) return false;
|
|
15902
|
+
const key = intrinsicKey(value);
|
|
15903
|
+
const operand = key === void 0 ? void 0 : value[key];
|
|
15904
|
+
let verdict = "clean";
|
|
15905
|
+
if (key === "Ref" && typeof operand === "string") verdict = nameTaint(operand);
|
|
15906
|
+
else if (key === "Fn::GetAtt") {
|
|
15907
|
+
const target = getAttTarget(operand);
|
|
15908
|
+
verdict = target === void 0 || Object.hasOwn(walk.resources, target) && hasOpaqueAttributes(target, walk) ? "tainted" : nameTaint(target);
|
|
15909
|
+
} else if (key === "Fn::ImportValue" || key === "Fn::GetStackOutput") verdict = "tainted";
|
|
15910
|
+
else if (key === "Fn::FindInMap" && mapReadClass(operand, walk.sources.template) !== "clean") verdict = "tainted";
|
|
15911
|
+
else if (key === "Fn::Sub") {
|
|
15912
|
+
const text = Array.isArray(operand) ? operand[0] : operand;
|
|
15913
|
+
const vars = Array.isArray(operand) && isPlainObject$2(operand[1]) ? operand[1] : {};
|
|
15914
|
+
if (typeof text === "string") for (const name of subPlaceholders(text)) {
|
|
15915
|
+
if (Object.hasOwn(vars, name)) continue;
|
|
15916
|
+
const owner = name.includes(".") ? name.split(".")[0] : name;
|
|
15917
|
+
const t = name.includes(".") && Object.hasOwn(walk.resources, owner) && hasOpaqueAttributes(owner, walk) ? "tainted" : nameTaint(owner);
|
|
15918
|
+
if (t === "tainted") return true;
|
|
15919
|
+
if (t === "unknown") unknown = true;
|
|
15920
|
+
}
|
|
15921
|
+
}
|
|
15922
|
+
if (verdict === "tainted") return true;
|
|
15923
|
+
if (verdict === "unknown") unknown = true;
|
|
15924
|
+
return Object.values(value).some(visit);
|
|
15925
|
+
};
|
|
15926
|
+
const definition = walk.resources[logicalId];
|
|
15927
|
+
const result = visit(isPlainObject$2(definition) ? definition["Properties"] : void 0) ? "tainted" : unknown ? "unknown" : "clean";
|
|
15928
|
+
walk.inProgress.delete(logicalId);
|
|
15929
|
+
walk.taint.set(logicalId, result);
|
|
15930
|
+
return result;
|
|
15931
|
+
}
|
|
15932
|
+
function conditionInput(name, walk) {
|
|
15933
|
+
const closure = conditionClosure(name, walk);
|
|
15934
|
+
if (closure.unknown || closure.unread) return "unknown";
|
|
15935
|
+
if (closure.secret) return "secret";
|
|
15936
|
+
const conditions = walk.sources.conditions;
|
|
15937
|
+
if (conditions === void 0 || !Object.hasOwn(conditions, name)) return "unknown";
|
|
15938
|
+
if (conditionsAssumedFalse(conditions).has(name)) return "unknown";
|
|
15939
|
+
const verdict = conditions[name];
|
|
15940
|
+
return typeof verdict === "boolean" ? verdict : "unknown";
|
|
15941
|
+
}
|
|
15942
|
+
function conditionClosure(name, walk) {
|
|
15943
|
+
const definitions = isPlainObject$2(walk.sources.template.Conditions) ? walk.sources.template.Conditions : {};
|
|
15944
|
+
let secret = false;
|
|
15945
|
+
let unknown = false;
|
|
15946
|
+
let unread = false;
|
|
15947
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15948
|
+
const pending = [name];
|
|
15949
|
+
const visit = (value) => {
|
|
15950
|
+
if (typeof value === "string") {
|
|
15951
|
+
if (value.includes(DYNAMIC_REFERENCE_OPEN)) secret = true;
|
|
15952
|
+
return;
|
|
15953
|
+
}
|
|
15954
|
+
if (Array.isArray(value)) {
|
|
15955
|
+
value.forEach(visit);
|
|
15956
|
+
return;
|
|
15957
|
+
}
|
|
15958
|
+
if (!isPlainObject$2(value)) return;
|
|
15959
|
+
const keys = Object.keys(value);
|
|
15960
|
+
if (keys.length === 1 && keys[0] === "Condition" && typeof value["Condition"] === "string") {
|
|
15961
|
+
pending.push(value["Condition"]);
|
|
15962
|
+
return;
|
|
15963
|
+
}
|
|
15964
|
+
const classifyName = (ref) => {
|
|
15965
|
+
if (ref.startsWith("AWS::")) return;
|
|
15966
|
+
if (!Object.hasOwn(walk.parameters, ref)) {
|
|
15967
|
+
unknown = true;
|
|
15968
|
+
return;
|
|
15969
|
+
}
|
|
15970
|
+
const input = walk.sources.parameterInput(ref);
|
|
15971
|
+
if (input.kind === "secret") secret = true;
|
|
15972
|
+
if (input.kind === "unknown") unread = true;
|
|
15973
|
+
};
|
|
15974
|
+
if (keys.length === 1 && keys[0] === "Ref" && typeof value["Ref"] === "string") {
|
|
15975
|
+
classifyName(value["Ref"]);
|
|
15976
|
+
return;
|
|
15977
|
+
}
|
|
15978
|
+
const key = keys.length === 1 ? keys[0] : void 0;
|
|
15979
|
+
if (key === "Fn::FindInMap") {
|
|
15980
|
+
const read = mapReadClass(value["Fn::FindInMap"], walk.sources.template);
|
|
15981
|
+
if (read === "secret") secret = true;
|
|
15982
|
+
if (read === "unknown") unknown = true;
|
|
15983
|
+
}
|
|
15984
|
+
if (key === "Fn::ImportValue" || key === "Fn::GetStackOutput" || key === "Fn::GetAtt") {
|
|
15985
|
+
secret = true;
|
|
15986
|
+
return;
|
|
15987
|
+
}
|
|
15988
|
+
if (key === "Fn::Sub") {
|
|
15989
|
+
const operand = value["Fn::Sub"];
|
|
15990
|
+
const text = Array.isArray(operand) ? operand[0] : operand;
|
|
15991
|
+
const vars = Array.isArray(operand) && isPlainObject$2(operand[1]) ? operand[1] : {};
|
|
15992
|
+
if (typeof text === "string") for (const name of subPlaceholders(text)) {
|
|
15993
|
+
if (Object.hasOwn(vars, name)) continue;
|
|
15994
|
+
if (name.includes(".") && !name.startsWith("AWS::")) secret = true;
|
|
15995
|
+
else classifyName(name);
|
|
15996
|
+
}
|
|
15997
|
+
}
|
|
15998
|
+
Object.values(value).forEach(visit);
|
|
15999
|
+
};
|
|
16000
|
+
while (pending.length > 0) {
|
|
16001
|
+
const current = pending.pop();
|
|
16002
|
+
if (seen.has(current)) continue;
|
|
16003
|
+
seen.add(current);
|
|
16004
|
+
if (!Object.hasOwn(definitions, current)) {
|
|
16005
|
+
unknown = true;
|
|
16006
|
+
continue;
|
|
16007
|
+
}
|
|
16008
|
+
visit(definitions[current]);
|
|
16009
|
+
}
|
|
16010
|
+
return {
|
|
16011
|
+
secret,
|
|
16012
|
+
unknown,
|
|
16013
|
+
unread
|
|
16014
|
+
};
|
|
16015
|
+
}
|
|
16016
|
+
function mapReadClass(operand, template) {
|
|
16017
|
+
const mapName = Array.isArray(operand) ? operand[0] : void 0;
|
|
16018
|
+
if (typeof mapName !== "string") return "unknown";
|
|
16019
|
+
const mappings = template.Mappings;
|
|
16020
|
+
const map = isPlainObject$2(mappings) && Object.hasOwn(mappings, mapName) ? mappings[mapName] : void 0;
|
|
16021
|
+
if (!isPlainObject$2(map)) return "unknown";
|
|
16022
|
+
return carriesSecretValue(map, []) ? "secret" : "clean";
|
|
16023
|
+
}
|
|
16024
|
+
async function resolvedInput(node, walk) {
|
|
16025
|
+
let resolved;
|
|
16026
|
+
try {
|
|
16027
|
+
resolved = await walk.sources.resolve(node);
|
|
16028
|
+
} catch {
|
|
16029
|
+
throw new UnknownInput();
|
|
16030
|
+
}
|
|
16031
|
+
if (resolved.keepAsWritten === true || carriesSecretValue(resolved.value, [resolved.secrets])) return {
|
|
16032
|
+
form: node,
|
|
16033
|
+
concrete: false
|
|
16034
|
+
};
|
|
16035
|
+
return {
|
|
16036
|
+
form: resolved.value,
|
|
16037
|
+
concrete: true
|
|
16038
|
+
};
|
|
16039
|
+
}
|
|
16040
|
+
async function nameInput(name, node, walk) {
|
|
16041
|
+
if (name === "AWS::NoValue") return {
|
|
16042
|
+
form: node,
|
|
16043
|
+
concrete: false
|
|
16044
|
+
};
|
|
16045
|
+
if (name.startsWith("AWS::")) return resolvedInput(node, walk);
|
|
16046
|
+
if (Object.hasOwn(walk.resources, name)) {
|
|
16047
|
+
const taint = taintOf(name, walk);
|
|
16048
|
+
if (taint === "unknown") throw new UnknownInput();
|
|
16049
|
+
if (taint === "tainted") return {
|
|
16050
|
+
form: node,
|
|
16051
|
+
concrete: false
|
|
16052
|
+
};
|
|
16053
|
+
return resolvedInput(node, walk);
|
|
16054
|
+
}
|
|
16055
|
+
if (Object.hasOwn(walk.parameters, name)) {
|
|
16056
|
+
const input = walk.sources.parameterInput(name);
|
|
16057
|
+
if (input.kind === "unknown") throw new UnknownInput();
|
|
16058
|
+
if (input.kind === "secret") return {
|
|
16059
|
+
form: node,
|
|
16060
|
+
concrete: false
|
|
16061
|
+
};
|
|
16062
|
+
return {
|
|
16063
|
+
form: input.value,
|
|
16064
|
+
concrete: true
|
|
16065
|
+
};
|
|
16066
|
+
}
|
|
16067
|
+
return {
|
|
16068
|
+
form: node,
|
|
16069
|
+
concrete: false
|
|
16070
|
+
};
|
|
16071
|
+
}
|
|
16072
|
+
async function inputForms(values, walk) {
|
|
16073
|
+
const parts = [];
|
|
16074
|
+
for (const element of values) parts.push(await inputForm(element, walk));
|
|
16075
|
+
return parts;
|
|
16076
|
+
}
|
|
16077
|
+
async function inputForm(value, walk) {
|
|
16078
|
+
if (typeof value === "string") return {
|
|
16079
|
+
form: value,
|
|
16080
|
+
concrete: !value.includes(DYNAMIC_REFERENCE_OPEN)
|
|
16081
|
+
};
|
|
16082
|
+
if (Array.isArray(value)) {
|
|
16083
|
+
const parts = await inputForms(value, walk);
|
|
16084
|
+
return {
|
|
16085
|
+
form: parts.map((p) => p.form),
|
|
16086
|
+
concrete: parts.every((p) => p.concrete)
|
|
16087
|
+
};
|
|
16088
|
+
}
|
|
16089
|
+
if (!isPlainObject$2(value)) return {
|
|
16090
|
+
form: value,
|
|
16091
|
+
concrete: true
|
|
16092
|
+
};
|
|
16093
|
+
const key = intrinsicKey(value);
|
|
16094
|
+
if (key === void 0) {
|
|
16095
|
+
const entries = Object.keys(value);
|
|
16096
|
+
const parts = await inputForms(entries.map((k) => value[k]), walk);
|
|
16097
|
+
return {
|
|
16098
|
+
form: Object.fromEntries(entries.map((k, i) => [k, parts[i].form])),
|
|
16099
|
+
concrete: parts.every((p) => p.concrete)
|
|
16100
|
+
};
|
|
16101
|
+
}
|
|
16102
|
+
const operand = value[key];
|
|
16103
|
+
switch (key) {
|
|
16104
|
+
case "Ref": return typeof operand === "string" ? nameInput(operand, value, walk) : {
|
|
16105
|
+
form: value,
|
|
16106
|
+
concrete: false
|
|
16107
|
+
};
|
|
16108
|
+
case "Fn::GetAtt": {
|
|
16109
|
+
const target = getAttTarget(operand);
|
|
16110
|
+
if (target !== void 0 && isNestedStackRow(target, walk)) return nestedOutputInput(target, getAttAttribute(operand, target), value, walk);
|
|
16111
|
+
if (target === void 0 || !Object.hasOwn(walk.resources, target) || hasOpaqueAttributes(target, walk)) return {
|
|
16112
|
+
form: value,
|
|
16113
|
+
concrete: false
|
|
16114
|
+
};
|
|
16115
|
+
if (Array.isArray(operand) && operand.length > 1 && typeof operand[1] !== "string") {
|
|
16116
|
+
const attribute = await inputForm(operand[1], walk);
|
|
16117
|
+
if (!attribute.concrete) return {
|
|
16118
|
+
form: { [key]: [operand[0], attribute.form] },
|
|
16119
|
+
concrete: false
|
|
16120
|
+
};
|
|
16121
|
+
}
|
|
16122
|
+
return nameInput(target, value, walk);
|
|
16123
|
+
}
|
|
16124
|
+
case "Fn::If": {
|
|
16125
|
+
if (!Array.isArray(operand) || typeof operand[0] !== "string") {
|
|
16126
|
+
const args = await inputForm(operand, walk);
|
|
16127
|
+
return {
|
|
16128
|
+
form: { [key]: args.form },
|
|
16129
|
+
concrete: false
|
|
16130
|
+
};
|
|
16131
|
+
}
|
|
16132
|
+
const verdict = conditionInput(operand[0], walk);
|
|
16133
|
+
if (verdict === "unknown") throw new UnknownInput();
|
|
16134
|
+
if (verdict === "secret") {
|
|
16135
|
+
const args = await inputForm(operand.slice(1), walk);
|
|
16136
|
+
return {
|
|
16137
|
+
form: { [key]: [operand[0], ...args.form] },
|
|
16138
|
+
concrete: false
|
|
16139
|
+
};
|
|
16140
|
+
}
|
|
16141
|
+
return inputForm(verdict ? operand[1] : operand[2], walk);
|
|
16142
|
+
}
|
|
16143
|
+
case "Fn::Sub": {
|
|
16144
|
+
const text = Array.isArray(operand) ? operand[0] : operand;
|
|
16145
|
+
if (typeof text !== "string") {
|
|
16146
|
+
const args = await inputForm(operand, walk);
|
|
16147
|
+
return {
|
|
16148
|
+
form: { [key]: args.form },
|
|
16149
|
+
concrete: false
|
|
16150
|
+
};
|
|
16151
|
+
}
|
|
16152
|
+
const explicit = Array.isArray(operand) && isPlainObject$2(operand[1]) ? operand[1] : {};
|
|
16153
|
+
const vars = await inputForm(explicit, walk);
|
|
16154
|
+
const placeholders = [];
|
|
16155
|
+
let concrete = vars.concrete && !text.includes(DYNAMIC_REFERENCE_OPEN);
|
|
16156
|
+
for (const name of subPlaceholders(text)) {
|
|
16157
|
+
if (Object.hasOwn(explicit, name)) continue;
|
|
16158
|
+
const dot = name.indexOf(".");
|
|
16159
|
+
const part = dot > 0 && !name.startsWith("AWS::") && isNestedStackRow(name.slice(0, dot), walk) ? await nestedOutputInput(name.slice(0, dot), name.slice(dot + 1), { "Fn::GetAtt": [name.slice(0, dot), name.slice(dot + 1)] }, walk) : dot > 0 && !name.startsWith("AWS::") ? Object.hasOwn(walk.resources, name.slice(0, dot)) && !hasOpaqueAttributes(name.slice(0, dot), walk) ? await nameInput(name.slice(0, dot), { "Fn::GetAtt": [name.slice(0, dot), name.slice(dot + 1)] }, walk) : {
|
|
16160
|
+
form: { "Fn::GetAtt": [name.slice(0, dot), name.slice(dot + 1)] },
|
|
16161
|
+
concrete: false
|
|
16162
|
+
} : await nameInput(name, { Ref: name }, walk);
|
|
16163
|
+
placeholders.push([name, part.form]);
|
|
16164
|
+
concrete &&= part.concrete;
|
|
16165
|
+
}
|
|
16166
|
+
return {
|
|
16167
|
+
form: { [key]: [
|
|
16168
|
+
text,
|
|
16169
|
+
vars.form,
|
|
16170
|
+
Object.fromEntries(placeholders)
|
|
16171
|
+
] },
|
|
16172
|
+
concrete
|
|
16173
|
+
};
|
|
16174
|
+
}
|
|
16175
|
+
case "Fn::ImportValue":
|
|
16176
|
+
case "Fn::GetStackOutput":
|
|
16177
|
+
case "Fn::FindInMap":
|
|
16178
|
+
case "Fn::GetAZs": {
|
|
16179
|
+
const args = await inputForm(operand, walk);
|
|
16180
|
+
if (!args.concrete) return {
|
|
16181
|
+
form: { [key]: args.form },
|
|
16182
|
+
concrete: false
|
|
16183
|
+
};
|
|
16184
|
+
const resolved = await resolvedInput(value, walk);
|
|
16185
|
+
return resolved.concrete ? resolved : {
|
|
16186
|
+
form: { [key]: args.form },
|
|
16187
|
+
concrete: false
|
|
16188
|
+
};
|
|
16189
|
+
}
|
|
16190
|
+
default: {
|
|
16191
|
+
const args = await inputForm(operand, walk);
|
|
16192
|
+
return {
|
|
16193
|
+
form: { [key]: args.form },
|
|
16194
|
+
concrete: args.concrete
|
|
16195
|
+
};
|
|
16196
|
+
}
|
|
16197
|
+
}
|
|
16198
|
+
}
|
|
16199
|
+
function newWalk(sources, nested = {
|
|
16200
|
+
stackChain: /* @__PURE__ */ new Set(),
|
|
16201
|
+
shared: newShared()
|
|
16202
|
+
}) {
|
|
16203
|
+
return {
|
|
16204
|
+
sources,
|
|
16205
|
+
resources: isPlainObject$2(sources.template.Resources) ? sources.template.Resources : {},
|
|
16206
|
+
parameters: isPlainObject$2(sources.template.Parameters) ? sources.template.Parameters : {},
|
|
16207
|
+
taint: /* @__PURE__ */ new Map(),
|
|
16208
|
+
inProgress: /* @__PURE__ */ new Set(),
|
|
16209
|
+
stackChain: nested.stackChain,
|
|
16210
|
+
shared: nested.shared
|
|
16211
|
+
};
|
|
16212
|
+
}
|
|
16213
|
+
const NESTED_OUTPUT_ORDER = {
|
|
16214
|
+
clean: 0,
|
|
16215
|
+
unread: 1,
|
|
16216
|
+
unknown: 2,
|
|
16217
|
+
secret: 3
|
|
16218
|
+
};
|
|
16219
|
+
function worseOf(a, b) {
|
|
16220
|
+
return NESTED_OUTPUT_ORDER[a] >= NESTED_OUTPUT_ORDER[b] ? a : b;
|
|
16221
|
+
}
|
|
16222
|
+
const MAX_NESTED_OUTPUT_DEPTH = 32;
|
|
16223
|
+
const MAX_NESTED_OUTPUT_STEPS = 1e4;
|
|
16224
|
+
function passedKey(passed) {
|
|
16225
|
+
return JSON.stringify([...passed.entries()]);
|
|
16226
|
+
}
|
|
16227
|
+
function isNestedStackRow(logicalId, walk) {
|
|
16228
|
+
if (!Object.hasOwn(walk.resources, logicalId)) return false;
|
|
16229
|
+
const definition = walk.resources[logicalId];
|
|
16230
|
+
return isPlainObject$2(definition) && definition["Type"] === NESTED_STACK_TYPE$2;
|
|
16231
|
+
}
|
|
16232
|
+
function getAttAttribute(operand, target) {
|
|
16233
|
+
if (Array.isArray(operand)) return operand.length === 2 && typeof operand[1] === "string" ? operand[1] : void 0;
|
|
16234
|
+
return typeof operand === "string" ? operand.slice(target.length + 1) : void 0;
|
|
16235
|
+
}
|
|
16236
|
+
function rowParameters(definition) {
|
|
16237
|
+
const properties = isPlainObject$2(definition) ? definition["Properties"] : void 0;
|
|
16238
|
+
if (properties === void 0) return {};
|
|
16239
|
+
if (!isPlainObject$2(properties)) return "unknown";
|
|
16240
|
+
const parameters = properties["Parameters"];
|
|
16241
|
+
if (parameters === void 0) return {};
|
|
16242
|
+
if (!isPlainObject$2(parameters) || intrinsicKey(parameters) !== void 0) return "unknown";
|
|
16243
|
+
return parameters;
|
|
16244
|
+
}
|
|
16245
|
+
function childParameterInputs(template, passed) {
|
|
16246
|
+
const declared = isPlainObject$2(template.Parameters) ? template.Parameters : {};
|
|
16247
|
+
const inputs = /* @__PURE__ */ new Map();
|
|
16248
|
+
for (const name of Object.keys(declared)) {
|
|
16249
|
+
const definition = declared[name];
|
|
16250
|
+
if (isPlainObject$2(definition) && (definition["NoEcho"] === true || definition["NoEcho"] === "true")) inputs.set(name, { kind: "secret" });
|
|
16251
|
+
else if (passed.has(name)) {
|
|
16252
|
+
const passedClass = passed.get(name);
|
|
16253
|
+
inputs.set(name, passedClass === "clean" ? {
|
|
16254
|
+
kind: "value",
|
|
16255
|
+
value: void 0
|
|
16256
|
+
} : passedClass === "unknown" ? { kind: "unknown" } : { kind: "secret" });
|
|
16257
|
+
} else if (isPlainObject$2(definition) && Object.hasOwn(definition, "Default") && !carriesSecretValue(definition["Default"], [])) inputs.set(name, {
|
|
16258
|
+
kind: "value",
|
|
16259
|
+
value: definition["Default"]
|
|
16260
|
+
});
|
|
16261
|
+
else inputs.set(name, { kind: "secret" });
|
|
16262
|
+
}
|
|
16263
|
+
return (name) => inputs.get(name) ?? { kind: "secret" };
|
|
16264
|
+
}
|
|
16265
|
+
function taintClass(taint) {
|
|
16266
|
+
return taint === "clean" ? "clean" : taint === "tainted" ? "secret" : "unread";
|
|
16267
|
+
}
|
|
16268
|
+
function closureClass(closure) {
|
|
16269
|
+
if (closure.secret) return "secret";
|
|
16270
|
+
if (closure.unknown) return "unknown";
|
|
16271
|
+
return closure.unread ? "unread" : "clean";
|
|
16272
|
+
}
|
|
16273
|
+
async function childOutputClass(loaded, outputName, passed, chain, shared) {
|
|
16274
|
+
if (loaded === void 0 || !isPlainObject$2(loaded.template)) return "unknown";
|
|
16275
|
+
const scopeKey = JSON.stringify([loaded.identity, passedKey(passed)]);
|
|
16276
|
+
const memoKey = JSON.stringify([scopeKey, outputName]);
|
|
16277
|
+
const memo = shared.outputs.get(memoKey);
|
|
16278
|
+
if (memo !== void 0) return memo;
|
|
16279
|
+
const outputClass = await classifyChildOutput(loaded, outputName, passed, chain, shared, scopeKey);
|
|
16280
|
+
shared.outputs.set(memoKey, outputClass);
|
|
16281
|
+
return outputClass;
|
|
16282
|
+
}
|
|
16283
|
+
async function classifyChildOutput(loaded, outputName, passed, chain, shared, scopeKey) {
|
|
16284
|
+
if (++shared.steps > MAX_NESTED_OUTPUT_STEPS) return "unknown";
|
|
16285
|
+
if (chain.includes(loaded.identity) || chain.length >= MAX_NESTED_OUTPUT_DEPTH) return "unknown";
|
|
16286
|
+
const template = loaded.template;
|
|
16287
|
+
const output = (isPlainObject$2(template.Outputs) ? template.Outputs : {})[outputName];
|
|
16288
|
+
if (!isPlainObject$2(output) || !Object.hasOwn(output, "Value")) return "unknown";
|
|
16289
|
+
const scope = {
|
|
16290
|
+
walk: newWalk({
|
|
16291
|
+
template,
|
|
16292
|
+
parameterInput: childParameterInputs(template, passed),
|
|
16293
|
+
resolve: () => Promise.reject(/* @__PURE__ */ new Error("a nested output is classified, never resolved"))
|
|
16294
|
+
}),
|
|
16295
|
+
childTemplate: loaded.childTemplate,
|
|
16296
|
+
chain: [...chain, loaded.identity],
|
|
16297
|
+
rows: /* @__PURE__ */ new Set(),
|
|
16298
|
+
key: scopeKey,
|
|
16299
|
+
shared
|
|
16300
|
+
};
|
|
16301
|
+
let outputClass = "clean";
|
|
16302
|
+
if (Object.hasOwn(output, "Condition")) {
|
|
16303
|
+
const condition = output["Condition"];
|
|
16304
|
+
outputClass = typeof condition === "string" ? closureClass(conditionClosure(condition, scope.walk)) : "unknown";
|
|
16305
|
+
}
|
|
16306
|
+
return worseOf(outputClass, await expressionClass(output["Value"], scope));
|
|
16307
|
+
}
|
|
16308
|
+
function nameClass(name, scope) {
|
|
16309
|
+
if (name.startsWith("AWS::")) return "clean";
|
|
16310
|
+
const walk = scope.walk;
|
|
16311
|
+
if (Object.hasOwn(walk.resources, name)) return taintClass(taintOf(name, walk));
|
|
16312
|
+
if (Object.hasOwn(walk.parameters, name)) {
|
|
16313
|
+
const input = walk.sources.parameterInput(name);
|
|
16314
|
+
return input.kind === "value" ? "clean" : input.kind === "secret" ? "secret" : "unread";
|
|
16315
|
+
}
|
|
16316
|
+
return "secret";
|
|
16317
|
+
}
|
|
16318
|
+
async function attributeClass(target, attribute, scope) {
|
|
16319
|
+
const walk = scope.walk;
|
|
16320
|
+
if (!Object.hasOwn(walk.resources, target)) return "secret";
|
|
16321
|
+
if (isNestedStackRow(target, walk)) {
|
|
16322
|
+
if (attribute === void 0 || !attribute.startsWith(NESTED_OUTPUT_PREFIX)) return "unknown";
|
|
16323
|
+
if (scope.rows.has(target)) return "unknown";
|
|
16324
|
+
const parameters = rowParameters(walk.resources[target]);
|
|
16325
|
+
if (parameters === "unknown") return "unknown";
|
|
16326
|
+
const rowKey = JSON.stringify([scope.key, target]);
|
|
16327
|
+
let passed = scope.shared.rowsPassed.get(rowKey);
|
|
16328
|
+
if (passed === void 0) {
|
|
16329
|
+
const inner = {
|
|
16330
|
+
...scope,
|
|
16331
|
+
rows: /* @__PURE__ */ new Set([...scope.rows, target])
|
|
16332
|
+
};
|
|
16333
|
+
const classes = /* @__PURE__ */ new Map();
|
|
16334
|
+
for (const [name, expression] of Object.entries(parameters)) {
|
|
16335
|
+
const passedClass = await expressionClass(expression, inner);
|
|
16336
|
+
classes.set(name, passedClass === "clean" ? "clean" : passedClass === "unread" ? "unknown" : "secret");
|
|
16337
|
+
}
|
|
16338
|
+
scope.shared.rowsPassed.set(rowKey, classes);
|
|
16339
|
+
passed = classes;
|
|
16340
|
+
}
|
|
16341
|
+
let loaded;
|
|
16342
|
+
try {
|
|
16343
|
+
loaded = scope.childTemplate(target);
|
|
16344
|
+
} catch {
|
|
16345
|
+
loaded = void 0;
|
|
16346
|
+
}
|
|
16347
|
+
return childOutputClass(loaded, attribute.slice(8), passed, scope.chain, scope.shared);
|
|
16348
|
+
}
|
|
16349
|
+
if (hasOpaqueAttributes(target, walk)) return "unknown";
|
|
16350
|
+
return taintClass(taintOf(target, walk));
|
|
16351
|
+
}
|
|
16352
|
+
async function expressionClass(value, scope) {
|
|
16353
|
+
if (typeof value === "string") return value.includes(DYNAMIC_REFERENCE_OPEN) ? "secret" : "clean";
|
|
16354
|
+
const all = async (values) => {
|
|
16355
|
+
let result = "clean";
|
|
16356
|
+
for (const element of values) result = worseOf(result, await expressionClass(element, scope));
|
|
16357
|
+
return result;
|
|
16358
|
+
};
|
|
16359
|
+
if (Array.isArray(value)) return all(value);
|
|
16360
|
+
if (!isPlainObject$2(value)) return "clean";
|
|
16361
|
+
const key = intrinsicKey(value);
|
|
16362
|
+
if (key === void 0) return all(Object.values(value));
|
|
16363
|
+
const operand = value[key];
|
|
16364
|
+
switch (key) {
|
|
16365
|
+
case "Ref": return typeof operand === "string" ? nameClass(operand, scope) : "unknown";
|
|
16366
|
+
case "Fn::GetAtt": {
|
|
16367
|
+
const target = getAttTarget(operand);
|
|
16368
|
+
if (target === void 0) return "secret";
|
|
16369
|
+
const attribute = getAttAttribute(operand, target);
|
|
16370
|
+
return worseOf(attribute === void 0 && Array.isArray(operand) ? await all(operand.slice(1)) : "clean", await attributeClass(target, attribute, scope));
|
|
16371
|
+
}
|
|
16372
|
+
case "Fn::Sub": {
|
|
16373
|
+
const text = Array.isArray(operand) ? operand[0] : operand;
|
|
16374
|
+
if (typeof text !== "string") return worseOf("unknown", await expressionClass(operand, scope));
|
|
16375
|
+
const vars = Array.isArray(operand) && isPlainObject$2(operand[1]) ? operand[1] : {};
|
|
16376
|
+
let result = text.includes(DYNAMIC_REFERENCE_OPEN) ? "secret" : "clean";
|
|
16377
|
+
result = worseOf(result, await all(Object.values(vars)));
|
|
16378
|
+
for (const name of subPlaceholders(text)) {
|
|
16379
|
+
if (Object.hasOwn(vars, name)) continue;
|
|
16380
|
+
const dot = name.indexOf(".");
|
|
16381
|
+
result = worseOf(result, dot > 0 && !name.startsWith("AWS::") ? await attributeClass(name.slice(0, dot), name.slice(dot + 1), scope) : nameClass(name, scope));
|
|
16382
|
+
}
|
|
16383
|
+
return result;
|
|
16384
|
+
}
|
|
16385
|
+
case "Fn::If":
|
|
16386
|
+
if (!Array.isArray(operand) || operand.length !== 3 || typeof operand[0] !== "string") return worseOf("unknown", await expressionClass(operand, scope));
|
|
16387
|
+
return worseOf(closureClass(conditionClosure(operand[0], scope.walk)), await all(operand.slice(1)));
|
|
16388
|
+
case "Fn::ImportValue":
|
|
16389
|
+
case "Fn::GetStackOutput": return "secret";
|
|
16390
|
+
case "Fn::FindInMap": {
|
|
16391
|
+
const read = mapReadClass(operand, scope.walk.sources.template);
|
|
16392
|
+
if (read === "unknown") return worseOf("unknown", await all([operand]));
|
|
16393
|
+
return worseOf(read, await all(operand.slice(1)));
|
|
16394
|
+
}
|
|
16395
|
+
default: return expressionClass(operand, scope);
|
|
16396
|
+
}
|
|
16397
|
+
}
|
|
16398
|
+
async function stackOutputClass(stackLogicalId, attribute, walk) {
|
|
16399
|
+
const loader = walk.sources.childTemplate;
|
|
16400
|
+
if (loader === void 0 || !isNestedStackRow(stackLogicalId, walk)) return "unknown";
|
|
16401
|
+
if (attribute === void 0 || !attribute.startsWith(NESTED_OUTPUT_PREFIX)) return "unknown";
|
|
16402
|
+
if (walk.stackChain.has(stackLogicalId)) return "unknown";
|
|
16403
|
+
const parameters = rowParameters(walk.resources[stackLogicalId]);
|
|
16404
|
+
if (parameters === "unknown") return "unknown";
|
|
16405
|
+
let passed = walk.shared.passed.get(stackLogicalId);
|
|
16406
|
+
if (passed === void 0) {
|
|
16407
|
+
if (++walk.shared.steps > MAX_NESTED_OUTPUT_STEPS) return "unknown";
|
|
16408
|
+
passed = await classifyPassed(parameters, walk.sources, {
|
|
16409
|
+
stackChain: /* @__PURE__ */ new Set([...walk.stackChain, stackLogicalId]),
|
|
16410
|
+
shared: walk.shared
|
|
16411
|
+
});
|
|
16412
|
+
walk.shared.passed.set(stackLogicalId, passed);
|
|
16413
|
+
}
|
|
16414
|
+
let loaded;
|
|
16415
|
+
try {
|
|
16416
|
+
loaded = loader(stackLogicalId);
|
|
16417
|
+
} catch {
|
|
16418
|
+
loaded = void 0;
|
|
16419
|
+
}
|
|
16420
|
+
return childOutputClass(loaded, attribute.slice(8), passed, [], walk.shared);
|
|
16421
|
+
}
|
|
16422
|
+
async function nestedOutputInput(stackLogicalId, attribute, node, walk) {
|
|
16423
|
+
const outputClass = await stackOutputClass(stackLogicalId, attribute, walk);
|
|
16424
|
+
if (outputClass === "unread") throw new UnknownInput();
|
|
16425
|
+
if (outputClass !== "clean") return {
|
|
16426
|
+
form: node,
|
|
16427
|
+
concrete: false
|
|
16428
|
+
};
|
|
16429
|
+
return resolvedInput(node, walk);
|
|
16430
|
+
}
|
|
16431
|
+
async function maskedInputFingerprint(templateValue, sources) {
|
|
16432
|
+
let form;
|
|
16433
|
+
try {
|
|
16434
|
+
form = (await inputForm(templateValue, newWalk(sources))).form;
|
|
16435
|
+
} catch (error) {
|
|
16436
|
+
if (error instanceof UnknownInput) return void 0;
|
|
16437
|
+
throw error;
|
|
16438
|
+
}
|
|
16439
|
+
const digest = createHash("sha256").update(canonicalJson$2({
|
|
16440
|
+
layout: INPUT_FINGERPRINT_LAYOUT,
|
|
16441
|
+
value: form
|
|
16442
|
+
})).digest("hex");
|
|
16443
|
+
return `${INPUT_FINGERPRINT_PREFIX}${digest}${TEXT_HALF_SEPARATOR}${maskedPropertyFingerprint(templateValue)}`;
|
|
16444
|
+
}
|
|
16445
|
+
async function classifyPassedParameters(parameters, sources) {
|
|
16446
|
+
return classifyPassed(parameters, sources, {
|
|
16447
|
+
stackChain: /* @__PURE__ */ new Set(),
|
|
16448
|
+
shared: newShared()
|
|
16449
|
+
});
|
|
16450
|
+
}
|
|
16451
|
+
async function classifyPassed(parameters, sources, nested) {
|
|
16452
|
+
const classes = /* @__PURE__ */ new Map();
|
|
16453
|
+
if (!isPlainObject$2(parameters)) return classes;
|
|
16454
|
+
for (const [name, expression] of Object.entries(parameters)) {
|
|
16455
|
+
let passedClass;
|
|
16456
|
+
try {
|
|
16457
|
+
passedClass = (await inputForm(expression, newWalk(sources, nested))).concrete ? "clean" : "secret";
|
|
16458
|
+
} catch {
|
|
16459
|
+
passedClass = "unknown";
|
|
16460
|
+
}
|
|
16461
|
+
classes.set(name, passedClass);
|
|
16462
|
+
}
|
|
16463
|
+
return classes;
|
|
16464
|
+
}
|
|
16465
|
+
const passedParameterClasses = /* @__PURE__ */ new WeakMap();
|
|
16466
|
+
function recordPassedParameterClasses(bag, classes) {
|
|
16467
|
+
passedParameterClasses.set(bag, classes);
|
|
16468
|
+
}
|
|
16469
|
+
function passedParameterClassesOf(bag) {
|
|
16470
|
+
return bag === void 0 ? void 0 : passedParameterClasses.get(bag);
|
|
16471
|
+
}
|
|
16472
|
+
function inputFingerprinter(templateProps, sources) {
|
|
16473
|
+
const memo = /* @__PURE__ */ new Map();
|
|
16474
|
+
return (key) => {
|
|
16475
|
+
let pending = memo.get(key);
|
|
16476
|
+
if (pending === void 0) {
|
|
16477
|
+
pending = Object.hasOwn(templateProps, key) ? maskedInputFingerprint(templateProps[key], sources).catch(() => void 0) : Promise.resolve(void 0);
|
|
16478
|
+
memo.set(key, pending);
|
|
16479
|
+
}
|
|
16480
|
+
return pending;
|
|
16481
|
+
};
|
|
16482
|
+
}
|
|
16483
|
+
function possiblyMaskedKeys(resolvedProps, corpora) {
|
|
16484
|
+
const needles = /* @__PURE__ */ new Set();
|
|
16485
|
+
for (const corpus of corpora) {
|
|
16486
|
+
if (corpus === void 0) continue;
|
|
16487
|
+
for (const needle of printingCorpusOf(corpus).keys()) if (needle.length > 0) needles.add(needle);
|
|
16488
|
+
}
|
|
16489
|
+
const short = [...needles].filter((needle) => needle.length < 4);
|
|
16490
|
+
const long = [...needles].filter((needle) => needle.length >= 4);
|
|
16491
|
+
const wholeShortLeaf = (value) => {
|
|
16492
|
+
if (typeof value === "string") return short.includes(value);
|
|
16493
|
+
if (Array.isArray(value)) return value.some(wholeShortLeaf);
|
|
16494
|
+
if (isPlainObject$2(value)) return Object.values(value).some(wholeShortLeaf);
|
|
16495
|
+
return false;
|
|
16496
|
+
};
|
|
16497
|
+
return Object.keys(resolvedProps).filter((key) => {
|
|
16498
|
+
const value = resolvedProps[key];
|
|
16499
|
+
if (carriesSecretMask(value) || wholeShortLeaf(value)) return true;
|
|
16500
|
+
const text = canonicalJson$2(value);
|
|
16501
|
+
return long.some((needle) => text.includes(needle) || text.includes(JSON.stringify(needle).slice(1, -1)));
|
|
16502
|
+
});
|
|
16503
|
+
}
|
|
16504
|
+
async function maskedInputFingerprintsFor(keys, fingerprinter) {
|
|
16505
|
+
const entries = [];
|
|
16506
|
+
for (const key of keys) {
|
|
16507
|
+
const fingerprint = await fingerprinter(key);
|
|
16508
|
+
if (fingerprint !== void 0) entries.push([key, fingerprint]);
|
|
16509
|
+
}
|
|
16510
|
+
return Object.fromEntries(entries);
|
|
16511
|
+
}
|
|
16512
|
+
function maskedPropertyFingerprintsFor(recordedProperties, templateProps) {
|
|
16513
|
+
const entries = [];
|
|
16514
|
+
for (const key of Object.keys(recordedProperties)) {
|
|
16515
|
+
if (!Object.hasOwn(templateProps, key)) continue;
|
|
16516
|
+
if (!carriesSecretMask(recordedProperties[key])) continue;
|
|
16517
|
+
entries.push([key, maskedPropertyFingerprint(templateProps[key])]);
|
|
16518
|
+
}
|
|
16519
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
16520
|
+
}
|
|
16521
|
+
function maskedPropertyFingerprintsOf(record) {
|
|
16522
|
+
const read = /* @__PURE__ */ new Map();
|
|
16523
|
+
if (record === null || typeof record !== "object") return read;
|
|
16524
|
+
const field = record.maskedPropertyFingerprints;
|
|
16525
|
+
if (!isPlainObject$2(field)) return read;
|
|
16526
|
+
for (const [key, value] of Object.entries(field)) if (typeof value === "string" && value.startsWith(FINGERPRINT_PREFIX)) read.set(key, value);
|
|
16527
|
+
return read;
|
|
16528
|
+
}
|
|
16529
|
+
function maskedPropertyInputFingerprintsOf(record) {
|
|
16530
|
+
const read = /* @__PURE__ */ new Map();
|
|
16531
|
+
if (record === null || typeof record !== "object") return read;
|
|
16532
|
+
const field = record.maskedPropertyInputFingerprints;
|
|
16533
|
+
if (!isPlainObject$2(field)) return read;
|
|
16534
|
+
const text = maskedPropertyFingerprintsOf(record);
|
|
16535
|
+
for (const [key, value] of Object.entries(field)) {
|
|
16536
|
+
if (typeof value !== "string" || !value.startsWith(INPUT_FINGERPRINT_PREFIX)) continue;
|
|
16537
|
+
const half = splitInputFingerprint(value).text;
|
|
16538
|
+
if (half !== void 0 && text.get(key) === half) read.set(key, value);
|
|
16539
|
+
}
|
|
16540
|
+
return read;
|
|
16541
|
+
}
|
|
16542
|
+
function boundInputFingerprints(textFingerprints, inputFingerprints) {
|
|
16543
|
+
if (textFingerprints === void 0 || inputFingerprints === void 0) return void 0;
|
|
16544
|
+
const entries = [];
|
|
16545
|
+
for (const [key, text] of Object.entries(textFingerprints)) {
|
|
16546
|
+
if (!text.startsWith(FINGERPRINT_PREFIX) || !Object.hasOwn(inputFingerprints, key)) continue;
|
|
16547
|
+
const input = inputFingerprints[key];
|
|
16548
|
+
if (splitInputFingerprint(input).text === text) entries.push([key, input]);
|
|
16549
|
+
}
|
|
16550
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
16551
|
+
}
|
|
16552
|
+
async function movedMaskedProperties(record, templateProps, fingerprinter, onRebaseline) {
|
|
16553
|
+
const recorded = maskedPropertyFingerprintsOf(record);
|
|
16554
|
+
if (recorded.size === 0) return [];
|
|
16555
|
+
const properties = record.properties;
|
|
16556
|
+
if (properties === null || typeof properties !== "object") return [];
|
|
16557
|
+
const inputs = maskedPropertyInputFingerprintsOf(record);
|
|
16558
|
+
const moved = [];
|
|
16559
|
+
for (const [key, fingerprint] of recorded) {
|
|
16560
|
+
if (!Object.hasOwn(templateProps, key) || !Object.hasOwn(properties, key)) continue;
|
|
16561
|
+
if (!carriesSecretMask(properties[key])) continue;
|
|
16562
|
+
if (maskedPropertyFingerprint(templateProps[key]) !== fingerprint) {
|
|
16563
|
+
moved.push(key);
|
|
16564
|
+
continue;
|
|
16565
|
+
}
|
|
16566
|
+
if (fingerprinter === void 0) continue;
|
|
16567
|
+
const bound = inputs.get(key);
|
|
16568
|
+
if (bound === void 0 && onRebaseline === void 0) continue;
|
|
16569
|
+
const now = await fingerprinter(key);
|
|
16570
|
+
if (now === void 0) continue;
|
|
16571
|
+
if (bound !== void 0) {
|
|
16572
|
+
if (splitInputFingerprint(now).input !== splitInputFingerprint(bound).input) moved.push(key);
|
|
16573
|
+
} else onRebaseline(key, now);
|
|
16574
|
+
}
|
|
16575
|
+
return moved;
|
|
16576
|
+
}
|
|
16577
|
+
function withRebaselinedFingerprints(record, fingerprints) {
|
|
16578
|
+
const text = maskedPropertyFingerprintsOf(record);
|
|
16579
|
+
const field = record.maskedPropertyInputFingerprints;
|
|
16580
|
+
const next = isPlainObject$2(field) ? Object.entries(field) : [];
|
|
16581
|
+
let changed = false;
|
|
16582
|
+
for (const [key, value] of Object.entries(fingerprints)) {
|
|
16583
|
+
if (text.get(key) !== splitInputFingerprint(value).text) continue;
|
|
16584
|
+
const at = next.findIndex(([k]) => k === key);
|
|
16585
|
+
if (at >= 0) next[at] = [key, value];
|
|
16586
|
+
else next.push([key, value]);
|
|
16587
|
+
changed = true;
|
|
16588
|
+
}
|
|
16589
|
+
return changed ? {
|
|
16590
|
+
...record,
|
|
16591
|
+
maskedPropertyInputFingerprints: Object.fromEntries(next)
|
|
16592
|
+
} : record;
|
|
16593
|
+
}
|
|
16594
|
+
const writtenFromDeployedTemplate = /* @__PURE__ */ new WeakSet();
|
|
16595
|
+
function markWrittenFromDeployedTemplate(bag) {
|
|
16596
|
+
writtenFromDeployedTemplate.add(bag);
|
|
16597
|
+
return bag;
|
|
16598
|
+
}
|
|
16599
|
+
function withMaskedPropertyFingerprints(scrubbed, writtenBag, templateProps, secrets, noEchoParameterValues, inputFingerprints) {
|
|
16600
|
+
if (templateProps === void 0) return scrubbed;
|
|
16601
|
+
const corpora = [secrets, noEchoParameterValues].filter((corpus) => corpus !== void 0);
|
|
16602
|
+
const written = writtenBag !== null && typeof writtenBag === "object" && writtenFromDeployedTemplate.has(writtenBag);
|
|
16603
|
+
const { maskedPropertyFingerprints: previous, maskedPropertyInputFingerprints: previousInputs, ...rest } = scrubbed;
|
|
16604
|
+
let fingerprints;
|
|
16605
|
+
let inputs;
|
|
16606
|
+
if (written) {
|
|
16607
|
+
fingerprints = maskedPropertyFingerprintsFor(scrubbed.properties, templateProps);
|
|
16608
|
+
inputs = boundInputFingerprints(fingerprints, inputFingerprints);
|
|
16609
|
+
} else {
|
|
16610
|
+
if (!isPlainObject$2(previous)) return scrubbed;
|
|
16611
|
+
if (corpora.length === 0) return scrubbed;
|
|
16612
|
+
fingerprints = { ...previous };
|
|
16613
|
+
inputs = isPlainObject$2(previousInputs) ? { ...previousInputs } : void 0;
|
|
16614
|
+
}
|
|
16615
|
+
if (fingerprints !== void 0 && corpora.length > 0) {
|
|
16616
|
+
const refused = Object.keys(fingerprints).filter((key) => Object.hasOwn(templateProps, key) && corpora.some((corpus) => templateCarriesNeedle(templateProps[key], corpus)));
|
|
16617
|
+
if (refused.length > 0) {
|
|
16618
|
+
fingerprints = Object.fromEntries(Object.entries(fingerprints).map(([key, value]) => [key, refused.includes(key) ? REFUSED_FINGERPRINT : value]));
|
|
16619
|
+
if (inputs !== void 0) {
|
|
16620
|
+
const kept = Object.entries(inputs).filter(([key]) => !refused.includes(key));
|
|
16621
|
+
inputs = kept.length > 0 ? Object.fromEntries(kept) : void 0;
|
|
16622
|
+
}
|
|
16623
|
+
}
|
|
16624
|
+
}
|
|
16625
|
+
if (!written && JSON.stringify(fingerprints) === JSON.stringify(previous) && JSON.stringify(inputs) === JSON.stringify(previousInputs)) return scrubbed;
|
|
16626
|
+
return {
|
|
16627
|
+
...rest,
|
|
16628
|
+
...fingerprints !== void 0 && { maskedPropertyFingerprints: fingerprints },
|
|
16629
|
+
...inputs !== void 0 && { maskedPropertyInputFingerprints: inputs }
|
|
16630
|
+
};
|
|
16631
|
+
}
|
|
16632
|
+
function backfillMaskedPropertyFingerprints(resources, template, noEchoParameterValues) {
|
|
16633
|
+
const declared = template?.Resources;
|
|
16634
|
+
if (declared === void 0 || declared === null) return 0;
|
|
16635
|
+
let stamped = 0;
|
|
16636
|
+
for (const [logicalId, record] of Object.entries(resources)) {
|
|
16637
|
+
if (record === null || typeof record !== "object") continue;
|
|
16638
|
+
const field = record.maskedPropertyFingerprints;
|
|
16639
|
+
if (field !== void 0 && (field === null || typeof field !== "object" || Array.isArray(field))) continue;
|
|
16640
|
+
const existing = field ?? {};
|
|
16641
|
+
if (!Object.hasOwn(declared, logicalId)) continue;
|
|
16642
|
+
const definition = declared[logicalId];
|
|
16643
|
+
if (definition === void 0 || definition.Type !== record.resourceType) continue;
|
|
16644
|
+
const properties = record.properties;
|
|
16645
|
+
if (properties === null || typeof properties !== "object" || Array.isArray(properties)) continue;
|
|
16646
|
+
const fingerprints = maskedPropertyFingerprintsFor(properties, definition.Properties ?? {});
|
|
16647
|
+
if (fingerprints === void 0) continue;
|
|
16648
|
+
const templateProps = definition.Properties ?? {};
|
|
16649
|
+
const added = Object.entries(fingerprints).filter(([key]) => !Object.hasOwn(existing, key)).map(([key, value]) => noEchoParameterValues !== void 0 && templateCarriesNeedle(templateProps[key], noEchoParameterValues) ? [key, REFUSED_FINGERPRINT] : [key, value]);
|
|
16650
|
+
if (added.length === 0) continue;
|
|
16651
|
+
resources[logicalId] = {
|
|
16652
|
+
...record,
|
|
16653
|
+
maskedPropertyFingerprints: Object.fromEntries([...Object.entries(existing), ...added])
|
|
16654
|
+
};
|
|
16655
|
+
stamped++;
|
|
16656
|
+
}
|
|
16657
|
+
return stamped;
|
|
16658
|
+
}
|
|
16659
|
+
|
|
15686
16660
|
//#endregion
|
|
15687
16661
|
//#region src/deployment/drain-budget.ts
|
|
15688
16662
|
const drainDeadlines = new AsyncLocalStorage();
|
|
@@ -15980,6 +16954,49 @@ const DEPLOY_RESOLVED_REFERENCE_SERVICES = /* @__PURE__ */ new Set([
|
|
|
15980
16954
|
"ssm",
|
|
15981
16955
|
"ssm-secure"
|
|
15982
16956
|
]);
|
|
16957
|
+
function sitsInsideResolvableReference(text, start, end) {
|
|
16958
|
+
const OPENING = "{{resolve:";
|
|
16959
|
+
const opening = text.lastIndexOf(OPENING, start);
|
|
16960
|
+
if (opening < 0) return false;
|
|
16961
|
+
const head = text.slice(opening + 10, start);
|
|
16962
|
+
if (head.includes("}}")) return false;
|
|
16963
|
+
const colon = head.indexOf(":");
|
|
16964
|
+
if (colon >= 0 && !DEPLOY_RESOLVED_REFERENCE_SERVICES.has(head.slice(0, colon))) return false;
|
|
16965
|
+
const close = text.indexOf("}}", end);
|
|
16966
|
+
if (close < 0) return false;
|
|
16967
|
+
const nextOpening = text.indexOf(OPENING, end);
|
|
16968
|
+
if (nextOpening >= 0 && nextOpening < close) return false;
|
|
16969
|
+
return !/["\r\n]/.test(text.slice(opening, close));
|
|
16970
|
+
}
|
|
16971
|
+
const KEPT_PLACEHOLDERS = /* @__PURE__ */ new WeakMap();
|
|
16972
|
+
function recordKeptPlaceholder(bag, placeholder, because) {
|
|
16973
|
+
let kept = KEPT_PLACEHOLDERS.get(bag);
|
|
16974
|
+
if (kept === void 0) {
|
|
16975
|
+
kept = /* @__PURE__ */ new Map();
|
|
16976
|
+
KEPT_PLACEHOLDERS.set(bag, kept);
|
|
16977
|
+
}
|
|
16978
|
+
if (!kept.has(placeholder)) kept.set(placeholder, {
|
|
16979
|
+
because,
|
|
16980
|
+
reported: false
|
|
16981
|
+
});
|
|
16982
|
+
}
|
|
16983
|
+
function takeKeptPlaceholdersInsideReferences(bag, text) {
|
|
16984
|
+
const kept = KEPT_PLACEHOLDERS.get(bag);
|
|
16985
|
+
if (kept === void 0) return [];
|
|
16986
|
+
const found = [];
|
|
16987
|
+
for (const [placeholder, entry] of kept) {
|
|
16988
|
+
if (entry.reported) continue;
|
|
16989
|
+
for (let at = text.indexOf(placeholder); at >= 0; at = text.indexOf(placeholder, at + 1)) if (sitsInsideResolvableReference(text, at, at + placeholder.length)) {
|
|
16990
|
+
entry.reported = true;
|
|
16991
|
+
found.push({
|
|
16992
|
+
placeholder,
|
|
16993
|
+
because: entry.because
|
|
16994
|
+
});
|
|
16995
|
+
break;
|
|
16996
|
+
}
|
|
16997
|
+
}
|
|
16998
|
+
return found;
|
|
16999
|
+
}
|
|
15983
17000
|
function keepsSecretReferenceToken(resolvedName) {
|
|
15984
17001
|
return dynamicReferenceTokens(resolvedName).some((token) => DEPLOY_RESOLVED_REFERENCE_SERVICES.has(token.slice(10, -2).split(":")[0] ?? ""));
|
|
15985
17002
|
}
|
|
@@ -17766,6 +18783,13 @@ async function resolveTemplateLeafReferences(value, context) {
|
|
|
17766
18783
|
return (await this.resolveDynamicReferencesWithLogTwin(value, value, context)).result;
|
|
17767
18784
|
}
|
|
17768
18785
|
async function resolveDynamicReferencesWithLogTwin(value, logTwin, context, inherited, persistedText = false) {
|
|
18786
|
+
if (context?.abandonedResolutions !== void 0) {
|
|
18787
|
+
const bag = context.abandonedResolutions;
|
|
18788
|
+
for (const { placeholder, because } of takeKeptPlaceholdersInsideReferences(bag, value)) {
|
|
18789
|
+
const reason = because instanceof Error ? because.message : String(because);
|
|
18790
|
+
bag.push(this.abandonedUnit("placeholder", placeholder, new Error(`Fn::Sub kept the placeholder ${placeholder} (${reason}) inside a {{resolve:...}} reference, so that reference was never resolved`, { cause: because }), context, value));
|
|
18791
|
+
}
|
|
18792
|
+
}
|
|
17769
18793
|
const pattern = /\{\{resolve:([^}]+)\}\}/g;
|
|
17770
18794
|
let result = value;
|
|
17771
18795
|
let twin = logTwin;
|
|
@@ -18228,6 +19252,15 @@ function rethrowStructuralSubFailure(varName, error, context) {
|
|
|
18228
19252
|
if (!this.subPlaceholderNamesADeclaredTemplateEntity(varName, context)) return;
|
|
18229
19253
|
throw error;
|
|
18230
19254
|
}
|
|
19255
|
+
function noteKeptSubPlaceholder(varName, placeholder, because, context) {
|
|
19256
|
+
if (context.abandonedResolutions === void 0) return;
|
|
19257
|
+
const firstDot = varName.indexOf(".");
|
|
19258
|
+
const head = firstDot >= 0 ? varName.slice(0, firstDot) : varName;
|
|
19259
|
+
for (const declared of [context.template?.Resources, context.template?.Parameters]) if (declared !== void 0 && declared !== null && typeof declared === "object") {
|
|
19260
|
+
if (Object.hasOwn(declared, head)) return;
|
|
19261
|
+
}
|
|
19262
|
+
recordKeptPlaceholder(context.abandonedResolutions, placeholder, because);
|
|
19263
|
+
}
|
|
18231
19264
|
function subListRefusal(subject, value, context) {
|
|
18232
19265
|
if (!Array.isArray(value)) return void 0;
|
|
18233
19266
|
const count = `${value.length} item${value.length === 1 ? "" : "s"}`;
|
|
@@ -18337,11 +19370,13 @@ async function resolveSub(subArgs, context, source) {
|
|
|
18337
19370
|
this.rethrowStructuralSubFailure(varNameStr, getAttError, context);
|
|
18338
19371
|
this.logger.warn(this.displayMasked(this.subPlaceholderWarning(varNameStr, getAttError), context));
|
|
18339
19372
|
replacement = match[0];
|
|
19373
|
+
noteKeptSubPlaceholder(varNameStr, match[0], getAttError, context);
|
|
18340
19374
|
}
|
|
18341
19375
|
else {
|
|
18342
19376
|
this.rethrowStructuralSubFailure(varNameStr, refError, context);
|
|
18343
19377
|
this.logger.warn(this.displayMasked(this.subPlaceholderWarning(varNameStr, refError), context));
|
|
18344
19378
|
replacement = match[0];
|
|
19379
|
+
noteKeptSubPlaceholder(varNameStr, match[0], refError, context);
|
|
18345
19380
|
}
|
|
18346
19381
|
}
|
|
18347
19382
|
}
|
|
@@ -18858,16 +19893,6 @@ function displayLeaf(value, context) {
|
|
|
18858
19893
|
return this.displayMasked(this.logTextOfLeaf(value, context), context);
|
|
18859
19894
|
}
|
|
18860
19895
|
|
|
18861
|
-
//#endregion
|
|
18862
|
-
//#region src/deployment/assumed-conditions.ts
|
|
18863
|
-
const assumedConditionNames = /* @__PURE__ */ new WeakMap();
|
|
18864
|
-
function recordAssumedConditions(conditions, assumed) {
|
|
18865
|
-
assumedConditionNames.set(conditions, assumed);
|
|
18866
|
-
}
|
|
18867
|
-
function conditionsAssumedFalse(conditions) {
|
|
18868
|
-
return assumedConditionNames.get(conditions) ?? /* @__PURE__ */ new Set();
|
|
18869
|
-
}
|
|
18870
|
-
|
|
18871
19896
|
//#endregion
|
|
18872
19897
|
//#region src/deployment/intrinsic-resolver/params-conditions.ts
|
|
18873
19898
|
async function resolveParameters(template, userParameters, options) {
|
|
@@ -19409,7 +20434,7 @@ var DiffCalculator = class DiffCalculator {
|
|
|
19409
20434
|
conditionalReplacementVerdict(resourceType, propertyPath, oldValue, newValue) {
|
|
19410
20435
|
return this.replacementRules.conditionalReplacementVerdict(resourceType, propertyPath, oldValue, newValue);
|
|
19411
20436
|
}
|
|
19412
|
-
async calculateDiff(currentState, desiredTemplate, resolveFn, canonicalizeProperties, allowedUnsupportedProperties, freshParameters, maskForLog, recreateTargets) {
|
|
20437
|
+
async calculateDiff(currentState, desiredTemplate, resolveFn, canonicalizeProperties, allowedUnsupportedProperties, freshParameters, maskForLog, recreateTargets, maskedInputs) {
|
|
19413
20438
|
const changes = /* @__PURE__ */ new Map();
|
|
19414
20439
|
refuseMalformedResourceEntriesForDeploy(currentState, void 0, void 0);
|
|
19415
20440
|
refuseMalformedResourceProperties(currentState, void 0, void 0);
|
|
@@ -19473,6 +20498,25 @@ var DiffCalculator = class DiffCalculator {
|
|
|
19473
20498
|
if (droppedKeys.length > 0) this.logger.warn(`${logicalId} (${desiredResource.Type}): part of the declared properties cannot be sent as declared and is ignored when comparing against deployed state — the provider narrows them (${droppedKeys.join(", ")}). Fix the template to declare only what the resource supports; until then changes to the ignored keys have no effect.`);
|
|
19474
20499
|
else if (canonicalizeProperties && !this.valuesEqual(desiredPropsForCompare, desiredAfterDrops)) this.logger.debug(`${logicalId} (${desiredResource.Type}): the provider normalizes part of the declared properties before sending them; the comparison uses the normalized form. Nothing is dropped.`);
|
|
19475
20500
|
const propertyChanges = await this.compareProperties(desiredResource.Type, currentPropsForCompare, desiredPropsForCompare, maskForLog);
|
|
20501
|
+
const reported = new Set(propertyChanges.map((pc) => pc.path));
|
|
20502
|
+
const rebaselined = [];
|
|
20503
|
+
const moved = await movedMaskedProperties(currentResource, rawDesiredProps, maskedInputs && inputFingerprinter(rawDesiredProps, maskedInputs.sources), maskedInputs?.rebaselined && ((key, fingerprint) => rebaselined.push([key, fingerprint])));
|
|
20504
|
+
if (rebaselined.length > 0) maskedInputs.rebaselined.set(logicalId, Object.fromEntries(rebaselined));
|
|
20505
|
+
for (const key of moved) {
|
|
20506
|
+
if (reported.has(key)) continue;
|
|
20507
|
+
if (!Object.hasOwn(currentPropsForCompare, key)) continue;
|
|
20508
|
+
if (!Object.hasOwn(desiredPropsForCompare, key)) continue;
|
|
20509
|
+
const oldValue = currentPropsForCompare[key];
|
|
20510
|
+
const newValue = desiredPropsForCompare[key];
|
|
20511
|
+
propertyChanges.push({
|
|
20512
|
+
path: key,
|
|
20513
|
+
oldValue,
|
|
20514
|
+
newValue,
|
|
20515
|
+
requiresReplacement: await this.maskedEditRequiresReplacement(desiredResource.Type, key, oldValue, newValue),
|
|
20516
|
+
maskedExpressionChanged: true
|
|
20517
|
+
});
|
|
20518
|
+
this.logger.debug(safeMsg`${logicalId}: ${key} is recorded masked and its template expression or a resolved input changed (go-to-k/cdkd#4451, go-to-k/cdkd#4543)`);
|
|
20519
|
+
}
|
|
19476
20520
|
const attributeChanges = this.compareAttributes(currentResource, desiredResource);
|
|
19477
20521
|
if (propertyChanges.length > 0 || attributeChanges.length > 0) {
|
|
19478
20522
|
changes.set(logicalId, {
|
|
@@ -19839,6 +20883,11 @@ var DiffCalculator = class DiffCalculator {
|
|
|
19839
20883
|
}
|
|
19840
20884
|
return changes;
|
|
19841
20885
|
}
|
|
20886
|
+
async maskedEditRequiresReplacement(resourceType, key, oldValue, newValue) {
|
|
20887
|
+
if (this.replacementRules.requiresReplacement(resourceType, key, oldValue, newValue)) return true;
|
|
20888
|
+
if (this.replacementRules.isClassified(resourceType, key)) return false;
|
|
20889
|
+
return (await getCreateOnlyPropertyPaths(resourceType)).some((path) => path.length === 1 && path[0] === key);
|
|
20890
|
+
}
|
|
19842
20891
|
static INTRINSIC_KEYS = INTRINSIC_KEYS;
|
|
19843
20892
|
static isIntrinsic(value) {
|
|
19844
20893
|
if (value === null || value === void 0 || typeof value !== "object" || Array.isArray(value)) return false;
|
|
@@ -20779,7 +21828,7 @@ var CloudControlProvider = class {
|
|
|
20779
21828
|
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
20780
21829
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
20781
21830
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
20782
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
21831
|
+
const { ASGProvider } = await import("./asg-provider-CbHiTBaE.js");
|
|
20783
21832
|
const delegateRegion = ambientRegion();
|
|
20784
21833
|
let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
|
|
20785
21834
|
if (asgProvider === void 0) {
|
|
@@ -20885,7 +21934,7 @@ var CloudControlProvider = class {
|
|
|
20885
21934
|
const family = SDK_DELETE_FAMILIES.get(resourceType);
|
|
20886
21935
|
const cached = this.sdkDeleteDelegates.get(family);
|
|
20887
21936
|
if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
|
|
20888
|
-
const provider = family === "rds" ? new (await (import("./rds-provider-
|
|
21937
|
+
const provider = family === "rds" ? new (await (import("./rds-provider-l9F4Y8YY.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-CS-r4Ufj.js"))).NeptuneProvider({ region: ccRegion });
|
|
20889
21938
|
this.sdkDeleteDelegates.set(family, {
|
|
20890
21939
|
region: ccRegion,
|
|
20891
21940
|
provider
|
|
@@ -24938,30 +25987,47 @@ async function reserveStackCreateToken(options) {
|
|
|
24938
25987
|
//#region src/deployment/inline-policy-claims.ts
|
|
24939
25988
|
function isInlinePolicyClaimedByCompletedWriter(args, kind, principal, policyName) {
|
|
24940
25989
|
const { selfLogicalId, writers, changes, stateResources } = args;
|
|
24941
|
-
const same = (a, b) => typeof a === "string" && IAM_NAME.test(a) && a.toLowerCase() === b.toLowerCase();
|
|
24942
25990
|
for (const [lid, write] of writers) {
|
|
24943
25991
|
if (lid === selfLogicalId || !Object.hasOwn(stateResources, lid)) continue;
|
|
24944
25992
|
const record = stateResources[lid];
|
|
24945
25993
|
if (record.provisionedBy === "cc-api") continue;
|
|
24946
25994
|
const props = record.properties ?? {};
|
|
24947
25995
|
if (record.resourceType === "AWS::IAM::Policy") {
|
|
24948
|
-
if (!
|
|
25996
|
+
if (!sameIamName(record.physicalId, policyName)) continue;
|
|
24949
25997
|
const listed = props[POLICY_LIST_FIELDS[kind]];
|
|
24950
|
-
if (Array.isArray(listed) && listed.some((p) =>
|
|
25998
|
+
if (Array.isArray(listed) && listed.some((p) => sameIamName(p, principal))) return true;
|
|
24951
25999
|
continue;
|
|
24952
26000
|
}
|
|
24953
26001
|
if (!Object.hasOwn(PRINCIPAL_KINDS, record.resourceType)) continue;
|
|
24954
26002
|
if (PRINCIPAL_KINDS[record.resourceType] !== kind) continue;
|
|
24955
|
-
if (!
|
|
26003
|
+
if (!sameIamName(record.physicalId, principal)) continue;
|
|
24956
26004
|
if (write !== "create" && !ownPoliciesChange(changes.get(lid))) continue;
|
|
24957
26005
|
const policies = props["Policies"];
|
|
24958
26006
|
if (!Array.isArray(policies)) continue;
|
|
24959
|
-
if (policies.some((entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry) &&
|
|
26007
|
+
if (policies.some((entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry) && sameIamName(entry["PolicyName"], policyName))) return true;
|
|
24960
26008
|
}
|
|
24961
26009
|
return false;
|
|
24962
26010
|
}
|
|
24963
26011
|
var RollbackInlinePolicyWriters = class {
|
|
24964
26012
|
entries = /* @__PURE__ */ new Map();
|
|
26013
|
+
removals = /* @__PURE__ */ new Map();
|
|
26014
|
+
unsettled = /* @__PURE__ */ new Map();
|
|
26015
|
+
notePending(ops) {
|
|
26016
|
+
for (const op of ops) if (!this.unsettled.has(op)) this.unsettled.set(op, {
|
|
26017
|
+
logicalId: op.logicalId,
|
|
26018
|
+
state: "pending"
|
|
26019
|
+
});
|
|
26020
|
+
}
|
|
26021
|
+
noteOutcome(op, completed) {
|
|
26022
|
+
if (!completed) {
|
|
26023
|
+
this.unsettled.set(op, {
|
|
26024
|
+
logicalId: op.logicalId,
|
|
26025
|
+
state: "failed"
|
|
26026
|
+
});
|
|
26027
|
+
return;
|
|
26028
|
+
}
|
|
26029
|
+
for (const [key, entry] of this.unsettled) if (key === op || entry.logicalId === op.logicalId) this.unsettled.delete(key);
|
|
26030
|
+
}
|
|
24965
26031
|
record(logicalId, write, record, policiesChanged, via) {
|
|
24966
26032
|
if (via === "cc-api") {
|
|
24967
26033
|
this.entries.delete(logicalId);
|
|
@@ -24993,15 +26059,100 @@ var RollbackInlinePolicyWriters = class {
|
|
|
24993
26059
|
}]
|
|
24994
26060
|
});
|
|
24995
26061
|
}
|
|
24996
|
-
|
|
26062
|
+
const claimed = isInlinePolicyClaimedByCompletedWriter({
|
|
24997
26063
|
selfLogicalId: logicalId,
|
|
24998
26064
|
writers,
|
|
24999
26065
|
changes,
|
|
25000
26066
|
stateResources
|
|
25001
26067
|
}, kind, principal, policyName);
|
|
26068
|
+
if (!claimed) {
|
|
26069
|
+
const key = removalKey(kind, principal, policyName);
|
|
26070
|
+
const noted = this.removals.get(key) ?? {
|
|
26071
|
+
kind,
|
|
26072
|
+
principal,
|
|
26073
|
+
policyName,
|
|
26074
|
+
removers: /* @__PURE__ */ new Map()
|
|
26075
|
+
};
|
|
26076
|
+
noted.removers.set(logicalId, stateResources[logicalId]);
|
|
26077
|
+
this.removals.set(key, noted);
|
|
26078
|
+
}
|
|
26079
|
+
return claimed;
|
|
25002
26080
|
};
|
|
25003
26081
|
}
|
|
26082
|
+
takeHeldRemovals(stateResources) {
|
|
26083
|
+
const held = [];
|
|
26084
|
+
for (const [key, { kind, principal, policyName, removers }] of this.removals) {
|
|
26085
|
+
const { holders, unreadable } = inlinePolicyHolders(stateResources, kind, principal, policyName);
|
|
26086
|
+
const others = holders.filter((h) => !removers.has(h.logicalId) || stateResources[h.logicalId] !== removers.get(h.logicalId));
|
|
26087
|
+
if (others.length === 0) continue;
|
|
26088
|
+
this.removals.delete(key);
|
|
26089
|
+
const open = new Set([...this.unsettled.values()].map((u) => u.logicalId));
|
|
26090
|
+
const unsettled = [...new Set(others.map((h) => h.logicalId))].filter((id) => open.has(id));
|
|
26091
|
+
held.push({
|
|
26092
|
+
kind,
|
|
26093
|
+
holders: others,
|
|
26094
|
+
unreadable,
|
|
26095
|
+
unsettled
|
|
26096
|
+
});
|
|
26097
|
+
}
|
|
26098
|
+
return held;
|
|
26099
|
+
}
|
|
25004
26100
|
};
|
|
26101
|
+
function inlinePolicyHolders(stateResources, kind, principal, policyName) {
|
|
26102
|
+
const holders = [];
|
|
26103
|
+
const unreadable = [];
|
|
26104
|
+
const unnamed = (v) => typeof v !== "string" || !IAM_NAME.test(v);
|
|
26105
|
+
for (const [logicalId, record] of Object.entries(stateResources)) {
|
|
26106
|
+
if (record === null || typeof record !== "object") continue;
|
|
26107
|
+
const props = record.properties ?? {};
|
|
26108
|
+
if (record.resourceType === "AWS::IAM::Policy") {
|
|
26109
|
+
const nameMatches = sameIamName(record.physicalId, policyName);
|
|
26110
|
+
if (!nameMatches && !unnamed(record.physicalId)) continue;
|
|
26111
|
+
const listed = props[POLICY_LIST_FIELDS[kind]];
|
|
26112
|
+
const entries = Array.isArray(listed) ? listed : [];
|
|
26113
|
+
const named = entries.find((p) => sameIamName(p, principal));
|
|
26114
|
+
if (nameMatches && typeof named === "string") holders.push({
|
|
26115
|
+
logicalId,
|
|
26116
|
+
principal: named,
|
|
26117
|
+
policyName: record.physicalId,
|
|
26118
|
+
document: props["PolicyDocument"]
|
|
26119
|
+
});
|
|
26120
|
+
else if (named !== void 0 || entries.some(unnamed)) unreadable.push(logicalId);
|
|
26121
|
+
continue;
|
|
26122
|
+
}
|
|
26123
|
+
if (!Object.hasOwn(PRINCIPAL_KINDS, record.resourceType)) continue;
|
|
26124
|
+
if (PRINCIPAL_KINDS[record.resourceType] !== kind) continue;
|
|
26125
|
+
const principalMatches = sameIamName(record.physicalId, principal);
|
|
26126
|
+
if (!principalMatches && !unnamed(record.physicalId)) continue;
|
|
26127
|
+
const policies = props["Policies"];
|
|
26128
|
+
if (!Array.isArray(policies)) continue;
|
|
26129
|
+
for (const entry of policies) {
|
|
26130
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) continue;
|
|
26131
|
+
const name = entry["PolicyName"];
|
|
26132
|
+
if (principalMatches && sameIamName(name, policyName)) holders.push({
|
|
26133
|
+
logicalId,
|
|
26134
|
+
principal: record.physicalId,
|
|
26135
|
+
policyName: name,
|
|
26136
|
+
document: entry["PolicyDocument"]
|
|
26137
|
+
});
|
|
26138
|
+
else if (unnamed(name) || sameIamName(name, policyName)) unreadable.push(logicalId);
|
|
26139
|
+
}
|
|
26140
|
+
}
|
|
26141
|
+
return {
|
|
26142
|
+
holders,
|
|
26143
|
+
unreadable: [...new Set(unreadable)]
|
|
26144
|
+
};
|
|
26145
|
+
}
|
|
26146
|
+
function sameIamName(a, b) {
|
|
26147
|
+
return typeof a === "string" && IAM_NAME.test(a) && a.toLowerCase() === b.toLowerCase();
|
|
26148
|
+
}
|
|
26149
|
+
function removalKey(kind, principal, policyName) {
|
|
26150
|
+
return JSON.stringify([
|
|
26151
|
+
kind,
|
|
26152
|
+
principal.toLowerCase(),
|
|
26153
|
+
policyName.toLowerCase()
|
|
26154
|
+
]);
|
|
26155
|
+
}
|
|
25005
26156
|
const IAM_NAME = /^[\w+=,.@-]+$/;
|
|
25006
26157
|
const POLICY_LIST_FIELDS = {
|
|
25007
26158
|
role: "Roles",
|
|
@@ -25561,6 +26712,18 @@ function deploymentEventsIndexKey(prefix, stackName, region) {
|
|
|
25561
26712
|
function deploymentsDirPrefix(prefix, stackName, region) {
|
|
25562
26713
|
return `${prefix}/${stackName}/${region}/deployments/`;
|
|
25563
26714
|
}
|
|
26715
|
+
const DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION = "deployment-event streams and their index, whose recorded error messages can quote values the secret mask does not catch";
|
|
26716
|
+
async function deleteAndPurgeEventObjects(backend, keys, dirPrefix) {
|
|
26717
|
+
if (keys.length === 0) return;
|
|
26718
|
+
try {
|
|
26719
|
+
await backend.deleteRawObjects(keys);
|
|
26720
|
+
} finally {
|
|
26721
|
+
await backend.purgeNoncurrentVersions(keys, {
|
|
26722
|
+
...keys.length > 1 && { listPrefix: dirPrefix },
|
|
26723
|
+
objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION
|
|
26724
|
+
});
|
|
26725
|
+
}
|
|
26726
|
+
}
|
|
25564
26727
|
function runIdTimestampMs(runId) {
|
|
25565
26728
|
const m = /^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})Z/.exec(runId);
|
|
25566
26729
|
if (!m) return null;
|
|
@@ -25705,7 +26868,7 @@ var DeploymentEventsStore = class {
|
|
|
25705
26868
|
return runId !== null && runId < cutoff;
|
|
25706
26869
|
});
|
|
25707
26870
|
if (stale.length === 0) return;
|
|
25708
|
-
await this.backend
|
|
26871
|
+
await deleteAndPurgeEventObjects(this.backend, stale, dirPrefix);
|
|
25709
26872
|
this.logger.debug(`Pruned ${stale.length} superseded deployment-event stream(s) for ${this.stackName} (${this.region})`);
|
|
25710
26873
|
}
|
|
25711
26874
|
warnOnce(message) {
|
|
@@ -25797,7 +26960,7 @@ var DeploymentEventsReader = class {
|
|
|
25797
26960
|
const indexExisted = keys.includes(indexKey);
|
|
25798
26961
|
if (opts.all === true) {
|
|
25799
26962
|
const toDelete = runIdsDesc.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
|
|
25800
|
-
await this.backend
|
|
26963
|
+
await deleteAndPurgeEventObjects(this.backend, [...toDelete, indexKey], dirPrefix);
|
|
25801
26964
|
return {
|
|
25802
26965
|
deletedRunIds: runIdsDesc,
|
|
25803
26966
|
remainingRunIds: [],
|
|
@@ -25823,35 +26986,39 @@ var DeploymentEventsReader = class {
|
|
|
25823
26986
|
const deletedSet = new Set(candidates);
|
|
25824
26987
|
const deleteKeys = candidates.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
|
|
25825
26988
|
const remainingRunIds = runIdsDesc.filter((id) => !deletedSet.has(id));
|
|
25826
|
-
|
|
25827
|
-
|
|
26989
|
+
if (remainingRunIds.length === 0) {
|
|
26990
|
+
await deleteAndPurgeEventObjects(this.backend, [...deleteKeys, indexKey], dirPrefix);
|
|
26991
|
+
return {
|
|
26992
|
+
deletedRunIds: candidates,
|
|
26993
|
+
remainingRunIds,
|
|
26994
|
+
indexDeleted: indexExisted
|
|
26995
|
+
};
|
|
26996
|
+
}
|
|
26997
|
+
await this.rewriteIndexAfterPrune(indexKey, stackName, region, deletedSet);
|
|
26998
|
+
await deleteAndPurgeEventObjects(this.backend, deleteKeys, dirPrefix);
|
|
25828
26999
|
return {
|
|
25829
27000
|
deletedRunIds: candidates,
|
|
25830
27001
|
remainingRunIds,
|
|
25831
|
-
indexDeleted
|
|
27002
|
+
indexDeleted: false
|
|
25832
27003
|
};
|
|
25833
27004
|
}
|
|
25834
|
-
async rewriteIndexAfterPrune(indexKey, stackName, region, deletedRunIds
|
|
25835
|
-
if (noRunsRemain) {
|
|
25836
|
-
await this.backend.deleteRawObjects([indexKey]);
|
|
25837
|
-
return indexExisted;
|
|
25838
|
-
}
|
|
27005
|
+
async rewriteIndexAfterPrune(indexKey, stackName, region, deletedRunIds) {
|
|
25839
27006
|
let raw;
|
|
25840
27007
|
try {
|
|
25841
27008
|
raw = await this.backend.getRawObject(indexKey);
|
|
25842
27009
|
} catch {
|
|
25843
|
-
return
|
|
27010
|
+
return;
|
|
25844
27011
|
}
|
|
25845
|
-
if (raw === null) return
|
|
27012
|
+
if (raw === null) return;
|
|
25846
27013
|
let parsed;
|
|
25847
27014
|
try {
|
|
25848
27015
|
parsed = JSON.parse(raw);
|
|
25849
27016
|
} catch {
|
|
25850
|
-
return
|
|
27017
|
+
return;
|
|
25851
27018
|
}
|
|
25852
|
-
if (!Array.isArray(parsed.runs)) return
|
|
27019
|
+
if (!Array.isArray(parsed.runs)) return;
|
|
25853
27020
|
const remaining = parsed.runs.filter((r) => !deletedRunIds.has(r.runId));
|
|
25854
|
-
if (remaining.length === parsed.runs.length) return
|
|
27021
|
+
if (remaining.length === parsed.runs.length) return;
|
|
25855
27022
|
const file = {
|
|
25856
27023
|
indexVersion: 1,
|
|
25857
27024
|
stackName,
|
|
@@ -25860,7 +27027,6 @@ var DeploymentEventsReader = class {
|
|
|
25860
27027
|
lastModified: Date.now()
|
|
25861
27028
|
};
|
|
25862
27029
|
await this.backend.putRawObject(indexKey, JSON.stringify(file, null, 2));
|
|
25863
|
-
return false;
|
|
25864
27030
|
}
|
|
25865
27031
|
};
|
|
25866
27032
|
|
|
@@ -25877,6 +27043,31 @@ function updatePartialMessage(reason) {
|
|
|
25877
27043
|
return `partial (${reason})`;
|
|
25878
27044
|
}
|
|
25879
27045
|
|
|
27046
|
+
//#endregion
|
|
27047
|
+
//#region src/provisioning/redacted-delete-address.ts
|
|
27048
|
+
function isRedactedRecordedValue(value) {
|
|
27049
|
+
if (carriesSecretMask(value)) return true;
|
|
27050
|
+
let text;
|
|
27051
|
+
try {
|
|
27052
|
+
text = typeof value === "string" ? value : JSON.stringify(value);
|
|
27053
|
+
} catch {
|
|
27054
|
+
return false;
|
|
27055
|
+
}
|
|
27056
|
+
return text !== void 0 && dynamicReferenceTokens(text).length > 0;
|
|
27057
|
+
}
|
|
27058
|
+
const REDACTED_DELETE_ADDRESS_SKIP_REASON = "redacted address property in state — no delete issued";
|
|
27059
|
+
function redactedDeleteAddressFields(fields) {
|
|
27060
|
+
return Object.keys(fields).filter((key) => isRedactedRecordedValue(fields[key]));
|
|
27061
|
+
}
|
|
27062
|
+
function redactedDeleteAddressSkip(logger, logicalId, what, redactedFields) {
|
|
27063
|
+
if (redactedFields.length === 0) return void 0;
|
|
27064
|
+
logger.warn(safeMsg`${what} ${logicalId} is recorded in state with ${redactedFields.join(", ")} ` + "redacted (the '***' mask of a NoEcho value it read, or a secret '{{resolve:...}}' reference), which names nothing in AWS; skipping deletion — no AWS call is issued, so the resource is LEFT IN PLACE unless a parent resource this run also deletes removes it (then only the record is stale). Re-deploying records the same redaction again. The state record is KEPT and the run reports the skip: on 'cdkd destroy' / 'cdkd state destroy' (which exits non-zero) and, since issue 1762, on the plain DELETE of a resource removed from the template during cdkd deploy. Remove the resource by hand, then clear the stack's records with 'cdkd state orphan <stack>' — that command drops EVERY record for the stack, not just this one. NOTE a deploy-side REPLACEMENT or rollback delete instead FAILS the resource (https://github.com/go-to-k/cdkd/issues/1762) — the old resource is left untracked there, so remove it by hand.");
|
|
27065
|
+
return {
|
|
27066
|
+
outcome: "skipped",
|
|
27067
|
+
reason: REDACTED_DELETE_ADDRESS_SKIP_REASON
|
|
27068
|
+
};
|
|
27069
|
+
}
|
|
27070
|
+
|
|
25880
27071
|
//#endregion
|
|
25881
27072
|
//#region src/provisioning/final-snapshot.ts
|
|
25882
27073
|
const ATOMIC_FINAL_SNAPSHOT_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -26204,30 +27395,6 @@ async function createReplicationGroupFinalSnapshot(client, replicationGroupId, l
|
|
|
26204
27395
|
const NESTED_STACK_RESOURCE_TYPE$1 = "AWS::CloudFormation::Stack";
|
|
26205
27396
|
const nonEmptyString = (v) => typeof v === "string" && v.length > 0;
|
|
26206
27397
|
|
|
26207
|
-
//#endregion
|
|
26208
|
-
//#region src/deployment/producer-regions-scope.ts
|
|
26209
|
-
const producerRegionsStore = new AsyncLocalStorage();
|
|
26210
|
-
function withProducerRegions(evidence, fn) {
|
|
26211
|
-
return producerRegionsStore.run(evidence, fn);
|
|
26212
|
-
}
|
|
26213
|
-
function getCurrentProducerRegions() {
|
|
26214
|
-
return producerRegionsStore.getStore();
|
|
26215
|
-
}
|
|
26216
|
-
function inheritProducerRegions(own, inherited) {
|
|
26217
|
-
const seen = /* @__PURE__ */ new Set();
|
|
26218
|
-
const regions = [];
|
|
26219
|
-
for (const region of [...own, ...inherited?.regions ?? []]) {
|
|
26220
|
-
const canonical = canonicalizeRegion(region);
|
|
26221
|
-
if (!canonical || seen.has(canonical)) continue;
|
|
26222
|
-
seen.add(canonical);
|
|
26223
|
-
regions.push(region);
|
|
26224
|
-
}
|
|
26225
|
-
return {
|
|
26226
|
-
regions,
|
|
26227
|
-
complete: inherited?.complete === true
|
|
26228
|
-
};
|
|
26229
|
-
}
|
|
26230
|
-
|
|
26231
27398
|
//#endregion
|
|
26232
27399
|
//#region src/deployment/rollback-executor/messages.ts
|
|
26233
27400
|
function throwIfDeleteSkipped(result, logicalId, physicalId, duringClause) {
|
|
@@ -26371,6 +27538,271 @@ function retainedSurvivorMessages(logicalId, resourceType, survivorPhysicalId, s
|
|
|
26371
27538
|
};
|
|
26372
27539
|
}
|
|
26373
27540
|
|
|
27541
|
+
//#endregion
|
|
27542
|
+
//#region src/deployment/rollback-executor/names.ts
|
|
27543
|
+
function replayPrefixScope(input, logger, mask, restoring) {
|
|
27544
|
+
const choice = replayPrefixChoice(input);
|
|
27545
|
+
if (choice.kind === "not-applicable") return (fn) => fn();
|
|
27546
|
+
const setting = (skip) => skip ? "SKIPPED" : "KEPT";
|
|
27547
|
+
const subject = `${safe(input.logicalId)} (${safe(input.resourceType)})`;
|
|
27548
|
+
const declared = choice.declared;
|
|
27549
|
+
const secretDerived = declared !== void 0 && mask(declared) !== declared;
|
|
27550
|
+
const withheld = secretDerived || choice.kind === "unreproduced" && declared === void 0;
|
|
27551
|
+
const shown = (value) => displayIdent(mask(String(value)));
|
|
27552
|
+
const quoted = (value) => {
|
|
27553
|
+
const masked = mask(value);
|
|
27554
|
+
const rendered = displayIdent(masked);
|
|
27555
|
+
return rendered === masked ? `"${masked}"` : rendered;
|
|
27556
|
+
};
|
|
27557
|
+
if (choice.kind === "reproduced" && choice.skipPrefix !== choice.recorded) logger.info(mask(` Rollback: ${restoring ? "re-creating" : "reverting"} ${subject} under the user-supplied-name prefix setting that created ` + (withheld ? `it (its physical id is withheld, as its name is secret-derived): ` : `${shown(input.physicalId)} (`) + `stack-name prefix ${setting(choice.skipPrefix)}; the failed deploy ran with it ${setting(choice.recorded)}${withheld ? "" : ")"}`));
|
|
27558
|
+
else if (choice.kind === "unreproduced" && restoring) {
|
|
27559
|
+
const idUnreadable = typeof input.physicalId !== "string" || input.physicalId === "";
|
|
27560
|
+
const prop = safe(choice.property);
|
|
27561
|
+
const unreadable = declared === void 0 ? idUnreadable ? `its ${prop} or its physical id` : `its ${prop}` : idUnreadable ? `its physical id` : void 0;
|
|
27562
|
+
logger.warn(mask(` ⚠ ${subject}: cdkd cannot tell which user-supplied-name prefix setting created the old resource (` + (withheld ? `its physical id is withheld, as its name is secret-derived or unreadable` : shown(input.physicalId)) + `) — ` + (choice.names === void 0 ? unreadable !== void 0 ? `cdkd cannot read ${unreadable} to compare` : `cdkd cannot derive the names its ${prop} takes to compare` : secretDerived ? `its ${prop} is secret-derived, and neither name it derives matches` : `its ${prop} derives to ${quoted(choice.names.skipped)} (prefix skipped) or ${quoted(choice.names.kept)} (prefix kept), and it is neither`) + `; re-creating it with the stack-name prefix ${setting(choice.skipPrefix)}, as the failed deploy ran, so it may come back under a different physical name.`));
|
|
27563
|
+
}
|
|
27564
|
+
const skip = choice.skipPrefix;
|
|
27565
|
+
return (fn) => withSkipPrefix(skip, fn);
|
|
27566
|
+
}
|
|
27567
|
+
function createOpMasker(logger, secrets) {
|
|
27568
|
+
const base = createMaskedLogSinks(logger, (text) => maskSecretsInText(text, secrets));
|
|
27569
|
+
const pairs = [];
|
|
27570
|
+
let sinks = base;
|
|
27571
|
+
return {
|
|
27572
|
+
mask: (text) => typeof text === "string" ? sinks.mask(text) : text,
|
|
27573
|
+
addNamed: (record) => {
|
|
27574
|
+
pairs.push(...secretDerivedNamePairs(record));
|
|
27575
|
+
sinks = withDerivedNameMasks(logger, base, pairs);
|
|
27576
|
+
}
|
|
27577
|
+
};
|
|
27578
|
+
}
|
|
27579
|
+
const OTHER_SPELLED_NAME_KEYS = {
|
|
27580
|
+
"AWS::Cognito::UserPoolDomain": ["Domain"],
|
|
27581
|
+
"AWS::Cognito::UserPoolUser": ["Username"],
|
|
27582
|
+
"AWS::ECS::TaskDefinition": ["Family"],
|
|
27583
|
+
"AWS::ElastiCache::ReplicationGroup": ["ReplicationGroupId"],
|
|
27584
|
+
"AWS::ElastiCache::User": ["UserId"],
|
|
27585
|
+
"AWS::ElastiCache::UserGroup": ["UserGroupId"],
|
|
27586
|
+
"AWS::SES::EmailIdentity": ["EmailIdentity"]
|
|
27587
|
+
};
|
|
27588
|
+
const COMPOSITE_SCOPE_LAST = /^(?:REGIONAL|CLOUDFRONT|GLOBAL)$/;
|
|
27589
|
+
const COMPOSITE_POOL_FIRST = /^[a-z]{2}(?:-gov)?-[a-z]+-\d+_[A-Za-z0-9]+$/;
|
|
27590
|
+
function idNameSegments(id) {
|
|
27591
|
+
const segments = /* @__PURE__ */ new Set();
|
|
27592
|
+
const arn = /^arn:[^:]*:([^:]*):[^:]*:[^:]*:(.+)$/.exec(id);
|
|
27593
|
+
if (arn !== null) {
|
|
27594
|
+
const service = arn[1];
|
|
27595
|
+
const resource = arn[2];
|
|
27596
|
+
const lambda = service === "lambda" ? /^(?:function|layer):([^:]+)(?::([^:]+))?/.exec(resource) : null;
|
|
27597
|
+
if (lambda !== null) {
|
|
27598
|
+
segments.add(lambda[1]);
|
|
27599
|
+
const qualifier = lambda[2];
|
|
27600
|
+
if (qualifier !== void 0 && !/^\d+$/.test(qualifier)) segments.add(qualifier);
|
|
27601
|
+
} else {
|
|
27602
|
+
const parts = resource.split(/[/:]/).filter((part) => part !== "");
|
|
27603
|
+
let body = parts.length > 1 ? parts.slice(1) : parts;
|
|
27604
|
+
if (body.length > 1 && /^\d+$/.test(body[body.length - 1])) body = body.slice(0, -1);
|
|
27605
|
+
for (const part of body) {
|
|
27606
|
+
segments.add(part);
|
|
27607
|
+
if (service === "secretsmanager") segments.add(part.replace(/-[A-Za-z0-9]{6}$/, ""));
|
|
27608
|
+
}
|
|
27609
|
+
}
|
|
27610
|
+
}
|
|
27611
|
+
if (id.includes("/")) {
|
|
27612
|
+
const afterSlash = id.slice(id.lastIndexOf("/") + 1);
|
|
27613
|
+
segments.add(afterSlash);
|
|
27614
|
+
segments.add(afterSlash.replace(/:\d+$/, ""));
|
|
27615
|
+
}
|
|
27616
|
+
if (id.includes("|")) {
|
|
27617
|
+
const parts = id.split("|");
|
|
27618
|
+
parts.forEach((part, index) => {
|
|
27619
|
+
if (part === "") return;
|
|
27620
|
+
if (index === parts.length - 1 && parts.length > 1 && COMPOSITE_SCOPE_LAST.test(part)) return;
|
|
27621
|
+
if (index === 0 && parts.length > 1 && COMPOSITE_POOL_FIRST.test(part)) return;
|
|
27622
|
+
segments.add(part);
|
|
27623
|
+
});
|
|
27624
|
+
}
|
|
27625
|
+
return [...segments].filter((segment) => segment.length >= 4 && segment !== id);
|
|
27626
|
+
}
|
|
27627
|
+
function ownEntry(table, key) {
|
|
27628
|
+
return Object.hasOwn(table, key) ? table[key] : void 0;
|
|
27629
|
+
}
|
|
27630
|
+
function secretDerivedNamePairs(record) {
|
|
27631
|
+
const { resourceType, properties, logicalId } = record;
|
|
27632
|
+
if (typeof resourceType !== "string" || !isRestorableBag(properties)) return [];
|
|
27633
|
+
const rewritten = reverseReplacementRewrittenNameTypes();
|
|
27634
|
+
const named = /* @__PURE__ */ new Set();
|
|
27635
|
+
const primary = Object.hasOwn(rewritten, resourceType) ? rewritten[resourceType].property : explicitNamePropertyFor(resourceType);
|
|
27636
|
+
if (typeof primary === "string") named.add(primary);
|
|
27637
|
+
for (const key of Object.keys(properties)) if (/(?:Name|Identifier)$/.test(key)) named.add(key);
|
|
27638
|
+
for (const key of ownEntry(OTHER_SPELLED_NAME_KEYS, resourceType) ?? []) named.add(key);
|
|
27639
|
+
const idSpellings = record.physicalIds.filter((id) => typeof id === "string" && id !== "").flatMap((id) => [
|
|
27640
|
+
id,
|
|
27641
|
+
...id.toLowerCase() === id || id.length < 4 ? [] : [id.toLowerCase()],
|
|
27642
|
+
finalSnapshotNamePrefix(id, resourceType),
|
|
27643
|
+
...idNameSegments(id)
|
|
27644
|
+
]);
|
|
27645
|
+
const pairs = [];
|
|
27646
|
+
for (const key of named) {
|
|
27647
|
+
if (!Object.hasOwn(properties, key)) continue;
|
|
27648
|
+
const value = properties[key];
|
|
27649
|
+
if (typeof value !== "string" || value === "") continue;
|
|
27650
|
+
const derived = key === primary && !value.includes("{{resolve:") && value !== "***" ? rewrittenNameSpellings(resourceType, value, logicalId) : [];
|
|
27651
|
+
for (const spelling of [...idSpellings, ...derived]) pairs.push([value, spelling]);
|
|
27652
|
+
}
|
|
27653
|
+
return pairs;
|
|
27654
|
+
}
|
|
27655
|
+
function addRecordNames(opMasker, op, current) {
|
|
27656
|
+
const { logicalId } = op;
|
|
27657
|
+
for (const properties of [op.properties, op.attemptedProperties]) opMasker.addNamed({
|
|
27658
|
+
resourceType: op.resourceType,
|
|
27659
|
+
properties,
|
|
27660
|
+
logicalId,
|
|
27661
|
+
physicalIds: [op.physicalId]
|
|
27662
|
+
});
|
|
27663
|
+
for (const record of [op.previousState, current]) {
|
|
27664
|
+
if (record === null || typeof record !== "object") continue;
|
|
27665
|
+
opMasker.addNamed({
|
|
27666
|
+
resourceType: record.resourceType ?? op.resourceType,
|
|
27667
|
+
properties: record.properties,
|
|
27668
|
+
logicalId,
|
|
27669
|
+
physicalIds: [record.physicalId]
|
|
27670
|
+
});
|
|
27671
|
+
}
|
|
27672
|
+
}
|
|
27673
|
+
const ABSENT_BASELINE_SKIP_CAUSE = "Its recorded previous state has no `properties` bag, so there is nothing to restore it to; the rollback left the resource exactly as it is.";
|
|
27674
|
+
function requireRestorableBaseline(bag, logger, { logicalId, consequence, remedy, retry }) {
|
|
27675
|
+
if (isRestorableBag(bag)) return true;
|
|
27676
|
+
if (bag === void 0) {
|
|
27677
|
+
logger.warn(` Rollback: Cannot restore ${shownLogicalId(logicalId)} \u2014 its recorded previous state has no \`properties\` bag, so there is nothing to restore it to. An empty desired state would ${consequence}. The resource is therefore left exactly as it is. ${remedy}`);
|
|
27678
|
+
return false;
|
|
27679
|
+
}
|
|
27680
|
+
const shape = bag === null ? "null" : Array.isArray(bag) ? "an array" : `a ${typeof bag}`;
|
|
27681
|
+
throw new CdkdError(`Cannot roll ${shownLogicalId(logicalId)} back: its recorded previous state has a \`properties\` field that is not a property bag (${shape}), so cdkd cannot tell what to restore it to. Replaying it would do one of two things, and cdkd does neither: send the malformed value to the provider as-is, or send an empty desired state (which would ${consequence}). The rollback JOURNAL record is kept: once that record holds a property bag again, ${retry}. Otherwise fix forward with \`cdkd deploy\`, or remove the stack with \`cdkd destroy\`.`, "ROLLBACK_UNUSABLE_BASELINE");
|
|
27682
|
+
}
|
|
27683
|
+
function isRestorableBag(bag) {
|
|
27684
|
+
return typeof bag === "object" && bag !== null && !Array.isArray(bag);
|
|
27685
|
+
}
|
|
27686
|
+
async function prepareCreateRollbackFinalSnapshot(op, provisionedBy, ctx, mask) {
|
|
27687
|
+
const { logicalId, resourceType } = op;
|
|
27688
|
+
const physicalId = op.physicalId;
|
|
27689
|
+
switch (finalSnapshotMechanism(resourceType, provisionedBy)) {
|
|
27690
|
+
case "atomic-delete-parameter": return buildFinalSnapshotIdentifier(physicalId, resourceType);
|
|
27691
|
+
case "pre-delete-snapshot":
|
|
27692
|
+
await createPreDeleteFinalSnapshot(resourceType, physicalId, logicalId, ctx.finalSnapshotClients ?? getAwsClients(), {
|
|
27693
|
+
info: (message) => ctx.logger.info(mask(message)),
|
|
27694
|
+
debug: (message) => ctx.logger.debug(mask(message))
|
|
27695
|
+
});
|
|
27696
|
+
return;
|
|
27697
|
+
case "refuse-cc-routed": throw ccRoutedFinalSnapshotError(logicalId, resourceType, SKIP_FINAL_SNAPSHOT_FLAG);
|
|
27698
|
+
case "refuse-unsupported-type": throw unsupportedFinalSnapshotError(logicalId, resourceType, SKIP_FINAL_SNAPSHOT_FLAG);
|
|
27699
|
+
}
|
|
27700
|
+
}
|
|
27701
|
+
|
|
27702
|
+
//#endregion
|
|
27703
|
+
//#region src/deployment/rollback-executor/replay-inline-policy-restore.ts
|
|
27704
|
+
async function restoreHeldInlinePolicies(writers, stateResources, stackName, ctx, result, options = {}) {
|
|
27705
|
+
for (const removal of writers.takeHeldRemovals(stateResources)) await restoreOne(removal, stateResources, stackName, ctx, result, options.refuseAll === true);
|
|
27706
|
+
}
|
|
27707
|
+
async function restoreOne({ kind, holders, unreadable, unsettled }, stateResources, stackName, ctx, result, refuseAll) {
|
|
27708
|
+
const { logger } = ctx;
|
|
27709
|
+
const ids = [...new Set(holders.map((h) => h.logicalId))].map((id) => safe(id)).join(", ");
|
|
27710
|
+
const lost = safeMsg`the ${kind} it is on lacks that inline policy until the resource is next updated, or ` + `'cdkd drift <stack> --revert' restores it`;
|
|
27711
|
+
if (refuseAll || unsettled.length > 0) {
|
|
27712
|
+
const pending = refuseAll ? ids : unsettled.map((id) => safe(id)).join(", ");
|
|
27713
|
+
logger.warn(safeMsg` Rollback: an inline policy this rollback removed is recorded by ${ids}, but the ` + safeMsg`rollback of ${pending} has not completed, so that record may be the failed ` + safeMsg`deploy's and cdkd did not put it back; ${lost}.`);
|
|
27714
|
+
result.warnings++;
|
|
27715
|
+
return;
|
|
27716
|
+
}
|
|
27717
|
+
if (unreadable.length > 0) {
|
|
27718
|
+
logger.warn(safeMsg` Rollback: an inline policy this rollback removed is recorded by ${ids}, and ` + safeMsg`${unreadable.map((id) => safe(id)).join(", ")} may record it too under a redacted ` + safeMsg`name, so cdkd did not put it back; ${lost}.`);
|
|
27719
|
+
result.warnings++;
|
|
27720
|
+
return;
|
|
27721
|
+
}
|
|
27722
|
+
const documents = holders.map((h) => serializedDocument(h.document));
|
|
27723
|
+
if (documents.some((d) => d === void 0)) {
|
|
27724
|
+
logger.warn(safeMsg` Rollback: an inline policy this rollback removed is still recorded by ${ids}, but its ` + safeMsg`recorded document is absent or redacted, so cdkd did not put it back; ${lost}.`);
|
|
27725
|
+
result.warnings++;
|
|
27726
|
+
return;
|
|
27727
|
+
}
|
|
27728
|
+
if (new Set(documents).size > 1) {
|
|
27729
|
+
logger.warn(safeMsg` Rollback: an inline policy this rollback removed is recorded by ${ids} with different ` + safeMsg`documents under one name on one ${kind}, so cdkd put neither back; ${lost}.`);
|
|
27730
|
+
result.warnings++;
|
|
27731
|
+
return;
|
|
27732
|
+
}
|
|
27733
|
+
const holder = holders[0];
|
|
27734
|
+
const secrets = /* @__PURE__ */ new Map();
|
|
27735
|
+
for (const h of holders) {
|
|
27736
|
+
const bag = ctx.logOnlyNeedlesFor?.(h.logicalId);
|
|
27737
|
+
if (bag) carryLogOnlyValues(bag, secrets);
|
|
27738
|
+
}
|
|
27739
|
+
const masker = createOpMasker(logger, secrets);
|
|
27740
|
+
for (const h of holders) {
|
|
27741
|
+
const record = stateResources[h.logicalId];
|
|
27742
|
+
addRecordNames(masker, {
|
|
27743
|
+
logicalId: h.logicalId,
|
|
27744
|
+
resourceType: record?.resourceType,
|
|
27745
|
+
physicalId: record?.physicalId
|
|
27746
|
+
}, record);
|
|
27747
|
+
}
|
|
27748
|
+
try {
|
|
27749
|
+
const { provider, provisionedBy } = ctx.providerRegistry.getProviderFor({
|
|
27750
|
+
resourceType: "AWS::IAM::Policy",
|
|
27751
|
+
provisionedBy: "sdk"
|
|
27752
|
+
});
|
|
27753
|
+
if (provisionedBy !== "sdk") throw new Error("AWS::IAM::Policy is not routed to its SDK provider");
|
|
27754
|
+
await provider.create(holder.logicalId, "AWS::IAM::Policy", {
|
|
27755
|
+
PolicyName: holder.policyName,
|
|
27756
|
+
PolicyDocument: holder.document,
|
|
27757
|
+
[POLICY_LIST_FIELDS[kind]]: [holder.principal]
|
|
27758
|
+
}, { maskSecrets: masker.mask });
|
|
27759
|
+
} catch (error) {
|
|
27760
|
+
logger.warn(maskedFailureText(safeMsg` Rollback: could not put back the inline policy ${ids} records on its ${kind} ` + safeMsg`(${lost}): `, error, masker.mask));
|
|
27761
|
+
result.warnings++;
|
|
27762
|
+
return;
|
|
27763
|
+
}
|
|
27764
|
+
logger.info(safeMsg` Rollback: put back the inline policy ${ids} records on its ${kind}`);
|
|
27765
|
+
const holderType = stateResources[holder.logicalId]?.resourceType;
|
|
27766
|
+
ctx.recordEvent?.({
|
|
27767
|
+
eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
|
|
27768
|
+
stackName,
|
|
27769
|
+
operation: "UPDATE",
|
|
27770
|
+
logicalId: holder.logicalId,
|
|
27771
|
+
...typeof holderType === "string" && { resourceType: holderType },
|
|
27772
|
+
provisionedBy: "sdk",
|
|
27773
|
+
reason: `Put back the inline policy this resource records on its ${kind}, which the rollback had removed from it.`
|
|
27774
|
+
});
|
|
27775
|
+
}
|
|
27776
|
+
function serializedDocument(document) {
|
|
27777
|
+
if (typeof document === "string") return document.length > 0 && !isRedactedRecordedValue(document) ? document : void 0;
|
|
27778
|
+
if (document === null || typeof document !== "object" || Array.isArray(document)) return;
|
|
27779
|
+
return isRedactedRecordedValue(document) ? void 0 : JSON.stringify(document);
|
|
27780
|
+
}
|
|
27781
|
+
|
|
27782
|
+
//#endregion
|
|
27783
|
+
//#region src/deployment/producer-regions-scope.ts
|
|
27784
|
+
const producerRegionsStore = new AsyncLocalStorage();
|
|
27785
|
+
function withProducerRegions(evidence, fn) {
|
|
27786
|
+
return producerRegionsStore.run(evidence, fn);
|
|
27787
|
+
}
|
|
27788
|
+
function getCurrentProducerRegions() {
|
|
27789
|
+
return producerRegionsStore.getStore();
|
|
27790
|
+
}
|
|
27791
|
+
function inheritProducerRegions(own, inherited) {
|
|
27792
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27793
|
+
const regions = [];
|
|
27794
|
+
for (const region of [...own, ...inherited?.regions ?? []]) {
|
|
27795
|
+
const canonical = canonicalizeRegion(region);
|
|
27796
|
+
if (!canonical || seen.has(canonical)) continue;
|
|
27797
|
+
seen.add(canonical);
|
|
27798
|
+
regions.push(region);
|
|
27799
|
+
}
|
|
27800
|
+
return {
|
|
27801
|
+
regions,
|
|
27802
|
+
complete: inherited?.complete === true
|
|
27803
|
+
};
|
|
27804
|
+
}
|
|
27805
|
+
|
|
26374
27806
|
//#endregion
|
|
26375
27807
|
//#region src/deployment/rollback-executor/replay-secrets.ts
|
|
26376
27808
|
function replayProducerRegionEvidence(ctx) {
|
|
@@ -26590,7 +28022,7 @@ function classifyFailedOp(op, stateResources) {
|
|
|
26590
28022
|
if (op.changeType === "CREATE") {
|
|
26591
28023
|
if (!op.physicalId) return "skip-failed-unknown";
|
|
26592
28024
|
if (!current) return "skip-failed-noop";
|
|
26593
|
-
if (current.physicalId !== op.physicalId) return "skip-failed-
|
|
28025
|
+
if (current.physicalId !== op.physicalId) return "skip-failed-mismatch";
|
|
26594
28026
|
const policy = effectiveDeletionPolicy(current.resourceType, current.deletionPolicy, current.properties);
|
|
26595
28027
|
if (policy === "Retain") return "orphan-failed-create-retain";
|
|
26596
28028
|
if (policy === "Snapshot") return "delete-failed-create-with-final-snapshot";
|
|
@@ -26674,167 +28106,6 @@ function sortRollbackCreates(createOps, stateResources, logger) {
|
|
|
26674
28106
|
return sorted;
|
|
26675
28107
|
}
|
|
26676
28108
|
|
|
26677
|
-
//#endregion
|
|
26678
|
-
//#region src/deployment/rollback-executor/names.ts
|
|
26679
|
-
function replayPrefixScope(input, logger, mask, restoring) {
|
|
26680
|
-
const choice = replayPrefixChoice(input);
|
|
26681
|
-
if (choice.kind === "not-applicable") return (fn) => fn();
|
|
26682
|
-
const setting = (skip) => skip ? "SKIPPED" : "KEPT";
|
|
26683
|
-
const subject = `${safe(input.logicalId)} (${safe(input.resourceType)})`;
|
|
26684
|
-
const declared = choice.declared;
|
|
26685
|
-
const secretDerived = declared !== void 0 && mask(declared) !== declared;
|
|
26686
|
-
const withheld = secretDerived || choice.kind === "unreproduced" && declared === void 0;
|
|
26687
|
-
const shown = (value) => displayIdent(mask(String(value)));
|
|
26688
|
-
const quoted = (value) => {
|
|
26689
|
-
const masked = mask(value);
|
|
26690
|
-
const rendered = displayIdent(masked);
|
|
26691
|
-
return rendered === masked ? `"${masked}"` : rendered;
|
|
26692
|
-
};
|
|
26693
|
-
if (choice.kind === "reproduced" && choice.skipPrefix !== choice.recorded) logger.info(mask(` Rollback: ${restoring ? "re-creating" : "reverting"} ${subject} under the user-supplied-name prefix setting that created ` + (withheld ? `it (its physical id is withheld, as its name is secret-derived): ` : `${shown(input.physicalId)} (`) + `stack-name prefix ${setting(choice.skipPrefix)}; the failed deploy ran with it ${setting(choice.recorded)}${withheld ? "" : ")"}`));
|
|
26694
|
-
else if (choice.kind === "unreproduced" && restoring) {
|
|
26695
|
-
const idUnreadable = typeof input.physicalId !== "string" || input.physicalId === "";
|
|
26696
|
-
const prop = safe(choice.property);
|
|
26697
|
-
const unreadable = declared === void 0 ? idUnreadable ? `its ${prop} or its physical id` : `its ${prop}` : idUnreadable ? `its physical id` : void 0;
|
|
26698
|
-
logger.warn(mask(` ⚠ ${subject}: cdkd cannot tell which user-supplied-name prefix setting created the old resource (` + (withheld ? `its physical id is withheld, as its name is secret-derived or unreadable` : shown(input.physicalId)) + `) — ` + (choice.names === void 0 ? unreadable !== void 0 ? `cdkd cannot read ${unreadable} to compare` : `cdkd cannot derive the names its ${prop} takes to compare` : secretDerived ? `its ${prop} is secret-derived, and neither name it derives matches` : `its ${prop} derives to ${quoted(choice.names.skipped)} (prefix skipped) or ${quoted(choice.names.kept)} (prefix kept), and it is neither`) + `; re-creating it with the stack-name prefix ${setting(choice.skipPrefix)}, as the failed deploy ran, so it may come back under a different physical name.`));
|
|
26699
|
-
}
|
|
26700
|
-
const skip = choice.skipPrefix;
|
|
26701
|
-
return (fn) => withSkipPrefix(skip, fn);
|
|
26702
|
-
}
|
|
26703
|
-
function createOpMasker(logger, secrets) {
|
|
26704
|
-
const base = createMaskedLogSinks(logger, (text) => maskSecretsInText(text, secrets));
|
|
26705
|
-
const pairs = [];
|
|
26706
|
-
let sinks = base;
|
|
26707
|
-
return {
|
|
26708
|
-
mask: (text) => typeof text === "string" ? sinks.mask(text) : text,
|
|
26709
|
-
addNamed: (record) => {
|
|
26710
|
-
pairs.push(...secretDerivedNamePairs(record));
|
|
26711
|
-
sinks = withDerivedNameMasks(logger, base, pairs);
|
|
26712
|
-
}
|
|
26713
|
-
};
|
|
26714
|
-
}
|
|
26715
|
-
const OTHER_SPELLED_NAME_KEYS = {
|
|
26716
|
-
"AWS::Cognito::UserPoolDomain": ["Domain"],
|
|
26717
|
-
"AWS::Cognito::UserPoolUser": ["Username"],
|
|
26718
|
-
"AWS::ECS::TaskDefinition": ["Family"],
|
|
26719
|
-
"AWS::ElastiCache::ReplicationGroup": ["ReplicationGroupId"],
|
|
26720
|
-
"AWS::ElastiCache::User": ["UserId"],
|
|
26721
|
-
"AWS::ElastiCache::UserGroup": ["UserGroupId"],
|
|
26722
|
-
"AWS::SES::EmailIdentity": ["EmailIdentity"]
|
|
26723
|
-
};
|
|
26724
|
-
const COMPOSITE_SCOPE_LAST = /^(?:REGIONAL|CLOUDFRONT|GLOBAL)$/;
|
|
26725
|
-
const COMPOSITE_POOL_FIRST = /^[a-z]{2}(?:-gov)?-[a-z]+-\d+_[A-Za-z0-9]+$/;
|
|
26726
|
-
function idNameSegments(id) {
|
|
26727
|
-
const segments = /* @__PURE__ */ new Set();
|
|
26728
|
-
const arn = /^arn:[^:]*:([^:]*):[^:]*:[^:]*:(.+)$/.exec(id);
|
|
26729
|
-
if (arn !== null) {
|
|
26730
|
-
const service = arn[1];
|
|
26731
|
-
const resource = arn[2];
|
|
26732
|
-
const lambda = service === "lambda" ? /^(?:function|layer):([^:]+)(?::([^:]+))?/.exec(resource) : null;
|
|
26733
|
-
if (lambda !== null) {
|
|
26734
|
-
segments.add(lambda[1]);
|
|
26735
|
-
const qualifier = lambda[2];
|
|
26736
|
-
if (qualifier !== void 0 && !/^\d+$/.test(qualifier)) segments.add(qualifier);
|
|
26737
|
-
} else {
|
|
26738
|
-
const parts = resource.split(/[/:]/).filter((part) => part !== "");
|
|
26739
|
-
let body = parts.length > 1 ? parts.slice(1) : parts;
|
|
26740
|
-
if (body.length > 1 && /^\d+$/.test(body[body.length - 1])) body = body.slice(0, -1);
|
|
26741
|
-
for (const part of body) {
|
|
26742
|
-
segments.add(part);
|
|
26743
|
-
if (service === "secretsmanager") segments.add(part.replace(/-[A-Za-z0-9]{6}$/, ""));
|
|
26744
|
-
}
|
|
26745
|
-
}
|
|
26746
|
-
}
|
|
26747
|
-
if (id.includes("/")) {
|
|
26748
|
-
const afterSlash = id.slice(id.lastIndexOf("/") + 1);
|
|
26749
|
-
segments.add(afterSlash);
|
|
26750
|
-
segments.add(afterSlash.replace(/:\d+$/, ""));
|
|
26751
|
-
}
|
|
26752
|
-
if (id.includes("|")) {
|
|
26753
|
-
const parts = id.split("|");
|
|
26754
|
-
parts.forEach((part, index) => {
|
|
26755
|
-
if (part === "") return;
|
|
26756
|
-
if (index === parts.length - 1 && parts.length > 1 && COMPOSITE_SCOPE_LAST.test(part)) return;
|
|
26757
|
-
if (index === 0 && parts.length > 1 && COMPOSITE_POOL_FIRST.test(part)) return;
|
|
26758
|
-
segments.add(part);
|
|
26759
|
-
});
|
|
26760
|
-
}
|
|
26761
|
-
return [...segments].filter((segment) => segment.length >= 4 && segment !== id);
|
|
26762
|
-
}
|
|
26763
|
-
function ownEntry(table, key) {
|
|
26764
|
-
return Object.hasOwn(table, key) ? table[key] : void 0;
|
|
26765
|
-
}
|
|
26766
|
-
function secretDerivedNamePairs(record) {
|
|
26767
|
-
const { resourceType, properties, logicalId } = record;
|
|
26768
|
-
if (typeof resourceType !== "string" || !isRestorableBag(properties)) return [];
|
|
26769
|
-
const rewritten = reverseReplacementRewrittenNameTypes();
|
|
26770
|
-
const named = /* @__PURE__ */ new Set();
|
|
26771
|
-
const primary = Object.hasOwn(rewritten, resourceType) ? rewritten[resourceType].property : explicitNamePropertyFor(resourceType);
|
|
26772
|
-
if (typeof primary === "string") named.add(primary);
|
|
26773
|
-
for (const key of Object.keys(properties)) if (/(?:Name|Identifier)$/.test(key)) named.add(key);
|
|
26774
|
-
for (const key of ownEntry(OTHER_SPELLED_NAME_KEYS, resourceType) ?? []) named.add(key);
|
|
26775
|
-
const idSpellings = record.physicalIds.filter((id) => typeof id === "string" && id !== "").flatMap((id) => [
|
|
26776
|
-
id,
|
|
26777
|
-
...id.toLowerCase() === id || id.length < 4 ? [] : [id.toLowerCase()],
|
|
26778
|
-
finalSnapshotNamePrefix(id, resourceType),
|
|
26779
|
-
...idNameSegments(id)
|
|
26780
|
-
]);
|
|
26781
|
-
const pairs = [];
|
|
26782
|
-
for (const key of named) {
|
|
26783
|
-
if (!Object.hasOwn(properties, key)) continue;
|
|
26784
|
-
const value = properties[key];
|
|
26785
|
-
if (typeof value !== "string" || value === "") continue;
|
|
26786
|
-
const derived = key === primary && !value.includes("{{resolve:") && value !== "***" ? rewrittenNameSpellings(resourceType, value, logicalId) : [];
|
|
26787
|
-
for (const spelling of [...idSpellings, ...derived]) pairs.push([value, spelling]);
|
|
26788
|
-
}
|
|
26789
|
-
return pairs;
|
|
26790
|
-
}
|
|
26791
|
-
function addRecordNames(opMasker, op, current) {
|
|
26792
|
-
const { logicalId } = op;
|
|
26793
|
-
for (const properties of [op.properties, op.attemptedProperties]) opMasker.addNamed({
|
|
26794
|
-
resourceType: op.resourceType,
|
|
26795
|
-
properties,
|
|
26796
|
-
logicalId,
|
|
26797
|
-
physicalIds: [op.physicalId]
|
|
26798
|
-
});
|
|
26799
|
-
for (const record of [op.previousState, current]) {
|
|
26800
|
-
if (record === null || typeof record !== "object") continue;
|
|
26801
|
-
opMasker.addNamed({
|
|
26802
|
-
resourceType: record.resourceType ?? op.resourceType,
|
|
26803
|
-
properties: record.properties,
|
|
26804
|
-
logicalId,
|
|
26805
|
-
physicalIds: [record.physicalId]
|
|
26806
|
-
});
|
|
26807
|
-
}
|
|
26808
|
-
}
|
|
26809
|
-
const ABSENT_BASELINE_SKIP_CAUSE = "Its recorded previous state has no `properties` bag, so there is nothing to restore it to; the rollback left the resource exactly as it is.";
|
|
26810
|
-
function requireRestorableBaseline(bag, logger, { logicalId, consequence, remedy, retry }) {
|
|
26811
|
-
if (isRestorableBag(bag)) return true;
|
|
26812
|
-
if (bag === void 0) {
|
|
26813
|
-
logger.warn(` Rollback: Cannot restore ${shownLogicalId(logicalId)} \u2014 its recorded previous state has no \`properties\` bag, so there is nothing to restore it to. An empty desired state would ${consequence}. The resource is therefore left exactly as it is. ${remedy}`);
|
|
26814
|
-
return false;
|
|
26815
|
-
}
|
|
26816
|
-
const shape = bag === null ? "null" : Array.isArray(bag) ? "an array" : `a ${typeof bag}`;
|
|
26817
|
-
throw new CdkdError(`Cannot roll ${shownLogicalId(logicalId)} back: its recorded previous state has a \`properties\` field that is not a property bag (${shape}), so cdkd cannot tell what to restore it to. Replaying it would do one of two things, and cdkd does neither: send the malformed value to the provider as-is, or send an empty desired state (which would ${consequence}). The rollback JOURNAL record is kept: once that record holds a property bag again, ${retry}. Otherwise fix forward with \`cdkd deploy\`, or remove the stack with \`cdkd destroy\`.`, "ROLLBACK_UNUSABLE_BASELINE");
|
|
26818
|
-
}
|
|
26819
|
-
function isRestorableBag(bag) {
|
|
26820
|
-
return typeof bag === "object" && bag !== null && !Array.isArray(bag);
|
|
26821
|
-
}
|
|
26822
|
-
async function prepareCreateRollbackFinalSnapshot(op, provisionedBy, ctx, mask) {
|
|
26823
|
-
const { logicalId, resourceType } = op;
|
|
26824
|
-
const physicalId = op.physicalId;
|
|
26825
|
-
switch (finalSnapshotMechanism(resourceType, provisionedBy)) {
|
|
26826
|
-
case "atomic-delete-parameter": return buildFinalSnapshotIdentifier(physicalId, resourceType);
|
|
26827
|
-
case "pre-delete-snapshot":
|
|
26828
|
-
await createPreDeleteFinalSnapshot(resourceType, physicalId, logicalId, ctx.finalSnapshotClients ?? getAwsClients(), {
|
|
26829
|
-
info: (message) => ctx.logger.info(mask(message)),
|
|
26830
|
-
debug: (message) => ctx.logger.debug(mask(message))
|
|
26831
|
-
});
|
|
26832
|
-
return;
|
|
26833
|
-
case "refuse-cc-routed": throw ccRoutedFinalSnapshotError(logicalId, resourceType, SKIP_FINAL_SNAPSHOT_FLAG);
|
|
26834
|
-
case "refuse-unsupported-type": throw unsupportedFinalSnapshotError(logicalId, resourceType, SKIP_FINAL_SNAPSHOT_FLAG);
|
|
26835
|
-
}
|
|
26836
|
-
}
|
|
26837
|
-
|
|
26838
28109
|
//#endregion
|
|
26839
28110
|
//#region src/deployment/rollback-executor/replay-props.ts
|
|
26840
28111
|
async function resolveReplayProps(props, resolvers, secrets, execCtx, logicalId) {
|
|
@@ -27410,6 +28681,7 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
|
|
|
27410
28681
|
};
|
|
27411
28682
|
if (operations.length === 0) {
|
|
27412
28683
|
ctx.logger.info("No completed operations to roll back.");
|
|
28684
|
+
await restoreHeldInlinePolicies(inlinePolicyWriters, stateResources, stackName, ctx, result);
|
|
27413
28685
|
return result;
|
|
27414
28686
|
}
|
|
27415
28687
|
ctx.logger.info(`Rolling back ${operations.length} completed operation(s)...`);
|
|
@@ -27418,6 +28690,7 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
|
|
|
27418
28690
|
stackName
|
|
27419
28691
|
});
|
|
27420
28692
|
const resolver = new ReplayResolvers(ctx.region);
|
|
28693
|
+
inlinePolicyWriters.notePending(operations);
|
|
27421
28694
|
const { createOps, otherOps } = partitionOps(operations);
|
|
27422
28695
|
for (let i = otherOps.length - 1; i >= 0; i--) {
|
|
27423
28696
|
if (options.isInterrupted?.()) {
|
|
@@ -27436,6 +28709,7 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
|
|
|
27436
28709
|
await replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, options.onOrphan, inlinePolicyWriters, options.afterOp, options.isInterrupted);
|
|
27437
28710
|
}
|
|
27438
28711
|
}
|
|
28712
|
+
await restoreHeldInlinePolicies(inlinePolicyWriters, stateResources, stackName, ctx, result);
|
|
27439
28713
|
ctx.logger.info("Rollback completed. Some resources may remain if deletion failed.");
|
|
27440
28714
|
ctx.recordEvent?.({
|
|
27441
28715
|
eventType: "ROLLBACK_FINISHED",
|
|
@@ -27470,6 +28744,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
|
|
|
27470
28744
|
mask,
|
|
27471
28745
|
createRollbackRoute: void 0
|
|
27472
28746
|
};
|
|
28747
|
+
const recordBefore = ownRecord(stateResources, op.logicalId);
|
|
27473
28748
|
try {
|
|
27474
28749
|
addRecordNames(opMasker, op, stateResources[op.logicalId]);
|
|
27475
28750
|
switch (action) {
|
|
@@ -27514,8 +28789,13 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
|
|
|
27514
28789
|
...failedRoute && { provisionedBy: failedRoute },
|
|
27515
28790
|
error: maskedRollbackEventError(rollbackError, mask)
|
|
27516
28791
|
});
|
|
28792
|
+
} finally {
|
|
28793
|
+
inlinePolicyWriters.noteOutcome(op, action === "skip-already-done" || ownRecord(stateResources, op.logicalId) !== recordBefore);
|
|
27517
28794
|
}
|
|
27518
28795
|
}
|
|
28796
|
+
function ownRecord(stateResources, logicalId) {
|
|
28797
|
+
return Object.hasOwn(stateResources, logicalId) ? stateResources[logicalId] : void 0;
|
|
28798
|
+
}
|
|
27519
28799
|
async function replayFailedOperationsUnbound(failedOps, stateResources, stackName, ctx, options = {}) {
|
|
27520
28800
|
const inlinePolicyWriters = options.inlinePolicyWriters ?? new RollbackInlinePolicyWriters();
|
|
27521
28801
|
const result = {
|
|
@@ -27552,12 +28832,17 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
|
|
|
27552
28832
|
mask
|
|
27553
28833
|
};
|
|
27554
28834
|
let createRollbackRoute;
|
|
28835
|
+
const recordBefore = ownRecord(stateResources, op.logicalId);
|
|
27555
28836
|
try {
|
|
27556
28837
|
addRecordNames(opMasker, op, stateResources[op.logicalId]);
|
|
27557
28838
|
switch (action) {
|
|
27558
28839
|
case "skip-failed-noop":
|
|
27559
28840
|
logger.info(` Rollback: failed ${safe(op.changeType)} of ${safe(op.logicalId)} (${safe(op.resourceType)}) left nothing to revert, skipping`);
|
|
27560
28841
|
break;
|
|
28842
|
+
case "skip-failed-mismatch":
|
|
28843
|
+
logger.warn(safeMsg` Rollback: Skipping failed CREATE of ${shownLogicalId(op.logicalId)} (${refusalResourceType(op.resourceType)}) — it recorded ${mask(String(op.physicalId))}, which is not the resource state tracks under this id; manual attention may be required`);
|
|
28844
|
+
recordRollbackSkip(skipScope, op, "The failed CREATE recorded a physical id other than the one state now tracks under this logical id, so the rollback left it as it is; manual attention may be required.");
|
|
28845
|
+
break;
|
|
27561
28846
|
case "skip-failed-unknown":
|
|
27562
28847
|
logger.warn(` Rollback: failed CREATE of ${safe(op.logicalId)} (${safe(op.resourceType)}) recorded no physical id — if it was partially created in AWS, delete it manually`);
|
|
27563
28848
|
recordRollbackSkip(skipScope, op, "The failed CREATE recorded no physical id, so the rollback cannot address it; if it was partially created in AWS, delete it manually.");
|
|
@@ -27720,7 +29005,9 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
|
|
|
27720
29005
|
error: maskedRollbackEventError(revertError, mask)
|
|
27721
29006
|
});
|
|
27722
29007
|
}
|
|
29008
|
+
inlinePolicyWriters.noteOutcome(op, action === "skip-failed-noop" || action === "skip-failed-mismatch" || ownRecord(stateResources, op.logicalId) !== recordBefore);
|
|
27723
29009
|
}
|
|
29010
|
+
if (result.interrupted) await restoreHeldInlinePolicies(inlinePolicyWriters, stateResources, stackName, ctx, result, { refuseAll: true });
|
|
27724
29011
|
if (emitEnvelope) ctx.recordEvent?.({
|
|
27725
29012
|
eventType: "ROLLBACK_FINISHED",
|
|
27726
29013
|
stackName
|
|
@@ -27763,7 +29050,7 @@ async function collectNestedChildUnaddressed(fn) {
|
|
|
27763
29050
|
//#endregion
|
|
27764
29051
|
//#region src/deployment/nested-child-journal.ts
|
|
27765
29052
|
const NESTED_PENDING_PARENT_REASON = "nested-pending-parent";
|
|
27766
|
-
const NESTED_STACK_TYPE = "AWS::CloudFormation::Stack";
|
|
29053
|
+
const NESTED_STACK_TYPE$1 = "AWS::CloudFormation::Stack";
|
|
27767
29054
|
const MAX_NESTED_WALK_DEPTH = 32;
|
|
27768
29055
|
function nestedChildStackName(parentStackName, logicalId) {
|
|
27769
29056
|
return `${parentStackName}~${logicalId}`;
|
|
@@ -27780,8 +29067,46 @@ function nestedPendingSnapshot(state) {
|
|
|
27780
29067
|
}
|
|
27781
29068
|
};
|
|
27782
29069
|
}
|
|
29070
|
+
function displacedPhysicalIdShown(op, logger, physicalId = journalOpPhysicalId(op)) {
|
|
29071
|
+
if (physicalId === void 0) return void 0;
|
|
29072
|
+
const masker = createOpMasker(logger, /* @__PURE__ */ new Map());
|
|
29073
|
+
for (const properties of [
|
|
29074
|
+
op.properties,
|
|
29075
|
+
op.attemptedProperties,
|
|
29076
|
+
op.previousState?.properties
|
|
29077
|
+
]) {
|
|
29078
|
+
if (properties === void 0) continue;
|
|
29079
|
+
masker.addNamed({
|
|
29080
|
+
resourceType: op.resourceType,
|
|
29081
|
+
properties,
|
|
29082
|
+
logicalId: op.logicalId,
|
|
29083
|
+
physicalIds: [physicalId]
|
|
29084
|
+
});
|
|
29085
|
+
}
|
|
29086
|
+
return displaySafe(String(masker.mask(physicalId)));
|
|
29087
|
+
}
|
|
29088
|
+
function displacedOpClause(op, marks, logger) {
|
|
29089
|
+
const retainedOld = retainedOldPhysicalId(op);
|
|
29090
|
+
if (retainedOld !== void 0 && marks.some((m) => isMarkFor(m, op))) {
|
|
29091
|
+
const shownOld = displacedPhysicalIdShown(op, logger, retainedOld);
|
|
29092
|
+
return `replaced ${shownOld} ${op.oldResourceRetained === true ? "but kept it (UpdateReplacePolicy: Retain)" : "and may have kept it (the journal records no verdict)"}; cdkd import adopted the replacement, so ${shownOld} is left untracked`;
|
|
29093
|
+
}
|
|
29094
|
+
const shownId = displacedPhysicalIdShown(op, logger);
|
|
29095
|
+
return shownId !== void 0 ? `recorded ${shownId}, which cdkd import has since replaced under this id` : "recorded no physical id, and cdkd import has since put another resource under this id";
|
|
29096
|
+
}
|
|
29097
|
+
function recordDisplacedSkips(recordEvent, stackName, ops) {
|
|
29098
|
+
for (const op of ops) recordEvent?.({
|
|
29099
|
+
eventType: "ROLLBACK_RESOURCE_SKIPPED",
|
|
29100
|
+
stackName,
|
|
29101
|
+
operation: op.changeType,
|
|
29102
|
+
logicalId: op.logicalId,
|
|
29103
|
+
resourceType: op.resourceType,
|
|
29104
|
+
...op.provisionedBy && { provisionedBy: op.provisionedBy },
|
|
29105
|
+
reason: "cdkd import has since put another resource under this logical id, so the op was not reverted; check the resource it recorded by hand"
|
|
29106
|
+
});
|
|
29107
|
+
}
|
|
27783
29108
|
function revertedNestedRowIds(ops) {
|
|
27784
|
-
return ops.filter((op) => op.resourceType === NESTED_STACK_TYPE && op.changeType === "UPDATE").map((op) => op.logicalId);
|
|
29109
|
+
return ops.filter((op) => op.resourceType === NESTED_STACK_TYPE$1 && op.changeType === "UPDATE").map((op) => op.logicalId);
|
|
27785
29110
|
}
|
|
27786
29111
|
const revertRunStorage = new AsyncLocalStorage();
|
|
27787
29112
|
function withNestedRevertRun(runId, fn) {
|
|
@@ -27807,7 +29132,7 @@ async function dropNestedChildJournals(args) {
|
|
|
27807
29132
|
if (!isPlainRecord(resources)) return;
|
|
27808
29133
|
if (depthExceeded(depth, parentStackName, logger)) return;
|
|
27809
29134
|
for (const [logicalId, record] of Object.entries(resources)) {
|
|
27810
|
-
if (!isPlainRecord(record) || record["resourceType"] !== NESTED_STACK_TYPE) continue;
|
|
29135
|
+
if (!isPlainRecord(record) || record["resourceType"] !== NESTED_STACK_TYPE$1) continue;
|
|
27811
29136
|
const child = nestedChildStackName(parentStackName, logicalId);
|
|
27812
29137
|
try {
|
|
27813
29138
|
const data = await stateBackend.getState(child, region);
|
|
@@ -27965,8 +29290,9 @@ async function revertNestedChildFromJournal(args) {
|
|
|
27965
29290
|
for (let s = segments.length - 1; s >= 0; s--) {
|
|
27966
29291
|
const segment = segments[s];
|
|
27967
29292
|
const skipPrefix = segment.skipPrefix ?? getCurrentSkipPrefix();
|
|
29293
|
+
const split = splitImportedOps(segment.operations, segment);
|
|
27968
29294
|
const result = await withNestedStackContext(childCtx, () => withSkipPrefix(skipPrefix, () => withStackName(childStackName, () => withCreateTokenLedger(ledgerForStack(ctx.stateBackend, childStackName, region), () => withNestedRevertRun(runId, async (inner) => {
|
|
27969
|
-
const replayed = await replayRollback(
|
|
29295
|
+
const replayed = await replayRollback(split.replay, stateResources, childStackName, execCtx, {
|
|
27970
29296
|
afterOp: save,
|
|
27971
29297
|
onOrphan: (record) => mintedOrphans.push(record),
|
|
27972
29298
|
inlinePolicyWriters
|
|
@@ -27978,7 +29304,9 @@ async function revertNestedChildFromJournal(args) {
|
|
|
27978
29304
|
};
|
|
27979
29305
|
})))));
|
|
27980
29306
|
failures += result.failures;
|
|
27981
|
-
warnings += result.warnings;
|
|
29307
|
+
warnings += result.warnings + split.displaced.length;
|
|
29308
|
+
recordDisplacedSkips(execCtx.recordEvent, childStackName, split.displaced);
|
|
29309
|
+
for (const op of split.displaced) logger.warn(safeMsg`Nested stack ${childStackName}: ${op.logicalId} ` + safeMsg`${displacedOpClause(op, segment.importedResources ?? [], logger)}; ` + "not reverted, check that resource by hand");
|
|
27982
29310
|
}
|
|
27983
29311
|
restoring = failures === 0;
|
|
27984
29312
|
await save();
|
|
@@ -29264,9 +30592,9 @@ function extractAllDependencies(template, logicalId) {
|
|
|
29264
30592
|
return deps.length > 0 ? deps : void 0;
|
|
29265
30593
|
}
|
|
29266
30594
|
function propertiesToRecord(desiredProperties, result, resourceType, provisionedBy) {
|
|
29267
|
-
if (result.effectiveProperties) return provisionedBy === "sdk" ? withoutSilentDropProperties(resourceType, result.effectiveProperties) : result.effectiveProperties;
|
|
30595
|
+
if (result.effectiveProperties) return markWrittenFromDeployedTemplate(provisionedBy === "sdk" ? withoutSilentDropProperties(resourceType, result.effectiveProperties) : result.effectiveProperties);
|
|
29268
30596
|
const written = provisionedBy === "sdk" ? withoutSilentDropProperties(resourceType, desiredProperties) : desiredProperties;
|
|
29269
|
-
return markSameGenerationBag(written);
|
|
30597
|
+
return markWrittenFromDeployedTemplate(markSameGenerationBag(written));
|
|
29270
30598
|
}
|
|
29271
30599
|
function extractTemplateAttributes(template, logicalId) {
|
|
29272
30600
|
const resource = template?.Resources?.[logicalId];
|
|
@@ -29383,8 +30711,15 @@ async function provisionCreate(logicalId, change, stateResources, stackName, tem
|
|
|
29383
30711
|
const resolvedProps = await this.resolver.resolve(desiredProps, context);
|
|
29384
30712
|
this.refuseRedactedAttributeReads(logicalId, resourceType, context);
|
|
29385
30713
|
this.perResourceTemplateProps.set(logicalId, desiredProps);
|
|
30714
|
+
const fingerprintSources = template && this.maskedInputSources(template, stateResources, conditions, stackName);
|
|
30715
|
+
if (fingerprintSources !== void 0) this.perResourceInputFingerprints.set(logicalId, await maskedInputFingerprintsFor(possiblyMaskedKeys(resolvedProps, [
|
|
30716
|
+
context.recordedSecretValues,
|
|
30717
|
+
this.fingerprintNoEchoValues,
|
|
30718
|
+
this.options.inheritedSecrets
|
|
30719
|
+
]), inputFingerprinter(desiredProps, fingerprintSources)));
|
|
29386
30720
|
this.perResourceResolvedType.set(logicalId, resourceType);
|
|
29387
30721
|
const createSecrets = context.recordedSecretValues ?? /* @__PURE__ */ new Map();
|
|
30722
|
+
if (fingerprintSources !== void 0 && resourceType === "AWS::CloudFormation::Stack") recordPassedParameterClasses(createSecrets, await classifyPassedParameters(desiredProps["Parameters"], fingerprintSources));
|
|
29388
30723
|
recordNestedStackParameterExpressions(createSecrets, resourceType, resolvedProps, desiredProps);
|
|
29389
30724
|
this.auditResolvedAssetReferences(logicalId, resourceType, resolvedProps);
|
|
29390
30725
|
this.attemptedResolvedProps.set(logicalId, resolvedProps);
|
|
@@ -32276,12 +33611,22 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
|
|
|
32276
33611
|
const lostChild = lostCandidate?.mode === "reattach" || lostCandidate !== void 0 && Object.hasOwn(resolvedProps, lostCandidate.property) && Object.hasOwn(currentProps, lostCandidate.property) && keyOrderFreeJson(resolvedProps[lostCandidate.property]) === keyOrderFreeJson(currentProps[lostCandidate.property]) ? lostCandidate : void 0;
|
|
32277
33612
|
const lostWithParent = lostChild?.mode === "recreate" ? lostChild.parent : void 0;
|
|
32278
33613
|
const suppliesFreshMaskOnlyValue = carriesFreshNoEchoValue(resolvedProps, updateSecrets);
|
|
33614
|
+
const fingerprintSources = template && this.maskedInputSources(template, stateResources, conditions, stackName);
|
|
33615
|
+
const fingerprints = fingerprintSources && inputFingerprinter(desiredProps, fingerprintSources);
|
|
33616
|
+
const movedMasked = new Set(await movedMaskedProperties(currentResource, desiredProps, fingerprints));
|
|
33617
|
+
if (fingerprints !== void 0) this.perResourceInputFingerprints.set(logicalId, await maskedInputFingerprintsFor(possiblyMaskedKeys(resolvedProps, [
|
|
33618
|
+
updateSecrets,
|
|
33619
|
+
this.fingerprintNoEchoValues,
|
|
33620
|
+
this.options.inheritedSecrets
|
|
33621
|
+
]), fingerprints));
|
|
33622
|
+
if (fingerprintSources !== void 0 && resourceType === "AWS::CloudFormation::Stack") recordPassedParameterClasses(updateSecrets, await classifyPassedParameters(desiredProps["Parameters"], fingerprintSources));
|
|
32279
33623
|
const desiredForSkipCheck = redactSecretsForState(markSameGenerationBag({ ...resolvedProps }), updateSecrets, desiredProps);
|
|
32280
33624
|
const allowedSilentDrops = this.providerRegistry.getAllowedUnsupportedProperties?.();
|
|
32281
33625
|
const desiredForSkipCheckAsWritten = currentResource.provisionedBy !== "cc-api" && allowedSilentDrops ? withoutAcceptedSilentDropProperties(resourceType, desiredForSkipCheck, allowedSilentDrops, currentResource.properties) : desiredForSkipCheck;
|
|
32282
33626
|
const allowedForRecord = allowedSilentDrops ?? /* @__PURE__ */ new Set();
|
|
32283
33627
|
const createOnlyEvidence = acceptedCreateOnlyDropsOf(currentResource);
|
|
32284
33628
|
const currentPropsAsWritten = currentResource.provisionedBy === "cc-api" ? currentProps : withoutUnwrittenSilentDropProperties(resourceType, currentProps, desiredForSkipCheck, allowedForRecord, createOnlyEvidence);
|
|
33629
|
+
const recordMatchesDesired = movedMasked.size === 0 && keyOrderFreeJson(desiredForSkipCheckAsWritten) === keyOrderFreeJson(currentPropsAsWritten);
|
|
32285
33630
|
const applyAttributeOnlyUpdate = (attributeChanges) => {
|
|
32286
33631
|
const attrSummary = attributeChanges.map((a) => `${a.attribute}: ${a.oldValue ?? "(unset)"} → ${a.newValue ?? "(unset)"}`).join(", ");
|
|
32287
33632
|
this.logger.info(safeMsg` ↻ ${logicalId} (${resourceType}) attribute update: ${attrSummary}`);
|
|
@@ -32295,7 +33640,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
|
|
|
32295
33640
|
renderer.removeTask(logicalId);
|
|
32296
33641
|
this.logger.info(safeMsg`${attrPrefix}${formatResourceLine("updated", logicalId, resourceType, "updated (metadata)")}`);
|
|
32297
33642
|
};
|
|
32298
|
-
if (!typeChanged && !suppliesFreshMaskOnlyValue && lostChild === void 0 && this.recreateDirectionFor(stackName, logicalId) === void 0 &&
|
|
33643
|
+
if (!typeChanged && !suppliesFreshMaskOnlyValue && lostChild === void 0 && this.recreateDirectionFor(stackName, logicalId) === void 0 && recordMatchesDesired) {
|
|
32299
33644
|
if (change.attributeChanges && change.attributeChanges.length > 0) {
|
|
32300
33645
|
applyAttributeOnlyUpdate(change.attributeChanges);
|
|
32301
33646
|
return;
|
|
@@ -32320,7 +33665,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
|
|
|
32320
33665
|
lowered.push(pc);
|
|
32321
33666
|
continue;
|
|
32322
33667
|
}
|
|
32323
|
-
const moved = keyOrderFreeJson(desiredForSkipCheckAsWritten[pc.path]) !== keyOrderFreeJson(currentPropsAsWritten[pc.path]);
|
|
33668
|
+
const moved = movedMasked.has(pc.path) || keyOrderFreeJson(desiredForSkipCheckAsWritten[pc.path]) !== keyOrderFreeJson(currentPropsAsWritten[pc.path]);
|
|
32324
33669
|
const conditionalVerdict = moved && !typeChanged && isReplacementCeiling(pc) ? this.diffCalculator.conditionalReplacementVerdict?.(resourceType, pc.path, currentPropsAsWritten[pc.path], desiredForSkipCheckAsWritten[pc.path]) : void 0;
|
|
32325
33670
|
if (moved && conditionalVerdict !== false) {
|
|
32326
33671
|
lowered.push(pc);
|
|
@@ -32352,7 +33697,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
|
|
|
32352
33697
|
}
|
|
32353
33698
|
change.propertyChanges = lowered;
|
|
32354
33699
|
}
|
|
32355
|
-
if (noEchoHeldPaths.size > 0 && !typeChanged && lostChild === void 0 && this.recreateDirectionFor(stackName, logicalId) === void 0 &&
|
|
33700
|
+
if (noEchoHeldPaths.size > 0 && !typeChanged && lostChild === void 0 && this.recreateDirectionFor(stackName, logicalId) === void 0 && recordMatchesDesired && Object.entries(resolvedProps).every(([key, value]) => noEchoHeldPaths.has(key) || freshNoEchoLeafPositions(value, updateSecrets).length === 0)) {
|
|
32356
33701
|
this.logger.debug(safeMsg`Skipping ${logicalId}: AWS already holds every NoEcho value it carries, and nothing else changed`);
|
|
32357
33702
|
this.attemptedResolvedProps.delete(logicalId);
|
|
32358
33703
|
if (change.attributeChanges && change.attributeChanges.length > 0) {
|
|
@@ -34014,6 +35359,184 @@ function conditionVerdictRecordsEqual(a, b) {
|
|
|
34014
35359
|
return names.every((name) => Object.hasOwn(right, name) && left[name].verdict === right[name].verdict && left[name].fingerprint === right[name].fingerprint);
|
|
34015
35360
|
}
|
|
34016
35361
|
|
|
35362
|
+
//#endregion
|
|
35363
|
+
//#region src/utils/nested-template-cycle.ts
|
|
35364
|
+
const NESTED_STACK_TYPE = "AWS::CloudFormation::Stack";
|
|
35365
|
+
function isAbsoluteAssetPath(p) {
|
|
35366
|
+
return path.isAbsolute(p) || p.startsWith("/");
|
|
35367
|
+
}
|
|
35368
|
+
function templateIdentity(templatePath) {
|
|
35369
|
+
const dir = path.dirname(templatePath);
|
|
35370
|
+
let realDir;
|
|
35371
|
+
try {
|
|
35372
|
+
realDir = fs.realpathSync.native(dir);
|
|
35373
|
+
} catch {
|
|
35374
|
+
realDir = path.resolve(dir);
|
|
35375
|
+
}
|
|
35376
|
+
return path.join(realDir, path.basename(templatePath));
|
|
35377
|
+
}
|
|
35378
|
+
function listNestedTemplateRows(template) {
|
|
35379
|
+
if (template === null || typeof template !== "object") return [];
|
|
35380
|
+
const resources = template.Resources;
|
|
35381
|
+
if (resources === null || resources === void 0) return [];
|
|
35382
|
+
const rows = [];
|
|
35383
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
35384
|
+
const row = resource;
|
|
35385
|
+
if (row?.Type !== NESTED_STACK_TYPE) continue;
|
|
35386
|
+
const assetPath = row.Metadata?.["aws:asset:path"];
|
|
35387
|
+
if (typeof assetPath !== "string" || assetPath.length === 0) continue;
|
|
35388
|
+
rows.push({
|
|
35389
|
+
logicalId,
|
|
35390
|
+
assetPath
|
|
35391
|
+
});
|
|
35392
|
+
}
|
|
35393
|
+
return rows;
|
|
35394
|
+
}
|
|
35395
|
+
function readNestedRows(templatePath) {
|
|
35396
|
+
let parsed;
|
|
35397
|
+
try {
|
|
35398
|
+
parsed = JSON.parse(fs.readFileSync(templatePath, "utf-8"));
|
|
35399
|
+
} catch {
|
|
35400
|
+
return;
|
|
35401
|
+
}
|
|
35402
|
+
return listNestedTemplateRows(parsed);
|
|
35403
|
+
}
|
|
35404
|
+
const MAX_NESTING_DEPTH = 512;
|
|
35405
|
+
const MAX_ROWS_FOLLOWED = 1e4;
|
|
35406
|
+
function findNestedTemplateTreeDefect(nestedTemplates, ancestorTemplatePaths = []) {
|
|
35407
|
+
const onChain = /* @__PURE__ */ new Set();
|
|
35408
|
+
for (const p of ancestorTemplatePaths) onChain.add(templateIdentity(p));
|
|
35409
|
+
const clean = /* @__PURE__ */ new Set();
|
|
35410
|
+
const chain = [];
|
|
35411
|
+
let rowsFollowed = 0;
|
|
35412
|
+
const visit = (logicalId, templatePath) => {
|
|
35413
|
+
if (typeof templatePath !== "string") return void 0;
|
|
35414
|
+
const identity = templateIdentity(templatePath);
|
|
35415
|
+
const lexical = path.resolve(templatePath);
|
|
35416
|
+
chain.push({
|
|
35417
|
+
logicalId,
|
|
35418
|
+
templatePath: identity
|
|
35419
|
+
});
|
|
35420
|
+
try {
|
|
35421
|
+
if (onChain.has(identity)) return {
|
|
35422
|
+
kind: "cycle",
|
|
35423
|
+
chain: [...chain]
|
|
35424
|
+
};
|
|
35425
|
+
if (chain.length > 512) return {
|
|
35426
|
+
kind: "too-deep",
|
|
35427
|
+
chain: [...chain]
|
|
35428
|
+
};
|
|
35429
|
+
if (++rowsFollowed > 1e4) return {
|
|
35430
|
+
kind: "too-large",
|
|
35431
|
+
chain: [...chain]
|
|
35432
|
+
};
|
|
35433
|
+
if (clean.has(lexical)) return void 0;
|
|
35434
|
+
const rows = readNestedRows(templatePath);
|
|
35435
|
+
if (rows === void 0) return void 0;
|
|
35436
|
+
onChain.add(identity);
|
|
35437
|
+
try {
|
|
35438
|
+
const dir = path.dirname(templatePath);
|
|
35439
|
+
for (const row of rows) {
|
|
35440
|
+
if (isAbsoluteAssetPath(row.assetPath)) return {
|
|
35441
|
+
kind: "absolute-path",
|
|
35442
|
+
chain: [...chain],
|
|
35443
|
+
logicalId: row.logicalId,
|
|
35444
|
+
assetPath: row.assetPath
|
|
35445
|
+
};
|
|
35446
|
+
const resolved = resolveAssemblyPath(dir, row.assetPath);
|
|
35447
|
+
if (!resolved.contained) return {
|
|
35448
|
+
kind: "escaping-path",
|
|
35449
|
+
chain: [...chain],
|
|
35450
|
+
logicalId: row.logicalId,
|
|
35451
|
+
assetPath: row.assetPath,
|
|
35452
|
+
escape: resolved,
|
|
35453
|
+
dir
|
|
35454
|
+
};
|
|
35455
|
+
const defect = visit(row.logicalId, resolved.path);
|
|
35456
|
+
if (defect) return defect;
|
|
35457
|
+
}
|
|
35458
|
+
} finally {
|
|
35459
|
+
onChain.delete(identity);
|
|
35460
|
+
}
|
|
35461
|
+
clean.add(lexical);
|
|
35462
|
+
return;
|
|
35463
|
+
} finally {
|
|
35464
|
+
chain.pop();
|
|
35465
|
+
}
|
|
35466
|
+
};
|
|
35467
|
+
for (const [logicalId, templatePath] of Object.entries(nestedTemplates)) {
|
|
35468
|
+
const defect = visit(logicalId, templatePath);
|
|
35469
|
+
if (defect) return defect;
|
|
35470
|
+
}
|
|
35471
|
+
}
|
|
35472
|
+
const MAX_RENDERED_HOPS = 8;
|
|
35473
|
+
function renderChain(chain) {
|
|
35474
|
+
const hop = (h) => `${displayIdent(h.logicalId)} (${displayAssemblyPath(h.templatePath)})`;
|
|
35475
|
+
if (chain.length <= MAX_RENDERED_HOPS) return chain.map(hop).join(" then ");
|
|
35476
|
+
const keep = MAX_RENDERED_HOPS / 2;
|
|
35477
|
+
return [
|
|
35478
|
+
...chain.slice(0, keep).map(hop),
|
|
35479
|
+
`... ${chain.length - 8} more ...`,
|
|
35480
|
+
...chain.slice(-4).map(hop)
|
|
35481
|
+
].join(" then ");
|
|
35482
|
+
}
|
|
35483
|
+
function renderNestedTemplateTreeDefect(defect, stackName, action) {
|
|
35484
|
+
const provenance = `CDK emits an acyclic nested template tree with relative asset paths, so this indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to ${action}.`;
|
|
35485
|
+
const owner = (chain) => {
|
|
35486
|
+
const ids = chain.slice(0, -1).map((h) => h.logicalId);
|
|
35487
|
+
const keep = MAX_RENDERED_HOPS / 2;
|
|
35488
|
+
if (ids.length <= MAX_RENDERED_HOPS) return displayStackName([stackName, ...ids].join("~"));
|
|
35489
|
+
const head = displayStackName([stackName, ...ids.slice(0, keep)].join("~"));
|
|
35490
|
+
const tail = displayStackName(ids.slice(-4).join("~"));
|
|
35491
|
+
return `${head}~...${ids.length - 8} more...~${tail}`;
|
|
35492
|
+
};
|
|
35493
|
+
if (defect.kind === "cycle") {
|
|
35494
|
+
const closing = defect.chain[defect.chain.length - 1];
|
|
35495
|
+
return `The nested template tree under stack ${displayStackName(stackName)} contains a cycle: ${renderChain(defect.chain)}. Nested stack ${displayIdent(closing.logicalId)} (declared in stack ${owner(defect.chain)}) resolves to a template that is already on that nesting chain, so its Metadata['aws:asset:path'] closes a cycle. ${provenance}`;
|
|
35496
|
+
}
|
|
35497
|
+
if (defect.kind === "too-large") return `The nested template tree under stack ${displayStackName(stackName)} has more than ${MAX_ROWS_FOLLOWED} nested-stack rows to follow (the walk stopped at ${renderChain(defect.chain)}). That is far beyond any CDK-generated assembly. Symlinked directories can give one template file many paths, which multiplies the tree without ever repeating on one chain. Refusing to ${action}.`;
|
|
35498
|
+
if (defect.kind === "too-deep") return `The nested template tree under stack ${displayStackName(stackName)} nests more than ${512} levels deep: ${renderChain(defect.chain)}. No tree that deep can deploy, because each level lengthens the child's state key and S3 caps a key at 1024 bytes. ${provenance}`;
|
|
35499
|
+
if (defect.kind === "escaping-path") return `The nested template tree under stack ${displayStackName(stackName)} has nested stack ${displayIdent(defect.logicalId)} (reached through ${renderChain(defect.chain)}) with Metadata['aws:asset:path']=${displayAssemblyPath(defect.assetPath)} which ${renderAssemblyPathEscape(defect.escape, defect.dir, action)}`;
|
|
35500
|
+
return `The nested template tree under stack ${displayStackName(stackName)} has nested stack ${displayIdent(defect.logicalId)} (reached through ${renderChain(defect.chain)}) with Metadata['aws:asset:path']=${displayAssemblyPath(defect.assetPath)} which is absolute. ${provenance}`;
|
|
35501
|
+
}
|
|
35502
|
+
|
|
35503
|
+
//#endregion
|
|
35504
|
+
//#region src/deployment/nested-output-templates.ts
|
|
35505
|
+
function childTemplateLoader(nestedTemplates) {
|
|
35506
|
+
if (nestedTemplates === void 0) return void 0;
|
|
35507
|
+
const read = /* @__PURE__ */ new Map();
|
|
35508
|
+
const loaderOver = (index) => (logicalId) => {
|
|
35509
|
+
const templatePath = index[logicalId];
|
|
35510
|
+
if (typeof templatePath !== "string") return void 0;
|
|
35511
|
+
const key = path.resolve(templatePath);
|
|
35512
|
+
if (read.has(key)) return read.get(key);
|
|
35513
|
+
let entry;
|
|
35514
|
+
try {
|
|
35515
|
+
const parsed = JSON.parse(fs.readFileSync(templatePath, "utf-8"));
|
|
35516
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) entry = {
|
|
35517
|
+
template: parsed,
|
|
35518
|
+
identity: templateIdentity(templatePath),
|
|
35519
|
+
childTemplate: loaderOver(childIndex(parsed, templatePath))
|
|
35520
|
+
};
|
|
35521
|
+
} catch {
|
|
35522
|
+
entry = void 0;
|
|
35523
|
+
}
|
|
35524
|
+
read.set(key, entry);
|
|
35525
|
+
return entry;
|
|
35526
|
+
};
|
|
35527
|
+
return loaderOver(nestedTemplates);
|
|
35528
|
+
}
|
|
35529
|
+
function childIndex(template, templatePath) {
|
|
35530
|
+
const dir = path.dirname(templatePath);
|
|
35531
|
+
const index = Object.create(null);
|
|
35532
|
+
for (const { logicalId, assetPath } of listNestedTemplateRows(template)) {
|
|
35533
|
+
if (isAbsoluteAssetPath(assetPath)) continue;
|
|
35534
|
+
const resolved = resolveAssemblyPath(dir, assetPath);
|
|
35535
|
+
if (resolved.contained) index[logicalId] = resolved.path;
|
|
35536
|
+
}
|
|
35537
|
+
return index;
|
|
35538
|
+
}
|
|
35539
|
+
|
|
34017
35540
|
//#endregion
|
|
34018
35541
|
//#region src/deployment/recreate-target-promotion.ts
|
|
34019
35542
|
function recreateTargetIdsFor(recreateTargets, stackName) {
|
|
@@ -34118,6 +35641,17 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
34118
35641
|
});
|
|
34119
35642
|
const parameterValues = await this.resolver.resolveParameters(template, this.options.parameters, { ...this.options.inheritedSecrets && hasMaskableValues(this.options.inheritedSecrets) && { inheritedSecrets: this.options.inheritedSecrets } });
|
|
34120
35643
|
this.logger.debug(`Resolved ${Object.keys(parameterValues).length} parameters: ${Object.keys(parameterValues).join(", ")}`);
|
|
35644
|
+
const backfillNoEchoValues = noEchoParameterValueSeed(template.Parameters, parameterValues, this.options.inheritedSecrets, this.options.parameters);
|
|
35645
|
+
this.fingerprintNoEchoValues = backfillNoEchoValues;
|
|
35646
|
+
this.fingerprintParameters = parameterInputsFor({
|
|
35647
|
+
template,
|
|
35648
|
+
values: parameterValues,
|
|
35649
|
+
nestedChild: this.options.parentStackInfo !== void 0,
|
|
35650
|
+
supplied: this.options.parameters,
|
|
35651
|
+
passedClasses: this.options.passedParameterClasses
|
|
35652
|
+
});
|
|
35653
|
+
this.fingerprintChildTemplates = childTemplateLoader(getCurrentNestedStackContext()?.nestedTemplates);
|
|
35654
|
+
let maskedFingerprintsBackfilled = backfillMaskedPropertyFingerprints(currentState.resources, template, backfillNoEchoValues) > 0;
|
|
34121
35655
|
const context = this.buildResolverContext({
|
|
34122
35656
|
template,
|
|
34123
35657
|
resources: currentState.resources,
|
|
@@ -34139,7 +35673,10 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
34139
35673
|
const effectiveTemplate = this.templateParser.filterResourcesByCondition(template, conditions);
|
|
34140
35674
|
const orphanCountBeforeAdoption = (currentState.orphans ?? []).length;
|
|
34141
35675
|
const orphanPlan = await this.adoptRollbackOrphans(currentState, effectiveTemplate);
|
|
34142
|
-
if (Object.keys(orphanPlan.adopted).length > 0)
|
|
35676
|
+
if (Object.keys(orphanPlan.adopted).length > 0) {
|
|
35677
|
+
this.stampReasonlessParameterRefusals(currentState.resources, template);
|
|
35678
|
+
if (backfillMaskedPropertyFingerprints(currentState.resources, template, backfillNoEchoValues) > 0) maskedFingerprintsBackfilled = true;
|
|
35679
|
+
}
|
|
34143
35680
|
const orphansChanged = Object.keys(orphanPlan.adopted).length > 0 || (currentState.orphans ?? []).length !== orphanCountBeforeAdoption;
|
|
34144
35681
|
const resourceTypes = new Set(Object.values(effectiveTemplate.Resources || {}).map((r) => r.Type).filter((type) => type !== "AWS::CDK::Metadata"));
|
|
34145
35682
|
this.providerRegistry.validateResourceTypes(resourceTypes);
|
|
@@ -34165,8 +35702,19 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
34165
35702
|
diffResolverContext.bestEffort = true;
|
|
34166
35703
|
diffResolverContext.skipDynamicReferences = true;
|
|
34167
35704
|
const diffResolveFn = (value) => this.resolver.resolve(value, diffResolverContext);
|
|
34168
|
-
const
|
|
35705
|
+
const maskedInputSourcesForDiff = this.maskedInputSources(effectiveTemplate, currentState.resources, conditions, stackName);
|
|
35706
|
+
const maskedInputs = maskedInputSourcesForDiff && {
|
|
35707
|
+
sources: maskedInputSourcesForDiff,
|
|
35708
|
+
rebaselined: /* @__PURE__ */ new Map()
|
|
35709
|
+
};
|
|
35710
|
+
const changes = await this.diffCalculator.calculateDiff(currentState, effectiveTemplate, diffResolveFn, makeCanonicalizePropertiesFn(this.providerRegistry), this.providerRegistry.getAllowedUnsupportedProperties?.(), this.freshNoEchoParameters(parameterValues), this.diffLogMasker(diffResolverContext.recordedSecretValues, effectiveTemplate, parameterValues), recreateTargetIdsFor(this.options.recreateTargets, stackName), maskedInputs);
|
|
34169
35711
|
createOnlyPrefetch.cancel();
|
|
35712
|
+
for (const [logicalId, fingerprints] of maskedInputs?.rebaselined ?? []) {
|
|
35713
|
+
const record = currentState.resources[logicalId];
|
|
35714
|
+
if (record === void 0) continue;
|
|
35715
|
+
currentState.resources[logicalId] = withRebaselinedFingerprints(record, fingerprints);
|
|
35716
|
+
maskedFingerprintsBackfilled = true;
|
|
35717
|
+
}
|
|
34170
35718
|
const nestedStackTypeChanges = findNestedStackTypeChanges({
|
|
34171
35719
|
changes,
|
|
34172
35720
|
stateResources: currentState.resources
|
|
@@ -34216,7 +35764,7 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
34216
35764
|
const skippedOutputsChanged = !skippedOutputsEqual(currentState.skippedOutputs, this.skippedOutputs);
|
|
34217
35765
|
const healedAttributesPending = this.hasUnpersistedHeals(currentState.resources);
|
|
34218
35766
|
const conditionVerdictsChanged = !conditionVerdictRecordsEqual(readRecordedConditionVerdicts(currentState), conditionVerdicts);
|
|
34219
|
-
if (observedRefresh || conditionVerdictsChanged || outputsChanged || exportSetChanged || skippedOutputsChanged || orphansChanged || healedAttributesPending) try {
|
|
35767
|
+
if (observedRefresh || maskedFingerprintsBackfilled || conditionVerdictsChanged || outputsChanged || exportSetChanged || skippedOutputsChanged || orphansChanged || healedAttributesPending) try {
|
|
34220
35768
|
const refreshedState = {
|
|
34221
35769
|
version: 10,
|
|
34222
35770
|
region: this.stackRegion,
|
|
@@ -34350,6 +35898,54 @@ function buildResolverContext(base, stackName) {
|
|
|
34350
35898
|
...base.redactedAttributeReads && { redactedAttributeReads: base.redactedAttributeReads }
|
|
34351
35899
|
};
|
|
34352
35900
|
}
|
|
35901
|
+
function getAttTargetOf(node) {
|
|
35902
|
+
if (node === null || typeof node !== "object" || Array.isArray(node)) return void 0;
|
|
35903
|
+
const getAtt = node["Fn::GetAtt"];
|
|
35904
|
+
if (Array.isArray(getAtt) && typeof getAtt[0] === "string") return getAtt[0];
|
|
35905
|
+
if (typeof getAtt === "string") return getAtt.split(".")[0];
|
|
35906
|
+
}
|
|
35907
|
+
function maskedInputSources(template, resources, conditions, stackName) {
|
|
35908
|
+
const parameters = this.fingerprintParameters;
|
|
35909
|
+
if (parameters === void 0) return void 0;
|
|
35910
|
+
return {
|
|
35911
|
+
template,
|
|
35912
|
+
parameterInput: parameters.parameterInput,
|
|
35913
|
+
conditions,
|
|
35914
|
+
childTemplate: this.fingerprintChildTemplates,
|
|
35915
|
+
resolve: async (node) => {
|
|
35916
|
+
const { attributeHealer: _healer, ...base } = this.buildResolverContext({
|
|
35917
|
+
template,
|
|
35918
|
+
resources,
|
|
35919
|
+
parameters: parameters.bound,
|
|
35920
|
+
...conditions && { conditions }
|
|
35921
|
+
}, stackName);
|
|
35922
|
+
const context = {
|
|
35923
|
+
...base,
|
|
35924
|
+
recordedImports: [],
|
|
35925
|
+
recordedOutputReads: [],
|
|
35926
|
+
bestEffort: true,
|
|
35927
|
+
skipDynamicReferences: true,
|
|
35928
|
+
staleAttributeHeal: { phase: "probe" }
|
|
35929
|
+
};
|
|
35930
|
+
const value = await this.resolver.resolve(structuredClone(node), context);
|
|
35931
|
+
const secrets = context.recordedSecretValues;
|
|
35932
|
+
const target = getAttTargetOf(node);
|
|
35933
|
+
const targetSecrets = target === void 0 ? void 0 : this.perResourceSecrets.get(target);
|
|
35934
|
+
if (targetSecrets !== void 0 && hasMaskableValues(targetSecrets)) {
|
|
35935
|
+
const probe = { value };
|
|
35936
|
+
const redacted = redactSecretsForState(probe, targetSecrets);
|
|
35937
|
+
if (JSON.stringify(redacted) !== JSON.stringify(probe)) return {
|
|
35938
|
+
value,
|
|
35939
|
+
keepAsWritten: true
|
|
35940
|
+
};
|
|
35941
|
+
}
|
|
35942
|
+
return {
|
|
35943
|
+
value,
|
|
35944
|
+
...secrets && { secrets }
|
|
35945
|
+
};
|
|
35946
|
+
}
|
|
35947
|
+
};
|
|
35948
|
+
}
|
|
34353
35949
|
|
|
34354
35950
|
//#endregion
|
|
34355
35951
|
//#region src/deployment/label-routing.ts
|
|
@@ -34573,6 +36169,10 @@ var DeployEngine = class {
|
|
|
34573
36169
|
noEchoAttributeResources = /* @__PURE__ */ new Map();
|
|
34574
36170
|
perResourceTemplateProps = /* @__PURE__ */ new Map();
|
|
34575
36171
|
perResourceResolvedType = /* @__PURE__ */ new Map();
|
|
36172
|
+
fingerprintNoEchoValues = void 0;
|
|
36173
|
+
fingerprintParameters = void 0;
|
|
36174
|
+
fingerprintChildTemplates = void 0;
|
|
36175
|
+
perResourceInputFingerprints = /* @__PURE__ */ new Map();
|
|
34576
36176
|
outputSecrets = /* @__PURE__ */ new Map();
|
|
34577
36177
|
outputsPassSecretMaps = [];
|
|
34578
36178
|
outputsTemplateSource = Object.create(null);
|
|
@@ -34620,6 +36220,10 @@ var DeployEngine = class {
|
|
|
34620
36220
|
this.noEchoAttributeResources = /* @__PURE__ */ new Map();
|
|
34621
36221
|
this.perResourceTemplateProps = /* @__PURE__ */ new Map();
|
|
34622
36222
|
this.perResourceResolvedType = /* @__PURE__ */ new Map();
|
|
36223
|
+
this.fingerprintNoEchoValues = void 0;
|
|
36224
|
+
this.fingerprintParameters = void 0;
|
|
36225
|
+
this.fingerprintChildTemplates = void 0;
|
|
36226
|
+
this.perResourceInputFingerprints = /* @__PURE__ */ new Map();
|
|
34623
36227
|
this.attemptedResolvedProps = /* @__PURE__ */ new Map();
|
|
34624
36228
|
this.liveTaskLabels = /* @__PURE__ */ new Map();
|
|
34625
36229
|
this.outputSecrets = /* @__PURE__ */ new Map();
|
|
@@ -34646,13 +36250,15 @@ var DeployEngine = class {
|
|
|
34646
36250
|
for (const [logicalId, record] of Object.entries(state.resources)) {
|
|
34647
36251
|
const secrets = this.perResourceSecrets.get(logicalId);
|
|
34648
36252
|
const templateProps = this.perResourceTemplateProps.get(logicalId);
|
|
34649
|
-
|
|
36253
|
+
const scrubbed = scrubResourceRecord(this.withHealedAttributes(logicalId, record), secrets ?? /* @__PURE__ */ new Map(), templateProps);
|
|
36254
|
+
resources[logicalId] = withMaskedPropertyFingerprints(scrubbed, record.properties, templateProps, secrets, this.fingerprintNoEchoValues, this.perResourceInputFingerprints.get(logicalId));
|
|
34650
36255
|
}
|
|
34651
36256
|
const orphans = state.orphans?.map((entry) => {
|
|
34652
36257
|
const sameResource = this.perResourceResolvedType.get(entry.logicalId) === entry.state.resourceType;
|
|
36258
|
+
const orphanTemplateProps = sameResource ? this.perResourceTemplateProps.get(entry.logicalId) : void 0;
|
|
34653
36259
|
return {
|
|
34654
36260
|
...entry,
|
|
34655
|
-
state: scrubResourceRecord(entry.state, (sameResource ? this.perResourceSecrets.get(entry.logicalId) : void 0) ?? /* @__PURE__ */ new Map(), sameResource ? this.
|
|
36261
|
+
state: withMaskedPropertyFingerprints(scrubResourceRecord(entry.state, (sameResource ? this.perResourceSecrets.get(entry.logicalId) : void 0) ?? /* @__PURE__ */ new Map(), orphanTemplateProps), entry.state.properties, orphanTemplateProps, sameResource ? this.perResourceSecrets.get(entry.logicalId) : void 0, sameResource ? this.fingerprintNoEchoValues : void 0, sameResource ? this.perResourceInputFingerprints.get(entry.logicalId) : void 0)
|
|
34656
36262
|
};
|
|
34657
36263
|
});
|
|
34658
36264
|
const outputs = this.redactOutputs(state.outputs);
|
|
@@ -34768,6 +36374,7 @@ DeployEngine.prototype.recreateDirectionFor = recreateDirectionFor;
|
|
|
34768
36374
|
DeployEngine.prototype.peekRoutingForLabel = peekRoutingForLabel;
|
|
34769
36375
|
DeployEngine.prototype.preparePropertiesForCcApi = preparePropertiesForCcApi;
|
|
34770
36376
|
DeployEngine.prototype.buildResolverContext = buildResolverContext;
|
|
36377
|
+
DeployEngine.prototype.maskedInputSources = maskedInputSources;
|
|
34771
36378
|
DeployEngine.prototype.doDeployWithPrefetch = doDeployWithPrefetch;
|
|
34772
36379
|
DeployEngine.prototype.executeDeployment = executeDeployment;
|
|
34773
36380
|
DeployEngine.prototype.persistStateAfterOutputFailure = persistStateAfterOutputFailure;
|
|
@@ -34825,5 +36432,5 @@ DeployEngine.prototype.replacementNameOrigin = replacementNameOrigin;
|
|
|
34825
36432
|
DeployEngine.prototype.orphanedNameCollisionAdvice = orphanedNameCollisionAdvice;
|
|
34826
36433
|
|
|
34827
36434
|
//#endregion
|
|
34828
|
-
export { nestedChildStackName as $, importableOutputs as $a, describeTypeWithThrottleRetry as $i, coerceParameterTypedValue as $n, resolveStateBucketWithDefaultAndSource as $o, refuseMalformedOutputs as $r, acquireIdempotencyToken as $t, ECR_AUTO_DELETE_IMAGES_TAG as A, pathCrossesDottedKey as Aa, findReplacedReadersOfRecreateTargets as Ai, reEnableInstanceApiTermination as An, formatDockerLoginError as Ao, malformedLocalResourceEntriesWarning as Ar, DeploymentEventsStore as At, gray as B, WHOLE_DYNAMIC_REFERENCE_PATTERN as Ba, toFiniteNumber as Bi, explicitRoleArnOrThrow as Bn, escapeRegExp$2 as Bo, malformedResourceEntriesWarning as Br, noEchoParameterValueSeed as Bt, deleteBudgetKey as C, markSameGenerationBag as Ca, unreadableResourceEntries as Ci, isWaitAbandonedError as Cn, buildDockerImage as Co, hasReadableResources as Cr, absoluteAssemblyPathEscape as Cs, effectiveDeletionPolicy as Ct, INDEX_SETTLE_POLL_INTERVAL_MS as D, DYNAMIC_REFERENCE_TOKEN_SCAN as Da, withoutSilentDropProperties as Di, isTerminationProtectionPropagationError as Dn, describeDockerFailure as Do, malformedExportNamesWarning as Dr, resolveAssemblyPath as Ds, updatePartialMessage as Dt, DELETE_INDEX_WAIT_PROCEED_NOTE as E, recoverMaskedOutput as Ea, unwrittenCreateOnlyReplacement as Ei, ec2InstanceProtectionSite as En, describeDockerExecFailure as Eo, malformedDriftResourcePropertiesWarning as Er, renderAssemblyPathEscape as Es, unsupportedFinalSnapshotError as Et, markRefusedBeforeApplying as F, recordNoEchoAttributeValues as Fa, renderStatefulReason as Fi, producerRegionsFromState as Fn, redactDockerArgvValues as Fo, malformedOrphansRefusalMessage as Fr, secretBearing as Ft, namesAnyDeclaredParameter as G, rebuildClientForBucketRegion as Ga, configStringRefusal as Gi, callerEnvCredentials as Gn, synthesisStatusMessage as Go, previewableOrphanRecords as Gr, DEFAULT_RESOURCE_TIMEOUT_MS as Gt, red as H, LockManager as Ha, coerceCfnInteger as Hi, sendableAssumeRoleCommand as Hn, AssetManifestLoader as Ho, malformedResourcesWarning as Hr, collectPublishedOutputNames as Ht, formatResourceLine as I, STATE_SOURCED_BASELINE_RULES as Ia, WARM_THROUGHPUT_MEMBERS as Ii, regionLessSecretName as In, redactedDockerCause as Io, malformedOrphansWarning as Ir, secretBearingStateKeyWarning as It, makeSiblingClaimReader as J, exportNamesCarriedFrom as Ja, requireConfigArray as Ji, s3BucketArn as Jn, resolveApp as Jo, refuseMalformedOrphanRecords as Jr, RollbackInlinePolicyWriters as Jt, reachableDivergentParameters as K, acceptedCreateOnlyDropsOf as Ka, readConfigString as Ki, envCredentialsAreAssumedRole as Kn, getDefaultStateBucketName as Ko, refuseDivergentRecordRegionForDestroy as Kr, DEFAULT_RESOURCE_WARN_AFTER_MS as Kt, createReadOnlyAttributeHealerFactory as L, STATE_SOURCED_CROSS_GENERATION_RULES as La, coerceWarmThroughput as Li, applyRoleArnIfSet as Ln, runDockerForeground as Lo, malformedOutputsRefusalMessage as Lr, secretSafeKeyDisplay as Lt, hasCdkAutoDeleteTag as M, carriesSecretMask as Ma, MULTI_REGION_RECREATE_BLOCKED_TYPES as Mi, INTRINSIC_KEYS as Mn, isDockerClientEnvKey as Mo, malformedOrphanRecordsRefusalMessage as Mr, WITHHELD_NAME_DISPLAY as Mt, isTruthyCfnBoolean as N, recordMaskOnlyValue as Na, isStatefulRecreateTargetForReplace as Ni, IntrinsicFunctionResolver as Nn, isMalformedEnvKey as No, malformedOrphanRecordsWarning as Nr, displayTextOrWithheld as Nt, deleteTableWithIndexBusyRetry as O, dynamicReferenceTokens as Oa, NO_CC_HANDLERS_REASON as Oi, observeThenDisableInstanceApiTermination as On, dockerSpawnEnvWithSensitive as Oo, malformedExportSourceWarning as Or, clearBucketRegionCache as Os, updatePartialReason as Ot, getPriorAttempts as P, recordMaskOnlyValuesIn as Pa, isStatefulRecreateTargetSync as Pi, classifyReplaySecretRegion as Pn, partitionSensitiveEnv as Po, malformedOrphanRowsKeptWarning as Pr, exportAliasCollisionScrubWarning as Pt, getNestedRevertRun as Q, importableOutputKeys as Qa, templateResourceTypes as Qi, s3BucketWebsiteUrl as Qn, resolveStateBucketWithDefault as Qo, refuseMalformedOrphansForOrphan as Qr, withCreateTokenLedger as Qt, bold as R, STATE_SOURCED_READBACK_RULES as Ra, isWarmThroughputDecrease as Ri, assertFlagRoleArn as Rn, runDockerStreaming as Ro, malformedOutputsWarning as Rr, exportNameSecretExposure as Rt, compensateRemovedDeletionProtection as S, maskSecretsInText as Sa, unreadableOrphanRecords as Si, withIndeterminateGuard as Sn, buildDenyExternalAccessPolicy as So, hasReadableOutputs as Sr, ownValue as Ss, createPreDeleteFinalSnapshot as St, resolveDynamoDbDeleteBudgetMs as T, scrubResourceRecord as Ta, findSilentDropProperties as Ti, disableInstanceApiTermination as Tn, describeDockerCapturedOutput as To, isReadableResourceEntry as Tr, displayAssemblyPath as Ts, refusesFinalSnapshot as Tt, yellow as U, isLockInfoExpired as Ua, configBooleanRefusal as Ui, AWS_CREDENTIAL_ENV_KEYS as Un, getDockerImageBySourceHash as Uo, malformedScrubResourceEntriesRefusalMessage as Ur, isExportAliasCollision as Ut, green as V, isSingleDynamicReferenceToken as Va, coerceCfnBoolean as Vi, isIamRoleArn as Vn, stripControlChars as Vo, malformedResourcePropertiesWarning as Vr, collectDeclaredOutputNames as Vt, computeParameterTaint as W, S3StateBackend as Wa, configIntegerRefusal as Wi, applyCallerIdentityCredentials as Wn, Synthesizer as Wo, malformedStateRefusalMessage as Wr, bindingSkippedOutputs as Wt, NESTED_PENDING_PARENT_REASON as X, hasReasonlessBaselineRefusal as Xa, requireConfigString as Xi, s3BucketDualStackDomainName as Xn, resolveCaptureObservedState as Xo, refuseMalformedOrphans as Xr, ledgerForStack as Xt, planOrphanAdoption as Y, hasReadableExportSet as Ya, requireConfigObject as Yi, s3BucketDomainName as Yn, resolveAutoAssetStorage as Yo, refuseMalformedOrphanRecordsForDestroy as Yr, earliestDefined as Yt, dropSettledNestedJournals as Z, hasUnverifiableParameterRefusal as Za, prefetchCreateOnlyPropertyPaths as Zi, s3BucketRegionalDomainName as Zn, resolveSkipPrefix as Zo, refuseMalformedOrphansForDestroy as Zr, reserveStackCreateToken as Zt, perType as _, recordLogOnlyValue as _a, repairMalformedOutputsForReadOnly as _i, ccProtectionRegistryTypes as _n, isCrossRegionRedirect as _o, UNREADABLE_ORPHANS_CONTAINER_ROW as _r, processStackMessages as _s, inheritProducerRegions as _t, conditionInputsFrom as a, DagBuilder as aa, refuseMalformedResourceEntriesForImport as ai, tagMapAsList as an, isSensitiveAttributeName as ao, carriesFetchableDynamicReference as ar, CFN_TEMPLATE_URL_LIMIT as as, replayFailedOperations as at, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as b, errorCauseChain as ba, repairMalformedResourcesForReadOnly as bi, deleteIndeterminateGuards as bn, validateAssetBucketName as bo, displayLogicalId as br, hasPlainPrototype$1 as bs, buildFinalSnapshotIdentifier as bt, isSecretBearingReferenceString as c, inheritNestedStackParameterAssociations as ca, refuseMalformedResourcePropertiesForDrift as ci, stringifyIfAssigned as cn, buildAssetRedirectMap as co, AWS_NO_VALUE as cr, uploadCfnTemplate as cs, destroyStackRecordsView as ct, makeCanonicalizePropertiesFn as d, createUnionSecretMasker as da, refuseMalformedResourcesForDeploy as di, ccBrokenReason as dn, rewriteTemplateAssetReferences as do, refStateLookupFromResource as dr, expectedOwnerParam as ds, recordAfterRollbackUpdate as dt, withRetry as ea, refuseMalformedOutputsForDestroy as ei, DBPROXY_TAGS_WHAT as en, isReadableBag as eo, isUnboundTemplateParameter as er, resolveUseCdkBootstrapAssets as es, revertNestedChildFromJournal as et, withResourceDeadline as f, hasMaskableValues as fa, refuseMalformedResourcesForDestroy as fi, wouldReturnToSdkProvider as fn, AssetModeResolver as fo, parseWebACLArn as fr, PARTITION_TABLE as fs, planFailedOps as ft, isProtectionValueActive as g, recordLogOnlyParameterValue as ga, repairMalformedOrphansForReadOnly as gi, slowCcOperationTimeoutMs as gn, getBootstrapMarkerKey as go, STATE_RESOURCES_MALFORMED as gr, StageLoadError as gs, getCurrentProducerRegions as gt, PROTECTION_PROPERTY_BY_TYPE as h, printingCorpusOf as ha, repairMalformedOrphanRecordsForReadOnly as hi, CloudControlProvider as hn, ensureAssetStorage as ho, STATE_REGION_DIVERGED as hr, AssemblyReader as hs, findNestedStackTypeChanges as ht, conditionFingerprint as i, sameLambdaFunctionAddress as ia, refuseMalformedResourceEntriesForDestroy as ii, refuseMalformedDesiredTags as in, AssetPublisher as io, carriesDynamicReference as ir, CFN_TEMPLATE_BODY_LIMIT as is, withNestedStackContext as it, S3_AUTO_DELETE_OBJECTS_TAG as j, identityKeyFor as ja, shownType as ji, DiffCalculator as jn, getDockerCmd as jo, malformedLocalResourcesWarning as jr, extractDeploymentEventError as jt, waitForIndexesSettled as k, isUncertifiedBaselineMaskPosition as ka, hasNoCloudControlHandlers as ki, reDisableInstanceApiTermination as kn, finchSecretArgvRefusal as ko, malformedLocalOutputsWarning as kr, resolveBucketRegion as ks, DeploymentEventsReader as kt, keptWholeReasonText as l, recordNestedStackParameterExpressions as la, refuseMalformedResourcePropertiesForExport as li, CC_BROKEN_REASON as ln, createAssetRedirectResolver as lo, cfnRefValueFromPhysicalId as lr, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as ls, getStackRecords as lt, recordedProtectionNote as m, logOnlyValueCount as ma, refuseMalformedState as mi, getCurrentResourceSecrets as mn, assertAssetBucketRegion as mo, JSON_LISTING_HOLE_VALUE as mr, derivePartitionAndUrlSuffix as ms, resolveReplacementOldType as mt, IMPLICIT_DELETE_DEPENDENCIES as n, canonicalLambdaFunctionName as na, refuseMalformedResourceEntries as ni, planTagDiff as nn, orphansCarriedFrom as no, getAccountInfo as nr, warnDeprecatedNoPrefixCliFlag as ns, withNestedRevertRun as nt, parentSuppliedValues as o, TemplateParser as oa, refuseMalformedResourceEntriesForImportSave as oi, tagPlanWarning as on, stringifyValue as oo, isNamelessDynamicReferenceError as or, MIGRATE_TMP_PREFIX as os, replayRollback as ot, recordedProtectionEvidence as p, literalSplitDelimitersOf as pa, refuseMalformedResourcesForExport as pi, isCustomResourceType as pn, BOOTSTRAP_MARKER_PREFIX as po, withSharedDrainBudget as pr, canonicalizeRegion as ps, planRollback as pt, resourcesNamingDeclaredParameter as q, describeRegionValueKind as qa, replayWarn as qi, isSettledInstanceState as qn, getLegacyStateBucketName as qo, refuseMalformedNestedChildOutputs as qr, maskingRetryLogger as qt, computeImplicitDeleteEdges as r, lambdaFunctionNameForMask as ra, refuseMalformedResourceEntriesForDeploy as ri, readTagList as rn, shouldRetainResource as ro, isImpossibleEmptyStoredAttribute as rr, ssmResolvedValueType as rs, getCurrentNestedStackContext as rt, readRecordedConditionVerdicts as s, liveMatchesUnresolvedTokenFrame as sa, refuseMalformedResourceEntriesForOrphan as si, definedAttributes as sn, WorkGraph as so, keepsSecretReferenceToken as sr, findLargeInlineResources as ss, awaitInFlightSibling as st, DeployEngine as t, markAuxiliaryFailure as ta, refuseMalformedResourceAttributesForOrphan as ti, DBPROXY_TAG_OPTIONS as tn, orphansAfterRollback as to, parameterTypeMayLoseSecretIdentity as tr, stateBucketExistenceConfirmed as ts, revertedNestedRowIds as tt, mergeNoChangeOutputs as u, carryLogOnlyValues as ua, refuseMalformedResourcePropertiesForOrphan as ui, ProviderRegistry as un, loadPublishableAssetManifest as uo, isStalePlaceholderArnAttribute as ur, decodeListingKey as us, withStackRecords as ut, readProtection as v, shareLogOnlyValues as va, repairMalformedResourceEntriesForReadOnly as vi, unchangedBehindSecretReference as vn, parseBootstrapMarker as vo, UNREADABLE_RESOURCES_MAP_ROW as vr, defineOwnKey as vs, ATOMIC_FINAL_SNAPSHOT_TYPES as vt, resolveDynamoDbDeleteBudgetClock as w, redactSecretsForState as wa, findActionableSilentDrops as wi, markWaitAbandoned as wn, resolveDockerContextDirectory as wo, isReadableOrphanRecord as wr, describeFileReadFailure as ws, isFinalSnapshotError as wt, beginDeleteWait as x, maskSecretsInError as xa, unpreviewableOrphanRecords as xi, deleteSkipReason as xn, validateContainerRepoName as xo, hasReadableOrphans as xr, nullPrototypeRecord as xs, ccRoutedFinalSnapshotError as xt, DynamoDBGlobalTableProvider as y, createSecretMasker as ya, repairMalformedResourcePropertiesForReadOnly as yi, UNSPECIFIED_SKIP_REASON as yn, readBootstrapMarkerBody as yo, deployRefusesOrphanRowsReason as yr, hasOwnKey as ys, PRE_DELETE_SNAPSHOT_TYPES as yt, cyan as z, TEMPLATE_SOURCED_RULES as za, toCfnInteger as zi, assertSendableRoleArn as zn, warnFinchArgvExposure as zo, malformedRenderedContainersWarning as zr, isWholeDynamicReferenceValue as zt };
|
|
34829
|
-
//# sourceMappingURL=deploy-engine-
|
|
36435
|
+
export { resourcesNamingDeclaredParameter as $, STATE_SOURCED_READBACK_RULES as $a, isWarmThroughputDecrease as $i, explicitRoleArnOrThrow as $n, runDockerForeground as $o, malformedOutputsWarning as $r, noEchoParameterValueSeed as $t, resolveDynamoDbDeleteBudgetClock as A, printingCorpusOf as Aa, repairMalformedOrphanRecordsForReadOnly as Ai, ccProtectionRegistryTypes as An, assertAssetBucketRegion as Ao, STATE_REGION_DIVERGED as Ar, derivePartitionAndUrlSuffix as As, ccRoutedFinalSnapshotError as At, getPriorAttempts as B, scrubResourceRecord as Ba, findSilentDropProperties as Bi, isTerminationProtectionPropagationError as Bn, resolveDockerContextDirectory as Bo, isReadableResourceEntry as Br, describeFileReadFailure as Bs, updatePartialMessage as Bt, perType as C, inheritNestedStackParameterAssociations as Ca, refuseMalformedResourcePropertiesForDrift as Ci, ProviderRegistry as Cn, WorkGraph as Co, isStalePlaceholderArnAttribute as Cr, findLargeInlineResources as Cs, resolveReplacementOldType as Ct, beginDeleteWait as D, hasMaskableValues as Da, refuseMalformedResourcesForDestroy as Di, getCurrentResourceSecrets as Dn, rewriteTemplateAssetReferences as Do, parameterInputsFor as Dr, expectedOwnerParam as Ds, ATOMIC_FINAL_SNAPSHOT_TYPES as Dt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as E, createUnionSecretMasker as Ea, refuseMalformedResourcesForDeploy as Ei, isCustomResourceType as En, loadPublishableAssetManifest as Eo, withSharedDrainBudget as Er, decodeListingKey as Es, inheritProducerRegions as Et, waitForIndexesSettled as F, errorCauseChain as Fa, repairMalformedResourcesForReadOnly as Fi, withIndeterminateGuard as Fn, readBootstrapMarkerBody as Fo, displayLogicalId as Fr, hasOwnKey as Fs, unsupportedFinalSnapshotError as Ft, cyan as G, pathCrossesDottedKey as Ga, findReplacedReadersOfRecreateTargets as Gi, INTRINSIC_KEYS as Gn, finchSecretArgvRefusal as Go, malformedLocalResourceEntriesWarning as Gr, resolveBucketRegion as Gs, WITHHELD_NAME_DISPLAY as Gt, formatResourceLine as H, DYNAMIC_REFERENCE_TOKEN_SCAN as Ha, withoutSilentDropProperties as Hi, reDisableInstanceApiTermination as Hn, describeDockerExecFailure as Ho, malformedExportNamesWarning as Hr, renderAssemblyPathEscape as Hs, DeploymentEventsReader as Ht, ECR_AUTO_DELETE_IMAGES_TAG as I, maskSecretsInError as Ia, unpreviewableOrphanRecords as Ii, isWaitAbandonedError as In, validateAssetBucketName as Io, hasReadableOrphans as Ir, hasPlainPrototype$1 as Is, REDACTED_DELETE_ADDRESS_SKIP_REASON as It, red as J, recordMaskOnlyValue as Ja, isStatefulRecreateTargetForReplace as Ji, producerRegionsFromState as Jn, isDockerClientEnvKey as Jo, malformedOrphanRecordsWarning as Jr, secretBearing as Jt, gray as K, identityKeyFor as Ka, shownType as Ki, IntrinsicFunctionResolver as Kn, formatDockerLoginError as Ko, malformedLocalResourcesWarning as Kr, displayTextOrWithheld as Kt, S3_AUTO_DELETE_OBJECTS_TAG as L, maskSecretsInText as La, unreadableOrphanRecords as Li, markWaitAbandoned as Ln, validateContainerRepoName as Lo, hasReadableOutputs as Lr, nullPrototypeRecord as Ls, isRedactedRecordedValue as Lt, DELETE_INDEX_WAIT_PROCEED_NOTE as M, recordLogOnlyValue as Ma, repairMalformedOutputsForReadOnly as Mi, UNSPECIFIED_SKIP_REASON as Mn, getBootstrapMarkerKey as Mo, UNREADABLE_ORPHANS_CONTAINER_ROW as Mr, StageLoadError as Ms, effectiveDeletionPolicy as Mt, INDEX_SETTLE_POLL_INTERVAL_MS as N, shareLogOnlyValues as Na, repairMalformedResourceEntriesForReadOnly as Ni, deleteIndeterminateGuards as Nn, isCrossRegionRedirect as No, UNREADABLE_RESOURCES_MAP_ROW as Nr, processStackMessages as Ns, isFinalSnapshotError as Nt, compensateRemovedDeletionProtection as O, literalSplitDelimitersOf as Oa, refuseMalformedResourcesForExport as Oi, CloudControlProvider as On, AssetModeResolver as Oo, passedParameterClassesOf as Or, PARTITION_TABLE as Os, PRE_DELETE_SNAPSHOT_TYPES as Ot, deleteTableWithIndexBusyRetry as P, createSecretMasker as Pa, repairMalformedResourcePropertiesForReadOnly as Pi, deleteSkipReason as Pn, parseBootstrapMarker as Po, deployRefusesOrphanRowsReason as Pr, defineOwnKey as Ps, refusesFinalSnapshot as Pt, reachableDivergentParameters as Q, STATE_SOURCED_CROSS_GENERATION_RULES as Qa, coerceWarmThroughput as Qi, assertSendableRoleArn as Qn, redactedDockerCause as Qo, malformedOutputsRefusalMessage as Qr, isWholeDynamicReferenceValue as Qt, hasCdkAutoDeleteTag as R, markSameGenerationBag as Ra, unreadableResourceEntries as Ri, disableInstanceApiTermination as Rn, buildDenyExternalAccessPolicy as Ro, hasReadableResources as Rr, ownValue as Rs, redactedDeleteAddressFields as Rt, isProtectionValueActive as S, liveMatchesUnresolvedTokenFrame as Sa, refuseMalformedResourceEntriesForOrphan as Si, CC_BROKEN_REASON as Sn, stringifyValue as So, cfnRefValueFromPhysicalId as Sr, MIGRATE_TMP_PREFIX as Ss, planRollback as St, DynamoDBGlobalTableProvider as T, carryLogOnlyValues as Ta, refuseMalformedResourcePropertiesForOrphan as Ti, wouldReturnToSdkProvider as Tn, createAssetRedirectResolver as To, parseWebACLArn as Tr, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Ts, getCurrentProducerRegions as Tt, createReadOnlyAttributeHealerFactory as U, dynamicReferenceTokens as Ua, NO_CC_HANDLERS_REASON as Ui, reEnableInstanceApiTermination as Un, describeDockerFailure as Uo, malformedExportSourceWarning as Ur, resolveAssemblyPath as Us, DeploymentEventsStore as Ut, markRefusedBeforeApplying as V, recoverMaskedOutput as Va, unwrittenCreateOnlyReplacement as Vi, observeThenDisableInstanceApiTermination as Vn, describeDockerCapturedOutput as Vo, malformedDriftResourcePropertiesWarning as Vr, displayAssemblyPath as Vs, updatePartialReason as Vt, bold as W, isUncertifiedBaselineMaskPosition as Wa, hasNoCloudControlHandlers as Wi, DiffCalculator as Wn, dockerSpawnEnvWithSensitive as Wo, malformedLocalOutputsWarning as Wr, clearBucketRegionCache as Ws, extractDeploymentEventError as Wt, computeParameterTaint as X, recordNoEchoAttributeValues as Xa, renderStatefulReason as Xi, applyRoleArnIfSet as Xn, partitionSensitiveEnv as Xo, malformedOrphansRefusalMessage as Xr, secretSafeKeyDisplay as Xt, yellow as Y, recordMaskOnlyValuesIn as Ya, isStatefulRecreateTargetSync as Yi, regionLessSecretName as Yn, isMalformedEnvKey as Yo, malformedOrphanRowsKeptWarning as Yr, secretBearingStateKeyWarning as Yt, namesAnyDeclaredParameter as Z, STATE_SOURCED_BASELINE_RULES as Za, WARM_THROUGHPUT_MEMBERS as Zi, assertFlagRoleArn as Zn, redactDockerArgvValues as Zo, malformedOrphansWarning as Zr, exportNameSecretExposure as Zt, makeCanonicalizePropertiesFn as _, canonicalLambdaFunctionName as _a, refuseMalformedResourceEntries as _i, refuseMalformedDesiredTags as _n, orphansAfterRollback as _o, carriesDynamicReference as _r, stateBucketExistenceConfirmed as _s, destroyStackRecordsView as _t, findNestedTemplateTreeDefect as a, configIntegerRefusal as aa, malformedStateRefusalMessage as ai, DEFAULT_RESOURCE_WARN_AFTER_MS as an, S3StateBackend as ao, envCredentialsAreAssumedRole as ar, getDockerImageBySourceHash as as, dropSettledNestedJournals as at, recordedProtectionNote as b, DagBuilder as ba, refuseMalformedResourceEntriesForImport as bi, definedAttributes as bn, AssetPublisher as bo, keepsSecretReferenceToken as br, CFN_TEMPLATE_BODY_LIMIT as bs, recordAfterRollbackUpdate as bt, renderNestedTemplateTreeDefect as c, replayWarn as ca, refuseMalformedNestedChildOutputs as ci, earliestDefined as cn, acceptedCreateOnlyDropsOf as co, s3BucketDomainName as cr, getDefaultStateBucketName as cs, recordDisplacedSkips as ct, conditionInputsFrom as d, requireConfigString as da, refuseMalformedOrphans as di, withCreateTokenLedger as dn, hasReadableExportSet as do, s3BucketWebsiteUrl as dr, resolveAutoAssetStorage as ds, withNestedRevertRun as dt, toCfnInteger as ea, malformedRenderedContainersWarning as ei, collectDeclaredOutputNames as en, TEMPLATE_SOURCED_RULES as eo, isIamRoleArn as er, runDockerStreaming as es, makeSiblingClaimReader as et, parentSuppliedValues as f, prefetchCreateOnlyPropertyPaths as fa, refuseMalformedOrphansForDestroy as fi, acquireIdempotencyToken as fn, hasReasonlessBaselineRefusal as fo, coerceParameterTypedValue as fr, resolveCaptureObservedState as fs, getCurrentNestedStackContext as ft, mergeNoChangeOutputs as g, markAuxiliaryFailure as ga, refuseMalformedResourceAttributesForOrphan as gi, readTagList as gn, isReadableBag as go, isImpossibleEmptyStoredAttribute as gr, resolveUseCdkBootstrapAssets as gs, awaitInFlightSibling as gt, keptWholeReasonText as h, withRetry as ha, refuseMalformedOutputsForDestroy as hi, planTagDiff as hn, importableOutputs as ho, getAccountInfo as hr, resolveStateBucketWithDefaultAndSource as hs, replayRollback as ht, childTemplateLoader as i, configBooleanRefusal as ia, malformedScrubResourceEntriesRefusalMessage as ii, DEFAULT_RESOURCE_TIMEOUT_MS as in, isLockInfoExpired as io, callerEnvCredentials as ir, AssetManifestLoader as is, displacedPhysicalIdShown as it, resolveDynamoDbDeleteBudgetMs as j, recordLogOnlyParameterValue as ja, repairMalformedOrphansForReadOnly as ji, unchangedBehindSecretReference as jn, ensureAssetStorage as jo, STATE_RESOURCES_MALFORMED as jr, AssemblyReader as js, createPreDeleteFinalSnapshot as jt, deleteBudgetKey as k, logOnlyValueCount as ka, refuseMalformedState as ki, slowCcOperationTimeoutMs as kn, BOOTSTRAP_MARKER_PREFIX as ko, JSON_LISTING_HOLE_VALUE as kr, canonicalizeRegion as ks, buildFinalSnapshotIdentifier as kt, templateIdentity as l, requireConfigArray as la, refuseMalformedOrphanRecords as li, ledgerForStack as ln, describeRegionValueKind as lo, s3BucketDualStackDomainName as lr, getLegacyStateBucketName as ls, revertNestedChildFromJournal as lt, isSecretBearingReferenceString as m, describeTypeWithThrottleRetry as ma, refuseMalformedOutputs as mi, DBPROXY_TAG_OPTIONS as mn, importableOutputKeys as mo, parameterTypeMayLoseSecretIdentity as mr, resolveStateBucketWithDefault as ms, replayFailedOperations as mt, IMPLICIT_DELETE_DEPENDENCIES as n, coerceCfnBoolean as na, malformedResourcePropertiesWarning as ni, isExportAliasCollision as nn, isSingleDynamicReferenceToken as no, AWS_CREDENTIAL_ENV_KEYS as nr, escapeRegExp$2 as ns, NESTED_PENDING_PARENT_REASON as nt, isAbsoluteAssetPath as o, configStringRefusal as oa, previewableOrphanRecords as oi, maskingRetryLogger as on, rebuildClientForBucketRegion as oo, isSettledInstanceState as or, Synthesizer as os, getNestedRevertRun as ot, readRecordedConditionVerdicts as p, templateResourceTypes as pa, refuseMalformedOrphansForOrphan as pi, DBPROXY_TAGS_WHAT as pn, hasUnverifiableParameterRefusal as po, isUnboundTemplateParameter as pr, resolveSkipPrefix as ps, withNestedStackContext as pt, green as q, carriesSecretMask as qa, MULTI_REGION_RECREATE_BLOCKED_TYPES as qi, classifyReplaySecretRegion as qn, getDockerCmd as qo, malformedOrphanRecordsRefusalMessage as qr, exportAliasCollisionScrubWarning as qt, computeImplicitDeleteEdges as r, coerceCfnInteger as ra, malformedResourcesWarning as ri, bindingSkippedOutputs as rn, LockManager as ro, applyCallerIdentityCredentials as rr, stripControlChars as rs, displacedOpClause as rt, listNestedTemplateRows as s, readConfigString as sa, refuseDivergentRecordRegionForDestroy as si, RollbackInlinePolicyWriters as sn, splitImportedOps as so, s3BucketArn as sr, synthesisStatusMessage as ss, nestedChildStackName as st, DeployEngine as t, toFiniteNumber as ta, malformedResourceEntriesWarning as ti, collectPublishedOutputNames as tn, WHOLE_DYNAMIC_REFERENCE_PATTERN as to, sendableAssumeRoleCommand as tr, warnFinchArgvExposure as ts, planOrphanAdoption as tt, conditionFingerprint as u, requireConfigObject as ua, refuseMalformedOrphanRecordsForDestroy as ui, reserveStackCreateToken as un, exportNamesCarriedFrom as uo, s3BucketRegionalDomainName as ur, resolveApp as us, revertedNestedRowIds as ut, withResourceDeadline as v, lambdaFunctionNameForMask as va, refuseMalformedResourceEntriesForDeploy as vi, tagMapAsList as vn, orphansCarriedFrom as vo, carriesFetchableDynamicReference as vr, warnDeprecatedNoPrefixCliFlag as vs, getStackRecords as vt, readProtection as w, recordNestedStackParameterExpressions as wa, refuseMalformedResourcePropertiesForExport as wi, ccBrokenReason as wn, buildAssetRedirectMap as wo, refStateLookupFromResource as wr, uploadCfnTemplate as ws, findNestedStackTypeChanges as wt, PROTECTION_PROPERTY_BY_TYPE as x, TemplateParser as xa, refuseMalformedResourceEntriesForImportSave as xi, stringifyIfAssigned as xn, isSensitiveAttributeName as xo, AWS_NO_VALUE as xr, CFN_TEMPLATE_URL_LIMIT as xs, planFailedOps as xt, recordedProtectionEvidence as y, sameLambdaFunctionAddress as ya, refuseMalformedResourceEntriesForDestroy as yi, tagPlanWarning as yn, shouldRetainResource as yo, isNamelessDynamicReferenceError as yr, ssmResolvedValueType as ys, withStackRecords as yt, isTruthyCfnBoolean as z, redactSecretsForState as za, findActionableSilentDrops as zi, ec2InstanceProtectionSite as zn, buildDockerImage as zo, isReadableOrphanRecord as zr, absoluteAssemblyPathEscape as zs, redactedDeleteAddressSkip as zt };
|
|
36436
|
+
//# sourceMappingURL=deploy-engine-CMRU0DTu.js.map
|