@go-to-k/cdkd 0.300.1 → 0.301.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{asg-provider-BS5i71bK.js → asg-provider-CK2nZE6B.js} +3 -3
- package/dist/{asg-provider-BS5i71bK.js.map → asg-provider-CK2nZE6B.js.map} +1 -1
- package/dist/aws-failure-text-BEQfs6za.js.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-BK4gG_5A.js → deploy-engine-DEvS2r2M.js} +1697 -1047
- package/dist/deploy-engine-DEvS2r2M.js.map +1 -0
- package/dist/{iam-policy-targets-DAs3w7QW.js → iam-policy-targets-DFk7zr0Q.js} +27 -2
- package/dist/iam-policy-targets-DFk7zr0Q.js.map +1 -0
- package/dist/{iam-role-provider-SmvPHPLC.js → iam-role-provider-s7oQ_V1d.js} +4 -10
- package/dist/iam-role-provider-s7oQ_V1d.js.map +1 -0
- package/dist/index.d.ts +25 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{neptune-provider-CqZ1FaqT.js → neptune-provider-BWESr5fm.js} +3 -3
- package/dist/{neptune-provider-CqZ1FaqT.js.map → neptune-provider-BWESr5fm.js.map} +1 -1
- package/dist/{program-DVPHKsxv.js → program-C_kDHyxY.js} +111 -86
- package/dist/program-C_kDHyxY.js.map +1 -0
- package/dist/{provider-classes-CDzT2xg0.js → provider-classes-C1xbZd9k.js} +229 -110
- package/dist/provider-classes-C1xbZd9k.js.map +1 -0
- package/dist/{rds-provider-DraxDuQq.js → rds-provider-BfwQbYRR.js} +3 -3
- package/dist/{rds-provider-DraxDuQq.js.map → rds-provider-BfwQbYRR.js.map} +1 -1
- package/dist/{version-DTSDiQcV.js → version-BdWNHoO2.js} +2 -2
- package/dist/{version-DTSDiQcV.js.map → version-BdWNHoO2.js.map} +1 -1
- package/package.json +2 -2
- package/dist/deploy-engine-BK4gG_5A.js.map +0 -1
- package/dist/iam-policy-targets-DAs3w7QW.js.map +0 -1
- package/dist/iam-role-provider-SmvPHPLC.js.map +0 -1
- package/dist/program-DVPHKsxv.js.map +0 -1
- package/dist/provider-classes-CDzT2xg0.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as getAwsClients, s as __exportAll } from "./aws-clients-B_CEQGE1.js";
|
|
2
2
|
import { A as UNRENDERABLE, B as safeMsg, C as looksLikeCdkdGeneratedName, D as SAFE_MSG_ALTERED_CHAR, E as withoutGeneratedFallbackName, F as displaySafe, H as terminalSafe, I as displayStackName, L as isPasteableIdent, N as displayAwsMessage, O as SECRET_REF_MAX_CODE_POINTS, P as displayIdent, S as getCurrentStackName, T as withStackName, U as truncateCodePoints, a as getLogger, b as generateResourceNameWithFallback, d as installLogLineMaskerSource, f as getLiveRenderer, g as applyDefaultNameForFallback, j as asIsMessage, k as STACK_REF_MAX_CODE_POINTS, o as isStdoutReservedForPayload, r as safeStringify$1, t as describeAwsFailure, u as currentLogLineMasker, v as explicitNamePropertyFor, w as withSkipPrefix, x as getCurrentSkipPrefix, y as generateResourceName, z as plainIdentOr } from "./aws-failure-text-BEQfs6za.js";
|
|
3
|
-
import { $ as protectedReplacementAdvice, $
|
|
3
|
+
import { $ as protectedReplacementAdvice, $t as ambientCredentialConfig, A as isQuotableImportValue, An as SHELL_ACTIVE, At as isAuxiliaryMarkOf, B as isTerminalDeleteFailure, Bn as shellBoundedDisplay, Bt as formatLockOperation, Cn as StateError, Ct as RETRY_AUXILIARY_OWNER, Dn as normalizeAwsError, Dt as createdResourceIdentityBeforeFailure, E as assertRegionMatch, Et as createdBeforeFailure, F as resolveExplicitPhysicalId, Fn as isInertUnquoted, Ft as UNREPRODUCIBLE_LOCK_CLAUSE, G as runDeleteAttempt, Gn as isUpdateUnsupportedError, Gt as DEFAULT_STATE_PREFIX, H as observeThenDisableProtection, Hn as withheldTargetClause, Ht as recoveryCommandFlags, In as pasteableCommand, It as buildForceUnlockCommand, J as DELETION_PROTECTION_DOC_POINTER, Jn as isNameCooldownError, Kn as hasReplayMayCollide, Kt as injectiveKey, L as ProtectionFlipRegistry, Ln as physicalIdShownBesideCommand, M as quotedRemedyLogicalId, Mn as UNSHOWABLE_VALUE, Mt as markCreatedBeforeFailure, N as refusalTypeShown, Nn as commandHole, Ot as hasCreatedBeforeFailure, Pt as replayMadeAnotherResource, Q as pasteableAwsCommand, Qn as markReplayMayCollide, Qt as ambientClientDefaults, R as compensateProtectionFlip, Rn as plainOrDescribed, St as withDerivedNameMasks, T as RESOURCE_NOT_FOUND, U as protectionFlipKey, Ut as sanitizeRecoveryValue, Vn as shellQuote, Vt as formatLockOwner, Wt as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xn as isReplayedNameCollisionFrom, Yn as isRecreateRetryableError, Yt as producerRecordKey, Zt as withPasteableAwsProfile, _t as createMaskedLogSinks, ar as isRetryableTransientError, at as startInterruptWatch, bn as ResourceUpdateNotSupportedError, bt as maskDeep, ct as canonicalizeRoute53QueryName, d as prepareRemovalForUpdate, dr as markNonRetryable, en as clientDefaultsFor, er as formatRetryClassificationSignals, f as removalWarning, fr as markRedactedCause, ft as logicalIdShown, gt as stateOrphanRecordRemedy, hn as MalformedProducerRecordRefusalError, ht as segmentAfterAnchor, i as holdsSecretDerivedEntry, in as CdkdError, ir as isIamPropagationError, it as isInterruptedWaitError, j as normalizeAwsTagsToCfn, jn as SHELL_ACTIVE_WHY, jt as markAuxiliaryFailure, kt as isAuxiliaryFailure, l as withUnchangedSecretPrincipalLists, ln as DynamicReferenceRegionAmbiguousError, lr as isMarkedNonRetryable, m as withoutInjectedRemovals, mn as MacroExpansionError, mt as resourceTypeShown, nn as AccountIdUnavailableError, nr as isAmbiguousOutcomeError, on as CrossAccountSecretRefusalError, or as isTransientServerError, ot as ElapsedBudgetRegistry, pn as LockError, pr as wrapMaskedAwsError, qn as isNameCollisionErrorFrom, rn as AssetError, sn as DependencyError, sr as retryClassificationText, st as monotonicNowMs, tn as credentialFingerprint, tr as isAmbiguousCcHandlerErrorCode, un as IntrinsicResolutionRefusalError, ur as isThrottlingError, ut as compositeIdSeparatorRefusal, vn as ProvisioningError, vt as createMaskedRetryLogger, w as withoutServerErrorRetries, wn as SynthesisError, wt as carryCreatedBeforeFailure, xt as maskerOrIdentity, yn as ResourceTimeoutError, yt as isSecretDerivedValue, z as deleteWithProtectionCompensation, zn as quotedOrDescribed, zt as formatLockExpiry } from "./iam-policy-targets-DFk7zr0Q.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-DBXBcg0J.js";
|
|
5
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
+
import { t as getCdkdVersion } from "./version-BdWNHoO2.js";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
8
|
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketLifecycleConfigurationCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -2888,6 +2888,12 @@ const DOCKER_CLIENT_ENV_KEYS = /* @__PURE__ */ new Set([
|
|
|
2888
2888
|
"USERPROFILE",
|
|
2889
2889
|
"HOMEDRIVE",
|
|
2890
2890
|
"HOMEPATH",
|
|
2891
|
+
"COMSPEC",
|
|
2892
|
+
"SYSTEMROOT",
|
|
2893
|
+
"WINDIR",
|
|
2894
|
+
"SYSTEMDRIVE",
|
|
2895
|
+
"PSMODULEPATH",
|
|
2896
|
+
"PSEXECUTIONPOLICYPREFERENCE",
|
|
2891
2897
|
"DOCKER_HOST",
|
|
2892
2898
|
"DOCKER_CONTEXT",
|
|
2893
2899
|
"DOCKER_CONFIG",
|
|
@@ -3016,10 +3022,13 @@ const WELL_FORMED_ENV_KEY = /^[^=\0]+$/;
|
|
|
3016
3022
|
function isMalformedEnvKey(key) {
|
|
3017
3023
|
return !WELL_FORMED_ENV_KEY.test(key);
|
|
3018
3024
|
}
|
|
3019
|
-
function partitionSensitiveEnv(env, sensitiveKeys) {
|
|
3025
|
+
function partitionSensitiveEnv(env, sensitiveKeys, options = {}) {
|
|
3026
|
+
const platform = options.platform ?? process.platform;
|
|
3020
3027
|
const flags = [];
|
|
3021
3028
|
const sensitiveEnv = {};
|
|
3022
3029
|
const collisions = [];
|
|
3030
|
+
const names = platform === "win32" ? new Win32EnvNames(Object.keys(process.env)) : void 0;
|
|
3031
|
+
const ambiguous = [];
|
|
3023
3032
|
for (const [k, v] of Object.entries(env)) {
|
|
3024
3033
|
if (!sensitiveKeys.has(k)) {
|
|
3025
3034
|
flags.push("-e", `${k}=${v}`);
|
|
@@ -3029,19 +3038,73 @@ function partitionSensitiveEnv(env, sensitiveKeys) {
|
|
|
3029
3038
|
collisions.push(k);
|
|
3030
3039
|
continue;
|
|
3031
3040
|
}
|
|
3041
|
+
if (names) {
|
|
3042
|
+
if (names.lookup(k).ambiguous) {
|
|
3043
|
+
ambiguous.push(k);
|
|
3044
|
+
continue;
|
|
3045
|
+
}
|
|
3046
|
+
names.replace(k);
|
|
3047
|
+
}
|
|
3032
3048
|
flags.push("-e", k);
|
|
3033
3049
|
defineOwnKey(sensitiveEnv, k, v);
|
|
3034
3050
|
}
|
|
3051
|
+
if (ambiguous.length > 0) getLogger().warn((options.subject === void 0 ? "" : safeMsg`${options.subject}: `) + safeMsg`Sensitive env var(s) ${ambiguous.map((k) => displayIdent(k)).join(", ")} ` + "were NOT passed to the container. On Windows each matches another variable's name (in your environment or another secret) only through a letter-case difference outside A-Z, which cdkd does not treat as the same variable. Rename the secret if the container needs it.");
|
|
3052
|
+
if (names) warnCaseVariantSensitiveKeys(Object.keys(sensitiveEnv), options.subject);
|
|
3035
3053
|
return {
|
|
3036
3054
|
flags,
|
|
3037
3055
|
sensitiveEnv,
|
|
3038
3056
|
collisions
|
|
3039
3057
|
};
|
|
3040
3058
|
}
|
|
3041
|
-
function
|
|
3059
|
+
function warnCaseVariantSensitiveKeys(keys, subject) {
|
|
3060
|
+
const byUpper = /* @__PURE__ */ new Map();
|
|
3061
|
+
for (const k of keys) {
|
|
3062
|
+
const upper = asciiUpper(k);
|
|
3063
|
+
const group = byUpper.get(upper);
|
|
3064
|
+
if (group) group.push(k);
|
|
3065
|
+
else byUpper.set(upper, [k]);
|
|
3066
|
+
}
|
|
3067
|
+
for (const group of byUpper.values()) {
|
|
3068
|
+
if (group.length < 2) continue;
|
|
3069
|
+
getLogger().warn((subject === void 0 ? "" : safeMsg`${subject}: `) + safeMsg`Sensitive env vars ${group.map((k) => displayIdent(k)).join(", ")} differ only by letter case. ` + safeMsg`Windows treats them as one variable, so the container receives the value of ` + safeMsg`${displayIdent(group[group.length - 1])} under every one of these names. ` + `Rename them to distinct names if the container needs each value.`);
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
function asciiUpper(name) {
|
|
3073
|
+
return name.replace(/[a-z]/g, (c) => c.toUpperCase());
|
|
3074
|
+
}
|
|
3075
|
+
var Win32EnvNames = class {
|
|
3076
|
+
groups = /* @__PURE__ */ new Map();
|
|
3077
|
+
constructor(names) {
|
|
3078
|
+
for (const name of names) {
|
|
3079
|
+
const key = name.toUpperCase();
|
|
3080
|
+
const group = this.groups.get(key);
|
|
3081
|
+
if (group) group.push(name);
|
|
3082
|
+
else this.groups.set(key, [name]);
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
lookup(name) {
|
|
3086
|
+
const others = (this.groups.get(name.toUpperCase()) ?? []).filter((n) => n !== name);
|
|
3087
|
+
const folded = asciiUpper(name);
|
|
3088
|
+
return {
|
|
3089
|
+
aliases: others,
|
|
3090
|
+
ambiguous: others.some((n) => asciiUpper(n) !== folded)
|
|
3091
|
+
};
|
|
3092
|
+
}
|
|
3093
|
+
replace(name) {
|
|
3094
|
+
this.groups.set(name.toUpperCase(), [name]);
|
|
3095
|
+
}
|
|
3096
|
+
};
|
|
3097
|
+
function dockerSpawnEnvWithSensitive(sensitiveEnv, platform = process.platform) {
|
|
3042
3098
|
const env = { ...process.env };
|
|
3099
|
+
const names = platform === "win32" ? new Win32EnvNames(Object.keys(env)) : void 0;
|
|
3043
3100
|
for (const [k, v] of Object.entries(sensitiveEnv)) {
|
|
3044
3101
|
if (isMalformedEnvKey(k) || isDockerClientEnvKey(k)) continue;
|
|
3102
|
+
if (names) {
|
|
3103
|
+
const { aliases, ambiguous } = names.lookup(k);
|
|
3104
|
+
if (ambiguous) continue;
|
|
3105
|
+
for (const alias of aliases) delete env[alias];
|
|
3106
|
+
names.replace(k);
|
|
3107
|
+
}
|
|
3045
3108
|
defineOwnKey(env, k, v);
|
|
3046
3109
|
}
|
|
3047
3110
|
return env;
|
|
@@ -4895,11 +4958,22 @@ function refuseMalformedOperation(shownStack, where, op) {
|
|
|
4895
4958
|
if (o["oldResourceMaySurvive"] !== void 0 && !["kept", "unconfirmed"].includes(o["oldResourceMaySurvive"])) fail("oldResourceMaySurvive", o["oldResourceMaySurvive"], "kept or unconfirmed when present");
|
|
4896
4959
|
if (o["physicalIdRecoveredFromError"] !== void 0 && typeof o["physicalIdRecoveredFromError"] !== "boolean") fail("physicalIdRecoveredFromError", o["physicalIdRecoveredFromError"], "a boolean when present");
|
|
4897
4960
|
if (o["physicalIdRecoveredFromError"] !== void 0 && o["changeType"] !== "CREATE") refuseMalformed(shownStack, `${where}.physicalIdRecoveredFromError is only valid on a CREATE (got changeType ${kind(o["changeType"])}).`);
|
|
4961
|
+
const pending = o["pendingCloudControlRequest"];
|
|
4962
|
+
if (pending !== void 0) {
|
|
4963
|
+
const p = pending;
|
|
4964
|
+
if (typeof pending !== "object" || pending === null || Array.isArray(pending) || typeof p["requestToken"] !== "string" || !/^[-A-Za-z0-9+/=]{1,128}$/.test(p["requestToken"]) || typeof p["abandonedAt"] !== "number" || !Number.isFinite(p["abandonedAt"])) fail("pendingCloudControlRequest", pending, "an object with a Cloud Control requestToken and a numeric abandonedAt when present");
|
|
4965
|
+
if (o["changeType"] !== "CREATE" || o["physicalId"] !== void 0 || o["physicalIdRecoveredFromError"] !== void 0) refuseMalformed(shownStack, `${where}.pendingCloudControlRequest is only valid on a CREATE with no physicalId.`);
|
|
4966
|
+
}
|
|
4898
4967
|
const identity = o["createdResourceIdentity"];
|
|
4899
4968
|
if (identity !== void 0) {
|
|
4900
4969
|
if (typeof identity !== "string" || identity === "") fail("createdResourceIdentity", identity, "a non-empty string when present");
|
|
4901
4970
|
if (typeof o["physicalIdRecoveredFromError"] !== "boolean") refuseMalformed(shownStack, `${where}.createdResourceIdentity is only valid on a CREATE carrying physicalIdRecoveredFromError.`);
|
|
4902
4971
|
}
|
|
4972
|
+
const unique = o["createdIdentifierUnique"];
|
|
4973
|
+
if (unique !== void 0) {
|
|
4974
|
+
if (typeof unique !== "boolean") fail("createdIdentifierUnique", unique, "a boolean when present");
|
|
4975
|
+
if (typeof o["physicalIdRecoveredFromError"] !== "boolean" || o["provisionedBy"] !== "cc-api") refuseMalformed(shownStack, `${where}.createdIdentifierUnique is only valid on a Cloud Control CREATE carrying physicalIdRecoveredFromError.`);
|
|
4976
|
+
}
|
|
4903
4977
|
if (o["deletionPolicy"] !== void 0 && ![
|
|
4904
4978
|
"Delete",
|
|
4905
4979
|
"Retain",
|
|
@@ -6395,6 +6469,25 @@ var S3StateBackend = class S3StateBackend {
|
|
|
6395
6469
|
await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
|
|
6396
6470
|
return removed;
|
|
6397
6471
|
}
|
|
6472
|
+
async rewriteRollbackJournalFailedOperations(stackName, region, rewrite) {
|
|
6473
|
+
const journal = await this.loadRollbackJournal(stackName, region);
|
|
6474
|
+
if (!journal) return 0;
|
|
6475
|
+
let changed = 0;
|
|
6476
|
+
for (const segment of journal.segments) {
|
|
6477
|
+
if (!segment.failedOperations) continue;
|
|
6478
|
+
const next = [];
|
|
6479
|
+
for (const op of segment.failedOperations) {
|
|
6480
|
+
const out = rewrite(op, segment);
|
|
6481
|
+
if (out !== op) changed++;
|
|
6482
|
+
if (out !== null) next.push(out);
|
|
6483
|
+
}
|
|
6484
|
+
if (next.length === 0) delete segment.failedOperations;
|
|
6485
|
+
else segment.failedOperations = next;
|
|
6486
|
+
}
|
|
6487
|
+
if (changed === 0) return 0;
|
|
6488
|
+
await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
|
|
6489
|
+
return changed;
|
|
6490
|
+
}
|
|
6398
6491
|
async reduceRollbackJournalToFailedOperations(stackName, region, keep, supersededLogicalIds = [], demote = () => false) {
|
|
6399
6492
|
const journal = await this.loadRollbackJournal(stackName, region);
|
|
6400
6493
|
if (!journal) return 0;
|
|
@@ -7672,6 +7765,40 @@ function positionByCrossStackSource(bag, source, secrets) {
|
|
|
7672
7765
|
return certifiedExpressionForLeaf(secrets, association, bag);
|
|
7673
7766
|
}
|
|
7674
7767
|
|
|
7768
|
+
//#endregion
|
|
7769
|
+
//#region src/deployment/secret-redaction/resolver-outcomes.ts
|
|
7770
|
+
const CONFLICTING = Symbol("cdkd.resolver-outcome.conflicting");
|
|
7771
|
+
const takenBranches = /* @__PURE__ */ new WeakMap();
|
|
7772
|
+
function recordTakenIfBranch(secrets, source, tookTrueBranch) {
|
|
7773
|
+
let taken = takenBranches.get(secrets);
|
|
7774
|
+
if (taken === void 0) {
|
|
7775
|
+
taken = /* @__PURE__ */ new WeakMap();
|
|
7776
|
+
takenBranches.set(secrets, taken);
|
|
7777
|
+
}
|
|
7778
|
+
const previous = taken.get(source);
|
|
7779
|
+
if (previous === void 0) taken.set(source, tookTrueBranch);
|
|
7780
|
+
else if (previous !== tookTrueBranch) taken.set(source, CONFLICTING);
|
|
7781
|
+
}
|
|
7782
|
+
function takenIfBranchOf(secrets, source) {
|
|
7783
|
+
const taken = takenBranches.get(secrets)?.get(source);
|
|
7784
|
+
return taken === CONFLICTING ? void 0 : taken;
|
|
7785
|
+
}
|
|
7786
|
+
const droppedElements = /* @__PURE__ */ new WeakMap();
|
|
7787
|
+
function recordDroppedArrayElements(secrets, source, dropped) {
|
|
7788
|
+
let arrays = droppedElements.get(secrets);
|
|
7789
|
+
if (arrays === void 0) {
|
|
7790
|
+
arrays = /* @__PURE__ */ new WeakMap();
|
|
7791
|
+
droppedElements.set(secrets, arrays);
|
|
7792
|
+
}
|
|
7793
|
+
const previous = arrays.get(source);
|
|
7794
|
+
if (previous === void 0) arrays.set(source, [...dropped]);
|
|
7795
|
+
else if (previous !== CONFLICTING && (previous.length !== dropped.length || previous.some((index, i) => index !== dropped[i]))) arrays.set(source, CONFLICTING);
|
|
7796
|
+
}
|
|
7797
|
+
function droppedArrayElementsOf(secrets, source) {
|
|
7798
|
+
const dropped = droppedElements.get(secrets)?.get(source);
|
|
7799
|
+
return dropped === CONFLICTING ? void 0 : dropped;
|
|
7800
|
+
}
|
|
7801
|
+
|
|
7675
7802
|
//#endregion
|
|
7676
7803
|
//#region src/deployment/secret-redaction/physical-name-copies.ts
|
|
7677
7804
|
const physicalNameCopiesOf = /* @__PURE__ */ new WeakMap();
|
|
@@ -8086,6 +8213,34 @@ function positionByInheritedParameter(bag, source, secrets) {
|
|
|
8086
8213
|
if (!deepEqualJsonValue(redactSecretsForState(answer, secrets), answer)) return void 0;
|
|
8087
8214
|
return answer;
|
|
8088
8215
|
}
|
|
8216
|
+
const REREAD_PSEUDO_PARAMETERS = /* @__PURE__ */ new Set([
|
|
8217
|
+
"AWS::Region",
|
|
8218
|
+
"AWS::Partition",
|
|
8219
|
+
"AWS::URLSuffix"
|
|
8220
|
+
]);
|
|
8221
|
+
const inheritedPseudoParameters = /* @__PURE__ */ new WeakMap();
|
|
8222
|
+
const POISONED_PSEUDO_PARAMETERS = Symbol("cdkd.inherited-pseudo-parameters.poisoned");
|
|
8223
|
+
function recordInheritedPseudoParameters(inheritedSecrets, values) {
|
|
8224
|
+
let table = inheritedPseudoParameters.get(inheritedSecrets);
|
|
8225
|
+
if (table === POISONED_PSEUDO_PARAMETERS) return;
|
|
8226
|
+
if (table === void 0) {
|
|
8227
|
+
table = /* @__PURE__ */ new Map();
|
|
8228
|
+
inheritedPseudoParameters.set(inheritedSecrets, table);
|
|
8229
|
+
}
|
|
8230
|
+
for (const [name, value] of values) {
|
|
8231
|
+
if (!REREAD_PSEUDO_PARAMETERS.has(name) || typeof value !== "string") continue;
|
|
8232
|
+
const known = table.get(name);
|
|
8233
|
+
if (known !== void 0 && known !== value) {
|
|
8234
|
+
inheritedPseudoParameters.set(inheritedSecrets, POISONED_PSEUDO_PARAMETERS);
|
|
8235
|
+
return;
|
|
8236
|
+
}
|
|
8237
|
+
table.set(name, value);
|
|
8238
|
+
}
|
|
8239
|
+
}
|
|
8240
|
+
function pseudoBindingOf(parentSecrets) {
|
|
8241
|
+
const table = inheritedPseudoParameters.get(parentSecrets);
|
|
8242
|
+
return (name) => table instanceof Map && table.has(name) ? { value: table.get(name) } : void 0;
|
|
8243
|
+
}
|
|
8089
8244
|
const REREAD_TRIGGERS = /* @__PURE__ */ new Set([
|
|
8090
8245
|
"Fn::Select",
|
|
8091
8246
|
"Fn::Split",
|
|
@@ -8124,9 +8279,9 @@ function standsForInheritedSecret(parentSecrets, token) {
|
|
|
8124
8279
|
return parentSecrets !== void 0 && resolvedPlaintextOf(parentSecrets, token) !== void 0;
|
|
8125
8280
|
}
|
|
8126
8281
|
const plainSplit = (text, delimiter) => text.split(delimiter);
|
|
8127
|
-
function evaluatePureRead(node, bind, split, choose, depth = 0) {
|
|
8282
|
+
function evaluatePureRead(node, bind, pseudo, split, choose, depth = 0) {
|
|
8128
8283
|
if (depth > MAX_REREAD_DEPTH) return void 0;
|
|
8129
|
-
const evaluate = (child) => evaluatePureRead(child, bind, split, choose, depth + 1);
|
|
8284
|
+
const evaluate = (child) => evaluatePureRead(child, bind, pseudo, split, choose, depth + 1);
|
|
8130
8285
|
if (typeof node === "string") return node.includes("{{resolve:") ? void 0 : { value: node };
|
|
8131
8286
|
if (Array.isArray(node)) {
|
|
8132
8287
|
const out = [];
|
|
@@ -8144,13 +8299,15 @@ function evaluatePureRead(node, bind, split, choose, depth = 0) {
|
|
|
8144
8299
|
const args = node[key];
|
|
8145
8300
|
if (key === "Ref") {
|
|
8146
8301
|
if (args === "AWS::NoValue") return { value: REREAD_NO_VALUE };
|
|
8147
|
-
return typeof args === "string" ?
|
|
8302
|
+
return typeof args === "string" ? bindReadName(args, bind, pseudo) : void 0;
|
|
8148
8303
|
}
|
|
8149
8304
|
if (key === "Fn::If") {
|
|
8150
8305
|
if (!Array.isArray(args) || args.length !== 3 || typeof args[0] !== "string") return void 0;
|
|
8151
|
-
|
|
8306
|
+
const tookTrue = choose(args[0], node);
|
|
8307
|
+
if (tookTrue === void 0) return void 0;
|
|
8308
|
+
return evaluate(tookTrue ? args[1] : args[2]);
|
|
8152
8309
|
}
|
|
8153
|
-
if (key === "Fn::Sub") return evaluatePureSub(args, bind, evaluate);
|
|
8310
|
+
if (key === "Fn::Sub") return evaluatePureSub(args, bind, pseudo, evaluate);
|
|
8154
8311
|
if (!Array.isArray(args) || args.length !== 2) return void 0;
|
|
8155
8312
|
if (key === "Fn::Select") {
|
|
8156
8313
|
const index = args[0];
|
|
@@ -8174,7 +8331,7 @@ function evaluatePureRead(node, bind, split, choose, depth = 0) {
|
|
|
8174
8331
|
return { value: parts.value.join(delimiter) };
|
|
8175
8332
|
}
|
|
8176
8333
|
}
|
|
8177
|
-
function evaluatePureSub(args, bind, evaluate) {
|
|
8334
|
+
function evaluatePureSub(args, bind, pseudo, evaluate) {
|
|
8178
8335
|
const [text, variables] = typeof args === "string" ? [args, {}] : Array.isArray(args) && args.length === 2 ? [args[0], args[1]] : [void 0, void 0];
|
|
8179
8336
|
if (typeof text !== "string" || text.includes("{{resolve:") || !isPlainObject$7(variables)) return;
|
|
8180
8337
|
const bound = /* @__PURE__ */ new Map();
|
|
@@ -8192,8 +8349,8 @@ function evaluatePureSub(args, bind, evaluate) {
|
|
|
8192
8349
|
else if (name === "") replacement = match[0];
|
|
8193
8350
|
else if (bound.has(name)) replacement = bound.get(name);
|
|
8194
8351
|
else {
|
|
8195
|
-
if (name.
|
|
8196
|
-
const value =
|
|
8352
|
+
if (name.includes(".")) return void 0;
|
|
8353
|
+
const value = bindReadName(name, bind, pseudo);
|
|
8197
8354
|
if (value === void 0 || typeof value.value !== "string") return void 0;
|
|
8198
8355
|
replacement = value.value;
|
|
8199
8356
|
}
|
|
@@ -8202,6 +8359,10 @@ function evaluatePureSub(args, bind, evaluate) {
|
|
|
8202
8359
|
}
|
|
8203
8360
|
return { value: out + text.slice(cursor) };
|
|
8204
8361
|
}
|
|
8362
|
+
function bindReadName(name, bind, pseudo) {
|
|
8363
|
+
if (!name.startsWith("AWS::")) return bind(name);
|
|
8364
|
+
return bind(name) === void 0 ? pseudo(name) : void 0;
|
|
8365
|
+
}
|
|
8205
8366
|
function collectRereadConditions(node, names, depth = 0) {
|
|
8206
8367
|
if (depth > MAX_REREAD_DEPTH) return false;
|
|
8207
8368
|
if (Array.isArray(node)) return node.every((element) => collectRereadConditions(element, names, depth + 1));
|
|
@@ -8228,17 +8389,57 @@ function rendersReadTo(spelling, parentSecrets, value) {
|
|
|
8228
8389
|
return false;
|
|
8229
8390
|
}
|
|
8230
8391
|
const REREAD_UNBOUND = Symbol("cdkd.reread.unbound");
|
|
8231
|
-
|
|
8392
|
+
const REREAD_PARAMETER_FREE = Symbol("cdkd.reread.parameter-free");
|
|
8393
|
+
function diffSideReading(bind, parentSecrets) {
|
|
8394
|
+
return {
|
|
8395
|
+
bind: (name) => {
|
|
8396
|
+
const bound = bind(name);
|
|
8397
|
+
return bound && { value: redactInheritedParameterValue(parentSecrets, name, bound.value) };
|
|
8398
|
+
},
|
|
8399
|
+
split: (text, delimiter) => splitOutsideDynamicReferences(text, delimiter, (token) => standsForInheritedSecret(parentSecrets, token))
|
|
8400
|
+
};
|
|
8401
|
+
}
|
|
8402
|
+
function rereadUnder(source, bind, parentSecrets, choose) {
|
|
8403
|
+
const pseudo = pseudoBindingOf(parentSecrets);
|
|
8404
|
+
const resolved = evaluatePureRead(source, bind, pseudo, plainSplit, choose);
|
|
8405
|
+
if (resolved === void 0) return void 0;
|
|
8406
|
+
const diffSide = diffSideReading(bind, parentSecrets);
|
|
8407
|
+
const redacted = evaluatePureRead(source, diffSide.bind, pseudo, diffSide.split, choose);
|
|
8408
|
+
if (redacted === void 0) return void 0;
|
|
8409
|
+
if (resolved.value === REREAD_NO_VALUE || redacted.value === REREAD_NO_VALUE) return resolved.value === redacted.value ? REREAD_NO_VALUE : void 0;
|
|
8410
|
+
if (!rendersReadTo(redacted.value, parentSecrets, resolved.value)) return void 0;
|
|
8411
|
+
return {
|
|
8412
|
+
resolved: resolved.value,
|
|
8413
|
+
redacted: redacted.value
|
|
8414
|
+
};
|
|
8415
|
+
}
|
|
8416
|
+
function namesParameterOnBranches(node, choose, isParameter, depth = 0) {
|
|
8417
|
+
if (depth > MAX_REREAD_DEPTH) return true;
|
|
8418
|
+
if (typeof node === "string") return node.includes("{{resolve:");
|
|
8419
|
+
if (Array.isArray(node)) return node.some((element) => namesParameterOnBranches(element, choose, isParameter, depth + 1));
|
|
8420
|
+
if (!isPlainObject$7(node)) return false;
|
|
8421
|
+
if (Object.hasOwn(node, "Fn::If")) {
|
|
8422
|
+
const args = node["Fn::If"];
|
|
8423
|
+
if (Object.keys(node).length !== 1) return true;
|
|
8424
|
+
if (!Array.isArray(args) || args.length !== 3 || typeof args[0] !== "string") return true;
|
|
8425
|
+
const tookTrue = choose(args[0], node);
|
|
8426
|
+
if (tookTrue === void 0) return true;
|
|
8427
|
+
return namesParameterOnBranches(tookTrue ? args[1] : args[2], choose, isParameter, depth + 1);
|
|
8428
|
+
}
|
|
8429
|
+
if (typeof node["Ref"] === "string" && isParameter(node["Ref"])) return true;
|
|
8430
|
+
const sub = node["Fn::Sub"];
|
|
8431
|
+
const text = typeof sub === "string" ? sub : Array.isArray(sub) ? sub[0] : void 0;
|
|
8432
|
+
if (typeof text === "string") {
|
|
8433
|
+
for (const match of text.matchAll(/\$\{([^}!][^}]*)\}/g)) if (isParameter(match[1].trim()) || isParameter(match[1])) return true;
|
|
8434
|
+
}
|
|
8435
|
+
return Object.values(node).some((child) => namesParameterOnBranches(child, choose, isParameter, depth + 1));
|
|
8436
|
+
}
|
|
8437
|
+
function rereadAssignments(source, bind, parentSecrets, untakenWhenUnbound = () => false, parameterFree) {
|
|
8232
8438
|
if (!holdsRereadTrigger(source)) return void 0;
|
|
8233
8439
|
const conditions = /* @__PURE__ */ new Set();
|
|
8234
8440
|
if (!collectRereadConditions(source, conditions)) return void 0;
|
|
8235
8441
|
if (conditions.size > MAX_REREAD_CONDITIONS) return void 0;
|
|
8236
8442
|
const names = [...conditions];
|
|
8237
|
-
const redactedBind = (name) => {
|
|
8238
|
-
const bound = bind(name);
|
|
8239
|
-
return bound && { value: redactInheritedParameterValue(parentSecrets, name, bound.value) };
|
|
8240
|
-
};
|
|
8241
|
-
const tokenSplit = (text, delimiter) => splitOutsideDynamicReferences(text, delimiter, (token) => standsForInheritedSecret(parentSecrets, token));
|
|
8242
8443
|
const out = [];
|
|
8243
8444
|
for (let assignment = 0; assignment < 2 ** names.length; assignment++) {
|
|
8244
8445
|
const choose = (condition) => Math.floor(assignment / 2 ** names.indexOf(condition)) % 2 === 1;
|
|
@@ -8248,25 +8449,18 @@ function rereadAssignments(source, bind, parentSecrets, untakenWhenUnbound = ()
|
|
|
8248
8449
|
if (bound === void 0 && untakenWhenUnbound(name)) unbound = true;
|
|
8249
8450
|
return bound;
|
|
8250
8451
|
};
|
|
8251
|
-
const
|
|
8252
|
-
const redacted = resolved && evaluatePureRead(source, redactedBind, tokenSplit, choose);
|
|
8452
|
+
const reread = rereadUnder(source, tracked, parentSecrets, choose);
|
|
8253
8453
|
if (unbound) out.push(REREAD_UNBOUND);
|
|
8254
|
-
else if (
|
|
8255
|
-
else if (
|
|
8256
|
-
else
|
|
8257
|
-
else out.push({
|
|
8258
|
-
resolved: resolved.value,
|
|
8259
|
-
redacted: redacted.value
|
|
8260
|
-
});
|
|
8454
|
+
else if (reread !== void 0) out.push(reread);
|
|
8455
|
+
else if (parameterFree !== void 0 && !namesParameterOnBranches(source, choose, parameterFree)) out.push(REREAD_PARAMETER_FREE);
|
|
8456
|
+
else out.push(void 0);
|
|
8261
8457
|
}
|
|
8262
8458
|
return out;
|
|
8263
8459
|
}
|
|
8264
8460
|
function rereadParameterExpression(source, bind, parentSecrets) {
|
|
8265
|
-
const assignments = rereadAssignments(source, bind, parentSecrets);
|
|
8461
|
+
const assignments = rereadAssignments(source, bind, parentSecrets, void 0, (name) => bind(name) !== void 0);
|
|
8266
8462
|
if (assignments === void 0 || assignments.includes(void 0) || assignments.includes(REREAD_UNBOUND)) return;
|
|
8267
|
-
|
|
8268
|
-
if (rereads.length === 0 || ambiguousRereads(rereads)) return void 0;
|
|
8269
|
-
return rereads[0];
|
|
8463
|
+
return assignments.find((entry) => entry !== void 0 && entry !== REREAD_NO_VALUE && entry !== REREAD_UNBOUND && entry !== REREAD_PARAMETER_FREE);
|
|
8270
8464
|
}
|
|
8271
8465
|
function ambiguousRereads(rereads) {
|
|
8272
8466
|
return rereads.some((a, i) => rereads.slice(i + 1).some((b) => deepEqualJsonValue(a.resolved, b.resolved) && !deepEqualJsonValue(a.redacted, b.redacted)));
|
|
@@ -8275,13 +8469,27 @@ function positionByParameterReread(bag, source, secrets) {
|
|
|
8275
8469
|
const reads = inheritedParameterReads.get(secrets);
|
|
8276
8470
|
if (reads === void 0 || typeof reads === "symbol") return void 0;
|
|
8277
8471
|
if (typeof bag !== "string" && !Array.isArray(bag)) return void 0;
|
|
8278
|
-
|
|
8279
|
-
const
|
|
8280
|
-
|
|
8281
|
-
const
|
|
8282
|
-
|
|
8472
|
+
if (!holdsRereadTrigger(source)) return void 0;
|
|
8473
|
+
const bind = (name) => reads.values.has(name) ? { value: reads.values.get(name) } : void 0;
|
|
8474
|
+
let unrecorded = false;
|
|
8475
|
+
const recorded = rereadUnder(source, bind, reads.parent, (_, node) => {
|
|
8476
|
+
const taken = takenIfBranchOf(secrets, node);
|
|
8477
|
+
if (taken === void 0) unrecorded = true;
|
|
8478
|
+
return taken;
|
|
8479
|
+
});
|
|
8480
|
+
let answer;
|
|
8481
|
+
if (!unrecorded) {
|
|
8482
|
+
if (recorded === void 0 || recorded === REREAD_NO_VALUE || !deepEqualJsonValue(recorded.resolved, bag)) return;
|
|
8483
|
+
answer = recorded.redacted;
|
|
8484
|
+
} else {
|
|
8485
|
+
const declared = reads.declared;
|
|
8486
|
+
const assignments = rereadAssignments(source, bind, reads.parent, (name) => declared?.has(name) === true);
|
|
8487
|
+
if (assignments === void 0 || assignments.includes(void 0)) return void 0;
|
|
8488
|
+
const matching = assignments.filter((entry) => entry !== void 0 && entry !== REREAD_NO_VALUE && entry !== REREAD_UNBOUND && entry !== REREAD_PARAMETER_FREE && deepEqualJsonValue(entry.resolved, bag));
|
|
8489
|
+
if (matching.length === 0 || ambiguousRereads(matching)) return void 0;
|
|
8490
|
+
answer = matching[0].redacted;
|
|
8491
|
+
}
|
|
8283
8492
|
if (carriesChildOnlyPlaintext(bag, secrets, reads.parent)) return void 0;
|
|
8284
|
-
const answer = matching[0].redacted;
|
|
8285
8493
|
if (!deepEqualJsonValue(redactSecretsForState(answer, secrets), answer)) return void 0;
|
|
8286
8494
|
return answer;
|
|
8287
8495
|
}
|
|
@@ -8542,7 +8750,12 @@ function arrayElementDrop(element, depth = 0) {
|
|
|
8542
8750
|
if (branches.every((branch) => branch === "always")) return "always";
|
|
8543
8751
|
return "maybe";
|
|
8544
8752
|
}
|
|
8545
|
-
function sourceElementsKeptFor(source, bagLength) {
|
|
8753
|
+
function sourceElementsKeptFor(source, bagLength, secrets) {
|
|
8754
|
+
const recorded = secrets && droppedArrayElementsOf(secrets, source);
|
|
8755
|
+
if (recorded !== void 0) {
|
|
8756
|
+
if (source.length - recorded.length !== bagLength) return void 0;
|
|
8757
|
+
return source.filter((_, i) => !recorded.includes(i));
|
|
8758
|
+
}
|
|
8546
8759
|
const drops = source.map((element) => arrayElementDrop(element));
|
|
8547
8760
|
if (drops.includes("unknown")) return void 0;
|
|
8548
8761
|
const always = drops.filter((drop) => drop === "always").length;
|
|
@@ -8587,8 +8800,7 @@ function corroboratesWhateverResolves(source, depth = 0) {
|
|
|
8587
8800
|
}
|
|
8588
8801
|
function arrayPairsWhateverDrops(source) {
|
|
8589
8802
|
if (!source.some((element) => isPlainObject$7(element) && (Object.hasOwn(element, "Fn::If") || element["Ref"] === "AWS::NoValue" || Array.isArray(element["Fn::FindInMap"]) && element["Fn::FindInMap"].length > 3))) return true;
|
|
8590
|
-
|
|
8591
|
-
return !drops.includes("unknown") && drops.filter((drop) => drop === "maybe").length <= 1 && source.every((element) => corroboratesWhateverResolves(element));
|
|
8803
|
+
return source.every((element) => corroboratesWhateverResolves(element));
|
|
8592
8804
|
}
|
|
8593
8805
|
function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameGeneration) {
|
|
8594
8806
|
if (isDynamicReferenceString(source) && typeof bag === "string") {
|
|
@@ -8645,7 +8857,7 @@ function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameG
|
|
|
8645
8857
|
}
|
|
8646
8858
|
if (rules.descendArrays && bag.length === source.length) return bag.map((item, i) => redactByPath(item, source[i], secrets, rules, secretExpressions, bagIsSameGeneration));
|
|
8647
8859
|
if (rules.descendArrays && bag.length < source.length) {
|
|
8648
|
-
const kept = sourceElementsKeptFor(source, bag.length);
|
|
8860
|
+
const kept = sourceElementsKeptFor(source, bag.length, secrets);
|
|
8649
8861
|
if (kept !== void 0 && keptLiteralsCorroborate(kept, bag, secrets)) return bag.map((item, i) => redactByPath(item, kept[i], secrets, rules, secretExpressions, bagIsSameGeneration));
|
|
8650
8862
|
}
|
|
8651
8863
|
}
|
|
@@ -22925,6 +23137,281 @@ async function resolveSub(subArgs, context, source) {
|
|
|
22925
23137
|
return result;
|
|
22926
23138
|
}
|
|
22927
23139
|
|
|
23140
|
+
//#endregion
|
|
23141
|
+
//#region src/deployment/intrinsic-resolver/parameter-secrets.ts
|
|
23142
|
+
function recordInheritedParameterSecrets(parameterName, value, context) {
|
|
23143
|
+
const inherited = context.inheritedSecrets;
|
|
23144
|
+
const recorded = context.recordedSecretValues;
|
|
23145
|
+
if (inherited && recorded) carryLogOnlyValuesCarriedBy(inherited, recorded, value);
|
|
23146
|
+
if (recorded) carryPhysicalNameCopiesCarriedBy(context, recorded, value);
|
|
23147
|
+
if (inherited && recorded) recordInheritedNoEchoListElements(this, inherited, recorded, value, context);
|
|
23148
|
+
if (!inherited || inherited.size === 0 || !recorded) return;
|
|
23149
|
+
const mirror = parameterReadMirrors.get(recorded);
|
|
23150
|
+
const declared = declaredParameterNames(context);
|
|
23151
|
+
recordInheritedParameterValue(recorded, inherited, parameterName, value, declared);
|
|
23152
|
+
if (mirror) recordInheritedParameterValue(mirror, inherited, parameterName, value, declared);
|
|
23153
|
+
for (const [plaintext, expression] of inheritedSecretsCarriedBy(value, inherited)) {
|
|
23154
|
+
const carried = carriedExpressionFor(inherited, parameterName, value, plaintext, expression);
|
|
23155
|
+
recorded.set(plaintext, carried);
|
|
23156
|
+
const parentEntry = context.inheritedReferenceProvenance?.get(carried);
|
|
23157
|
+
if (parentEntry !== void 0) recordReferenceProvenanceEntry(recorded, carried, parentEntry, "read");
|
|
23158
|
+
recordInheritedParameterRead(recorded, inherited, parameterName);
|
|
23159
|
+
if (mirror) recordInheritedParameterRead(mirror, inherited, parameterName);
|
|
23160
|
+
carryFreshNoEchoMark(inherited, recorded, plaintext);
|
|
23161
|
+
}
|
|
23162
|
+
}
|
|
23163
|
+
async function recordInheritedPseudoParameterValues(resolver, inherited) {
|
|
23164
|
+
if (inherited.size === 0) return;
|
|
23165
|
+
const values = /* @__PURE__ */ new Map();
|
|
23166
|
+
for (const name of [
|
|
23167
|
+
"AWS::Region",
|
|
23168
|
+
"AWS::Partition",
|
|
23169
|
+
"AWS::URLSuffix"
|
|
23170
|
+
]) values.set(name, await resolver.resolvePseudoParameter(name));
|
|
23171
|
+
recordInheritedPseudoParameters(inherited, values);
|
|
23172
|
+
}
|
|
23173
|
+
function declaredParameterNames(context) {
|
|
23174
|
+
const declared = context.template?.Parameters;
|
|
23175
|
+
if (declared === null || typeof declared !== "object") return void 0;
|
|
23176
|
+
let names = declaredNamesCache.get(declared);
|
|
23177
|
+
if (names === void 0) {
|
|
23178
|
+
names = new Set(Object.keys(declared));
|
|
23179
|
+
declaredNamesCache.set(declared, names);
|
|
23180
|
+
}
|
|
23181
|
+
return names;
|
|
23182
|
+
}
|
|
23183
|
+
const declaredNamesCache = /* @__PURE__ */ new WeakMap();
|
|
23184
|
+
const parameterReadMirrors = /* @__PURE__ */ new WeakMap();
|
|
23185
|
+
function mirrorInheritedParameterReads(passSecrets, persistSecrets) {
|
|
23186
|
+
if (passSecrets !== persistSecrets) parameterReadMirrors.set(passSecrets, persistSecrets);
|
|
23187
|
+
}
|
|
23188
|
+
function recordTakenIfBranchIn(context, source, tookTrueBranch) {
|
|
23189
|
+
if (!context.inheritedSecrets || context.inheritedSecrets.size === 0) return;
|
|
23190
|
+
const recorded = context.recordedSecretValues;
|
|
23191
|
+
if (recorded === void 0) return;
|
|
23192
|
+
recordTakenIfBranch(recorded, source, tookTrueBranch);
|
|
23193
|
+
const mirror = parameterReadMirrors.get(recorded);
|
|
23194
|
+
if (mirror) recordTakenIfBranch(mirror, source, tookTrueBranch);
|
|
23195
|
+
}
|
|
23196
|
+
function recordDroppedArrayElementsIn(context, source, dropped) {
|
|
23197
|
+
const recorded = context.recordedSecretValues;
|
|
23198
|
+
if (recorded === void 0) return;
|
|
23199
|
+
recordDroppedArrayElements(recorded, source, dropped);
|
|
23200
|
+
const mirror = parameterReadMirrors.get(recorded);
|
|
23201
|
+
if (mirror) recordDroppedArrayElements(mirror, source, dropped);
|
|
23202
|
+
}
|
|
23203
|
+
function carryPhysicalNameCopiesCarriedBy(context, recorded, value) {
|
|
23204
|
+
const names = context.inheritedPhysicalNameCopies ?? (context.inheritedSecrets && physicalNameCopiesOf.get(context.inheritedSecrets));
|
|
23205
|
+
if (names === void 0 || names.size === 0) return;
|
|
23206
|
+
const leaves = [...wholeStringLeavesOf(value)];
|
|
23207
|
+
for (const name of names) if (leaves.some((leaf) => leaf.includes(name))) recordPhysicalNameCopy(recorded, name);
|
|
23208
|
+
}
|
|
23209
|
+
function carriedExpressionFor(inherited, parameterName, value, plaintext, survivor) {
|
|
23210
|
+
const own = inheritedParameterExpression(inherited, parameterName, plaintext);
|
|
23211
|
+
if (typeof own === "string") return own;
|
|
23212
|
+
return inheritedRenderedToken(inherited, parameterName, value, plaintext) ?? survivor;
|
|
23213
|
+
}
|
|
23214
|
+
function poisonRenderedSpellingsCollidingIn(template, parameterValues, inherited) {
|
|
23215
|
+
if (!inherited || inherited.size === 0 || template === void 0) return;
|
|
23216
|
+
const names = new Set(Object.keys(parameterValues));
|
|
23217
|
+
if (names.size < 2) return;
|
|
23218
|
+
const groups = [];
|
|
23219
|
+
if (template.Resources !== null && typeof template.Resources === "object") for (const resource of Object.values(template.Resources)) groups.push([{
|
|
23220
|
+
node: resource,
|
|
23221
|
+
mode: "resource"
|
|
23222
|
+
}]);
|
|
23223
|
+
if (template.Outputs !== void 0) groups.push(outputsGroupParts(template.Outputs));
|
|
23224
|
+
const bind = (name) => Object.hasOwn(parameterValues, name) ? { value: parameterValues[name] } : void 0;
|
|
23225
|
+
const withdrawn = /* @__PURE__ */ new Set();
|
|
23226
|
+
for (;;) {
|
|
23227
|
+
const fresh = [...collidingRenderedNames(groups.map((parts) => {
|
|
23228
|
+
const reads = /* @__PURE__ */ new Map();
|
|
23229
|
+
for (const { node, mode } of parts) {
|
|
23230
|
+
const reread = mode === "slot" ? void 0 : {
|
|
23231
|
+
bind,
|
|
23232
|
+
inherited
|
|
23233
|
+
};
|
|
23234
|
+
for (const [name, slotRead] of parameterReadsOf(node, names, reread, mode !== "output")) reads.set(name, slotRead || reads.get(name) === true);
|
|
23235
|
+
}
|
|
23236
|
+
return reads;
|
|
23237
|
+
}).filter((reads) => reads.size >= 2), parameterValues, inherited)].filter((name) => !withdrawn.has(name));
|
|
23238
|
+
if (fresh.length === 0) return;
|
|
23239
|
+
for (const name of fresh) {
|
|
23240
|
+
withdrawn.add(name);
|
|
23241
|
+
withdrawRenderedParameterSpelling(inherited, name);
|
|
23242
|
+
}
|
|
23243
|
+
}
|
|
23244
|
+
}
|
|
23245
|
+
function collidingRenderedNames(readsByGroup, parameterValues, inherited) {
|
|
23246
|
+
const withdraw = /* @__PURE__ */ new Set();
|
|
23247
|
+
for (const reads of readsByGroup) {
|
|
23248
|
+
const byPlaintext = /* @__PURE__ */ new Map();
|
|
23249
|
+
const slotReadPlaintexts = /* @__PURE__ */ new Set();
|
|
23250
|
+
for (const [name, slotRead] of reads) {
|
|
23251
|
+
if (!Object.hasOwn(parameterValues, name)) continue;
|
|
23252
|
+
const value = parameterValues[name];
|
|
23253
|
+
for (const [plaintext, survivor] of inheritedSecretsCarriedBy(value, inherited)) {
|
|
23254
|
+
const expression = carriedExpressionFor(inherited, name, value, plaintext, survivor);
|
|
23255
|
+
const rendered = typeof inheritedParameterExpression(inherited, name, plaintext) !== "string" && inheritedRenderedToken(inherited, name, value, plaintext) !== void 0;
|
|
23256
|
+
let byExpression = byPlaintext.get(plaintext);
|
|
23257
|
+
if (byExpression === void 0) {
|
|
23258
|
+
byExpression = /* @__PURE__ */ new Map();
|
|
23259
|
+
byPlaintext.set(plaintext, byExpression);
|
|
23260
|
+
}
|
|
23261
|
+
let renderedNames = byExpression.get(expression);
|
|
23262
|
+
if (renderedNames === void 0) {
|
|
23263
|
+
renderedNames = [];
|
|
23264
|
+
byExpression.set(expression, renderedNames);
|
|
23265
|
+
}
|
|
23266
|
+
if (rendered) renderedNames.push(name);
|
|
23267
|
+
if (slotRead) slotReadPlaintexts.add(plaintext);
|
|
23268
|
+
}
|
|
23269
|
+
}
|
|
23270
|
+
for (const [plaintext, byExpression] of byPlaintext) {
|
|
23271
|
+
if (byExpression.size < 2 || !slotReadPlaintexts.has(plaintext)) continue;
|
|
23272
|
+
for (const renderedNames of byExpression.values()) for (const name of renderedNames) withdraw.add(name);
|
|
23273
|
+
}
|
|
23274
|
+
}
|
|
23275
|
+
return withdraw;
|
|
23276
|
+
}
|
|
23277
|
+
const POSITIONED_INTRINSICS = /* @__PURE__ */ new Set(["Fn::Join", "Fn::Sub"]);
|
|
23278
|
+
function parameterReadsOf(node, names, reread, positionsArrays) {
|
|
23279
|
+
const reads = /* @__PURE__ */ new Map();
|
|
23280
|
+
const add = (name, slotRead) => {
|
|
23281
|
+
reads.set(name, slotRead || reads.get(name) === true);
|
|
23282
|
+
};
|
|
23283
|
+
const visit = (value, slotRead, atLeaf) => {
|
|
23284
|
+
if (Array.isArray(value)) {
|
|
23285
|
+
const mayShrink = atLeaf ? !positionsArrays || !arrayPairsWhateverDrops(value) : value.some((element) => element !== null && typeof element === "object" && !Array.isArray(element) && (Object.hasOwn(element, "Fn::If") || element["Ref"] === "AWS::NoValue"));
|
|
23286
|
+
for (const element of value) visit(element, slotRead || mayShrink, atLeaf && !mayShrink);
|
|
23287
|
+
return;
|
|
23288
|
+
}
|
|
23289
|
+
if (value === null || typeof value !== "object") return;
|
|
23290
|
+
const record = value;
|
|
23291
|
+
const intrinsic = Object.keys(record).some((key) => key === "Ref" || key.startsWith("Fn::"));
|
|
23292
|
+
if (intrinsic && atLeaf && reread !== void 0 && rereadParameterExpression(record, reread.bind, reread.inherited) !== void 0) {
|
|
23293
|
+
for (const name of refNamesIn(record, names)) add(name, false);
|
|
23294
|
+
return;
|
|
23295
|
+
}
|
|
23296
|
+
const ref = record["Ref"];
|
|
23297
|
+
if (typeof ref === "string" && names.has(ref)) add(ref, slotRead);
|
|
23298
|
+
const placeholderSlot = !positionsArrays && unkeyedPlaceholderParts(record, (name) => certifiesPlaceholder(name, reread)) > MAX_UNKEYED_PARTS;
|
|
23299
|
+
const sub = record["Fn::Sub"];
|
|
23300
|
+
const text = typeof sub === "string" ? sub : Array.isArray(sub) ? sub[0] : void 0;
|
|
23301
|
+
if (typeof text === "string") for (const match of text.matchAll(/\$\{([^}!][^}]*)\}/g)) {
|
|
23302
|
+
const name = match[1].trim();
|
|
23303
|
+
if (names.has(name)) add(name, slotRead || placeholderSlot);
|
|
23304
|
+
}
|
|
23305
|
+
for (const [key, child] of Object.entries(record)) visit(child, slotRead || placeholderSlot || key.startsWith("Fn::") && !POSITIONED_INTRINSICS.has(key), atLeaf && !intrinsic);
|
|
23306
|
+
};
|
|
23307
|
+
visit(node, reread === void 0, true);
|
|
23308
|
+
return reads;
|
|
23309
|
+
}
|
|
23310
|
+
const MAX_UNKEYED_PARTS = 1;
|
|
23311
|
+
function certifiesPlaceholder(name, reread) {
|
|
23312
|
+
if (reread === void 0) return false;
|
|
23313
|
+
const bound = reread.bind(name);
|
|
23314
|
+
if (bound === void 0) return false;
|
|
23315
|
+
if (inheritedSecretsCarriedBy(bound.value, reread.inherited).length === 0) return false;
|
|
23316
|
+
return typeof inheritedParameterExpression(reread.inherited, name, bound.value) === "string";
|
|
23317
|
+
}
|
|
23318
|
+
function unkeyedPlaceholderParts(record, certified) {
|
|
23319
|
+
const keyed = (value) => typeof value === "string" || value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 1 && typeof value["Ref"] === "string" && certified(value["Ref"]);
|
|
23320
|
+
if (Object.hasOwn(record, "Fn::Join")) {
|
|
23321
|
+
const args = record["Fn::Join"];
|
|
23322
|
+
if (!Array.isArray(args) || args.length !== 2 || !Array.isArray(args[1])) return Number.POSITIVE_INFINITY;
|
|
23323
|
+
return args[1].filter((part) => !keyed(part)).length;
|
|
23324
|
+
}
|
|
23325
|
+
if (Object.hasOwn(record, "Fn::Sub")) {
|
|
23326
|
+
const args = record["Fn::Sub"];
|
|
23327
|
+
const [template, variables] = typeof args === "string" ? [args, {}] : Array.isArray(args) ? [args[0], args[1]] : [];
|
|
23328
|
+
if (typeof template !== "string" || variables === null || typeof variables !== "object") return Number.POSITIVE_INFINITY;
|
|
23329
|
+
let unkeyed = 0;
|
|
23330
|
+
for (const hit of template.matchAll(/\$\{(!)?([^}]*)\}/g)) {
|
|
23331
|
+
const name = hit[2] ?? "";
|
|
23332
|
+
if (hit[1] === "!" || name === "") continue;
|
|
23333
|
+
if (!(Object.hasOwn(variables, name) ? keyed(variables[name]) : certified(name))) unkeyed += 1;
|
|
23334
|
+
}
|
|
23335
|
+
return unkeyed;
|
|
23336
|
+
}
|
|
23337
|
+
return 0;
|
|
23338
|
+
}
|
|
23339
|
+
function outputsGroupParts(outputs) {
|
|
23340
|
+
if (outputs === null || typeof outputs !== "object" || Array.isArray(outputs)) return [{
|
|
23341
|
+
node: outputs,
|
|
23342
|
+
mode: "slot"
|
|
23343
|
+
}];
|
|
23344
|
+
const parts = [];
|
|
23345
|
+
for (const output of Object.values(outputs)) {
|
|
23346
|
+
if (output === null || typeof output !== "object" || Array.isArray(output)) {
|
|
23347
|
+
parts.push({
|
|
23348
|
+
node: output,
|
|
23349
|
+
mode: "slot"
|
|
23350
|
+
});
|
|
23351
|
+
continue;
|
|
23352
|
+
}
|
|
23353
|
+
const { Value: value, ...rest } = output;
|
|
23354
|
+
parts.push({
|
|
23355
|
+
node: value,
|
|
23356
|
+
mode: "output"
|
|
23357
|
+
}, {
|
|
23358
|
+
node: rest,
|
|
23359
|
+
mode: "slot"
|
|
23360
|
+
});
|
|
23361
|
+
}
|
|
23362
|
+
return parts;
|
|
23363
|
+
}
|
|
23364
|
+
function refNamesIn(node, names) {
|
|
23365
|
+
const found = /* @__PURE__ */ new Set();
|
|
23366
|
+
const visit = (value) => {
|
|
23367
|
+
if (Array.isArray(value)) {
|
|
23368
|
+
for (const element of value) visit(element);
|
|
23369
|
+
return;
|
|
23370
|
+
}
|
|
23371
|
+
if (value === null || typeof value !== "object") return;
|
|
23372
|
+
const record = value;
|
|
23373
|
+
if (typeof record["Ref"] === "string" && names.has(record["Ref"])) found.add(record["Ref"]);
|
|
23374
|
+
const sub = record["Fn::Sub"];
|
|
23375
|
+
const text = typeof sub === "string" ? sub : Array.isArray(sub) ? sub[0] : void 0;
|
|
23376
|
+
if (typeof text === "string") for (const match of text.matchAll(/\$\{([^}!][^}]*)\}/g)) {
|
|
23377
|
+
const name = match[1].trim();
|
|
23378
|
+
if (names.has(name)) found.add(name);
|
|
23379
|
+
}
|
|
23380
|
+
for (const child of Object.values(record)) visit(child);
|
|
23381
|
+
};
|
|
23382
|
+
visit(node);
|
|
23383
|
+
return found;
|
|
23384
|
+
}
|
|
23385
|
+
function recordInheritedNoEchoListElements(resolver, inherited, recorded, value, context) {
|
|
23386
|
+
if (!Array.isArray(value)) return;
|
|
23387
|
+
const parameterValues = [...inherited.keys()].filter((plaintext) => isNoEchoParameterPlaintext(inherited, plaintext));
|
|
23388
|
+
if (parameterValues.length === 0) return;
|
|
23389
|
+
const joined = value.map((element) => String(element)).join(",");
|
|
23390
|
+
const normalized = (plaintext) => plaintext.split(",").map((piece) => piece.trim()).join(",");
|
|
23391
|
+
if (!parameterValues.some((plaintext) => `,${normalized(plaintext)},`.includes(`,${joined},`))) return;
|
|
23392
|
+
for (const element of value) {
|
|
23393
|
+
if (typeof element !== "string" || element.length < 4) continue;
|
|
23394
|
+
recordNoEchoParameterFreshValue(element, recorded, resolver.publicNoEchoTokens(context));
|
|
23395
|
+
}
|
|
23396
|
+
}
|
|
23397
|
+
function recordNoEchoParameterValue(paramDef, value, context) {
|
|
23398
|
+
const bag = context.recordedSecretValues;
|
|
23399
|
+
if (!declaresNoEcho(paramDef) || bag === void 0) return;
|
|
23400
|
+
recordLogOnlyParameterValue(bag, value);
|
|
23401
|
+
recordNoEchoParameterFreshValue(value, bag, this.publicNoEchoTokens(context));
|
|
23402
|
+
}
|
|
23403
|
+
function refuseCoercedInheritedSecret(name, paramDef, userValue, inherited) {
|
|
23404
|
+
if (!inherited || inherited.size === 0) return;
|
|
23405
|
+
const secretPairs = new Map([...inherited].filter(([plaintext]) => !isNoEchoParameterPlaintext(inherited, plaintext)));
|
|
23406
|
+
if (secretPairs.size === 0) return;
|
|
23407
|
+
const carriedBefore = inheritedSecretsCarriedBy(userValue, secretPairs).length;
|
|
23408
|
+
if (carriedBefore === 0) return;
|
|
23409
|
+
if (inheritedSecretsCarriedBy(this.coerceParameterValue(userValue, paramDef.Type), secretPairs).length >= carriedBefore) return;
|
|
23410
|
+
const loggedName = this.displayMasked(name);
|
|
23411
|
+
const loggedType = this.displayMasked(paramDef.Type);
|
|
23412
|
+
throw markNonRetryable(new IntrinsicResolutionRefusalError(`Nested-stack parameter ${quotedRender(loggedName, "'")} is declared ${QUOTABLE_RENDER.test(loggedType) ? `'Type: ${loggedType}'` : "with a Type that is not a plain identifier"}, but the parent stack resolved a SECRET dynamic reference into it. cdkd keeps a resolved secret out of persisted state by rewriting STRING leaves back to their {{resolve:...}} expression; coercing this value to ${quotedRender(loggedType, "'", "that Type")} destroys the plaintext cdkd would have matched on, so the DECRYPTED secret would be left in the child stack's state.json with nothing to redact it back to. Declare ${quotedRender(loggedName, "'", "the parameter")} as 'Type: String' in the nested stack's template (CDK does this by default for cross-stack references), or stop passing a secret reference into it.`, void 0, "NESTED_STACK_SECRET_PARAMETER_TYPE"));
|
|
23413
|
+
}
|
|
23414
|
+
|
|
22928
23415
|
//#endregion
|
|
22929
23416
|
//#region src/deployment/intrinsic-resolver/functions.ts
|
|
22930
23417
|
async function resolveIf(ifArgs, context, source) {
|
|
@@ -22946,11 +23433,13 @@ async function resolveIf(ifArgs, context, source) {
|
|
|
22946
23433
|
};
|
|
22947
23434
|
if (!context.conditions || !Object.hasOwn(context.conditions, conditionName)) {
|
|
22948
23435
|
this.logger.warn(`Condition ${this.displayMasked(String(conditionName), context)} not found in context, assuming false`);
|
|
23436
|
+
recordTakenIfBranchIn(context, source, false);
|
|
22949
23437
|
return await resolveBranch(valueIfFalse);
|
|
22950
23438
|
}
|
|
22951
23439
|
const conditionValue = context.conditions[conditionName];
|
|
22952
23440
|
const selectedValue = conditionValue ? valueIfTrue : valueIfFalse;
|
|
22953
23441
|
this.logger.debug(`Resolved Fn::If: condition ${this.logRender(String(conditionName), context)} = ${conditionValue}, selected ${conditionValue ? "true" : "false"} branch`);
|
|
23442
|
+
recordTakenIfBranchIn(context, source, Boolean(conditionValue));
|
|
22954
23443
|
return await resolveBranch(selectedValue);
|
|
22955
23444
|
}
|
|
22956
23445
|
async function resolveEquals(equalsArgs, context) {
|
|
@@ -23398,6 +23887,7 @@ function displayLeaf(value, context) {
|
|
|
23398
23887
|
//#region src/deployment/intrinsic-resolver/params-conditions.ts
|
|
23399
23888
|
async function resolveParameters(template, userParameters, options) {
|
|
23400
23889
|
const inheritedSecrets = options?.inheritedSecrets;
|
|
23890
|
+
if (inheritedSecrets) await recordInheritedPseudoParameterValues(this, inheritedSecrets);
|
|
23401
23891
|
const maskInherited = (text) => {
|
|
23402
23892
|
const mask = (value) => inheritedSecrets && hasMaskableValues(inheritedSecrets) ? maskSecretsInText(value, inheritedSecrets) : value;
|
|
23403
23893
|
return displaySafe(mask(stripControlChars(mask(text))));
|
|
@@ -23505,256 +23995,6 @@ async function resolveKeyUnit(key, val, context, abandoned) {
|
|
|
23505
23995
|
}
|
|
23506
23996
|
}
|
|
23507
23997
|
|
|
23508
|
-
//#endregion
|
|
23509
|
-
//#region src/deployment/intrinsic-resolver/parameter-secrets.ts
|
|
23510
|
-
function recordInheritedParameterSecrets(parameterName, value, context) {
|
|
23511
|
-
const inherited = context.inheritedSecrets;
|
|
23512
|
-
const recorded = context.recordedSecretValues;
|
|
23513
|
-
if (inherited && recorded) carryLogOnlyValuesCarriedBy(inherited, recorded, value);
|
|
23514
|
-
if (recorded) carryPhysicalNameCopiesCarriedBy(context, recorded, value);
|
|
23515
|
-
if (inherited && recorded) recordInheritedNoEchoListElements(this, inherited, recorded, value, context);
|
|
23516
|
-
if (!inherited || inherited.size === 0 || !recorded) return;
|
|
23517
|
-
const mirror = parameterReadMirrors.get(recorded);
|
|
23518
|
-
const declared = declaredParameterNames(context);
|
|
23519
|
-
recordInheritedParameterValue(recorded, inherited, parameterName, value, declared);
|
|
23520
|
-
if (mirror) recordInheritedParameterValue(mirror, inherited, parameterName, value, declared);
|
|
23521
|
-
for (const [plaintext, expression] of inheritedSecretsCarriedBy(value, inherited)) {
|
|
23522
|
-
const carried = carriedExpressionFor(inherited, parameterName, value, plaintext, expression);
|
|
23523
|
-
recorded.set(plaintext, carried);
|
|
23524
|
-
const parentEntry = context.inheritedReferenceProvenance?.get(carried);
|
|
23525
|
-
if (parentEntry !== void 0) recordReferenceProvenanceEntry(recorded, carried, parentEntry, "read");
|
|
23526
|
-
recordInheritedParameterRead(recorded, inherited, parameterName);
|
|
23527
|
-
if (mirror) recordInheritedParameterRead(mirror, inherited, parameterName);
|
|
23528
|
-
carryFreshNoEchoMark(inherited, recorded, plaintext);
|
|
23529
|
-
}
|
|
23530
|
-
}
|
|
23531
|
-
function declaredParameterNames(context) {
|
|
23532
|
-
const declared = context.template?.Parameters;
|
|
23533
|
-
if (declared === null || typeof declared !== "object") return void 0;
|
|
23534
|
-
let names = declaredNamesCache.get(declared);
|
|
23535
|
-
if (names === void 0) {
|
|
23536
|
-
names = new Set(Object.keys(declared));
|
|
23537
|
-
declaredNamesCache.set(declared, names);
|
|
23538
|
-
}
|
|
23539
|
-
return names;
|
|
23540
|
-
}
|
|
23541
|
-
const declaredNamesCache = /* @__PURE__ */ new WeakMap();
|
|
23542
|
-
const parameterReadMirrors = /* @__PURE__ */ new WeakMap();
|
|
23543
|
-
function mirrorInheritedParameterReads(passSecrets, persistSecrets) {
|
|
23544
|
-
if (passSecrets !== persistSecrets) parameterReadMirrors.set(passSecrets, persistSecrets);
|
|
23545
|
-
}
|
|
23546
|
-
function carryPhysicalNameCopiesCarriedBy(context, recorded, value) {
|
|
23547
|
-
const names = context.inheritedPhysicalNameCopies ?? (context.inheritedSecrets && physicalNameCopiesOf.get(context.inheritedSecrets));
|
|
23548
|
-
if (names === void 0 || names.size === 0) return;
|
|
23549
|
-
const leaves = [...wholeStringLeavesOf(value)];
|
|
23550
|
-
for (const name of names) if (leaves.some((leaf) => leaf.includes(name))) recordPhysicalNameCopy(recorded, name);
|
|
23551
|
-
}
|
|
23552
|
-
function carriedExpressionFor(inherited, parameterName, value, plaintext, survivor) {
|
|
23553
|
-
const own = inheritedParameterExpression(inherited, parameterName, plaintext);
|
|
23554
|
-
if (typeof own === "string") return own;
|
|
23555
|
-
return inheritedRenderedToken(inherited, parameterName, value, plaintext) ?? survivor;
|
|
23556
|
-
}
|
|
23557
|
-
function poisonRenderedSpellingsCollidingIn(template, parameterValues, inherited) {
|
|
23558
|
-
if (!inherited || inherited.size === 0 || template === void 0) return;
|
|
23559
|
-
const names = new Set(Object.keys(parameterValues));
|
|
23560
|
-
if (names.size < 2) return;
|
|
23561
|
-
const groups = [];
|
|
23562
|
-
if (template.Resources !== null && typeof template.Resources === "object") for (const resource of Object.values(template.Resources)) groups.push([{
|
|
23563
|
-
node: resource,
|
|
23564
|
-
mode: "resource"
|
|
23565
|
-
}]);
|
|
23566
|
-
if (template.Outputs !== void 0) groups.push(outputsGroupParts(template.Outputs));
|
|
23567
|
-
const bind = (name) => Object.hasOwn(parameterValues, name) ? { value: parameterValues[name] } : void 0;
|
|
23568
|
-
const withdrawn = /* @__PURE__ */ new Set();
|
|
23569
|
-
for (;;) {
|
|
23570
|
-
const fresh = [...collidingRenderedNames(groups.map((parts) => {
|
|
23571
|
-
const reads = /* @__PURE__ */ new Map();
|
|
23572
|
-
for (const { node, mode } of parts) {
|
|
23573
|
-
const reread = mode === "slot" ? void 0 : {
|
|
23574
|
-
bind,
|
|
23575
|
-
inherited
|
|
23576
|
-
};
|
|
23577
|
-
for (const [name, slotRead] of parameterReadsOf(node, names, reread, mode !== "output")) reads.set(name, slotRead || reads.get(name) === true);
|
|
23578
|
-
}
|
|
23579
|
-
return reads;
|
|
23580
|
-
}).filter((reads) => reads.size >= 2), parameterValues, inherited)].filter((name) => !withdrawn.has(name));
|
|
23581
|
-
if (fresh.length === 0) return;
|
|
23582
|
-
for (const name of fresh) {
|
|
23583
|
-
withdrawn.add(name);
|
|
23584
|
-
withdrawRenderedParameterSpelling(inherited, name);
|
|
23585
|
-
}
|
|
23586
|
-
}
|
|
23587
|
-
}
|
|
23588
|
-
function collidingRenderedNames(readsByGroup, parameterValues, inherited) {
|
|
23589
|
-
const withdraw = /* @__PURE__ */ new Set();
|
|
23590
|
-
for (const reads of readsByGroup) {
|
|
23591
|
-
const byPlaintext = /* @__PURE__ */ new Map();
|
|
23592
|
-
const slotReadPlaintexts = /* @__PURE__ */ new Set();
|
|
23593
|
-
for (const [name, slotRead] of reads) {
|
|
23594
|
-
if (!Object.hasOwn(parameterValues, name)) continue;
|
|
23595
|
-
const value = parameterValues[name];
|
|
23596
|
-
for (const [plaintext, survivor] of inheritedSecretsCarriedBy(value, inherited)) {
|
|
23597
|
-
const expression = carriedExpressionFor(inherited, name, value, plaintext, survivor);
|
|
23598
|
-
const rendered = typeof inheritedParameterExpression(inherited, name, plaintext) !== "string" && inheritedRenderedToken(inherited, name, value, plaintext) !== void 0;
|
|
23599
|
-
let byExpression = byPlaintext.get(plaintext);
|
|
23600
|
-
if (byExpression === void 0) {
|
|
23601
|
-
byExpression = /* @__PURE__ */ new Map();
|
|
23602
|
-
byPlaintext.set(plaintext, byExpression);
|
|
23603
|
-
}
|
|
23604
|
-
let renderedNames = byExpression.get(expression);
|
|
23605
|
-
if (renderedNames === void 0) {
|
|
23606
|
-
renderedNames = [];
|
|
23607
|
-
byExpression.set(expression, renderedNames);
|
|
23608
|
-
}
|
|
23609
|
-
if (rendered) renderedNames.push(name);
|
|
23610
|
-
if (slotRead) slotReadPlaintexts.add(plaintext);
|
|
23611
|
-
}
|
|
23612
|
-
}
|
|
23613
|
-
for (const [plaintext, byExpression] of byPlaintext) {
|
|
23614
|
-
if (byExpression.size < 2 || !slotReadPlaintexts.has(plaintext)) continue;
|
|
23615
|
-
for (const renderedNames of byExpression.values()) for (const name of renderedNames) withdraw.add(name);
|
|
23616
|
-
}
|
|
23617
|
-
}
|
|
23618
|
-
return withdraw;
|
|
23619
|
-
}
|
|
23620
|
-
const POSITIONED_INTRINSICS = /* @__PURE__ */ new Set(["Fn::Join", "Fn::Sub"]);
|
|
23621
|
-
function parameterReadsOf(node, names, reread, positionsArrays) {
|
|
23622
|
-
const reads = /* @__PURE__ */ new Map();
|
|
23623
|
-
const add = (name, slotRead) => {
|
|
23624
|
-
reads.set(name, slotRead || reads.get(name) === true);
|
|
23625
|
-
};
|
|
23626
|
-
const visit = (value, slotRead, atLeaf) => {
|
|
23627
|
-
if (Array.isArray(value)) {
|
|
23628
|
-
const mayShrink = atLeaf ? !positionsArrays || !arrayPairsWhateverDrops(value) : value.some((element) => element !== null && typeof element === "object" && !Array.isArray(element) && (Object.hasOwn(element, "Fn::If") || element["Ref"] === "AWS::NoValue"));
|
|
23629
|
-
for (const element of value) visit(element, slotRead || mayShrink, atLeaf && !mayShrink);
|
|
23630
|
-
return;
|
|
23631
|
-
}
|
|
23632
|
-
if (value === null || typeof value !== "object") return;
|
|
23633
|
-
const record = value;
|
|
23634
|
-
const intrinsic = Object.keys(record).some((key) => key === "Ref" || key.startsWith("Fn::"));
|
|
23635
|
-
if (intrinsic && atLeaf && reread !== void 0 && rereadParameterExpression(record, reread.bind, reread.inherited) !== void 0) {
|
|
23636
|
-
for (const name of refNamesIn(record, names)) add(name, false);
|
|
23637
|
-
return;
|
|
23638
|
-
}
|
|
23639
|
-
const ref = record["Ref"];
|
|
23640
|
-
if (typeof ref === "string" && names.has(ref)) add(ref, slotRead);
|
|
23641
|
-
const placeholderSlot = !positionsArrays && unkeyedPlaceholderParts(record, (name) => certifiesPlaceholder(name, reread)) > MAX_UNKEYED_PARTS;
|
|
23642
|
-
const sub = record["Fn::Sub"];
|
|
23643
|
-
const text = typeof sub === "string" ? sub : Array.isArray(sub) ? sub[0] : void 0;
|
|
23644
|
-
if (typeof text === "string") for (const match of text.matchAll(/\$\{([^}!][^}]*)\}/g)) {
|
|
23645
|
-
const name = match[1].trim();
|
|
23646
|
-
if (names.has(name)) add(name, slotRead || placeholderSlot);
|
|
23647
|
-
}
|
|
23648
|
-
for (const [key, child] of Object.entries(record)) visit(child, slotRead || placeholderSlot || key.startsWith("Fn::") && !POSITIONED_INTRINSICS.has(key), atLeaf && !intrinsic);
|
|
23649
|
-
};
|
|
23650
|
-
visit(node, reread === void 0, true);
|
|
23651
|
-
return reads;
|
|
23652
|
-
}
|
|
23653
|
-
const MAX_UNKEYED_PARTS = 1;
|
|
23654
|
-
function certifiesPlaceholder(name, reread) {
|
|
23655
|
-
if (reread === void 0) return false;
|
|
23656
|
-
const bound = reread.bind(name);
|
|
23657
|
-
if (bound === void 0) return false;
|
|
23658
|
-
if (inheritedSecretsCarriedBy(bound.value, reread.inherited).length === 0) return false;
|
|
23659
|
-
return typeof inheritedParameterExpression(reread.inherited, name, bound.value) === "string";
|
|
23660
|
-
}
|
|
23661
|
-
function unkeyedPlaceholderParts(record, certified) {
|
|
23662
|
-
const keyed = (value) => typeof value === "string" || value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 1 && typeof value["Ref"] === "string" && certified(value["Ref"]);
|
|
23663
|
-
if (Object.hasOwn(record, "Fn::Join")) {
|
|
23664
|
-
const args = record["Fn::Join"];
|
|
23665
|
-
if (!Array.isArray(args) || args.length !== 2 || !Array.isArray(args[1])) return Number.POSITIVE_INFINITY;
|
|
23666
|
-
return args[1].filter((part) => !keyed(part)).length;
|
|
23667
|
-
}
|
|
23668
|
-
if (Object.hasOwn(record, "Fn::Sub")) {
|
|
23669
|
-
const args = record["Fn::Sub"];
|
|
23670
|
-
const [template, variables] = typeof args === "string" ? [args, {}] : Array.isArray(args) ? [args[0], args[1]] : [];
|
|
23671
|
-
if (typeof template !== "string" || variables === null || typeof variables !== "object") return Number.POSITIVE_INFINITY;
|
|
23672
|
-
let unkeyed = 0;
|
|
23673
|
-
for (const hit of template.matchAll(/\$\{(!)?([^}]*)\}/g)) {
|
|
23674
|
-
const name = hit[2] ?? "";
|
|
23675
|
-
if (hit[1] === "!" || name === "") continue;
|
|
23676
|
-
if (!(Object.hasOwn(variables, name) ? keyed(variables[name]) : certified(name))) unkeyed += 1;
|
|
23677
|
-
}
|
|
23678
|
-
return unkeyed;
|
|
23679
|
-
}
|
|
23680
|
-
return 0;
|
|
23681
|
-
}
|
|
23682
|
-
function outputsGroupParts(outputs) {
|
|
23683
|
-
if (outputs === null || typeof outputs !== "object" || Array.isArray(outputs)) return [{
|
|
23684
|
-
node: outputs,
|
|
23685
|
-
mode: "slot"
|
|
23686
|
-
}];
|
|
23687
|
-
const parts = [];
|
|
23688
|
-
for (const output of Object.values(outputs)) {
|
|
23689
|
-
if (output === null || typeof output !== "object" || Array.isArray(output)) {
|
|
23690
|
-
parts.push({
|
|
23691
|
-
node: output,
|
|
23692
|
-
mode: "slot"
|
|
23693
|
-
});
|
|
23694
|
-
continue;
|
|
23695
|
-
}
|
|
23696
|
-
const { Value: value, ...rest } = output;
|
|
23697
|
-
parts.push({
|
|
23698
|
-
node: value,
|
|
23699
|
-
mode: "output"
|
|
23700
|
-
}, {
|
|
23701
|
-
node: rest,
|
|
23702
|
-
mode: "slot"
|
|
23703
|
-
});
|
|
23704
|
-
}
|
|
23705
|
-
return parts;
|
|
23706
|
-
}
|
|
23707
|
-
function refNamesIn(node, names) {
|
|
23708
|
-
const found = /* @__PURE__ */ new Set();
|
|
23709
|
-
const visit = (value) => {
|
|
23710
|
-
if (Array.isArray(value)) {
|
|
23711
|
-
for (const element of value) visit(element);
|
|
23712
|
-
return;
|
|
23713
|
-
}
|
|
23714
|
-
if (value === null || typeof value !== "object") return;
|
|
23715
|
-
const record = value;
|
|
23716
|
-
if (typeof record["Ref"] === "string" && names.has(record["Ref"])) found.add(record["Ref"]);
|
|
23717
|
-
const sub = record["Fn::Sub"];
|
|
23718
|
-
const text = typeof sub === "string" ? sub : Array.isArray(sub) ? sub[0] : void 0;
|
|
23719
|
-
if (typeof text === "string") for (const match of text.matchAll(/\$\{([^}!][^}]*)\}/g)) {
|
|
23720
|
-
const name = match[1].trim();
|
|
23721
|
-
if (names.has(name)) found.add(name);
|
|
23722
|
-
}
|
|
23723
|
-
for (const child of Object.values(record)) visit(child);
|
|
23724
|
-
};
|
|
23725
|
-
visit(node);
|
|
23726
|
-
return found;
|
|
23727
|
-
}
|
|
23728
|
-
function recordInheritedNoEchoListElements(resolver, inherited, recorded, value, context) {
|
|
23729
|
-
if (!Array.isArray(value)) return;
|
|
23730
|
-
const parameterValues = [...inherited.keys()].filter((plaintext) => isNoEchoParameterPlaintext(inherited, plaintext));
|
|
23731
|
-
if (parameterValues.length === 0) return;
|
|
23732
|
-
const joined = value.map((element) => String(element)).join(",");
|
|
23733
|
-
const normalized = (plaintext) => plaintext.split(",").map((piece) => piece.trim()).join(",");
|
|
23734
|
-
if (!parameterValues.some((plaintext) => `,${normalized(plaintext)},`.includes(`,${joined},`))) return;
|
|
23735
|
-
for (const element of value) {
|
|
23736
|
-
if (typeof element !== "string" || element.length < 4) continue;
|
|
23737
|
-
recordNoEchoParameterFreshValue(element, recorded, resolver.publicNoEchoTokens(context));
|
|
23738
|
-
}
|
|
23739
|
-
}
|
|
23740
|
-
function recordNoEchoParameterValue(paramDef, value, context) {
|
|
23741
|
-
const bag = context.recordedSecretValues;
|
|
23742
|
-
if (!declaresNoEcho(paramDef) || bag === void 0) return;
|
|
23743
|
-
recordLogOnlyParameterValue(bag, value);
|
|
23744
|
-
recordNoEchoParameterFreshValue(value, bag, this.publicNoEchoTokens(context));
|
|
23745
|
-
}
|
|
23746
|
-
function refuseCoercedInheritedSecret(name, paramDef, userValue, inherited) {
|
|
23747
|
-
if (!inherited || inherited.size === 0) return;
|
|
23748
|
-
const secretPairs = new Map([...inherited].filter(([plaintext]) => !isNoEchoParameterPlaintext(inherited, plaintext)));
|
|
23749
|
-
if (secretPairs.size === 0) return;
|
|
23750
|
-
const carriedBefore = inheritedSecretsCarriedBy(userValue, secretPairs).length;
|
|
23751
|
-
if (carriedBefore === 0) return;
|
|
23752
|
-
if (inheritedSecretsCarriedBy(this.coerceParameterValue(userValue, paramDef.Type), secretPairs).length >= carriedBefore) return;
|
|
23753
|
-
const loggedName = this.displayMasked(name);
|
|
23754
|
-
const loggedType = this.displayMasked(paramDef.Type);
|
|
23755
|
-
throw markNonRetryable(new IntrinsicResolutionRefusalError(`Nested-stack parameter ${quotedRender(loggedName, "'")} is declared ${QUOTABLE_RENDER.test(loggedType) ? `'Type: ${loggedType}'` : "with a Type that is not a plain identifier"}, but the parent stack resolved a SECRET dynamic reference into it. cdkd keeps a resolved secret out of persisted state by rewriting STRING leaves back to their {{resolve:...}} expression; coercing this value to ${quotedRender(loggedType, "'", "that Type")} destroys the plaintext cdkd would have matched on, so the DECRYPTED secret would be left in the child stack's state.json with nothing to redact it back to. Declare ${quotedRender(loggedName, "'", "the parameter")} as 'Type: String' in the nested stack's template (CDK does this by default for cross-stack references), or stop passing a secret reference into it.`, void 0, "NESTED_STACK_SECRET_PARAMETER_TYPE"));
|
|
23756
|
-
}
|
|
23757
|
-
|
|
23758
23998
|
//#endregion
|
|
23759
23999
|
//#region src/deployment/intrinsic-resolver/refs.ts
|
|
23760
24000
|
function nameIsNeverAResource(logicalId, context) {
|
|
@@ -23931,7 +24171,18 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
23931
24171
|
if (typeof value === "string" && value.includes("{{resolve:")) return await this.resolveTemplateLeafReferences(value, context);
|
|
23932
24172
|
return value;
|
|
23933
24173
|
}
|
|
23934
|
-
if (Array.isArray(value))
|
|
24174
|
+
if (Array.isArray(value)) {
|
|
24175
|
+
const resolved = await allSettledKeepingFirstRejection(() => value.map((v) => this.resolveValue(v, context)), (pending) => this.warnAbandonedParts(pending));
|
|
24176
|
+
const kept = resolved.filter((v) => v !== AWS_NO_VALUE);
|
|
24177
|
+
if (kept.length !== resolved.length) {
|
|
24178
|
+
const dropped = [];
|
|
24179
|
+
resolved.forEach((v, i) => {
|
|
24180
|
+
if (v === AWS_NO_VALUE) dropped.push(i);
|
|
24181
|
+
});
|
|
24182
|
+
recordDroppedArrayElementsIn(context, value, dropped);
|
|
24183
|
+
}
|
|
24184
|
+
return kept;
|
|
24185
|
+
}
|
|
23935
24186
|
const obj = value;
|
|
23936
24187
|
if ("Ref" in obj) {
|
|
23937
24188
|
const logicalId = obj["Ref"];
|
|
@@ -24919,8 +25170,9 @@ function ec2InstanceProtectionSite(instanceId, region) {
|
|
|
24919
25170
|
//#endregion
|
|
24920
25171
|
//#region src/provisioning/wait-abandoned.ts
|
|
24921
25172
|
const WAIT_ABANDONED_MARKER = Symbol.for("cdkd.waitAbandoned");
|
|
25173
|
+
const ABANDONED_REQUEST = Symbol.for("cdkd.waitAbandoned.request");
|
|
24922
25174
|
const MAX_CAUSE_CHAIN_DEPTH = 5;
|
|
24923
|
-
function markWaitAbandoned(error) {
|
|
25175
|
+
function markWaitAbandoned(error, request) {
|
|
24924
25176
|
if (!Object.isExtensible(error)) return error;
|
|
24925
25177
|
Object.defineProperty(error, WAIT_ABANDONED_MARKER, {
|
|
24926
25178
|
value: true,
|
|
@@ -24928,6 +25180,12 @@ function markWaitAbandoned(error) {
|
|
|
24928
25180
|
configurable: true,
|
|
24929
25181
|
writable: false
|
|
24930
25182
|
});
|
|
25183
|
+
if (request !== void 0) Object.defineProperty(error, ABANDONED_REQUEST, {
|
|
25184
|
+
value: Object.freeze({ ...request }),
|
|
25185
|
+
enumerable: false,
|
|
25186
|
+
configurable: true,
|
|
25187
|
+
writable: false
|
|
25188
|
+
});
|
|
24931
25189
|
return error;
|
|
24932
25190
|
}
|
|
24933
25191
|
function isWaitAbandonedError(error) {
|
|
@@ -24938,6 +25196,14 @@ function isWaitAbandonedError(error) {
|
|
|
24938
25196
|
}
|
|
24939
25197
|
return false;
|
|
24940
25198
|
}
|
|
25199
|
+
function abandonedRequestOf(error) {
|
|
25200
|
+
let current = error;
|
|
25201
|
+
for (let depth = 0; depth < MAX_CAUSE_CHAIN_DEPTH && current != null; depth++) {
|
|
25202
|
+
const request = current[ABANDONED_REQUEST];
|
|
25203
|
+
if (request !== void 0) return request;
|
|
25204
|
+
current = current.cause;
|
|
25205
|
+
}
|
|
25206
|
+
}
|
|
24941
25207
|
|
|
24942
25208
|
//#endregion
|
|
24943
25209
|
//#region src/provisioning/ec2-volume-delete.ts
|
|
@@ -26195,9 +26461,18 @@ var CloudControlWaitAbandonedError = class CloudControlWaitAbandonedError extend
|
|
|
26195
26461
|
this.lastSeenIdentifier = lastSeenIdentifier;
|
|
26196
26462
|
this.name = "CloudControlWaitAbandonedError";
|
|
26197
26463
|
Object.setPrototypeOf(this, CloudControlWaitAbandonedError.prototype);
|
|
26198
|
-
markWaitAbandoned(this
|
|
26464
|
+
markWaitAbandoned(this, {
|
|
26465
|
+
requestToken,
|
|
26466
|
+
operation: ccOperation
|
|
26467
|
+
});
|
|
26199
26468
|
}
|
|
26200
26469
|
};
|
|
26470
|
+
function failedOutcome$1(errorCode, identifier) {
|
|
26471
|
+
return identifier && errorCode !== "AlreadyExists" && errorCode !== "ResourceConflict" ? {
|
|
26472
|
+
status: "failed",
|
|
26473
|
+
remnant: identifier
|
|
26474
|
+
} : { status: "failed" };
|
|
26475
|
+
}
|
|
26201
26476
|
const POLL_TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
26202
26477
|
"ECONNRESET",
|
|
26203
26478
|
"ECONNREFUSED",
|
|
@@ -26525,7 +26800,7 @@ var CloudControlProvider = class {
|
|
|
26525
26800
|
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
26526
26801
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
26527
26802
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
26528
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
26803
|
+
const { ASGProvider } = await import("./asg-provider-CK2nZE6B.js");
|
|
26529
26804
|
const delegateRegion = ambientRegion();
|
|
26530
26805
|
let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
|
|
26531
26806
|
if (asgProvider === void 0) {
|
|
@@ -26631,7 +26906,7 @@ var CloudControlProvider = class {
|
|
|
26631
26906
|
const family = SDK_DELETE_FAMILIES.get(resourceType);
|
|
26632
26907
|
const cached = this.sdkDeleteDelegates.get(family);
|
|
26633
26908
|
if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
|
|
26634
|
-
const provider = family === "rds" ? new (await (import("./rds-provider-
|
|
26909
|
+
const provider = family === "rds" ? new (await (import("./rds-provider-BfwQbYRR.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-BWESr5fm.js"))).NeptuneProvider({ region: ccRegion });
|
|
26635
26910
|
this.sdkDeleteDelegates.set(family, {
|
|
26636
26911
|
region: ccRegion,
|
|
26637
26912
|
provider
|
|
@@ -26839,9 +27114,10 @@ var CloudControlProvider = class {
|
|
|
26839
27114
|
const failureMessage = progressEvent.StatusMessage || "Unknown error";
|
|
26840
27115
|
throw new CloudControlOperationFailedError(`${operation} failed for ${logicalId}: ${failureMessage}${handlerAuthFailureHint(failureMessage)}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier, progressEvent.ErrorCode, operation);
|
|
26841
27116
|
}
|
|
26842
|
-
case "CANCEL_COMPLETE": throw new ProvisioningError(`${operation} cancelled for ${logicalId}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier);
|
|
27117
|
+
case "CANCEL_COMPLETE": throw Object.assign(new ProvisioningError(`${operation} cancelled for ${logicalId}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier), { ccOperationCancelled: true });
|
|
26843
27118
|
case "IN_PROGRESS":
|
|
26844
27119
|
case "PENDING":
|
|
27120
|
+
case "CANCEL_IN_PROGRESS":
|
|
26845
27121
|
await this.sleep(pollInterval);
|
|
26846
27122
|
pollInterval = Math.min(Math.ceil(pollInterval * 1.5), this.MAX_POLL_INTERVAL_MS);
|
|
26847
27123
|
break;
|
|
@@ -26853,13 +27129,90 @@ var CloudControlProvider = class {
|
|
|
26853
27129
|
}
|
|
26854
27130
|
throw await this.abandonWait(requestToken, logicalId, operation, resourceType, lastSeenIdentifier, `${operation} timeout for ${logicalId} after ${maxWaitMs / 1e3}s`, lastTransientError);
|
|
26855
27131
|
}
|
|
27132
|
+
async resumeCreatedResource(logicalId, resourceType, identifier, properties, context) {
|
|
27133
|
+
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
27134
|
+
const attributeNamesLookup = getTopLevelDeployAttributeNames(resourceType);
|
|
27135
|
+
let raw;
|
|
27136
|
+
try {
|
|
27137
|
+
raw = (await this.cloudControlClient.send(new GetResourceCommand({
|
|
27138
|
+
TypeName: resourceType,
|
|
27139
|
+
Identifier: identifier
|
|
27140
|
+
}))).ResourceDescription?.Properties;
|
|
27141
|
+
} catch (error) {
|
|
27142
|
+
if (error.name === "ResourceNotFoundException") throw Object.assign(new ProvisioningError(`${logicalId}'s resource that an earlier CREATE made no longer exists`, resourceType, logicalId, identifier, error instanceof Error ? error : void 0), { resumedResourceGone: true });
|
|
27143
|
+
throw error;
|
|
27144
|
+
}
|
|
27145
|
+
const model = typeof raw === "string" && raw !== "" ? this.parseResourceModel(raw) : {};
|
|
27146
|
+
const modelKeys = Object.keys(model);
|
|
27147
|
+
const enriched = await this.enrichResourceAttributes(resourceType, identifier, model);
|
|
27148
|
+
return {
|
|
27149
|
+
physicalId: identifier,
|
|
27150
|
+
attributes: await this.maskDeployedNonAttributeKeys(enriched, modelKeys, resourceType, identifier, attributeNamesLookup, properties, mask)
|
|
27151
|
+
};
|
|
27152
|
+
}
|
|
27153
|
+
async resumeAbandonedRequest(requestToken, logicalId, resourceType) {
|
|
27154
|
+
let first;
|
|
27155
|
+
try {
|
|
27156
|
+
first = await this.cloudControlClient.send(new GetResourceRequestStatusCommand({ RequestToken: requestToken }));
|
|
27157
|
+
} catch (error) {
|
|
27158
|
+
if (error.name === "RequestTokenNotFoundException") return { status: "not-found" };
|
|
27159
|
+
return {
|
|
27160
|
+
status: "unresolved",
|
|
27161
|
+
error
|
|
27162
|
+
};
|
|
27163
|
+
}
|
|
27164
|
+
let event = first.ProgressEvent;
|
|
27165
|
+
if (event?.TypeName !== void 0 && event.TypeName !== resourceType || event?.Operation !== void 0 && event.Operation !== "CREATE") return {
|
|
27166
|
+
status: "unresolved",
|
|
27167
|
+
error: /* @__PURE__ */ new Error("the request is not a CREATE of the type the journal records")
|
|
27168
|
+
};
|
|
27169
|
+
if (event !== void 0 && ![
|
|
27170
|
+
"SUCCESS",
|
|
27171
|
+
"FAILED",
|
|
27172
|
+
"CANCEL_COMPLETE"
|
|
27173
|
+
].includes(String(event.OperationStatus))) try {
|
|
27174
|
+
event = await this.waitForOperation(requestToken, logicalId, "CREATE", resourceType);
|
|
27175
|
+
} catch (error) {
|
|
27176
|
+
if (error instanceof CloudControlOperationFailedError) return failedOutcome$1(error.ccErrorCode, error.physicalId);
|
|
27177
|
+
if (error.ccOperationCancelled === true) {
|
|
27178
|
+
const made = error.physicalId;
|
|
27179
|
+
return made ? {
|
|
27180
|
+
status: "cancelled",
|
|
27181
|
+
remnant: made
|
|
27182
|
+
} : { status: "cancelled" };
|
|
27183
|
+
}
|
|
27184
|
+
if (isInterruptedWaitError(error)) throw error;
|
|
27185
|
+
return {
|
|
27186
|
+
status: "unresolved",
|
|
27187
|
+
error
|
|
27188
|
+
};
|
|
27189
|
+
}
|
|
27190
|
+
switch (event?.OperationStatus) {
|
|
27191
|
+
case "SUCCESS": return event.Identifier ? {
|
|
27192
|
+
status: "succeeded",
|
|
27193
|
+
identifier: event.Identifier
|
|
27194
|
+
} : {
|
|
27195
|
+
status: "unresolved",
|
|
27196
|
+
error: /* @__PURE__ */ new Error("the SUCCESS event named no Identifier")
|
|
27197
|
+
};
|
|
27198
|
+
case "FAILED": return failedOutcome$1(event.ErrorCode, event.Identifier);
|
|
27199
|
+
case "CANCEL_COMPLETE": return event.Identifier ? {
|
|
27200
|
+
status: "cancelled",
|
|
27201
|
+
remnant: event.Identifier
|
|
27202
|
+
} : { status: "cancelled" };
|
|
27203
|
+
default: return {
|
|
27204
|
+
status: "unresolved",
|
|
27205
|
+
error: /* @__PURE__ */ new Error(`unexpected operation status ${String(event?.OperationStatus)}`)
|
|
27206
|
+
};
|
|
27207
|
+
}
|
|
27208
|
+
}
|
|
26856
27209
|
async abandonWait(requestToken, logicalId, operation, resourceType, lastSeenIdentifier, reason, cause) {
|
|
26857
27210
|
const described = describePollFailure(cause);
|
|
26858
27211
|
const safeDisplay = displaySafe(described.display);
|
|
26859
27212
|
const causeText = safeDisplay === "" ? "" : `: ${safeDisplay}`;
|
|
26860
27213
|
if (described.detail !== "") this.logger.debug(`${operation} ${logicalId}: the abandoned operation's underlying failure was: ${displaySafe(described.detail)}`);
|
|
26861
27214
|
const identifierClause = lastSeenIdentifier === void 0 ? "" : ` The last status cdkd read named the resource ${displaySafe(lastSeenIdentifier, { asciiOnly: true })}.`;
|
|
26862
|
-
const consequence = operation === "CREATE" ? "cdkd has NO state record for it
|
|
27215
|
+
const consequence = operation === "CREATE" ? "cdkd has NO state record for it: when the failed deploy records the request in the stack's rollback journal, the next cdkd deploy, destroy or rollback checks how it ended, and otherwise any resource it creates is untracked" : operation === "DELETE" ? "the resource may or may not have been removed; its state record is kept so a re-run can finish the delete" : "its state record still holds the PREVIOUS properties, so the record may no longer describe the live resource";
|
|
26863
27216
|
const error = new CloudControlWaitAbandonedError(safeMsg`${operation} of ${logicalId} was accepted by Cloud Control API, but cdkd stopped waiting for it ` + safeMsg`(${reason}${causeText}). The operation may still be running in AWS, and ${consequence}.` + `${identifierClause} Check what it did with:\n ${await this.buildResumeCommand(requestToken)}`, resourceType, logicalId, requestToken, operation, lastSeenIdentifier, cause instanceof Error ? cause : void 0);
|
|
26864
27217
|
if (described.marker) markRedactedCause(error);
|
|
26865
27218
|
return operation === "CREATE" ? markNonRetryable(error) : error;
|
|
@@ -33266,343 +33619,95 @@ function seedOnlyAliasRefusal(seed) {
|
|
|
33266
33619
|
}
|
|
33267
33620
|
|
|
33268
33621
|
//#endregion
|
|
33269
|
-
//#region src/
|
|
33270
|
-
const
|
|
33271
|
-
|
|
33272
|
-
|
|
33273
|
-
|
|
33274
|
-
|
|
33275
|
-
|
|
33276
|
-
|
|
33277
|
-
|
|
33278
|
-
|
|
33279
|
-
|
|
33280
|
-
|
|
33622
|
+
//#region src/deployment/rollback-executor/orphan-identity.ts
|
|
33623
|
+
const UNIQUE_PHYSICAL_ID_TYPES = /* @__PURE__ */ new Set([
|
|
33624
|
+
"AWS::EC2::VPC",
|
|
33625
|
+
"AWS::EC2::Subnet",
|
|
33626
|
+
"AWS::EC2::EIP",
|
|
33627
|
+
"AWS::EC2::NatGateway",
|
|
33628
|
+
"AWS::EC2::SecurityGroup",
|
|
33629
|
+
"AWS::EC2::Instance",
|
|
33630
|
+
"AWS::EFS::FileSystem",
|
|
33631
|
+
"AWS::EFS::MountTarget",
|
|
33632
|
+
"AWS::FSx::FileSystem",
|
|
33633
|
+
"AWS::KMS::Key",
|
|
33634
|
+
"AWS::CertificateManager::Certificate",
|
|
33635
|
+
"AWS::ElasticLoadBalancingV2::LoadBalancer",
|
|
33636
|
+
"AWS::ElasticLoadBalancingV2::TargetGroup",
|
|
33637
|
+
"AWS::ElasticLoadBalancingV2::Listener",
|
|
33638
|
+
"AWS::EMR::Cluster",
|
|
33639
|
+
"AWS::EMR::InstanceGroupConfig",
|
|
33640
|
+
"AWS::EMR::InstanceFleetConfig",
|
|
33641
|
+
"AWS::Cognito::UserPool",
|
|
33642
|
+
"AWS::Route53::HostedZone",
|
|
33643
|
+
"AWS::ServiceDiscovery::PrivateDnsNamespace",
|
|
33644
|
+
"AWS::ServiceDiscovery::PublicDnsNamespace",
|
|
33645
|
+
"AWS::ServiceDiscovery::HttpNamespace",
|
|
33646
|
+
"AWS::ServiceDiscovery::Service",
|
|
33647
|
+
"AWS::AppSync::GraphQLApi",
|
|
33648
|
+
"AWS::IAM::AccessKey",
|
|
33649
|
+
"AWS::Kinesis::StreamConsumer"
|
|
33650
|
+
]);
|
|
33651
|
+
const CONTENT_COMPARED_DELETE_TYPES = /* @__PURE__ */ new Set(["AWS::SQS::QueuePolicy", "AWS::SNS::TopicPolicy"]);
|
|
33652
|
+
const CDKD_NAMESPACE_ID_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::Stack"]);
|
|
33653
|
+
function orphanDeleteNeedsIdentity(resourceType) {
|
|
33654
|
+
return !UNIQUE_PHYSICAL_ID_TYPES.has(resourceType) && !CONTENT_COMPARED_DELETE_TYPES.has(resourceType) && !CDKD_NAMESPACE_ID_TYPES.has(resourceType);
|
|
33281
33655
|
}
|
|
33282
|
-
function
|
|
33283
|
-
return
|
|
33656
|
+
function orphanNeedsIdentity(op) {
|
|
33657
|
+
if (op.provisionedBy === "cc-api") return op.createdIdentifierUnique !== true;
|
|
33658
|
+
return orphanDeleteNeedsIdentity(op.resourceType);
|
|
33284
33659
|
}
|
|
33285
|
-
const
|
|
33286
|
-
async function
|
|
33287
|
-
|
|
33288
|
-
|
|
33660
|
+
const RESOURCE_IDENTITY_TIMEOUT_MS = 1e4;
|
|
33661
|
+
async function readResourceIdentity(providerRegistry, target, region, timeoutMs = RESOURCE_IDENTITY_TIMEOUT_MS) {
|
|
33662
|
+
let timer;
|
|
33663
|
+
const timedOut = new Promise((resolve) => {
|
|
33664
|
+
timer = setTimeout(() => resolve(void 0), timeoutMs);
|
|
33665
|
+
});
|
|
33289
33666
|
try {
|
|
33290
|
-
await
|
|
33667
|
+
return await Promise.race([askResourceIdentity(providerRegistry, target, region), timedOut]);
|
|
33291
33668
|
} finally {
|
|
33292
|
-
|
|
33293
|
-
else await backend.purgeNoncurrentVersions(keys, {
|
|
33294
|
-
...keys.length > 1 && { listPrefix: dirPrefix },
|
|
33295
|
-
objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION
|
|
33296
|
-
});
|
|
33669
|
+
clearTimeout(timer);
|
|
33297
33670
|
}
|
|
33298
|
-
return swept;
|
|
33299
33671
|
}
|
|
33300
|
-
function
|
|
33301
|
-
|
|
33302
|
-
|
|
33303
|
-
|
|
33304
|
-
|
|
33305
|
-
return Number.isNaN(ms) ? null : ms;
|
|
33306
|
-
}
|
|
33307
|
-
function runIdFromJsonlKey(key, dirPrefix) {
|
|
33308
|
-
if (!key.startsWith(dirPrefix) || !key.endsWith(".jsonl")) return null;
|
|
33309
|
-
return key.slice(dirPrefix.length, -6);
|
|
33310
|
-
}
|
|
33311
|
-
var DeploymentEventsStore = class {
|
|
33312
|
-
logger = getLogger().child("DeploymentEvents");
|
|
33313
|
-
backend;
|
|
33314
|
-
stackName;
|
|
33315
|
-
region;
|
|
33316
|
-
command;
|
|
33317
|
-
runId;
|
|
33318
|
-
cdkdVersion;
|
|
33319
|
-
startedAt;
|
|
33320
|
-
events = [];
|
|
33321
|
-
persistedCount = 0;
|
|
33322
|
-
flushTimer;
|
|
33323
|
-
writeChain = Promise.resolve();
|
|
33324
|
-
warnedOnce = false;
|
|
33325
|
-
finalized = false;
|
|
33326
|
-
constructor(backend, options) {
|
|
33327
|
-
this.backend = backend;
|
|
33328
|
-
this.stackName = options.stackName;
|
|
33329
|
-
this.region = options.region;
|
|
33330
|
-
this.command = options.command;
|
|
33331
|
-
this.runId = options.runId ?? newDeploymentRunId();
|
|
33332
|
-
this.cdkdVersion = options.cdkdVersion ?? getCdkdVersion();
|
|
33333
|
-
this.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
33334
|
-
}
|
|
33335
|
-
record(event) {
|
|
33336
|
-
try {
|
|
33337
|
-
if (this.finalized) return;
|
|
33338
|
-
this.events.push({
|
|
33339
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33340
|
-
...event
|
|
33341
|
-
});
|
|
33342
|
-
if (this.events.length - this.persistedCount >= FLUSH_EVENT_THRESHOLD) this.scheduleFlush(0);
|
|
33343
|
-
else this.scheduleFlush(FLUSH_INTERVAL_MS);
|
|
33344
|
-
} catch {}
|
|
33345
|
-
}
|
|
33346
|
-
async finalize(result) {
|
|
33347
|
-
if (this.finalized) return;
|
|
33348
|
-
this.finalized = true;
|
|
33349
|
-
if (this.flushTimer) {
|
|
33350
|
-
clearTimeout(this.flushTimer);
|
|
33351
|
-
this.flushTimer = void 0;
|
|
33352
|
-
}
|
|
33353
|
-
if (this.events.length === 0) return;
|
|
33354
|
-
await this.enqueueWrite(async () => {
|
|
33355
|
-
const indexRead = this.readIndexRuns();
|
|
33356
|
-
indexRead.catch(() => {});
|
|
33357
|
-
await this.doFlush();
|
|
33358
|
-
await this.writeIndexAndPrune(result, await indexRead);
|
|
33359
|
-
});
|
|
33360
|
-
}
|
|
33361
|
-
async writeIndexAndPrune(result, existingRuns) {
|
|
33362
|
-
const { key, file, runs } = this.buildIndexUpdate(result, existingRuns);
|
|
33363
|
-
const keptRunIds = runs.map((r) => r.runId);
|
|
33364
|
-
const willPrune = keptRunIds.length >= 20;
|
|
33365
|
-
const dirPrefix = deploymentsDirPrefix(this.backend.prefix, this.stackName, this.region);
|
|
33366
|
-
const staleKeysRead = willPrune ? this.backend.listRawKeys(dirPrefix) : void 0;
|
|
33367
|
-
staleKeysRead?.catch(() => {});
|
|
33368
|
-
await this.backend.putRawObject(key, JSON.stringify(file, null, 2));
|
|
33369
|
-
if (!staleKeysRead) return;
|
|
33370
|
-
await this.pruneSupersededRunFiles(keptRunIds, dirPrefix, await staleKeysRead);
|
|
33371
|
-
}
|
|
33372
|
-
async drain() {
|
|
33373
|
-
await this.writeChain;
|
|
33374
|
-
}
|
|
33375
|
-
scheduleFlush(delayMs) {
|
|
33376
|
-
if (this.flushTimer) {
|
|
33377
|
-
if (delayMs > 0) return;
|
|
33378
|
-
clearTimeout(this.flushTimer);
|
|
33379
|
-
}
|
|
33380
|
-
this.flushTimer = setTimeout(() => {
|
|
33381
|
-
this.flushTimer = void 0;
|
|
33382
|
-
this.enqueueWrite(() => this.doFlush());
|
|
33383
|
-
}, delayMs);
|
|
33384
|
-
this.flushTimer.unref?.();
|
|
33385
|
-
}
|
|
33386
|
-
enqueueWrite(op) {
|
|
33387
|
-
const next = this.writeChain.then(op).catch((err) => {
|
|
33388
|
-
this.warnOnce(`Failed to persist deployment events for run ${this.runId}: ${describeAwsFailure(err).detail}`);
|
|
33389
|
-
});
|
|
33390
|
-
this.writeChain = next;
|
|
33391
|
-
return next;
|
|
33392
|
-
}
|
|
33393
|
-
async doFlush() {
|
|
33394
|
-
if (this.events.length === 0 || this.events.length === this.persistedCount) return;
|
|
33395
|
-
const snapshotCount = this.events.length;
|
|
33396
|
-
const body = this.events.slice(0, snapshotCount).map((e) => JSON.stringify(e)).join("\n");
|
|
33397
|
-
await this.backend.putRawObject(deploymentEventsKey(this.backend.prefix, this.stackName, this.region, this.runId), body + "\n", "application/x-ndjson");
|
|
33398
|
-
this.persistedCount = snapshotCount;
|
|
33399
|
-
}
|
|
33400
|
-
async readIndexRuns() {
|
|
33401
|
-
const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
|
|
33402
|
-
try {
|
|
33403
|
-
const raw = await this.backend.getRawObject(key);
|
|
33404
|
-
if (raw !== null) {
|
|
33405
|
-
const parsed = JSON.parse(raw);
|
|
33406
|
-
if (Array.isArray(parsed.runs)) return parsed.runs;
|
|
33407
|
-
}
|
|
33408
|
-
} catch (err) {
|
|
33409
|
-
this.logger.debug(`Deployment-events index unreadable, rewriting: ${describeAwsFailure(err).detail}`);
|
|
33410
|
-
}
|
|
33411
|
-
return [];
|
|
33412
|
-
}
|
|
33413
|
-
buildIndexUpdate(result, existingRuns) {
|
|
33414
|
-
const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
|
|
33415
|
-
const runs = [{
|
|
33416
|
-
runId: this.runId,
|
|
33417
|
-
command: this.command,
|
|
33418
|
-
cdkdVersion: this.cdkdVersion,
|
|
33419
|
-
startedAt: this.startedAt,
|
|
33420
|
-
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33421
|
-
result,
|
|
33422
|
-
eventCount: this.persistedCount
|
|
33423
|
-
}, ...existingRuns.filter((r) => r.runId !== this.runId)].slice(0, 20);
|
|
33424
|
-
return {
|
|
33425
|
-
key,
|
|
33426
|
-
file: {
|
|
33427
|
-
indexVersion: 1,
|
|
33428
|
-
stackName: this.stackName,
|
|
33429
|
-
region: this.region,
|
|
33430
|
-
runs,
|
|
33431
|
-
lastModified: Date.now()
|
|
33432
|
-
},
|
|
33433
|
-
runs
|
|
33434
|
-
};
|
|
33435
|
-
}
|
|
33436
|
-
async pruneSupersededRunFiles(keptRunIds, dirPrefix, keys) {
|
|
33437
|
-
if (keptRunIds.length < 20) return;
|
|
33438
|
-
const cutoff = keptRunIds.reduce((min, id) => id < min ? id : min, keptRunIds[0]);
|
|
33439
|
-
const stale = keys.filter((k) => {
|
|
33440
|
-
const runId = runIdFromJsonlKey(k, dirPrefix);
|
|
33441
|
-
return runId !== null && runId < cutoff;
|
|
33672
|
+
async function askResourceIdentity(providerRegistry, target, region) {
|
|
33673
|
+
try {
|
|
33674
|
+
const { provider } = providerRegistry.getProviderFor({
|
|
33675
|
+
resourceType: target.resourceType,
|
|
33676
|
+
provisionedBy: target.provisionedBy
|
|
33442
33677
|
});
|
|
33443
|
-
if (
|
|
33444
|
-
await
|
|
33445
|
-
|
|
33446
|
-
|
|
33447
|
-
|
|
33448
|
-
|
|
33449
|
-
this.logger.debug(message);
|
|
33450
|
-
return;
|
|
33451
|
-
}
|
|
33452
|
-
this.warnedOnce = true;
|
|
33453
|
-
this.logger.warn(`${message} — continuing; deployment events are best-effort and never block the run.`);
|
|
33454
|
-
}
|
|
33455
|
-
};
|
|
33456
|
-
var DeploymentEventsReader = class {
|
|
33457
|
-
backend;
|
|
33458
|
-
constructor(backend) {
|
|
33459
|
-
this.backend = backend;
|
|
33460
|
-
}
|
|
33461
|
-
async listRegions(stackName) {
|
|
33462
|
-
const prefix = `${this.backend.prefix}/${stackName}/`;
|
|
33463
|
-
const keys = await this.backend.listRawKeys(prefix);
|
|
33464
|
-
const regions = /* @__PURE__ */ new Set();
|
|
33465
|
-
for (const key of keys) {
|
|
33466
|
-
const segments = key.slice(prefix.length).split("/");
|
|
33467
|
-
if (segments.length === 3 && segments[1] === "deployments" && segments[0]) regions.add(segments[0]);
|
|
33468
|
-
}
|
|
33469
|
-
return [...regions].sort();
|
|
33470
|
-
}
|
|
33471
|
-
async listRuns(stackName, region) {
|
|
33472
|
-
const key = deploymentEventsIndexKey(this.backend.prefix, stackName, region);
|
|
33473
|
-
try {
|
|
33474
|
-
const raw = await this.backend.getRawObject(key);
|
|
33475
|
-
if (raw !== null) {
|
|
33476
|
-
const parsed = JSON.parse(raw);
|
|
33477
|
-
if (Array.isArray(parsed.runs)) return parsed.runs;
|
|
33478
|
-
}
|
|
33479
|
-
} catch {}
|
|
33480
|
-
const dirPrefix = `${this.backend.prefix}/${stackName}/${region}/deployments/`;
|
|
33481
|
-
const runIds = (await this.backend.listRawKeys(dirPrefix)).filter((k) => k.endsWith(".jsonl")).map((k) => k.slice(dirPrefix.length, -6)).sort().reverse();
|
|
33482
|
-
return Promise.all(runIds.map((runId) => this.summarizeRunFromJsonl(stackName, region, runId)));
|
|
33483
|
-
}
|
|
33484
|
-
async summarizeRunFromJsonl(stackName, region, runId) {
|
|
33485
|
-
const fallback = {
|
|
33486
|
-
runId,
|
|
33487
|
-
command: "deploy",
|
|
33488
|
-
cdkdVersion: "unknown",
|
|
33489
|
-
startedAt: "",
|
|
33490
|
-
finishedAt: "",
|
|
33491
|
-
result: "UNKNOWN",
|
|
33492
|
-
eventCount: 0
|
|
33493
|
-
};
|
|
33494
|
-
let events = null;
|
|
33495
|
-
try {
|
|
33496
|
-
events = await this.readRunEvents(stackName, region, runId);
|
|
33497
|
-
} catch {
|
|
33498
|
-
return fallback;
|
|
33499
|
-
}
|
|
33500
|
-
if (events === null || events.length === 0) return fallback;
|
|
33501
|
-
const started = events.find((e) => e.eventType === "RUN_STARTED");
|
|
33502
|
-
let finished;
|
|
33503
|
-
for (const e of events) if (e.eventType === "RUN_FINISHED") finished = e;
|
|
33504
|
-
return {
|
|
33505
|
-
runId,
|
|
33506
|
-
command: started?.command ?? fallback.command,
|
|
33507
|
-
cdkdVersion: started?.cdkdVersion ?? fallback.cdkdVersion,
|
|
33508
|
-
startedAt: started?.timestamp ?? fallback.startedAt,
|
|
33509
|
-
finishedAt: finished?.timestamp ?? fallback.finishedAt,
|
|
33510
|
-
result: finished?.result ?? "UNKNOWN",
|
|
33511
|
-
eventCount: events.length
|
|
33512
|
-
};
|
|
33513
|
-
}
|
|
33514
|
-
async readRunEvents(stackName, region, runId) {
|
|
33515
|
-
const key = deploymentEventsKey(this.backend.prefix, stackName, region, runId);
|
|
33516
|
-
const raw = await this.backend.getRawObject(key);
|
|
33517
|
-
if (raw === null) return null;
|
|
33518
|
-
const events = [];
|
|
33519
|
-
for (const line of raw.split("\n")) {
|
|
33520
|
-
const trimmed = line.trim();
|
|
33521
|
-
if (!trimmed) continue;
|
|
33522
|
-
try {
|
|
33523
|
-
events.push(JSON.parse(trimmed));
|
|
33524
|
-
} catch {}
|
|
33525
|
-
}
|
|
33526
|
-
return events;
|
|
33678
|
+
if (typeof provider.resourceIdentity !== "function") return void 0;
|
|
33679
|
+
const identity = await provider.resourceIdentity(target.physicalId, target.resourceType, { expectedRegion: region });
|
|
33680
|
+
if (identity === RESOURCE_NOT_FOUND) return RESOURCE_NOT_FOUND;
|
|
33681
|
+
return typeof identity === "string" && identity !== "" ? identity : void 0;
|
|
33682
|
+
} catch {
|
|
33683
|
+
return;
|
|
33527
33684
|
}
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
|
|
33532
|
-
|
|
33533
|
-
|
|
33534
|
-
|
|
33535
|
-
|
|
33536
|
-
|
|
33537
|
-
|
|
33538
|
-
|
|
33539
|
-
|
|
33540
|
-
|
|
33541
|
-
|
|
33542
|
-
|
|
33543
|
-
|
|
33544
|
-
|
|
33545
|
-
|
|
33546
|
-
|
|
33547
|
-
|
|
33548
|
-
if (opts.olderThanMs !== void 0) {
|
|
33549
|
-
const cutoff = (opts.now ?? /* @__PURE__ */ new Date()).getTime() - opts.olderThanMs;
|
|
33550
|
-
candidates = candidates.filter((id) => {
|
|
33551
|
-
const t = runIdTimestampMs(id);
|
|
33552
|
-
return t !== null && t < cutoff;
|
|
33553
|
-
});
|
|
33554
|
-
}
|
|
33555
|
-
if (candidates.length === 0) return {
|
|
33556
|
-
deletedRunIds: [],
|
|
33557
|
-
remainingRunIds: runIdsDesc,
|
|
33558
|
-
indexDeleted: false
|
|
33559
|
-
};
|
|
33560
|
-
const deletedSet = new Set(candidates);
|
|
33561
|
-
const deleteKeys = candidates.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
|
|
33562
|
-
const remainingRunIds = runIdsDesc.filter((id) => !deletedSet.has(id));
|
|
33563
|
-
if (remainingRunIds.length === 0) {
|
|
33564
|
-
await deleteAndPurgeEventObjects(this.backend, [...deleteKeys, indexKey], dirPrefix);
|
|
33565
|
-
return {
|
|
33566
|
-
deletedRunIds: candidates,
|
|
33567
|
-
remainingRunIds,
|
|
33568
|
-
indexDeleted: indexExisted
|
|
33569
|
-
};
|
|
33570
|
-
}
|
|
33571
|
-
await this.rewriteIndexAfterPrune(indexKey, stackName, region, deletedSet);
|
|
33572
|
-
await deleteAndPurgeEventObjects(this.backend, deleteKeys, dirPrefix);
|
|
33685
|
+
}
|
|
33686
|
+
async function createdResourceStillThere(op, ctx) {
|
|
33687
|
+
if (op.deletionPolicy === "Retain") return "proven";
|
|
33688
|
+
if (!orphanNeedsIdentity(op)) return "proven";
|
|
33689
|
+
const physicalId = op.physicalId;
|
|
33690
|
+
if (!physicalId) return "unproven";
|
|
33691
|
+
const live = await readResourceIdentity(ctx.providerRegistry, {
|
|
33692
|
+
resourceType: op.resourceType,
|
|
33693
|
+
physicalId,
|
|
33694
|
+
provisionedBy: op.provisionedBy
|
|
33695
|
+
}, ctx.region);
|
|
33696
|
+
if (live === RESOURCE_NOT_FOUND) return "gone";
|
|
33697
|
+
const journaled = op.createdResourceIdentity;
|
|
33698
|
+
if (typeof journaled !== "string" || journaled === "" || typeof live !== "string") return "unproven";
|
|
33699
|
+
return live === journaled ? "proven" : "mismatch";
|
|
33700
|
+
}
|
|
33701
|
+
async function askForeignHolder(foreignHolder, op) {
|
|
33702
|
+
try {
|
|
33703
|
+
return await foreignHolder(op.resourceType, op.physicalId);
|
|
33704
|
+
} catch {
|
|
33573
33705
|
return {
|
|
33574
|
-
|
|
33575
|
-
|
|
33576
|
-
indexDeleted: false
|
|
33577
|
-
};
|
|
33578
|
-
}
|
|
33579
|
-
async rewriteIndexAfterPrune(indexKey, stackName, region, deletedRunIds) {
|
|
33580
|
-
let raw;
|
|
33581
|
-
try {
|
|
33582
|
-
raw = await this.backend.getRawObject(indexKey);
|
|
33583
|
-
} catch {
|
|
33584
|
-
return;
|
|
33585
|
-
}
|
|
33586
|
-
if (raw === null) return;
|
|
33587
|
-
let parsed;
|
|
33588
|
-
try {
|
|
33589
|
-
parsed = JSON.parse(raw);
|
|
33590
|
-
} catch {
|
|
33591
|
-
return;
|
|
33592
|
-
}
|
|
33593
|
-
if (!Array.isArray(parsed.runs)) return;
|
|
33594
|
-
const remaining = parsed.runs.filter((r) => !deletedRunIds.has(r.runId));
|
|
33595
|
-
if (remaining.length === parsed.runs.length) return;
|
|
33596
|
-
const file = {
|
|
33597
|
-
indexVersion: 1,
|
|
33598
|
-
stackName,
|
|
33599
|
-
region,
|
|
33600
|
-
runs: remaining,
|
|
33601
|
-
lastModified: Date.now()
|
|
33706
|
+
kind: "unreadable",
|
|
33707
|
+
what: "the other stacks' state records (the scan failed)"
|
|
33602
33708
|
};
|
|
33603
|
-
await this.backend.putRawObject(indexKey, JSON.stringify(file, null, 2));
|
|
33604
33709
|
}
|
|
33605
|
-
}
|
|
33710
|
+
}
|
|
33606
33711
|
|
|
33607
33712
|
//#endregion
|
|
33608
33713
|
//#region src/deployment/rollback-executor/replay-scope.ts
|
|
@@ -33912,93 +34017,6 @@ function renderNestedStackTypeChangeRefusal(typeChanges, stackName) {
|
|
|
33912
34017
|
return `Refusing to deploy ${stackName}: ` + (typeChanges.length === 1 ? `a resource changes its Type ` : `${typeChanges.length} resources change their Type `) + `into or out of ${NESTED_STACK_RESOURCE_TYPE}, which cdkd does not replace in place.\n${rows.join("\n")}\n Deploy this as two changes instead: give the new resource a DIFFERENT logical id (in CDK, rename the construct) so the existing row is deleted through its own type's provider and the new one is created under its own — or remove the resource in one deploy and add its replacement in the next. There is no flag that overrides this refusal.`;
|
|
33913
34018
|
}
|
|
33914
34019
|
|
|
33915
|
-
//#endregion
|
|
33916
|
-
//#region src/deployment/rollback-executor/orphan-identity.ts
|
|
33917
|
-
const UNIQUE_PHYSICAL_ID_TYPES = /* @__PURE__ */ new Set([
|
|
33918
|
-
"AWS::EC2::VPC",
|
|
33919
|
-
"AWS::EC2::Subnet",
|
|
33920
|
-
"AWS::EC2::EIP",
|
|
33921
|
-
"AWS::EC2::NatGateway",
|
|
33922
|
-
"AWS::EC2::SecurityGroup",
|
|
33923
|
-
"AWS::EC2::Instance",
|
|
33924
|
-
"AWS::EFS::FileSystem",
|
|
33925
|
-
"AWS::EFS::MountTarget",
|
|
33926
|
-
"AWS::FSx::FileSystem",
|
|
33927
|
-
"AWS::KMS::Key",
|
|
33928
|
-
"AWS::CertificateManager::Certificate",
|
|
33929
|
-
"AWS::ElasticLoadBalancingV2::LoadBalancer",
|
|
33930
|
-
"AWS::ElasticLoadBalancingV2::TargetGroup",
|
|
33931
|
-
"AWS::ElasticLoadBalancingV2::Listener",
|
|
33932
|
-
"AWS::EMR::Cluster",
|
|
33933
|
-
"AWS::EMR::InstanceGroupConfig",
|
|
33934
|
-
"AWS::EMR::InstanceFleetConfig",
|
|
33935
|
-
"AWS::Cognito::UserPool",
|
|
33936
|
-
"AWS::Route53::HostedZone",
|
|
33937
|
-
"AWS::ServiceDiscovery::PrivateDnsNamespace",
|
|
33938
|
-
"AWS::ServiceDiscovery::PublicDnsNamespace",
|
|
33939
|
-
"AWS::ServiceDiscovery::HttpNamespace",
|
|
33940
|
-
"AWS::ServiceDiscovery::Service",
|
|
33941
|
-
"AWS::AppSync::GraphQLApi",
|
|
33942
|
-
"AWS::IAM::AccessKey",
|
|
33943
|
-
"AWS::Kinesis::StreamConsumer"
|
|
33944
|
-
]);
|
|
33945
|
-
const CONTENT_COMPARED_DELETE_TYPES = /* @__PURE__ */ new Set(["AWS::SQS::QueuePolicy", "AWS::SNS::TopicPolicy"]);
|
|
33946
|
-
const CDKD_NAMESPACE_ID_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::Stack"]);
|
|
33947
|
-
function orphanDeleteNeedsIdentity(resourceType) {
|
|
33948
|
-
return !UNIQUE_PHYSICAL_ID_TYPES.has(resourceType) && !CONTENT_COMPARED_DELETE_TYPES.has(resourceType) && !CDKD_NAMESPACE_ID_TYPES.has(resourceType);
|
|
33949
|
-
}
|
|
33950
|
-
const RESOURCE_IDENTITY_TIMEOUT_MS = 1e4;
|
|
33951
|
-
async function readResourceIdentity(providerRegistry, target, region, timeoutMs = RESOURCE_IDENTITY_TIMEOUT_MS) {
|
|
33952
|
-
let timer;
|
|
33953
|
-
const timedOut = new Promise((resolve) => {
|
|
33954
|
-
timer = setTimeout(() => resolve(void 0), timeoutMs);
|
|
33955
|
-
});
|
|
33956
|
-
try {
|
|
33957
|
-
return await Promise.race([askResourceIdentity(providerRegistry, target, region), timedOut]);
|
|
33958
|
-
} finally {
|
|
33959
|
-
clearTimeout(timer);
|
|
33960
|
-
}
|
|
33961
|
-
}
|
|
33962
|
-
async function askResourceIdentity(providerRegistry, target, region) {
|
|
33963
|
-
try {
|
|
33964
|
-
const { provider } = providerRegistry.getProviderFor({
|
|
33965
|
-
resourceType: target.resourceType,
|
|
33966
|
-
provisionedBy: target.provisionedBy
|
|
33967
|
-
});
|
|
33968
|
-
if (typeof provider.resourceIdentity !== "function") return void 0;
|
|
33969
|
-
const identity = await provider.resourceIdentity(target.physicalId, target.resourceType, { expectedRegion: region });
|
|
33970
|
-
if (identity === RESOURCE_NOT_FOUND) return RESOURCE_NOT_FOUND;
|
|
33971
|
-
return typeof identity === "string" && identity !== "" ? identity : void 0;
|
|
33972
|
-
} catch {
|
|
33973
|
-
return;
|
|
33974
|
-
}
|
|
33975
|
-
}
|
|
33976
|
-
async function createdResourceStillThere(op, ctx) {
|
|
33977
|
-
if (op.deletionPolicy === "Retain") return "proven";
|
|
33978
|
-
if (!orphanDeleteNeedsIdentity(op.resourceType)) return "proven";
|
|
33979
|
-
const physicalId = op.physicalId;
|
|
33980
|
-
if (!physicalId) return "unproven";
|
|
33981
|
-
const live = await readResourceIdentity(ctx.providerRegistry, {
|
|
33982
|
-
resourceType: op.resourceType,
|
|
33983
|
-
physicalId,
|
|
33984
|
-
provisionedBy: op.provisionedBy
|
|
33985
|
-
}, ctx.region);
|
|
33986
|
-
if (live === RESOURCE_NOT_FOUND) return "gone";
|
|
33987
|
-
const journaled = op.createdResourceIdentity;
|
|
33988
|
-
if (typeof journaled !== "string" || journaled === "" || typeof live !== "string") return "unproven";
|
|
33989
|
-
return live === journaled ? "proven" : "mismatch";
|
|
33990
|
-
}
|
|
33991
|
-
async function askForeignHolder(foreignHolder, op) {
|
|
33992
|
-
try {
|
|
33993
|
-
return await foreignHolder(op.resourceType, op.physicalId);
|
|
33994
|
-
} catch {
|
|
33995
|
-
return {
|
|
33996
|
-
kind: "unreadable",
|
|
33997
|
-
what: "the other stacks' state records (the scan failed)"
|
|
33998
|
-
};
|
|
33999
|
-
}
|
|
34000
|
-
}
|
|
34001
|
-
|
|
34002
34020
|
//#endregion
|
|
34003
34021
|
//#region src/deployment/rollback-executor/plan.ts
|
|
34004
34022
|
function journaledOldTypes(op) {
|
|
@@ -35455,7 +35473,7 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
|
|
|
35455
35473
|
}
|
|
35456
35474
|
function protectionRemovalProven(op, deleteProven) {
|
|
35457
35475
|
if (op.physicalIdRecoveredFromError !== true) return true;
|
|
35458
|
-
return deleteProven && (!
|
|
35476
|
+
return deleteProven && (!orphanNeedsIdentity(op) || removeProtectionTypes().includes(op.resourceType));
|
|
35459
35477
|
}
|
|
35460
35478
|
async function journaledOrphanKeepReason(op, foreignHolder, ctx) {
|
|
35461
35479
|
const holding = await askForeignHolder(foreignHolder, op);
|
|
@@ -35873,6 +35891,344 @@ async function replayFailedOperations(...args) {
|
|
|
35873
35891
|
return await withProducerRegions(() => replayProducerRegionEvidence(args[3]), () => withStackRecords(replayStackRecordsView(args[1]), () => replayFailedOperationsUnbound(...args)));
|
|
35874
35892
|
}
|
|
35875
35893
|
|
|
35894
|
+
//#endregion
|
|
35895
|
+
//#region src/provisioning/nested-stack-context.ts
|
|
35896
|
+
const storage$1 = new AsyncLocalStorage();
|
|
35897
|
+
function withNestedStackContext(ctx, fn) {
|
|
35898
|
+
return storage$1.run(ctx, fn);
|
|
35899
|
+
}
|
|
35900
|
+
function getCurrentNestedStackContext() {
|
|
35901
|
+
return storage$1.getStore();
|
|
35902
|
+
}
|
|
35903
|
+
async function collectNestedChildUnaddressed(fn) {
|
|
35904
|
+
const ctx = storage$1.getStore();
|
|
35905
|
+
if (!ctx) return {
|
|
35906
|
+
value: await fn(),
|
|
35907
|
+
unaddressed: void 0
|
|
35908
|
+
};
|
|
35909
|
+
const slot = {};
|
|
35910
|
+
return {
|
|
35911
|
+
value: await storage$1.run({
|
|
35912
|
+
...ctx,
|
|
35913
|
+
childUnaddressed: slot
|
|
35914
|
+
}, fn),
|
|
35915
|
+
unaddressed: slot.last
|
|
35916
|
+
};
|
|
35917
|
+
}
|
|
35918
|
+
|
|
35919
|
+
//#endregion
|
|
35920
|
+
//#region src/deployment/nested-child-journal.ts
|
|
35921
|
+
const NESTED_PENDING_PARENT_REASON = "nested-pending-parent";
|
|
35922
|
+
const NESTED_STACK_TYPE$2 = "AWS::CloudFormation::Stack";
|
|
35923
|
+
const MAX_NESTED_WALK_DEPTH = 32;
|
|
35924
|
+
function nestedChildStackName(parentStackName, logicalId) {
|
|
35925
|
+
return `${parentStackName}~${logicalId}`;
|
|
35926
|
+
}
|
|
35927
|
+
function nestedPendingSnapshot(state, refusesExportName) {
|
|
35928
|
+
const outputs = { ...isPlainRecord(state.outputs) ? state.outputs : {} };
|
|
35929
|
+
let exportNames = Array.isArray(state.exportNames) ? [...state.exportNames] : void 0;
|
|
35930
|
+
const refused = new Set(importableOutputKeys(state).filter((name) => refusesExportName(name)));
|
|
35931
|
+
if (refused.size > 0) {
|
|
35932
|
+
for (const name of refused) Reflect.deleteProperty(outputs, name);
|
|
35933
|
+
if (exportNames !== void 0) exportNames = exportNames.filter((name) => !refused.has(name));
|
|
35934
|
+
}
|
|
35935
|
+
return {
|
|
35936
|
+
previousOutputs: {
|
|
35937
|
+
outputs,
|
|
35938
|
+
...exportNames !== void 0 && { exportNames }
|
|
35939
|
+
},
|
|
35940
|
+
previousCrossStackReads: {
|
|
35941
|
+
...Array.isArray(state.imports) && { imports: [...state.imports] },
|
|
35942
|
+
...Array.isArray(state.outputReads) && { outputReads: [...state.outputReads] }
|
|
35943
|
+
}
|
|
35944
|
+
};
|
|
35945
|
+
}
|
|
35946
|
+
function displacedPhysicalIdShown(op, logger, physicalId = journalOpPhysicalId(op)) {
|
|
35947
|
+
if (physicalId === void 0) return void 0;
|
|
35948
|
+
const masker = createOpMasker(logger, /* @__PURE__ */ new Map());
|
|
35949
|
+
for (const properties of [
|
|
35950
|
+
op.properties,
|
|
35951
|
+
op.attemptedProperties,
|
|
35952
|
+
op.previousState?.properties
|
|
35953
|
+
]) {
|
|
35954
|
+
if (properties === void 0) continue;
|
|
35955
|
+
masker.addNamed({
|
|
35956
|
+
resourceType: op.resourceType,
|
|
35957
|
+
properties,
|
|
35958
|
+
logicalId: op.logicalId,
|
|
35959
|
+
physicalIds: [physicalId]
|
|
35960
|
+
});
|
|
35961
|
+
}
|
|
35962
|
+
return displaySafe(String(masker.mask(physicalId)));
|
|
35963
|
+
}
|
|
35964
|
+
function displacedOpClause(op, marks, logger) {
|
|
35965
|
+
const retainedOld = retainedOldPhysicalId(op);
|
|
35966
|
+
if (retainedOld !== void 0 && marks.some((m) => isMarkFor(m, op))) {
|
|
35967
|
+
const shownOld = displacedPhysicalIdShown(op, logger, retainedOld);
|
|
35968
|
+
return `replaced ${shownOld} ${op.oldResourceRetained === true ? "but kept it (UpdateReplacePolicy: Retain)" : op.oldResourceMaySurvive !== void 0 ? "and may have kept it (its delete was not confirmed)" : "and may have kept it (the journal records no verdict)"}; cdkd import adopted the replacement, so ${shownOld} is left untracked`;
|
|
35969
|
+
}
|
|
35970
|
+
const shownId = displacedPhysicalIdShown(op, logger);
|
|
35971
|
+
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";
|
|
35972
|
+
}
|
|
35973
|
+
function recordDisplacedSkips(recordEvent, stackName, ops) {
|
|
35974
|
+
for (const op of ops) recordEvent?.({
|
|
35975
|
+
eventType: "ROLLBACK_RESOURCE_SKIPPED",
|
|
35976
|
+
stackName,
|
|
35977
|
+
operation: op.changeType,
|
|
35978
|
+
logicalId: op.logicalId,
|
|
35979
|
+
resourceType: op.resourceType,
|
|
35980
|
+
...op.provisionedBy && { provisionedBy: op.provisionedBy },
|
|
35981
|
+
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"
|
|
35982
|
+
});
|
|
35983
|
+
}
|
|
35984
|
+
function revertedNestedRowIds(ops) {
|
|
35985
|
+
return ops.filter((op) => op.resourceType === NESTED_STACK_TYPE$2 && op.changeType === "UPDATE").map((op) => op.logicalId);
|
|
35986
|
+
}
|
|
35987
|
+
const revertRunStorage = new AsyncLocalStorage();
|
|
35988
|
+
function withNestedRevertRun(runId, fn) {
|
|
35989
|
+
const run = {
|
|
35990
|
+
runId,
|
|
35991
|
+
settled: /* @__PURE__ */ new Map(),
|
|
35992
|
+
warnings: 0
|
|
35993
|
+
};
|
|
35994
|
+
return revertRunStorage.run(run, () => fn(run));
|
|
35995
|
+
}
|
|
35996
|
+
function getNestedRevertRun() {
|
|
35997
|
+
return revertRunStorage.getStore();
|
|
35998
|
+
}
|
|
35999
|
+
function errorText(error) {
|
|
36000
|
+
return displaySafe(describeAwsFailure(error).detail);
|
|
36001
|
+
}
|
|
36002
|
+
function isPlainRecord(value) {
|
|
36003
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36004
|
+
}
|
|
36005
|
+
async function dropNestedChildJournals(args) {
|
|
36006
|
+
const { stateBackend, parentStackName, region, resources, logger } = args;
|
|
36007
|
+
const depth = args.depth ?? 0;
|
|
36008
|
+
if (!isPlainRecord(resources)) return;
|
|
36009
|
+
if (depthExceeded(depth, parentStackName, logger)) return;
|
|
36010
|
+
for (const [logicalId, record] of Object.entries(resources)) {
|
|
36011
|
+
if (!isPlainRecord(record) || record["resourceType"] !== NESTED_STACK_TYPE$2) continue;
|
|
36012
|
+
const child = nestedChildStackName(parentStackName, logicalId);
|
|
36013
|
+
try {
|
|
36014
|
+
const data = await stateBackend.getState(child, region);
|
|
36015
|
+
if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) await dropNestedChildJournals({
|
|
36016
|
+
...args,
|
|
36017
|
+
parentStackName: child,
|
|
36018
|
+
resources: data.state.resources,
|
|
36019
|
+
depth: depth + 1
|
|
36020
|
+
});
|
|
36021
|
+
} catch (error) {
|
|
36022
|
+
warnUncleared(logger, child, error);
|
|
36023
|
+
}
|
|
36024
|
+
try {
|
|
36025
|
+
if (await withChildLock(args.lockManager, child, region, logger, async () => {
|
|
36026
|
+
if (args.beforeDelete) {
|
|
36027
|
+
if (!await args.beforeDelete(child, await readOwnRecord(stateBackend, child, region))) return false;
|
|
36028
|
+
}
|
|
36029
|
+
let gone;
|
|
36030
|
+
try {
|
|
36031
|
+
gone = await stateBackend.deleteRollbackJournal(child, region);
|
|
36032
|
+
} catch (error) {
|
|
36033
|
+
await args.onDeleteFailed?.(child);
|
|
36034
|
+
throw error;
|
|
36035
|
+
}
|
|
36036
|
+
if (gone === false) {
|
|
36037
|
+
await args.onDeleteFailed?.(child);
|
|
36038
|
+
return false;
|
|
36039
|
+
}
|
|
36040
|
+
return true;
|
|
36041
|
+
})) logger.debug(safeMsg`Deleted the rollback journal of nested stack ${displaySafe(child)}`);
|
|
36042
|
+
} catch (error) {
|
|
36043
|
+
warnUncleared(logger, child, error);
|
|
36044
|
+
}
|
|
36045
|
+
}
|
|
36046
|
+
}
|
|
36047
|
+
async function readOwnRecord(stateBackend, child, region) {
|
|
36048
|
+
try {
|
|
36049
|
+
const data = await stateBackend.getState(child, region);
|
|
36050
|
+
if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) return data.state;
|
|
36051
|
+
} catch {}
|
|
36052
|
+
}
|
|
36053
|
+
async function dropSettledNestedJournals(args) {
|
|
36054
|
+
const { stateBackend, parentStackName, region, runId, logger } = args;
|
|
36055
|
+
const depth = args.depth ?? 0;
|
|
36056
|
+
if (runId === void 0) return;
|
|
36057
|
+
if (depthExceeded(depth, parentStackName, logger)) return;
|
|
36058
|
+
const isSettled = (segment) => segment.runId === runId && segment.reason === "nested-pending-parent";
|
|
36059
|
+
for (const [logicalId, grandchildren] of args.settled) {
|
|
36060
|
+
const child = nestedChildStackName(parentStackName, logicalId);
|
|
36061
|
+
if (grandchildren.size > 0) await dropSettledNestedJournals({
|
|
36062
|
+
...args,
|
|
36063
|
+
parentStackName: child,
|
|
36064
|
+
settled: grandchildren,
|
|
36065
|
+
depth: depth + 1
|
|
36066
|
+
});
|
|
36067
|
+
try {
|
|
36068
|
+
const removed = await withChildLock(args.lockManager, child, region, logger, () => stateBackend.dropRollbackJournalSegments(child, region, isSettled));
|
|
36069
|
+
if (removed > 0) logger.debug(safeMsg`Dropped ${removed} settled rollback journal segment(s) of ${displaySafe(child)}`);
|
|
36070
|
+
} catch (error) {
|
|
36071
|
+
warnUncleared(logger, child, error);
|
|
36072
|
+
}
|
|
36073
|
+
}
|
|
36074
|
+
}
|
|
36075
|
+
async function withChildLock(lockManager, child, region, logger, fn) {
|
|
36076
|
+
await lockManager.acquireLockWithRetry(child, region, void 0, "rollback");
|
|
36077
|
+
try {
|
|
36078
|
+
return await fn();
|
|
36079
|
+
} finally {
|
|
36080
|
+
await lockManager.releaseLock(child, region).catch((error) => {
|
|
36081
|
+
logger.warn(safeMsg`Failed to release the lock of nested stack ${displayIdent(child)}: ${errorText(error)}`);
|
|
36082
|
+
});
|
|
36083
|
+
}
|
|
36084
|
+
}
|
|
36085
|
+
function depthExceeded(depth, parentStackName, logger) {
|
|
36086
|
+
if (depth < MAX_NESTED_WALK_DEPTH) return false;
|
|
36087
|
+
logger.warn(safeMsg`Stopped clearing nested rollback journals below ${displayIdent(parentStackName)}: ` + safeMsg`the nesting is deeper than ${MAX_NESTED_WALK_DEPTH} levels.`);
|
|
36088
|
+
return true;
|
|
36089
|
+
}
|
|
36090
|
+
function warnUncleared(logger, child, error) {
|
|
36091
|
+
logger.warn(safeMsg`Could not clear the rollback journal of nested stack ${displayIdent(child)}: ${errorText(error)}. ` + "It is inert to every parent revert (they select segments by run) and the next successful deploy of the top-level stack removes it.");
|
|
36092
|
+
}
|
|
36093
|
+
async function revertNestedChildFromJournal(args) {
|
|
36094
|
+
const { ctx, logicalId, childStackName, region, run, logger } = args;
|
|
36095
|
+
const runId = run.runId;
|
|
36096
|
+
const shownChild = displayIdent(childStackName);
|
|
36097
|
+
const refuse = (detail) => {
|
|
36098
|
+
throw markNonRetryable(/* @__PURE__ */ new Error(`Cannot revert nested stack ${shownChild} (row ${displayIdent(logicalId)}): ${detail} The child was NOT (fully) reverted and may still hold the failed deploy's configuration. Inspect it with 'cdkd state show'; re-run the rollback once the cause is fixed (its journal is kept), or re-deploy the parent to converge.`));
|
|
36099
|
+
};
|
|
36100
|
+
if (runId === void 0) refuse("the rollback carries no deploy run id to select its journal segments by.");
|
|
36101
|
+
await ctx.lockManager.acquireLockWithRetry(childStackName, region, void 0, "rollback");
|
|
36102
|
+
try {
|
|
36103
|
+
const stateData = await ctx.stateBackend.getState(childStackName, region);
|
|
36104
|
+
if (!stateData) refuse("its state.json is missing.");
|
|
36105
|
+
if (stateData.divergentBodyRegion !== void 0) refuse("its state record's region field disagrees with the key it is stored under.");
|
|
36106
|
+
const base = stateData.state;
|
|
36107
|
+
const refusalRecovery = {
|
|
36108
|
+
profile: ctx.destroyOptions?.profile,
|
|
36109
|
+
stateBucket: ctx.stateBucket,
|
|
36110
|
+
statePrefix: ctx.destroyOptions?.statePrefix
|
|
36111
|
+
};
|
|
36112
|
+
refuseMalformedState(base, childStackName, region, refusalRecovery);
|
|
36113
|
+
refuseMalformedOrphans(base, childStackName, region, refusalRecovery);
|
|
36114
|
+
refuseMalformedOrphanRecords(base, childStackName, region, refusalRecovery);
|
|
36115
|
+
const segments = ((await ctx.stateBackend.loadRollbackJournal(childStackName, region))?.segments ?? []).filter((segment) => segment.runId === runId);
|
|
36116
|
+
if (segments.length === 0) refuse("its rollback journal holds no segment for this deploy run, so there is no record of what it held before.");
|
|
36117
|
+
const stateResources = { ...base.resources };
|
|
36118
|
+
const mintedOrphans = [];
|
|
36119
|
+
const restoredOutputs = segments.find((s) => s.previousOutputs)?.previousOutputs;
|
|
36120
|
+
const restoredReads = segments.find((s) => s.previousCrossStackReads)?.previousCrossStackReads;
|
|
36121
|
+
let currentEtag = stateData.etag;
|
|
36122
|
+
let persisted = false;
|
|
36123
|
+
let restoring = false;
|
|
36124
|
+
const { skippedOutputs: _dropped, ...carried } = base;
|
|
36125
|
+
const next = () => ({
|
|
36126
|
+
...carried,
|
|
36127
|
+
version: 12,
|
|
36128
|
+
region,
|
|
36129
|
+
resources: { ...stateResources },
|
|
36130
|
+
...orphansAfterRollback(base, mintedOrphans),
|
|
36131
|
+
...restoring && restoredOutputs && { outputs: { ...restoredOutputs.outputs } },
|
|
36132
|
+
...restoring && restoredReads && {
|
|
36133
|
+
...restoredReads.imports && { imports: [...restoredReads.imports] },
|
|
36134
|
+
...restoredReads.outputReads && { outputReads: [...restoredReads.outputReads] }
|
|
36135
|
+
},
|
|
36136
|
+
...restoring && restoredOutputs?.exportNames && { exportNames: [...restoredOutputs.exportNames] },
|
|
36137
|
+
lastModified: Date.now()
|
|
36138
|
+
});
|
|
36139
|
+
const nextState = () => {
|
|
36140
|
+
const state = next();
|
|
36141
|
+
if (!restoring) return state;
|
|
36142
|
+
if (restoredOutputs && !restoredOutputs.exportNames) delete state.exportNames;
|
|
36143
|
+
if (restoredOutputs) delete state.outputReferenceProvenance;
|
|
36144
|
+
if (restoredReads && !restoredReads.imports) delete state.imports;
|
|
36145
|
+
if (restoredReads && !restoredReads.outputReads) delete state.outputReads;
|
|
36146
|
+
return state;
|
|
36147
|
+
};
|
|
36148
|
+
const save = async () => {
|
|
36149
|
+
persisted = false;
|
|
36150
|
+
try {
|
|
36151
|
+
currentEtag = await ctx.stateBackend.saveState(childStackName, region, nextState(), { ...currentEtag !== void 0 && { expectedEtag: currentEtag } });
|
|
36152
|
+
persisted = true;
|
|
36153
|
+
} catch {
|
|
36154
|
+
try {
|
|
36155
|
+
const fresh = await ctx.stateBackend.getState(childStackName, region);
|
|
36156
|
+
currentEtag = await ctx.stateBackend.saveState(childStackName, region, nextState(), { ...fresh?.etag !== void 0 && { expectedEtag: fresh.etag } });
|
|
36157
|
+
persisted = true;
|
|
36158
|
+
} catch (retryError) {
|
|
36159
|
+
logger.warn(safeMsg`Failed to persist the state of nested stack ${shownChild} after reverting it: ` + safeMsg`${errorText(retryError)}. The resources were reverted in AWS.`);
|
|
36160
|
+
}
|
|
36161
|
+
}
|
|
36162
|
+
};
|
|
36163
|
+
const producerRegions = inheritProducerRegions(producerRegionsFromState({
|
|
36164
|
+
imports: [...base.imports ?? [], ...restoredReads?.imports ?? []],
|
|
36165
|
+
outputReads: [...base.outputReads ?? [], ...restoredReads?.outputReads ?? []]
|
|
36166
|
+
}), args.inheritedProducerRegions);
|
|
36167
|
+
const execCtx = {
|
|
36168
|
+
providerRegistry: ctx.providerRegistry,
|
|
36169
|
+
region,
|
|
36170
|
+
logger,
|
|
36171
|
+
...ctx.options?.eventRecorder && { recordEvent: (event) => ctx.options.eventRecorder.record(maskEventTextWithBoundBags(event)) },
|
|
36172
|
+
finalSnapshotClients: ctx.options?.finalSnapshotClients,
|
|
36173
|
+
skipFinalSnapshot: ctx.options?.skipFinalSnapshot === true || ctx.destroyOptions?.skipFinalSnapshot === true,
|
|
36174
|
+
...ctx.destroyOptions?.removeProtection === true && {
|
|
36175
|
+
removeProtection: true,
|
|
36176
|
+
foreignHolder: makeForeignHolderScan(ctx.stateBackend)({
|
|
36177
|
+
stackName: childStackName,
|
|
36178
|
+
region
|
|
36179
|
+
})
|
|
36180
|
+
},
|
|
36181
|
+
importedProducerRegions: producerRegions.regions,
|
|
36182
|
+
producerRegionsIncomplete: !producerRegions.complete,
|
|
36183
|
+
nestedChildRevert: true
|
|
36184
|
+
};
|
|
36185
|
+
const childCtx = {
|
|
36186
|
+
...ctx,
|
|
36187
|
+
parentStackName: childStackName,
|
|
36188
|
+
parentRegion: region,
|
|
36189
|
+
nestedTemplates: void 0
|
|
36190
|
+
};
|
|
36191
|
+
let failures = 0;
|
|
36192
|
+
let warnings = 0;
|
|
36193
|
+
const inlinePolicyWriters = new RollbackInlinePolicyWriters();
|
|
36194
|
+
const settledBelow = /* @__PURE__ */ new Map();
|
|
36195
|
+
for (let s = segments.length - 1; s >= 0; s--) {
|
|
36196
|
+
const segment = segments[s];
|
|
36197
|
+
const skipPrefix = segment.skipPrefix ?? getCurrentSkipPrefix();
|
|
36198
|
+
const split = splitImportedOps(segment.operations, segment);
|
|
36199
|
+
const result = await withNestedStackContext(childCtx, () => withSkipPrefix(skipPrefix, () => withStackName(childStackName, () => withCreateTokenLedger(ledgerForStack(ctx.stateBackend, childStackName, region), () => withNestedRevertRun(runId, async (inner) => {
|
|
36200
|
+
const replayed = await withPrintingSecrets(journaledOrphanPrintingBag(completedReplayEntries(split.replay), stateResources), () => replayRollback(split.replay, stateResources, childStackName, execCtx, {
|
|
36201
|
+
afterOp: save,
|
|
36202
|
+
onOrphan: (record) => mintedOrphans.push(record),
|
|
36203
|
+
inlinePolicyWriters,
|
|
36204
|
+
failedOperations: segment.failedOperations
|
|
36205
|
+
}));
|
|
36206
|
+
for (const [id, below] of inner.settled) settledBelow.set(id, below);
|
|
36207
|
+
return {
|
|
36208
|
+
...replayed,
|
|
36209
|
+
warnings: replayed.warnings + inner.warnings
|
|
36210
|
+
};
|
|
36211
|
+
})))));
|
|
36212
|
+
failures += result.failures;
|
|
36213
|
+
warnings += result.warnings + split.displaced.length;
|
|
36214
|
+
recordDisplacedSkips(execCtx.recordEvent, childStackName, split.displaced);
|
|
36215
|
+
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");
|
|
36216
|
+
}
|
|
36217
|
+
restoring = failures === 0;
|
|
36218
|
+
await save();
|
|
36219
|
+
if (restoring && persisted && restoredOutputs && ctx.exportIndexStore) await ctx.exportIndexStore.updateForStack(childStackName, region, importableOutputs(nextState()));
|
|
36220
|
+
if (warnings > 0) logger.warn(safeMsg`Nested stack ${shownChild}: ${warnings} operation(s) were skipped with a warning during ` + `its revert (see above); they may need attention by hand.`);
|
|
36221
|
+
if (failures > 0) refuse(`${failures} of its operation(s) failed to revert (see the warnings above).`);
|
|
36222
|
+
if (warnings > 0) run.warnings += warnings;
|
|
36223
|
+
else run.settled.set(logicalId, settledBelow);
|
|
36224
|
+
return { warnings };
|
|
36225
|
+
} finally {
|
|
36226
|
+
await ctx.lockManager.releaseLock(childStackName, region).catch((error) => {
|
|
36227
|
+
logger.warn(safeMsg`Failed to release the lock of nested stack ${shownChild}: ${errorText(error)}`);
|
|
36228
|
+
});
|
|
36229
|
+
}
|
|
36230
|
+
}
|
|
36231
|
+
|
|
35876
36232
|
//#endregion
|
|
35877
36233
|
//#region src/deployment/rollback-executor/journaled-orphans.ts
|
|
35878
36234
|
const NONE = {
|
|
@@ -35905,6 +36261,7 @@ async function loadJournaledOrphans(stateBackend, stackName, region, rollbackOrp
|
|
|
35905
36261
|
for (const segment of segments) if (options.deployRunId !== void 0 && segment.reason === "nested-pending-parent" && segment.runId === options.deployRunId) for (const op of segment.operations) deployLogicalIds.add(op.logicalId);
|
|
35906
36262
|
const out = [];
|
|
35907
36263
|
let count = 0;
|
|
36264
|
+
const pendingRequests = segments.flatMap((segment) => segment.failedOperations ?? []).filter((op) => op.pendingCloudControlRequest !== void 0).length;
|
|
35908
36265
|
for (let s = segments.length - 1; s >= 0; s--) {
|
|
35909
36266
|
const segment = segments[s];
|
|
35910
36267
|
if (segment.reason === "nested-pending-parent") continue;
|
|
@@ -35922,7 +36279,8 @@ async function loadJournaledOrphans(stateBackend, stackName, region, rollbackOrp
|
|
|
35922
36279
|
return {
|
|
35923
36280
|
segments: out,
|
|
35924
36281
|
count,
|
|
35925
|
-
deployLogicalIds
|
|
36282
|
+
deployLogicalIds,
|
|
36283
|
+
...pendingRequests > 0 && { pendingRequests }
|
|
35926
36284
|
};
|
|
35927
36285
|
}
|
|
35928
36286
|
function journaledOrphanLines(orphans, logger) {
|
|
@@ -36038,10 +36396,24 @@ async function settleJournaledOrphansOnSuccess(args) {
|
|
|
36038
36396
|
keepJournal: true
|
|
36039
36397
|
};
|
|
36040
36398
|
}
|
|
36041
|
-
|
|
36042
|
-
|
|
36043
|
-
|
|
36399
|
+
const pendingKept = (orphans.pendingRequests ?? 0) > 0;
|
|
36400
|
+
const keepPendingOnly = async () => {
|
|
36401
|
+
try {
|
|
36402
|
+
await stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op) => op.pendingCloudControlRequest !== void 0, newerIds, () => false);
|
|
36403
|
+
return true;
|
|
36404
|
+
} catch (err) {
|
|
36405
|
+
logger.warn(safeMsg`Failed to reduce the rollback journal of stack ${stack} to its unsettled Cloud ` + safeMsg`Control requests: ${errorDetail(err)}. The whole journal is kept.`);
|
|
36406
|
+
await markSuperseded(stateBackend, stackName, region, newerIds);
|
|
36407
|
+
return false;
|
|
36408
|
+
}
|
|
36044
36409
|
};
|
|
36410
|
+
if (orphans.count === 0) {
|
|
36411
|
+
if (pendingKept) await keepPendingOnly();
|
|
36412
|
+
return {
|
|
36413
|
+
unaddressed: 0,
|
|
36414
|
+
keepJournal: pendingKept
|
|
36415
|
+
};
|
|
36416
|
+
}
|
|
36045
36417
|
const all = orphans.segments.flatMap(({ segment, ops }) => ops.map((op) => ({
|
|
36046
36418
|
segment,
|
|
36047
36419
|
op
|
|
@@ -36093,15 +36465,18 @@ async function settleJournaledOrphansOnSuccess(args) {
|
|
|
36093
36465
|
logger.warn(safeMsg`Failed to remove the settled entries from the rollback journal of stack ${stack}: ` + safeMsg`${errorDetail(err)}. A cdkd rollback or cdkd destroy could act on them again; run a ` + "successful cdkd deploy of the stack first, which settles them again.");
|
|
36094
36466
|
}
|
|
36095
36467
|
};
|
|
36096
|
-
if (kept.length === 0)
|
|
36097
|
-
|
|
36098
|
-
|
|
36099
|
-
|
|
36100
|
-
|
|
36468
|
+
if (kept.length === 0) {
|
|
36469
|
+
if (pendingKept && !await keepPendingOnly()) await stripCleared?.();
|
|
36470
|
+
return {
|
|
36471
|
+
unaddressed: skipped + leftInPlace,
|
|
36472
|
+
keepJournal: pendingKept,
|
|
36473
|
+
...stripCleared && { stripCleared }
|
|
36474
|
+
};
|
|
36475
|
+
}
|
|
36101
36476
|
const keptIds = new Set(kept.map(({ op }) => op.logicalId));
|
|
36102
36477
|
const supersededIds = newerIds.filter((id) => !keptIds.has(id));
|
|
36103
36478
|
const demoted = kept.filter(({ op }) => op.physicalIdRecoveredFromError === false);
|
|
36104
|
-
const reduce = () => stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op, segment) => isHandledOrphan(kept, segment, op), supersededIds, (op, segment) => isHandledOrphan(demoted, segment, op));
|
|
36479
|
+
const reduce = () => stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op, segment) => isHandledOrphan(kept, segment, op) || op.pendingCloudControlRequest !== void 0, supersededIds, (op, segment) => isHandledOrphan(demoted, segment, op));
|
|
36105
36480
|
let reduced = false;
|
|
36106
36481
|
for (let attempt = 0; attempt < 2 && !reduced; attempt++) try {
|
|
36107
36482
|
await reduce();
|
|
@@ -36302,342 +36677,496 @@ function sameJournaledOrphans(a, b) {
|
|
|
36302
36677
|
}
|
|
36303
36678
|
|
|
36304
36679
|
//#endregion
|
|
36305
|
-
//#region src/
|
|
36306
|
-
|
|
36307
|
-
|
|
36308
|
-
return storage$1.run(ctx, fn);
|
|
36680
|
+
//#region src/deployment/cc-pending-requests.ts
|
|
36681
|
+
function hasPendingCloudControlRequest(op) {
|
|
36682
|
+
return op.pendingCloudControlRequest !== void 0;
|
|
36309
36683
|
}
|
|
36310
|
-
function
|
|
36311
|
-
return
|
|
36684
|
+
function pendingRequestCount(journal) {
|
|
36685
|
+
return pendingRequests(journal ?? null).size;
|
|
36312
36686
|
}
|
|
36313
|
-
async function
|
|
36314
|
-
const
|
|
36315
|
-
if (
|
|
36316
|
-
|
|
36317
|
-
|
|
36318
|
-
|
|
36319
|
-
|
|
36320
|
-
|
|
36321
|
-
|
|
36322
|
-
|
|
36323
|
-
|
|
36324
|
-
|
|
36325
|
-
|
|
36687
|
+
async function resolvePendingCloudControlRequests(params) {
|
|
36688
|
+
const { journal, stackName, region } = params;
|
|
36689
|
+
if (pendingRequests(params.loaded).size === 0) return false;
|
|
36690
|
+
const settle = async () => {
|
|
36691
|
+
await params.beforeSettle?.();
|
|
36692
|
+
let current = params.loaded;
|
|
36693
|
+
if (params.underLock) try {
|
|
36694
|
+
current = await journal.loadRollbackJournal(stackName, region);
|
|
36695
|
+
} catch (error) {
|
|
36696
|
+
throw new CdkdError(safeMsg`cdkd ${params.command} of ${displayStackName(stackName)} refused: its rollback ` + "journal recorded an unsettled Cloud Control CREATE when this run started and cannot " + safeMsg`be read now (${displaySafe(describeAwsFailure(error).summary)}). Nothing was ` + "changed; re-run once it can be read.", "CC_PENDING_REQUEST_UNREADABLE");
|
|
36697
|
+
}
|
|
36698
|
+
const pending = pendingRequests(current);
|
|
36699
|
+
if (pending.size > 0) await settlePending(params, pending);
|
|
36700
|
+
return params.underLock !== void 0 || pending.size > 0;
|
|
36326
36701
|
};
|
|
36702
|
+
return params.underLock ? params.underLock(settle) : settle();
|
|
36327
36703
|
}
|
|
36328
|
-
|
|
36329
|
-
|
|
36330
|
-
|
|
36331
|
-
|
|
36332
|
-
const NESTED_STACK_TYPE$2 = "AWS::CloudFormation::Stack";
|
|
36333
|
-
const MAX_NESTED_WALK_DEPTH = 32;
|
|
36334
|
-
function nestedChildStackName(parentStackName, logicalId) {
|
|
36335
|
-
return `${parentStackName}~${logicalId}`;
|
|
36704
|
+
function pendingRequests(loaded) {
|
|
36705
|
+
const pending = /* @__PURE__ */ new Map();
|
|
36706
|
+
for (const segment of loaded?.segments ?? []) for (const op of segment.failedOperations ?? []) if (hasPendingCloudControlRequest(op)) pending.set(op.pendingCloudControlRequest.requestToken, op);
|
|
36707
|
+
return pending;
|
|
36336
36708
|
}
|
|
36337
|
-
function
|
|
36338
|
-
const
|
|
36339
|
-
|
|
36340
|
-
const
|
|
36341
|
-
|
|
36342
|
-
|
|
36343
|
-
|
|
36344
|
-
|
|
36345
|
-
|
|
36346
|
-
|
|
36347
|
-
|
|
36348
|
-
|
|
36349
|
-
|
|
36350
|
-
|
|
36351
|
-
|
|
36352
|
-
|
|
36709
|
+
async function settlePending(params, pending) {
|
|
36710
|
+
const { journal, stackName, region, command, logger } = params;
|
|
36711
|
+
const reader = params.reader();
|
|
36712
|
+
const isUnique = params.identifierUnique ?? ccIdentifierIsUnique;
|
|
36713
|
+
const stackShown = displayStackName(stackName);
|
|
36714
|
+
const settlements = /* @__PURE__ */ new Map();
|
|
36715
|
+
const unresolved = [];
|
|
36716
|
+
for (const [token, op] of pending) {
|
|
36717
|
+
const named = `${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)})`;
|
|
36718
|
+
logger.info(safeMsg`A previous run of ${stackShown} stopped waiting for the Cloud Control CREATE of ${named}; ` + "checking how it ended...");
|
|
36719
|
+
const outcome = await reader.resumeAbandonedRequest(token, op.logicalId, op.resourceType);
|
|
36720
|
+
switch (outcome.status) {
|
|
36721
|
+
case "succeeded":
|
|
36722
|
+
case "failed":
|
|
36723
|
+
case "cancelled": {
|
|
36724
|
+
const made = outcome.status === "succeeded" ? outcome.identifier : outcome.remnant;
|
|
36725
|
+
if (made === void 0) {
|
|
36726
|
+
logger.info(safeMsg`The CREATE of ${named} ${outcome.status === "cancelled" ? "was cancelled" : "failed"} ` + "in AWS and made nothing.");
|
|
36727
|
+
settlements.set(token, { kind: "drop" });
|
|
36728
|
+
break;
|
|
36729
|
+
}
|
|
36730
|
+
const madeShown = displacedPhysicalIdShown({
|
|
36731
|
+
...op,
|
|
36732
|
+
physicalId: made
|
|
36733
|
+
}, logger, made) ?? "a resource";
|
|
36734
|
+
const held = params.stateResources?.[op.logicalId];
|
|
36735
|
+
if (held !== void 0 && held.physicalId === made) {
|
|
36736
|
+
logger.info(safeMsg`The CREATE of ${named} made ${madeShown}, which state already records.`);
|
|
36737
|
+
settlements.set(token, { kind: "drop" });
|
|
36738
|
+
break;
|
|
36739
|
+
}
|
|
36740
|
+
const unique = await isUnique({
|
|
36741
|
+
resourceType: op.resourceType,
|
|
36742
|
+
identifier: made,
|
|
36743
|
+
attemptedProperties: op.attemptedProperties,
|
|
36744
|
+
logicalId: op.logicalId,
|
|
36745
|
+
stackName
|
|
36746
|
+
});
|
|
36747
|
+
const ended = outcome.status === "succeeded" ? "completed" : outcome.status === "cancelled" ? "was cancelled" : "failed";
|
|
36748
|
+
if (outcome.status === "succeeded" && unique && held === void 0 && params.resume?.(op, made)) {
|
|
36749
|
+
logger.info(safeMsg`The CREATE of ${named} completed in AWS after cdkd stopped waiting, and made ` + safeMsg`${madeShown}; this deploy's CREATE of it takes that resource over when it sends ` + "the same properties.");
|
|
36750
|
+
settlements.set(token, { kind: "resume" });
|
|
36751
|
+
break;
|
|
36752
|
+
}
|
|
36753
|
+
if (params.resume !== void 0 && !unique) logger.warn(safeMsg`The CREATE of ${named} ${ended} in AWS after cdkd stopped waiting, and made ` + safeMsg`${madeShown}. cdkd cannot prove its id is unique (it may be a name, which can ` + safeMsg`since belong to another resource), so this deploy does not take it over, and creating ${logicalIdShown(op.logicalId)} ` + "again will ask for the name it holds. Adopt it with cdkd import (--resource " + safeMsg`${logicalIdShown(op.logicalId)}=<its id>), or delete it, then re-run. It is kept in the ` + "rollback journal as a resource the failed deploy created.");
|
|
36754
|
+
else logger.warn(safeMsg`The CREATE of ${named} ${ended} in AWS after cdkd stopped waiting, and made ` + safeMsg`${madeShown}. It is now recorded in the rollback journal as a resource the failed ` + "deploy created: cdkd destroy, cdkd rollback --revert-failed and the next successful deploy delete it as its DeletionPolicy directs when cdkd can prove it is still the resource that create made, and otherwise name it in a warning for you to delete by hand.");
|
|
36755
|
+
settlements.set(token, {
|
|
36756
|
+
kind: "orphan",
|
|
36757
|
+
physicalId: made,
|
|
36758
|
+
unique
|
|
36759
|
+
});
|
|
36760
|
+
break;
|
|
36761
|
+
}
|
|
36762
|
+
case "not-found":
|
|
36763
|
+
logger.warn(safeMsg`Cloud Control no longer has the CREATE request of ${named}: requests expire after ` + "seven days, and a request is not visible from another account or region. cdkd cannot tell whether it created the resource and stops tracking the request. If it exists, adopt it with cdkd import or delete it by hand.");
|
|
36764
|
+
settlements.set(token, { kind: "drop" });
|
|
36765
|
+
break;
|
|
36766
|
+
case "unresolved": {
|
|
36767
|
+
settlements.set(token, { kind: "keep" });
|
|
36768
|
+
const reason = holdsSecretReference(op.attemptedProperties) ? "details withheld: its properties carry a secret" : displaySafe(describeAwsFailure(outcome.error).summary);
|
|
36769
|
+
unresolved.push(safeMsg` - ${named}${reason === "" ? "" : ` (${reason})`}\n` + ` Check it with: ${await reader.buildResumeCommand(token)}`);
|
|
36770
|
+
break;
|
|
36771
|
+
}
|
|
36353
36772
|
}
|
|
36354
|
-
};
|
|
36355
|
-
}
|
|
36356
|
-
function displacedPhysicalIdShown(op, logger, physicalId = journalOpPhysicalId(op)) {
|
|
36357
|
-
if (physicalId === void 0) return void 0;
|
|
36358
|
-
const masker = createOpMasker(logger, /* @__PURE__ */ new Map());
|
|
36359
|
-
for (const properties of [
|
|
36360
|
-
op.properties,
|
|
36361
|
-
op.attemptedProperties,
|
|
36362
|
-
op.previousState?.properties
|
|
36363
|
-
]) {
|
|
36364
|
-
if (properties === void 0) continue;
|
|
36365
|
-
masker.addNamed({
|
|
36366
|
-
resourceType: op.resourceType,
|
|
36367
|
-
properties,
|
|
36368
|
-
logicalId: op.logicalId,
|
|
36369
|
-
physicalIds: [physicalId]
|
|
36370
|
-
});
|
|
36371
36773
|
}
|
|
36372
|
-
|
|
36774
|
+
if ([...settlements.values()].some((s) => s.kind === "orphan" || s.kind === "drop")) await journal.rewriteRollbackJournalFailedOperations(stackName, region, (op) => {
|
|
36775
|
+
if (!hasPendingCloudControlRequest(op)) return op;
|
|
36776
|
+
const settlement = settlements.get(op.pendingCloudControlRequest.requestToken);
|
|
36777
|
+
if (settlement?.kind === "drop") return withoutPendingRequest(op);
|
|
36778
|
+
if (settlement?.kind !== "orphan") return op;
|
|
36779
|
+
return {
|
|
36780
|
+
...withoutPendingRequest(op),
|
|
36781
|
+
provisionedBy: "cc-api",
|
|
36782
|
+
physicalId: settlement.physicalId,
|
|
36783
|
+
physicalIdRecoveredFromError: true,
|
|
36784
|
+
...settlement.unique && { createdIdentifierUnique: true }
|
|
36785
|
+
};
|
|
36786
|
+
});
|
|
36787
|
+
if (unresolved.length > 0) {
|
|
36788
|
+
const kept = [...pending.values()].filter((op) => settlements.get(op.pendingCloudControlRequest.requestToken)?.kind === "keep");
|
|
36789
|
+
const drop = dropFailedCommands(stackName, region, kept.map((op) => op.logicalId));
|
|
36790
|
+
const withheld = drop?.commands.some((c) => c.includes("<")) === true;
|
|
36791
|
+
throw new CdkdError(safeMsg`cdkd ${command} of ${stackShown} refused: a previous run stopped waiting for a Cloud ` + `Control CREATE, and cdkd still cannot tell whether it made its resource. Proceeding could leave that resource untracked. Nothing was changed.
|
|
36792
|
+
${unresolved.join("\n")}\nRe-run once the request has finished and can be read. If you have reconciled it by hand (cdkd import, or deleted the resource), drop its journal entry with:` + (drop === void 0 ? "" : drop.commands.map((c) => `\n ${c}`).join("")) + (withheld ? "\nA value that is not a plain identifier is shown as a <hole>; read it from the stack's state record and rollback-journal.json." : ""), "CC_PENDING_REQUEST_UNRESOLVED");
|
|
36793
|
+
}
|
|
36794
|
+
}
|
|
36795
|
+
function holdsSecretReference(properties) {
|
|
36796
|
+
if (properties === void 0) return false;
|
|
36797
|
+
return carriesSecretMask(properties) || JSON.stringify(properties).includes("{{resolve:");
|
|
36798
|
+
}
|
|
36799
|
+
const ccIdentifierIsUnique = async ({ resourceType, identifier, attemptedProperties, logicalId, stackName }) => {
|
|
36800
|
+
if (attemptedProperties === void 0 || holdsSecretReference(attemptedProperties)) return false;
|
|
36801
|
+
const [fields, readOnly] = await Promise.all([getPrimaryIdentifierFields(resourceType), getTopLevelReadOnlyProperties(resourceType)]);
|
|
36802
|
+
if (fields === void 0 || readOnly === void 0) return false;
|
|
36803
|
+
const parts = identifier.split("|");
|
|
36804
|
+
if (parts.length !== fields.length) return false;
|
|
36805
|
+
const sent = /* @__PURE__ */ new Set();
|
|
36806
|
+
const collect = (value) => {
|
|
36807
|
+
if (typeof value === "string" || typeof value === "number") for (const piece of nameSegments(String(value))) sent.add(piece);
|
|
36808
|
+
else if (Array.isArray(value)) value.forEach(collect);
|
|
36809
|
+
else if (value !== null && typeof value === "object") Object.values(value).forEach(collect);
|
|
36810
|
+
};
|
|
36811
|
+
collect(attemptedProperties);
|
|
36812
|
+
return parts.some((part, i) => {
|
|
36813
|
+
if (part === "" || !readOnly.has(fields[i])) return false;
|
|
36814
|
+
return !nameSegments(part).some((segment) => sent.has(segment) || looksLikeCdkdGeneratedName(segment, logicalId, stackName));
|
|
36815
|
+
});
|
|
36816
|
+
};
|
|
36817
|
+
function nameSegments(value) {
|
|
36818
|
+
const text = value.toLowerCase();
|
|
36819
|
+
const arn = /^arn:[^:]*:[^:]*:[^:]*:[^:]*:(.*)$/.exec(text);
|
|
36820
|
+
const body = arn ? arn[1] : text;
|
|
36821
|
+
return [
|
|
36822
|
+
text,
|
|
36823
|
+
body,
|
|
36824
|
+
...body.split(/[:/]/)
|
|
36825
|
+
].filter((piece) => piece !== "");
|
|
36373
36826
|
}
|
|
36374
|
-
function
|
|
36375
|
-
const
|
|
36376
|
-
|
|
36377
|
-
const shownOld = displacedPhysicalIdShown(op, logger, retainedOld);
|
|
36378
|
-
return `replaced ${shownOld} ${op.oldResourceRetained === true ? "but kept it (UpdateReplacePolicy: Retain)" : op.oldResourceMaySurvive !== void 0 ? "and may have kept it (its delete was not confirmed)" : "and may have kept it (the journal records no verdict)"}; cdkd import adopted the replacement, so ${shownOld} is left untracked`;
|
|
36379
|
-
}
|
|
36380
|
-
const shownId = displacedPhysicalIdShown(op, logger);
|
|
36381
|
-
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";
|
|
36827
|
+
function withoutPendingRequest(op) {
|
|
36828
|
+
const { pendingCloudControlRequest: _settled, ...rest } = op;
|
|
36829
|
+
return rest;
|
|
36382
36830
|
}
|
|
36383
|
-
|
|
36384
|
-
|
|
36385
|
-
|
|
36386
|
-
|
|
36387
|
-
|
|
36388
|
-
|
|
36389
|
-
|
|
36390
|
-
|
|
36391
|
-
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"
|
|
36392
|
-
});
|
|
36831
|
+
|
|
36832
|
+
//#endregion
|
|
36833
|
+
//#region src/state/deployment-events-store.ts
|
|
36834
|
+
const DEPLOYMENT_EVENTS_MAX_INDEX_RUNS = 20;
|
|
36835
|
+
const FLUSH_INTERVAL_MS = 2e3;
|
|
36836
|
+
const FLUSH_EVENT_THRESHOLD = 50;
|
|
36837
|
+
function newDeploymentRunId(now = /* @__PURE__ */ new Date()) {
|
|
36838
|
+
return `${now.toISOString().replace(/[-:.]/g, "")}-${randomUUID().slice(0, 8)}`;
|
|
36393
36839
|
}
|
|
36394
|
-
function
|
|
36395
|
-
return
|
|
36840
|
+
function deploymentEventsKey(prefix, stackName, region, runId) {
|
|
36841
|
+
return `${prefix}/${stackName}/${region}/deployments/${runId}.jsonl`;
|
|
36396
36842
|
}
|
|
36397
|
-
|
|
36398
|
-
|
|
36399
|
-
const run = {
|
|
36400
|
-
runId,
|
|
36401
|
-
settled: /* @__PURE__ */ new Map(),
|
|
36402
|
-
warnings: 0
|
|
36403
|
-
};
|
|
36404
|
-
return revertRunStorage.run(run, () => fn(run));
|
|
36843
|
+
function deploymentEventsIndexKey(prefix, stackName, region) {
|
|
36844
|
+
return `${prefix}/${stackName}/${region}/deployments/index.json`;
|
|
36405
36845
|
}
|
|
36406
|
-
function
|
|
36407
|
-
return
|
|
36846
|
+
function deploymentsDirPrefix(prefix, stackName, region) {
|
|
36847
|
+
return `${prefix}/${stackName}/${region}/deployments/`;
|
|
36408
36848
|
}
|
|
36409
|
-
|
|
36410
|
-
|
|
36849
|
+
const DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION = "deployment-event streams and their index, whose recorded error messages can quote values the secret mask does not catch";
|
|
36850
|
+
async function deleteAndPurgeEventObjects(backend, keys, dirPrefix, scope = "deleted-keys") {
|
|
36851
|
+
if (keys.length === 0) return void 0;
|
|
36852
|
+
let swept;
|
|
36853
|
+
try {
|
|
36854
|
+
await backend.deleteRawObjects(keys);
|
|
36855
|
+
} finally {
|
|
36856
|
+
if (scope === "whole-dir") swept = await backend.purgeNoncurrentVersionsUnderPrefix(dirPrefix, { objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION });
|
|
36857
|
+
else await backend.purgeNoncurrentVersions(keys, {
|
|
36858
|
+
...keys.length > 1 && { listPrefix: dirPrefix },
|
|
36859
|
+
objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION
|
|
36860
|
+
});
|
|
36861
|
+
}
|
|
36862
|
+
return swept;
|
|
36411
36863
|
}
|
|
36412
|
-
function
|
|
36413
|
-
|
|
36864
|
+
function runIdTimestampMs(runId) {
|
|
36865
|
+
const m = /^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})Z/.exec(runId);
|
|
36866
|
+
if (!m) return null;
|
|
36867
|
+
const iso = `${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}.${m[7]}Z`;
|
|
36868
|
+
const ms = Date.parse(iso);
|
|
36869
|
+
return Number.isNaN(ms) ? null : ms;
|
|
36414
36870
|
}
|
|
36415
|
-
|
|
36416
|
-
|
|
36417
|
-
|
|
36418
|
-
|
|
36419
|
-
|
|
36420
|
-
|
|
36421
|
-
|
|
36422
|
-
|
|
36871
|
+
function runIdFromJsonlKey(key, dirPrefix) {
|
|
36872
|
+
if (!key.startsWith(dirPrefix) || !key.endsWith(".jsonl")) return null;
|
|
36873
|
+
return key.slice(dirPrefix.length, -6);
|
|
36874
|
+
}
|
|
36875
|
+
var DeploymentEventsStore = class {
|
|
36876
|
+
logger = getLogger().child("DeploymentEvents");
|
|
36877
|
+
backend;
|
|
36878
|
+
stackName;
|
|
36879
|
+
region;
|
|
36880
|
+
command;
|
|
36881
|
+
runId;
|
|
36882
|
+
cdkdVersion;
|
|
36883
|
+
startedAt;
|
|
36884
|
+
events = [];
|
|
36885
|
+
persistedCount = 0;
|
|
36886
|
+
flushTimer;
|
|
36887
|
+
writeChain = Promise.resolve();
|
|
36888
|
+
warnedOnce = false;
|
|
36889
|
+
finalized = false;
|
|
36890
|
+
constructor(backend, options) {
|
|
36891
|
+
this.backend = backend;
|
|
36892
|
+
this.stackName = options.stackName;
|
|
36893
|
+
this.region = options.region;
|
|
36894
|
+
this.command = options.command;
|
|
36895
|
+
this.runId = options.runId ?? newDeploymentRunId();
|
|
36896
|
+
this.cdkdVersion = options.cdkdVersion ?? getCdkdVersion();
|
|
36897
|
+
this.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
36898
|
+
}
|
|
36899
|
+
record(event) {
|
|
36423
36900
|
try {
|
|
36424
|
-
|
|
36425
|
-
|
|
36426
|
-
|
|
36427
|
-
|
|
36428
|
-
resources: data.state.resources,
|
|
36429
|
-
depth: depth + 1
|
|
36901
|
+
if (this.finalized) return;
|
|
36902
|
+
this.events.push({
|
|
36903
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
36904
|
+
...event
|
|
36430
36905
|
});
|
|
36431
|
-
|
|
36432
|
-
|
|
36906
|
+
if (this.events.length - this.persistedCount >= FLUSH_EVENT_THRESHOLD) this.scheduleFlush(0);
|
|
36907
|
+
else this.scheduleFlush(FLUSH_INTERVAL_MS);
|
|
36908
|
+
} catch {}
|
|
36909
|
+
}
|
|
36910
|
+
async finalize(result) {
|
|
36911
|
+
if (this.finalized) return;
|
|
36912
|
+
this.finalized = true;
|
|
36913
|
+
if (this.flushTimer) {
|
|
36914
|
+
clearTimeout(this.flushTimer);
|
|
36915
|
+
this.flushTimer = void 0;
|
|
36433
36916
|
}
|
|
36434
|
-
|
|
36435
|
-
|
|
36436
|
-
|
|
36437
|
-
|
|
36438
|
-
|
|
36439
|
-
|
|
36440
|
-
|
|
36441
|
-
|
|
36442
|
-
|
|
36443
|
-
|
|
36444
|
-
|
|
36445
|
-
|
|
36446
|
-
|
|
36447
|
-
|
|
36448
|
-
|
|
36449
|
-
|
|
36450
|
-
|
|
36451
|
-
|
|
36452
|
-
|
|
36453
|
-
|
|
36917
|
+
if (this.events.length === 0) return;
|
|
36918
|
+
await this.enqueueWrite(async () => {
|
|
36919
|
+
const indexRead = this.readIndexRuns();
|
|
36920
|
+
indexRead.catch(() => {});
|
|
36921
|
+
await this.doFlush();
|
|
36922
|
+
await this.writeIndexAndPrune(result, await indexRead);
|
|
36923
|
+
});
|
|
36924
|
+
}
|
|
36925
|
+
async writeIndexAndPrune(result, existingRuns) {
|
|
36926
|
+
const { key, file, runs } = this.buildIndexUpdate(result, existingRuns);
|
|
36927
|
+
const keptRunIds = runs.map((r) => r.runId);
|
|
36928
|
+
const willPrune = keptRunIds.length >= 20;
|
|
36929
|
+
const dirPrefix = deploymentsDirPrefix(this.backend.prefix, this.stackName, this.region);
|
|
36930
|
+
const staleKeysRead = willPrune ? this.backend.listRawKeys(dirPrefix) : void 0;
|
|
36931
|
+
staleKeysRead?.catch(() => {});
|
|
36932
|
+
await this.backend.putRawObject(key, JSON.stringify(file, null, 2));
|
|
36933
|
+
if (!staleKeysRead) return;
|
|
36934
|
+
await this.pruneSupersededRunFiles(keptRunIds, dirPrefix, await staleKeysRead);
|
|
36935
|
+
}
|
|
36936
|
+
async drain() {
|
|
36937
|
+
await this.writeChain;
|
|
36938
|
+
}
|
|
36939
|
+
scheduleFlush(delayMs) {
|
|
36940
|
+
if (this.flushTimer) {
|
|
36941
|
+
if (delayMs > 0) return;
|
|
36942
|
+
clearTimeout(this.flushTimer);
|
|
36454
36943
|
}
|
|
36944
|
+
this.flushTimer = setTimeout(() => {
|
|
36945
|
+
this.flushTimer = void 0;
|
|
36946
|
+
this.enqueueWrite(() => this.doFlush());
|
|
36947
|
+
}, delayMs);
|
|
36948
|
+
this.flushTimer.unref?.();
|
|
36455
36949
|
}
|
|
36456
|
-
|
|
36457
|
-
|
|
36458
|
-
|
|
36459
|
-
const data = await stateBackend.getState(child, region);
|
|
36460
|
-
if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) return data.state;
|
|
36461
|
-
} catch {}
|
|
36462
|
-
}
|
|
36463
|
-
async function dropSettledNestedJournals(args) {
|
|
36464
|
-
const { stateBackend, parentStackName, region, runId, logger } = args;
|
|
36465
|
-
const depth = args.depth ?? 0;
|
|
36466
|
-
if (runId === void 0) return;
|
|
36467
|
-
if (depthExceeded(depth, parentStackName, logger)) return;
|
|
36468
|
-
const isSettled = (segment) => segment.runId === runId && segment.reason === "nested-pending-parent";
|
|
36469
|
-
for (const [logicalId, grandchildren] of args.settled) {
|
|
36470
|
-
const child = nestedChildStackName(parentStackName, logicalId);
|
|
36471
|
-
if (grandchildren.size > 0) await dropSettledNestedJournals({
|
|
36472
|
-
...args,
|
|
36473
|
-
parentStackName: child,
|
|
36474
|
-
settled: grandchildren,
|
|
36475
|
-
depth: depth + 1
|
|
36950
|
+
enqueueWrite(op) {
|
|
36951
|
+
const next = this.writeChain.then(op).catch((err) => {
|
|
36952
|
+
this.warnOnce(`Failed to persist deployment events for run ${this.runId}: ${describeAwsFailure(err).detail}`);
|
|
36476
36953
|
});
|
|
36954
|
+
this.writeChain = next;
|
|
36955
|
+
return next;
|
|
36956
|
+
}
|
|
36957
|
+
async doFlush() {
|
|
36958
|
+
if (this.events.length === 0 || this.events.length === this.persistedCount) return;
|
|
36959
|
+
const snapshotCount = this.events.length;
|
|
36960
|
+
const body = this.events.slice(0, snapshotCount).map((e) => JSON.stringify(e)).join("\n");
|
|
36961
|
+
await this.backend.putRawObject(deploymentEventsKey(this.backend.prefix, this.stackName, this.region, this.runId), body + "\n", "application/x-ndjson");
|
|
36962
|
+
this.persistedCount = snapshotCount;
|
|
36963
|
+
}
|
|
36964
|
+
async readIndexRuns() {
|
|
36965
|
+
const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
|
|
36477
36966
|
try {
|
|
36478
|
-
const
|
|
36479
|
-
if (
|
|
36480
|
-
|
|
36481
|
-
|
|
36967
|
+
const raw = await this.backend.getRawObject(key);
|
|
36968
|
+
if (raw !== null) {
|
|
36969
|
+
const parsed = JSON.parse(raw);
|
|
36970
|
+
if (Array.isArray(parsed.runs)) return parsed.runs;
|
|
36971
|
+
}
|
|
36972
|
+
} catch (err) {
|
|
36973
|
+
this.logger.debug(`Deployment-events index unreadable, rewriting: ${describeAwsFailure(err).detail}`);
|
|
36482
36974
|
}
|
|
36975
|
+
return [];
|
|
36483
36976
|
}
|
|
36484
|
-
|
|
36485
|
-
|
|
36486
|
-
|
|
36487
|
-
|
|
36488
|
-
|
|
36489
|
-
|
|
36490
|
-
|
|
36491
|
-
|
|
36977
|
+
buildIndexUpdate(result, existingRuns) {
|
|
36978
|
+
const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
|
|
36979
|
+
const runs = [{
|
|
36980
|
+
runId: this.runId,
|
|
36981
|
+
command: this.command,
|
|
36982
|
+
cdkdVersion: this.cdkdVersion,
|
|
36983
|
+
startedAt: this.startedAt,
|
|
36984
|
+
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
36985
|
+
result,
|
|
36986
|
+
eventCount: this.persistedCount
|
|
36987
|
+
}, ...existingRuns.filter((r) => r.runId !== this.runId)].slice(0, 20);
|
|
36988
|
+
return {
|
|
36989
|
+
key,
|
|
36990
|
+
file: {
|
|
36991
|
+
indexVersion: 1,
|
|
36992
|
+
stackName: this.stackName,
|
|
36993
|
+
region: this.region,
|
|
36994
|
+
runs,
|
|
36995
|
+
lastModified: Date.now()
|
|
36996
|
+
},
|
|
36997
|
+
runs
|
|
36998
|
+
};
|
|
36999
|
+
}
|
|
37000
|
+
async pruneSupersededRunFiles(keptRunIds, dirPrefix, keys) {
|
|
37001
|
+
if (keptRunIds.length < 20) return;
|
|
37002
|
+
const cutoff = keptRunIds.reduce((min, id) => id < min ? id : min, keptRunIds[0]);
|
|
37003
|
+
const stale = keys.filter((k) => {
|
|
37004
|
+
const runId = runIdFromJsonlKey(k, dirPrefix);
|
|
37005
|
+
return runId !== null && runId < cutoff;
|
|
36492
37006
|
});
|
|
37007
|
+
if (stale.length === 0) return;
|
|
37008
|
+
await deleteAndPurgeEventObjects(this.backend, stale, dirPrefix);
|
|
37009
|
+
this.logger.debug(`Pruned ${stale.length} superseded deployment-event stream(s) for ${this.stackName} (${this.region})`);
|
|
36493
37010
|
}
|
|
36494
|
-
|
|
36495
|
-
|
|
36496
|
-
|
|
36497
|
-
|
|
36498
|
-
|
|
36499
|
-
|
|
36500
|
-
|
|
36501
|
-
|
|
36502
|
-
}
|
|
36503
|
-
|
|
36504
|
-
|
|
36505
|
-
|
|
36506
|
-
|
|
36507
|
-
|
|
36508
|
-
|
|
36509
|
-
|
|
36510
|
-
|
|
36511
|
-
|
|
36512
|
-
|
|
36513
|
-
|
|
36514
|
-
|
|
36515
|
-
|
|
36516
|
-
|
|
36517
|
-
|
|
36518
|
-
|
|
36519
|
-
|
|
36520
|
-
|
|
37011
|
+
warnOnce(message) {
|
|
37012
|
+
if (this.warnedOnce) {
|
|
37013
|
+
this.logger.debug(message);
|
|
37014
|
+
return;
|
|
37015
|
+
}
|
|
37016
|
+
this.warnedOnce = true;
|
|
37017
|
+
this.logger.warn(`${message} — continuing; deployment events are best-effort and never block the run.`);
|
|
37018
|
+
}
|
|
37019
|
+
};
|
|
37020
|
+
var DeploymentEventsReader = class {
|
|
37021
|
+
backend;
|
|
37022
|
+
constructor(backend) {
|
|
37023
|
+
this.backend = backend;
|
|
37024
|
+
}
|
|
37025
|
+
async listRegions(stackName) {
|
|
37026
|
+
const prefix = `${this.backend.prefix}/${stackName}/`;
|
|
37027
|
+
const keys = await this.backend.listRawKeys(prefix);
|
|
37028
|
+
const regions = /* @__PURE__ */ new Set();
|
|
37029
|
+
for (const key of keys) {
|
|
37030
|
+
const segments = key.slice(prefix.length).split("/");
|
|
37031
|
+
if (segments.length === 3 && segments[1] === "deployments" && segments[0]) regions.add(segments[0]);
|
|
37032
|
+
}
|
|
37033
|
+
return [...regions].sort();
|
|
37034
|
+
}
|
|
37035
|
+
async listRuns(stackName, region) {
|
|
37036
|
+
const key = deploymentEventsIndexKey(this.backend.prefix, stackName, region);
|
|
37037
|
+
try {
|
|
37038
|
+
const raw = await this.backend.getRawObject(key);
|
|
37039
|
+
if (raw !== null) {
|
|
37040
|
+
const parsed = JSON.parse(raw);
|
|
37041
|
+
if (Array.isArray(parsed.runs)) return parsed.runs;
|
|
37042
|
+
}
|
|
37043
|
+
} catch {}
|
|
37044
|
+
const dirPrefix = `${this.backend.prefix}/${stackName}/${region}/deployments/`;
|
|
37045
|
+
const runIds = (await this.backend.listRawKeys(dirPrefix)).filter((k) => k.endsWith(".jsonl")).map((k) => k.slice(dirPrefix.length, -6)).sort().reverse();
|
|
37046
|
+
return Promise.all(runIds.map((runId) => this.summarizeRunFromJsonl(stackName, region, runId)));
|
|
37047
|
+
}
|
|
37048
|
+
async summarizeRunFromJsonl(stackName, region, runId) {
|
|
37049
|
+
const fallback = {
|
|
37050
|
+
runId,
|
|
37051
|
+
command: "deploy",
|
|
37052
|
+
cdkdVersion: "unknown",
|
|
37053
|
+
startedAt: "",
|
|
37054
|
+
finishedAt: "",
|
|
37055
|
+
result: "UNKNOWN",
|
|
37056
|
+
eventCount: 0
|
|
36521
37057
|
};
|
|
36522
|
-
|
|
36523
|
-
|
|
36524
|
-
|
|
36525
|
-
|
|
36526
|
-
|
|
36527
|
-
|
|
36528
|
-
|
|
36529
|
-
const
|
|
36530
|
-
|
|
36531
|
-
|
|
36532
|
-
|
|
36533
|
-
|
|
36534
|
-
|
|
36535
|
-
|
|
36536
|
-
|
|
36537
|
-
|
|
36538
|
-
|
|
36539
|
-
|
|
36540
|
-
...orphansAfterRollback(base, mintedOrphans),
|
|
36541
|
-
...restoring && restoredOutputs && { outputs: { ...restoredOutputs.outputs } },
|
|
36542
|
-
...restoring && restoredReads && {
|
|
36543
|
-
...restoredReads.imports && { imports: [...restoredReads.imports] },
|
|
36544
|
-
...restoredReads.outputReads && { outputReads: [...restoredReads.outputReads] }
|
|
36545
|
-
},
|
|
36546
|
-
...restoring && restoredOutputs?.exportNames && { exportNames: [...restoredOutputs.exportNames] },
|
|
36547
|
-
lastModified: Date.now()
|
|
36548
|
-
});
|
|
36549
|
-
const nextState = () => {
|
|
36550
|
-
const state = next();
|
|
36551
|
-
if (!restoring) return state;
|
|
36552
|
-
if (restoredOutputs && !restoredOutputs.exportNames) delete state.exportNames;
|
|
36553
|
-
if (restoredOutputs) delete state.outputReferenceProvenance;
|
|
36554
|
-
if (restoredReads && !restoredReads.imports) delete state.imports;
|
|
36555
|
-
if (restoredReads && !restoredReads.outputReads) delete state.outputReads;
|
|
36556
|
-
return state;
|
|
37058
|
+
let events = null;
|
|
37059
|
+
try {
|
|
37060
|
+
events = await this.readRunEvents(stackName, region, runId);
|
|
37061
|
+
} catch {
|
|
37062
|
+
return fallback;
|
|
37063
|
+
}
|
|
37064
|
+
if (events === null || events.length === 0) return fallback;
|
|
37065
|
+
const started = events.find((e) => e.eventType === "RUN_STARTED");
|
|
37066
|
+
let finished;
|
|
37067
|
+
for (const e of events) if (e.eventType === "RUN_FINISHED") finished = e;
|
|
37068
|
+
return {
|
|
37069
|
+
runId,
|
|
37070
|
+
command: started?.command ?? fallback.command,
|
|
37071
|
+
cdkdVersion: started?.cdkdVersion ?? fallback.cdkdVersion,
|
|
37072
|
+
startedAt: started?.timestamp ?? fallback.startedAt,
|
|
37073
|
+
finishedAt: finished?.timestamp ?? fallback.finishedAt,
|
|
37074
|
+
result: finished?.result ?? "UNKNOWN",
|
|
37075
|
+
eventCount: events.length
|
|
36557
37076
|
};
|
|
36558
|
-
|
|
36559
|
-
|
|
37077
|
+
}
|
|
37078
|
+
async readRunEvents(stackName, region, runId) {
|
|
37079
|
+
const key = deploymentEventsKey(this.backend.prefix, stackName, region, runId);
|
|
37080
|
+
const raw = await this.backend.getRawObject(key);
|
|
37081
|
+
if (raw === null) return null;
|
|
37082
|
+
const events = [];
|
|
37083
|
+
for (const line of raw.split("\n")) {
|
|
37084
|
+
const trimmed = line.trim();
|
|
37085
|
+
if (!trimmed) continue;
|
|
36560
37086
|
try {
|
|
36561
|
-
|
|
36562
|
-
|
|
36563
|
-
|
|
36564
|
-
|
|
36565
|
-
|
|
36566
|
-
|
|
36567
|
-
|
|
36568
|
-
|
|
36569
|
-
|
|
36570
|
-
|
|
36571
|
-
|
|
36572
|
-
|
|
36573
|
-
|
|
36574
|
-
|
|
36575
|
-
|
|
36576
|
-
|
|
36577
|
-
|
|
36578
|
-
|
|
36579
|
-
|
|
36580
|
-
|
|
36581
|
-
|
|
36582
|
-
|
|
36583
|
-
|
|
36584
|
-
|
|
36585
|
-
|
|
36586
|
-
|
|
36587
|
-
|
|
36588
|
-
|
|
36589
|
-
|
|
36590
|
-
|
|
36591
|
-
|
|
36592
|
-
|
|
36593
|
-
|
|
37087
|
+
events.push(JSON.parse(trimmed));
|
|
37088
|
+
} catch {}
|
|
37089
|
+
}
|
|
37090
|
+
return events;
|
|
37091
|
+
}
|
|
37092
|
+
async pruneRuns(stackName, region, opts = {}) {
|
|
37093
|
+
const dirPrefix = deploymentsDirPrefix(this.backend.prefix, stackName, region);
|
|
37094
|
+
const keys = await this.backend.listRawKeys(dirPrefix);
|
|
37095
|
+
const runIdsDesc = keys.map((k) => runIdFromJsonlKey(k, dirPrefix)).filter((id) => id !== null).sort().reverse();
|
|
37096
|
+
const indexKey = deploymentEventsIndexKey(this.backend.prefix, stackName, region);
|
|
37097
|
+
const indexExisted = keys.includes(indexKey);
|
|
37098
|
+
if (opts.all === true) {
|
|
37099
|
+
const toDelete = runIdsDesc.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
|
|
37100
|
+
const earlierVersions = await deleteAndPurgeEventObjects(this.backend, [...toDelete, indexKey], dirPrefix, "whole-dir");
|
|
37101
|
+
return {
|
|
37102
|
+
deletedRunIds: runIdsDesc,
|
|
37103
|
+
remainingRunIds: [],
|
|
37104
|
+
indexDeleted: indexExisted,
|
|
37105
|
+
...earlierVersions !== void 0 && { earlierVersions }
|
|
37106
|
+
};
|
|
37107
|
+
}
|
|
37108
|
+
const noGuards = opts.keep === void 0 && opts.olderThanMs === void 0;
|
|
37109
|
+
const keep = opts.keep ?? (noGuards ? 20 : void 0);
|
|
37110
|
+
const protectedByCount = keep === void 0 ? /* @__PURE__ */ new Set() : new Set(runIdsDesc.slice(0, keep));
|
|
37111
|
+
let candidates = runIdsDesc.filter((id) => !protectedByCount.has(id));
|
|
37112
|
+
if (opts.olderThanMs !== void 0) {
|
|
37113
|
+
const cutoff = (opts.now ?? /* @__PURE__ */ new Date()).getTime() - opts.olderThanMs;
|
|
37114
|
+
candidates = candidates.filter((id) => {
|
|
37115
|
+
const t = runIdTimestampMs(id);
|
|
37116
|
+
return t !== null && t < cutoff;
|
|
37117
|
+
});
|
|
37118
|
+
}
|
|
37119
|
+
if (candidates.length === 0) return {
|
|
37120
|
+
deletedRunIds: [],
|
|
37121
|
+
remainingRunIds: runIdsDesc,
|
|
37122
|
+
indexDeleted: false
|
|
36594
37123
|
};
|
|
36595
|
-
const
|
|
36596
|
-
|
|
36597
|
-
|
|
36598
|
-
|
|
36599
|
-
|
|
37124
|
+
const deletedSet = new Set(candidates);
|
|
37125
|
+
const deleteKeys = candidates.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
|
|
37126
|
+
const remainingRunIds = runIdsDesc.filter((id) => !deletedSet.has(id));
|
|
37127
|
+
if (remainingRunIds.length === 0) {
|
|
37128
|
+
await deleteAndPurgeEventObjects(this.backend, [...deleteKeys, indexKey], dirPrefix);
|
|
37129
|
+
return {
|
|
37130
|
+
deletedRunIds: candidates,
|
|
37131
|
+
remainingRunIds,
|
|
37132
|
+
indexDeleted: indexExisted
|
|
37133
|
+
};
|
|
37134
|
+
}
|
|
37135
|
+
await this.rewriteIndexAfterPrune(indexKey, stackName, region, deletedSet);
|
|
37136
|
+
await deleteAndPurgeEventObjects(this.backend, deleteKeys, dirPrefix);
|
|
37137
|
+
return {
|
|
37138
|
+
deletedRunIds: candidates,
|
|
37139
|
+
remainingRunIds,
|
|
37140
|
+
indexDeleted: false
|
|
36600
37141
|
};
|
|
36601
|
-
|
|
36602
|
-
|
|
36603
|
-
|
|
36604
|
-
|
|
36605
|
-
|
|
36606
|
-
|
|
36607
|
-
|
|
36608
|
-
const split = splitImportedOps(segment.operations, segment);
|
|
36609
|
-
const result = await withNestedStackContext(childCtx, () => withSkipPrefix(skipPrefix, () => withStackName(childStackName, () => withCreateTokenLedger(ledgerForStack(ctx.stateBackend, childStackName, region), () => withNestedRevertRun(runId, async (inner) => {
|
|
36610
|
-
const replayed = await withPrintingSecrets(journaledOrphanPrintingBag(completedReplayEntries(split.replay), stateResources), () => replayRollback(split.replay, stateResources, childStackName, execCtx, {
|
|
36611
|
-
afterOp: save,
|
|
36612
|
-
onOrphan: (record) => mintedOrphans.push(record),
|
|
36613
|
-
inlinePolicyWriters,
|
|
36614
|
-
failedOperations: segment.failedOperations
|
|
36615
|
-
}));
|
|
36616
|
-
for (const [id, below] of inner.settled) settledBelow.set(id, below);
|
|
36617
|
-
return {
|
|
36618
|
-
...replayed,
|
|
36619
|
-
warnings: replayed.warnings + inner.warnings
|
|
36620
|
-
};
|
|
36621
|
-
})))));
|
|
36622
|
-
failures += result.failures;
|
|
36623
|
-
warnings += result.warnings + split.displaced.length;
|
|
36624
|
-
recordDisplacedSkips(execCtx.recordEvent, childStackName, split.displaced);
|
|
36625
|
-
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");
|
|
37142
|
+
}
|
|
37143
|
+
async rewriteIndexAfterPrune(indexKey, stackName, region, deletedRunIds) {
|
|
37144
|
+
let raw;
|
|
37145
|
+
try {
|
|
37146
|
+
raw = await this.backend.getRawObject(indexKey);
|
|
37147
|
+
} catch {
|
|
37148
|
+
return;
|
|
36626
37149
|
}
|
|
36627
|
-
|
|
36628
|
-
|
|
36629
|
-
|
|
36630
|
-
|
|
36631
|
-
|
|
36632
|
-
|
|
36633
|
-
|
|
36634
|
-
|
|
36635
|
-
|
|
36636
|
-
|
|
36637
|
-
|
|
36638
|
-
|
|
37150
|
+
if (raw === null) return;
|
|
37151
|
+
let parsed;
|
|
37152
|
+
try {
|
|
37153
|
+
parsed = JSON.parse(raw);
|
|
37154
|
+
} catch {
|
|
37155
|
+
return;
|
|
37156
|
+
}
|
|
37157
|
+
if (!Array.isArray(parsed.runs)) return;
|
|
37158
|
+
const remaining = parsed.runs.filter((r) => !deletedRunIds.has(r.runId));
|
|
37159
|
+
if (remaining.length === parsed.runs.length) return;
|
|
37160
|
+
const file = {
|
|
37161
|
+
indexVersion: 1,
|
|
37162
|
+
stackName,
|
|
37163
|
+
region,
|
|
37164
|
+
runs: remaining,
|
|
37165
|
+
lastModified: Date.now()
|
|
37166
|
+
};
|
|
37167
|
+
await this.backend.putRawObject(indexKey, JSON.stringify(file, null, 2));
|
|
36639
37168
|
}
|
|
36640
|
-
}
|
|
37169
|
+
};
|
|
36641
37170
|
|
|
36642
37171
|
//#endregion
|
|
36643
37172
|
//#region src/deployment/orphan-adoption.ts
|
|
@@ -36943,6 +37472,7 @@ async function settleJournalAfterSuccess(stackName, completedOperations, previou
|
|
|
36943
37472
|
const deployRunId = this.options.eventRecorder?.runId;
|
|
36944
37473
|
const stripOnFailure = /* @__PURE__ */ new Map();
|
|
36945
37474
|
const [ownLeft] = await Promise.all([(async () => {
|
|
37475
|
+
await orphanUntakenResumes.call(this, stackName, finalResources);
|
|
36946
37476
|
if (this.absentJournalVersionPurge !== void 0 && this.stateBackend.rollbackJournalReadAbsent(stackName, this.stackRegion)) {
|
|
36947
37477
|
await this.absentJournalVersionPurge;
|
|
36948
37478
|
return 0;
|
|
@@ -37114,6 +37644,27 @@ async function writeRollbackJournalSegment(stackName, completedOperations, faile
|
|
|
37114
37644
|
return false;
|
|
37115
37645
|
}
|
|
37116
37646
|
}
|
|
37647
|
+
async function orphanUntakenResumes(stackName, finalResources) {
|
|
37648
|
+
if (this.resumedCreates.size === 0) return;
|
|
37649
|
+
const untaken = new Map([...this.resumedCreates.values()].map((r) => [r.requestToken, r]));
|
|
37650
|
+
this.resumedCreates = /* @__PURE__ */ new Map();
|
|
37651
|
+
try {
|
|
37652
|
+
await this.stateBackend.rewriteRollbackJournalFailedOperations(stackName, this.stackRegion, (op) => {
|
|
37653
|
+
const resumed = op.pendingCloudControlRequest === void 0 ? void 0 : untaken.get(op.pendingCloudControlRequest.requestToken);
|
|
37654
|
+
if (resumed === void 0) return op;
|
|
37655
|
+
if (resumed.gone || finalResources[op.logicalId]?.physicalId === resumed.identifier) return withoutPendingRequest(op);
|
|
37656
|
+
return {
|
|
37657
|
+
...withoutPendingRequest(op),
|
|
37658
|
+
provisionedBy: "cc-api",
|
|
37659
|
+
physicalId: resumed.identifier,
|
|
37660
|
+
physicalIdRecoveredFromError: true,
|
|
37661
|
+
createdIdentifierUnique: true
|
|
37662
|
+
};
|
|
37663
|
+
});
|
|
37664
|
+
} catch (error) {
|
|
37665
|
+
this.logger.warn(safeMsg`Could not settle the resumed Cloud Control requests in the rollback journal of ` + safeMsg`${displayStackName(stackName)} (${displaySafe(describeAwsFailure(error).summary)}); ` + "the next run settles them.");
|
|
37666
|
+
}
|
|
37667
|
+
}
|
|
37117
37668
|
|
|
37118
37669
|
//#endregion
|
|
37119
37670
|
//#region src/analyzer/parameter-dependence.ts
|
|
@@ -38540,30 +39091,45 @@ async function provisionCreate(logicalId, change, stateResources, stackName, tem
|
|
|
38540
39091
|
});
|
|
38541
39092
|
const createProvider = createDecision.provider;
|
|
38542
39093
|
const createProps = createDecision.provisionedBy === "cc-api" ? this.preparePropertiesForCcApi(resourceType, resolvedProps, logicalId) : resolvedProps;
|
|
38543
|
-
await
|
|
38544
|
-
logicalId,
|
|
38545
|
-
resourceType,
|
|
38546
|
-
stackName,
|
|
38547
|
-
createdVia: createDecision.provisionedBy,
|
|
38548
|
-
resolvedProps
|
|
38549
|
-
});
|
|
38550
|
-
await refuseTakenCreateName.call(this, {
|
|
39094
|
+
const resumed = await resumeAbandonedCreate.call(this, {
|
|
38551
39095
|
logicalId,
|
|
38552
39096
|
resourceType,
|
|
38553
39097
|
stackName,
|
|
39098
|
+
resolvedProps,
|
|
39099
|
+
createProps,
|
|
38554
39100
|
createProvider,
|
|
38555
39101
|
createdVia: createDecision.provisionedBy,
|
|
38556
|
-
|
|
38557
|
-
secrets: createSecrets,
|
|
38558
|
-
stateResources
|
|
39102
|
+
maskSecrets: createSecretMasker(createSecrets)
|
|
38559
39103
|
});
|
|
38560
|
-
this.generatedNameGuard?.noteSent(logicalId);
|
|
38561
39104
|
let result;
|
|
38562
|
-
|
|
38563
|
-
|
|
38564
|
-
|
|
38565
|
-
|
|
38566
|
-
|
|
39105
|
+
if (resumed !== void 0) {
|
|
39106
|
+
this.generatedNameGuard?.noteSent(logicalId);
|
|
39107
|
+
result = resumed;
|
|
39108
|
+
} else {
|
|
39109
|
+
await refuseUnlicensedGeneratedName.call(this, {
|
|
39110
|
+
logicalId,
|
|
39111
|
+
resourceType,
|
|
39112
|
+
stackName,
|
|
39113
|
+
createdVia: createDecision.provisionedBy,
|
|
39114
|
+
resolvedProps
|
|
39115
|
+
});
|
|
39116
|
+
await refuseTakenCreateName.call(this, {
|
|
39117
|
+
logicalId,
|
|
39118
|
+
resourceType,
|
|
39119
|
+
stackName,
|
|
39120
|
+
createProvider,
|
|
39121
|
+
createdVia: createDecision.provisionedBy,
|
|
39122
|
+
createProps,
|
|
39123
|
+
secrets: createSecrets,
|
|
39124
|
+
stateResources
|
|
39125
|
+
});
|
|
39126
|
+
this.generatedNameGuard?.noteSent(logicalId);
|
|
39127
|
+
try {
|
|
39128
|
+
result = await this.withRetry(() => withCurrentResourceSecrets(createSecrets, () => createProvider.create(logicalId, resourceType, createProps, { maskSecrets: createSecretMasker(createSecrets) })), logicalId, void 0, void 0, createProvider);
|
|
39129
|
+
} catch (error) {
|
|
39130
|
+
this.generatedNameGuard?.noteFailed(logicalId, error);
|
|
39131
|
+
throw error;
|
|
39132
|
+
}
|
|
38567
39133
|
}
|
|
38568
39134
|
this.generatedNameGuard?.noteReturned(logicalId);
|
|
38569
39135
|
this.registerNoEchoAttributes(logicalId, result, createSecrets, resolvedProps);
|
|
@@ -38693,6 +39259,45 @@ async function refuseTakenCreateName(input) {
|
|
|
38693
39259
|
return refuse(`${subject} is created with ${named}, and an existing resource (${shown(holderId)}) already holds that name. Since ${adoptsText}, creating it would take that resource over and record it as this stack's, for a later \`cdkd destroy\` to delete. Nothing was created. Choose a name no other resource holds; ` + ownRemedy + holeNote + (adopt === void 0 ? "" : `
|
|
38694
39260
|
CONFIRM IT IS YOURS FIRST: another stack or app may own a resource of that name, and adopting it hands that resource to this stack's \`cdkd destroy\`.\nAdopt with: ${adopt.command}`));
|
|
38695
39261
|
}
|
|
39262
|
+
async function resumeAbandonedCreate(args) {
|
|
39263
|
+
const { logicalId, resourceType } = args;
|
|
39264
|
+
const resumed = this.resumedCreates.get(logicalId);
|
|
39265
|
+
if (resumed === void 0 || resumed.taken || resumed.resourceType !== resourceType) return;
|
|
39266
|
+
const reader = args.createProvider;
|
|
39267
|
+
if (args.createdVia !== "cc-api" || typeof reader.resumeCreatedResource !== "function") return;
|
|
39268
|
+
const probe = {
|
|
39269
|
+
logicalId,
|
|
39270
|
+
changeType: "CREATE",
|
|
39271
|
+
resourceType,
|
|
39272
|
+
attemptedProperties: args.resolvedProps
|
|
39273
|
+
};
|
|
39274
|
+
const [redacted] = this.redactOperationsForJournal([probe]);
|
|
39275
|
+
const sentNow = redacted?.attemptedProperties;
|
|
39276
|
+
const asJson = (value) => value === void 0 ? void 0 : JSON.parse(JSON.stringify(value));
|
|
39277
|
+
if (!isDeepStrictEqual(asJson(sentNow), asJson(resumed.attemptedProperties))) {
|
|
39278
|
+
this.logger.warn(safeMsg`${logicalId}: the template changed since the CREATE cdkd stopped waiting for, so ` + "this deploy creates the resource again; the one that CREATE made is kept in the rollback journal as a resource the failed deploy created.");
|
|
39279
|
+
return;
|
|
39280
|
+
}
|
|
39281
|
+
let result;
|
|
39282
|
+
try {
|
|
39283
|
+
result = await this.withRetry(() => reader.resumeCreatedResource(logicalId, resourceType, resumed.identifier, args.createProps, { maskSecrets: args.maskSecrets }), logicalId, void 0, void 0, args.createProvider);
|
|
39284
|
+
} catch (error) {
|
|
39285
|
+
if (error.resumedResourceGone !== true) throw error;
|
|
39286
|
+
resumed.gone = true;
|
|
39287
|
+
this.logger.warn(safeMsg`${logicalId}: the resource the earlier CREATE made no longer exists; creating it as usual.`);
|
|
39288
|
+
return;
|
|
39289
|
+
}
|
|
39290
|
+
resumed.taken = true;
|
|
39291
|
+
const shown = displacedPhysicalIdShown({
|
|
39292
|
+
logicalId,
|
|
39293
|
+
changeType: "CREATE",
|
|
39294
|
+
resourceType,
|
|
39295
|
+
physicalId: resumed.identifier,
|
|
39296
|
+
attemptedProperties: resumed.attemptedProperties
|
|
39297
|
+
}, this.logger, resumed.identifier) ?? "the resource";
|
|
39298
|
+
this.logger.info(safeMsg`${logicalId}: took over ${shown}, the resource the earlier CREATE made, instead of ` + "creating another.");
|
|
39299
|
+
return result;
|
|
39300
|
+
}
|
|
38696
39301
|
|
|
38697
39302
|
//#endregion
|
|
38698
39303
|
//#region src/provisioning/data-delete-intent.ts
|
|
@@ -45148,11 +45753,20 @@ async function executeDeployment(template, currentState, changes, dag, execution
|
|
|
45148
45753
|
record: replaced,
|
|
45149
45754
|
createdId: replacementCreatedId
|
|
45150
45755
|
} : void 0;
|
|
45756
|
+
const abandoned = change.changeType === "CREATE" && statePhysicalId === void 0 && createdId === void 0 ? abandonedRequestOf(provisionError) : void 0;
|
|
45757
|
+
const pendingRequest = abandoned?.operation === "CREATE" && /^[-A-Za-z0-9+/=]{1,128}$/.test(abandoned.requestToken) ? {
|
|
45758
|
+
requestToken: abandoned.requestToken,
|
|
45759
|
+
abandonedAt: Date.now()
|
|
45760
|
+
} : void 0;
|
|
45151
45761
|
const failedOp = {
|
|
45152
45762
|
logicalId,
|
|
45153
45763
|
changeType: change.changeType,
|
|
45154
45764
|
resourceType: change.resourceType,
|
|
45155
|
-
provisionedBy: createdId !== void 0 ? "sdk" : newResources[logicalId]?.provisionedBy ?? previousState?.provisionedBy,
|
|
45765
|
+
provisionedBy: createdId !== void 0 ? "sdk" : pendingRequest !== void 0 ? "cc-api" : newResources[logicalId]?.provisionedBy ?? previousState?.provisionedBy,
|
|
45766
|
+
...pendingRequest !== void 0 && {
|
|
45767
|
+
pendingCloudControlRequest: pendingRequest,
|
|
45768
|
+
deletionPolicy: journaledOrphanPolicy(this.extractTemplateAttributes(template, logicalId).deletionPolicy)
|
|
45769
|
+
},
|
|
45156
45770
|
...previousState && { previousState },
|
|
45157
45771
|
physicalId: createdId ?? statePhysicalId,
|
|
45158
45772
|
...createdId !== void 0 && {
|
|
@@ -45182,7 +45796,7 @@ async function executeDeployment(template, currentState, changes, dag, execution
|
|
|
45182
45796
|
failedOperations.push(replacementOrphanOp);
|
|
45183
45797
|
}
|
|
45184
45798
|
const orphanOp = createdId !== void 0 ? failedOp : replacementOrphanOp;
|
|
45185
|
-
if (orphanOp?.physicalId !== void 0 && orphanOp.deletionPolicy !== "Retain" &&
|
|
45799
|
+
if (orphanOp?.physicalId !== void 0 && orphanOp.deletionPolicy !== "Retain" && orphanNeedsIdentity(orphanOp)) {
|
|
45186
45800
|
const markedIdentity = createdResourceIdentityBeforeFailure(provisionError, logicalId, change.resourceType);
|
|
45187
45801
|
if (markedIdentity !== void 0) orphanOp.createdResourceIdentity = markedIdentity;
|
|
45188
45802
|
else if (this.interruptCause !== "user") {
|
|
@@ -46861,8 +47475,42 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
46861
47475
|
if (exportIndexStore && importableOutputKeys(currentState).length === 0) exportsPrefetch = afterGate(() => exportIndexStore.prefetch());
|
|
46862
47476
|
}
|
|
46863
47477
|
this.absentJournalVersionPurge = void 0;
|
|
47478
|
+
let journalAtStart = null;
|
|
47479
|
+
let journalReadError;
|
|
47480
|
+
try {
|
|
47481
|
+
journalAtStart = await this.stateBackend.loadRollbackJournal(stackName, this.stackRegion);
|
|
47482
|
+
} catch (error) {
|
|
47483
|
+
journalReadError = error ?? /* @__PURE__ */ new Error("unreadable rollback journal");
|
|
47484
|
+
}
|
|
47485
|
+
if (!this.options.dryRun && await resolvePendingCloudControlRequests({
|
|
47486
|
+
journal: this.stateBackend,
|
|
47487
|
+
loaded: journalAtStart,
|
|
47488
|
+
reader: () => this.providerRegistry.getCloudControlProvider(),
|
|
47489
|
+
stackName,
|
|
47490
|
+
region: this.stackRegion,
|
|
47491
|
+
command: "deploy",
|
|
47492
|
+
logger: this.logger,
|
|
47493
|
+
stateResources: currentState.resources,
|
|
47494
|
+
resume: (op, identifier) => {
|
|
47495
|
+
const attempted = op.attemptedProperties;
|
|
47496
|
+
if (template.Resources?.[op.logicalId]?.Type !== op.resourceType || attempted === void 0 || carriesSecretMask(attempted) || op.pendingCloudControlRequest === void 0 || Object.values(currentState.resources).some((r) => r.physicalId === identifier && r.resourceType === op.resourceType)) return false;
|
|
47497
|
+
this.resumedCreates.set(op.logicalId, {
|
|
47498
|
+
requestToken: op.pendingCloudControlRequest.requestToken,
|
|
47499
|
+
identifier,
|
|
47500
|
+
resourceType: op.resourceType,
|
|
47501
|
+
attemptedProperties: attempted
|
|
47502
|
+
});
|
|
47503
|
+
return true;
|
|
47504
|
+
},
|
|
47505
|
+
...gate !== void 0 && { beforeSettle: () => gate }
|
|
47506
|
+
})) try {
|
|
47507
|
+
journalAtStart = await this.stateBackend.loadRollbackJournal(stackName, this.stackRegion);
|
|
47508
|
+
} catch (error) {
|
|
47509
|
+
journalReadError = error ?? /* @__PURE__ */ new Error("unreadable rollback journal");
|
|
47510
|
+
}
|
|
46864
47511
|
try {
|
|
46865
|
-
|
|
47512
|
+
if (journalReadError !== void 0) throw journalReadError;
|
|
47513
|
+
const loaded = journalAtStart;
|
|
46866
47514
|
if (loaded === null && !this.options.parentStackInfo && !this.options.dryRun) this.absentJournalVersionPurge = afterGate(() => this.stateBackend.purgeRollbackJournalVersions(stackName, this.stackRegion));
|
|
46867
47515
|
const journal = loaded && {
|
|
46868
47516
|
...loaded,
|
|
@@ -47497,6 +48145,7 @@ var DeployEngine = class {
|
|
|
47497
48145
|
constructPathTemplate;
|
|
47498
48146
|
outputsSourceUsable = true;
|
|
47499
48147
|
attemptedResolvedProps = /* @__PURE__ */ new Map();
|
|
48148
|
+
resumedCreates = /* @__PURE__ */ new Map();
|
|
47500
48149
|
generatedNameGuard;
|
|
47501
48150
|
liveTaskLabels = /* @__PURE__ */ new Map();
|
|
47502
48151
|
retainedOldOnReplacement = /* @__PURE__ */ new Set();
|
|
@@ -47569,6 +48218,7 @@ var DeployEngine = class {
|
|
|
47569
48218
|
this.fingerprintChildTemplates = void 0;
|
|
47570
48219
|
this.perResourceInputFingerprints = /* @__PURE__ */ new Map();
|
|
47571
48220
|
this.attemptedResolvedProps = /* @__PURE__ */ new Map();
|
|
48221
|
+
this.resumedCreates = /* @__PURE__ */ new Map();
|
|
47572
48222
|
this.generatedNameGuard = void 0;
|
|
47573
48223
|
this.liveTaskLabels = /* @__PURE__ */ new Map();
|
|
47574
48224
|
this.outputSecrets = /* @__PURE__ */ new Map();
|
|
@@ -47850,5 +48500,5 @@ DeployEngine.prototype.replacementNameOrigin = replacementNameOrigin;
|
|
|
47850
48500
|
DeployEngine.prototype.orphanedNameCollisionAdvice = orphanedNameCollisionAdvice;
|
|
47851
48501
|
|
|
47852
48502
|
//#endregion
|
|
47853
|
-
export { S3_AUTO_DELETE_OBJECTS_TAG as $, withheldAccountClause as $a, getDockerImageBySourceHash as $c, isReadableResourceEntry as $i, findDestructiveChanges as $n, literalSplitDelimitersOf as $o, applyRoleArnIfSet as $r, splitImportedOps as $s, recordUnderIdIsNotOwn as $t, diffSecurity as A, refuseMalformedResourceEntries as Aa, buildDenyExternalAccessPolicy as Ac, isNamelessDynamicReferenceError as Ai, hasOwnKey as Al, DEFAULT_RESOURCE_TIMEOUT_MS as An, withRetry as Ao, CloudControlProvider as Ar, provenPublicValue as As, withNestedStackContext as At, readProtection as B, refuseMalformedResourcesForDeploy as Ba, isDockerClientEnvKey as Bc, declaresNoEcho as Bi, injectedAwsRegionValue as Bl, storedSecretNameNeedles as Bn, maskWholeValue as Bo, markWaitAbandoned as Br, TEMPLATE_SOURCED_RULES as Bs, awaitInFlightSibling as Bt, withApiLimit as C, refuseMalformedOrphanRecordsForDestroy as Ca, ensureAssetStorage as Cc, coerceParameterTypedValue as Ci, PARTITION_TABLE as Cl, exportNameSecretExposure as Cn, replayWarn as Co, readsNoEchoDeleteValues as Cr, recordNestedStackParameterExpressions as Cs, nestedChildStackName as Ct, findServiceTokenRefusals as D, refuseMalformedOutputs as Da, readBootstrapMarkerBody as Dc, isImpossibleEmptyStoredAttribute as Di, StageLoadError as Dl, collectPublishedOutputNames as Dn, prefetchCreateOnlyPropertyPaths as Do, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Dr, recordPhysicalNameCopy as Ds, withNestedRevertRun as Dt, deferredServiceTokenWarning as E, refuseMalformedOrphansForOrphan as Ea, parseBootstrapMarker as Ec, getAccountInfo as Ei, AssemblyReader as El, collectDeclaredOutputNames as En, requireConfigString as Eo, withPrintingSecrets as Er, recordAttributeIdCopy as Es, revertedNestedRowIds as Et, recordedProtectionEvidence as F, refuseMalformedResourceEntriesForOrphan as Fa, describeDockerFailure as Fc, refStateLookupFromResource as Fi, describeFileReadFailure as Fl, orphanRecordsPrintingBag as Fn, TemplateParser as Fo, deleteIndeterminateGuards as Fr, recordProvenPublicExpression as Fs, loadJournaledOrphans as Ft, deleteBudgetKey as G, repairMalformedOrphansForReadOnly as Ga, redactedDockerCause as Gc, UNREADABLE_RESOURCES_MAP_ROW as Gi, ccRoutedFinalSnapshotError as Gn, passedNoEchoParametersOf as Go, reDisableInstanceApiTermination as Gr, S3StateBackend as Gs, replacedDeleteFailureVerdict as Gt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as H, refuseMalformedResourcesForExport as Ha, partitionSensitiveEnv as Hc, STATE_REGION_DIVERGED as Hi, resolveBucketRegion as Hl, ATOMIC_FINAL_SNAPSHOT_TYPES as Hn, noEchoCoordinatesOf as Ho, ec2InstanceProtectionSite as Hr, isSingleDynamicReferenceToken as Hs, getStackRecords as Ht, recordedProtectionNote as I, refuseMalformedResourcePropertiesForDestroy as Ia, dockerSpawnEnvWithSensitive as Ic, parseWebACLArn as Ii, displayAssemblyPath as Il, secretNamePrintingBag as In, canonicalCoordinates as Io, deleteLeftInPlace as Ir, wholeStringLeavesOf as Is, makeForeignHolderScan as It, DELETE_INDEX_WAIT_PROCEED_NOTE as J, repairMalformedResourcePropertiesForReadOnly as Ja, warnFinchArgvExposure as Jc, displayLogicalId as Ji, isFinalSnapshotError as Jn, valueAtCoordinate as Jo, INTRINSIC_KEYS as Jr, CrossPrefixScanCache as Js, isJournaledOrphan as Jt, resolveDynamoDbDeleteBudgetClock as K, repairMalformedOutputsForReadOnly as Ka, runDockerForeground as Kc, accountArgs as Ki, createPreDeleteFinalSnapshot as Kn, readbackPathFor as Ko, reEnableInstanceApiTermination as Kr, rebuildClientForBucketRegion as Ks, recordAfterRollbackUpdate as Kt, PROTECTION_PROPERTY_BY_TYPE as L, refuseMalformedResourcePropertiesForDrift as La, finchSecretArgvRefusal as Lc, withSharedDrainBudget as Li, renderAssemblyPathEscape as Ll, secretNamePrintingBags as Ln, isMarkedCoordinate as Lo, deleteSkipReason as Lr, STATE_SOURCED_BASELINE_RULES as Ls, sameJournaledOrphans as Lt, noEchoComparisonForTemplate as M, refuseMalformedResourceEntriesForDestroy as Ma, resolveDockerContextDirectory as Mc, AWS_NO_VALUE as Mi, nullPrototypeRecord as Ml, completedReplayEntries as Mn, lambdaFunctionNameForMask as Mo, unchangedBehindSecretReference as Mr, recordMaskOnlyValuesIn as Ms, dropFailedHint as Mt, noEchoExactEchoLeavesOf as N, refuseMalformedResourceEntriesForImport as Na, describeDockerCapturedOutput as Nc, cfnRefValueFromPhysicalId as Ni, ownValue as Nl, journaledOrphanPrintingBag as Nn, sameLambdaFunctionAddress as No, RollbackInlinePolicyWriters as Nr, recordNoEchoAttributeValues as Ns, isHandledOrphan as Nt, serviceTokenBlockingReason as O, refuseMalformedOutputsForDestroy as Oa, validateAssetBucketName as Oc, carriesDynamicReference as Oi, processStackMessages as Ol, isExportAliasCollision as On, templateResourceTypes as Oo, applyCustomResourceResponseExpiration as Or, splitGetAttStringForm as Os, collectNestedChildUnaddressed as Ot, noEchoParameterNamesOf as P, refuseMalformedResourceEntriesForImportSave as Pa, describeDockerExecFailure as Pc, isStalePlaceholderArnAttribute as Pi, absoluteAssemblyPathEscape as Pl, maskEventTextWithBoundBags as Pn, DagBuilder as Po, UNSPECIFIED_SKIP_REASON as Pr, recordNoEchoParameterFreshValue as Ps, journaledOrphanLines as Pt, ECR_AUTO_DELETE_IMAGES_TAG as Q, unreadableResourceEntries as Qa, AssetManifestLoader as Qc, isReadableOrphanRecord as Qi, constructPathOf as Qn, hasMaskableValues as Qo, refuseUnreadableCdkCrossAccountRefs as Qr, isNotImplemented as Qs, recheckFailedPlan as Qt, isProtectionValueActive as R, refuseMalformedResourcePropertiesForExport as Ra, formatDockerLoginError as Rc, parameterInputsFor as Ri, resolveAssemblyPath as Rl, secretNamedRecordNeedles as Rn, maskAtCoordinates as Ro, withIndeterminateGuard as Rr, STATE_SOURCED_CROSS_GENERATION_RULES as Rs, replayFailedOperations as Rt, lookupEachName as S, refuseMalformedOrphanRecords as Sa, assertAssetBucketRegion as Sc, regionLessSecretName as Si, expectedOwnerParam as Sl, exportNameNoEchoParameters as Sn, readConfigString as So, TemplateNoEchoReresolver as Sr, inheritNestedStackParameterAssociations as Ss, getNestedRevertRun as St, recordRetainedForReadoption as T, refuseMalformedOrphansForDestroy as Ta, isCrossRegionRedirect as Tc, parameterTypeMayLoseSecretIdentity as Ti, derivePartitionAndUrlSuffix as Tl, noEchoParameterValueSeed as Tn, requireConfigObject as To, getCurrentResourceSecrets as Tr, physicalNameCopiesOf as Ts, revertNestedChildFromJournal as Tt, beginDeleteWait as U, refuseMalformedState as Ua, redactDockerArgvValues as Uc, STATE_RESOURCES_MALFORMED as Ui, PRE_DELETE_SNAPSHOT_TYPES as Un, noEchoLeavesOf as Uo, isTerminationProtectionPropagationError as Ur, LockManager as Us, withStackRecords as Ut, DynamoDBGlobalTableProvider as V, refuseMalformedResourcesForDestroy as Va, isMalformedEnvKey as Vc, JSON_LISTING_HOLE_VALUE as Vi, clearBucketRegionCache as Vl, extractDeploymentEventError as Vn, maskedLeafCoordinatesOf as Vo, disableInstanceApiTermination as Vr, WHOLE_DYNAMIC_REFERENCE_PATTERN as Vs, destroyStackRecordsView as Vt, compensateRemovedDeletionProtection as W, repairMalformedOrphanRecordsForReadOnly as Wa, redactedCause as Wc, UNREADABLE_ORPHANS_CONTAINER_ROW as Wi, buildFinalSnapshotIdentifier as Wn, noEchoOutputsComparison as Wo, observeThenDisableInstanceApiTermination as Wr, isLockInfoExpired as Ws, removeProtectionTypeList as Wt, deleteTableWithIndexBusyRetry as X, unpreviewableOrphanRecords as Xa, stripControlChars as Xc, hasReadableOutputs as Xi, unsupportedFinalSnapshotError as Xn, carryLogOnlyValues as Xo, poisonRenderedSpellingsCollidingIn as Xr, crossPrefixDeniedWarning as Xs, planFailedOps as Xt, INDEX_SETTLE_POLL_INTERVAL_MS as Y, repairMalformedResourcesForReadOnly as Ya, escapeRegExp$3 as Yc, hasReadableOrphans as Yi, refusesFinalSnapshot as Yn, liveMatchesUnresolvedTokenFrame as Yo, IntrinsicFunctionResolver as Yr, applyCrossPrefixScan as Ys, isReplacementOrphan as Yt, waitForIndexesSettled as Z, unreadableOrphanRecords as Za, stripForDisplay as Zc, hasReadableResources as Zi, maskingRetryLogger as Zn, createUnionSecretMasker as Zo, producerLookupOver as Zr, isAccessDenied$1 as Zs, planRollback as Zt, keptWholeReasonText as _, malformedScrubResourceEntriesRefusalMessage as _a, createAssetRedirectResolver as _c, s3BucketRegionalDomainName as _i, MIGRATE_TMP_PREFIX as _l, exportAliasCollisionScrubWarning as _n, coerceCfnBoolean as _o, CC_BROKEN_REASON as _r, DYNAMIC_REFERENCE_TOKEN_SCAN as _s, planOrphanAdoption as _t, inheritedProvenanceForChildDiff as a, malformedLocalResourcesWarning as aa, hasUnverifiableParameterRefusal as ac, AWS_CREDENTIAL_ENV_KEYS as ai, resolveApp as al, getCurrentProducerRegions as an, hasNoCloudControlHandlers as ao, acquireIdempotencyToken as ar, unionOfSecretBags as as, createReadOnlyAttributeHealerFactory as at, chunks as b, refuseDivergentRecordRegionForDestroy as ba, AssetModeResolver as bc, classifyReplaySecretRegion as bi, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as bl, secretSafeKeyDisplay as bn, configIntegerRefusal as bo, isCustomResource as br, pathCrossesDottedKey as bs, displacedPhysicalIdShown as bt, isAbsoluteAssetPath as c, malformedOrphanRowsKeptWarning as ca, isReadableBag as cc, envCredentialsAreAssumedRole as ci, resolveSkipPrefix as cl, isRedactedRecordedValue as cn, MULTI_REGION_RECREATE_BLOCKED_TYPES as co, DBPROXY_TAGS_WHAT as cr, maskSecretsInError as cs, gray as ct, templateIdentity as d, malformedOutputsRefusalMessage as da, shouldRetainResource as dc, outputReferenceProvenanceOf as di, resolveUseCdkBootstrapAssets as dl, updatePartialMessage as dn, renderStatefulReason as do, readTagList as dr, recordReferenceProvenanceEntry as ds, yellow as dt, malformedDriftResourcePropertiesWarning as ea, acceptedCreateOnlyDropsOf as ec, assertFlagRoleArn as ei, Synthesizer as el, replacementNeverSwapped as en, findActionableSilentDrops as eo, formatDestructiveChange as er, logOnlyValueCount as es, hasCdkAutoDeleteTag as et, conditionFingerprint as f, malformedOutputsWarning as fa, AssetPublisher as fc, recordedOutputReferenceRegions as fi, stateBucketExistenceConfirmed as fl, updatePartialReason as fn, WARM_THROUGHPUT_MEMBERS as fo, refuseMalformedDesiredTags as fr, snapshotPassProvenance as fs, computeParameterTaint as ft, isSecretBearingReferenceString as g, malformedResourcesWarning as ga, buildAssetRedirectMap as gc, s3BucketDualStackDomainName as gi, CFN_TEMPLATE_URL_LIMIT as gl, displayTextOrWithheld as gn, toFiniteNumber as go, stringifyIfAssigned as gr, withoutPhysicalNameCopies as gs, makeSiblingClaimReader as gt, readRecordedConditionVerdicts as h, malformedResourcePropertiesWarning as ha, WorkGraph as hc, s3BucketDomainName as hi, CFN_TEMPLATE_BODY_LIMIT as hl, WITHHELD_NAME_DISPLAY as hn, toCfnInteger as ho, definedAttributes as hr, withPhysicalNameCopies as hs, resourcesNamingDeclaredParameter as ht, crossStackOutputProvenanceSource as i, malformedLocalResourceEntriesWarning as ia, hasReasonlessBaselineRefusal as ic, sendableAssumeRoleCommand as ii, loadCdkJson as il, findNestedStackTypeChanges as in, NO_CC_HANDLERS_REASON as io, withCreateTokenLedger as ir, shareLogOnlyValues as is, formatResourceLine as it, noEchoAttributeNamesOf as j, refuseMalformedResourceEntriesForDeploy as ja, buildDockerImage as jc, keepsSecretReferenceToken as ji, hasPlainPrototype$1 as jl, DEFAULT_RESOURCE_WARN_AFTER_MS as jn, canonicalLambdaFunctionName as jo, slowCcOperationTimeoutMs as jr, recordMaskOnlyValue as js, deleteJournaledOrphans as jt, withResourceDeadline as k, refuseMalformedResourceAttributesForOrphan as ka, validateContainerRepoName as kc, carriesFetchableDynamicReference as ki, defineOwnKey as kl, bindingSkippedOutputs as kn, describeTypeWithThrottleRetry as ko, customResourceResponseExpirationWarning as kr, carriesSecretMask as ks, getCurrentNestedStackContext as kt, listNestedTemplateRows as l, malformedOrphansRefusalMessage as la, orphansAfterRollback as lc, isSettledInstanceState as li, resolveStateBucketWithDefault as ll, redactedDeleteAddressFields as ln, isStatefulRecreateTargetForReplace as lo, DBPROXY_TAG_OPTIONS as lr, maskSecretsInText as ls, green as lt, parentSuppliedValues as m, malformedResourceEntriesWarning as ma, stringifyValue as mc, s3BucketArn as mi, ssmResolvedValueType as ml, DeploymentEventsStore as mn, isWarmThroughputDecrease as mo, tagPlanWarning as mr, scrubResourceRecord as ms, reachableDivergentParameters as mt, IMPLICIT_DELETE_DEPENDENCIES as n, malformedExportSourceWarning as na, exportNamesCarriedFrom as nc, explicitRoleArnOrThrow as ni, getDefaultStateBucketName as nl, seedsDeleteFirstGuard as nn, unwrittenCreateOnlyReplacement as no, ledgerForStack as nr, recordLogOnlyParameterValue as ns, getPriorAttempts as nt, childTemplateLoader as o, malformedOrphanRecordsRefusalMessage as oa, importableOutputKeys as oc, applyCallerIdentityCredentials as oi, resolveAutoAssetStorage as ol, inheritProducerRegions as on, findReplacedReadersOfRecreateTargets as oo, isRefusedByName as or, createSecretMasker as os, bold as ot, conditionInputsFrom as p, malformedRenderedContainersWarning as pa, isSensitiveAttributeName as pc, recordedReferenceRegions as pi, warnDeprecatedNoPrefixCliFlag as pl, DeploymentEventsReader as pn, coerceWarmThroughput as po, tagMapAsList as pr, redactSecretsForState as ps, namesAnyDeclaredParameter as pt, resolveDynamoDbDeleteBudgetMs as q, repairMalformedResourceEntriesForReadOnly as qa, runDockerStreaming as qc, deployRefusesOrphanRowsReason as qi, effectiveDeletionPolicy as qn, readsNoEchoSource as qo, DiffCalculator as qr, CrossPrefixReadError as qs, demoteSupersededOrphans as qt, computeImplicitDeleteEdges as r, malformedLocalOutputsWarning as ra, hasReadableExportSet as rc, isIamRoleArn as ri, getLegacyStateBucketName as rl, orphanDeleteNeedsIdentity as rn, withoutSilentDropProperties as ro, reserveStackCreateToken as rr, recordLogOnlyValue as rs, markRefusedBeforeApplying as rt, findNestedTemplateTreeDefect as s, malformedOrphanRecordsWarning as sa, importableOutputs as sc, callerEnvCredentials as si, resolveCaptureObservedState as sl, REDACTED_DELETE_ADDRESS_SKIP_REASON as sn, shownType as so, markDeleteStarted as sr, errorCauseChain as ss, cyan as st, DeployEngine as t, malformedExportNamesWarning as ta, describeRegionValueKind as tc, assertSendableRoleArn as ti, synthesisStatusMessage as tl, resolveReplacementOldType as tn, findSilentDropProperties as to, earliestDefined as tr, printingCorpusOf as ts, isTruthyCfnBoolean as tt, renderNestedTemplateTreeDefect as u, malformedOrphansWarning as ua, orphansCarriedFrom as uc, keepHeldTokenProvenance as ui, resolveStateBucketWithDefaultAndSource as ul, redactedDeleteAddressSkip as un, isStatefulRecreateTargetSync as uo, planTagDiff as ur, markSameGenerationBag as us, red as ut, mergeNoChangeOutputs as v, malformedStateRefusalMessage as va, loadPublishableAssetManifest as vc, s3BucketWebsiteUrl as vi, findLargeInlineResources as vl, secretBearing as vn, coerceCfnInteger as vo, ProviderRegistry as vr, dynamicReferenceTokens as vs, NESTED_PENDING_PARENT_REASON as vt, keptForReadoption as w, refuseMalformedOrphans as wa, getBootstrapMarkerKey as wc, isUnboundTemplateParameter as wi, canonicalizeRegion as wl, isWholeDynamicReferenceValue as wn, requireConfigArray as wo, isCustomResourceType as wr, recoverMaskedOutput as ws, recordDisplacedSkips as wt, isAccessDeniedError as x, refuseMalformedNestedChildOutputs as xa, BOOTSTRAP_MARKER_PREFIX as xc, producerRegionsFromState as xi, decodeListingKey as xl, carriedExportAliasExposure as xn, configStringRefusal as xo, wouldReturnToSdkProvider as xr, identityKeyFor as xs, dropSettledNestedJournals as xt, makeCanonicalizePropertiesFn as y, previewableOrphanRecords as ya, rewriteTemplateAssetReferences as yc, classifyRecordedSecretRegion as yi, uploadCfnTemplate as yl, secretBearingStateKeyWarning as yn, configBooleanRefusal as yo, ccBrokenReason as yr, isUncertifiedBaselineMaskPosition as ys, displacedOpClause as yt, perType as z, refuseMalformedResourcePropertiesForOrphan as za, getDockerCmd as zc, passedParameterClassesOf as zi, injectAwsRegion as zl, stateSecretNameNeedles as zn, maskReadbackAtCoordinates as zo, isWaitAbandonedError as zr, STATE_SOURCED_READBACK_RULES as zs, replayRollback as zt };
|
|
47854
|
-
//# sourceMappingURL=deploy-engine-
|
|
48503
|
+
export { S3_AUTO_DELETE_OBJECTS_TAG as $, unpreviewableOrphanRecords as $a, stripControlChars as $c, hasReadableOutputs as $i, unsupportedFinalSnapshotError as $n, carryLogOnlyValues as $o, poisonRenderedSpellingsCollidingIn as $r, crossPrefixDeniedWarning as $s, isJournaledOrphan as $t, diffSecurity as A, refuseMalformedOutputs as Aa, readBootstrapMarkerBody as Ac, isImpossibleEmptyStoredAttribute as Ai, StageLoadError as Al, collectPublishedOutputNames as An, prefetchCreateOnlyPropertyPaths as Ao, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Ar, recordPhysicalNameCopy as As, NESTED_PENDING_PARENT_REASON as At, readProtection as B, refuseMalformedResourcePropertiesForDrift as Ba, finchSecretArgvRefusal as Bc, withSharedDrainBudget as Bi, renderAssemblyPathEscape as Bl, secretNamePrintingBags as Bn, isMarkedCoordinate as Bo, deleteSkipReason as Br, STATE_SOURCED_BASELINE_RULES as Bs, collectNestedChildUnaddressed as Bt, withApiLimit as C, refuseDivergentRecordRegionForDestroy as Ca, AssetModeResolver as Cc, classifyReplaySecretRegion as Ci, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Cl, secretSafeKeyDisplay as Cn, configIntegerRefusal as Co, isCustomResource as Cr, pathCrossesDottedKey as Cs, dropFailedCommands as Ct, findServiceTokenRefusals as D, refuseMalformedOrphans as Da, getBootstrapMarkerKey as Dc, isUnboundTemplateParameter as Di, canonicalizeRegion as Dl, isWholeDynamicReferenceValue as Dn, requireConfigArray as Do, isCustomResourceType as Dr, recoverMaskedOutput as Ds, loadJournaledOrphans as Dt, deferredServiceTokenWarning as E, refuseMalformedOrphanRecordsForDestroy as Ea, ensureAssetStorage as Ec, coerceParameterTypedValue as Ei, PARTITION_TABLE as El, exportNameSecretExposure as En, replayWarn as Eo, readsNoEchoDeleteValues as Er, recordNestedStackParameterExpressions as Es, journaledOrphanLines as Et, recordedProtectionEvidence as F, refuseMalformedResourceEntriesForDestroy as Fa, resolveDockerContextDirectory as Fc, AWS_NO_VALUE as Fi, nullPrototypeRecord as Fl, completedReplayEntries as Fn, lambdaFunctionNameForMask as Fo, unchangedBehindSecretReference as Fr, recordMaskOnlyValuesIn as Fs, nestedChildStackName as Ft, deleteBudgetKey as G, refuseMalformedResourcesForExport as Ga, partitionSensitiveEnv as Gc, STATE_REGION_DIVERGED as Gi, resolveBucketRegion as Gl, ATOMIC_FINAL_SNAPSHOT_TYPES as Gn, noEchoCoordinatesOf as Go, ec2InstanceProtectionSite as Gr, isSingleDynamicReferenceToken as Gs, awaitInFlightSibling as Gt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as H, refuseMalformedResourcePropertiesForOrphan as Ha, getDockerCmd as Hc, passedParameterClassesOf as Hi, injectAwsRegion as Hl, stateSecretNameNeedles as Hn, maskReadbackAtCoordinates as Ho, isWaitAbandonedError as Hr, STATE_SOURCED_READBACK_RULES as Hs, withNestedStackContext as Ht, recordedProtectionNote as I, refuseMalformedResourceEntriesForImport as Ia, describeDockerCapturedOutput as Ic, cfnRefValueFromPhysicalId as Ii, ownValue as Il, journaledOrphanPrintingBag as In, sameLambdaFunctionAddress as Io, RollbackInlinePolicyWriters as Ir, recordNoEchoAttributeValues as Is, recordDisplacedSkips as It, DELETE_INDEX_WAIT_PROCEED_NOTE as J, repairMalformedOrphansForReadOnly as Ja, redactedDockerCause as Jc, UNREADABLE_RESOURCES_MAP_ROW as Ji, ccRoutedFinalSnapshotError as Jn, passedNoEchoParametersOf as Jo, reDisableInstanceApiTermination as Jr, S3StateBackend as Js, withStackRecords as Jt, resolveDynamoDbDeleteBudgetClock as K, refuseMalformedState as Ka, redactDockerArgvValues as Kc, STATE_RESOURCES_MALFORMED as Ki, PRE_DELETE_SNAPSHOT_TYPES as Kn, noEchoLeavesOf as Ko, isTerminationProtectionPropagationError as Kr, LockManager as Ks, destroyStackRecordsView as Kt, PROTECTION_PROPERTY_BY_TYPE as L, refuseMalformedResourceEntriesForImportSave as La, describeDockerExecFailure as Lc, isStalePlaceholderArnAttribute as Li, absoluteAssemblyPathEscape as Ll, maskEventTextWithBoundBags as Ln, DagBuilder as Lo, UNSPECIFIED_SKIP_REASON as Lr, recordNoEchoParameterFreshValue as Ls, revertNestedChildFromJournal as Lt, noEchoComparisonForTemplate as M, refuseMalformedResourceAttributesForOrphan as Ma, validateContainerRepoName as Mc, carriesFetchableDynamicReference as Mi, defineOwnKey as Ml, bindingSkippedOutputs as Mn, describeTypeWithThrottleRetry as Mo, customResourceResponseExpirationWarning as Mr, carriesSecretMask as Ms, displacedPhysicalIdShown as Mt, noEchoExactEchoLeavesOf as N, refuseMalformedResourceEntries as Na, buildDenyExternalAccessPolicy as Nc, isNamelessDynamicReferenceError as Ni, hasOwnKey as Nl, DEFAULT_RESOURCE_TIMEOUT_MS as Nn, withRetry as No, CloudControlProvider as Nr, provenPublicValue as Ns, dropSettledNestedJournals as Nt, serviceTokenBlockingReason as O, refuseMalformedOrphansForDestroy as Oa, isCrossRegionRedirect as Oc, parameterTypeMayLoseSecretIdentity as Oi, derivePartitionAndUrlSuffix as Ol, noEchoParameterValueSeed as On, requireConfigObject as Oo, getCurrentResourceSecrets as Or, physicalNameCopiesOf as Os, makeForeignHolderScan as Ot, noEchoParameterNamesOf as P, refuseMalformedResourceEntriesForDeploy as Pa, buildDockerImage as Pc, keepsSecretReferenceToken as Pi, hasPlainPrototype$1 as Pl, DEFAULT_RESOURCE_WARN_AFTER_MS as Pn, canonicalLambdaFunctionName as Po, slowCcOperationTimeoutMs as Pr, recordMaskOnlyValue as Ps, getNestedRevertRun as Pt, ECR_AUTO_DELETE_IMAGES_TAG as Q, repairMalformedResourcesForReadOnly as Qa, escapeRegExp$3 as Qc, hasReadableOrphans as Qi, refusesFinalSnapshot as Qn, liveMatchesUnresolvedTokenFrame as Qo, IntrinsicFunctionResolver as Qr, applyCrossPrefixScan as Qs, demoteSupersededOrphans as Qt, isProtectionValueActive as R, refuseMalformedResourceEntriesForOrphan as Ra, describeDockerFailure as Rc, refStateLookupFromResource as Ri, describeFileReadFailure as Rl, orphanRecordsPrintingBag as Rn, TemplateParser as Ro, deleteIndeterminateGuards as Rr, recordProvenPublicExpression as Rs, revertedNestedRowIds as Rt, lookupEachName as S, previewableOrphanRecords as Sa, rewriteTemplateAssetReferences as Sc, classifyRecordedSecretRegion as Si, uploadCfnTemplate as Sl, secretBearingStateKeyWarning as Sn, configBooleanRefusal as So, ccBrokenReason as Sr, isUncertifiedBaselineMaskPosition as Ss, deleteJournaledOrphans as St, recordRetainedForReadoption as T, refuseMalformedOrphanRecords as Ta, assertAssetBucketRegion as Tc, regionLessSecretName as Ti, expectedOwnerParam as Tl, exportNameNoEchoParameters as Tn, readConfigString as To, TemplateNoEchoReresolver as Tr, inheritNestedStackParameterAssociations as Ts, isHandledOrphan as Tt, beginDeleteWait as U, refuseMalformedResourcesForDeploy as Ua, isDockerClientEnvKey as Uc, declaresNoEcho as Ui, injectedAwsRegionValue as Ul, storedSecretNameNeedles as Un, maskWholeValue as Uo, markWaitAbandoned as Ur, TEMPLATE_SOURCED_RULES as Us, replayFailedOperations as Ut, DynamoDBGlobalTableProvider as V, refuseMalformedResourcePropertiesForExport as Va, formatDockerLoginError as Vc, parameterInputsFor as Vi, resolveAssemblyPath as Vl, secretNamedRecordNeedles as Vn, maskAtCoordinates as Vo, withIndeterminateGuard as Vr, STATE_SOURCED_CROSS_GENERATION_RULES as Vs, getCurrentNestedStackContext as Vt, compensateRemovedDeletionProtection as W, refuseMalformedResourcesForDestroy as Wa, isMalformedEnvKey as Wc, JSON_LISTING_HOLE_VALUE as Wi, clearBucketRegionCache as Wl, extractDeploymentEventError as Wn, maskedLeafCoordinatesOf as Wo, disableInstanceApiTermination as Wr, WHOLE_DYNAMIC_REFERENCE_PATTERN as Ws, replayRollback as Wt, deleteTableWithIndexBusyRetry as X, repairMalformedResourceEntriesForReadOnly as Xa, runDockerStreaming as Xc, deployRefusesOrphanRowsReason as Xi, effectiveDeletionPolicy as Xn, readsNoEchoSource as Xo, DiffCalculator as Xr, CrossPrefixReadError as Xs, replacedDeleteFailureVerdict as Xt, INDEX_SETTLE_POLL_INTERVAL_MS as Y, repairMalformedOutputsForReadOnly as Ya, runDockerForeground as Yc, accountArgs as Yi, createPreDeleteFinalSnapshot as Yn, readbackPathFor as Yo, reEnableInstanceApiTermination as Yr, rebuildClientForBucketRegion as Ys, removeProtectionTypeList as Yt, waitForIndexesSettled as Z, repairMalformedResourcePropertiesForReadOnly as Za, warnFinchArgvExposure as Zc, displayLogicalId as Zi, isFinalSnapshotError as Zn, valueAtCoordinate as Zo, INTRINSIC_KEYS as Zr, CrossPrefixScanCache as Zs, recordAfterRollbackUpdate as Zt, keptWholeReasonText as _, malformedResourceEntriesWarning as _a, stringifyValue as _c, s3BucketArn as _i, ssmResolvedValueType as _l, orphanNeedsIdentity as _n, isWarmThroughputDecrease as _o, tagPlanWarning as _r, scrubResourceRecord as _s, planOrphanAdoption as _t, inheritedProvenanceForChildDiff as a, malformedExportSourceWarning as aa, exportNamesCarriedFrom as ac, explicitRoleArnOrThrow as ai, getDefaultStateBucketName as al, replacementNeverSwapped as an, unwrittenCreateOnlyReplacement as ao, ledgerForStack as ar, recordLogOnlyParameterValue as as, createReadOnlyAttributeHealerFactory as at, chunks as b, malformedScrubResourceEntriesRefusalMessage as ba, createAssetRedirectResolver as bc, s3BucketRegionalDomainName as bi, MIGRATE_TMP_PREFIX as bl, exportAliasCollisionScrubWarning as bn, coerceCfnBoolean as bo, CC_BROKEN_REASON as br, DYNAMIC_REFERENCE_TOKEN_SCAN as bs, pendingRequestCount as bt, isAbsoluteAssetPath as c, malformedLocalResourcesWarning as ca, hasUnverifiableParameterRefusal as cc, AWS_CREDENTIAL_ENV_KEYS as ci, resolveApp as cl, findNestedStackTypeChanges as cn, hasNoCloudControlHandlers as co, acquireIdempotencyToken as cr, unionOfSecretBags as cs, gray as ct, templateIdentity as d, malformedOrphanRowsKeptWarning as da, isReadableBag as dc, envCredentialsAreAssumedRole as di, resolveSkipPrefix as dl, REDACTED_DELETE_ADDRESS_SKIP_REASON as dn, MULTI_REGION_RECREATE_BLOCKED_TYPES as do, DBPROXY_TAGS_WHAT as dr, maskSecretsInError as ds, yellow as dt, hasReadableResources as ea, isAccessDenied$1 as ec, producerLookupOver as ei, stripForDisplay as el, isReplacementOrphan as en, unreadableOrphanRecords as eo, maskingRetryLogger as er, createUnionSecretMasker as es, hasCdkAutoDeleteTag as et, conditionFingerprint as f, malformedOrphansRefusalMessage as fa, orphansAfterRollback as fc, isSettledInstanceState as fi, resolveStateBucketWithDefault as fl, isRedactedRecordedValue as fn, isStatefulRecreateTargetForReplace as fo, DBPROXY_TAG_OPTIONS as fr, maskSecretsInText as fs, computeParameterTaint as ft, isSecretBearingReferenceString as g, malformedRenderedContainersWarning as ga, isSensitiveAttributeName as gc, recordedReferenceRegions as gi, warnDeprecatedNoPrefixCliFlag as gl, updatePartialReason as gn, coerceWarmThroughput as go, tagMapAsList as gr, redactSecretsForState as gs, makeSiblingClaimReader as gt, readRecordedConditionVerdicts as h, malformedOutputsWarning as ha, AssetPublisher as hc, recordedOutputReferenceRegions as hi, stateBucketExistenceConfirmed as hl, updatePartialMessage as hn, WARM_THROUGHPUT_MEMBERS as ho, refuseMalformedDesiredTags as hr, snapshotPassProvenance as hs, resourcesNamingDeclaredParameter as ht, crossStackOutputProvenanceSource as i, malformedExportNamesWarning as ia, describeRegionValueKind as ic, assertSendableRoleArn as ii, synthesisStatusMessage as il, recordUnderIdIsNotOwn as in, findSilentDropProperties as io, earliestDefined as ir, printingCorpusOf as is, formatResourceLine as it, noEchoAttributeNamesOf as j, refuseMalformedOutputsForDestroy as ja, validateAssetBucketName as jc, carriesDynamicReference as ji, processStackMessages as jl, isExportAliasCollision as jn, templateResourceTypes as jo, applyCustomResourceResponseExpiration as jr, splitGetAttStringForm as js, displacedOpClause as jt, withResourceDeadline as k, refuseMalformedOrphansForOrphan as ka, parseBootstrapMarker as kc, getAccountInfo as ki, AssemblyReader as kl, collectDeclaredOutputNames as kn, requireConfigString as ko, withPrintingSecrets as kr, recordAttributeIdCopy as ks, sameJournaledOrphans as kt, listNestedTemplateRows as l, malformedOrphanRecordsRefusalMessage as la, importableOutputKeys as lc, applyCallerIdentityCredentials as li, resolveAutoAssetStorage as ll, getCurrentProducerRegions as ln, findReplacedReadersOfRecreateTargets as lo, isRefusedByName as lr, createSecretMasker as ls, green as lt, parentSuppliedValues as m, malformedOutputsRefusalMessage as ma, shouldRetainResource as mc, outputReferenceProvenanceOf as mi, resolveUseCdkBootstrapAssets as ml, redactedDeleteAddressSkip as mn, renderStatefulReason as mo, readTagList as mr, recordReferenceProvenanceEntry as ms, reachableDivergentParameters as mt, IMPLICIT_DELETE_DEPENDENCIES as n, isReadableResourceEntry as na, splitImportedOps as nc, applyRoleArnIfSet as ni, getDockerImageBySourceHash as nl, planRollback as nn, withheldAccountClause as no, findDestructiveChanges as nr, literalSplitDelimitersOf as ns, getPriorAttempts as nt, childTemplateLoader as o, malformedLocalOutputsWarning as oa, hasReadableExportSet as oc, isIamRoleArn as oi, getLegacyStateBucketName as ol, resolveReplacementOldType as on, withoutSilentDropProperties as oo, reserveStackCreateToken as or, recordLogOnlyValue as os, bold as ot, conditionInputsFrom as p, malformedOrphansWarning as pa, orphansCarriedFrom as pc, keepHeldTokenProvenance as pi, resolveStateBucketWithDefaultAndSource as pl, redactedDeleteAddressFields as pn, isStatefulRecreateTargetSync as po, planTagDiff as pr, markSameGenerationBag as ps, namesAnyDeclaredParameter as pt, resolveDynamoDbDeleteBudgetMs as q, repairMalformedOrphanRecordsForReadOnly as qa, redactedCause as qc, UNREADABLE_ORPHANS_CONTAINER_ROW as qi, buildFinalSnapshotIdentifier as qn, noEchoOutputsComparison as qo, observeThenDisableInstanceApiTermination as qr, isLockInfoExpired as qs, getStackRecords as qt, computeImplicitDeleteEdges as r, malformedDriftResourcePropertiesWarning as ra, acceptedCreateOnlyDropsOf as rc, assertFlagRoleArn as ri, Synthesizer as rl, recheckFailedPlan as rn, findActionableSilentDrops as ro, formatDestructiveChange as rr, logOnlyValueCount as rs, markRefusedBeforeApplying as rt, findNestedTemplateTreeDefect as s, malformedLocalResourceEntriesWarning as sa, hasReasonlessBaselineRefusal as sc, sendableAssumeRoleCommand as si, loadCdkJson as sl, seedsDeleteFirstGuard as sn, NO_CC_HANDLERS_REASON as so, withCreateTokenLedger as sr, shareLogOnlyValues as ss, cyan as st, DeployEngine as t, isReadableOrphanRecord as ta, isNotImplemented as tc, refuseUnreadableCdkCrossAccountRefs as ti, AssetManifestLoader as tl, planFailedOps as tn, unreadableResourceEntries as to, constructPathOf as tr, hasMaskableValues as ts, isTruthyCfnBoolean as tt, renderNestedTemplateTreeDefect as u, malformedOrphanRecordsWarning as ua, importableOutputs as uc, callerEnvCredentials as ui, resolveCaptureObservedState as ul, inheritProducerRegions as un, shownType as uo, markDeleteStarted as ur, errorCauseChain as us, red as ut, mergeNoChangeOutputs as v, malformedResourcePropertiesWarning as va, WorkGraph as vc, s3BucketDomainName as vi, CFN_TEMPLATE_BODY_LIMIT as vl, WITHHELD_NAME_DISPLAY as vn, toCfnInteger as vo, definedAttributes as vr, withPhysicalNameCopies as vs, DeploymentEventsReader as vt, keptForReadoption as w, refuseMalformedNestedChildOutputs as wa, BOOTSTRAP_MARKER_PREFIX as wc, producerRegionsFromState as wi, decodeListingKey as wl, carriedExportAliasExposure as wn, configStringRefusal as wo, wouldReturnToSdkProvider as wr, identityKeyFor as ws, dropFailedHint as wt, isAccessDeniedError as x, malformedStateRefusalMessage as xa, loadPublishableAssetManifest as xc, s3BucketWebsiteUrl as xi, findLargeInlineResources as xl, secretBearing as xn, coerceCfnInteger as xo, ProviderRegistry as xr, dynamicReferenceTokens as xs, resolvePendingCloudControlRequests as xt, makeCanonicalizePropertiesFn as y, malformedResourcesWarning as ya, buildAssetRedirectMap as yc, s3BucketDualStackDomainName as yi, CFN_TEMPLATE_URL_LIMIT as yl, displayTextOrWithheld as yn, toFiniteNumber as yo, stringifyIfAssigned as yr, withoutPhysicalNameCopies as ys, DeploymentEventsStore as yt, perType as z, refuseMalformedResourcePropertiesForDestroy as za, dockerSpawnEnvWithSensitive as zc, parseWebACLArn as zi, displayAssemblyPath as zl, secretNamePrintingBag as zn, canonicalCoordinates as zo, deleteLeftInPlace as zr, wholeStringLeavesOf as zs, withNestedRevertRun as zt };
|
|
48504
|
+
//# sourceMappingURL=deploy-engine-DEvS2r2M.js.map
|