@go-to-k/cdkd 0.295.1 → 0.296.1
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-CbwOK2TQ.js → asg-provider-BwWy0pBH.js} +8 -6
- package/dist/asg-provider-BwWy0pBH.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-DG-oC9YK.js → deploy-engine-xlct0Hcm.js} +1015 -307
- package/dist/deploy-engine-xlct0Hcm.js.map +1 -0
- package/dist/{iam-policy-targets-CMSQGQnm.js → iam-policy-targets-DSDSdxXz.js} +145 -4
- package/dist/iam-policy-targets-DSDSdxXz.js.map +1 -0
- package/dist/{iam-role-provider-DUZtt9lH.js → iam-role-provider-BRVCTUZu.js} +11 -5
- package/dist/iam-role-provider-BRVCTUZu.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/{logger-B46YMG0h.js → logger-Dvc7ddKe.js} +19 -3
- package/dist/{logger-B46YMG0h.js.map → logger-Dvc7ddKe.js.map} +1 -1
- package/dist/{neptune-provider-TnGNCeLX.js → neptune-provider-Cdp4jX8S.js} +20 -14
- package/dist/neptune-provider-Cdp4jX8S.js.map +1 -0
- package/dist/{program-DfJFegS1.js → program-DXRavuSm.js} +6245 -5940
- package/dist/program-DXRavuSm.js.map +1 -0
- package/dist/{provider-classes-DUw5QAWI.js → provider-classes-DNkoEEo4.js} +754 -208
- package/dist/provider-classes-DNkoEEo4.js.map +1 -0
- package/dist/{rds-provider-COCDd7bS.js → rds-provider-McCDKyXN.js} +22 -15
- package/dist/rds-provider-McCDKyXN.js.map +1 -0
- package/dist/{version-Bqzsng8Y.js → version-Dpc_HYX0.js} +2 -2
- package/dist/{version-Bqzsng8Y.js.map → version-Dpc_HYX0.js.map} +1 -1
- package/package.json +1 -1
- package/dist/asg-provider-CbwOK2TQ.js.map +0 -1
- package/dist/deploy-engine-DG-oC9YK.js.map +0 -1
- package/dist/iam-policy-targets-CMSQGQnm.js.map +0 -1
- package/dist/iam-role-provider-DUZtt9lH.js.map +0 -1
- package/dist/neptune-provider-TnGNCeLX.js.map +0 -1
- package/dist/program-DfJFegS1.js.map +0 -1
- package/dist/provider-classes-DUw5QAWI.js.map +0 -1
- package/dist/rds-provider-COCDd7bS.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as getAwsClients, s as __exportAll } from "./aws-clients-CnmtbrxD.js";
|
|
2
|
-
import { A as displaySafe, E as UNRENDERABLE, F as safeMsg, L as truncateCodePoints, M as isPasteableIdent, O as displayAwsMessage, P as plainIdentOr, S as withoutGeneratedFallbackName, T as STACK_REF_MAX_CODE_POINTS, _ as getCurrentSkipPrefix, b as withSkipPrefix, c as getLiveRenderer, f as applyDefaultNameForFallback, g as generateResourceNameWithFallback, h as generateResourceName, j as displayStackName, k as displayIdent, m as explicitNamePropertyFor, n as getLogger, r as isStdoutReservedForPayload, s as installLogLineMaskerSource, v as getCurrentStackName, w as SECRET_REF_MAX_CODE_POINTS, x as withStackName, y as looksLikeCdkdGeneratedName } from "./logger-
|
|
3
|
-
import { $
|
|
2
|
+
import { A as displaySafe, E as UNRENDERABLE, F as safeMsg, L as truncateCodePoints, M as isPasteableIdent, O as displayAwsMessage, P as plainIdentOr, S as withoutGeneratedFallbackName, T as STACK_REF_MAX_CODE_POINTS, _ as getCurrentSkipPrefix, b as withSkipPrefix, c as getLiveRenderer, f as applyDefaultNameForFallback, g as generateResourceNameWithFallback, h as generateResourceName, j as displayStackName, k as displayIdent, m as explicitNamePropertyFor, n as getLogger, r as isStdoutReservedForPayload, s as installLogLineMaskerSource, v as getCurrentStackName, w as SECRET_REF_MAX_CODE_POINTS, x as withStackName, y as looksLikeCdkdGeneratedName } from "./logger-Dvc7ddKe.js";
|
|
3
|
+
import { $n as markRedactedCause, $t as LockError, A as isTerminalDeleteFailure, At as CUSTOM_RESOURCE_RESPONSE_PREFIX, Bn as isAmbiguousCcHandlerErrorCode, Bt as clientDefaultsFor, C as refusalTypeShown, Cn as physicalIdShownBesideCommand, Ct as buildForceUnlockCommand, D as ProtectionFlipRegistry, Dn as shellQuote, Dt as formatLockOperation, En as shellBoundedDisplay, Et as formatLockExpiry, Fn as isRecreateRetryableError, Ft as producerRecordKey, Gn as retryClassificationText, H as pasteableAwsCommand, Hn as isIamPropagationError, Ht as AccountIdUnavailableError, In as isReplayedNameCollisionFrom, J as isInterruptedWaitError, Jn as safeStringify$1, Kn as describeAwsFailure, Kt as CrossAccountSecretRefusalError, Lt as withPasteableAwsProfile, M as observeThenDisableProtection, Mn as hasReplayMayCollide, Mt as injectiveKey, N as protectionFlipKey, Nn as isNameCollisionErrorFrom, O as compensateProtectionFlip, On as withheldTargetClause, Ot as formatLockOwner, Pn as isNameCooldownError, Q as canonicalizeRoute53QueryName, Qn as markNonRetryable, R as DELETION_PROTECTION_DOC_POINTER, Rn as markReplayMayCollide, Rt as ambientClientDefaults, S as quotedRemedyLogicalId, Sn as pasteableCommand, St as UNREPRODUCIBLE_LOCK_CLAUSE, T as resolveExplicitPhysicalId, Tn as quotedOrDescribed, U as protectedReplacementAdvice, Un as isRetryableTransientError, Ut as AssetError, Vn as isAmbiguousOutcomeError, Vt as credentialFingerprint, Wn as isTransientServerError, Wt as CdkdError, X as ElapsedBudgetRegistry, Xn as isMarkedNonRetryable, Xt as IntrinsicResolutionRefusalError, Y as startInterruptWatch, Yt as DynamicReferenceRegionAmbiguousError, Z as monotonicNowMs, Zn as isThrottlingError, _n as SHELL_ACTIVE_WHY, _t as hasCreatedBeforeFailure, an as ResourceTimeoutError, at as segmentAfterAnchor, b as isQuotableImportValue, bt as markAuxiliaryFailure, ct as createMaskedRetryLogger, d as prepareRemovalForUpdate, dt as maskerOrIdentity, en as MacroExpansionError, er as wrapMaskedAwsError, et as compositeIdSeparatorRefusal, f as removalWarning, ft as withDerivedNameMasks, g as assertRegionMatch, gn as SHELL_ACTIVE, gt as createdBeforeFailure, h as RESOURCE_NOT_FOUND, i as holdsSecretDerivedEntry, in as ProvisioningError, it as resourceTypeShown, jn as isUpdateUnsupportedError, jt as DEFAULT_STATE_PREFIX, k as deleteWithProtectionCompensation, kt as sanitizeRecoveryValue, l as withUnchangedSecretPrincipalLists, ln as StateError, lt as isSecretDerivedValue, m as withoutInjectedRemovals, mt as carryCreatedBeforeFailure, nt as logicalIdShown, on as ResourceUpdateNotSupportedError, ot as stateOrphanRecordRemedy, pn as normalizeAwsError, pt as RETRY_AUXILIARY_OWNER, qt as DependencyError, st as createMaskedLogSinks, tn as MalformedProducerRecordRefusalError, un as SynthesisError, ut as maskDeep, vn as UNSHOWABLE_VALUE, vt as isAuxiliaryFailure, wn as plainOrDescribed, x as normalizeAwsTagsToCfn, xn as isInertUnquoted, xt as markCreatedBeforeFailure, yn as commandHole, yt as isAuxiliaryMarkOf, zn as formatRetryClassificationSignals, zt as ambientCredentialConfig } from "./iam-policy-targets-DSDSdxXz.js";
|
|
4
4
|
import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as ambientRegion, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-D0q0z4dG.js";
|
|
5
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
+
import { t as getCdkdVersion } from "./version-Dpc_HYX0.js";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
8
|
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -4976,7 +4976,7 @@ async function rebuildClientForBucketRegion(client, bucket, opts = {}) {
|
|
|
4976
4976
|
|
|
4977
4977
|
//#endregion
|
|
4978
4978
|
//#region src/state/s3-state-backend.ts
|
|
4979
|
-
function errorDetail$
|
|
4979
|
+
function errorDetail$2(error) {
|
|
4980
4980
|
return displaySafe(error instanceof Error ? error.message : error, { asciiOnly: true }) || "<unrenderable>";
|
|
4981
4981
|
}
|
|
4982
4982
|
const LEGACY_KEY_DEPTH = 2;
|
|
@@ -5096,7 +5096,7 @@ var S3StateBackend = class {
|
|
|
5096
5096
|
} catch (error) {
|
|
5097
5097
|
if (!isNoSuchKey(error)) {
|
|
5098
5098
|
if (error instanceof StateError) throw error;
|
|
5099
|
-
throw new StateError(`Failed to get state for stack ${shownStackName} (${shownRegionName}): ${errorDetail$
|
|
5099
|
+
throw new StateError(`Failed to get state for stack ${shownStackName} (${shownRegionName}): ${errorDetail$2(error)}`, error instanceof Error ? error : void 0);
|
|
5100
5100
|
}
|
|
5101
5101
|
this.logger.debug(`No state at new key for stack: ${shownStackName} (${shownRegionName})`);
|
|
5102
5102
|
}
|
|
@@ -5143,7 +5143,7 @@ var S3StateBackend = class {
|
|
|
5143
5143
|
}));
|
|
5144
5144
|
this.logger.info(`Migrated state for stack ${this.displayName(stackName)} to region-scoped layout (${displayIdent(region)})`);
|
|
5145
5145
|
} catch (deleteError) {
|
|
5146
|
-
this.logger.warn(`Migrated stack ${this.displayName(stackName)} to new key, but failed to delete legacy key: ${errorDetail$
|
|
5146
|
+
this.logger.warn(`Migrated stack ${this.displayName(stackName)} to new key, but failed to delete legacy key: ${errorDetail$2(deleteError)}`);
|
|
5147
5147
|
}
|
|
5148
5148
|
await notifyStateSaved(stackName, region);
|
|
5149
5149
|
return response.ETag;
|
|
@@ -5153,7 +5153,7 @@ var S3StateBackend = class {
|
|
|
5153
5153
|
bucket: this.config.bucket,
|
|
5154
5154
|
operation: "PutObject"
|
|
5155
5155
|
});
|
|
5156
|
-
throw new StateError(`Failed to save state for stack ${this.stackRef(stackName, region)}: ${errorDetail$
|
|
5156
|
+
throw new StateError(`Failed to save state for stack ${this.stackRef(stackName, region)}: ${errorDetail$2(normalized)}`, normalized);
|
|
5157
5157
|
}
|
|
5158
5158
|
}
|
|
5159
5159
|
async deleteState(stackName, region) {
|
|
@@ -5185,7 +5185,7 @@ var S3StateBackend = class {
|
|
|
5185
5185
|
bucket: this.config.bucket,
|
|
5186
5186
|
operation: "DeleteObject"
|
|
5187
5187
|
});
|
|
5188
|
-
throw new StateError(`Failed to delete state for stack ${this.stackRef(stackName, region)}: ${errorDetail$
|
|
5188
|
+
throw new StateError(`Failed to delete state for stack ${this.stackRef(stackName, region)}: ${errorDetail$2(normalized)}`, normalized);
|
|
5189
5189
|
} finally {
|
|
5190
5190
|
await this.deleteRollbackJournal(stackName, region);
|
|
5191
5191
|
}
|
|
@@ -5207,7 +5207,7 @@ var S3StateBackend = class {
|
|
|
5207
5207
|
bucket: this.config.bucket,
|
|
5208
5208
|
operation: "DeleteObject"
|
|
5209
5209
|
});
|
|
5210
|
-
throw new StateError(`Failed to delete legacy state for stack ${displayStackName(stackName)}: ${errorDetail$
|
|
5210
|
+
throw new StateError(`Failed to delete legacy state for stack ${displayStackName(stackName)}: ${errorDetail$2(normalized)}`, normalized);
|
|
5211
5211
|
}
|
|
5212
5212
|
}
|
|
5213
5213
|
async listStacks() {
|
|
@@ -5378,7 +5378,7 @@ var S3StateBackend = class {
|
|
|
5378
5378
|
});
|
|
5379
5379
|
} catch (error) {
|
|
5380
5380
|
const describing = options.objectDescription ? ` (${options.objectDescription})` : "";
|
|
5381
|
-
this.logger.warn(`Could not purge noncurrent versions of ${keys.length} key(s) in bucket '${this.config.bucket}': the purge could not be started. Their previous versions survive and remain readable via GetObject with a VersionId${describing}. Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the key(s) by hand. Underlying error: ${errorDetail$
|
|
5381
|
+
this.logger.warn(`Could not purge noncurrent versions of ${keys.length} key(s) in bucket '${this.config.bucket}': the purge could not be started. Their previous versions survive and remain readable via GetObject with a VersionId${describing}. Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the key(s) by hand. Underlying error: ${errorDetail$2(error)}`);
|
|
5382
5382
|
}
|
|
5383
5383
|
}
|
|
5384
5384
|
async purgeNoncurrentVersionsUnderPrefix(keyPrefix, options = {}) {
|
|
@@ -5392,7 +5392,7 @@ var S3StateBackend = class {
|
|
|
5392
5392
|
} catch (error) {
|
|
5393
5393
|
const prefixShown = displayIdent(keyPrefix, { maxCodePoints: STACK_REF_MAX_CODE_POINTS });
|
|
5394
5394
|
const describing = options.objectDescription ? ` (${options.objectDescription})` : "";
|
|
5395
|
-
this.logger.warn(safeMsg`Could not purge noncurrent versions under the prefix ${prefixShown} in bucket ${this.config.bucket}: the purge could not be started. Their previous versions survive and remain readable via GetObject with a VersionId${describing}. Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the prefix by hand. Underlying error: ${errorDetail$
|
|
5395
|
+
this.logger.warn(safeMsg`Could not purge noncurrent versions under the prefix ${prefixShown} in bucket ${this.config.bucket}: the purge could not be started. Their previous versions survive and remain readable via GetObject with a VersionId${describing}. Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the prefix by hand. Underlying error: ${errorDetail$2(error)}`);
|
|
5396
5396
|
return {
|
|
5397
5397
|
deletedBodies: 0,
|
|
5398
5398
|
complete: false
|
|
@@ -5418,7 +5418,7 @@ var S3StateBackend = class {
|
|
|
5418
5418
|
await this.saveCreateTokenLedger(stackName, region, ledger);
|
|
5419
5419
|
} catch (error) {
|
|
5420
5420
|
const normalized = normalizeAwsError(error, { bucket: this.config.bucket });
|
|
5421
|
-
throw new StateError(`Failed to renew the create-token ledger of stack ${this.stackRef(stackName, region)}: ${errorDetail$
|
|
5421
|
+
throw new StateError(`Failed to renew the create-token ledger of stack ${this.stackRef(stackName, region)}: ${errorDetail$2(normalized)}. The state record was left in place; re-run once the ledger can be written.`, normalized);
|
|
5422
5422
|
}
|
|
5423
5423
|
}
|
|
5424
5424
|
async deleteCreateTokenLedger(stackName, region) {
|
|
@@ -5435,7 +5435,7 @@ var S3StateBackend = class {
|
|
|
5435
5435
|
bucket: this.config.bucket,
|
|
5436
5436
|
operation: "DeleteObject"
|
|
5437
5437
|
});
|
|
5438
|
-
throw new StateError(`Failed to delete the create-token ledger for stack ${this.stackRef(stackName, region)}: ${errorDetail$
|
|
5438
|
+
throw new StateError(`Failed to delete the create-token ledger for stack ${this.stackRef(stackName, region)}: ${errorDetail$2(normalized)}. The state record was left in place; re-run once the ledger can be deleted.`, normalized);
|
|
5439
5439
|
}
|
|
5440
5440
|
}
|
|
5441
5441
|
async loadRollbackJournal(stackName, region) {
|
|
@@ -5461,6 +5461,58 @@ var S3StateBackend = class {
|
|
|
5461
5461
|
else newest.failedOperations = remaining;
|
|
5462
5462
|
await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
|
|
5463
5463
|
}
|
|
5464
|
+
async dropRollbackJournalFailedOperations(stackName, region, drop) {
|
|
5465
|
+
const journal = await this.loadRollbackJournal(stackName, region);
|
|
5466
|
+
if (!journal) return 0;
|
|
5467
|
+
let removed = 0;
|
|
5468
|
+
for (const segment of journal.segments) {
|
|
5469
|
+
if (!segment.failedOperations) continue;
|
|
5470
|
+
const kept = segment.failedOperations.filter((op) => !drop(op, segment));
|
|
5471
|
+
removed += segment.failedOperations.length - kept.length;
|
|
5472
|
+
if (kept.length === 0) delete segment.failedOperations;
|
|
5473
|
+
else segment.failedOperations = kept;
|
|
5474
|
+
}
|
|
5475
|
+
if (removed === 0) return 0;
|
|
5476
|
+
await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
|
|
5477
|
+
return removed;
|
|
5478
|
+
}
|
|
5479
|
+
async reduceRollbackJournalToFailedOperations(stackName, region, keep, supersededLogicalIds = [], demote = () => false) {
|
|
5480
|
+
const journal = await this.loadRollbackJournal(stackName, region);
|
|
5481
|
+
if (!journal) return 0;
|
|
5482
|
+
const carried = new Set(supersededLogicalIds);
|
|
5483
|
+
const kept = [];
|
|
5484
|
+
let count = 0;
|
|
5485
|
+
const keptBySegment = journal.segments.map((segment) => (segment.failedOperations ?? []).filter((op) => keep(op, segment)).map((op) => op.physicalIdRecoveredFromError === true && demote(op, segment) ? {
|
|
5486
|
+
...op,
|
|
5487
|
+
physicalIdRecoveredFromError: false
|
|
5488
|
+
} : op));
|
|
5489
|
+
const keptIds = new Set(keptBySegment.flat().map((op) => op.logicalId));
|
|
5490
|
+
for (let s = journal.segments.length - 1; s >= 0; s--) {
|
|
5491
|
+
const segment = journal.segments[s];
|
|
5492
|
+
for (const op of segment.operations) carried.add(op.logicalId);
|
|
5493
|
+
for (const id of segment.supersededLogicalIds ?? []) carried.add(id);
|
|
5494
|
+
const failed = keptBySegment[s];
|
|
5495
|
+
if (failed.length === 0) continue;
|
|
5496
|
+
const reduced = {
|
|
5497
|
+
...segment,
|
|
5498
|
+
initialDeploy: false,
|
|
5499
|
+
operations: [],
|
|
5500
|
+
failedOperations: failed
|
|
5501
|
+
};
|
|
5502
|
+
delete reduced.previousOutputs;
|
|
5503
|
+
delete reduced.previousCrossStackReads;
|
|
5504
|
+
addSupersededIds(reduced, [...carried].filter((id) => !keptIds.has(id) || segment.supersededLogicalIds?.includes(id)));
|
|
5505
|
+
kept.unshift(reduced);
|
|
5506
|
+
count += failed.length;
|
|
5507
|
+
}
|
|
5508
|
+
if (kept.length === 0) {
|
|
5509
|
+
await this.deleteRollbackJournal(stackName, region);
|
|
5510
|
+
return 0;
|
|
5511
|
+
}
|
|
5512
|
+
journal.segments = kept;
|
|
5513
|
+
await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
|
|
5514
|
+
return count;
|
|
5515
|
+
}
|
|
5464
5516
|
async popRollbackJournalSegment(stackName, region) {
|
|
5465
5517
|
const journal = await this.loadRollbackJournal(stackName, region);
|
|
5466
5518
|
if (!journal || journal.segments.length === 0) {
|
|
@@ -5529,7 +5581,7 @@ var S3StateBackend = class {
|
|
|
5529
5581
|
} catch (error) {
|
|
5530
5582
|
if (!isNoSuchKey(error) && error.name !== "NotFound") {
|
|
5531
5583
|
gone = false;
|
|
5532
|
-
this.logger.warn(`Failed to delete rollback journal for ${this.stackRef(stackName, region)}: ${errorDetail$
|
|
5584
|
+
this.logger.warn(`Failed to delete rollback journal for ${this.stackRef(stackName, region)}: ${errorDetail$2(error)}`);
|
|
5533
5585
|
}
|
|
5534
5586
|
}
|
|
5535
5587
|
await this.purgeNoncurrentVersions([key], { objectDescription: "the rollback journal, whose `failedOperations[].attemptedProperties` records the properties of the failed write verbatim" });
|
|
@@ -5647,7 +5699,7 @@ var S3StateBackend = class {
|
|
|
5647
5699
|
};
|
|
5648
5700
|
} catch (error) {
|
|
5649
5701
|
if (isNoSuchKey(error)) return null;
|
|
5650
|
-
throw new StateError(`Failed to get legacy state for stack ${this.displayName(stackName)}: ${errorDetail$
|
|
5702
|
+
throw new StateError(`Failed to get legacy state for stack ${this.displayName(stackName)}: ${errorDetail$2(error)}`, error instanceof Error ? error : void 0);
|
|
5651
5703
|
}
|
|
5652
5704
|
}
|
|
5653
5705
|
parseStateBody(bodyString, stackName) {
|
|
@@ -5699,7 +5751,7 @@ function safeSegment(value) {
|
|
|
5699
5751
|
function stackRef(stackName, region) {
|
|
5700
5752
|
return region === void 0 ? safeSegment(stackName) : `${safeSegment(stackName)} (${safeSegment(region)})`;
|
|
5701
5753
|
}
|
|
5702
|
-
function errorDetail(error) {
|
|
5754
|
+
function errorDetail$1(error) {
|
|
5703
5755
|
return displaySafe(error instanceof Error ? error.message : error, { asciiOnly: true }) || "<unrenderable>";
|
|
5704
5756
|
}
|
|
5705
5757
|
function isLockInfoExpired(lockInfo) {
|
|
@@ -5835,7 +5887,7 @@ var LockManager = class {
|
|
|
5835
5887
|
}
|
|
5836
5888
|
return false;
|
|
5837
5889
|
}
|
|
5838
|
-
throw new LockError(`Failed to acquire lock for stack ${safeSegment(stackName)} (${safeSegment(region)}): ` + errorDetail(error), error instanceof Error ? error : void 0);
|
|
5890
|
+
throw new LockError(`Failed to acquire lock for stack ${safeSegment(stackName)} (${safeSegment(region)}): ` + errorDetail$1(error), error instanceof Error ? error : void 0);
|
|
5839
5891
|
}
|
|
5840
5892
|
}
|
|
5841
5893
|
async putLockObject(key, lockInfo, condition = { IfNoneMatch: "*" }) {
|
|
@@ -5890,7 +5942,7 @@ var LockManager = class {
|
|
|
5890
5942
|
return null;
|
|
5891
5943
|
}
|
|
5892
5944
|
if (error instanceof LockError) throw error;
|
|
5893
|
-
throw new LockError(`Failed to get lock info for stack ${shownStack}: ${errorDetail(error)}`, error instanceof Error ? error : void 0);
|
|
5945
|
+
throw new LockError(`Failed to get lock info for stack ${shownStack}: ${errorDetail$1(error)}`, error instanceof Error ? error : void 0);
|
|
5894
5946
|
}
|
|
5895
5947
|
}
|
|
5896
5948
|
async isLocked(stackName, region) {
|
|
@@ -5938,16 +5990,16 @@ var LockManager = class {
|
|
|
5938
5990
|
this.logger.warn(`Not releasing the lock for stack ${stackRef(stackName, region)}: the conditional delete could not be evaluated here, and this process could not confirm the lock is still its own. Leaving it in place rather than risk deleting another process's lock. It expires on its own, or clear it with cdkd force-unlock. If this repeats, grant s3:GetObject on the lock key -- a delete conditioned on an ETag requires it.`);
|
|
5939
5991
|
return;
|
|
5940
5992
|
}
|
|
5941
|
-
this.logger.debug(`Conditional lock release for stack ${stackRef(stackName, region)} is not supported here (${errorDetail(error)}); retrying unconditionally`);
|
|
5993
|
+
this.logger.debug(`Conditional lock release for stack ${stackRef(stackName, region)} is not supported here (${errorDetail$1(error)}); retrying unconditionally`);
|
|
5942
5994
|
try {
|
|
5943
5995
|
await this.deleteLock(stackName, region);
|
|
5944
5996
|
this.logger.debug(`Lock released for stack: ${stackRef(stackName, region)}`);
|
|
5945
5997
|
return;
|
|
5946
5998
|
} catch (fallbackError) {
|
|
5947
|
-
throw new LockError(`Failed to release lock for stack ${stackRef(stackName, region)}: ${errorDetail(fallbackError)}`, fallbackError instanceof Error ? fallbackError : void 0);
|
|
5999
|
+
throw new LockError(`Failed to release lock for stack ${stackRef(stackName, region)}: ${errorDetail$1(fallbackError)}`, fallbackError instanceof Error ? fallbackError : void 0);
|
|
5948
6000
|
}
|
|
5949
6001
|
}
|
|
5950
|
-
throw new LockError(`Failed to release lock for stack ${stackRef(stackName, region)}: ${errorDetail(error)}`, error instanceof Error ? error : void 0);
|
|
6002
|
+
throw new LockError(`Failed to release lock for stack ${stackRef(stackName, region)}: ${errorDetail$1(error)}`, error instanceof Error ? error : void 0);
|
|
5951
6003
|
} finally {
|
|
5952
6004
|
await this.purgeLockVersions(this.getLockKey(stackName, region), "release");
|
|
5953
6005
|
}
|
|
@@ -6006,7 +6058,7 @@ var LockManager = class {
|
|
|
6006
6058
|
objectDescription: LOCK_OBJECT_DESCRIPTION
|
|
6007
6059
|
});
|
|
6008
6060
|
} catch (error) {
|
|
6009
|
-
report(`Could not purge noncurrent versions of the lock key ${displayIdent(key, { maxCodePoints: STACK_REF_MAX_CODE_POINTS })} in bucket '${this.config.bucket}': the purge could not be started. Their previous versions survive and remain readable via GetObject with a VersionId (${LOCK_OBJECT_DESCRIPTION}). Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the key by hand. Underlying error: ${errorDetail(error)}`);
|
|
6061
|
+
report(`Could not purge noncurrent versions of the lock key ${displayIdent(key, { maxCodePoints: STACK_REF_MAX_CODE_POINTS })} in bucket '${this.config.bucket}': the purge could not be started. Their previous versions survive and remain readable via GetObject with a VersionId (${LOCK_OBJECT_DESCRIPTION}). Grant s3:ListBucketVersions and s3:DeleteObjectVersion on the state bucket, or purge the key by hand. Underlying error: ${errorDetail$1(error)}`);
|
|
6010
6062
|
}
|
|
6011
6063
|
}
|
|
6012
6064
|
trackHeldLock(args) {
|
|
@@ -6086,7 +6138,7 @@ var LockManager = class {
|
|
|
6086
6138
|
this.logger.warn(`Lost the lock for stack ${stackRef(held.stackName, held.region)} while the operation was still running: the lock object has been replaced or removed. Another cdkd process may now be writing to this stack concurrently. This process will not delete the current lock when it finishes.`);
|
|
6087
6139
|
return;
|
|
6088
6140
|
}
|
|
6089
|
-
this.logger.debug(`Lock renewal for stack ${stackRef(held.stackName, held.region)} failed, will retry: ${errorDetail(error)}`);
|
|
6141
|
+
this.logger.debug(`Lock renewal for stack ${stackRef(held.stackName, held.region)} failed, will retry: ${errorDetail$1(error)}`);
|
|
6090
6142
|
if (!held.warnedPastExpiry && Date.now() >= held.info.expiresAt) {
|
|
6091
6143
|
held.warnedPastExpiry = true;
|
|
6092
6144
|
this.logger.warn(`Lock renewal for stack ${stackRef(held.stackName, held.region)} has been failing long enough that the lock expired at ${new Date(held.info.expiresAt).toISOString()}. Another cdkd process can now take it while this operation is still running. Renewal keeps retrying.`);
|
|
@@ -7622,6 +7674,10 @@ const CLASSIFIER_IDENTIFIER_FIELDS = /* @__PURE__ */ new Set([
|
|
|
7622
7674
|
function isAuxiliaryAnchor(key, descriptor) {
|
|
7623
7675
|
return key === "logicalId" && descriptor.enumerable === false && descriptor.writable === false && typeof descriptor.value === "string" && descriptor.value.endsWith("/auxiliary");
|
|
7624
7676
|
}
|
|
7677
|
+
const CREATED_BEFORE_FAILURE_MARK = Symbol.for("cdkd.createdBeforeFailure");
|
|
7678
|
+
function isCreatedBeforeFailureMark(key, descriptor) {
|
|
7679
|
+
return key === CREATED_BEFORE_FAILURE_MARK && descriptor.enumerable === false && descriptor.writable === false && typeof descriptor.value === "object" && descriptor.value !== null && Object.isFrozen(descriptor.value);
|
|
7680
|
+
}
|
|
7625
7681
|
function isPlainContainer(value) {
|
|
7626
7682
|
const proto = Object.getPrototypeOf(value);
|
|
7627
7683
|
return Array.isArray(value) ? proto === Array.prototype : proto === Object.prototype || proto === null;
|
|
@@ -7709,7 +7765,7 @@ function maskSecretsInError(error, secrets, extraMask) {
|
|
|
7709
7765
|
if (key === "message" || key === "cause" || key === "stack") continue;
|
|
7710
7766
|
const descriptor = Object.getOwnPropertyDescriptor(link, key);
|
|
7711
7767
|
if (!descriptor) continue;
|
|
7712
|
-
descriptors[key] = typeof key === "string" && CLASSIFIER_IDENTIFIER_FIELDS.has(key) && typeof descriptor.value === "string" || isAuxiliaryAnchor(key, descriptor) ? descriptor : maskDescriptorValue(descriptor, maskText);
|
|
7768
|
+
descriptors[key] = typeof key === "string" && CLASSIFIER_IDENTIFIER_FIELDS.has(key) && typeof descriptor.value === "string" || isAuxiliaryAnchor(key, descriptor) || isCreatedBeforeFailureMark(key, descriptor) ? descriptor : maskDescriptorValue(descriptor, maskText);
|
|
7713
7769
|
if (descriptors[key] !== descriptor) changed = true;
|
|
7714
7770
|
}
|
|
7715
7771
|
let cause = Object.getOwnPropertyDescriptor(link, "cause");
|
|
@@ -9107,129 +9163,6 @@ var ReplacementRulesRegistry = class {
|
|
|
9107
9163
|
}
|
|
9108
9164
|
};
|
|
9109
9165
|
|
|
9110
|
-
//#endregion
|
|
9111
|
-
//#region src/provisioning/auxiliary-failure.ts
|
|
9112
|
-
const AUXILIARY_LOGICAL_ID_SUFFIX = "/auxiliary";
|
|
9113
|
-
const MAX_DEPTH = 5;
|
|
9114
|
-
function auxiliaryLogicalId(ownerLogicalId) {
|
|
9115
|
-
return `${ownerLogicalId}${AUXILIARY_LOGICAL_ID_SUFFIX}`;
|
|
9116
|
-
}
|
|
9117
|
-
const RETRY_AUXILIARY_OWNER = "withRetry";
|
|
9118
|
-
function isAuxiliaryMarkOf(link, ownerLogicalId) {
|
|
9119
|
-
try {
|
|
9120
|
-
if (typeof link !== "object" && typeof link !== "function" || link === null) return false;
|
|
9121
|
-
const own = Object.getOwnPropertyDescriptor(link, "logicalId");
|
|
9122
|
-
return isAuxiliaryMark(own) && own?.value === auxiliaryLogicalId(ownerLogicalId);
|
|
9123
|
-
} catch {
|
|
9124
|
-
return false;
|
|
9125
|
-
}
|
|
9126
|
-
}
|
|
9127
|
-
function isAuxiliaryMark(descriptor) {
|
|
9128
|
-
return descriptor !== void 0 && descriptor.enumerable === false && descriptor.writable === false && typeof descriptor.value === "string" && descriptor.value.endsWith(AUXILIARY_LOGICAL_ID_SUFFIX);
|
|
9129
|
-
}
|
|
9130
|
-
function isAuxiliaryFailure(error) {
|
|
9131
|
-
try {
|
|
9132
|
-
let current = error;
|
|
9133
|
-
for (let depth = 0; depth < MAX_DEPTH && typeof current === "object" && current !== null; depth++) {
|
|
9134
|
-
if (isAuxiliaryMark(Object.getOwnPropertyDescriptor(current, "logicalId"))) return true;
|
|
9135
|
-
current = current.cause;
|
|
9136
|
-
}
|
|
9137
|
-
} catch {}
|
|
9138
|
-
return false;
|
|
9139
|
-
}
|
|
9140
|
-
const CREATED_BEFORE_FAILURE = Symbol.for("cdkd.createdBeforeFailure");
|
|
9141
|
-
function markCreatedBeforeFailure(error, ownerLogicalId, resourceType, physicalId) {
|
|
9142
|
-
try {
|
|
9143
|
-
if (typeof error !== "object" || error === null || !Object.isExtensible(error)) return error;
|
|
9144
|
-
if (physicalId === "") return error;
|
|
9145
|
-
Object.defineProperty(error, CREATED_BEFORE_FAILURE, {
|
|
9146
|
-
value: Object.freeze({
|
|
9147
|
-
logicalId: ownerLogicalId,
|
|
9148
|
-
resourceType,
|
|
9149
|
-
physicalId
|
|
9150
|
-
}),
|
|
9151
|
-
enumerable: false,
|
|
9152
|
-
writable: false,
|
|
9153
|
-
configurable: true
|
|
9154
|
-
});
|
|
9155
|
-
} catch {}
|
|
9156
|
-
return error;
|
|
9157
|
-
}
|
|
9158
|
-
function createdMarkOn(link) {
|
|
9159
|
-
const value = link[CREATED_BEFORE_FAILURE];
|
|
9160
|
-
if (typeof value !== "object" || value === null) return void 0;
|
|
9161
|
-
const { logicalId, resourceType, physicalId } = value;
|
|
9162
|
-
if (typeof logicalId !== "string" || typeof resourceType !== "string" || typeof physicalId !== "string" || physicalId === "") return;
|
|
9163
|
-
return {
|
|
9164
|
-
logicalId,
|
|
9165
|
-
resourceType,
|
|
9166
|
-
physicalId
|
|
9167
|
-
};
|
|
9168
|
-
}
|
|
9169
|
-
function createdBeforeFailure(error, logicalId, resourceType) {
|
|
9170
|
-
try {
|
|
9171
|
-
let current = error;
|
|
9172
|
-
for (let depth = 0; depth < 10 && typeof current === "object" && current !== null; depth++) {
|
|
9173
|
-
const mark = createdMarkOn(current);
|
|
9174
|
-
if (mark) return mark.logicalId === logicalId && mark.resourceType === resourceType ? mark.physicalId : void 0;
|
|
9175
|
-
const own = Object.getOwnPropertyDescriptor(current, "logicalId");
|
|
9176
|
-
if (typeof own?.value === "string" && own.value !== logicalId && !isAuxiliaryMarkOf(current, logicalId)) return;
|
|
9177
|
-
current = current.cause;
|
|
9178
|
-
}
|
|
9179
|
-
} catch {}
|
|
9180
|
-
}
|
|
9181
|
-
function hasCreatedBeforeFailure(error) {
|
|
9182
|
-
try {
|
|
9183
|
-
let current = error;
|
|
9184
|
-
for (let depth = 0; depth < 10 && typeof current === "object" && current !== null; depth++) {
|
|
9185
|
-
if (createdMarkOn(current)) return true;
|
|
9186
|
-
current = current.cause;
|
|
9187
|
-
}
|
|
9188
|
-
} catch {}
|
|
9189
|
-
return false;
|
|
9190
|
-
}
|
|
9191
|
-
function carryCreatedBeforeFailure(from, to) {
|
|
9192
|
-
try {
|
|
9193
|
-
if (typeof to !== "object" || to === null) return to;
|
|
9194
|
-
let current = from;
|
|
9195
|
-
let mark;
|
|
9196
|
-
for (let depth = 0; depth < 10 && typeof current === "object" && current !== null && !mark; depth++) {
|
|
9197
|
-
mark = createdMarkOn(current);
|
|
9198
|
-
current = current.cause;
|
|
9199
|
-
}
|
|
9200
|
-
if (!mark) return to;
|
|
9201
|
-
let probe = to;
|
|
9202
|
-
for (let depth = 0; depth < 10 && typeof probe === "object" && probe !== null; depth++) {
|
|
9203
|
-
if (createdMarkOn(probe)) return to;
|
|
9204
|
-
probe = probe.cause;
|
|
9205
|
-
}
|
|
9206
|
-
return markCreatedBeforeFailure(to, mark.logicalId, mark.resourceType, mark.physicalId);
|
|
9207
|
-
} catch {
|
|
9208
|
-
return to;
|
|
9209
|
-
}
|
|
9210
|
-
}
|
|
9211
|
-
function markAuxiliaryFailure(error, ownerLogicalId) {
|
|
9212
|
-
try {
|
|
9213
|
-
let current = error;
|
|
9214
|
-
for (let depth = 0; depth < MAX_DEPTH && typeof current === "object" && current !== null; depth++) {
|
|
9215
|
-
const own = Object.getOwnPropertyDescriptor(current, "logicalId");
|
|
9216
|
-
if (typeof own?.value === "string") {
|
|
9217
|
-
if (isAuxiliaryMark(own)) return error;
|
|
9218
|
-
} else {
|
|
9219
|
-
if (Object.isExtensible(current) && own?.configurable !== false) Object.defineProperty(current, "logicalId", {
|
|
9220
|
-
value: auxiliaryLogicalId(ownerLogicalId),
|
|
9221
|
-
enumerable: false,
|
|
9222
|
-
writable: false,
|
|
9223
|
-
configurable: true
|
|
9224
|
-
});
|
|
9225
|
-
return error;
|
|
9226
|
-
}
|
|
9227
|
-
current = current.cause;
|
|
9228
|
-
}
|
|
9229
|
-
} catch {}
|
|
9230
|
-
return error;
|
|
9231
|
-
}
|
|
9232
|
-
|
|
9233
9166
|
//#endregion
|
|
9234
9167
|
//#region src/deployment/retry.ts
|
|
9235
9168
|
const IAM_PROPAGATION_INITIAL_DELAY_MS = 250;
|
|
@@ -15291,10 +15224,10 @@ function refuseMalformedResourcesForDestroy(state, stackName, region, recovery)
|
|
|
15291
15224
|
throw markNonRetryable(new CdkdError(malformedDestroyResourcesRefusalMessage(stackName, region, recovery), STATE_RESOURCES_MALFORMED));
|
|
15292
15225
|
}
|
|
15293
15226
|
const STATE_REGION_DIVERGED = "STATE_REGION_DIVERGED";
|
|
15294
|
-
function divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBodyRegion, resourceCount, recovery) {
|
|
15227
|
+
function divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBodyRegion, resourceCount, recovery, provenOrphans = 0) {
|
|
15295
15228
|
const cap = STACK_REF_MAX_CODE_POINTS;
|
|
15296
15229
|
const exact = rendersExactly(stackName, cap) && rendersExactly(keyRegion, cap) && isPasteableIdent(stackName) && isPasteableIdent(keyRegion);
|
|
15297
|
-
const lists = resourceCount === void 0 ? "its resources map cannot be read" : `it still lists ${resourceCount} resource${resourceCount === 1 ? "" : "s"}`;
|
|
15230
|
+
const lists = resourceCount === void 0 ? "its resources map cannot be read" : resourceCount === 0 && provenOrphans > 0 ? `its rollback journal holds ${provenOrphans} failed create${provenOrphans === 1 ? "" : "s"} whose resource the destroy would delete` : `it still lists ${resourceCount} resource${resourceCount === 1 ? "" : "s"}`;
|
|
15298
15231
|
const kind = describeRegionValueKind(divergentBodyRegion);
|
|
15299
15232
|
const opening = exact ? `cdkd will not destroy stack ${shellQuote(safeIdentifier(stackName, cap))} (${shellQuote(safeIdentifier(keyRegion, cap))}): the state record read from that region's key carries a 'region' of its own (${kind}) that is not the key's, and ${lists}` : `cdkd will not destroy the state record this command loaded: it carries a 'region' of its own (${kind}) that is not the region of the key it was read from, and ${lists}`;
|
|
15300
15233
|
const listing = withheldListingPointer(recovery);
|
|
@@ -15302,11 +15235,11 @@ function divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBody
|
|
|
15302
15235
|
const remedy = exact ? "Re-run with --verbose to see what the record's region field holds, then either destroy against the region the resources are really in, or repair that field to match the key it is stored under and re-run. " + withheldAccountClause(withheldAccounts, "the command at the end of this message prints") + "To drop the record and leave the live resources standing, spelled out rather than pasteable because that command DELETES a record: " + dropRecordTemplate(recovery) : "This record's stack name or region does NOT render exactly — what any surrounding output shows is a sanitized form, and another record may render identically — so this message names no target and offers no command against one. List the records with " + (listing.line === void 0 ? `${WITHHELD_LISTING_POINTER}. Inspect it with: ${inspectCommand(void 0, void 0)}` : `${listing.pointer}.` + destroyAccountClause(recovery) + `\n${listing.line}\nInspect it with: ${inspectCommand(void 0, void 0, recovery)}`);
|
|
15303
15236
|
return `${opening} ${resourceCount === void 0 ? `— so cdkd can neither count what it would delete nor tell which region it is in` : `— so cdkd cannot tell which region those resources are in`}. cdkd stamps the key's region into every record it writes, so this record was not written by cdkd. Destroying against the key's region would issue every delete there; if the record's own region is the honest half, each delete comes back not-found, which this command reads as ALREADY DELETED — it would report success, remove the record, and leave every resource standing in the other region with nothing naming it. ${remedy}`;
|
|
15304
15237
|
}
|
|
15305
|
-
function refuseDivergentRecordRegionForDestroy(state, stackName, keyRegion, divergentBodyRegion, recovery) {
|
|
15238
|
+
function refuseDivergentRecordRegionForDestroy(state, stackName, keyRegion, divergentBodyRegion, recovery, provenOrphans = 0) {
|
|
15306
15239
|
if (divergentBodyRegion === void 0) return;
|
|
15307
15240
|
const resourceCount = isReadableBag(state.resources) ? Object.keys(state.resources).length : void 0;
|
|
15308
|
-
if (resourceCount === 0) return;
|
|
15309
|
-
throw markNonRetryable(new CdkdError(divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBodyRegion, resourceCount, recovery), STATE_REGION_DIVERGED));
|
|
15241
|
+
if (resourceCount === 0 && provenOrphans === 0) return;
|
|
15242
|
+
throw markNonRetryable(new CdkdError(divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBodyRegion, resourceCount, recovery, provenOrphans), STATE_REGION_DIVERGED));
|
|
15310
15243
|
}
|
|
15311
15244
|
function malformedDeployResourcesRefusalMessage(rawStackName, rawRegion) {
|
|
15312
15245
|
const stackName = absentIfEmpty(rawStackName);
|
|
@@ -15994,7 +15927,7 @@ function isPlainObject$2(value) {
|
|
|
15994
15927
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
15995
15928
|
}
|
|
15996
15929
|
const DYNAMIC_REFERENCE_OPEN = "{{resolve:";
|
|
15997
|
-
const NESTED_STACK_TYPE$
|
|
15930
|
+
const NESTED_STACK_TYPE$3 = "AWS::CloudFormation::Stack";
|
|
15998
15931
|
const NESTED_OUTPUT_PREFIX = "Outputs.";
|
|
15999
15932
|
function carriesSecretValue(value, corpora) {
|
|
16000
15933
|
if (carriesSecretMask(value)) return true;
|
|
@@ -16069,7 +16002,7 @@ function intrinsicKey(value) {
|
|
|
16069
16002
|
const key = keys[0];
|
|
16070
16003
|
return key === "Ref" || key.startsWith("Fn::") ? key : void 0;
|
|
16071
16004
|
}
|
|
16072
|
-
const OPAQUE_ATTRIBUTE_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::CustomResource", NESTED_STACK_TYPE$
|
|
16005
|
+
const OPAQUE_ATTRIBUTE_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::CustomResource", NESTED_STACK_TYPE$3]);
|
|
16073
16006
|
function hasOpaqueAttributes(logicalId, walk) {
|
|
16074
16007
|
const definition = walk.resources[logicalId];
|
|
16075
16008
|
const type = isPlainObject$2(definition) ? definition["Type"] : void 0;
|
|
@@ -16426,7 +16359,7 @@ function passedKey(passed) {
|
|
|
16426
16359
|
function isNestedStackRow(logicalId, walk) {
|
|
16427
16360
|
if (!Object.hasOwn(walk.resources, logicalId)) return false;
|
|
16428
16361
|
const definition = walk.resources[logicalId];
|
|
16429
|
-
return isPlainObject$2(definition) && definition["Type"] === NESTED_STACK_TYPE$
|
|
16362
|
+
return isPlainObject$2(definition) && definition["Type"] === NESTED_STACK_TYPE$3;
|
|
16430
16363
|
}
|
|
16431
16364
|
function getAttAttribute(operand, target) {
|
|
16432
16365
|
if (Array.isArray(operand)) return operand.length === 2 && typeof operand[1] === "string" ? operand[1] : void 0;
|
|
@@ -18046,6 +17979,7 @@ async function resolveGetAtt(getAtt, context) {
|
|
|
18046
17979
|
}
|
|
18047
17980
|
const resource = this.lookupResourceRecord(logicalId, "Fn::GetAtt", context);
|
|
18048
17981
|
if (!resource) throw markNonRetryable(/* @__PURE__ */ new Error(`Resource ${this.displayMasked(logicalId, context)} not found for Fn::GetAtt`));
|
|
17982
|
+
recordSecretNamedRead(logicalId, void 0, context);
|
|
18049
17983
|
if (!(resource.resourceType === "AWS::EC2::VPC" && attributeName === "Ipv6CidrBlocks") && resource.attributes !== void 0) {
|
|
18050
17984
|
const storedValue = Object.hasOwn(resource.attributes, attributeName) ? resource.attributes[attributeName] : void 0;
|
|
18051
17985
|
const flatValue = isImpossibleEmptyStoredAttribute(resource.resourceType, attributeName, storedValue) ? void 0 : storedValue;
|
|
@@ -18099,6 +18033,7 @@ async function resolveGetAtt(getAtt, context) {
|
|
|
18099
18033
|
throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${loggedLogicalId}, ${this.displayMasked(attributeName, context)}]: the nested stack ${quotedRender(loggedLogicalId, "'")} declares no output named ${quotedRender(this.displayMasked(this.outputNameLogText(attributeName, context), context), "'")}. Its outputs are ${this.displayMasked(declaredText, context)}. Check the output name in the nested stack's template, and deploy the child stack again if you have just added it.`));
|
|
18100
18034
|
}
|
|
18101
18035
|
const value = await this.constructWithStaleRecordHeal(resource, attributeName, context, logicalId);
|
|
18036
|
+
recordSecretNamedRead(logicalId, value, context);
|
|
18102
18037
|
this.logger.debug(`Resolved Fn::GetAtt: ${this.logRender(logicalId, context)}.${this.logRender(attributeName, context)} resolved to ${this.logRender(stringifyAttributeForLog(attributeName, this.maskValueLeaves(value, context)), context, {
|
|
18103
18038
|
structured: isStructured(value),
|
|
18104
18039
|
redacted: isSensitiveAttributeName(attributeName)
|
|
@@ -18128,6 +18063,7 @@ function publicNoEchoTokens(context, producer) {
|
|
|
18128
18063
|
return tokens;
|
|
18129
18064
|
}
|
|
18130
18065
|
function noteAttributeSecrecy(logicalId, attributeName, value, context) {
|
|
18066
|
+
recordSecretNamedRead(logicalId, value, context);
|
|
18131
18067
|
const declared = context.noEchoAttributeResources?.get(logicalId);
|
|
18132
18068
|
if ((declared === true || declared !== void 0 && declared.has(attributeName)) && context.recordedSecretValues) recordFreshNoEchoValuesIn(value, context.recordedSecretValues, void 0, this.publicNoEchoTokens(context, logicalId));
|
|
18133
18069
|
if (context.redactedAttributeReads !== void 0 && carriesSecretMask(value)) {
|
|
@@ -18141,6 +18077,17 @@ function noteAttributeSecrecy(logicalId, attributeName, value, context) {
|
|
|
18141
18077
|
}
|
|
18142
18078
|
return value;
|
|
18143
18079
|
}
|
|
18080
|
+
function recordSecretNamedRead(logicalId, value, context) {
|
|
18081
|
+
const bag = context.printingSecrets ?? context.recordedSecretValues;
|
|
18082
|
+
if (bag === void 0 || context.secretNameNeedles === void 0) return;
|
|
18083
|
+
const needles = context.secretNameNeedles(logicalId);
|
|
18084
|
+
if (needles === void 0) return;
|
|
18085
|
+
for (const needle of needles) recordLogOnlyValue(bag, needle);
|
|
18086
|
+
for (const leaf of wholeStringLeavesOf(value)) for (const needle of needles) if (needle.length >= 4 && leaf.includes(needle)) {
|
|
18087
|
+
recordLogOnlyValue(bag, leaf);
|
|
18088
|
+
break;
|
|
18089
|
+
}
|
|
18090
|
+
}
|
|
18144
18091
|
function rejectPlaceholderArnAttribute(resource, attributeName, value, logicalId, context, healOutcome) {
|
|
18145
18092
|
if (!isStalePlaceholderArnAttribute(resource.resourceType, attributeName, value)) return;
|
|
18146
18093
|
throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${resource.resourceType}: the recorded value ${quotedRender(stringifyValue(this.maskValueLeaves(value, context)), "\"")} is a placeholder written by a cdkd version older than issue #1681 — its region and account fields are literal wildcards, so it is not a usable ARN. ` + this.staleRecordRemedy(healOutcome, context)));
|
|
@@ -20268,6 +20215,7 @@ async function resolveRef(logicalId, context, onParameter) {
|
|
|
20268
20215
|
const resource = this.lookupResourceRecord(logicalId, "Ref", context);
|
|
20269
20216
|
if (resource) {
|
|
20270
20217
|
const refValue = this.resolveRefValue(logicalId, resource, context);
|
|
20218
|
+
recordSecretNamedRead(logicalId, refValue, context);
|
|
20271
20219
|
this.logger.debug(`Resolved Ref to resource: ${this.logRender(logicalId, context)} resolved to ${this.logRender(String(refValue), context)}`);
|
|
20272
20220
|
return refValue;
|
|
20273
20221
|
}
|
|
@@ -22068,7 +22016,7 @@ var CloudControlProvider = class {
|
|
|
22068
22016
|
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
22069
22017
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
22070
22018
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
22071
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
22019
|
+
const { ASGProvider } = await import("./asg-provider-BwWy0pBH.js");
|
|
22072
22020
|
const delegateRegion = ambientRegion();
|
|
22073
22021
|
let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
|
|
22074
22022
|
if (asgProvider === void 0) {
|
|
@@ -22174,7 +22122,7 @@ var CloudControlProvider = class {
|
|
|
22174
22122
|
const family = SDK_DELETE_FAMILIES.get(resourceType);
|
|
22175
22123
|
const cached = this.sdkDeleteDelegates.get(family);
|
|
22176
22124
|
if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
|
|
22177
|
-
const provider = family === "rds" ? new (await (import("./rds-provider-
|
|
22125
|
+
const provider = family === "rds" ? new (await (import("./rds-provider-McCDKyXN.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-Cdp4jX8S.js"))).NeptuneProvider({ region: ccRegion });
|
|
22178
22126
|
this.sdkDeleteDelegates.set(family, {
|
|
22179
22127
|
region: ccRegion,
|
|
22180
22128
|
provider
|
|
@@ -22997,6 +22945,10 @@ function withCurrentResourceSecrets(secrets, fn) {
|
|
|
22997
22945
|
const outer = boundSecretBagsStore.getStore() ?? [];
|
|
22998
22946
|
return boundSecretBagsStore.run([...outer, secrets], () => currentResourceSecretsStore.run(secrets, fn));
|
|
22999
22947
|
}
|
|
22948
|
+
function withPrintingSecrets(secrets, fn) {
|
|
22949
|
+
const outer = boundSecretBagsStore.getStore() ?? [];
|
|
22950
|
+
return boundSecretBagsStore.run([...outer, secrets], fn);
|
|
22951
|
+
}
|
|
23000
22952
|
function getCurrentResourceSecrets() {
|
|
23001
22953
|
return currentResourceSecretsStore.getStore();
|
|
23002
22954
|
}
|
|
@@ -23073,8 +23025,34 @@ const CR_MASKED_SERVICE_TOKEN_SKIP_REASON = "masked ServiceToken in state — De
|
|
|
23073
23025
|
const CR_REFERENCE_SERVICE_TOKEN_SKIP_REASON = "dynamic reference as ServiceToken in state — handler not invoked";
|
|
23074
23026
|
const CR_DELETE_INVOKE_FAILED_SKIP_REASON = "Delete request to the handler did not complete — resource unproven";
|
|
23075
23027
|
const CR_DELETE_HANDLER_FAILED_SKIP_REASON = "Delete handler reported FAILED — resource unproven";
|
|
23076
|
-
const
|
|
23028
|
+
const CR_BACKING_LAMBDA_GONE_SKIP_REASON = "backing Lambda function is gone — Delete handler not invoked";
|
|
23029
|
+
function crSkipNotARetryCaveat(context, logicalId) {
|
|
23030
|
+
return `NOTE this record is a POINTER, not a retry: the same destroy run deletes the backing Lambda, so the next 'cdkd destroy' cannot reach the handler either: it skips this resource again and keeps the record (issue 2115). Tear the resource down by hand, then drop the record with ${stateOrphanRecordRemedy(context, logicalId)}.`;
|
|
23031
|
+
}
|
|
23077
23032
|
const DEPLOY_SKIP_CAVEAT = "NOTE this arm is ALSO reached from cdkd deploy. Since issue 1762 the DELETE of a resource removed from the template behaves like destroy — the record is KEPT and the next deploy re-attempts it — but a REPLACEMENT / rollback delete FAILS the resource instead (https://github.com/go-to-k/cdkd/issues/1762), leaving the old one untracked; there, tear the resource down by hand.";
|
|
23033
|
+
function crDeployNoStateOrphan(logicalId) {
|
|
23034
|
+
return `For a resource removed from the template, to give up on the delete and stop tracking it, drop the record with ${stateOrphanRecordRemedy(void 0, logicalId)}.`;
|
|
23035
|
+
}
|
|
23036
|
+
function crDeploySkipTail(logicalId) {
|
|
23037
|
+
return "Meanwhile 'cdkd deploy --allow-unaddressed' exits 0 (a deploy-only flag; 'cdkd rollback' has none); the record stays and each deploy re-attempts the delete. A delete-first REPLACEMENT or a rollback delete usually FAILS the resource and keeps the record (https://github.com/go-to-k/cdkd/issues/1762). Where the other copy already exists (a replacement that created the new resource first, or a rollback that re-created the old one first), the skip only warns and the surviving copy is no longer tracked, so tear it down by hand. " + crDeployNoStateOrphan(logicalId);
|
|
23038
|
+
}
|
|
23039
|
+
const CR_DEPLOY_HANDLER_SKIP_HEAD = "This delete is not part of a stack destroy (a 'cdkd deploy' template removal, replacement or rollback, or a 'cdkd rollback'). For a resource removed from the template the record is KEPT and the next 'cdkd deploy' re-sends the Delete: fix what made it fail (the handler's Delete logic, or what stopped the invoke) and re-deploy. That reaches the handler only while its function exists: if this deploy also deleted the backing Lambda, the next deploy finds it gone and DROPS the record with a warning, so tear down what the handler manages by hand. ";
|
|
23040
|
+
const CR_DEPLOY_UNADDRESSABLE_HEAD = "This delete is not part of a stack destroy (a 'cdkd deploy' template removal, replacement or rollback, or a 'cdkd rollback'). For a resource removed from the template the record is KEPT and every 'cdkd deploy' skips it again until ServiceToken is restored: put the provider's Lambda function or SNS topic ARN back in state.json and re-deploy, which sends the Delete while that handler exists. If its Lambda function is gone, that deploy DROPS the record with a warning instead, so tear down what the handler manages by hand. ";
|
|
23041
|
+
function crDestroyUnaddressableRemedy(context, logicalId) {
|
|
23042
|
+
return `Tear the resource down by hand, then drop the record with ${stateOrphanRecordRemedy(context, logicalId)}. Restoring ServiceToken (the provider's Lambda function or SNS topic ARN) in state.json and re-running helps only while that handler still exists: a destroy goes on to delete its backing Lambda.`;
|
|
23043
|
+
}
|
|
23044
|
+
function handlerSkipRemedy(context, logicalId) {
|
|
23045
|
+
return context?.stackDestroy === true ? ` — cdkd is KEEPING the state record and the run exits non-zero. ${crSkipNotARetryCaveat(context, logicalId)}` : `. ${CR_DEPLOY_HANDLER_SKIP_HEAD}${crDeploySkipTail(logicalId)}`;
|
|
23046
|
+
}
|
|
23047
|
+
function crUnresolvedTokenUpdateRemedy() {
|
|
23048
|
+
return "This indicates an unresolved value in the template, or, on a rollback, in the resource's recorded state. Check that the template resolves ServiceToken to the provider's Lambda function or SNS topic ARN and re-deploy; a rollback replays the recorded value, so restore the template and re-deploy instead. Do not drop this record with 'cdkd state orphan', with or without --resource: the template still declares the resource, so the next deploy would send the handler a fresh Create and leave what it already manages untracked.";
|
|
23049
|
+
}
|
|
23050
|
+
function unresolvedTokenDeleteRemedy(context, logicalId) {
|
|
23051
|
+
return context?.stackDestroy === true ? `re-run 'cdkd import', or drop the record with ${stateOrphanRecordRemedy(context, logicalId)}, to recover.` : `put the provider's Lambda function or SNS topic ARN back as ServiceToken in state.json and re-run to recover. ${crDeployNoStateOrphan(logicalId)}`;
|
|
23052
|
+
}
|
|
23053
|
+
function unaddressableServiceTokenRemedy(context, logicalId) {
|
|
23054
|
+
return context?.stackDestroy === true ? crDestroyUnaddressableRemedy(context, logicalId) : `${CR_DEPLOY_UNADDRESSABLE_HEAD}${crDeploySkipTail(logicalId)}`;
|
|
23055
|
+
}
|
|
23078
23056
|
function isCustomResourceResponsePayload(value) {
|
|
23079
23057
|
if (typeof value !== "object" || value === null) return false;
|
|
23080
23058
|
const payload = value;
|
|
@@ -23417,7 +23395,7 @@ var CustomResourceProvider = class CustomResourceProvider {
|
|
|
23417
23395
|
this.logger.debug(`Creating custom resource ${logicalId} (${resourceType})`);
|
|
23418
23396
|
const serviceToken = properties["ServiceToken"];
|
|
23419
23397
|
if (!serviceToken) throw new ProvisioningError(`ServiceToken is required for custom resource ${logicalId}`, resourceType, logicalId);
|
|
23420
|
-
if (typeof serviceToken !== "string") throw new ProvisioningError(`Custom Resource ${logicalId}: ServiceToken is not a resolved string ARN (got ${typeof serviceToken}). This
|
|
23398
|
+
if (typeof serviceToken !== "string") throw new ProvisioningError(`Custom Resource ${logicalId}: ServiceToken is not a resolved string ARN (got ${typeof serviceToken}). This indicates an unresolved value in the template, or, on a rollback, in the resource's recorded state. Check that the template resolves ServiceToken to the provider's Lambda function or SNS topic ARN; a rollback replays the recorded value, so restore the template and re-deploy instead.`, resourceType, logicalId);
|
|
23421
23399
|
this.refuseResolvedSecret(logicalId, resourceType, properties);
|
|
23422
23400
|
try {
|
|
23423
23401
|
const cfnResponse = await this.invokeCustomResourceWithRetry(serviceToken, logicalId, "Create", (invocation) => ({
|
|
@@ -23448,7 +23426,7 @@ var CustomResourceProvider = class CustomResourceProvider {
|
|
|
23448
23426
|
this.logger.debug(`Updating custom resource ${logicalId}: ${physicalId} (${resourceType})`);
|
|
23449
23427
|
const serviceToken = properties["ServiceToken"];
|
|
23450
23428
|
if (!serviceToken) throw new ProvisioningError(`ServiceToken is required for custom resource ${logicalId}`, resourceType, logicalId, physicalId);
|
|
23451
|
-
if (typeof serviceToken !== "string") throw new ProvisioningError(`Custom Resource ${logicalId}: ServiceToken is not a resolved string ARN (got ${typeof serviceToken}).
|
|
23429
|
+
if (typeof serviceToken !== "string") throw new ProvisioningError(`Custom Resource ${logicalId}: ServiceToken is not a resolved string ARN (got ${typeof serviceToken}). ` + crUnresolvedTokenUpdateRemedy(), resourceType, logicalId, physicalId);
|
|
23452
23430
|
this.refuseResolvedSecret(logicalId, resourceType, properties, physicalId, previousProperties);
|
|
23453
23431
|
try {
|
|
23454
23432
|
const cfnResponse = await this.invokeCustomResourceWithRetry(serviceToken, logicalId, "Update", (invocation) => ({
|
|
@@ -23478,7 +23456,7 @@ var CustomResourceProvider = class CustomResourceProvider {
|
|
|
23478
23456
|
throw new ProvisioningError(`Failed to update custom resource ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
23479
23457
|
}
|
|
23480
23458
|
}
|
|
23481
|
-
async delete(logicalId, physicalId, resourceType, properties,
|
|
23459
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
23482
23460
|
this.logger.debug(`Deleting custom resource ${logicalId}: ${physicalId} (${resourceType})`);
|
|
23483
23461
|
if (!properties) {
|
|
23484
23462
|
this.logger.warn(`No properties available for custom resource ${logicalId}, skipping deletion — the handler is never invoked, so anything this custom resource manages is LEFT IN PLACE. Restore the record's properties in state.json and re-run, or tear the resource down by hand. ${DEPLOY_SKIP_CAVEAT}`);
|
|
@@ -23495,23 +23473,30 @@ var CustomResourceProvider = class CustomResourceProvider {
|
|
|
23495
23473
|
reason: CR_NO_SERVICE_TOKEN_SKIP_REASON
|
|
23496
23474
|
};
|
|
23497
23475
|
}
|
|
23498
|
-
if (typeof serviceToken !== "string") throw new ProvisioningError(`Custom Resource ${logicalId}: ServiceToken is not a resolved string ARN (got ${typeof serviceToken}). This usually indicates state was written by a pre-fix cdkd import;
|
|
23476
|
+
if (typeof serviceToken !== "string") throw new ProvisioningError(`Custom Resource ${logicalId}: ServiceToken is not a resolved string ARN (got ${typeof serviceToken}). This usually indicates state was written by a pre-fix cdkd import; ` + unresolvedTokenDeleteRemedy(context, logicalId), resourceType, logicalId, physicalId);
|
|
23499
23477
|
if (carriesSecretMask(serviceToken)) {
|
|
23500
|
-
this.logger.warn(safeMsg`ServiceToken for custom resource ${logicalId} is recorded in state as the redaction ` + safeMsg`mask '${"***"}' (a NoEcho value this resource reads equals, or is contained ` + "in, its ServiceToken), so cdkd cannot address the handler; skipping deletion — anything this custom resource manages is LEFT IN PLACE. Re-deploying does not repair the record while that attribute still carries the value.
|
|
23478
|
+
this.logger.warn(safeMsg`ServiceToken for custom resource ${logicalId} is recorded in state as the redaction ` + safeMsg`mask '${"***"}' (a NoEcho value this resource reads equals, or is contained ` + "in, its ServiceToken), so cdkd cannot address the handler; skipping deletion — anything this custom resource manages is LEFT IN PLACE. Re-deploying does not repair the record while that attribute still carries the value. " + safeMsg`${unaddressableServiceTokenRemedy(context, logicalId)}`);
|
|
23501
23479
|
return {
|
|
23502
23480
|
outcome: "skipped",
|
|
23503
23481
|
reason: CR_MASKED_SERVICE_TOKEN_SKIP_REASON
|
|
23504
23482
|
};
|
|
23505
23483
|
}
|
|
23506
23484
|
if (dynamicReferenceTokens(serviceToken).length > 0) {
|
|
23507
|
-
this.logger.warn(safeMsg`ServiceToken for custom resource ${logicalId} is recorded in state as a ` + "'{{resolve:...}}' dynamic reference, which cdkd does not resolve on delete, so it cannot address the handler; skipping deletion — anything this custom resource manages is LEFT IN PLACE. CloudFormation does not support secure (secretsmanager / ssm-secure) dynamic references in custom resources, and cdkd now refuses such a template at deploy time.
|
|
23485
|
+
this.logger.warn(safeMsg`ServiceToken for custom resource ${logicalId} is recorded in state as a ` + "'{{resolve:...}}' dynamic reference, which cdkd does not resolve on delete, so it cannot address the handler; skipping deletion — anything this custom resource manages is LEFT IN PLACE. CloudFormation does not support secure (secretsmanager / ssm-secure) dynamic references in custom resources, and cdkd now refuses such a template at deploy time. " + safeMsg`${unaddressableServiceTokenRemedy(context, logicalId)}`);
|
|
23508
23486
|
return {
|
|
23509
23487
|
outcome: "skipped",
|
|
23510
23488
|
reason: CR_REFERENCE_SERVICE_TOKEN_SKIP_REASON
|
|
23511
23489
|
};
|
|
23512
23490
|
}
|
|
23513
23491
|
if (!this.isSnsServiceToken(serviceToken) && await this.isBackingLambdaGone(serviceToken)) {
|
|
23514
|
-
|
|
23492
|
+
if (context?.stackDestroy === true) {
|
|
23493
|
+
this.logger.warn(safeMsg`Backing Lambda for custom resource ${logicalId} no longer exists (${serviceToken}), so ` + "its Delete handler cannot be invoked and cdkd cannot confirm the resource was deleted; skipping deletion — anything this custom resource manages may still be LIVE. cdkd is KEEPING the state record and the run exits non-zero, as CloudFormation leaves such a stack DELETE_FAILED. A re-run skips it again unless a function with that exact ARN exists again (e.g. a shared provider stack destroyed before this one, then redeployed). Otherwise confirm by hand that whatever it manages is gone (or tear it down), then drop the record with " + safeMsg`${stateOrphanRecordRemedy(context, logicalId)}.`);
|
|
23494
|
+
return {
|
|
23495
|
+
outcome: "skipped",
|
|
23496
|
+
reason: CR_BACKING_LAMBDA_GONE_SKIP_REASON
|
|
23497
|
+
};
|
|
23498
|
+
}
|
|
23499
|
+
this.logger.warn(safeMsg`Backing Lambda for custom resource ${logicalId} no longer exists (${serviceToken}); ` + "treating the custom resource as already deleted and DROPPING its state record, as CloudFormation ignores a delete failure in an update's cleanup phase. The handler can never run again, so if its teardown was never PROVEN, whatever it manages may still be LIVE and is now untracked by cdkd. Check for leftovers by hand.");
|
|
23515
23500
|
return;
|
|
23516
23501
|
}
|
|
23517
23502
|
try {
|
|
@@ -23526,7 +23511,7 @@ var CustomResourceProvider = class CustomResourceProvider {
|
|
|
23526
23511
|
ResourceProperties: this.stringifyProperties(properties)
|
|
23527
23512
|
}), DELETE_PATH_UNMASKED);
|
|
23528
23513
|
if (cfnResponse.Status === "FAILED") {
|
|
23529
|
-
this.logger.warn(`Custom resource delete handler returned FAILED for ${logicalId}: ${cfnResponse.Reason || "Unknown reason"}. The handler reported that it did NOT delete, so anything this custom resource manages is LEFT IN PLACE
|
|
23514
|
+
this.logger.warn(`Custom resource delete handler returned FAILED for ${logicalId}: ${cfnResponse.Reason || "Unknown reason"}. The handler reported that it did NOT delete, so anything this custom resource manages is LEFT IN PLACE${handlerSkipRemedy(context, logicalId)}`);
|
|
23530
23515
|
return {
|
|
23531
23516
|
outcome: "skipped",
|
|
23532
23517
|
reason: CR_DELETE_HANDLER_FAILED_SKIP_REASON
|
|
@@ -23534,7 +23519,7 @@ var CustomResourceProvider = class CustomResourceProvider {
|
|
|
23534
23519
|
}
|
|
23535
23520
|
this.logger.debug(`Successfully deleted custom resource ${logicalId}`);
|
|
23536
23521
|
} catch (error) {
|
|
23537
|
-
this.logger.warn(`Failed to delete custom resource ${logicalId}, but continuing: ${describeAwsFailure(error).detail}. The Delete handler did not complete, so anything this custom resource manages may still be LIVE
|
|
23522
|
+
this.logger.warn(`Failed to delete custom resource ${logicalId}, but continuing: ${describeAwsFailure(error).detail}. The Delete handler did not complete, so anything this custom resource manages may still be LIVE${handlerSkipRemedy(context, logicalId)}`);
|
|
23538
23523
|
return {
|
|
23539
23524
|
outcome: "skipped",
|
|
23540
23525
|
reason: CR_DELETE_INVOKE_FAILED_SKIP_REASON
|
|
@@ -26482,6 +26467,81 @@ function ownPoliciesChange(change) {
|
|
|
26482
26467
|
return (change?.propertyChanges ?? []).some((c) => c.path === "Policies" && c.inPlacePropagated !== true && c.replacementPropagated !== true);
|
|
26483
26468
|
}
|
|
26484
26469
|
|
|
26470
|
+
//#endregion
|
|
26471
|
+
//#region src/analyzer/destructive-changes.ts
|
|
26472
|
+
const IGNORED_RESOURCE_TYPES = /* @__PURE__ */ new Set(["AWS::CDK::Metadata"]);
|
|
26473
|
+
const PATH_METADATA_KEY = "aws:cdk:path";
|
|
26474
|
+
function findDestructiveChanges(stackName, changes, records, template, recreateTargets = /* @__PURE__ */ new Set()) {
|
|
26475
|
+
const found = [];
|
|
26476
|
+
for (const change of changes) {
|
|
26477
|
+
const record = Object.hasOwn(records, change.logicalId) ? records[change.logicalId] : void 0;
|
|
26478
|
+
const resourceType = record?.resourceType ?? change.resourceType;
|
|
26479
|
+
if (IGNORED_RESOURCE_TYPES.has(resourceType) || IGNORED_RESOURCE_TYPES.has(change.resourceType)) continue;
|
|
26480
|
+
const impact = change.changeType === "UPDATE" && recreateTargets.has(change.logicalId) ? "WILL_REPLACE" : destructiveImpactOf(change, record);
|
|
26481
|
+
if (impact === void 0) continue;
|
|
26482
|
+
const recorded = typeof record?.constructPath === "string" ? record.constructPath : void 0;
|
|
26483
|
+
const constructPath = constructPathOf(template, change.logicalId) ?? recorded;
|
|
26484
|
+
found.push({
|
|
26485
|
+
stackName,
|
|
26486
|
+
logicalId: change.logicalId,
|
|
26487
|
+
resourceType,
|
|
26488
|
+
...constructPath !== void 0 && { constructPath },
|
|
26489
|
+
impact
|
|
26490
|
+
});
|
|
26491
|
+
}
|
|
26492
|
+
return found;
|
|
26493
|
+
}
|
|
26494
|
+
function destructiveImpactOf(change, record) {
|
|
26495
|
+
switch (change.changeType) {
|
|
26496
|
+
case "DELETE": return shouldRetainResource(record?.deletionPolicy) ? "WILL_ORPHAN" : "WILL_DESTROY";
|
|
26497
|
+
case "UPDATE": {
|
|
26498
|
+
if (record !== void 0 && record.resourceType !== change.resourceType) return "WILL_REPLACE";
|
|
26499
|
+
let mayReplace = false;
|
|
26500
|
+
for (const pc of change.propertyChanges ?? []) {
|
|
26501
|
+
if (!pc.requiresReplacement) continue;
|
|
26502
|
+
if (pc.inPlacePropagated === true || pc.replacementPropagated === true) mayReplace = true;
|
|
26503
|
+
else return "WILL_REPLACE";
|
|
26504
|
+
}
|
|
26505
|
+
return mayReplace ? "MAY_REPLACE" : void 0;
|
|
26506
|
+
}
|
|
26507
|
+
default: return;
|
|
26508
|
+
}
|
|
26509
|
+
}
|
|
26510
|
+
function constructPathOf(template, logicalId) {
|
|
26511
|
+
const resources = template?.Resources;
|
|
26512
|
+
if (resources === void 0 || !Object.hasOwn(resources, logicalId)) return void 0;
|
|
26513
|
+
const path = resources[logicalId]?.Metadata?.[PATH_METADATA_KEY];
|
|
26514
|
+
return typeof path === "string" && path !== "" ? path : void 0;
|
|
26515
|
+
}
|
|
26516
|
+
function describeDestructiveImpact(impact) {
|
|
26517
|
+
switch (impact) {
|
|
26518
|
+
case "WILL_REPLACE": return "will be replaced";
|
|
26519
|
+
case "MAY_REPLACE": return "may be replaced";
|
|
26520
|
+
case "WILL_DESTROY": return "will be destroyed";
|
|
26521
|
+
case "WILL_ORPHAN": return "will be orphaned";
|
|
26522
|
+
}
|
|
26523
|
+
}
|
|
26524
|
+
function formatDestructiveChange(change) {
|
|
26525
|
+
const path = change.constructPath !== void 0 ? `${displaySafe(displayPath(change.constructPath))} ` : "";
|
|
26526
|
+
return `${displayIdent(change.stackName)}: ${displaySafe(change.resourceType)} ${path}${displayIdent(change.logicalId)} ${describeDestructiveImpact(change.impact)}`;
|
|
26527
|
+
}
|
|
26528
|
+
function displayPath(constructPath) {
|
|
26529
|
+
let parts = constructPath.replace(/^\//, "").split("/");
|
|
26530
|
+
if (parts.length > 1) {
|
|
26531
|
+
parts = parts.slice(1);
|
|
26532
|
+
const last = parts[parts.length - 1];
|
|
26533
|
+
if (parts.length > 1 && (last === "Resource" || last === "Default")) parts = parts.slice(0, -1);
|
|
26534
|
+
}
|
|
26535
|
+
return parts.join("/");
|
|
26536
|
+
}
|
|
26537
|
+
function withConstructPath(record, path) {
|
|
26538
|
+
if (path === void 0 || record.constructPath === path) return record;
|
|
26539
|
+
return {
|
|
26540
|
+
...record,
|
|
26541
|
+
constructPath: path
|
|
26542
|
+
};
|
|
26543
|
+
}
|
|
26544
|
+
|
|
26485
26545
|
//#endregion
|
|
26486
26546
|
//#region src/deployment/masking-retry-logger.ts
|
|
26487
26547
|
function maskingRetryLogger(logger, secrets) {
|
|
@@ -26894,6 +26954,7 @@ async function resolveOutputs(template, resources, stackName, digestSource, para
|
|
|
26894
26954
|
...parameterValues && { parameters: parameterValues },
|
|
26895
26955
|
...conditions && { conditions }
|
|
26896
26956
|
}, stackName);
|
|
26957
|
+
context.printingSecrets = /* @__PURE__ */ new Map();
|
|
26897
26958
|
const refuseMaskedOutputReads = (outputKey, ownReads) => {
|
|
26898
26959
|
const added = ownReads.filter((read) => read.kind === "ref-state-key");
|
|
26899
26960
|
if (added.length === 0) return;
|
|
@@ -27377,9 +27438,9 @@ const REDACTED_DELETE_ADDRESS_SKIP_REASON = "redacted address property in state
|
|
|
27377
27438
|
function redactedDeleteAddressFields(fields) {
|
|
27378
27439
|
return Object.keys(fields).filter((key) => isRedactedRecordedValue(fields[key]));
|
|
27379
27440
|
}
|
|
27380
|
-
function redactedDeleteAddressSkip(logger, logicalId, what, redactedFields) {
|
|
27441
|
+
function redactedDeleteAddressSkip(logger, logicalId, what, redactedFields, context) {
|
|
27381
27442
|
if (redactedFields.length === 0) return void 0;
|
|
27382
|
-
logger.warn(safeMsg`${what} ${logicalId} is recorded in state with ${redactedFields.join(", ")} ` + "redacted (the '***' mask of a NoEcho value it read, or a secret '{{resolve:...}}' reference), which names nothing in AWS; skipping deletion — no AWS call is issued, so the resource is LEFT IN PLACE unless a parent resource this run also deletes removes it (then only the record is stale). Re-deploying records the same redaction again. The state record is KEPT and the run reports the skip: on 'cdkd destroy' / 'cdkd state destroy' (which exits non-zero) and, since issue 1762, on the plain DELETE of a resource removed from the template during cdkd deploy. Remove the resource by hand, then
|
|
27443
|
+
logger.warn(safeMsg`${what} ${logicalId} is recorded in state with ${redactedFields.join(", ")} ` + "redacted (the '***' mask of a NoEcho value it read, or a secret '{{resolve:...}}' reference), which names nothing in AWS; skipping deletion — no AWS call is issued, so the resource is LEFT IN PLACE unless a parent resource this run also deletes removes it (then only the record is stale). Re-deploying records the same redaction again. The state record is KEPT and the run reports the skip: on 'cdkd destroy' / 'cdkd state destroy' (which exits non-zero) and, since issue 1762, on the plain DELETE of a resource removed from the template during cdkd deploy. Remove the resource by hand, " + safeMsg`then drop the record with ${stateOrphanRecordRemedy(context, logicalId)}. ` + "NOTE a deploy-side REPLACEMENT or rollback delete instead FAILS the resource (https://github.com/go-to-k/cdkd/issues/1762) — the old resource is left untracked there, so remove it by hand.");
|
|
27383
27444
|
return {
|
|
27384
27445
|
outcome: "skipped",
|
|
27385
27446
|
reason: REDACTED_DELETE_ADDRESS_SKIP_REASON
|
|
@@ -28395,6 +28456,9 @@ function mayOwn(o, orphan, completed) {
|
|
|
28395
28456
|
if (o.physicalId === orphan.physicalId) return true;
|
|
28396
28457
|
return o.previousState?.physicalId === orphan.physicalId;
|
|
28397
28458
|
}
|
|
28459
|
+
function isJournaledOrphan(op) {
|
|
28460
|
+
return op.changeType === "CREATE" && typeof op.physicalIdRecoveredFromError === "boolean";
|
|
28461
|
+
}
|
|
28398
28462
|
function planFailedOps(failedOps, stateResources) {
|
|
28399
28463
|
return failedOps.map((op) => ({
|
|
28400
28464
|
op,
|
|
@@ -29278,7 +29342,7 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
|
|
|
29278
29342
|
const takeFinalSnapshot = snapshotPolicy && ctx.skipFinalSnapshot !== true;
|
|
29279
29343
|
let finalSnapshotIdentifier;
|
|
29280
29344
|
if (takeFinalSnapshot) finalSnapshotIdentifier = await prepareCreateRollbackFinalSnapshot(op, deleteProvisionedBy, ctx, mask);
|
|
29281
|
-
logger.info(` Rollback: deleting partially-created ${safe(op.logicalId)} (${safe(op.resourceType)})
|
|
29345
|
+
logger.info(` Rollback: deleting partially-created ${safe(op.logicalId)} (${safe(op.resourceType)})` + (takeFinalSnapshot ? " — DeletionPolicy: Snapshot" : "") + (snapshotPolicy && !takeFinalSnapshot ? " — DeletionPolicy: Snapshot NOT taken (--skip-final-snapshot)" : ""));
|
|
29282
29346
|
const { provider, provisionedBy: deleteRoutedVia } = ctx.providerRegistry.getProviderFor({
|
|
29283
29347
|
resourceType: op.resourceType,
|
|
29284
29348
|
provisionedBy: deleteProvisionedBy
|
|
@@ -29292,7 +29356,7 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
|
|
|
29292
29356
|
deletionPolicy: snapshotPolicy ? "Snapshot" : "Delete",
|
|
29293
29357
|
recordedAttributes: stateResources[op.logicalId]?.attributes
|
|
29294
29358
|
});
|
|
29295
|
-
throwIfDeleteSkipped(failedCreateDelete, op.logicalId, op.physicalId, "while deleting the partially-created resource
|
|
29359
|
+
throwIfDeleteSkipped(failedCreateDelete, op.logicalId, op.physicalId, "while deleting the partially-created resource", {
|
|
29296
29360
|
ctx,
|
|
29297
29361
|
stackName,
|
|
29298
29362
|
resourceType: op.resourceType,
|
|
@@ -29444,7 +29508,7 @@ async function collectNestedChildUnaddressed(fn) {
|
|
|
29444
29508
|
//#endregion
|
|
29445
29509
|
//#region src/deployment/nested-child-journal.ts
|
|
29446
29510
|
const NESTED_PENDING_PARENT_REASON = "nested-pending-parent";
|
|
29447
|
-
const NESTED_STACK_TYPE$
|
|
29511
|
+
const NESTED_STACK_TYPE$2 = "AWS::CloudFormation::Stack";
|
|
29448
29512
|
const MAX_NESTED_WALK_DEPTH = 32;
|
|
29449
29513
|
function nestedChildStackName(parentStackName, logicalId) {
|
|
29450
29514
|
return `${parentStackName}~${logicalId}`;
|
|
@@ -29500,7 +29564,7 @@ function recordDisplacedSkips(recordEvent, stackName, ops) {
|
|
|
29500
29564
|
});
|
|
29501
29565
|
}
|
|
29502
29566
|
function revertedNestedRowIds(ops) {
|
|
29503
|
-
return ops.filter((op) => op.resourceType === NESTED_STACK_TYPE$
|
|
29567
|
+
return ops.filter((op) => op.resourceType === NESTED_STACK_TYPE$2 && op.changeType === "UPDATE").map((op) => op.logicalId);
|
|
29504
29568
|
}
|
|
29505
29569
|
const revertRunStorage = new AsyncLocalStorage();
|
|
29506
29570
|
function withNestedRevertRun(runId, fn) {
|
|
@@ -29526,7 +29590,7 @@ async function dropNestedChildJournals(args) {
|
|
|
29526
29590
|
if (!isPlainRecord(resources)) return;
|
|
29527
29591
|
if (depthExceeded(depth, parentStackName, logger)) return;
|
|
29528
29592
|
for (const [logicalId, record] of Object.entries(resources)) {
|
|
29529
|
-
if (!isPlainRecord(record) || record["resourceType"] !== NESTED_STACK_TYPE$
|
|
29593
|
+
if (!isPlainRecord(record) || record["resourceType"] !== NESTED_STACK_TYPE$2) continue;
|
|
29530
29594
|
const child = nestedChildStackName(parentStackName, logicalId);
|
|
29531
29595
|
try {
|
|
29532
29596
|
const data = await stateBackend.getState(child, region);
|
|
@@ -29540,13 +29604,34 @@ async function dropNestedChildJournals(args) {
|
|
|
29540
29604
|
warnUncleared(logger, child, error);
|
|
29541
29605
|
}
|
|
29542
29606
|
try {
|
|
29543
|
-
await withChildLock(args.lockManager, child, region, logger, () =>
|
|
29544
|
-
|
|
29607
|
+
if (await withChildLock(args.lockManager, child, region, logger, async () => {
|
|
29608
|
+
if (args.beforeDelete) {
|
|
29609
|
+
if (!await args.beforeDelete(child, await readOwnRecord(stateBackend, child, region))) return false;
|
|
29610
|
+
}
|
|
29611
|
+
let gone;
|
|
29612
|
+
try {
|
|
29613
|
+
gone = await stateBackend.deleteRollbackJournal(child, region);
|
|
29614
|
+
} catch (error) {
|
|
29615
|
+
await args.onDeleteFailed?.(child);
|
|
29616
|
+
throw error;
|
|
29617
|
+
}
|
|
29618
|
+
if (gone === false) {
|
|
29619
|
+
await args.onDeleteFailed?.(child);
|
|
29620
|
+
return false;
|
|
29621
|
+
}
|
|
29622
|
+
return true;
|
|
29623
|
+
})) logger.debug(safeMsg`Deleted the rollback journal of nested stack ${displaySafe(child)}`);
|
|
29545
29624
|
} catch (error) {
|
|
29546
29625
|
warnUncleared(logger, child, error);
|
|
29547
29626
|
}
|
|
29548
29627
|
}
|
|
29549
29628
|
}
|
|
29629
|
+
async function readOwnRecord(stateBackend, child, region) {
|
|
29630
|
+
try {
|
|
29631
|
+
const data = await stateBackend.getState(child, region);
|
|
29632
|
+
if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) return data.state;
|
|
29633
|
+
} catch {}
|
|
29634
|
+
}
|
|
29550
29635
|
async function dropSettledNestedJournals(args) {
|
|
29551
29636
|
const { stateBackend, parentStackName, region, runId, logger } = args;
|
|
29552
29637
|
const depth = args.depth ?? 0;
|
|
@@ -29856,6 +29941,306 @@ function makeSiblingClaimReader(params) {
|
|
|
29856
29941
|
};
|
|
29857
29942
|
}
|
|
29858
29943
|
|
|
29944
|
+
//#endregion
|
|
29945
|
+
//#region src/deployment/rollback-executor/journaled-orphans.ts
|
|
29946
|
+
const NONE = {
|
|
29947
|
+
segments: [],
|
|
29948
|
+
count: 0
|
|
29949
|
+
};
|
|
29950
|
+
async function loadJournaledOrphans(stateBackend, stackName, region, rollbackOrphans, logger, options = {}) {
|
|
29951
|
+
let segments;
|
|
29952
|
+
try {
|
|
29953
|
+
const journal = await stateBackend.loadRollbackJournal(stackName, region);
|
|
29954
|
+
if (!journal) return NONE;
|
|
29955
|
+
segments = journal.segments;
|
|
29956
|
+
} catch (err) {
|
|
29957
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
29958
|
+
logger.warn(safeMsg`Could not read the stack's rollback journal (${displaySafe(detail)}); ` + safeMsg`no resource it records for a failed CREATE is deleted, and ${options.unreadableOutcome ?? "a destroy that proceeds removes the journal with the state"}.`);
|
|
29959
|
+
return {
|
|
29960
|
+
...NONE,
|
|
29961
|
+
unreadable: true
|
|
29962
|
+
};
|
|
29963
|
+
}
|
|
29964
|
+
const physicalIdOnly = (ops) => ops.filter((op) => op.changeType !== "CREATE");
|
|
29965
|
+
const evidence = segments.map((segment) => options.deployRunId !== void 0 && segment.reason === "nested-pending-parent" && segment.runId === options.deployRunId ? {
|
|
29966
|
+
...segment,
|
|
29967
|
+
operations: physicalIdOnly(segment.operations)
|
|
29968
|
+
} : segment);
|
|
29969
|
+
const newer = options.newerOperations ?? [];
|
|
29970
|
+
if (newer.length > 0) evidence.push({ operations: physicalIdOnly(newer) });
|
|
29971
|
+
demoteSupersededOrphans(evidence, Array.isArray(rollbackOrphans) ? rollbackOrphans : []);
|
|
29972
|
+
const deployLogicalIds = new Set(newer.map((op) => op.logicalId));
|
|
29973
|
+
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);
|
|
29974
|
+
const out = [];
|
|
29975
|
+
let count = 0;
|
|
29976
|
+
for (let s = segments.length - 1; s >= 0; s--) {
|
|
29977
|
+
const segment = segments[s];
|
|
29978
|
+
if (segment.reason === "nested-pending-parent") continue;
|
|
29979
|
+
const ops = splitImportedOps(segment.failedOperations ?? [], segment).replay.filter(isJournaledOrphan);
|
|
29980
|
+
if (ops.length === 0) continue;
|
|
29981
|
+
out.push({
|
|
29982
|
+
segment,
|
|
29983
|
+
ops
|
|
29984
|
+
});
|
|
29985
|
+
count += ops.length;
|
|
29986
|
+
}
|
|
29987
|
+
return {
|
|
29988
|
+
segments: out,
|
|
29989
|
+
count,
|
|
29990
|
+
deployLogicalIds
|
|
29991
|
+
};
|
|
29992
|
+
}
|
|
29993
|
+
function journaledOrphanLines(orphans, logger) {
|
|
29994
|
+
return orphans.segments.flatMap(({ ops }) => ops.map((op) => ` - ${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}) ${displacedPhysicalIdShown(op, logger) ?? "a physical id"}`));
|
|
29995
|
+
}
|
|
29996
|
+
async function deleteJournaledOrphans(orphans, stateResources, stackName, ctx, options = {}) {
|
|
29997
|
+
const total = {
|
|
29998
|
+
failures: 0,
|
|
29999
|
+
warnings: 0,
|
|
30000
|
+
interrupted: false,
|
|
30001
|
+
handled: []
|
|
30002
|
+
};
|
|
30003
|
+
const inlinePolicyWriters = new RollbackInlinePolicyWriters();
|
|
30004
|
+
for (const { segment, ops } of orphans.segments) {
|
|
30005
|
+
if (options.isInterrupted?.()) {
|
|
30006
|
+
total.interrupted = true;
|
|
30007
|
+
break;
|
|
30008
|
+
}
|
|
30009
|
+
const replay = () => withStackName(stackName, () => replayFailedOperations(ops, stateResources, stackName, ctx, {
|
|
30010
|
+
emitEnvelope: false,
|
|
30011
|
+
inlinePolicyWriters,
|
|
30012
|
+
...options.isInterrupted && { isInterrupted: options.isInterrupted }
|
|
30013
|
+
}));
|
|
30014
|
+
const result = segment.skipPrefix === void 0 ? await replay() : await withSkipPrefix(segment.skipPrefix, replay);
|
|
30015
|
+
total.failures += result.failures;
|
|
30016
|
+
total.warnings += result.warnings;
|
|
30017
|
+
const pending = new Set(result.remainingFailedOps);
|
|
30018
|
+
for (const op of ops) if (!pending.has(op)) total.handled.push({
|
|
30019
|
+
segment,
|
|
30020
|
+
op
|
|
30021
|
+
});
|
|
30022
|
+
if (result.interrupted) {
|
|
30023
|
+
total.interrupted = true;
|
|
30024
|
+
break;
|
|
30025
|
+
}
|
|
30026
|
+
}
|
|
30027
|
+
return total;
|
|
30028
|
+
}
|
|
30029
|
+
async function settleJournaledOrphansOnSuccess(args) {
|
|
30030
|
+
const { stateBackend, stackName, region, stateResources, newerOperations, ctx, logger } = args;
|
|
30031
|
+
const stack = displayIdent(stackName);
|
|
30032
|
+
const newerIds = newerOperations.map((op) => op.logicalId);
|
|
30033
|
+
let orphans;
|
|
30034
|
+
try {
|
|
30035
|
+
orphans = await loadJournaledOrphans(stateBackend, stackName, region, args.rollbackOrphans, logger, {
|
|
30036
|
+
newerOperations,
|
|
30037
|
+
...args.deployRunId !== void 0 && { deployRunId: args.deployRunId },
|
|
30038
|
+
unreadableOutcome: "the successful deploy removes the journal"
|
|
30039
|
+
});
|
|
30040
|
+
} catch (err) {
|
|
30041
|
+
logger.warn(safeMsg`Could not act on the rollback journal of stack ${stack}: ${errorDetail(err)}. It is kept.`);
|
|
30042
|
+
await markSuperseded(stateBackend, stackName, region, newerIds);
|
|
30043
|
+
return {
|
|
30044
|
+
unaddressed: 1,
|
|
30045
|
+
keepJournal: true
|
|
30046
|
+
};
|
|
30047
|
+
}
|
|
30048
|
+
if (orphans.count === 0) return {
|
|
30049
|
+
unaddressed: 0,
|
|
30050
|
+
keepJournal: false
|
|
30051
|
+
};
|
|
30052
|
+
const all = orphans.segments.flatMap(({ segment, ops }) => ops.map((op) => ({
|
|
30053
|
+
segment,
|
|
30054
|
+
op
|
|
30055
|
+
})));
|
|
30056
|
+
let kept = all;
|
|
30057
|
+
if (stateResources === void 0) logger.warn(safeMsg`The rollback journal of stack ${stack} records ${all.length} resource(s) a failed deploy ` + `created, but the stack's state cannot be read, so whether a record now owns them is unknown: none is deleted.`);
|
|
30058
|
+
else {
|
|
30059
|
+
logger.info(safeMsg`The rollback journal of stack ${stack} records ${all.length} resource(s) a failed deploy ` + `created that no state record holds; acting on them per their DeletionPolicy before the journal is removed:`);
|
|
30060
|
+
for (const line of journaledOrphanLines(orphans, logger)) logger.info(line);
|
|
30061
|
+
try {
|
|
30062
|
+
const { unreadable, tracked } = await applySuccessRule(orphans, stateResources, orphans.deployLogicalIds ?? /* @__PURE__ */ new Set(), args.foreignHolder, stack, logger, args.isInterrupted);
|
|
30063
|
+
const outcome = await deleteJournaledOrphans({
|
|
30064
|
+
segments: orphans.segments.map(({ segment, ops }) => ({
|
|
30065
|
+
segment,
|
|
30066
|
+
ops: ops.filter((op) => !unreadable.has(op) && !tracked.has(op))
|
|
30067
|
+
})).filter(({ ops }) => ops.length > 0),
|
|
30068
|
+
count: orphans.count - unreadable.size - tracked.size
|
|
30069
|
+
}, { ...stateResources }, stackName, ctx, args.isInterrupted ? { isInterrupted: args.isInterrupted } : {});
|
|
30070
|
+
kept = all.filter(({ segment, op }) => unreadable.has(op) || !tracked.has(op) && !isHandledOrphan(outcome.handled, segment, op));
|
|
30071
|
+
} catch (err) {
|
|
30072
|
+
logger.warn(safeMsg`Acting on the journaled resources of stack ${stack} failed: ${errorDetail(err)}`);
|
|
30073
|
+
}
|
|
30074
|
+
}
|
|
30075
|
+
const keptOps = new Set(kept.map(({ op }) => op));
|
|
30076
|
+
const skipped = all.filter(({ op }) => !keptOps.has(op) && op.physicalIdRecoveredFromError === false).length;
|
|
30077
|
+
const cleared = all.filter(({ op }) => !keptOps.has(op));
|
|
30078
|
+
const stripCleared = cleared.length === 0 ? void 0 : async () => {
|
|
30079
|
+
try {
|
|
30080
|
+
await stateBackend.dropRollbackJournalFailedOperations(stackName, region, (op, segment) => isHandledOrphan(cleared, segment, op));
|
|
30081
|
+
} catch (err) {
|
|
30082
|
+
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.");
|
|
30083
|
+
}
|
|
30084
|
+
};
|
|
30085
|
+
if (kept.length === 0) return {
|
|
30086
|
+
unaddressed: skipped,
|
|
30087
|
+
keepJournal: false,
|
|
30088
|
+
...stripCleared && { stripCleared }
|
|
30089
|
+
};
|
|
30090
|
+
const keptIds = new Set(kept.map(({ op }) => op.logicalId));
|
|
30091
|
+
const supersededIds = newerIds.filter((id) => !keptIds.has(id));
|
|
30092
|
+
const demoted = kept.filter(({ op }) => op.physicalIdRecoveredFromError === false);
|
|
30093
|
+
const reduce = () => stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op, segment) => isHandledOrphan(kept, segment, op), supersededIds, (op, segment) => isHandledOrphan(demoted, segment, op));
|
|
30094
|
+
let reduced = false;
|
|
30095
|
+
for (let attempt = 0; attempt < 2 && !reduced; attempt++) try {
|
|
30096
|
+
await reduce();
|
|
30097
|
+
reduced = true;
|
|
30098
|
+
} catch (err) {
|
|
30099
|
+
if (attempt === 1) logger.warn(safeMsg`Failed to reduce the rollback journal of stack ${stack} to its undeleted resources: ` + safeMsg`${errorDetail(err)}. The whole journal is kept.`);
|
|
30100
|
+
}
|
|
30101
|
+
if (!reduced) {
|
|
30102
|
+
await markSuperseded(stateBackend, stackName, region, supersededIds);
|
|
30103
|
+
await stripCleared?.();
|
|
30104
|
+
}
|
|
30105
|
+
logger.warn(safeMsg`${kept.length} resource(s) a failed deploy of stack ${stack} created were not deleted ` + (reduced ? "(see above). The rollback journal, their only record, is kept with just them; the next " : "(see above). The rollback journal, their only record, is kept; the next ") + "successful deploy retries.");
|
|
30106
|
+
return {
|
|
30107
|
+
unaddressed: kept.length + skipped,
|
|
30108
|
+
keepJournal: true
|
|
30109
|
+
};
|
|
30110
|
+
}
|
|
30111
|
+
async function applySuccessRule(orphans, stateResources, deployLogicalIds, foreignHolder, stack, logger, isInterrupted) {
|
|
30112
|
+
const unreadable = /* @__PURE__ */ new Set();
|
|
30113
|
+
const tracked = /* @__PURE__ */ new Set();
|
|
30114
|
+
let interrupted = false;
|
|
30115
|
+
for (const { ops } of orphans.segments) for (const op of ops) {
|
|
30116
|
+
if (op.physicalIdRecoveredFromError !== true || !op.physicalId) continue;
|
|
30117
|
+
if (interrupted || isInterrupted?.()) {
|
|
30118
|
+
interrupted = true;
|
|
30119
|
+
unreadable.add(op);
|
|
30120
|
+
continue;
|
|
30121
|
+
}
|
|
30122
|
+
if (Object.values(stateResources).some((r) => r?.resourceType === op.resourceType && r.physicalId === op.physicalId)) {
|
|
30123
|
+
tracked.add(op);
|
|
30124
|
+
continue;
|
|
30125
|
+
}
|
|
30126
|
+
if (Object.prototype.hasOwnProperty.call(stateResources, op.logicalId) || deployLogicalIds.has(op.logicalId)) {
|
|
30127
|
+
op.physicalIdRecoveredFromError = false;
|
|
30128
|
+
continue;
|
|
30129
|
+
}
|
|
30130
|
+
const holding = await foreignHolder(op.resourceType, op.physicalId);
|
|
30131
|
+
if (holding === void 0) continue;
|
|
30132
|
+
if (holding.kind === "held") {
|
|
30133
|
+
logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: ${holding.by} holds a resource of that type under ` + "the same physical id.");
|
|
30134
|
+
op.physicalIdRecoveredFromError = false;
|
|
30135
|
+
continue;
|
|
30136
|
+
}
|
|
30137
|
+
logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: ${holding.what}, so whether another stack holds it is unknown.`);
|
|
30138
|
+
unreadable.add(op);
|
|
30139
|
+
}
|
|
30140
|
+
return {
|
|
30141
|
+
unreadable,
|
|
30142
|
+
tracked
|
|
30143
|
+
};
|
|
30144
|
+
}
|
|
30145
|
+
function makeForeignHolderScan(stateBackend) {
|
|
30146
|
+
let scan;
|
|
30147
|
+
const key = (type, id) => JSON.stringify([type, id]);
|
|
30148
|
+
const run = async () => {
|
|
30149
|
+
const holders = /* @__PURE__ */ new Map();
|
|
30150
|
+
let refs;
|
|
30151
|
+
try {
|
|
30152
|
+
refs = await stateBackend.listStacks();
|
|
30153
|
+
} catch {
|
|
30154
|
+
return {
|
|
30155
|
+
holders,
|
|
30156
|
+
unreadable: "the state bucket listing (it could not be read)"
|
|
30157
|
+
};
|
|
30158
|
+
}
|
|
30159
|
+
let unreadable;
|
|
30160
|
+
await Promise.all(refs.map(async (ref) => {
|
|
30161
|
+
const named = (why) => safeMsg`the state record of stack ${displayIdent(ref.stackName)} (${why})`;
|
|
30162
|
+
if (ref.region === void 0) {
|
|
30163
|
+
unreadable ??= named("its region cannot be read");
|
|
30164
|
+
return;
|
|
30165
|
+
}
|
|
30166
|
+
const region = ref.region;
|
|
30167
|
+
let state;
|
|
30168
|
+
try {
|
|
30169
|
+
state = (await stateBackend.getState(ref.stackName, region))?.state;
|
|
30170
|
+
} catch {
|
|
30171
|
+
unreadable ??= named("it could not be read");
|
|
30172
|
+
return;
|
|
30173
|
+
}
|
|
30174
|
+
if (state === void 0) return;
|
|
30175
|
+
const resources = state.resources;
|
|
30176
|
+
if (resources !== void 0 && (typeof resources !== "object" || resources === null || Array.isArray(resources))) {
|
|
30177
|
+
unreadable ??= named("its resources cannot be read");
|
|
30178
|
+
return;
|
|
30179
|
+
}
|
|
30180
|
+
if (!hasReadableOrphans(state) || unreadableOrphanRecords(state).length > 0) {
|
|
30181
|
+
unreadable ??= named("its rollback-orphan records cannot be read");
|
|
30182
|
+
return;
|
|
30183
|
+
}
|
|
30184
|
+
const held = [...Object.values(resources ?? {}), ...(state.orphans ?? []).map((record) => record.state)];
|
|
30185
|
+
for (const record of held) {
|
|
30186
|
+
const r = record;
|
|
30187
|
+
if (typeof r?.resourceType !== "string" || typeof r.physicalId !== "string") continue;
|
|
30188
|
+
const k = key(r.resourceType, r.physicalId);
|
|
30189
|
+
const list = holders.get(k) ?? [];
|
|
30190
|
+
list.push({
|
|
30191
|
+
stackName: ref.stackName,
|
|
30192
|
+
region
|
|
30193
|
+
});
|
|
30194
|
+
holders.set(k, list);
|
|
30195
|
+
}
|
|
30196
|
+
}));
|
|
30197
|
+
return {
|
|
30198
|
+
holders,
|
|
30199
|
+
...unreadable !== void 0 && { unreadable }
|
|
30200
|
+
};
|
|
30201
|
+
};
|
|
30202
|
+
return (self) => async (resourceType, physicalId) => {
|
|
30203
|
+
scan ??= run();
|
|
30204
|
+
const { holders, unreadable } = await scan;
|
|
30205
|
+
const other = (holders.get(key(resourceType, physicalId)) ?? []).find((h) => !(h.stackName === self.stackName && h.region === self.region));
|
|
30206
|
+
if (other) return {
|
|
30207
|
+
kind: "held",
|
|
30208
|
+
by: safeMsg`the state record of stack ${displayIdent(other.stackName)} (${displaySafe(other.region)})`
|
|
30209
|
+
};
|
|
30210
|
+
return unreadable === void 0 ? void 0 : {
|
|
30211
|
+
kind: "unreadable",
|
|
30212
|
+
what: unreadable
|
|
30213
|
+
};
|
|
30214
|
+
};
|
|
30215
|
+
}
|
|
30216
|
+
async function markSuperseded(stateBackend, stackName, region, ids) {
|
|
30217
|
+
try {
|
|
30218
|
+
await stateBackend.markRollbackJournalSuperseded(stackName, region, ids);
|
|
30219
|
+
} catch {}
|
|
30220
|
+
}
|
|
30221
|
+
function errorDetail(err) {
|
|
30222
|
+
return displaySafe(err instanceof Error ? err.message : String(err));
|
|
30223
|
+
}
|
|
30224
|
+
function isHandledOrphan(handled, segment, op) {
|
|
30225
|
+
return handled.some((h) => h.segment.timestamp === segment.timestamp && h.segment.runId === segment.runId && h.op.logicalId === op.logicalId && h.op.changeType === op.changeType && h.op.resourceType === op.resourceType && h.op.physicalId === op.physicalId);
|
|
30226
|
+
}
|
|
30227
|
+
function orphanKey(segment, op) {
|
|
30228
|
+
return JSON.stringify([
|
|
30229
|
+
segment.timestamp,
|
|
30230
|
+
segment.runId ?? null,
|
|
30231
|
+
op.logicalId,
|
|
30232
|
+
op.changeType,
|
|
30233
|
+
op.resourceType,
|
|
30234
|
+
op.physicalId ?? null
|
|
30235
|
+
]);
|
|
30236
|
+
}
|
|
30237
|
+
function sameJournaledOrphans(a, b) {
|
|
30238
|
+
const keys = (o) => o.segments.flatMap(({ segment, ops }) => ops.map((op) => orphanKey(segment, op))).sort();
|
|
30239
|
+
const ka = keys(a);
|
|
30240
|
+
const kb = keys(b);
|
|
30241
|
+
return ka.length === kb.length && ka.every((k, i) => k === kb[i]);
|
|
30242
|
+
}
|
|
30243
|
+
|
|
29859
30244
|
//#endregion
|
|
29860
30245
|
//#region src/deployment/deploy-engine/rollback.ts
|
|
29861
30246
|
function redactOperationsForJournal(operations) {
|
|
@@ -29904,33 +30289,109 @@ async function adoptRollbackOrphans(currentState, effectiveTemplate) {
|
|
|
29904
30289
|
if (records.length > 0) currentState.orphans = plan.remaining;
|
|
29905
30290
|
return plan;
|
|
29906
30291
|
}
|
|
29907
|
-
async function performRollback(completedOperations, stateResources, stackName, previousState) {
|
|
30292
|
+
async function performRollback(completedOperations, stateResources, stackName, previousState, failedOperations = [], priorOrphans = []) {
|
|
30293
|
+
const orphanIndexes = [];
|
|
30294
|
+
const orphanOps = [];
|
|
30295
|
+
failedOperations.forEach((op, i) => {
|
|
30296
|
+
if (!isJournaledOrphan(op)) return;
|
|
30297
|
+
orphanIndexes.push(i);
|
|
30298
|
+
orphanOps.push({ ...op });
|
|
30299
|
+
});
|
|
30300
|
+
demoteSupersededOrphans([{
|
|
30301
|
+
operations: completedOperations,
|
|
30302
|
+
failedOperations: orphanOps
|
|
30303
|
+
}], priorOrphans);
|
|
30304
|
+
const ctx = this.rollbackExecutorContext(previousState, stackName);
|
|
30305
|
+
const inlinePolicyWriters = new RollbackInlinePolicyWriters();
|
|
29908
30306
|
const runId = this.options.eventRecorder?.runId;
|
|
29909
|
-
const { result, run } = await withNestedRevertRun(runId, async (scope) =>
|
|
29910
|
-
|
|
29911
|
-
|
|
29912
|
-
|
|
30307
|
+
const { result, failed, run } = await withNestedRevertRun(runId, async (scope) => {
|
|
30308
|
+
return {
|
|
30309
|
+
failed: orphanOps.length > 0 ? await replayFailedOperations(orphanOps, stateResources, stackName, ctx, {
|
|
30310
|
+
emitEnvelope: completedOperations.length === 0,
|
|
30311
|
+
inlinePolicyWriters
|
|
30312
|
+
}) : void 0,
|
|
30313
|
+
result: await replayRollback(completedOperations, stateResources, stackName, ctx, { inlinePolicyWriters }),
|
|
30314
|
+
run: scope
|
|
30315
|
+
};
|
|
30316
|
+
});
|
|
30317
|
+
const pendingOrphans = new Set(failed?.remainingFailedOps ?? []);
|
|
30318
|
+
const handled = new Set(orphanIndexes.filter((_, k) => !pendingOrphans.has(orphanOps[k])));
|
|
29913
30319
|
return {
|
|
29914
|
-
failures: result.failures,
|
|
29915
|
-
warnings: result.warnings + run.warnings,
|
|
29916
|
-
skipped: result.skipped,
|
|
29917
|
-
orphaned: result.orphaned,
|
|
29918
|
-
settledNested: run.settled
|
|
30320
|
+
failures: result.failures + (failed?.failures ?? 0),
|
|
30321
|
+
warnings: result.warnings + run.warnings + (failed?.warnings ?? 0),
|
|
30322
|
+
skipped: result.skipped + (failed?.skipped ?? 0),
|
|
30323
|
+
orphaned: [...failed?.orphaned ?? [], ...result.orphaned],
|
|
30324
|
+
settledNested: run.settled,
|
|
30325
|
+
remainingFailedOps: failedOperations.filter((_, i) => !handled.has(i))
|
|
29919
30326
|
};
|
|
29920
30327
|
}
|
|
29921
30328
|
async function settleJournalAfterSuccess(stackName, completedOperations, previousState, finalResources, initialDeploy) {
|
|
29922
30329
|
if (this.options.parentStackInfo) {
|
|
29923
30330
|
await this.writeRollbackJournalSegment(stackName, completedOperations, [], NESTED_PENDING_PARENT_REASON, initialDeploy, nestedPendingSnapshot(previousState));
|
|
29924
|
-
return;
|
|
29925
|
-
}
|
|
29926
|
-
|
|
30331
|
+
return 0;
|
|
30332
|
+
}
|
|
30333
|
+
let nestedLeft = 0;
|
|
30334
|
+
const foreignHolderFor = makeForeignHolderScan(this.stateBackend);
|
|
30335
|
+
const deployRunId = this.options.eventRecorder?.runId;
|
|
30336
|
+
const stripOnFailure = /* @__PURE__ */ new Map();
|
|
30337
|
+
const [ownLeft] = await Promise.all([(async () => {
|
|
30338
|
+
const own = await settleJournaledOrphansOnSuccess({
|
|
30339
|
+
stateBackend: this.stateBackend,
|
|
30340
|
+
stackName,
|
|
30341
|
+
region: this.stackRegion,
|
|
30342
|
+
stateResources: finalResources,
|
|
30343
|
+
rollbackOrphans: previousState.orphans,
|
|
30344
|
+
newerOperations: completedOperations,
|
|
30345
|
+
...deployRunId !== void 0 && { deployRunId },
|
|
30346
|
+
foreignHolder: foreignHolderFor({
|
|
30347
|
+
stackName,
|
|
30348
|
+
region: this.stackRegion
|
|
30349
|
+
}),
|
|
30350
|
+
ctx: this.rollbackExecutorContext(previousState, stackName),
|
|
30351
|
+
isInterrupted: () => this.interrupted,
|
|
30352
|
+
logger: this.logger
|
|
30353
|
+
});
|
|
30354
|
+
if (own.keepJournal) return own.unaddressed;
|
|
30355
|
+
if (!await this.deleteRollbackJournalBestEffort(stackName, completedOperations.map((op) => op.logicalId))) await own.stripCleared?.();
|
|
30356
|
+
return own.unaddressed;
|
|
30357
|
+
})(), dropNestedChildJournals({
|
|
29927
30358
|
stateBackend: this.stateBackend,
|
|
29928
30359
|
lockManager: this.lockManager,
|
|
29929
30360
|
parentStackName: stackName,
|
|
29930
30361
|
region: this.stackRegion,
|
|
29931
30362
|
resources: finalResources,
|
|
29932
|
-
logger: this.logger
|
|
30363
|
+
logger: this.logger,
|
|
30364
|
+
beforeDelete: async (child, childRecord) => {
|
|
30365
|
+
const childState = childRecord !== void 0 && hasReadableOrphans(childRecord) ? childRecord : void 0;
|
|
30366
|
+
const settled = await settleJournaledOrphansOnSuccess({
|
|
30367
|
+
stateBackend: this.stateBackend,
|
|
30368
|
+
stackName: child,
|
|
30369
|
+
region: this.stackRegion,
|
|
30370
|
+
stateResources: childState?.resources,
|
|
30371
|
+
rollbackOrphans: childState?.orphans,
|
|
30372
|
+
newerOperations: [],
|
|
30373
|
+
...deployRunId !== void 0 && { deployRunId },
|
|
30374
|
+
foreignHolder: foreignHolderFor({
|
|
30375
|
+
stackName: child,
|
|
30376
|
+
region: this.stackRegion
|
|
30377
|
+
}),
|
|
30378
|
+
isInterrupted: () => this.interrupted,
|
|
30379
|
+
ctx: {
|
|
30380
|
+
...this.rollbackExecutorContext(childState ?? previousState, child),
|
|
30381
|
+
producerRegionsIncomplete: true,
|
|
30382
|
+
nestedChildStack: child
|
|
30383
|
+
},
|
|
30384
|
+
logger: this.logger
|
|
30385
|
+
});
|
|
30386
|
+
nestedLeft += settled.unaddressed;
|
|
30387
|
+
if (settled.stripCleared) stripOnFailure.set(child, settled.stripCleared);
|
|
30388
|
+
return !settled.keepJournal;
|
|
30389
|
+
},
|
|
30390
|
+
onDeleteFailed: async (child) => {
|
|
30391
|
+
await stripOnFailure.get(child)?.();
|
|
30392
|
+
}
|
|
29933
30393
|
})]);
|
|
30394
|
+
return ownLeft + nestedLeft;
|
|
29934
30395
|
}
|
|
29935
30396
|
async function deleteRollbackJournalBestEffort(stackName, supersededLogicalIds = []) {
|
|
29936
30397
|
let deleted;
|
|
@@ -29940,12 +30401,14 @@ async function deleteRollbackJournalBestEffort(stackName, supersededLogicalIds =
|
|
|
29940
30401
|
this.logger.debug(safeMsg`Failed to delete rollback journal for ${stackName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
29941
30402
|
deleted = false;
|
|
29942
30403
|
}
|
|
29943
|
-
if (deleted !== false
|
|
30404
|
+
if (deleted !== false) return true;
|
|
30405
|
+
if (supersededLogicalIds.length === 0) return false;
|
|
29944
30406
|
try {
|
|
29945
30407
|
await this.stateBackend.markRollbackJournalSuperseded(stackName, this.stackRegion, supersededLogicalIds);
|
|
29946
30408
|
} catch (markErr) {
|
|
29947
30409
|
this.logger.debug(safeMsg`Failed to record superseded logical ids on the rollback journal for ${stackName}: ${markErr instanceof Error ? markErr.message : String(markErr)}`);
|
|
29948
30410
|
}
|
|
30411
|
+
return false;
|
|
29949
30412
|
}
|
|
29950
30413
|
async function settleJournalAfterCleanRollback(stackName, failedOperations, initialDeploy) {
|
|
29951
30414
|
if (failedOperations.length === 0) {
|
|
@@ -30623,7 +31086,88 @@ async function readReaderForFreshNoEchoCeiling(logicalId, currentResource, secre
|
|
|
30623
31086
|
}
|
|
30624
31087
|
}
|
|
30625
31088
|
function maskForResource(logicalId, text) {
|
|
30626
|
-
return maskSecretsInText(text, this.
|
|
31089
|
+
return maskSecretsInText(text, this.printingSecretsFor(logicalId) ?? EMPTY_SECRETS);
|
|
31090
|
+
}
|
|
31091
|
+
function secretNameNeedlesOf(logicalId, record, secrets, options) {
|
|
31092
|
+
const physicalId = typeof record?.physicalId === "string" && record.physicalId !== "" ? record.physicalId : void 0;
|
|
31093
|
+
const bag = secrets !== void 0 && hasMaskableValues(secrets) ? secrets : void 0;
|
|
31094
|
+
const mask = (text) => bag === void 0 ? text : maskSecretsInText(text, bag);
|
|
31095
|
+
const unresolved = (value) => value.includes("{{resolve:") || value === "***";
|
|
31096
|
+
const named = {
|
|
31097
|
+
resourceType: record?.resourceType,
|
|
31098
|
+
properties: record?.properties,
|
|
31099
|
+
logicalId
|
|
31100
|
+
};
|
|
31101
|
+
const needles = /* @__PURE__ */ new Set();
|
|
31102
|
+
const add = (needle) => {
|
|
31103
|
+
if (typeof needle === "string" && needle !== "") needles.add(needle);
|
|
31104
|
+
};
|
|
31105
|
+
for (const [raw, derived] of secretDerivedNamePairs({
|
|
31106
|
+
...named,
|
|
31107
|
+
physicalIds: []
|
|
31108
|
+
})) if (typeof raw === "string" && !unresolved(raw) && isSecretDerivedValue(raw, mask)) add(derived);
|
|
31109
|
+
for (const [raw, spelling] of secretDerivedNamePairs({
|
|
31110
|
+
...named,
|
|
31111
|
+
physicalIds: [physicalId ?? "cdkd-no-physical-id-yet"]
|
|
31112
|
+
})) {
|
|
31113
|
+
if (!isSecretDerivedValue(raw, mask)) continue;
|
|
31114
|
+
if (unresolved(raw)) {
|
|
31115
|
+
if (physicalId === void 0) continue;
|
|
31116
|
+
add(spelling);
|
|
31117
|
+
} else {
|
|
31118
|
+
add(raw);
|
|
31119
|
+
if (raw.toLowerCase() !== raw && raw.length >= 4) add(raw.toLowerCase());
|
|
31120
|
+
}
|
|
31121
|
+
}
|
|
31122
|
+
const properties = record?.properties;
|
|
31123
|
+
const path = properties !== null && typeof properties === "object" && Object.hasOwn(properties, "Path") ? properties["Path"] : void 0;
|
|
31124
|
+
if (physicalId !== void 0 && isSecretDerivedValue(path, mask)) add(physicalId);
|
|
31125
|
+
const embedded = options === void 0 ? secrets : options.embedded;
|
|
31126
|
+
const embeddedBag = embedded !== void 0 && hasMaskableValues(embedded) ? embedded : void 0;
|
|
31127
|
+
if (embeddedBag !== void 0 && physicalId !== void 0) {
|
|
31128
|
+
for (const needle of printingCorpusOf(embeddedBag).keys()) if (needle !== "" && (needle === physicalId || needle.length >= 4 && physicalId.includes(needle))) add(needle);
|
|
31129
|
+
}
|
|
31130
|
+
return needles.size > 0 ? needles : void 0;
|
|
31131
|
+
}
|
|
31132
|
+
function secretNameBagFor(logicalId) {
|
|
31133
|
+
let bag = this.secretNameNeedles.get(logicalId);
|
|
31134
|
+
if (bag === void 0) {
|
|
31135
|
+
bag = /* @__PURE__ */ new Map();
|
|
31136
|
+
this.secretNameNeedles.set(logicalId, bag);
|
|
31137
|
+
}
|
|
31138
|
+
return bag;
|
|
31139
|
+
}
|
|
31140
|
+
function noteSecretNamedRecord(logicalId, record) {
|
|
31141
|
+
const needles = secretNameNeedlesOf(logicalId, record, this.namingSecretsFor(logicalId), { embedded: this.perResourceSecrets.get(logicalId) });
|
|
31142
|
+
if (needles === void 0) return void 0;
|
|
31143
|
+
const registry = this.secretNameBagFor(logicalId);
|
|
31144
|
+
for (const needle of needles) recordLogOnlyValue(registry, needle);
|
|
31145
|
+
return needles;
|
|
31146
|
+
}
|
|
31147
|
+
function namingSecretsFor(logicalId) {
|
|
31148
|
+
const own = this.perResourceSecrets.get(logicalId);
|
|
31149
|
+
const noEcho = this.fingerprintNoEchoValues;
|
|
31150
|
+
if (!hasMaskableValues(noEcho)) return own;
|
|
31151
|
+
return unionOfSecretBags([own, noEcho]);
|
|
31152
|
+
}
|
|
31153
|
+
function noteSecretNamedReads(logicalId, record, resources) {
|
|
31154
|
+
const leaves = [...wholeStringLeavesOf(record?.properties)].filter((leaf) => leaf !== "");
|
|
31155
|
+
if (leaves.length === 0) return;
|
|
31156
|
+
for (const [otherId, other] of Object.entries(resources)) {
|
|
31157
|
+
if (otherId === logicalId) continue;
|
|
31158
|
+
const needles = secretNameNeedlesOf(otherId, other, this.namingSecretsFor(otherId), { embedded: this.perResourceSecrets.get(otherId) });
|
|
31159
|
+
if (needles === void 0) continue;
|
|
31160
|
+
const read = [...needles].filter((needle) => leaves.some((leaf) => leaf === needle || needle.length >= 4 && leaf.includes(needle)));
|
|
31161
|
+
if (read.length === 0) continue;
|
|
31162
|
+
const registry = this.secretNameBagFor(logicalId);
|
|
31163
|
+
for (const needle of read) recordLogOnlyValue(registry, needle);
|
|
31164
|
+
}
|
|
31165
|
+
}
|
|
31166
|
+
function printingSecretsFor(logicalId) {
|
|
31167
|
+
const secrets = this.perResourceSecrets.get(logicalId);
|
|
31168
|
+
const registry = this.secretNameNeedles.get(logicalId);
|
|
31169
|
+
if (!hasMaskableValues(registry)) return secrets;
|
|
31170
|
+
return unionOfSecretBags([secrets, registry]);
|
|
30627
31171
|
}
|
|
30628
31172
|
function maskedRecordRemedyFor(reads, resources, causeScoped = false) {
|
|
30629
31173
|
const NESTED_STACK_RESOURCE_TYPE = "AWS::CloudFormation::Stack";
|
|
@@ -31117,6 +31661,82 @@ function isRefusedBeforeApplying(error, logicalId) {
|
|
|
31117
31661
|
return false;
|
|
31118
31662
|
}
|
|
31119
31663
|
|
|
31664
|
+
//#endregion
|
|
31665
|
+
//#region src/deployment/deploy-engine/resolver-context.ts
|
|
31666
|
+
function buildResolverContext(base, stackName) {
|
|
31667
|
+
const recordedSecretValues = /* @__PURE__ */ new Map();
|
|
31668
|
+
if (this.options.inheritedSecrets && this.options.inheritedSecrets.size > 0) inheritNestedStackParameterAssociations(recordedSecretValues, this.options.inheritedSecrets);
|
|
31669
|
+
return {
|
|
31670
|
+
template: base.template,
|
|
31671
|
+
resources: base.resources,
|
|
31672
|
+
...base.parameters && Object.keys(base.parameters).length > 0 && { parameters: base.parameters },
|
|
31673
|
+
...base.conditions && Object.keys(base.conditions).length > 0 && { conditions: base.conditions },
|
|
31674
|
+
stateBackend: this.stateBackend,
|
|
31675
|
+
stackName,
|
|
31676
|
+
...this.exportIndexStore && { exportIndex: this.exportIndexStore },
|
|
31677
|
+
recordedImports: this.recordedImports,
|
|
31678
|
+
recordedOutputReads: this.recordedOutputReads,
|
|
31679
|
+
attributeHealer: (logicalId, resource) => this.healStaleAttributes(logicalId, resource, stackName),
|
|
31680
|
+
...this.options.inheritedSecrets && hasMaskableValues(this.options.inheritedSecrets) && { inheritedSecrets: this.options.inheritedSecrets },
|
|
31681
|
+
recordedSecretValues,
|
|
31682
|
+
noEchoAttributeResources: this.noEchoAttributeResources,
|
|
31683
|
+
secretNameNeedles: (logicalId) => this.noteSecretNamedRecord(logicalId, Object.hasOwn(base.resources, logicalId) ? base.resources[logicalId] : void 0),
|
|
31684
|
+
...base.redactedAttributeReads && { redactedAttributeReads: base.redactedAttributeReads }
|
|
31685
|
+
};
|
|
31686
|
+
}
|
|
31687
|
+
function printNestedStackReadsOnly(context, resourceType) {
|
|
31688
|
+
if (resourceType === "AWS::CloudFormation::Stack") context.printingSecrets = /* @__PURE__ */ new Map();
|
|
31689
|
+
}
|
|
31690
|
+
function getAttTargetOf(node) {
|
|
31691
|
+
if (node === null || typeof node !== "object" || Array.isArray(node)) return void 0;
|
|
31692
|
+
const getAtt = node["Fn::GetAtt"];
|
|
31693
|
+
if (Array.isArray(getAtt) && typeof getAtt[0] === "string") return getAtt[0];
|
|
31694
|
+
if (typeof getAtt === "string") return getAtt.split(".")[0];
|
|
31695
|
+
}
|
|
31696
|
+
function maskedInputSources(template, resources, conditions, stackName) {
|
|
31697
|
+
const parameters = this.fingerprintParameters;
|
|
31698
|
+
if (parameters === void 0) return void 0;
|
|
31699
|
+
return {
|
|
31700
|
+
template,
|
|
31701
|
+
parameterInput: parameters.parameterInput,
|
|
31702
|
+
conditions,
|
|
31703
|
+
childTemplate: this.fingerprintChildTemplates,
|
|
31704
|
+
resolve: async (node) => {
|
|
31705
|
+
const { attributeHealer: _healer, ...base } = this.buildResolverContext({
|
|
31706
|
+
template,
|
|
31707
|
+
resources,
|
|
31708
|
+
parameters: parameters.bound,
|
|
31709
|
+
...conditions && { conditions }
|
|
31710
|
+
}, stackName);
|
|
31711
|
+
const context = {
|
|
31712
|
+
...base,
|
|
31713
|
+
recordedImports: [],
|
|
31714
|
+
recordedOutputReads: [],
|
|
31715
|
+
bestEffort: true,
|
|
31716
|
+
skipDynamicReferences: true,
|
|
31717
|
+
staleAttributeHeal: { phase: "probe" },
|
|
31718
|
+
printingSecrets: /* @__PURE__ */ new Map()
|
|
31719
|
+
};
|
|
31720
|
+
const value = await this.resolver.resolve(structuredClone(node), context);
|
|
31721
|
+
const secrets = context.recordedSecretValues;
|
|
31722
|
+
const target = getAttTargetOf(node);
|
|
31723
|
+
const targetSecrets = target === void 0 ? void 0 : this.perResourceSecrets.get(target);
|
|
31724
|
+
if (targetSecrets !== void 0 && hasMaskableValues(targetSecrets)) {
|
|
31725
|
+
const probe = { value };
|
|
31726
|
+
const redacted = redactSecretsForState(probe, targetSecrets);
|
|
31727
|
+
if (JSON.stringify(redacted) !== JSON.stringify(probe)) return {
|
|
31728
|
+
value,
|
|
31729
|
+
keepAsWritten: true
|
|
31730
|
+
};
|
|
31731
|
+
}
|
|
31732
|
+
return {
|
|
31733
|
+
value,
|
|
31734
|
+
...secrets && { secrets }
|
|
31735
|
+
};
|
|
31736
|
+
}
|
|
31737
|
+
};
|
|
31738
|
+
}
|
|
31739
|
+
|
|
31120
31740
|
//#endregion
|
|
31121
31741
|
//#region src/deployment/deploy-engine/create.ts
|
|
31122
31742
|
async function provisionCreate(logicalId, change, stateResources, stackName, template, parameterValues, conditions, counts, progress) {
|
|
@@ -31131,7 +31751,12 @@ async function provisionCreate(logicalId, change, stateResources, stackName, tem
|
|
|
31131
31751
|
redactedAttributeReads: []
|
|
31132
31752
|
}, stackName);
|
|
31133
31753
|
if (context.recordedSecretValues) this.perResourceSecrets.set(logicalId, context.recordedSecretValues);
|
|
31754
|
+
printNestedStackReadsOnly(context, resourceType);
|
|
31134
31755
|
const resolvedProps = await this.resolver.resolve(desiredProps, context);
|
|
31756
|
+
this.noteSecretNamedRecord(logicalId, {
|
|
31757
|
+
resourceType,
|
|
31758
|
+
properties: resolvedProps
|
|
31759
|
+
});
|
|
31135
31760
|
this.refuseRedactedAttributeReads(logicalId, resourceType, context);
|
|
31136
31761
|
this.perResourceTemplateProps.set(logicalId, desiredProps);
|
|
31137
31762
|
const fingerprintSources = template && this.maskedInputSources(template, stateResources, conditions, stackName);
|
|
@@ -31737,6 +32362,7 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
31737
32362
|
};
|
|
31738
32363
|
} catch (wiringError) {
|
|
31739
32364
|
warn(`Wiring failed after CreateTable for ${tableName}; attempting best-effort cleanup`);
|
|
32365
|
+
let tableLeftBehind = false;
|
|
31740
32366
|
try {
|
|
31741
32367
|
const replicasForCleanup = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: tableName }))).Table?.Replicas ?? [];
|
|
31742
32368
|
for (const replica of replicasForCleanup) {
|
|
@@ -31755,12 +32381,15 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
31755
32381
|
}
|
|
31756
32382
|
await this.dynamoDBClient.send(new DeleteTableCommand({ TableName: tableName }));
|
|
31757
32383
|
} catch (cleanupErr) {
|
|
32384
|
+
tableLeftBehind = true;
|
|
31758
32385
|
const cleanupMsg = describeAwsFailure(cleanupErr).detail;
|
|
31759
32386
|
warn(`Partial-create cleanup failed for ${tableName}: ${cleanupMsg}. To remove the orphaned AWS-side table, run: ` + pasteableAwsCommand(maskSecrets)`aws dynamodb delete-table --table-name ${tableName}`.render());
|
|
31760
32387
|
}
|
|
31761
32388
|
markAuxiliaryFailure(wiringError, logicalId);
|
|
31762
32389
|
const cause = wiringError instanceof Error ? wiringError : void 0;
|
|
31763
|
-
|
|
32390
|
+
const thrown = this.wrapMaskedError(log, wiringError, (text) => new ProvisioningError(`Failed to create DynamoDB GlobalTable ${logicalId}: ${text}`, resourceType, logicalId, tableName, cause));
|
|
32391
|
+
if (tableLeftBehind) markCreatedBeforeFailure(thrown, logicalId, resourceType, tableName);
|
|
32392
|
+
throw thrown;
|
|
31764
32393
|
}
|
|
31765
32394
|
}
|
|
31766
32395
|
reportThroughputDiagnostics(diagnostics, logicalId, physicalId, maskSecrets = (text) => text) {
|
|
@@ -34019,7 +34648,13 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
|
|
|
34019
34648
|
}, stackName);
|
|
34020
34649
|
const updateSecrets = context.recordedSecretValues ?? /* @__PURE__ */ new Map();
|
|
34021
34650
|
this.perResourceSecrets.set(logicalId, updateSecrets);
|
|
34651
|
+
printNestedStackReadsOnly(context, resourceType);
|
|
34022
34652
|
const resolvedProps = await this.resolver.resolve(desiredProps, context);
|
|
34653
|
+
this.noteSecretNamedRecord(logicalId, {
|
|
34654
|
+
resourceType,
|
|
34655
|
+
physicalId: stateResources[logicalId]?.physicalId,
|
|
34656
|
+
properties: resolvedProps
|
|
34657
|
+
});
|
|
34023
34658
|
this.perResourceTemplateProps.set(logicalId, desiredProps);
|
|
34024
34659
|
this.perResourceResolvedType.set(logicalId, resourceType);
|
|
34025
34660
|
recordNestedStackParameterExpressions(updateSecrets, resourceType, resolvedProps, desiredProps);
|
|
@@ -34645,7 +35280,14 @@ async function updateInPlace({ conditions, counts, currentProps, currentPropsAsW
|
|
|
34645
35280
|
captureProvider = replProvider;
|
|
34646
35281
|
} else throw updateError;
|
|
34647
35282
|
}
|
|
34648
|
-
if (result.wasReplaced)
|
|
35283
|
+
if (result.wasReplaced) {
|
|
35284
|
+
this.noteSecretNamedRecord(logicalId, {
|
|
35285
|
+
resourceType,
|
|
35286
|
+
physicalId: result.physicalId,
|
|
35287
|
+
properties: resolvedProps
|
|
35288
|
+
});
|
|
35289
|
+
this.logger.info(`Resource ${logicalId} was replaced: ${currentResource.physicalId} -> ${result.physicalId}`);
|
|
35290
|
+
}
|
|
34649
35291
|
const dischargedByReplacement = result.wasReplaced === true && result.physicalId !== currentResource.physicalId;
|
|
34650
35292
|
const keepsParameterRefusal = !dischargedByReplacement && hasUnverifiableParameterRefusal(currentResource);
|
|
34651
35293
|
const carriedAttributes = result.attributes ?? (result.wasReplaced ? void 0 : currentResource.attributes);
|
|
@@ -34741,21 +35383,32 @@ async function provisionDelete(logicalId, change, stateResources, stackName, tem
|
|
|
34741
35383
|
const skipPrefix = progress ? `[${progress.current}/${progress.total}] ` : " ";
|
|
34742
35384
|
renderer.removeTask(logicalId);
|
|
34743
35385
|
this.logger.info(`${skipPrefix}${formatResourceLine("skipped", logicalId, resourceType, `skipped (${deleteSkipped})`)}`);
|
|
34744
|
-
|
|
34745
|
-
|
|
34746
|
-
|
|
34747
|
-
|
|
34748
|
-
|
|
34749
|
-
|
|
34750
|
-
|
|
34751
|
-
}
|
|
34752
|
-
|
|
34753
|
-
hole: "stack"
|
|
34754
|
-
}, {
|
|
35386
|
+
const nested = resourceType === "AWS::CloudFormation::Stack";
|
|
35387
|
+
const recordStack = nested ? nestedChildStackName(stackName, logicalId) : stackName;
|
|
35388
|
+
const interrupted = nested && deleteSkipped.endsWith(" was interrupted");
|
|
35389
|
+
const stackArg = {
|
|
35390
|
+
value: recordStack,
|
|
35391
|
+
hole: nested ? "child-stack" : "stack",
|
|
35392
|
+
opts: { plainIdent: true }
|
|
35393
|
+
};
|
|
35394
|
+
this.logger.warn(deleteSkippedMessage(logicalId, currentResource.physicalId, deleteSkipped, "while removing it from the template") + ". Its cdkd state record was KEPT, so the next 'cdkd deploy' re-attempts the delete. Repair the record first (for a nested stack it is the CHILD's own state, whose other resources may already be gone), or delete the resource by hand and drop the record." + (interrupted ? " The commands name the child stack record. Its destroy was interrupted: re-run 'cdkd deploy' to resume it, and drop the child record only if that cannot finish, after deleting by hand what the child still holds (the inspect command with --show-nested lists every level; a child with nested stacks of its own has records under '<child>~<logicalId>' too, each needing the same drop)." : nested ? " The commands name the child stack record. Dropping it drops every record the child still has and nothing reaches those resources again, so first delete by hand what the child still holds (the inspect command with --show-nested lists every level; a child with nested stacks of its own has records under '<child>~<logicalId>' too, each needing the same drop). The next 'cdkd deploy' then removes this row." : " Keep '--resource' on the drop: without it the command drops the record of every resource in this still-deployed stack.") + `\nInspect it with: ${pasteableCommand("cdkd state show", [stackArg, {
|
|
34755
35395
|
flag: "--stack-region",
|
|
34756
35396
|
value: this.stackRegion,
|
|
34757
35397
|
hole: "region"
|
|
34758
|
-
}]).command}
|
|
35398
|
+
}]).command}\nDrop the record with: ${pasteableCommand("cdkd state orphan", [
|
|
35399
|
+
stackArg,
|
|
35400
|
+
{
|
|
35401
|
+
flag: "--stack-region",
|
|
35402
|
+
value: this.stackRegion,
|
|
35403
|
+
hole: "region"
|
|
35404
|
+
},
|
|
35405
|
+
...nested ? [] : [{
|
|
35406
|
+
flag: "--resource",
|
|
35407
|
+
value: logicalId,
|
|
35408
|
+
hole: "logicalId",
|
|
35409
|
+
opts: { plainIdent: true }
|
|
35410
|
+
}]
|
|
35411
|
+
]).command}`);
|
|
34759
35412
|
if (counts) counts.deleteSkipped++;
|
|
34760
35413
|
return { deleteSkipped };
|
|
34761
35414
|
}
|
|
@@ -34782,31 +35435,61 @@ function validateOptions(opts) {
|
|
|
34782
35435
|
}
|
|
34783
35436
|
async function withResourceDeadline(operation, opts) {
|
|
34784
35437
|
validateOptions(opts);
|
|
34785
|
-
const startedAt = Date.now();
|
|
34786
35438
|
return new Promise((resolve, reject) => {
|
|
34787
35439
|
let settled = false;
|
|
35440
|
+
let timedOut = false;
|
|
35441
|
+
let warned = false;
|
|
34788
35442
|
let warnTimer;
|
|
34789
35443
|
let timeoutTimer;
|
|
35444
|
+
let elapsedBeforePause = 0;
|
|
35445
|
+
let runningSince = Date.now();
|
|
35446
|
+
let pauses = 0;
|
|
35447
|
+
const elapsed = () => elapsedBeforePause + (pauses > 0 ? 0 : Date.now() - runningSince);
|
|
34790
35448
|
const cleanup = () => {
|
|
34791
35449
|
if (warnTimer !== void 0) clearTimeout(warnTimer);
|
|
34792
35450
|
if (timeoutTimer !== void 0) clearTimeout(timeoutTimer);
|
|
34793
35451
|
warnTimer = void 0;
|
|
34794
35452
|
timeoutTimer = void 0;
|
|
34795
35453
|
};
|
|
34796
|
-
|
|
34797
|
-
if (
|
|
34798
|
-
|
|
34799
|
-
|
|
34800
|
-
|
|
34801
|
-
|
|
34802
|
-
|
|
34803
|
-
|
|
34804
|
-
|
|
34805
|
-
|
|
34806
|
-
|
|
34807
|
-
|
|
34808
|
-
|
|
34809
|
-
|
|
35454
|
+
const arm = () => {
|
|
35455
|
+
if (opts.onWarn && !warned) warnTimer = setTimeout(() => {
|
|
35456
|
+
if (settled) return;
|
|
35457
|
+
warned = true;
|
|
35458
|
+
try {
|
|
35459
|
+
opts.onWarn(elapsed());
|
|
35460
|
+
} catch {}
|
|
35461
|
+
}, Math.max(0, opts.warnAfterMs - elapsed()));
|
|
35462
|
+
timeoutTimer = setTimeout(() => {
|
|
35463
|
+
if (settled) return;
|
|
35464
|
+
settled = true;
|
|
35465
|
+
timedOut = true;
|
|
35466
|
+
cleanup();
|
|
35467
|
+
reject(opts.onTimeout(elapsed()));
|
|
35468
|
+
}, Math.max(0, opts.timeoutMs - elapsed()));
|
|
35469
|
+
};
|
|
35470
|
+
arm();
|
|
35471
|
+
const outer = deadlineScope.getStore();
|
|
35472
|
+
const control = {
|
|
35473
|
+
pause: () => {
|
|
35474
|
+
pauses += 1;
|
|
35475
|
+
if (pauses === 1) {
|
|
35476
|
+
elapsedBeforePause += Date.now() - runningSince;
|
|
35477
|
+
cleanup();
|
|
35478
|
+
}
|
|
35479
|
+
outer?.pause();
|
|
35480
|
+
},
|
|
35481
|
+
resume: () => {
|
|
35482
|
+
if (pauses === 0) return;
|
|
35483
|
+
pauses -= 1;
|
|
35484
|
+
if (pauses === 0) {
|
|
35485
|
+
runningSince = Date.now();
|
|
35486
|
+
if (!settled) arm();
|
|
35487
|
+
}
|
|
35488
|
+
outer?.resume();
|
|
35489
|
+
},
|
|
35490
|
+
expired: () => timedOut || (outer?.expired() ?? false)
|
|
35491
|
+
};
|
|
35492
|
+
Promise.resolve().then(() => deadlineScope.run(control, operation)).then((value) => {
|
|
34810
35493
|
if (settled) return;
|
|
34811
35494
|
settled = true;
|
|
34812
35495
|
cleanup();
|
|
@@ -34819,6 +35502,20 @@ async function withResourceDeadline(operation, opts) {
|
|
|
34819
35502
|
});
|
|
34820
35503
|
});
|
|
34821
35504
|
}
|
|
35505
|
+
const deadlineScope = new AsyncLocalStorage();
|
|
35506
|
+
async function whileEnclosingDeadlinesPaused(fn) {
|
|
35507
|
+
const control = deadlineScope.getStore();
|
|
35508
|
+
if (control === void 0) return fn();
|
|
35509
|
+
control.pause();
|
|
35510
|
+
try {
|
|
35511
|
+
return await fn();
|
|
35512
|
+
} finally {
|
|
35513
|
+
control.resume();
|
|
35514
|
+
}
|
|
35515
|
+
}
|
|
35516
|
+
function enclosingDeadlineExpired() {
|
|
35517
|
+
return deadlineScope.getStore()?.expired() ?? false;
|
|
35518
|
+
}
|
|
34822
35519
|
|
|
34823
35520
|
//#endregion
|
|
34824
35521
|
//#region src/deployment/deploy-engine/provision.ts
|
|
@@ -34856,10 +35553,13 @@ async function provisionResource(logicalId, change, stateResources, stackName, t
|
|
|
34856
35553
|
let updatePartial;
|
|
34857
35554
|
const physicalIdBeforeUpdate = stateResources[logicalId]?.physicalId;
|
|
34858
35555
|
const provisionedByBeforeUpdate = stateResources[logicalId]?.provisionedBy;
|
|
35556
|
+
this.noteSecretNamedRecord(logicalId, stateResources[logicalId]);
|
|
35557
|
+
if (change.changeType === "DELETE") this.noteSecretNamedReads(logicalId, stateResources[logicalId], stateResources);
|
|
35558
|
+
const printingRegistry = this.secretNameBagFor(logicalId);
|
|
34859
35559
|
let nestedChildUnaddressed;
|
|
34860
35560
|
const deleteGuards = [];
|
|
34861
35561
|
try {
|
|
34862
|
-
await withResourceDeadline(async () => {
|
|
35562
|
+
await withPrintingSecrets(printingRegistry, () => withResourceDeadline(async () => {
|
|
34863
35563
|
try {
|
|
34864
35564
|
const { value: bodyResult, unaddressed } = await collectDeleteGuards(deleteGuards, () => collectNestedChildUnaddressed(() => this.provisionResourceBody(logicalId, change, stateResources, stackName, template, parameterValues, conditions, counts, progress)));
|
|
34865
35565
|
deleteSkipped = bodyResult?.deleteSkipped;
|
|
@@ -34873,7 +35573,7 @@ async function provisionResource(logicalId, change, stateResources, stackName, t
|
|
|
34873
35573
|
logicalId,
|
|
34874
35574
|
resourceType: guard.resourceType,
|
|
34875
35575
|
...guard.provisionedBy && { provisionedBy: guard.provisionedBy },
|
|
34876
|
-
...guard.physicalId && { physicalId: this.
|
|
35576
|
+
...guard.physicalId && { physicalId: maskSecretsInText(guard.physicalId, this.perResourceSecrets.get(logicalId) ?? EMPTY_SECRETS) },
|
|
34877
35577
|
guard: guard.guard,
|
|
34878
35578
|
reason: guard.reason
|
|
34879
35579
|
});
|
|
@@ -34892,7 +35592,7 @@ async function provisionResource(logicalId, change, stateResources, stackName, t
|
|
|
34892
35592
|
});
|
|
34893
35593
|
},
|
|
34894
35594
|
onTimeout: (elapsedMs) => new ResourceTimeoutError(logicalId, resourceType, this.stackRegion, elapsedMs, operationKind, timeoutMs)
|
|
34895
|
-
});
|
|
35595
|
+
}));
|
|
34896
35596
|
if (counts && nestedChildUnaddressed) {
|
|
34897
35597
|
counts.deleteSkipped += nestedChildUnaddressed.deleteSkipped;
|
|
34898
35598
|
counts.updatePartial += nestedChildUnaddressed.updatePartial;
|
|
@@ -34949,7 +35649,7 @@ async function provisionResource(logicalId, change, stateResources, stackName, t
|
|
|
34949
35649
|
durationMs: Date.now() - resourceStartedAt,
|
|
34950
35650
|
error: extractDeploymentEventError(error)
|
|
34951
35651
|
});
|
|
34952
|
-
throw new ProvisioningError(`Failed to ${change.changeType.toLowerCase()} resource ${logicalId}`, resourceType, logicalId, stateResources[logicalId]?.physicalId, error instanceof Error ? maskSecretsInError(error, this.
|
|
35652
|
+
throw new ProvisioningError(`Failed to ${change.changeType.toLowerCase()} resource ${logicalId}`, resourceType, logicalId, stateResources[logicalId]?.physicalId, error instanceof Error ? maskSecretsInError(error, this.printingSecretsFor(logicalId) ?? EMPTY_SECRETS) : void 0);
|
|
34953
35653
|
} finally {
|
|
34954
35654
|
renderer.removeTask(logicalId);
|
|
34955
35655
|
}
|
|
@@ -35381,6 +36081,7 @@ async function executeDeployment(template, currentState, changes, dag, execution
|
|
|
35381
36081
|
let autoRollbackJournaled = false;
|
|
35382
36082
|
let rollbackOrphans = [];
|
|
35383
36083
|
let rollbackSettledNested = /* @__PURE__ */ new Map();
|
|
36084
|
+
let rollbackRemainingFailedOps = failedOperations;
|
|
35384
36085
|
if (error instanceof InterruptedError || isInterruptedWaitError(error) || this.interruptCause === "user") {
|
|
35385
36086
|
await this.writeRollbackJournalSegment(stackName, completedOperations, failedOperations, "interrupted", initialDeploy);
|
|
35386
36087
|
this.logger.info(`Partial state saved (${Object.keys(newResources).length} resources). Run deploy again to resume, 'cdkd rollback' to revert, or destroy to clean up.`);
|
|
@@ -35392,7 +36093,7 @@ async function executeDeployment(template, currentState, changes, dag, execution
|
|
|
35392
36093
|
this.logger.warn(safeMsg`Partial state has been saved. ${this.recoveryHint("Run 'cdkd deploy' to resume, 'cdkd rollback' to revert, or destroy to clean up.")}`);
|
|
35393
36094
|
} else {
|
|
35394
36095
|
autoRollbackJournaled = await this.writeRollbackJournalSegment(stackName, completedOperations, failedOperations, "auto-rollback-started", initialDeploy);
|
|
35395
|
-
const rollbackResult = await this.performRollback(completedOperations, newResources, stackName, currentState);
|
|
36096
|
+
const rollbackResult = await this.performRollback(completedOperations, newResources, stackName, currentState, failedOperations, currentState.orphans ?? []);
|
|
35396
36097
|
autoRollbackClean = autoRollbackJournaled && rollbackResult.failures === 0 && rollbackResult.skipped === 0;
|
|
35397
36098
|
if (rollbackResult.failures === 0 && rollbackResult.skipped > 0) {
|
|
35398
36099
|
this.logger.warn(safeMsg`The automatic rollback could not revert ${rollbackResult.skipped} operation(s) ` + `(see the warnings above; each is recorded as a ROLLBACK_RESOURCE_SKIPPED event).` + (autoRollbackJournaled ? ` The rollback journal keeps them.` : ""));
|
|
@@ -35403,6 +36104,7 @@ async function executeDeployment(template, currentState, changes, dag, execution
|
|
|
35403
36104
|
}
|
|
35404
36105
|
rollbackOrphans = rollbackResult.orphaned;
|
|
35405
36106
|
rollbackSettledNested = rollbackResult.settledNested;
|
|
36107
|
+
rollbackRemainingFailedOps = rollbackResult.remainingFailedOps;
|
|
35406
36108
|
}
|
|
35407
36109
|
try {
|
|
35408
36110
|
const postRollbackState = {
|
|
@@ -35419,7 +36121,7 @@ async function executeDeployment(template, currentState, changes, dag, execution
|
|
|
35419
36121
|
};
|
|
35420
36122
|
await this.stateBackend.saveState(stackName, this.stackRegion, this.withParentInfo(postRollbackState), { ...currentEtag !== void 0 && { expectedEtag: currentEtag } });
|
|
35421
36123
|
this.logger.debug("State saved after deployment failure");
|
|
35422
|
-
if (autoRollbackClean) await this.settleNestedChildrenAfterCleanRollback(stackName, rollbackSettledNested, await this.settleJournalAfterCleanRollback(stackName,
|
|
36124
|
+
if (autoRollbackClean) await this.settleNestedChildrenAfterCleanRollback(stackName, rollbackSettledNested, await this.settleJournalAfterCleanRollback(stackName, rollbackRemainingFailedOps, initialDeploy));
|
|
35423
36125
|
} catch (saveError) {
|
|
35424
36126
|
this.logger.debug(`Retrying state save after rollback (ETag mismatch): ${saveError instanceof Error ? saveError.message : String(saveError)}`);
|
|
35425
36127
|
try {
|
|
@@ -35438,7 +36140,7 @@ async function executeDeployment(template, currentState, changes, dag, execution
|
|
|
35438
36140
|
};
|
|
35439
36141
|
await this.stateBackend.saveState(stackName, this.stackRegion, this.withParentInfo(postRollbackState), { ...freshEtag !== void 0 && { expectedEtag: freshEtag } });
|
|
35440
36142
|
this.logger.debug("State saved after deployment failure (retry succeeded)");
|
|
35441
|
-
if (autoRollbackClean) await this.settleNestedChildrenAfterCleanRollback(stackName, rollbackSettledNested, await this.settleJournalAfterCleanRollback(stackName,
|
|
36143
|
+
if (autoRollbackClean) await this.settleNestedChildrenAfterCleanRollback(stackName, rollbackSettledNested, await this.settleJournalAfterCleanRollback(stackName, rollbackRemainingFailedOps, initialDeploy));
|
|
35442
36144
|
} catch (retryError) {
|
|
35443
36145
|
this.logger.warn(`Failed to save state after rollback: ${retryError instanceof Error ? retryError.message : String(retryError)}`);
|
|
35444
36146
|
}
|
|
@@ -35610,6 +36312,62 @@ function refuseNoValueOutputs(outputs, conditions) {
|
|
|
35610
36312
|
throw markNonRetryable(/* @__PURE__ */ new Error(`Output ${offending.join(", ")} evaluates to AWS::NoValue, and CloudFormation rejects the template for it ("The Value field of every Outputs member must evaluate to a String") before creating anything. To publish an Output only sometimes, give it a Condition instead of selecting AWS::NoValue in its Value.`));
|
|
35611
36313
|
}
|
|
35612
36314
|
|
|
36315
|
+
//#endregion
|
|
36316
|
+
//#region src/deployment/deployment-approval.ts
|
|
36317
|
+
const NESTED_STACK_TYPE$1 = "AWS::CloudFormation::Stack";
|
|
36318
|
+
async function requireDeploymentApproval(args) {
|
|
36319
|
+
const level = args.options.requireApproval ?? "never";
|
|
36320
|
+
const approve = args.options.approveDeployment;
|
|
36321
|
+
if (level === "never" || approve === void 0) return;
|
|
36322
|
+
const changes = [...args.changes].filter((c) => c.changeType !== "NO_CHANGE");
|
|
36323
|
+
const destructiveChanges = findDestructiveChanges(args.stackName, changes, args.records, args.template, new Set(args.recreateTargetIds ?? []));
|
|
36324
|
+
const onlyNestedUpdates = changes.every((c) => c.changeType === "UPDATE" && c.resourceType === NESTED_STACK_TYPE$1);
|
|
36325
|
+
if (!(level === "destructive" ? destructiveChanges.length > 0 : changes.length > 0 && !onlyNestedUpdates)) return;
|
|
36326
|
+
const count = (type) => changes.filter((c) => c.changeType === type).length;
|
|
36327
|
+
if (enclosingDeadlineExpired()) throw approvalAfterTimeout(args.stackName);
|
|
36328
|
+
let approved;
|
|
36329
|
+
try {
|
|
36330
|
+
approved = await whileEnclosingDeadlinesPaused(() => approve({
|
|
36331
|
+
stackName: args.stackName,
|
|
36332
|
+
level,
|
|
36333
|
+
counts: {
|
|
36334
|
+
create: count("CREATE"),
|
|
36335
|
+
update: count("UPDATE"),
|
|
36336
|
+
delete: count("DELETE")
|
|
36337
|
+
},
|
|
36338
|
+
destructiveChanges
|
|
36339
|
+
}));
|
|
36340
|
+
} catch (error) {
|
|
36341
|
+
throw error instanceof Error ? markNonRetryable(error) : error;
|
|
36342
|
+
}
|
|
36343
|
+
if (!approved) throw markNonRetryable(new CdkdError(safeMsg`Deployment of stack ${args.stackName} was not approved (--require-approval=${level}). Nothing was changed.`, "DEPLOY_NOT_APPROVED"));
|
|
36344
|
+
}
|
|
36345
|
+
function approvalAfterTimeout(stackName) {
|
|
36346
|
+
return markNonRetryable(new CdkdError(safeMsg`Deployment of stack ${stackName} was not started: its parent's nested-stack row already timed out (--resource-timeout). Nothing was changed.`, "DEPLOY_APPROVAL_AFTER_TIMEOUT"));
|
|
36347
|
+
}
|
|
36348
|
+
async function requireOutputsOnlyApproval(args) {
|
|
36349
|
+
const approve = args.options.approveDeployment;
|
|
36350
|
+
if (args.options.requireApproval !== "any-change" || approve === void 0) return;
|
|
36351
|
+
if (enclosingDeadlineExpired()) throw approvalAfterTimeout(args.stackName);
|
|
36352
|
+
let approved;
|
|
36353
|
+
try {
|
|
36354
|
+
approved = await whileEnclosingDeadlinesPaused(() => approve({
|
|
36355
|
+
stackName: args.stackName,
|
|
36356
|
+
level: "any-change",
|
|
36357
|
+
counts: {
|
|
36358
|
+
create: 0,
|
|
36359
|
+
update: 0,
|
|
36360
|
+
delete: 0
|
|
36361
|
+
},
|
|
36362
|
+
destructiveChanges: [],
|
|
36363
|
+
outputsOnly: true
|
|
36364
|
+
}));
|
|
36365
|
+
} catch (error) {
|
|
36366
|
+
throw error instanceof Error ? markNonRetryable(error) : error;
|
|
36367
|
+
}
|
|
36368
|
+
if (!approved) throw markNonRetryable(new CdkdError(safeMsg`Deployment of stack ${args.stackName} was not approved (--require-approval=any-change). Nothing was changed.`, "DEPLOY_NOT_APPROVED"));
|
|
36369
|
+
}
|
|
36370
|
+
|
|
35613
36371
|
//#endregion
|
|
35614
36372
|
//#region src/deployment/condition-verdicts.ts
|
|
35615
36373
|
function conditionInputsFrom(args) {
|
|
@@ -36137,6 +36895,7 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
36137
36895
|
}));
|
|
36138
36896
|
}
|
|
36139
36897
|
const effectiveTemplate = this.templateParser.filterResourcesByCondition(template, conditions);
|
|
36898
|
+
this.constructPathTemplate = effectiveTemplate;
|
|
36140
36899
|
const orphanCountBeforeAdoption = (currentState.orphans ?? []).length;
|
|
36141
36900
|
const orphanPlan = await this.adoptRollbackOrphans(currentState, effectiveTemplate);
|
|
36142
36901
|
if (Object.keys(orphanPlan.adopted).length > 0) {
|
|
@@ -36230,6 +36989,10 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
36230
36989
|
const skippedOutputsChanged = !skippedOutputsEqual(currentState.skippedOutputs, this.skippedOutputs);
|
|
36231
36990
|
const healedAttributesPending = this.hasUnpersistedHeals(currentState.resources);
|
|
36232
36991
|
const conditionVerdictsChanged = !conditionVerdictRecordsEqual(readRecordedConditionVerdicts(currentState), conditionVerdicts);
|
|
36992
|
+
if (outputsChanged || exportSetChanged && currentState.exportNames !== void 0) await requireOutputsOnlyApproval({
|
|
36993
|
+
options: this.options,
|
|
36994
|
+
stackName
|
|
36995
|
+
});
|
|
36233
36996
|
if (observedRefresh || maskedFingerprintsBackfilled || conditionVerdictsChanged || outputsChanged || exportSetChanged || skippedOutputsChanged || orphansChanged || healedAttributesPending) try {
|
|
36234
36997
|
const refreshedState = {
|
|
36235
36998
|
version: 10,
|
|
@@ -36263,13 +37026,12 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
36263
37026
|
this.logger.warn(`Failed to persist no-change state update: ${saveError instanceof Error ? saveError.message : String(saveError)} — drift baseline / outputs will be re-resolved on next deploy.`);
|
|
36264
37027
|
}
|
|
36265
37028
|
}
|
|
36266
|
-
if (!this.options.dryRun) await this.settleJournalAfterSuccess(stackName, [], currentState, currentState.resources, currentEtag === void 0);
|
|
36267
37029
|
return {
|
|
36268
37030
|
stackName,
|
|
36269
37031
|
created: 0,
|
|
36270
37032
|
updated: 0,
|
|
36271
37033
|
deleted: 0,
|
|
36272
|
-
deleteSkipped: 0,
|
|
37034
|
+
deleteSkipped: this.options.dryRun ? 0 : await this.settleJournalAfterSuccess(stackName, [], currentState, currentState.resources, currentEtag === void 0),
|
|
36273
37035
|
updatePartial: 0,
|
|
36274
37036
|
unchanged: Object.keys(currentState.resources).length,
|
|
36275
37037
|
durationMs: Date.now() - startTime,
|
|
@@ -36295,6 +37057,14 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
36295
37057
|
attributeFallbackCount: this.resolver.getPhysicalIdFallbackCount()
|
|
36296
37058
|
};
|
|
36297
37059
|
}
|
|
37060
|
+
await requireDeploymentApproval({
|
|
37061
|
+
options: this.options,
|
|
37062
|
+
stackName,
|
|
37063
|
+
changes: changes.values(),
|
|
37064
|
+
records: currentState.resources,
|
|
37065
|
+
template: effectiveTemplate,
|
|
37066
|
+
recreateTargetIds: recreateTargetIdsFor(this.options.recreateTargets, stackName)
|
|
37067
|
+
});
|
|
36298
37068
|
this.resolver.resetPhysicalIdFallbackCount();
|
|
36299
37069
|
const progress = {
|
|
36300
37070
|
current: 0,
|
|
@@ -36308,7 +37078,7 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
36308
37078
|
} : newState));
|
|
36309
37079
|
this.logger.debug(`State saved (ETag: ${newEtag})`);
|
|
36310
37080
|
await forgetRecordedCreateTokens(Object.keys(newState.resources));
|
|
36311
|
-
await Promise.all([this.settleJournalAfterSuccess(stackName, completedOperations, currentState, newState.resources, currentEtag === void 0), this.exportIndexStore ? this.exportIndexStore.updateForStack(stackName, this.stackRegion, importableOutputs({
|
|
37081
|
+
const [journaledOrphansLeft] = await Promise.all([this.settleJournalAfterSuccess(stackName, completedOperations, currentState, newState.resources, currentEtag === void 0), this.exportIndexStore ? this.exportIndexStore.updateForStack(stackName, this.stackRegion, importableOutputs({
|
|
36312
37082
|
...newState,
|
|
36313
37083
|
outputs: this.redactOutputs(newState.outputs)
|
|
36314
37084
|
})) : Promise.resolve()]);
|
|
@@ -36319,7 +37089,7 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
36319
37089
|
created: actualCounts.created,
|
|
36320
37090
|
updated: actualCounts.updated,
|
|
36321
37091
|
deleted: actualCounts.deleted,
|
|
36322
|
-
deleteSkipped: actualCounts.deleteSkipped,
|
|
37092
|
+
deleteSkipped: actualCounts.deleteSkipped + journaledOrphansLeft,
|
|
36323
37093
|
updatePartial: actualCounts.updatePartial,
|
|
36324
37094
|
nestedUpdatePartial: actualCounts.nestedUpdatePartial,
|
|
36325
37095
|
unchanged: unchangedCount,
|
|
@@ -36342,77 +37112,6 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
|
|
|
36342
37112
|
}
|
|
36343
37113
|
}
|
|
36344
37114
|
|
|
36345
|
-
//#endregion
|
|
36346
|
-
//#region src/deployment/deploy-engine/resolver-context.ts
|
|
36347
|
-
function buildResolverContext(base, stackName) {
|
|
36348
|
-
const recordedSecretValues = /* @__PURE__ */ new Map();
|
|
36349
|
-
if (this.options.inheritedSecrets && this.options.inheritedSecrets.size > 0) inheritNestedStackParameterAssociations(recordedSecretValues, this.options.inheritedSecrets);
|
|
36350
|
-
return {
|
|
36351
|
-
template: base.template,
|
|
36352
|
-
resources: base.resources,
|
|
36353
|
-
...base.parameters && Object.keys(base.parameters).length > 0 && { parameters: base.parameters },
|
|
36354
|
-
...base.conditions && Object.keys(base.conditions).length > 0 && { conditions: base.conditions },
|
|
36355
|
-
stateBackend: this.stateBackend,
|
|
36356
|
-
stackName,
|
|
36357
|
-
...this.exportIndexStore && { exportIndex: this.exportIndexStore },
|
|
36358
|
-
recordedImports: this.recordedImports,
|
|
36359
|
-
recordedOutputReads: this.recordedOutputReads,
|
|
36360
|
-
attributeHealer: (logicalId, resource) => this.healStaleAttributes(logicalId, resource, stackName),
|
|
36361
|
-
...this.options.inheritedSecrets && hasMaskableValues(this.options.inheritedSecrets) && { inheritedSecrets: this.options.inheritedSecrets },
|
|
36362
|
-
recordedSecretValues,
|
|
36363
|
-
noEchoAttributeResources: this.noEchoAttributeResources,
|
|
36364
|
-
...base.redactedAttributeReads && { redactedAttributeReads: base.redactedAttributeReads }
|
|
36365
|
-
};
|
|
36366
|
-
}
|
|
36367
|
-
function getAttTargetOf(node) {
|
|
36368
|
-
if (node === null || typeof node !== "object" || Array.isArray(node)) return void 0;
|
|
36369
|
-
const getAtt = node["Fn::GetAtt"];
|
|
36370
|
-
if (Array.isArray(getAtt) && typeof getAtt[0] === "string") return getAtt[0];
|
|
36371
|
-
if (typeof getAtt === "string") return getAtt.split(".")[0];
|
|
36372
|
-
}
|
|
36373
|
-
function maskedInputSources(template, resources, conditions, stackName) {
|
|
36374
|
-
const parameters = this.fingerprintParameters;
|
|
36375
|
-
if (parameters === void 0) return void 0;
|
|
36376
|
-
return {
|
|
36377
|
-
template,
|
|
36378
|
-
parameterInput: parameters.parameterInput,
|
|
36379
|
-
conditions,
|
|
36380
|
-
childTemplate: this.fingerprintChildTemplates,
|
|
36381
|
-
resolve: async (node) => {
|
|
36382
|
-
const { attributeHealer: _healer, ...base } = this.buildResolverContext({
|
|
36383
|
-
template,
|
|
36384
|
-
resources,
|
|
36385
|
-
parameters: parameters.bound,
|
|
36386
|
-
...conditions && { conditions }
|
|
36387
|
-
}, stackName);
|
|
36388
|
-
const context = {
|
|
36389
|
-
...base,
|
|
36390
|
-
recordedImports: [],
|
|
36391
|
-
recordedOutputReads: [],
|
|
36392
|
-
bestEffort: true,
|
|
36393
|
-
skipDynamicReferences: true,
|
|
36394
|
-
staleAttributeHeal: { phase: "probe" }
|
|
36395
|
-
};
|
|
36396
|
-
const value = await this.resolver.resolve(structuredClone(node), context);
|
|
36397
|
-
const secrets = context.recordedSecretValues;
|
|
36398
|
-
const target = getAttTargetOf(node);
|
|
36399
|
-
const targetSecrets = target === void 0 ? void 0 : this.perResourceSecrets.get(target);
|
|
36400
|
-
if (targetSecrets !== void 0 && hasMaskableValues(targetSecrets)) {
|
|
36401
|
-
const probe = { value };
|
|
36402
|
-
const redacted = redactSecretsForState(probe, targetSecrets);
|
|
36403
|
-
if (JSON.stringify(redacted) !== JSON.stringify(probe)) return {
|
|
36404
|
-
value,
|
|
36405
|
-
keepAsWritten: true
|
|
36406
|
-
};
|
|
36407
|
-
}
|
|
36408
|
-
return {
|
|
36409
|
-
value,
|
|
36410
|
-
...secrets && { secrets }
|
|
36411
|
-
};
|
|
36412
|
-
}
|
|
36413
|
-
};
|
|
36414
|
-
}
|
|
36415
|
-
|
|
36416
37115
|
//#endregion
|
|
36417
37116
|
//#region src/deployment/label-routing.ts
|
|
36418
37117
|
function deriveLabelRouting(change, existingState, registry, forceCcApi = false) {
|
|
@@ -36633,6 +37332,7 @@ var DeployEngine = class {
|
|
|
36633
37332
|
recordedOutputReads = [];
|
|
36634
37333
|
perResourceSecrets = /* @__PURE__ */ new Map();
|
|
36635
37334
|
noEchoAttributeResources = /* @__PURE__ */ new Map();
|
|
37335
|
+
secretNameNeedles = /* @__PURE__ */ new Map();
|
|
36636
37336
|
perResourceTemplateProps = /* @__PURE__ */ new Map();
|
|
36637
37337
|
perResourceResolvedType = /* @__PURE__ */ new Map();
|
|
36638
37338
|
fingerprintNoEchoValues = void 0;
|
|
@@ -36644,6 +37344,7 @@ var DeployEngine = class {
|
|
|
36644
37344
|
outputsTemplateSource = Object.create(null);
|
|
36645
37345
|
resolvedExportNames = [];
|
|
36646
37346
|
skippedOutputs;
|
|
37347
|
+
constructPathTemplate;
|
|
36647
37348
|
outputsSourceUsable = true;
|
|
36648
37349
|
attemptedResolvedProps = /* @__PURE__ */ new Map();
|
|
36649
37350
|
liveTaskLabels = /* @__PURE__ */ new Map();
|
|
@@ -36684,7 +37385,9 @@ var DeployEngine = class {
|
|
|
36684
37385
|
this.recordedOutputReads = [];
|
|
36685
37386
|
this.perResourceSecrets = /* @__PURE__ */ new Map();
|
|
36686
37387
|
this.noEchoAttributeResources = /* @__PURE__ */ new Map();
|
|
37388
|
+
this.secretNameNeedles = /* @__PURE__ */ new Map();
|
|
36687
37389
|
this.perResourceTemplateProps = /* @__PURE__ */ new Map();
|
|
37390
|
+
this.constructPathTemplate = void 0;
|
|
36688
37391
|
this.perResourceResolvedType = /* @__PURE__ */ new Map();
|
|
36689
37392
|
this.fingerprintNoEchoValues = void 0;
|
|
36690
37393
|
this.fingerprintParameters = void 0;
|
|
@@ -36717,7 +37420,7 @@ var DeployEngine = class {
|
|
|
36717
37420
|
const secrets = this.perResourceSecrets.get(logicalId);
|
|
36718
37421
|
const templateProps = this.perResourceTemplateProps.get(logicalId);
|
|
36719
37422
|
const scrubbed = scrubResourceRecord(this.withHealedAttributes(logicalId, record), secrets ?? /* @__PURE__ */ new Map(), templateProps);
|
|
36720
|
-
resources[logicalId] = withMaskedPropertyFingerprints(scrubbed, record.properties, templateProps, secrets, this.fingerprintNoEchoValues, this.perResourceInputFingerprints.get(logicalId));
|
|
37423
|
+
resources[logicalId] = withConstructPath(withMaskedPropertyFingerprints(scrubbed, record.properties, templateProps, secrets, this.fingerprintNoEchoValues, this.perResourceInputFingerprints.get(logicalId)), constructPathOf(this.constructPathTemplate, logicalId));
|
|
36721
37424
|
}
|
|
36722
37425
|
const orphans = state.orphans?.map((entry) => {
|
|
36723
37426
|
const sameResource = this.perResourceResolvedType.get(entry.logicalId) === entry.state.resourceType;
|
|
@@ -36798,7 +37501,7 @@ var DeployEngine = class {
|
|
|
36798
37501
|
} catch {}
|
|
36799
37502
|
}
|
|
36800
37503
|
maskSecretsInEvent(event) {
|
|
36801
|
-
const secrets = event.logicalId ? this.
|
|
37504
|
+
const secrets = event.logicalId ? this.printingSecretsFor(event.logicalId) : void 0;
|
|
36802
37505
|
if (!secrets || !hasMaskableValues(secrets)) return event;
|
|
36803
37506
|
const next = { ...event };
|
|
36804
37507
|
if (next.error?.message) next.error = {
|
|
@@ -36874,6 +37577,11 @@ DeployEngine.prototype.refuseRedactedAttributeReads = refuseRedactedAttributeRea
|
|
|
36874
37577
|
DeployEngine.prototype.allRecordedSecrets = allRecordedSecrets;
|
|
36875
37578
|
DeployEngine.prototype.readReaderForFreshNoEchoCeiling = readReaderForFreshNoEchoCeiling;
|
|
36876
37579
|
DeployEngine.prototype.maskForResource = maskForResource;
|
|
37580
|
+
DeployEngine.prototype.secretNameBagFor = secretNameBagFor;
|
|
37581
|
+
DeployEngine.prototype.noteSecretNamedRecord = noteSecretNamedRecord;
|
|
37582
|
+
DeployEngine.prototype.printingSecretsFor = printingSecretsFor;
|
|
37583
|
+
DeployEngine.prototype.namingSecretsFor = namingSecretsFor;
|
|
37584
|
+
DeployEngine.prototype.noteSecretNamedReads = noteSecretNamedReads;
|
|
36877
37585
|
DeployEngine.prototype.kickOffObservedCapture = kickOffObservedCapture;
|
|
36878
37586
|
DeployEngine.prototype.drainObservedCaptures = drainObservedCaptures;
|
|
36879
37587
|
DeployEngine.prototype.buildObservedCaptureSiblings = buildObservedCaptureSiblings;
|
|
@@ -36898,5 +37606,5 @@ DeployEngine.prototype.replacementNameOrigin = replacementNameOrigin;
|
|
|
36898
37606
|
DeployEngine.prototype.orphanedNameCollisionAdvice = orphanedNameCollisionAdvice;
|
|
36899
37607
|
|
|
36900
37608
|
//#endregion
|
|
36901
|
-
export { resourcesNamingDeclaredParameter as $, recordMaskOnlyValuesIn as $a, WARM_THROUGHPUT_MEMBERS as $i, assertSendableRoleArn as $n, getDockerCmd as $o, malformedOutputsRefusalMessage as $r, isWholeDynamicReferenceValue as $t, resolveDynamoDbDeleteBudgetClock as A, hasMaskableValues as Aa, refuseMalformedResourcesForExport as Ai, slowCcOperationTimeoutMs as An, buildAssetRedirectMap as Ao, JSON_LISTING_HOLE_VALUE as Ar, uploadCfnTemplate as As, buildFinalSnapshotIdentifier as At, getPriorAttempts as B, maskSecretsInText as Ba, unreadableResourceEntries as Bi, ec2InstanceProtectionSite as Bn, parseBootstrapMarker as Bo, isReadableOrphanRecord as Br, defineOwnKey as Bs, redactedDeleteAddressSkip as Bt, perType as C, DagBuilder as Ca, refuseMalformedResourceEntriesForOrphan as Ci, CC_BROKEN_REASON as Cn, orphansAfterRollback as Co, cfnRefValueFromPhysicalId as Cr, stateBucketExistenceConfirmed as Cs, planRollback as Ct, beginDeleteWait as D, recordNestedStackParameterExpressions as Da, refuseMalformedResourcePropertiesForOrphan as Di, isCustomResourceType as Dn, isSensitiveAttributeName as Do, withSharedDrainBudget as Dr, CFN_TEMPLATE_URL_LIMIT as Ds, inheritProducerRegions as Dt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as E, inheritNestedStackParameterAssociations as Ea, refuseMalformedResourcePropertiesForExport as Ei, wouldReturnToSdkProvider as En, AssetPublisher as Eo, parseWebACLArn as Er, CFN_TEMPLATE_BODY_LIMIT as Es, getCurrentProducerRegions as Et, waitForIndexesSettled as F, recordLogOnlyValue as Fa, repairMalformedResourceEntriesForReadOnly as Fi, deleteSkipReason as Fn, BOOTSTRAP_MARKER_PREFIX as Fo, deployRefusesOrphanRowsReason as Fr, canonicalizeRegion as Fs, refusesFinalSnapshot as Ft, cyan as G, DYNAMIC_REFERENCE_TOKEN_SCAN as Ga, NO_CC_HANDLERS_REASON as Gi, DiffCalculator as Gn, buildDockerImage as Go, malformedLocalOutputsWarning as Gr, absoluteAssemblyPathEscape as Gs, extractDeploymentEventError as Gt, formatResourceLine as H, redactSecretsForState as Ha, findSilentDropProperties as Hi, observeThenDisableInstanceApiTermination as Hn, validateAssetBucketName as Ho, malformedDriftResourcePropertiesWarning as Hr, hasPlainPrototype$1 as Hs, updatePartialReason as Ht, ECR_AUTO_DELETE_IMAGES_TAG as I, shareLogOnlyValues as Ia, repairMalformedResourcePropertiesForReadOnly as Ii, withIndeterminateGuard as In, assertAssetBucketRegion as Io, displayLogicalId as Ir, derivePartitionAndUrlSuffix as Is, unsupportedFinalSnapshotError as It, red as J, pathCrossesDottedKey as Ja, shownType as Ji, classifyReplaySecretRegion as Jn, describeDockerExecFailure as Jo, malformedOrphanRecordsRefusalMessage as Jr, renderAssemblyPathEscape as Js, exportAliasCollisionScrubWarning as Jt, gray as K, dynamicReferenceTokens as Ka, hasNoCloudControlHandlers as Ki, INTRINSIC_KEYS as Kn, resolveDockerContextDirectory as Ko, malformedLocalResourceEntriesWarning as Kr, describeFileReadFailure as Ks, WITHHELD_NAME_DISPLAY as Kt, S3_AUTO_DELETE_OBJECTS_TAG as L, createSecretMasker as La, repairMalformedResourcesForReadOnly as Li, isWaitAbandonedError as Ln, ensureAssetStorage as Lo, hasReadableOrphans as Lr, AssemblyReader as Ls, REDACTED_DELETE_ADDRESS_SKIP_REASON as Lt, DELETE_INDEX_WAIT_PROCEED_NOTE as M, logOnlyValueCount as Ma, repairMalformedOrphanRecordsForReadOnly as Mi, unchangedBehindSecretReference as Mn, loadPublishableAssetManifest as Mo, STATE_RESOURCES_MALFORMED as Mr, decodeListingKey as Ms, createPreDeleteFinalSnapshot as Mt, INDEX_SETTLE_POLL_INTERVAL_MS as N, printingCorpusOf as Na, repairMalformedOrphansForReadOnly as Ni, UNSPECIFIED_SKIP_REASON as Nn, rewriteTemplateAssetReferences as No, UNREADABLE_ORPHANS_CONTAINER_ROW as Nr, expectedOwnerParam as Ns, effectiveDeletionPolicy as Nt, compensateRemovedDeletionProtection as O, carryLogOnlyValues as Oa, refuseMalformedResourcesForDeploy as Oi, getCurrentResourceSecrets as On, stringifyValue as Oo, parameterInputsFor as Or, MIGRATE_TMP_PREFIX as Os, ATOMIC_FINAL_SNAPSHOT_TYPES as Ot, deleteTableWithIndexBusyRetry as P, recordLogOnlyParameterValue as Pa, repairMalformedOutputsForReadOnly as Pi, deleteIndeterminateGuards as Pn, AssetModeResolver as Po, UNREADABLE_RESOURCES_MAP_ROW as Pr, PARTITION_TABLE as Ps, isFinalSnapshotError as Pt, reachableDivergentParameters as Q, recordMaskOnlyValue as Qa, renderStatefulReason as Qi, assertFlagRoleArn as Qn, formatDockerLoginError as Qo, malformedOrphansWarning as Qr, exportNameSecretExposure as Qt, hasCdkAutoDeleteTag as R, errorCauseChain as Ra, unpreviewableOrphanRecords as Ri, markWaitAbandoned as Rn, getBootstrapMarkerKey as Ro, hasReadableOutputs as Rr, StageLoadError as Rs, isRedactedRecordedValue as Rt, isProtectionValueActive as S, sameLambdaFunctionAddress as Sa, refuseMalformedResourceEntriesForImportSave as Si, stringifyIfAssigned as Sn, isReadableBag as So, AWS_NO_VALUE as Sr, resolveUseCdkBootstrapAssets as Ss, planFailedOps as St, DynamoDBGlobalTableProvider as T, liveMatchesUnresolvedTokenFrame as Ta, refuseMalformedResourcePropertiesForDrift as Ti, ccBrokenReason as Tn, shouldRetainResource as To, refStateLookupFromResource as Tr, ssmResolvedValueType as Ts, findNestedStackTypeChanges as Tt, createReadOnlyAttributeHealerFactory as U, scrubResourceRecord as Ua, unwrittenCreateOnlyReplacement as Ui, reDisableInstanceApiTermination as Un, validateContainerRepoName as Uo, malformedExportNamesWarning as Ur, nullPrototypeRecord as Us, DeploymentEventsReader as Ut, markRefusedBeforeApplying as V, markSameGenerationBag as Va, findActionableSilentDrops as Vi, isTerminationProtectionPropagationError as Vn, readBootstrapMarkerBody as Vo, isReadableResourceEntry as Vr, hasOwnKey as Vs, updatePartialMessage as Vt, bold as W, recoverMaskedOutput as Wa, withoutSilentDropProperties as Wi, reEnableInstanceApiTermination as Wn, buildDenyExternalAccessPolicy as Wo, malformedExportSourceWarning as Wr, ownValue as Ws, DeploymentEventsStore as Wt, computeParameterTaint as X, carriesSecretMask as Xa, isStatefulRecreateTargetForReplace as Xi, regionLessSecretName as Xn, dockerSpawnEnvWithSensitive as Xo, malformedOrphanRowsKeptWarning as Xr, clearBucketRegionCache as Xs, secretBearingStateKeyWarning as Xt, yellow as Y, identityKeyFor as Ya, MULTI_REGION_RECREATE_BLOCKED_TYPES as Yi, producerRegionsFromState as Yn, describeDockerFailure as Yo, malformedOrphanRecordsWarning as Yr, resolveAssemblyPath as Ys, secretBearing as Yt, namesAnyDeclaredParameter as Z, provenPublicValue as Za, isStatefulRecreateTargetSync as Zi, applyRoleArnIfSet as Zn, finchSecretArgvRefusal as Zo, malformedOrphansRefusalMessage as Zr, resolveBucketRegion as Zs, secretSafeKeyDisplay as Zt, makeCanonicalizePropertiesFn as _, withRetry as _a, refuseMalformedResourceAttributesForOrphan as _i, readTagList as _n, hasReadableExportSet as _o, isImpossibleEmptyStoredAttribute as _r, resolveAutoAssetStorage as _s, destroyStackRecordsView as _t, findNestedTemplateTreeDefect as a, coerceCfnInteger as aa, malformedScrubResourceEntriesRefusalMessage as ai, DEFAULT_RESOURCE_TIMEOUT_MS as an, STATE_SOURCED_READBACK_RULES as ao, callerEnvCredentials as ar, runDockerForeground as as, dropSettledNestedJournals as at, recordedProtectionNote as b, canonicalLambdaFunctionName as ba, refuseMalformedResourceEntriesForDestroy as bi, tagPlanWarning as bn, importableOutputKeys as bo, isNamelessDynamicReferenceError as br, resolveStateBucketWithDefault as bs, recordAfterRollbackUpdate as bt, renderNestedTemplateTreeDefect as c, configStringRefusal as ca, refuseDivergentRecordRegionForDestroy as ci, RollbackInlinePolicyWriters as cn, isSingleDynamicReferenceToken as co, s3BucketArn as cr, escapeRegExp$3 as cs, recordDisplacedSkips as ct, conditionInputsFrom as d, requireConfigArray as da, refuseMalformedOrphanRecordsForDestroy as di, reserveStackCreateToken as dn, S3StateBackend as do, s3BucketRegionalDomainName as dr, getDockerImageBySourceHash as ds, withNestedRevertRun as dt, coerceWarmThroughput as ea, malformedOutputsWarning as ei, noEchoParameterValueSeed as en, recordNoEchoAttributeValues as eo, explicitRoleArnOrThrow as er, isDockerClientEnvKey as es, makeSiblingClaimReader as et, parentSuppliedValues as f, requireConfigObject as fa, refuseMalformedOrphans as fi, withCreateTokenLedger as fn, rebuildClientForBucketRegion as fo, s3BucketWebsiteUrl as fr, Synthesizer as fs, getCurrentNestedStackContext as ft, mergeNoChangeOutputs as g, describeTypeWithThrottleRetry as ga, refuseMalformedOutputsForDestroy as gi, planTagDiff as gn, exportNamesCarriedFrom as go, getAccountInfo as gr, resolveApp as gs, awaitInFlightSibling as gt, keptWholeReasonText as h, templateResourceTypes as ha, refuseMalformedOutputs as hi, DBPROXY_TAG_OPTIONS as hn, describeRegionValueKind as ho, parameterTypeMayLoseSecretIdentity as hr, getLegacyStateBucketName as hs, replayRollback as ht, childTemplateLoader as i, coerceCfnBoolean as ia, malformedResourcesWarning as ii, bindingSkippedOutputs as in, STATE_SOURCED_CROSS_GENERATION_RULES as io, applyCallerIdentityCredentials as ir, redactedDockerCause as is, displacedPhysicalIdShown as it, resolveDynamoDbDeleteBudgetMs as j, literalSplitDelimitersOf as ja, refuseMalformedState as ji, ccProtectionRegistryTypes as jn, createAssetRedirectResolver as jo, STATE_REGION_DIVERGED as jr, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as js, ccRoutedFinalSnapshotError as jt, deleteBudgetKey as k, createUnionSecretMasker as ka, refuseMalformedResourcesForDestroy as ki, CloudControlProvider as kn, WorkGraph as ko, passedParameterClassesOf as kr, findLargeInlineResources as ks, PRE_DELETE_SNAPSHOT_TYPES as kt, templateIdentity as l, readConfigString as la, refuseMalformedNestedChildOutputs as li, earliestDefined as ln, LockManager as lo, s3BucketDomainName as lr, stripControlChars as ls, revertNestedChildFromJournal as lt, isSecretBearingReferenceString as m, prefetchCreateOnlyPropertyPaths as ma, refuseMalformedOrphansForOrphan as mi, DBPROXY_TAGS_WHAT as mn, acceptedCreateOnlyDropsOf as mo, isUnboundTemplateParameter as mr, getDefaultStateBucketName as ms, replayFailedOperations as mt, IMPLICIT_DELETE_DEPENDENCIES as n, toCfnInteger as na, malformedResourceEntriesWarning as ni, collectPublishedOutputNames as nn, wholeStringLeavesOf as no, sendableAssumeRoleCommand as nr, partitionSensitiveEnv as ns, NESTED_PENDING_PARENT_REASON as nt, isAbsoluteAssetPath as o, configBooleanRefusal as oa, malformedStateRefusalMessage as oi, DEFAULT_RESOURCE_WARN_AFTER_MS as on, TEMPLATE_SOURCED_RULES as oo, envCredentialsAreAssumedRole as or, runDockerStreaming as os, getNestedRevertRun as ot, readRecordedConditionVerdicts as p, requireConfigString as pa, refuseMalformedOrphansForDestroy as pi, acquireIdempotencyToken as pn, splitImportedOps as po, coerceParameterTypedValue as pr, synthesisStatusMessage as ps, withNestedStackContext as pt, green as q, isUncertifiedBaselineMaskPosition as qa, findReplacedReadersOfRecreateTargets as qi, IntrinsicFunctionResolver as qn, describeDockerCapturedOutput as qo, malformedLocalResourcesWarning as qr, displayAssemblyPath as qs, displayTextOrWithheld as qt, computeImplicitDeleteEdges as r, toFiniteNumber as ra, malformedResourcePropertiesWarning as ri, isExportAliasCollision as rn, STATE_SOURCED_BASELINE_RULES as ro, AWS_CREDENTIAL_ENV_KEYS as rr, redactDockerArgvValues as rs, displacedOpClause as rt, listNestedTemplateRows as s, configIntegerRefusal as sa, previewableOrphanRecords as si, maskingRetryLogger as sn, WHOLE_DYNAMIC_REFERENCE_PATTERN as so, isSettledInstanceState as sr, warnFinchArgvExposure as ss, nestedChildStackName as st, DeployEngine as t, isWarmThroughputDecrease as ta, malformedRenderedContainersWarning as ti, collectDeclaredOutputNames as tn, recordProvenPublicExpression as to, isIamRoleArn as tr, isMalformedEnvKey as ts, planOrphanAdoption as tt, conditionFingerprint as u, replayWarn as ua, refuseMalformedOrphanRecords as ui, ledgerForStack as un, isLockInfoExpired as uo, s3BucketDualStackDomainName as ur, AssetManifestLoader as us, revertedNestedRowIds as ut, withResourceDeadline as v, markAuxiliaryFailure as va, refuseMalformedResourceEntries as vi, refuseMalformedDesiredTags as vn, hasReasonlessBaselineRefusal as vo, carriesDynamicReference as vr, resolveCaptureObservedState as vs, getStackRecords as vt, readProtection as w, TemplateParser as wa, refuseMalformedResourcePropertiesForDestroy as wi, ProviderRegistry as wn, orphansCarriedFrom as wo, isStalePlaceholderArnAttribute as wr, warnDeprecatedNoPrefixCliFlag as ws, resolveReplacementOldType as wt, PROTECTION_PROPERTY_BY_TYPE as x, lambdaFunctionNameForMask as xa, refuseMalformedResourceEntriesForImport as xi, definedAttributes as xn, importableOutputs as xo, keepsSecretReferenceToken as xr, resolveStateBucketWithDefaultAndSource as xs, demoteSupersededOrphans as xt, recordedProtectionEvidence as y, markCreatedBeforeFailure as ya, refuseMalformedResourceEntriesForDeploy as yi, tagMapAsList as yn, hasUnverifiableParameterRefusal as yo, carriesFetchableDynamicReference as yr, resolveSkipPrefix as ys, withStackRecords as yt, isTruthyCfnBoolean as z, maskSecretsInError as za, unreadableOrphanRecords as zi, disableInstanceApiTermination as zn, isCrossRegionRedirect as zo, hasReadableResources as zr, processStackMessages as zs, redactedDeleteAddressFields as zt };
|
|
36902
|
-
//# sourceMappingURL=deploy-engine-
|
|
37609
|
+
export { resourcesNamingDeclaredParameter as $, dynamicReferenceTokens as $a, withoutSilentDropProperties as $i, reEnableInstanceApiTermination as $n, resolveDockerContextDirectory as $o, malformedExportSourceWarning as $r, absoluteAssemblyPathEscape as $s, displayTextOrWithheld as $t, resolveDynamoDbDeleteBudgetClock as A, DagBuilder as Aa, refuseMalformedResourceEntriesForImport as Ai, definedAttributes as An, orphansAfterRollback as Ao, keepsSecretReferenceToken as Ar, resolveUseCdkBootstrapAssets as As, resolveReplacementOldType as At, getPriorAttempts as B, printingCorpusOf as Ba, refuseMalformedState as Bi, ccProtectionRegistryTypes as Bn, rewriteTemplateAssetReferences as Bo, STATE_REGION_DIVERGED as Br, decodeListingKey as Bs, isFinalSnapshotError as Bt, perType as C, prefetchCreateOnlyPropertyPaths as Ca, refuseMalformedOrphansForOrphan as Ci, DBPROXY_TAGS_WHAT as Cn, exportNamesCarriedFrom as Co, isUnboundTemplateParameter as Cr, loadCdkJson as Cs, getStackRecords as Ct, beginDeleteWait as D, canonicalLambdaFunctionName as Da, refuseMalformedResourceEntries as Di, refuseMalformedDesiredTags as Dn, importableOutputKeys as Do, carriesDynamicReference as Dr, resolveSkipPrefix as Ds, isJournaledOrphan as Dt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as E, withRetry as Ea, refuseMalformedResourceAttributesForOrphan as Ei, readTagList as En, hasUnverifiableParameterRefusal as Eo, isImpossibleEmptyStoredAttribute as Er, resolveCaptureObservedState as Es, demoteSupersededOrphans as Et, waitForIndexesSettled as F, carryLogOnlyValues as Fa, refuseMalformedResourcePropertiesForExport as Fi, wouldReturnToSdkProvider as Fn, stringifyValue as Fo, parseWebACLArn as Fr, CFN_TEMPLATE_URL_LIMIT as Fs, PRE_DELETE_SNAPSHOT_TYPES as Ft, cyan as G, errorCauseChain as Ga, repairMalformedResourcePropertiesForReadOnly as Gi, withIndeterminateGuard as Gn, getBootstrapMarkerKey as Go, displayLogicalId as Gr, AssemblyReader as Gs, redactedDeleteAddressFields as Gt, formatResourceLine as H, recordLogOnlyValue as Ha, repairMalformedOrphansForReadOnly as Hi, UNSPECIFIED_SKIP_REASON as Hn, BOOTSTRAP_MARKER_PREFIX as Ho, UNREADABLE_ORPHANS_CONTAINER_ROW as Hr, PARTITION_TABLE as Hs, unsupportedFinalSnapshotError as Ht, ECR_AUTO_DELETE_IMAGES_TAG as I, createUnionSecretMasker as Ia, refuseMalformedResourcePropertiesForOrphan as Ii, isCustomResourceType as In, WorkGraph as Io, withSharedDrainBudget as Ir, MIGRATE_TMP_PREFIX as Is, buildFinalSnapshotIdentifier as It, red as J, markSameGenerationBag as Ja, unreadableOrphanRecords as Ji, disableInstanceApiTermination as Jn, readBootstrapMarkerBody as Jo, hasReadableResources as Jr, defineOwnKey as Js, updatePartialReason as Jt, gray as K, maskSecretsInError as Ka, repairMalformedResourcesForReadOnly as Ki, isWaitAbandonedError as Kn, isCrossRegionRedirect as Ko, hasReadableOrphans as Kr, StageLoadError as Ks, redactedDeleteAddressSkip as Kt, S3_AUTO_DELETE_OBJECTS_TAG as L, hasMaskableValues as La, refuseMalformedResourcesForDeploy as Li, getCurrentResourceSecrets as Ln, buildAssetRedirectMap as Lo, parameterInputsFor as Lr, findLargeInlineResources as Ls, ccRoutedFinalSnapshotError as Lt, DELETE_INDEX_WAIT_PROCEED_NOTE as M, liveMatchesUnresolvedTokenFrame as Ma, refuseMalformedResourceEntriesForOrphan as Mi, CC_BROKEN_REASON as Mn, shouldRetainResource as Mo, cfnRefValueFromPhysicalId as Mr, warnDeprecatedNoPrefixCliFlag as Ms, getCurrentProducerRegions as Mt, INDEX_SETTLE_POLL_INTERVAL_MS as N, inheritNestedStackParameterAssociations as Na, refuseMalformedResourcePropertiesForDestroy as Ni, ProviderRegistry as Nn, AssetPublisher as No, isStalePlaceholderArnAttribute as Nr, ssmResolvedValueType as Ns, inheritProducerRegions as Nt, compensateRemovedDeletionProtection as O, lambdaFunctionNameForMask as Oa, refuseMalformedResourceEntriesForDeploy as Oi, tagMapAsList as On, importableOutputs as Oo, carriesFetchableDynamicReference as Or, resolveStateBucketWithDefault as Os, planFailedOps as Ot, deleteTableWithIndexBusyRetry as P, recordNestedStackParameterExpressions as Pa, refuseMalformedResourcePropertiesForDrift as Pi, ccBrokenReason as Pn, isSensitiveAttributeName as Po, refStateLookupFromResource as Pr, CFN_TEMPLATE_BODY_LIMIT as Ps, ATOMIC_FINAL_SNAPSHOT_TYPES as Pt, reachableDivergentParameters as Q, DYNAMIC_REFERENCE_TOKEN_SCAN as Qa, unwrittenCreateOnlyReplacement as Qi, reDisableInstanceApiTermination as Qn, buildDockerImage as Qo, malformedExportNamesWarning as Qr, ownValue as Qs, WITHHELD_NAME_DISPLAY as Qt, hasCdkAutoDeleteTag as R, literalSplitDelimitersOf as Ra, refuseMalformedResourcesForDestroy as Ri, CloudControlProvider as Rn, createAssetRedirectResolver as Ro, passedParameterClassesOf as Rr, uploadCfnTemplate as Rs, createPreDeleteFinalSnapshot as Rt, isProtectionValueActive as S, requireConfigString as Sa, refuseMalformedOrphansForDestroy as Si, acquireIdempotencyToken as Sn, describeRegionValueKind as So, coerceParameterTypedValue as Sr, getLegacyStateBucketName as Ss, destroyStackRecordsView as St, DynamoDBGlobalTableProvider as T, describeTypeWithThrottleRetry as Ta, refuseMalformedOutputsForDestroy as Ti, planTagDiff as Tn, hasReasonlessBaselineRefusal as To, getAccountInfo as Tr, resolveAutoAssetStorage as Ts, recordAfterRollbackUpdate as Tt, createReadOnlyAttributeHealerFactory as U, shareLogOnlyValues as Ua, repairMalformedOutputsForReadOnly as Ui, deleteIndeterminateGuards as Un, assertAssetBucketRegion as Uo, UNREADABLE_RESOURCES_MAP_ROW as Ur, canonicalizeRegion as Us, REDACTED_DELETE_ADDRESS_SKIP_REASON as Ut, markRefusedBeforeApplying as V, recordLogOnlyParameterValue as Va, repairMalformedOrphanRecordsForReadOnly as Vi, unchangedBehindSecretReference as Vn, AssetModeResolver as Vo, STATE_RESOURCES_MALFORMED as Vr, expectedOwnerParam as Vs, refusesFinalSnapshot as Vt, bold as W, createSecretMasker as Wa, repairMalformedResourceEntriesForReadOnly as Wi, deleteSkipReason as Wn, ensureAssetStorage as Wo, deployRefusesOrphanRowsReason as Wr, derivePartitionAndUrlSuffix as Ws, isRedactedRecordedValue as Wt, computeParameterTaint as X, scrubResourceRecord as Xa, findActionableSilentDrops as Xi, isTerminationProtectionPropagationError as Xn, validateContainerRepoName as Xo, isReadableResourceEntry as Xr, hasPlainPrototype$1 as Xs, DeploymentEventsStore as Xt, yellow as Y, redactSecretsForState as Ya, unreadableResourceEntries as Yi, ec2InstanceProtectionSite as Yn, validateAssetBucketName as Yo, isReadableOrphanRecord as Yr, hasOwnKey as Ys, DeploymentEventsReader as Yt, namesAnyDeclaredParameter as Z, recoverMaskedOutput as Za, findSilentDropProperties as Zi, observeThenDisableInstanceApiTermination as Zn, buildDenyExternalAccessPolicy as Zo, malformedDriftResourcePropertiesWarning as Zr, nullPrototypeRecord as Zs, extractDeploymentEventError as Zt, makeCanonicalizePropertiesFn as _, configStringRefusal as _a, refuseDivergentRecordRegionForDestroy as _i, RollbackInlinePolicyWriters as _n, isLockInfoExpired as _o, s3BucketArn as _r, AssetManifestLoader as _s, getCurrentNestedStackContext as _t, findNestedTemplateTreeDefect as a, isStatefulRecreateTargetForReplace as aa, resolveBucketRegion as ac, malformedOrphanRowsKeptWarning as ai, isWholeDynamicReferenceValue as an, recordMaskOnlyValue as ao, regionLessSecretName as ar, formatDockerLoginError as as, makeSiblingClaimReader as at, recordedProtectionNote as b, requireConfigArray as ba, refuseMalformedOrphanRecordsForDestroy as bi, reserveStackCreateToken as bn, splitImportedOps as bo, s3BucketRegionalDomainName as br, synthesisStatusMessage as bs, replayRollback as bt, renderNestedTemplateTreeDefect as c, WARM_THROUGHPUT_MEMBERS as ca, malformedOutputsRefusalMessage as ci, collectPublishedOutputNames as cn, recordProvenPublicExpression as co, assertSendableRoleArn as cr, isMalformedEnvKey as cs, displacedOpClause as ct, conditionInputsFrom as d, toCfnInteger as da, malformedResourceEntriesWarning as di, DEFAULT_RESOURCE_TIMEOUT_MS as dn, STATE_SOURCED_CROSS_GENERATION_RULES as do, sendableAssumeRoleCommand as dr, redactedDockerCause as ds, getNestedRevertRun as dt, NO_CC_HANDLERS_REASON as ea, describeFileReadFailure as ec, malformedLocalOutputsWarning as ei, exportAliasCollisionScrubWarning as en, isUncertifiedBaselineMaskPosition as eo, DiffCalculator as er, describeDockerCapturedOutput as es, deleteJournaledOrphans as et, parentSuppliedValues as f, toFiniteNumber as fa, malformedResourcePropertiesWarning as fi, DEFAULT_RESOURCE_WARN_AFTER_MS as fn, STATE_SOURCED_READBACK_RULES as fo, AWS_CREDENTIAL_ENV_KEYS as fr, runDockerForeground as fs, nestedChildStackName as ft, mergeNoChangeOutputs as g, configIntegerRefusal as ga, previewableOrphanRecords as gi, formatDestructiveChange as gn, LockManager as go, isSettledInstanceState as gr, stripControlChars as gs, withNestedRevertRun as gt, keptWholeReasonText as h, configBooleanRefusal as ha, malformedStateRefusalMessage as hi, findDestructiveChanges as hn, isSingleDynamicReferenceToken as ho, envCredentialsAreAssumedRole as hr, escapeRegExp$3 as hs, revertedNestedRowIds as ht, childTemplateLoader as i, MULTI_REGION_RECREATE_BLOCKED_TYPES as ia, clearBucketRegionCache as ic, malformedOrphanRecordsWarning as ii, exportNameSecretExposure as in, provenPublicValue as io, producerRegionsFromState as ir, finchSecretArgvRefusal as is, sameJournaledOrphans as it, resolveDynamoDbDeleteBudgetMs as j, TemplateParser as ja, refuseMalformedResourceEntriesForImportSave as ji, stringifyIfAssigned as jn, orphansCarriedFrom as jo, AWS_NO_VALUE as jr, stateBucketExistenceConfirmed as js, findNestedStackTypeChanges as jt, deleteBudgetKey as k, sameLambdaFunctionAddress as ka, refuseMalformedResourceEntriesForDestroy as ki, tagPlanWarning as kn, isReadableBag as ko, isNamelessDynamicReferenceError as kr, resolveStateBucketWithDefaultAndSource as ks, planRollback as kt, templateIdentity as l, coerceWarmThroughput as la, malformedOutputsWarning as li, isExportAliasCollision as ln, wholeStringLeavesOf as lo, explicitRoleArnOrThrow as lr, partitionSensitiveEnv as ls, displacedPhysicalIdShown as lt, isSecretBearingReferenceString as m, coerceCfnInteger as ma, malformedScrubResourceEntriesRefusalMessage as mi, constructPathOf as mn, WHOLE_DYNAMIC_REFERENCE_PATTERN as mo, callerEnvCredentials as mr, warnFinchArgvExposure as ms, revertNestedChildFromJournal as mt, IMPLICIT_DELETE_DEPENDENCIES as n, findReplacedReadersOfRecreateTargets as na, renderAssemblyPathEscape as nc, malformedLocalResourcesWarning as ni, secretBearingStateKeyWarning as nn, identityKeyFor as no, IntrinsicFunctionResolver as nr, describeDockerFailure as ns, journaledOrphanLines as nt, isAbsoluteAssetPath as o, isStatefulRecreateTargetSync as oa, malformedOrphansRefusalMessage as oi, noEchoParameterValueSeed as on, recordMaskOnlyValuesIn as oo, applyRoleArnIfSet as or, getDockerCmd as os, planOrphanAdoption as ot, readRecordedConditionVerdicts as p, coerceCfnBoolean as pa, malformedResourcesWarning as pi, maskingRetryLogger as pn, TEMPLATE_SOURCED_RULES as po, applyCallerIdentityCredentials as pr, runDockerStreaming as ps, recordDisplacedSkips as pt, green as q, maskSecretsInText as qa, unpreviewableOrphanRecords as qi, markWaitAbandoned as qn, parseBootstrapMarker as qo, hasReadableOutputs as qr, processStackMessages as qs, updatePartialMessage as qt, computeImplicitDeleteEdges as r, shownType as ra, resolveAssemblyPath as rc, malformedOrphanRecordsRefusalMessage as ri, secretSafeKeyDisplay as rn, carriesSecretMask as ro, classifyReplaySecretRegion as rr, dockerSpawnEnvWithSensitive as rs, loadJournaledOrphans as rt, listNestedTemplateRows as s, renderStatefulReason as sa, malformedOrphansWarning as si, collectDeclaredOutputNames as sn, recordNoEchoAttributeValues as so, assertFlagRoleArn as sr, isDockerClientEnvKey as ss, NESTED_PENDING_PARENT_REASON as st, DeployEngine as t, hasNoCloudControlHandlers as ta, displayAssemblyPath as tc, malformedLocalResourceEntriesWarning as ti, secretBearing as tn, pathCrossesDottedKey as to, INTRINSIC_KEYS as tr, describeDockerExecFailure as ts, isHandledOrphan as tt, conditionFingerprint as u, isWarmThroughputDecrease as ua, malformedRenderedContainersWarning as ui, bindingSkippedOutputs as un, STATE_SOURCED_BASELINE_RULES as uo, isIamRoleArn as ur, redactDockerArgvValues as us, dropSettledNestedJournals as ut, withResourceDeadline as v, readConfigString as va, refuseMalformedNestedChildOutputs as vi, earliestDefined as vn, S3StateBackend as vo, s3BucketDomainName as vr, getDockerImageBySourceHash as vs, withNestedStackContext as vt, readProtection as w, templateResourceTypes as wa, refuseMalformedOutputs as wi, DBPROXY_TAG_OPTIONS as wn, hasReadableExportSet as wo, parameterTypeMayLoseSecretIdentity as wr, resolveApp as ws, withStackRecords as wt, PROTECTION_PROPERTY_BY_TYPE as x, requireConfigObject as xa, refuseMalformedOrphans as xi, withCreateTokenLedger as xn, acceptedCreateOnlyDropsOf as xo, s3BucketWebsiteUrl as xr, getDefaultStateBucketName as xs, awaitInFlightSibling as xt, recordedProtectionEvidence as y, replayWarn as ya, refuseMalformedOrphanRecords as yi, ledgerForStack as yn, rebuildClientForBucketRegion as yo, s3BucketDualStackDomainName as yr, Synthesizer as ys, replayFailedOperations as yt, isTruthyCfnBoolean as z, logOnlyValueCount as za, refuseMalformedResourcesForExport as zi, slowCcOperationTimeoutMs as zn, loadPublishableAssetManifest as zo, JSON_LISTING_HOLE_VALUE as zr, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as zs, effectiveDeletionPolicy as zt };
|
|
37610
|
+
//# sourceMappingURL=deploy-engine-xlct0Hcm.js.map
|