@go-to-k/cdkd 0.296.27 → 0.296.29
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-BiMLPagi.js → asg-provider-UKRukGI_.js} +3 -3
- package/dist/{asg-provider-BiMLPagi.js.map → asg-provider-UKRukGI_.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-DC4Yblxp.js → deploy-engine-Bt-8KvUj.js} +3621 -1642
- package/dist/deploy-engine-Bt-8KvUj.js.map +1 -0
- package/dist/{iam-policy-targets-B61e5_Sk.js → iam-policy-targets-Cz2tPxXk.js} +2 -2
- package/dist/{iam-policy-targets-B61e5_Sk.js.map → iam-policy-targets-Cz2tPxXk.js.map} +1 -1
- package/dist/{iam-role-provider-BA2eujXF.js → iam-role-provider-BBFYFBLx.js} +3 -3
- package/dist/{iam-role-provider-BA2eujXF.js.map → iam-role-provider-BBFYFBLx.js.map} +1 -1
- package/dist/index.d.ts +123 -55
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{neptune-provider-DME95IcZ.js → neptune-provider-B9InVgs6.js} +3 -3
- package/dist/{neptune-provider-DME95IcZ.js.map → neptune-provider-B9InVgs6.js.map} +1 -1
- package/dist/{program-BwNb3_Ot.js → program-CN7Dqb3j.js} +548 -44
- package/dist/program-CN7Dqb3j.js.map +1 -0
- package/dist/{provider-classes-BcSDENeH.js → provider-classes-eEgFT-Vt.js} +196 -22
- package/dist/provider-classes-eEgFT-Vt.js.map +1 -0
- package/dist/{rds-provider-iouJXdXX.js → rds-provider-DgbVxaPP.js} +3 -3
- package/dist/{rds-provider-iouJXdXX.js.map → rds-provider-DgbVxaPP.js.map} +1 -1
- package/dist/{version-Cs9QbaaH.js → version-DyV_xwRX.js} +2 -2
- package/dist/{version-Cs9QbaaH.js.map → version-DyV_xwRX.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-DC4Yblxp.js.map +0 -1
- package/dist/program-BwNb3_Ot.js.map +0 -1
- package/dist/provider-classes-BcSDENeH.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { a as runWithStackAwsClients, i as resetAwsClients, o as setAwsClients, t as AwsClients } from "./aws-clients-CnmtbrxD.js";
|
|
2
2
|
import { A as UNRENDERABLE, B as stringifyJsonPayload, D as SAFE_MSG_ALTERED_CHAR, F as displayStackName, I as isPasteableIdent, M as displayAwsMessage, N as displayIdent, O as SECRET_REF_MAX_CODE_POINTS, P as displaySafe, R as plainIdentOr, T as withStackName, V as truncateCodePoints, _ as derivesPatternBName, a as getLogger, f as getLiveRenderer, h as PATTERN_B_RESOURCE_TYPES, j as cutMarker, k as STACK_REF_MAX_CODE_POINTS, l as runStackBuffered, m as PATTERN_B_NAME_PROPERTIES, o as isStdoutReservedForPayload, p as PATTERN_B_NAME_OPTIONS, r as safeStringify, s as reserveStdoutForPayload, t as describeAwsFailure, v as explicitNamePropertyFor, w as withSkipPrefix, y as generateResourceName, z as safeMsg } from "./aws-failure-text-BaWeCWRz.js";
|
|
3
|
-
import { $
|
|
3
|
+
import { $n as isAmbiguousOutcomeError, $t as credentialFingerprint, Bn as withheldTargetClause, D as VALUE_NOT_SHOWN, Dn as TIMEOUT_FLAG_RESOURCE_TYPE, E as assertRegionMatch, En as withErrorHandling, Ft as buildLockContentionMessage, G as runDeleteAttempt, Hn as setPasteableVerbFlags, Ht as CUSTOM_RESOURCE_RESPONSE_PREFIX, In as plainOrDescribed, It as forceQuitRecoveryClause, Jt as setPasteableAwsProfile, Kt as producerCoordinateKey, Ln as quotedOrDescribed, Lt as formatLockExpiry, Nn as isInertUnquoted, Nt as UNREPRODUCIBLE_LOCK_CLAUSE, P as remedyLogicalId, Pn as pasteableCommand, Pt as buildForceUnlockCommand, Qt as clientDefaultsFor, Rn as shellBoundedDisplay, Rt as formatLockOperation, Sn as SynthesisError, T as RESOURCE_NOT_FOUND, Tn as normalizeAwsError, Ut as DEFAULT_STATE_PREFIX, Vn as setPasteableRunFlags, Wt as injectiveKey, Xt as ambientClientDefaults, Yt as withPasteableAwsProfile, Z as isAwsCliLiteral, Zt as ambientCredentialConfig, _n as ResourceTimeoutError, ar as isMarkedNonRetryable, bn as StackTerminationProtectionError, cn as IntrinsicResolutionRefusalError, en as AccountIdUnavailableError, ft as logicalIdShown, gn as ProvisioningError, hn as PartialFailureError, in as CrossAccountSecretRefusalError, it as isInterruptedWaitError, jn as commandHole, kn as SHELL_ACTIVE_WHY, ln as LocalInvokeBuildError$1, mn as NestedStackChildDirectDestroyError, mt as resourceTypeShown, n as RESOLVED_PREVIOUS_PRINCIPAL_KEYS, nn as CdkdError, nr as isTransientServerError, nt as endCommandInterruptScope, on as DeployCancelledError, or as isThrottlingError, pn as MalformedProducerRecordRefusalError, qt as producerRecordKey, rr as retryClassificationText, rt as interruptWatchListenerCount, s as readRecordedPrincipals, sn as DynamicReferenceRegionAmbiguousError, sr as markNonRetryable, t as IAM_PRINCIPAL_NAME, tr as isRetryableTransientError, tt as beginCommandInterruptScope, un as LocalStartServiceError, vn as ResourceUpdateNotSupportedError, yn as StackHasActiveImportsError, zn as shellQuote, zt as formatLockOwner } from "./iam-policy-targets-Cz2tPxXk.js";
|
|
4
4
|
import { n as awsClientDefaults, r as getAssumedRoleCredentials, u as formatAuthority } from "./aws-client-defaults-D0q0z4dG.js";
|
|
5
|
-
import { $ as gray, $a as templateResourceTypes, $i as refuseMalformedOutputsForDestroy, $o as STATE_SOURCED_BASELINE_RULES, $r as isImpossibleEmptyStoredAttribute, $s as redactDockerArgvValues, $t as updatePartialMessage, A as perType, Aa as hasNoCloudControlHandlers, Ac as expectedOwnerParam, Ai as malformedLocalResourcesWarning, An as collectDeclaredOutputNames, Ao as createSecretMasker, Ar as classifyReplaySecretRegion, As as AssetModeResolver, Bc as nullPrototypeRecord, Bi as malformedResourcePropertiesWarning, Bn as RollbackInlinePolicyWriters, Bo as pathCrossesDottedKey, Br as applyCallerIdentityCredentials, Bs as buildDenyExternalAccessPolicy, Bt as planRollback, C as noEchoComparisonForTemplate, Ca as unreadableResourceEntries, Cc as CFN_TEMPLATE_BODY_LIMIT, Ci as isReadableOrphanRecord, Cn as secretBearingStateKeyWarning, Co as hasMaskableValues, Cs as isSensitiveAttributeName, Ct as isHandledOrphan, D as recordedProtectionNote, Da as unwrittenCreateOnlyReplacement, Dc as uploadCfnTemplate, Di as malformedExportSourceWarning, Dn as exportNameSecretExposure, Do as recordLogOnlyParameterValue, Dr as INTRINSIC_KEYS, Ds as createAssetRedirectResolver, Dt as sameJournaledOrphans, E as recordedProtectionEvidence, Ec as findLargeInlineResources, Ei as malformedExportNamesWarning, En as exportNameNoEchoParameters, Eo as printingCorpusOf, Er as DiffCalculator, Es as buildAssetRedirectMap, Et as makeForeignHolderScan, Fa as isStatefulRecreateTargetSync, Fc as StageLoadError, Fi as malformedOrphansWarning, Fn as DEFAULT_RESOURCE_WARN_AFTER_MS, Fo as redactSecretsForState, Fr as assertSendableRoleArn, Fs as isCrossRegionRedirect, Ft as recordAfterRollbackUpdate, Gc as renderAssemblyPathEscape, Gi as refuseDivergentRecordRegionForDestroy, Go as carriesSecretMask, Gs as describeDockerFailure, Gt as orphanDeleteNeedsIdentity, Hc as absoluteAssemblyPathEscape, Hi as malformedScrubResourceEntriesRefusalMessage, Hn as ledgerForStack, Ho as inheritNestedStackParameterAssociations, Hr as envCredentialsAreAssumedRole, Hs as resolveDockerContextDirectory, Ht as recordUnderIdIsNotOwn, Ia as renderStatefulReason, Ic as processStackMessages, Ii as malformedOutputsRefusalMessage, In as maskingRetryLogger, Io as scrubResourceRecord, Ir as explicitRoleArnOrThrow, Is as parseBootstrapMarker, It as demoteSupersededOrphans, Jc as resolveBucketRegion, Ji as refuseMalformedOrphanRecordsForDestroy, Jo as recordMaskOnlyValuesIn, Js as formatDockerLoginError, Jt as inheritProducerRegions, Kc as resolveAssemblyPath, Ko as provenPublicValue, Ks as dockerSpawnEnvWithSensitive, Kt as findNestedStackTypeChanges, Lc as defineOwnKey, Li as malformedOutputsWarning, Ln as constructPathOf, Lo as DYNAMIC_REFERENCE_TOKEN_SCAN, Lr as isIamRoleArn, Ls as readBootstrapMarkerBody, Lt as isJournaledOrphan, Ma as shownType, Mc as canonicalizeRegion, Mi as malformedOrphanRecordsWarning, Mn as isExportAliasCollision, Mo as maskSecretsInError, Mr as regionLessSecretName, Ms as assertAssetBucketRegion, Na as MULTI_REGION_RECREATE_BLOCKED_TYPES, Nc as derivePartitionAndUrlSuffix, Ni as malformedOrphanRowsKeptWarning, Nn as bindingSkippedOutputs, No as maskSecretsInText, Nr as applyRoleArnIfSet, Ns as ensureAssetStorage, Nt as withStackRecords, O as PROTECTION_PROPERTY_BY_TYPE, Oc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Oi as malformedLocalOutputsWarning, On as isWholeDynamicReferenceValue, Oo as recordLogOnlyValue, Or as IntrinsicFunctionResolver, Os as loadPublishableAssetManifest, Ot as replayFailedOperations, Pa as isStatefulRecreateTargetForReplace, Pc as AssemblyReader, Pi as malformedOrphansRefusalMessage, Pn as DEFAULT_RESOURCE_TIMEOUT_MS, Po as markSameGenerationBag, Pr as assertFlagRoleArn, Ps as getBootstrapMarkerKey, Pt as removeProtectionTypeList, Q as cyan, Qa as prefetchCreateOnlyPropertyPaths, Qi as refuseMalformedOutputs, Qo as wholeStringLeavesOf, Qr as getAccountInfo, Qs as partitionSensitiveEnv, Rc as hasOwnKey, Ri as malformedRenderedContainersWarning, Rn as findDestructiveChanges, Ro as dynamicReferenceTokens, Rr as sendableAssumeRoleCommand, Rs as validateAssetBucketName, Rt as isReplacementOrphan, S as noEchoAttributeNamesOf, Sa as unreadableOrphanRecords, Sc as ssmResolvedValueType, Si as hasReadableResources, Sn as secretBearing, So as createUnionSecretMasker, Ss as AssetPublisher, St as dropFailedHint, T as noEchoParameterNamesOf, Ta as findActionableSilentDrops, Tc as MIGRATE_TMP_PREFIX, Ti as malformedDriftResourcePropertiesWarning, Tn as carriedExportAliasExposure, To as logOnlyValueCount, Ts as WorkGraph, Tt as loadJournaledOrphans, Uc as describeFileReadFailure, Ui as malformedStateRefusalMessage, Uo as recordNestedStackParameterExpressions, Us as describeDockerCapturedOutput, Ut as replacementNeverSwapped, Vc as ownValue, Vi as malformedResourcesWarning, Vo as identityKeyFor, Vr as callerEnvCredentials, Vs as buildDockerImage, Vt as recheckFailedPlan, Wc as displayAssemblyPath, Wi as previewableOrphanRecords, Wn as withCreateTokenLedger, Ws as describeDockerExecFailure, Wt as resolveReplacementOldType, X as createReadOnlyAttributeHealerFactory, Xi as refuseMalformedOrphansForDestroy, Xo as recordNoEchoParameterFreshValue, Xr as isUnboundTemplateParameter, Xs as isDockerClientEnvKey, Y as formatResourceLine, Yi as refuseMalformedOrphans, Yo as recordNoEchoAttributeValues, Yr as coerceParameterTypedValue, Ys as getDockerCmd, Z as bold, Zi as refuseMalformedOrphansForOrphan, Zo as recordProvenPublicExpression, Zr as parameterTypeMayLoseSecretIdentity, Zs as isMalformedEnvKey, _ as makeCanonicalizePropertiesFn, _a as repairMalformedOutputsForReadOnly, _c as resolveStateBucketWithDefault, _i as accountArgs, _n as DeploymentEventsStore, _o as readbackPathFor, _s as importableOutputs, _t as revertedNestedRowIds, a as findNestedTemplateTreeDefect, aa as refuseMalformedResourceEntriesForImportSave, ac as stripControlChars, ai as cfnRefValueFromPhysicalId, an as secretNamePrintingBag, ao as DagBuilder, ar as wouldReturnToSdkProvider, as as LockManager, at as reachableDivergentParameters, b as serviceTokenBlockingReason, ba as repairMalformedResourcesForReadOnly, bc as stateBucketExistenceConfirmed, bi as hasReadableOrphans, bn as displayTextOrWithheld, bo as liveMatchesUnresolvedTokenFrame, bs as orphansCarriedFrom, bt as withNestedStackContext, c as renderNestedTemplateTreeDefect, ca as refuseMalformedResourcePropertiesForDrift, cc as Synthesizer, cn as PRE_DELETE_SNAPSHOT_TYPES, co as isMarkedCoordinate, cr as isCustomResourceType$1, cs as rebuildClientForBucketRegion, ct as planOrphanAdoption, d as conditionInputsFrom, da as refuseMalformedResourcesForDeploy, dc as getLegacyStateBucketName, dn as createPreDeleteFinalSnapshot, do as maskWholeValue, dr as CloudControlProvider, ds as describeRegionValueKind, dt as displacedPhysicalIdShown, ea as refuseMalformedResourceAttributesForOrphan, ec as redactedDockerCause, ei as carriesDynamicReference, en as updatePartialReason, eo as describeTypeWithThrottleRetry, es as STATE_SOURCED_CROSS_GENERATION_RULES, et as green, f as parentSuppliedValues, fa as refuseMalformedResourcesForDestroy, fc as loadCdkJson, fi as JSON_LISTING_HOLE_VALUE, fn as effectiveDeletionPolicy, fo as maskedLeafCoordinatesOf, fr as slowCcOperationTimeoutMs, fs as exportNamesCarriedFrom, ft as dropSettledNestedJournals, g as mergeNoChangeOutputs, ga as repairMalformedOrphansForReadOnly, gc as resolveSkipPrefix, gi as UNREADABLE_RESOURCES_MAP_ROW, gn as DeploymentEventsReader, gr as deleteSkipReason, gs as importableOutputKeys, h as keptWholeReasonText, ha as repairMalformedOrphanRecordsForReadOnly, hc as resolveCaptureObservedState, hi as UNREADABLE_ORPHANS_CONTAINER_ROW, hn as unsupportedFinalSnapshotError, ho as noEchoOutputsComparison, hr as deleteIndeterminateGuards, hs as hasUnverifiableParameterRefusal, ht as recordDisplacedSkips, i as childTemplateLoader, ia as refuseMalformedResourceEntriesForImport, ic as escapeRegExp, ii as AWS_NO_VALUE, in as orphanRecordsPrintingBag, ir as isCustomResource, is as isSingleDynamicReferenceToken, it as namesAnyDeclaredParameter, j as readProtection, ja as findReplacedReadersOfRecreateTargets, jc as PARTITION_TABLE, ji as malformedOrphanRecordsRefusalMessage, jn as collectPublishedOutputNames, jo as errorCauseChain, jr as producerRegionsFromState, js as BOOTSTRAP_MARKER_PREFIX, jt as destroyStackRecordsView, k as isProtectionValueActive, ka as NO_CC_HANDLERS_REASON, kc as decodeListingKey, ki as malformedLocalResourceEntriesWarning, kn as noEchoParameterValueSeed, ko as shareLogOnlyValues, kr as poisonRenderedSpellingsCollidingIn, ks as rewriteTemplateAssetReferences, kt as replayRollback, l as templateIdentity, la as refuseMalformedResourcePropertiesForExport, lc as synthesisStatusMessage, li as withSharedDrainBudget, ln as buildFinalSnapshotIdentifier, lo as maskAtCoordinates, ls as splitImportedOps, lt as NESTED_PENDING_PARENT_REASON, m as isSecretBearingReferenceString, ma as refuseMalformedState, mc as resolveAutoAssetStorage, mi as STATE_RESOURCES_MALFORMED, mn as refusesFinalSnapshot, mo as noEchoLeavesOf, mr as UNSPECIFIED_SKIP_REASON, ms as hasReasonlessBaselineRefusal, mt as nestedChildStackName$1, n as IMPLICIT_DELETE_DEPENDENCIES, na as refuseMalformedResourceEntriesForDeploy, nc as runDockerStreaming, ni as isNamelessDynamicReferenceError, nn as journaledOrphanPrintingBag, nr as ProviderRegistry, ns as TEMPLATE_SOURCED_RULES, nt as yellow, o as isAbsoluteAssetPath, oa as refuseMalformedResourceEntriesForOrphan, oc as AssetManifestLoader, oi as isStalePlaceholderArnAttribute, on as stateSecretNameNeedles, oo as TemplateParser, or as TemplateNoEchoReresolver, os as isLockInfoExpired, ot as resourcesNamingDeclaredParameter, p as readRecordedConditionVerdicts, pa as refuseMalformedResourcesForExport, pc as resolveApp, pi as STATE_REGION_DIVERGED, pn as isFinalSnapshotError, po as noEchoCoordinatesOf, ps as hasReadableExportSet, qi as refuseMalformedOrphanRecords, qo as recordMaskOnlyValue, qs as finchSecretArgvRefusal, r as computeImplicitDeleteEdges, ra as refuseMalformedResourceEntriesForDestroy, rc as warnFinchArgvExposure, ri as keepsSecretReferenceToken, rn as maskEventTextWithBoundBags, rr as ccBrokenReason, rs as WHOLE_DYNAMIC_REFERENCE_PATTERN, rt as computeParameterTaint, s as listNestedTemplateRows, sa as refuseMalformedResourcePropertiesForDestroy, sc as getDockerImageBySourceHash, si as refStateLookupFromResource, sn as ATOMIC_FINAL_SNAPSHOT_TYPES, so as canonicalCoordinates, sr as readsNoEchoDeleteValues, ss as S3StateBackend, st as makeSiblingClaimReader, t as DeployEngine, ta as refuseMalformedResourceEntries, tc as runDockerForeground, ti as carriesFetchableDynamicReference, tn as completedReplayEntries, to as withRetry, tr as CC_BROKEN_REASON, ts as STATE_SOURCED_READBACK_RULES, tt as red, u as conditionFingerprint, ua as refuseMalformedResourcePropertiesForOrphan, uc as getDefaultStateBucketName, ui as parameterInputsFor, un as ccRoutedFinalSnapshotError, uo as maskReadbackAtCoordinates, ur as withPrintingSecrets, us as acceptedCreateOnlyDropsOf, ut as displacedOpClause, v as deferredServiceTokenWarning, va as repairMalformedResourceEntriesForReadOnly, vc as resolveStateBucketWithDefaultAndSource, vi as deployRefusesOrphanRowsReason, vn as extractDeploymentEventError, vo as readsNoEchoSource, vr as isWaitAbandonedError, vs as isReadableBag, vt as withNestedRevertRun, w as noEchoExactEchoLeavesOf, wa as withheldAccountClause, wc as CFN_TEMPLATE_URL_LIMIT, wi as isReadableResourceEntry, wn as secretSafeKeyDisplay, wo as literalSplitDelimitersOf, ws as stringifyValue, wt as journaledOrphanLines, x as withResourceDeadline, xa as unpreviewableOrphanRecords, xc as warnDeprecatedNoPrefixCliFlag, xi as hasReadableOutputs, xn as exportAliasCollisionScrubWarning, xo as carryLogOnlyValues, xs as shouldRetainResource, xt as deleteJournaledOrphans, y as findServiceTokenRefusals, ya as repairMalformedResourcePropertiesForReadOnly, yc as resolveUseCdkBootstrapAssets, yi as displayLogicalId, yn as WITHHELD_NAME_DISPLAY, yo as valueAtCoordinate, ys as orphansAfterRollback, zc as hasPlainPrototype, zi as malformedResourceEntriesWarning, zn as formatDestructiveChange, zo as isUncertifiedBaselineMaskPosition, zr as AWS_CREDENTIAL_ENV_KEYS, zs as validateContainerRepoName, zt as planFailedOps } from "./deploy-engine-DC4Yblxp.js";
|
|
6
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
+
import { $c as nullPrototypeRecord, $o as provenPublicValue, $s as buildDenyExternalAccessPolicy, $t as findNestedStackTypeChanges, A as noEchoExactEchoLeavesOf, Aa as unreadableResourceEntries, Ac as resolveStateBucketWithDefault, Ai as isReadableOrphanRecord, An as orphanRecordsPrintingBag, Ao as hasMaskableValues, As as importableOutputs, At as journaledOrphanLines, Ba as MULTI_REGION_RECREATE_BLOCKED_TYPES, Bc as uploadCfnTemplate, Bi as malformedOrphanRowsKeptWarning, Bn as isFinalSnapshotError, Bo as maskSecretsInText, Br as applyRoleArnIfSet, Bs as createAssetRedirectResolver, Bt as removeProtectionTypeList, C as recordRetainedForReadoption, Ca as repairMalformedOrphansForReadOnly, Cc as getDefaultStateBucketName, Ci as UNREADABLE_RESOURCES_MAP_ROW, Cn as isExportAliasCollision, Cr as deleteSkipReason, Cs as acceptedCreateOnlyDropsOf, Ct as revertedNestedRowIds, D as withResourceDeadline, Da as repairMalformedResourcesForReadOnly, Dc as resolveAutoAssetStorage, Di as hasReadableOrphans, Dn as completedReplayEntries, Do as liveMatchesUnresolvedTokenFrame, Ds as hasReasonlessBaselineRefusal, Dt as deleteJournaledOrphans, E as serviceTokenBlockingReason, Ea as repairMalformedResourcePropertiesForReadOnly, Ec as resolveApp, Ei as displayLogicalId, En as DEFAULT_RESOURCE_WARN_AFTER_MS, Eo as valueAtCoordinate, Es as hasReadableExportSet, Et as withNestedStackContext, F as isProtectionValueActive, Fc as ssmResolvedValueType, Fi as malformedLocalOutputsWarning, Fn as PRE_DELETE_SNAPSHOT_TYPES, Fo as recordLogOnlyValue, Fr as IntrinsicFunctionResolver, Fs as AssetPublisher, Ft as replayRollback, Gc as canonicalizeRegion, Gi as malformedRenderedContainersWarning, Gn as findDestructiveChanges, Go as dynamicReferenceTokens, Gr as sendableAssumeRoleCommand, Gs as assertAssetBucketRegion, Gt as planFailedOps, Ha as isStatefulRecreateTargetSync, Hc as decodeListingKey, Hi as malformedOrphansWarning, Hn as unsupportedFinalSnapshotError, Ho as redactSecretsForState, Hr as assertSendableRoleArn, Hs as rewriteTemplateAssetReferences, Ht as demoteSupersededOrphans, I as perType, Ia as NO_CC_HANDLERS_REASON, Ic as CFN_TEMPLATE_BODY_LIMIT, Ii as malformedLocalResourceEntriesWarning, In as buildFinalSnapshotIdentifier, Io as shareLogOnlyValues, Ir as poisonRenderedSpellingsCollidingIn, Is as isSensitiveAttributeName, Jc as StageLoadError, Ji as malformedResourcesWarning, Jo as identityKeyFor, Jr as callerEnvCredentials, Js as isCrossRegionRedirect, Jt as recordUnderIdIsNotOwn, Kc as derivePartitionAndUrlSuffix, Ki as malformedResourceEntriesWarning, Kn as formatDestructiveChange, Ko as isUncertifiedBaselineMaskPosition, Kr as AWS_CREDENTIAL_ENV_KEYS, Ks as ensureAssetStorage, Kt as planRollback, L as readProtection, La as hasNoCloudControlHandlers, Lc as CFN_TEMPLATE_URL_LIMIT, Li as malformedLocalResourcesWarning, Ln as ccRoutedFinalSnapshotError, Lo as createSecretMasker, Lr as classifyReplaySecretRegion, Ls as stringifyValue, Lt as destroyStackRecordsView, M as recordedProtectionEvidence, Ma as findActionableSilentDrops, Mc as resolveUseCdkBootstrapAssets, Mi as malformedDriftResourcePropertiesWarning, Mn as stateSecretNameNeedles, Mo as logOnlyValueCount, Ms as orphansAfterRollback, Mt as makeForeignHolderScan, N as recordedProtectionNote, Nc as stateBucketExistenceConfirmed, Ni as malformedExportNamesWarning, Nn as extractDeploymentEventError, No as printingCorpusOf, Nr as DiffCalculator, Ns as orphansCarriedFrom, Nt as sameJournaledOrphans, O as noEchoAttributeNamesOf, Oa as unpreviewableOrphanRecords, Oc as resolveCaptureObservedState, Oi as hasReadableOutputs, On as journaledOrphanPrintingBag, Oo as carryLogOnlyValues, Os as hasUnverifiableParameterRefusal, Ot as dropFailedHint, P as PROTECTION_PROPERTY_BY_TYPE, Pa as unwrittenCreateOnlyReplacement, Pc as warnDeprecatedNoPrefixCliFlag, Pi as malformedExportSourceWarning, Pn as ATOMIC_FINAL_SNAPSHOT_TYPES, Po as recordLogOnlyParameterValue, Pr as INTRINSIC_KEYS, Ps as shouldRetainResource, Pt as replayFailedOperations, Qc as hasPlainPrototype, Qi as refuseDivergentRecordRegionForDestroy, Qo as carriesSecretMask, Qs as validateContainerRepoName, Qt as orphanDeleteNeedsIdentity, Ra as findReplacedReadersOfRecreateTargets, Rc as MIGRATE_TMP_PREFIX, Ri as malformedOrphanRecordsRefusalMessage, Rn as createPreDeleteFinalSnapshot, Ro as errorCauseChain, Rr as producerRegionsFromState, Rs as WorkGraph, S as keptForReadoption, Sa as repairMalformedOrphanRecordsForReadOnly, Sc as synthesisStatusMessage, Si as UNREADABLE_ORPHANS_CONTAINER_ROW, Sn as collectPublishedOutputNames, So as noEchoOutputsComparison, Sr as deleteIndeterminateGuards, Ss as splitImportedOps, T as findServiceTokenRefusals, Ta as repairMalformedResourceEntriesForReadOnly, Tc as loadCdkJson, Ti as deployRefusesOrphanRowsReason, Tn as DEFAULT_RESOURCE_TIMEOUT_MS, To as readsNoEchoSource, Tr as isWaitAbandonedError, Ts as exportNamesCarriedFrom, Ua as renderStatefulReason, Uc as expectedOwnerParam, Ui as malformedOutputsRefusalMessage, Un as maskingRetryLogger, Uo as scrubResourceRecord, Ur as explicitRoleArnOrThrow, Us as AssetModeResolver, Ut as isJournaledOrphan, Va as isStatefulRecreateTargetForReplace, Vc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Vi as malformedOrphansRefusalMessage, Vn as refusesFinalSnapshot, Vo as markSameGenerationBag, Vr as assertFlagRoleArn, Vs as loadPublishableAssetManifest, Vt as recordAfterRollbackUpdate, Wc as PARTITION_TABLE, Wi as malformedOutputsWarning, Wn as constructPathOf, Wo as DYNAMIC_REFERENCE_TOKEN_SCAN, Wr as isIamRoleArn, Ws as BOOTSTRAP_MARKER_PREFIX, Wt as isReplacementOrphan, Xc as defineOwnKey, Xi as malformedStateRefusalMessage, Xo as recordNestedStackParameterExpressions, Xs as readBootstrapMarkerBody, Xt as resolveReplacementOldType, Yc as processStackMessages, Yi as malformedScrubResourceEntriesRefusalMessage, Yn as ledgerForStack, Yo as inheritNestedStackParameterAssociations, Yr as envCredentialsAreAssumedRole, Ys as parseBootstrapMarker, Yt as replacementNeverSwapped, Zc as hasOwnKey, Zi as previewableOrphanRecords, Zn as withCreateTokenLedger, Zs as validateAssetBucketName, Zt as seedsDeleteFirstGuard, _ as makeCanonicalizePropertiesFn, _a as refuseMalformedResourcePropertiesForOrphan, _c as escapeRegExp, _i as parameterInputsFor, _n as exportNameNoEchoParameters, _o as maskReadbackAtCoordinates, _r as withPrintingSecrets, _s as CrossPrefixScanCache, _t as displacedPhysicalIdShown, a as findNestedTemplateTreeDefect, aa as refuseMalformedOutputs, ac as dockerSpawnEnvWithSensitive, ai as getAccountInfo, al as resolveAssemblyPath, ao as prefetchCreateOnlyPropertyPaths, as as wholeStringLeavesOf, at as gray, ba as refuseMalformedResourcesForExport, bc as getDockerImageBySourceHash, bi as STATE_REGION_DIVERGED, bn as noEchoParameterValueSeed, bo as noEchoCoordinatesOf, bs as isAccessDenied, bt as nestedChildStackName$1, c as renderNestedTemplateTreeDefect, ca as refuseMalformedResourceEntries, cc as getDockerCmd, ci as carriesFetchableDynamicReference, cn as DeploymentEventsReader, co as withRetry, cr as CC_BROKEN_REASON, cs as STATE_SOURCED_READBACK_RULES, ct as yellow, d as conditionInputsFrom, da as refuseMalformedResourceEntriesForImport, dc as partitionSensitiveEnv, di as AWS_NO_VALUE, dn as displayTextOrWithheld, dr as isCustomResource, ds as isSingleDynamicReferenceToken, dt as reachableDivergentParameters, ea as refuseMalformedOrphanRecords, ec as buildDockerImage, el as ownValue, es as recordMaskOnlyValue, f as parentSuppliedValues, fa as refuseMalformedResourceEntriesForImportSave, fc as redactDockerArgvValues, fi as cfnRefValueFromPhysicalId, fn as exportAliasCollisionScrubWarning, fo as DagBuilder, fr as wouldReturnToSdkProvider, fs as LockManager, ft as resourcesNamingDeclaredParameter, g as mergeNoChangeOutputs, ga as refuseMalformedResourcePropertiesForExport, gc as warnFinchArgvExposure, gi as withSharedDrainBudget, gn as carriedExportAliasExposure, go as maskAtCoordinates, gs as CrossPrefixReadError, gt as displacedOpClause, h as keptWholeReasonText, ha as refuseMalformedResourcePropertiesForDrift, hc as runDockerStreaming, hn as secretSafeKeyDisplay, ho as isMarkedCoordinate, hr as isCustomResourceType$1, hs as rebuildClientForBucketRegion, ht as NESTED_PENDING_PARENT_REASON, i as childTemplateLoader, ia as refuseMalformedOrphansForOrphan, ic as describeDockerFailure, ii as parameterTypeMayLoseSecretIdentity, il as renderAssemblyPathEscape, is as recordProvenPublicExpression, it as cyan, j as noEchoParameterNamesOf, ja as withheldAccountClause, jc as resolveStateBucketWithDefaultAndSource, ji as isReadableResourceEntry, jn as secretNamePrintingBag, jo as literalSplitDelimitersOf, js as isReadableBag, jt as loadJournaledOrphans, k as noEchoComparisonForTemplate, ka as unreadableOrphanRecords, kc as resolveSkipPrefix, ki as hasReadableResources, kn as maskEventTextWithBoundBags, ko as createUnionSecretMasker, ks as importableOutputKeys, kt as isHandledOrphan, l as templateIdentity, la as refuseMalformedResourceEntriesForDeploy, lc as isDockerClientEnvKey, li as isNamelessDynamicReferenceError, ln as DeploymentEventsStore, lr as ProviderRegistry, ls as TEMPLATE_SOURCED_RULES, lt as computeParameterTaint, m as isSecretBearingReferenceString, ma as refuseMalformedResourcePropertiesForDestroy, mc as runDockerForeground, mi as refStateLookupFromResource, mn as secretBearingStateKeyWarning, mo as canonicalCoordinates, mr as readsNoEchoDeleteValues, ms as S3StateBackend, mt as planOrphanAdoption, n as IMPLICIT_DELETE_DEPENDENCIES, na as refuseMalformedOrphans, nc as describeDockerCapturedOutput, ni as coerceParameterTypedValue, nl as describeFileReadFailure, ns as recordNoEchoAttributeValues, nt as createReadOnlyAttributeHealerFactory, o as isAbsoluteAssetPath, oa as refuseMalformedOutputsForDestroy, oc as finchSecretArgvRefusal, oi as isImpossibleEmptyStoredAttribute, on as updatePartialMessage, oo as templateResourceTypes, os as STATE_SOURCED_BASELINE_RULES, ot as green, p as readRecordedConditionVerdicts, pa as refuseMalformedResourceEntriesForOrphan, pc as redactedDockerCause, pi as isStalePlaceholderArnAttribute, pn as secretBearing, po as TemplateParser, pr as TemplateNoEchoReresolver, ps as isLockInfoExpired, pt as makeSiblingClaimReader, qc as AssemblyReader, qi as malformedResourcePropertiesWarning, qn as RollbackInlinePolicyWriters, qo as pathCrossesDottedKey, qr as applyCallerIdentityCredentials, qs as getBootstrapMarkerKey, qt as recheckFailedPlan, r as computeImplicitDeleteEdges, ra as refuseMalformedOrphansForDestroy, rc as describeDockerExecFailure, ri as isUnboundTemplateParameter, rl as displayAssemblyPath, rs as recordNoEchoParameterFreshValue, rt as bold, s as listNestedTemplateRows, sa as refuseMalformedResourceAttributesForOrphan, sc as formatDockerLoginError, si as carriesDynamicReference, sl as resolveBucketRegion, sn as updatePartialReason, so as describeTypeWithThrottleRetry, ss as STATE_SOURCED_CROSS_GENERATION_RULES, st as red, t as DeployEngine, ta as refuseMalformedOrphanRecordsForDestroy, tc as resolveDockerContextDirectory, tl as absoluteAssemblyPathEscape, tn as inheritProducerRegions, ts as recordMaskOnlyValuesIn, tt as formatResourceLine, u as conditionFingerprint, ua as refuseMalformedResourceEntriesForDestroy, uc as isMalformedEnvKey, ui as keepsSecretReferenceToken, un as WITHHELD_NAME_DISPLAY, ur as ccBrokenReason, us as WHOLE_DYNAMIC_REFERENCE_PATTERN, ut as namesAnyDeclaredParameter, va as refuseMalformedResourcesForDeploy, vc as stripControlChars, vn as exportNameSecretExposure, vo as maskWholeValue, vr as CloudControlProvider, vs as applyCrossPrefixScan, vt as dropSettledNestedJournals, w as deferredServiceTokenWarning, wa as repairMalformedOutputsForReadOnly, wc as getLegacyStateBucketName, wi as accountArgs, wn as bindingSkippedOutputs, wo as readbackPathFor, ws as describeRegionValueKind, wt as withNestedRevertRun, xa as refuseMalformedState, xc as Synthesizer, xi as STATE_RESOURCES_MALFORMED, xn as collectDeclaredOutputNames, xo as noEchoLeavesOf, xr as UNSPECIFIED_SKIP_REASON, xs as isNotImplemented, xt as recordDisplacedSkips, ya as refuseMalformedResourcesForDestroy, yc as AssetManifestLoader, yi as JSON_LISTING_HOLE_VALUE, yn as isWholeDynamicReferenceValue, yo as maskedLeafCoordinatesOf, yr as slowCcOperationTimeoutMs, ys as crossPrefixDeniedWarning, za as shownType, zc as findLargeInlineResources, zi as malformedOrphanRecordsWarning, zn as effectiveDeletionPolicy, zo as maskSecretsInError, zr as regionLessSecretName, zs as buildAssetRedirectMap, zt as withStackRecords } from "./deploy-engine-Bt-8KvUj.js";
|
|
6
|
+
import { t as getCdkdVersion } from "./version-DyV_xwRX.js";
|
|
7
7
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
8
8
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, NotFound, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutBucketVersioningCommand, PutObjectCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
9
9
|
import { GetRoleCommand, GetUserCommand } from "@aws-sdk/client-iam";
|
|
@@ -1306,6 +1306,14 @@ function createListCommand() {
|
|
|
1306
1306
|
|
|
1307
1307
|
//#endregion
|
|
1308
1308
|
//#region src/utils/interrupt-signals.ts
|
|
1309
|
+
const postCleanupListeners = /* @__PURE__ */ new WeakSet();
|
|
1310
|
+
function prependPostCleanupSigintListener(listener) {
|
|
1311
|
+
postCleanupListeners.add(listener);
|
|
1312
|
+
process.prependListener("SIGINT", listener);
|
|
1313
|
+
return () => {
|
|
1314
|
+
process.removeListener("SIGINT", listener);
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1309
1317
|
function forwardSigtermToSigint() {
|
|
1310
1318
|
beginCommandInterruptScope();
|
|
1311
1319
|
try {
|
|
@@ -1333,7 +1341,7 @@ function watchCommandInterrupt(opts) {
|
|
|
1333
1341
|
}
|
|
1334
1342
|
let stacksInFlight = 0;
|
|
1335
1343
|
function gracefulOwnerArmed() {
|
|
1336
|
-
return process.listeners("SIGINT").filter((l) => l !== handler).length - interruptWatchListenerCount() > 0;
|
|
1344
|
+
return process.listeners("SIGINT").filter((l) => l !== handler && !postCleanupListeners.has(l)).length - interruptWatchListenerCount() > 0;
|
|
1337
1345
|
}
|
|
1338
1346
|
const handler = () => {
|
|
1339
1347
|
if (stacksInFlight > 0 && gracefulOwnerArmed()) {
|
|
@@ -1923,8 +1931,8 @@ function resolveRequireApproval(cliValue, logger, cdkJson = loadCdkJson()) {
|
|
|
1923
1931
|
throw new CdkdError(`cdk.json "requireApproval" must be one of ${REQUIRE_APPROVAL_VALUES.join(", ")}, got: ${displayIdent(typeof configured === "string" ? configured : JSON.stringify(configured))}`, "INVALID_REQUIRE_APPROVAL");
|
|
1924
1932
|
}
|
|
1925
1933
|
function createApprovalPrompter(options) {
|
|
1934
|
+
if (options.yes) return Object.assign(() => Promise.resolve(true), { autoApproves: true });
|
|
1926
1935
|
return (request) => {
|
|
1927
|
-
if (options.yes) return Promise.resolve(true);
|
|
1928
1936
|
return serializePrompt(() => getLiveRenderer().suspendWhile(async () => {
|
|
1929
1937
|
process.stdout.write(renderApprovalRequest(request));
|
|
1930
1938
|
return confirmOrRefuse("Do you wish to deploy these changes?", {
|
|
@@ -2396,7 +2404,7 @@ function collectCrossStackRefs(node, onRef) {
|
|
|
2396
2404
|
//#region src/provisioning/register-providers.ts
|
|
2397
2405
|
let providerClasses;
|
|
2398
2406
|
function loadProviderClasses() {
|
|
2399
|
-
providerClasses ??= import("./provider-classes-
|
|
2407
|
+
providerClasses ??= import("./provider-classes-eEgFT-Vt.js");
|
|
2400
2408
|
return providerClasses;
|
|
2401
2409
|
}
|
|
2402
2410
|
function registerAllProviders(registry, classes) {
|
|
@@ -2637,6 +2645,262 @@ function createPrefixMigrationGate(opts) {
|
|
|
2637
2645
|
};
|
|
2638
2646
|
}
|
|
2639
2647
|
|
|
2648
|
+
//#endregion
|
|
2649
|
+
//#region src/cli/commands/registry-release.ts
|
|
2650
|
+
async function releaseRegistryMarkerQuietly(backend, stackName, region, logger, known) {
|
|
2651
|
+
if (stackName.includes("~")) return;
|
|
2652
|
+
try {
|
|
2653
|
+
const released = known === void 0 ? await backend.releaseRegistryMarker(stackName, region) : await backend.releaseRegistryMarker(stackName, region, known);
|
|
2654
|
+
logger.debug(safeMsg`Stack registry marker: ${released}`);
|
|
2655
|
+
} catch (error) {
|
|
2656
|
+
logger.warn(safeMsg`Could not delete the stack registry marker of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}). It names this state prefix, which no longer ` + `records the stack, so a deploy under another prefix treats it as stale.`);
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
//#endregion
|
|
2661
|
+
//#region src/cli/commands/cross-prefix-gate.ts
|
|
2662
|
+
function deployStackRegion(stack, baseRegion) {
|
|
2663
|
+
return stack.region || baseRegion;
|
|
2664
|
+
}
|
|
2665
|
+
function createCrossPrefixDeployGate(opts) {
|
|
2666
|
+
return async (gateStackName, state) => {
|
|
2667
|
+
if (gateStackName !== opts.stackName) return;
|
|
2668
|
+
if (state !== void 0) return;
|
|
2669
|
+
const result = await opts.guard.firstDeploy(opts.stackName, opts.region);
|
|
2670
|
+
applyCrossPrefixScan(result, {
|
|
2671
|
+
stackName: opts.stackName,
|
|
2672
|
+
region: opts.region,
|
|
2673
|
+
bucket: opts.bucket,
|
|
2674
|
+
recovery: opts.recovery
|
|
2675
|
+
}, "deploy", ...reportOnce(result));
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
const reported = /* @__PURE__ */ new WeakSet();
|
|
2679
|
+
function reportOnce(result) {
|
|
2680
|
+
const first = !reported.has(result);
|
|
2681
|
+
reported.add(result);
|
|
2682
|
+
return first ? [(message) => getLogger().warn(message), (message) => getLogger().info(message)] : [() => void 0, () => void 0];
|
|
2683
|
+
}
|
|
2684
|
+
function createCrossPrefixDestructiveGate(opts) {
|
|
2685
|
+
return async (stackName, _destructive, stage) => {
|
|
2686
|
+
const result = await opts.cache.full(stackName, opts.region);
|
|
2687
|
+
applyCrossPrefixScan(result, {
|
|
2688
|
+
stackName,
|
|
2689
|
+
region: opts.region,
|
|
2690
|
+
bucket: opts.bucket,
|
|
2691
|
+
recovery: opts.recovery
|
|
2692
|
+
}, stage === "late" ? "deploy-late-replace" : "deploy-destructive", ...reportOnce(result));
|
|
2693
|
+
};
|
|
2694
|
+
}
|
|
2695
|
+
function createCrossPrefixHolder(opts) {
|
|
2696
|
+
return async (stackName) => {
|
|
2697
|
+
const result = await opts.cache.full(stackName, opts.region);
|
|
2698
|
+
switch (result.kind) {
|
|
2699
|
+
case "found": return {
|
|
2700
|
+
kind: "unreadable",
|
|
2701
|
+
what: safeMsg`bucket ${opts.bucket} also records this stack under another state prefix (${displayIdent(result.prefixes[0])}), whose record may hold it`
|
|
2702
|
+
};
|
|
2703
|
+
case "in-progress": return {
|
|
2704
|
+
kind: "unreadable",
|
|
2705
|
+
what: safeMsg`bucket ${opts.bucket} assigns this stack to another state prefix (${displayIdent(result.prefix)}), where a deploy may be in progress`
|
|
2706
|
+
};
|
|
2707
|
+
case "failed": return {
|
|
2708
|
+
kind: "unreadable",
|
|
2709
|
+
what: safeMsg`the other state prefixes of bucket ${opts.bucket} could not be checked`,
|
|
2710
|
+
retryable: true
|
|
2711
|
+
};
|
|
2712
|
+
case "denied":
|
|
2713
|
+
reportOnce(result)[0](crossPrefixDeniedWarning({
|
|
2714
|
+
stackName,
|
|
2715
|
+
region: opts.region,
|
|
2716
|
+
bucket: opts.bucket
|
|
2717
|
+
}, result.error, result.stage));
|
|
2718
|
+
return;
|
|
2719
|
+
default: return;
|
|
2720
|
+
}
|
|
2721
|
+
};
|
|
2722
|
+
}
|
|
2723
|
+
function crossPrefixEngineOptions(opts) {
|
|
2724
|
+
const backend = opts.backend;
|
|
2725
|
+
return {
|
|
2726
|
+
...backend !== void 0 && { onFirstDeployLeftNoRecord: async (stackName) => {
|
|
2727
|
+
if (stackName !== opts.stackName) return;
|
|
2728
|
+
const known = await opts.guard.knownMarker?.(stackName, opts.region);
|
|
2729
|
+
await releaseRegistryMarkerQuietly(backend, stackName, opts.region, getLogger(), known);
|
|
2730
|
+
} },
|
|
2731
|
+
firstDeployGate: createCrossPrefixDeployGate({
|
|
2732
|
+
stackName: opts.stackName,
|
|
2733
|
+
region: opts.region,
|
|
2734
|
+
bucket: opts.bucket,
|
|
2735
|
+
recovery: opts.recovery,
|
|
2736
|
+
guard: opts.guard
|
|
2737
|
+
}),
|
|
2738
|
+
onDestructivePlan: createCrossPrefixDestructiveGate({
|
|
2739
|
+
region: opts.region,
|
|
2740
|
+
bucket: opts.bucket,
|
|
2741
|
+
recovery: opts.recovery,
|
|
2742
|
+
cache: opts.guard
|
|
2743
|
+
}),
|
|
2744
|
+
crossPrefixHolder: createCrossPrefixHolder({
|
|
2745
|
+
region: opts.region,
|
|
2746
|
+
bucket: opts.bucket,
|
|
2747
|
+
cache: opts.guard
|
|
2748
|
+
})
|
|
2749
|
+
};
|
|
2750
|
+
}
|
|
2751
|
+
function composeStateLoadedGates(crossPrefix, migration) {
|
|
2752
|
+
return async (stackName, state) => {
|
|
2753
|
+
await crossPrefix(stackName, state);
|
|
2754
|
+
if (migration) await migration(stackName, state);
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
//#endregion
|
|
2759
|
+
//#region src/state/stack-registry.ts
|
|
2760
|
+
function unwrapReadError(error) {
|
|
2761
|
+
return error instanceof CrossPrefixReadError ? error.cause : error;
|
|
2762
|
+
}
|
|
2763
|
+
function topLevelStackName(stackName) {
|
|
2764
|
+
return stackName.split("~")[0];
|
|
2765
|
+
}
|
|
2766
|
+
var CrossPrefixGuard = class {
|
|
2767
|
+
scan;
|
|
2768
|
+
backend;
|
|
2769
|
+
readOnly;
|
|
2770
|
+
markers = /* @__PURE__ */ new Map();
|
|
2771
|
+
answers = /* @__PURE__ */ new Map();
|
|
2772
|
+
constructor(backend, opts = {}) {
|
|
2773
|
+
this.backend = backend;
|
|
2774
|
+
this.readOnly = opts.readOnly === true;
|
|
2775
|
+
this.scan = opts.scan ?? new CrossPrefixScanCache(backend);
|
|
2776
|
+
}
|
|
2777
|
+
get target() {
|
|
2778
|
+
return this.scan.target;
|
|
2779
|
+
}
|
|
2780
|
+
full(stackName, region, when = "now") {
|
|
2781
|
+
const key = JSON.stringify([stackName, region]);
|
|
2782
|
+
let answer = this.answers.get(key);
|
|
2783
|
+
if (answer === void 0) {
|
|
2784
|
+
answer = this.evaluate(stackName, region, false, when);
|
|
2785
|
+
this.answers.set(key, answer);
|
|
2786
|
+
} else if (when === "now") this.scan.target.rank(stackName, region, "now");
|
|
2787
|
+
return answer;
|
|
2788
|
+
}
|
|
2789
|
+
firstDeploy(stackName, region) {
|
|
2790
|
+
const key = JSON.stringify([stackName, region]);
|
|
2791
|
+
const answer = this.evaluate(stackName, region, true, "now");
|
|
2792
|
+
this.answers.set(key, answer);
|
|
2793
|
+
return answer;
|
|
2794
|
+
}
|
|
2795
|
+
async knownMarker(stackName, region) {
|
|
2796
|
+
const read = this.markers.get(JSON.stringify([topLevelStackName(stackName), region]));
|
|
2797
|
+
if (read === void 0) return void 0;
|
|
2798
|
+
return read.catch(() => void 0);
|
|
2799
|
+
}
|
|
2800
|
+
marker(top, region, fresh = false) {
|
|
2801
|
+
const key = JSON.stringify([top, region]);
|
|
2802
|
+
let read = fresh ? void 0 : this.markers.get(key);
|
|
2803
|
+
if (read === void 0) {
|
|
2804
|
+
read = this.backend.getRegistryMarker(top, region);
|
|
2805
|
+
this.markers.set(key, read);
|
|
2806
|
+
}
|
|
2807
|
+
return read;
|
|
2808
|
+
}
|
|
2809
|
+
async evaluate(stackName, region, firstDeploy, when) {
|
|
2810
|
+
const top = topLevelStackName(stackName);
|
|
2811
|
+
const claimable = top === stackName && !this.readOnly;
|
|
2812
|
+
if (firstDeploy && claimable && !this.markers.has(JSON.stringify([top, region]))) {
|
|
2813
|
+
if (await this.claim(top, region) === "claimed") return { kind: "clear" };
|
|
2814
|
+
}
|
|
2815
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
2816
|
+
let marker;
|
|
2817
|
+
try {
|
|
2818
|
+
marker = await this.marker(top, region, attempt > 0);
|
|
2819
|
+
} catch (error) {
|
|
2820
|
+
return this.fallback(stackName, region, when, error);
|
|
2821
|
+
}
|
|
2822
|
+
if (marker === null) {
|
|
2823
|
+
if (firstDeploy) {
|
|
2824
|
+
if (!claimable) return { kind: "clear" };
|
|
2825
|
+
const claimed = await this.claim(top, region);
|
|
2826
|
+
if (claimed === "conflict") continue;
|
|
2827
|
+
if (claimed !== "claimed") return this.fallback(stackName, region, when, claimed.error);
|
|
2828
|
+
return { kind: "clear" };
|
|
2829
|
+
}
|
|
2830
|
+
const scanned = await this.scan.full(stackName, region, when);
|
|
2831
|
+
if (scanned.kind === "clear" && claimable) {
|
|
2832
|
+
if (await this.claim(top, region) === "conflict") continue;
|
|
2833
|
+
}
|
|
2834
|
+
return scanned;
|
|
2835
|
+
}
|
|
2836
|
+
if (marker.prefix === this.backend.prefix) return { kind: "clear" };
|
|
2837
|
+
let held;
|
|
2838
|
+
let locked;
|
|
2839
|
+
try {
|
|
2840
|
+
held = await this.backend.recordUnderPrefix(marker.prefix, stackName, region);
|
|
2841
|
+
locked = held === "holder" ? false : await this.backend.lockUnderPrefix(marker.prefix, top, region);
|
|
2842
|
+
} catch (error) {
|
|
2843
|
+
return isAccessDenied(error) ? {
|
|
2844
|
+
kind: "denied",
|
|
2845
|
+
error,
|
|
2846
|
+
stage: "probe"
|
|
2847
|
+
} : {
|
|
2848
|
+
kind: "failed",
|
|
2849
|
+
error
|
|
2850
|
+
};
|
|
2851
|
+
}
|
|
2852
|
+
if (held === "holder") return {
|
|
2853
|
+
kind: "found",
|
|
2854
|
+
prefixes: [marker.prefix]
|
|
2855
|
+
};
|
|
2856
|
+
if (locked) return {
|
|
2857
|
+
kind: "in-progress",
|
|
2858
|
+
prefix: marker.prefix
|
|
2859
|
+
};
|
|
2860
|
+
const stale = held === "empty" ? [marker.prefix] : [];
|
|
2861
|
+
const scanned = await this.scan.full(stackName, region, when);
|
|
2862
|
+
if (scanned.kind !== "clear") return scanned;
|
|
2863
|
+
const allStale = [.../* @__PURE__ */ new Set([...stale, ...scanned.stale ?? []])];
|
|
2864
|
+
const answer = {
|
|
2865
|
+
kind: "clear",
|
|
2866
|
+
...allStale.length > 0 && { stale: allStale }
|
|
2867
|
+
};
|
|
2868
|
+
if (!claimable) return answer;
|
|
2869
|
+
if (await this.claim(top, region, marker.etag) === "conflict") continue;
|
|
2870
|
+
return answer;
|
|
2871
|
+
}
|
|
2872
|
+
return {
|
|
2873
|
+
kind: "failed",
|
|
2874
|
+
error: new CrossPrefixReadError(`_cdkd-registry/${region}/${top}.json`, Object.assign(/* @__PURE__ */ new Error("the marker changed twice while cdkd was claiming it"), { name: "ConcurrentClaim" }))
|
|
2875
|
+
};
|
|
2876
|
+
}
|
|
2877
|
+
async claim(top, region, ifMatch) {
|
|
2878
|
+
try {
|
|
2879
|
+
const result = await this.backend.claimRegistryMarker(top, region, ifMatch);
|
|
2880
|
+
if (result === "claimed") this.markers.set(JSON.stringify([top, region]), Promise.resolve({
|
|
2881
|
+
prefix: this.backend.prefix,
|
|
2882
|
+
etag: ""
|
|
2883
|
+
}));
|
|
2884
|
+
return result;
|
|
2885
|
+
} catch (error) {
|
|
2886
|
+
return { error };
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
async fallback(stackName, region, when, error) {
|
|
2890
|
+
if (!isAccessDenied(error) && !isNotImplemented(unwrapReadError(error))) return {
|
|
2891
|
+
kind: "failed",
|
|
2892
|
+
error
|
|
2893
|
+
};
|
|
2894
|
+
const scanned = await this.scan.full(stackName, region, when);
|
|
2895
|
+
return scanned.kind === "clear" ? {
|
|
2896
|
+
kind: "denied",
|
|
2897
|
+
error,
|
|
2898
|
+
stage: "registry",
|
|
2899
|
+
...scanned.stale && { stale: scanned.stale }
|
|
2900
|
+
} : scanned;
|
|
2901
|
+
}
|
|
2902
|
+
};
|
|
2903
|
+
|
|
2640
2904
|
//#endregion
|
|
2641
2905
|
//#region src/cli/commands/deploy.ts
|
|
2642
2906
|
async function deployCommand(stacks, options) {
|
|
@@ -2706,6 +2970,7 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
2706
2970
|
};
|
|
2707
2971
|
process.on("SIGINT", topLevelSigintHandler);
|
|
2708
2972
|
const unforwardSigterm = forwardSigtermToSigint();
|
|
2973
|
+
let preflightBackendForCleanup;
|
|
2709
2974
|
try {
|
|
2710
2975
|
logger.info(cyan(synthesisStatusMessage(app, "Synthesizing CDK app...")));
|
|
2711
2976
|
const synthesizer = new Synthesizer();
|
|
@@ -2721,6 +2986,7 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
2721
2986
|
};
|
|
2722
2987
|
const [result, statePrep] = await Promise.all([synthesizer.synthesize(synthOptions), statePrepPromise]);
|
|
2723
2988
|
const { stateBucket, preflightStateBackend, exportIndexStore } = statePrep;
|
|
2989
|
+
preflightBackendForCleanup = preflightStateBackend;
|
|
2724
2990
|
synthOptions.stateBucket = stateBucket;
|
|
2725
2991
|
const refusalRecovery = {
|
|
2726
2992
|
profile: options.profile,
|
|
@@ -2787,6 +3053,8 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
2787
3053
|
ignoreErrors: options.ignoreErrors === true
|
|
2788
3054
|
});
|
|
2789
3055
|
refuseMalformedNestedTemplateTrees(targetStacks);
|
|
3056
|
+
const baseRegion = namedCliRegion(options.region) ?? "us-east-1";
|
|
3057
|
+
const crossPrefixGuard = new CrossPrefixGuard(preflightStateBackend, { readOnly: options.dryRun === true });
|
|
2790
3058
|
await synthesizer.expandMacrosForStacks(targetStacks, synthOptions);
|
|
2791
3059
|
const { STSClient, GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
|
|
2792
3060
|
const stsClient = new STSClient({
|
|
@@ -2816,7 +3084,6 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
2816
3084
|
};
|
|
2817
3085
|
const dagBuilder = new DagBuilder({ relaxCdkVpcDefensiveDeps: !!options.aggressiveVpcParallel });
|
|
2818
3086
|
const diffCalculator = new DiffCalculator();
|
|
2819
|
-
const baseRegion = namedCliRegion(options.region) ?? "us-east-1";
|
|
2820
3087
|
const workGraph = new WorkGraph();
|
|
2821
3088
|
const stackMap = new Map(targetStacks.map((s) => [s.stackName, s]));
|
|
2822
3089
|
const stackRedirects = /* @__PURE__ */ new Map();
|
|
@@ -2864,13 +3131,14 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
2864
3131
|
logger.debug(`Work graph: ${summary["asset-publish"]} asset(s), ${summary["stack"]} stack(s)`);
|
|
2865
3132
|
const bufferStackOutput = targetStacks.length > 1;
|
|
2866
3133
|
let totalUnaddressed = 0;
|
|
3134
|
+
let totalCrossPrefixKept = 0;
|
|
2867
3135
|
let cancelledStacks = 0;
|
|
2868
3136
|
const runStack = async (stackInfo) => {
|
|
2869
3137
|
return withSkipPrefix(skipPrefix, () => runStackInner(stackInfo));
|
|
2870
3138
|
};
|
|
2871
3139
|
const runStackInner = async (stackInfo) => {
|
|
2872
3140
|
if (deployInterrupted) throw new DeployCancelledError(`Deploy interrupted before stack '${stackInfo.stackName}' started — not starting it.`);
|
|
2873
|
-
const stackRegion = stackInfo
|
|
3141
|
+
const stackRegion = deployStackRegion(stackInfo, baseRegion);
|
|
2874
3142
|
logger.info(`\n${cyan("Deploying stack:")} ${bold(cyan(stackInfo.stackName))}${stackRegion !== baseRegion ? gray(` (region: ${stackRegion})`) : ""}`);
|
|
2875
3143
|
const stackAwsClients = new AwsClients({
|
|
2876
3144
|
region: stackRegion,
|
|
@@ -2908,6 +3176,14 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
2908
3176
|
skipPrefix,
|
|
2909
3177
|
yes: options.yes
|
|
2910
3178
|
});
|
|
3179
|
+
const crossPrefix = crossPrefixEngineOptions({
|
|
3180
|
+
stackName: stackInfo.stackName,
|
|
3181
|
+
region: stackRegion,
|
|
3182
|
+
bucket: stateBucket,
|
|
3183
|
+
recovery: refusalRecovery,
|
|
3184
|
+
guard: crossPrefixGuard,
|
|
3185
|
+
backend: preflightStateBackend
|
|
3186
|
+
});
|
|
2911
3187
|
let recreateTargets;
|
|
2912
3188
|
if (options.recreateViaCcApi?.length || options.recreateViaSdkProvider?.length) {
|
|
2913
3189
|
const stateForRecreateCheck = await stackStateBackend.getState(stackInfo.stackName, stackRegion);
|
|
@@ -2987,7 +3263,10 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
2987
3263
|
refusalRecovery,
|
|
2988
3264
|
...assetRedirect && { assetRedirect },
|
|
2989
3265
|
...eventRecorder && { eventRecorder },
|
|
2990
|
-
|
|
3266
|
+
onCurrentStateLoaded: composeStateLoadedGates(crossPrefix.firstDeployGate, migrationGate),
|
|
3267
|
+
...crossPrefix.onFirstDeployLeftNoRecord && { onFirstDeployLeftNoRecord: crossPrefix.onFirstDeployLeftNoRecord },
|
|
3268
|
+
onDestructivePlan: crossPrefix.onDestructivePlan,
|
|
3269
|
+
crossPrefixHolder: crossPrefix.crossPrefixHolder,
|
|
2991
3270
|
...options.pinCcApi?.length && { pinCcApi: {
|
|
2992
3271
|
stackName: stackInfo.stackName,
|
|
2993
3272
|
logicalIds: new Set(options.pinCcApi)
|
|
@@ -3038,10 +3317,15 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
3038
3317
|
logger.info(` Updated: ${updatedTotal > 0 ? yellow(updatedTotal) : gray(updatedTotal)}`);
|
|
3039
3318
|
logger.info(` Deleted: ${deployResult.deleted > 0 ? red(deployResult.deleted) : gray(deployResult.deleted)}`);
|
|
3040
3319
|
if (deployResult.deleteSkipped > 0) logger.info(` Skipped (not deleted): ${yellow(deployResult.deleteSkipped)}`);
|
|
3320
|
+
const crossPrefixKept = deployResult.crossPrefixKept ?? 0;
|
|
3321
|
+
if (crossPrefixKept > 0) logger.info(` Kept (replacement refused: another state prefix records the stack, or the check could not run): ${yellow(crossPrefixKept)}`);
|
|
3041
3322
|
if (ownUpdatePartial > 0) logger.info(safeMsg` of which left an orphaned predecessor: ${yellow(ownUpdatePartial)}`);
|
|
3042
3323
|
if (nestedUpdatePartial > 0) logger.info(safeMsg` Left an orphaned predecessor in a nested stack: ${yellow(nestedUpdatePartial)}`);
|
|
3043
|
-
const stackUnaddressed = deployResult.deleteSkipped + deployResult.updatePartial;
|
|
3044
|
-
if (!options.dryRun)
|
|
3324
|
+
const stackUnaddressed = deployResult.deleteSkipped + deployResult.updatePartial + crossPrefixKept;
|
|
3325
|
+
if (!options.dryRun) {
|
|
3326
|
+
totalUnaddressed += stackUnaddressed;
|
|
3327
|
+
totalCrossPrefixKept += crossPrefixKept;
|
|
3328
|
+
}
|
|
3045
3329
|
logger.info(` Unchanged: ${gray(deployResult.unchanged)}`);
|
|
3046
3330
|
logger.info(` Duration: ${cyan((deployResult.durationMs / 1e3).toFixed(2) + "s")}`);
|
|
3047
3331
|
if (deployResult.attributeFallbackCount > 0) logger.warn(`${deployResult.attributeFallbackCount} attribute resolution(s) fell back to the physical ID (potentially wrong values); re-run with --strict-getatt to fail on these`);
|
|
@@ -3057,7 +3341,7 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
3057
3341
|
created: deployResult.created,
|
|
3058
3342
|
updated: updatedTotal,
|
|
3059
3343
|
deleted: deployResult.deleted,
|
|
3060
|
-
...
|
|
3344
|
+
...stackUnaddressed > 0 && { skipped: stackUnaddressed }
|
|
3061
3345
|
}, deployResult.durationMs);
|
|
3062
3346
|
} catch (deployError) {
|
|
3063
3347
|
if (deployError instanceof DeployCancelledError) {
|
|
@@ -3102,11 +3386,12 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
|
|
|
3102
3386
|
if (!outcome.ok) throw outcome.error;
|
|
3103
3387
|
}
|
|
3104
3388
|
});
|
|
3105
|
-
if (totalUnaddressed > 0 && !options.allowUnaddressed) throw new PartialFailureError(`Deploy left ${totalUnaddressed} resource(s) unaddressed, so they may still exist in AWS. The two cases differ in what happens next: a DELETE the provider could not issue KEEPS its state record, so the next 'cdkd deploy' re-attempts it, while a replacement's surviving predecessor is NOT tracked and will never be retried — delete it by hand. The per-stack summaries above give the breakdown, and each resource's own warning names its cause and remedy.
|
|
3389
|
+
if (totalUnaddressed > 0 && !options.allowUnaddressed) throw new PartialFailureError(`Deploy left ${totalUnaddressed} resource(s) unaddressed, so they may still exist in AWS. The two cases differ in what happens next: a DELETE the provider could not issue KEEPS its state record, so the next 'cdkd deploy' re-attempts it, while a replacement's surviving predecessor is NOT tracked and will never be retried — delete it by hand. ` + (totalCrossPrefixKept > 0 ? "A replacement kept because another state prefix records the stack, or the check could not run, keeps its old resource and applies no new value — resolve the pair, or let the check run, and re-deploy. " : "") + "The per-stack summaries above give the breakdown, and each resource's own warning names its cause and remedy. " + (cancelledStacks > 0 ? `Note ${cancelledStacks} stack(s) were also cancelled and never deployed, so the template is not fully applied beyond the resources named above. ` : "") + `Pass --allow-unaddressed to exit 0 instead.`);
|
|
3106
3390
|
} finally {
|
|
3107
3391
|
unforwardSigterm();
|
|
3108
3392
|
process.removeListener("SIGINT", topLevelSigintHandler);
|
|
3109
3393
|
awsClients.destroy();
|
|
3394
|
+
preflightBackendForCleanup?.destroyClient();
|
|
3110
3395
|
}
|
|
3111
3396
|
}
|
|
3112
3397
|
function createDeployCommand() {
|
|
@@ -4372,7 +4657,7 @@ function maskOutputChangeForDisplay(change, mask, nameCorpus) {
|
|
|
4372
4657
|
return changed ? shown : change;
|
|
4373
4658
|
}
|
|
4374
4659
|
async function computeStackDiff(currentState, template, region, stackName, stateBackend, diffCalculator, options = {}) {
|
|
4375
|
-
const { parameters, canonicalizeProperties, cfnFallback, inheritSecretBearingTemplate, inheritedSecrets, attributeHealer, parentUnresolvedParameters, inheritedNoEchoParameters, inheritedNoEchoParametersAnyVerdict } = options;
|
|
4660
|
+
const { parameters, canonicalizeProperties, cfnFallback, inheritSecretBearingTemplate, inheritedSecrets, inheritedDerivedNames, attributeHealer, parentUnresolvedParameters, inheritedNoEchoParameters, inheritedNoEchoParametersAnyVerdict } = options;
|
|
4376
4661
|
const noEchoParametersOf = (t) => /* @__PURE__ */ new Set([...noEchoParameterNamesOf(t), ...inheritedNoEchoParameters ?? []]);
|
|
4377
4662
|
const inheritedForResolver = inheritedSecrets !== void 0 && hasMaskableValues(inheritedSecrets) ? inheritedSecrets : void 0;
|
|
4378
4663
|
const intrinsicResolver = new IntrinsicFunctionResolver(region, { cfnFallback: cfnFallback ?? true });
|
|
@@ -4502,7 +4787,11 @@ async function computeStackDiff(currentState, template, region, stackName, state
|
|
|
4502
4787
|
diffSecrets,
|
|
4503
4788
|
inheritedForResolver,
|
|
4504
4789
|
outputsPassSecrets
|
|
4505
|
-
], [
|
|
4790
|
+
], [
|
|
4791
|
+
splitPieces,
|
|
4792
|
+
derivedNames,
|
|
4793
|
+
...inheritedDerivedNames ? [inheritedDerivedNames] : []
|
|
4794
|
+
]);
|
|
4506
4795
|
const maskForLog = printing.mask;
|
|
4507
4796
|
const resolveRecordingInto = (bag, printingSecrets) => (value) => intrinsicResolver.resolve(value, {
|
|
4508
4797
|
recordedSecretValues: bag,
|
|
@@ -4706,6 +4995,7 @@ async function computeStackDiff(currentState, template, region, stackName, state
|
|
|
4706
4995
|
deployRefusals: shownDeployRefusals,
|
|
4707
4996
|
effectiveTemplate,
|
|
4708
4997
|
printingSecrets,
|
|
4998
|
+
derivedNames: diffPrintingSecrets([derivedNames, inheritedDerivedNames]),
|
|
4709
4999
|
resolvedParameters: mergedParameters,
|
|
4710
5000
|
conditions,
|
|
4711
5001
|
knownConditions: conditions === void 0 ? void 0 : Object.fromEntries(Object.entries(conditions).filter(([name]) => !stillUnknown.includes(name))),
|
|
@@ -4879,7 +5169,7 @@ function noEchoFedChildParameters(parentStackRow, parentNoEchoParameters, parent
|
|
|
4879
5169
|
})) fed.add(name);
|
|
4880
5170
|
return fed;
|
|
4881
5171
|
}
|
|
4882
|
-
async function resolveChildStackParameters(parentStackRow, parentTemplate, parentState, region, parentStackName, stateBackend, parentParameters, parentConditions, cfnFallback, printingSecrets, attributeHealer, unresolvedKeys, trust) {
|
|
5172
|
+
async function resolveChildStackParameters(parentStackRow, parentTemplate, parentState, region, parentStackName, stateBackend, parentParameters, parentConditions, cfnFallback, printingSecrets, attributeHealer, unresolvedKeys, trust, derivedNameSink) {
|
|
4883
5173
|
const rawParams = parentStackRow.Properties?.["Parameters"];
|
|
4884
5174
|
if (!rawParams || typeof rawParams !== "object" || Array.isArray(rawParams)) return {};
|
|
4885
5175
|
const resolver = new IntrinsicFunctionResolver(region, { cfnFallback: cfnFallback ?? true });
|
|
@@ -4891,7 +5181,7 @@ async function resolveChildStackParameters(parentStackRow, parentTemplate, paren
|
|
|
4891
5181
|
template: parentTemplate,
|
|
4892
5182
|
resources: parentState.resources,
|
|
4893
5183
|
secretNameNeedles: stateSecretNameNeedles(parentState.resources),
|
|
4894
|
-
secretNameSink: /* @__PURE__ */ new Map(),
|
|
5184
|
+
secretNameSink: derivedNameSink ?? /* @__PURE__ */ new Map(),
|
|
4895
5185
|
stateBackend,
|
|
4896
5186
|
stackName: parentStackName,
|
|
4897
5187
|
bestEffort: true,
|
|
@@ -4918,7 +5208,7 @@ function recordedTemplateResources(template, state) {
|
|
|
4918
5208
|
return recorded;
|
|
4919
5209
|
}
|
|
4920
5210
|
async function buildDiffTree(args) {
|
|
4921
|
-
const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parentHasSecretReference, parameters, parentUnresolvedParameters, canonicalizeProperties, assetRedirect, cfnFallback, previewOrphanAdoption, attributeHealerFor, ancestorTemplatePaths, isNestedChild, inheritedSecrets, inheritedNoEchoParameters, inheritedNoEchoParametersAnyVerdict, refusalRecovery } = args;
|
|
5211
|
+
const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parentHasSecretReference, parameters, parentUnresolvedParameters, canonicalizeProperties, assetRedirect, cfnFallback, previewOrphanAdoption, attributeHealerFor, ancestorTemplatePaths, isNestedChild, inheritedSecrets, inheritedDerivedNames, inheritedNoEchoParameters, inheritedNoEchoParametersAnyVerdict, refusalRecovery } = args;
|
|
4922
5212
|
const attributeHealer = attributeHealerFor?.(stackName, region);
|
|
4923
5213
|
const { state, unreadable, unreadableContainers, deployRefusals } = await loadStateOrEmpty(stackName, region, stateBackend, refusalRecovery);
|
|
4924
5214
|
const createOnlyPrefetch = prefetchCreateOnlyPropertyPaths(templateResourceTypes(recordedTemplateResources(template, state)));
|
|
@@ -4932,6 +5222,7 @@ async function buildDiffTree(args) {
|
|
|
4932
5222
|
...cfnFallback !== void 0 && { cfnFallback },
|
|
4933
5223
|
...previewOrphanAdoption && { previewOrphanAdoption },
|
|
4934
5224
|
...inheritedSecrets && { inheritedSecrets },
|
|
5225
|
+
...inheritedDerivedNames && { inheritedDerivedNames },
|
|
4935
5226
|
...inheritedNoEchoParameters && { inheritedNoEchoParameters },
|
|
4936
5227
|
...inheritedNoEchoParametersAnyVerdict && { inheritedNoEchoParametersAnyVerdict },
|
|
4937
5228
|
...attributeHealer && { attributeHealer },
|
|
@@ -4943,7 +5234,7 @@ async function buildDiffTree(args) {
|
|
|
4943
5234
|
} finally {
|
|
4944
5235
|
createOnlyPrefetch.cancel();
|
|
4945
5236
|
}
|
|
4946
|
-
const { changes, outputChanges, adoptedOrphans, adoptedRecords, blocking, unreadableOrphans, deployRefusals: adoptedDeployRefusals, effectiveTemplate, printingSecrets, resolvedParameters, conditions, knownConditions, trust } = stackDiff;
|
|
5237
|
+
const { changes, outputChanges, adoptedOrphans, adoptedRecords, blocking, unreadableOrphans, deployRefusals: adoptedDeployRefusals, effectiveTemplate, printingSecrets, derivedNames: nodeDerivedNames, resolvedParameters, conditions, knownConditions, trust } = stackDiff;
|
|
4947
5238
|
const stateAfterAdoption = Object.keys(adoptedRecords).length > 0 ? {
|
|
4948
5239
|
...state,
|
|
4949
5240
|
resources: {
|
|
@@ -4992,8 +5283,10 @@ async function buildDiffTree(args) {
|
|
|
4992
5283
|
...inheritedNoEchoParameters ?? [],
|
|
4993
5284
|
...inheritedNoEchoParametersAnyVerdict ?? []
|
|
4994
5285
|
]), void 0, stateAfterAdoption.resources);
|
|
4995
|
-
const
|
|
4996
|
-
|
|
5286
|
+
const rowDerivedNames = /* @__PURE__ */ new Map();
|
|
5287
|
+
const childParameters = await resolveChildStackParameters(resource, effectiveTemplate, stateAfterAdoption, region, stackName, stateBackend, resolvedParameters, conditions, cfnFallback, printingSecrets, attributeHealer, childUnresolvedParameters, trust, rowDerivedNames);
|
|
5288
|
+
const childDerivedNames = diffPrintingSecrets([inheritedDerivedNames, rowDerivedNames]);
|
|
5289
|
+
const buildChild = () => buildDiffTree({
|
|
4997
5290
|
stackName: childStackName,
|
|
4998
5291
|
displayName: childStackName,
|
|
4999
5292
|
region,
|
|
@@ -5013,10 +5306,12 @@ async function buildDiffTree(args) {
|
|
|
5013
5306
|
isNestedChild: true,
|
|
5014
5307
|
parentHasSecretReference: secretBearingAbove,
|
|
5015
5308
|
inheritedSecrets: printingSecrets,
|
|
5309
|
+
...hasMaskableValues(childDerivedNames) && { inheritedDerivedNames: childDerivedNames },
|
|
5016
5310
|
...childNoEchoParameters.size > 0 && { inheritedNoEchoParameters: childNoEchoParameters },
|
|
5017
5311
|
...childNoEchoParametersAnyVerdict.size > 0 && { inheritedNoEchoParametersAnyVerdict: childNoEchoParametersAnyVerdict },
|
|
5018
5312
|
...refusalRecovery && { refusalRecovery }
|
|
5019
|
-
})
|
|
5313
|
+
});
|
|
5314
|
+
node.children.push(await (hasMaskableValues(childDerivedNames) ? withPrintingSecrets(childDerivedNames, buildChild) : buildChild()));
|
|
5020
5315
|
}
|
|
5021
5316
|
if (!isNestedChild) {
|
|
5022
5317
|
const defect = findNestedTemplateTreeDefect(nestedTemplates);
|
|
@@ -5025,15 +5320,17 @@ async function buildDiffTree(args) {
|
|
|
5025
5320
|
for (const [logicalId, resource] of Object.entries(state.resources ?? {})) {
|
|
5026
5321
|
if (resource.resourceType !== "AWS::CloudFormation::Stack") continue;
|
|
5027
5322
|
if (templateChildIds.has(logicalId)) continue;
|
|
5028
|
-
node.children.push(await buildDeletedSubtree(`${stackName}~${logicalId}`, region, stateBackend, diffCalculator, secretBearingAbove, printingSecrets, refusalRecovery));
|
|
5323
|
+
node.children.push(await buildDeletedSubtree(`${stackName}~${logicalId}`, region, stateBackend, diffCalculator, secretBearingAbove, printingSecrets, refusalRecovery, diffPrintingSecrets([nodeDerivedNames, stateDerivedNames(state.resources ?? {})])));
|
|
5029
5324
|
}
|
|
5030
5325
|
return node;
|
|
5031
5326
|
}
|
|
5032
|
-
async function buildDeletedSubtree(stackName, region, stateBackend, diffCalculator, parentHasSecretReference, inheritedSecrets, refusalRecovery) {
|
|
5327
|
+
async function buildDeletedSubtree(stackName, region, stateBackend, diffCalculator, parentHasSecretReference, inheritedSecrets, refusalRecovery, inheritedDerivedNames) {
|
|
5033
5328
|
const { state, unreadable, unreadableContainers } = await loadStateOrEmpty(stackName, region, stateBackend, refusalRecovery);
|
|
5329
|
+
const derivedNames = diffPrintingSecrets([inheritedDerivedNames, stateDerivedNames(state.resources ?? {})]);
|
|
5034
5330
|
const { changes, outputChanges } = await computeStackDiff(state, EMPTY_TEMPLATE, region, stackName, stateBackend, diffCalculator, {
|
|
5035
5331
|
inheritSecretBearingTemplate: parentHasSecretReference,
|
|
5036
5332
|
inheritedSecrets,
|
|
5333
|
+
...hasMaskableValues(derivedNames) && { inheritedDerivedNames: derivedNames },
|
|
5037
5334
|
...refusalRecovery && { refusalRecovery }
|
|
5038
5335
|
});
|
|
5039
5336
|
const node = {
|
|
@@ -5053,10 +5350,16 @@ async function buildDeletedSubtree(stackName, region, stateBackend, diffCalculat
|
|
|
5053
5350
|
};
|
|
5054
5351
|
for (const [logicalId, resource] of Object.entries(state.resources ?? {})) {
|
|
5055
5352
|
if (resource.resourceType !== "AWS::CloudFormation::Stack") continue;
|
|
5056
|
-
node.children.push(await buildDeletedSubtree(`${stackName}~${logicalId}`, region, stateBackend, diffCalculator, parentHasSecretReference, inheritedSecrets, refusalRecovery));
|
|
5353
|
+
node.children.push(await buildDeletedSubtree(`${stackName}~${logicalId}`, region, stateBackend, diffCalculator, parentHasSecretReference, inheritedSecrets, refusalRecovery, derivedNames));
|
|
5057
5354
|
}
|
|
5058
5355
|
return node;
|
|
5059
5356
|
}
|
|
5357
|
+
function stateDerivedNames(resources) {
|
|
5358
|
+
const bag = /* @__PURE__ */ new Map();
|
|
5359
|
+
const needlesOf = stateSecretNameNeedles(resources);
|
|
5360
|
+
for (const logicalId of Object.keys(resources)) for (const needle of needlesOf(logicalId) ?? []) recordLogOnlyValue(bag, needle);
|
|
5361
|
+
return bag;
|
|
5362
|
+
}
|
|
5060
5363
|
const EMPTY_ALLOW_SET = /* @__PURE__ */ new Set();
|
|
5061
5364
|
function diffReplaces(change, record) {
|
|
5062
5365
|
if (change?.changeType !== "UPDATE") return false;
|
|
@@ -10726,19 +11029,40 @@ async function acquireStackLock(opts) {
|
|
|
10726
11029
|
get interrupted() {
|
|
10727
11030
|
return interrupted;
|
|
10728
11031
|
},
|
|
10729
|
-
async release({ failureMessage, beforeRelease }) {
|
|
11032
|
+
async release({ failureMessage, beforeRelease, holdUntil }) {
|
|
10730
11033
|
if (released) return;
|
|
10731
11034
|
released = true;
|
|
10732
|
-
|
|
10733
|
-
await beforeRelease?.();
|
|
11035
|
+
const releaseNow = async () => {
|
|
10734
11036
|
try {
|
|
10735
11037
|
await lockManager.releaseLock(stackName, region);
|
|
10736
11038
|
lockHeld = false;
|
|
10737
11039
|
} catch (releaseErr) {
|
|
10738
11040
|
getLogger().warn(safeMsg`${failureMessage}: ${describeAwsFailure(releaseErr).detail}`);
|
|
10739
11041
|
}
|
|
11042
|
+
};
|
|
11043
|
+
let deferred = false;
|
|
11044
|
+
try {
|
|
11045
|
+
await beforeRelease?.();
|
|
11046
|
+
if (holdUntil !== void 0) {
|
|
11047
|
+
process.removeListener("SIGINT", sigintHandler);
|
|
11048
|
+
let forced = false;
|
|
11049
|
+
const removeDeferred = prependPostCleanupSigintListener(() => {
|
|
11050
|
+
if (!interrupted) {
|
|
11051
|
+
interrupted = true;
|
|
11052
|
+
return;
|
|
11053
|
+
}
|
|
11054
|
+
if (forced || !lockHeld) return;
|
|
11055
|
+
forced = true;
|
|
11056
|
+
lockManager.releaseLock(stackName, region).catch(() => {});
|
|
11057
|
+
process.stderr.write(`\nForce-quit (post-destroy cleanup): stack lock may not be released.${forceQuitRecoveryClause(stackName, region, recovery)}\n`);
|
|
11058
|
+
});
|
|
11059
|
+
holdUntil.defer(holdUntil.work.then(() => void 0, () => void 0).then(releaseNow).finally(removeDeferred));
|
|
11060
|
+
deferred = true;
|
|
11061
|
+
return;
|
|
11062
|
+
}
|
|
11063
|
+
await releaseNow();
|
|
10740
11064
|
} finally {
|
|
10741
|
-
process.removeListener("SIGINT", sigintHandler);
|
|
11065
|
+
if (!deferred) process.removeListener("SIGINT", sigintHandler);
|
|
10742
11066
|
}
|
|
10743
11067
|
}
|
|
10744
11068
|
};
|
|
@@ -10846,6 +11170,16 @@ function countProtectedJournaledOrphans(orphans, region) {
|
|
|
10846
11170
|
}
|
|
10847
11171
|
return count;
|
|
10848
11172
|
}
|
|
11173
|
+
async function releaseRegistryMarkerAfterDestroy(ctx, stackName, region, logger) {
|
|
11174
|
+
if (ctx.crossPrefixCheck === void 0) return;
|
|
11175
|
+
try {
|
|
11176
|
+
const known = await ctx.crossPrefixCheck.cache.knownMarker?.(stackName, region);
|
|
11177
|
+
const released = await ctx.stateBackend.releaseRegistryMarker(stackName, region, known);
|
|
11178
|
+
logger.debug(safeMsg`Stack registry marker: ${released}`);
|
|
11179
|
+
} catch (error) {
|
|
11180
|
+
logger.warn(safeMsg`Could not delete the stack registry marker of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}). It names this state prefix, which no longer ` + `records the stack, so a deploy under another prefix treats it as stale.`);
|
|
11181
|
+
}
|
|
11182
|
+
}
|
|
10849
11183
|
async function runDestroyForStack(stackName, state, ctx) {
|
|
10850
11184
|
const providerClasses = await loadProviderClasses();
|
|
10851
11185
|
const logger = getLogger();
|
|
@@ -10860,8 +11194,11 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
10860
11194
|
errorCount: 0,
|
|
10861
11195
|
interrupted: false
|
|
10862
11196
|
};
|
|
11197
|
+
const retainedForReadoption = [];
|
|
11198
|
+
let retainedEarlier;
|
|
10863
11199
|
const guardIndeterminateTargets = /* @__PURE__ */ new Set();
|
|
10864
11200
|
const regionForState = state.region ?? ctx.baseRegion;
|
|
11201
|
+
const crossPrefixScan = ctx.crossPrefixCheck?.cache.full(stackName, regionForState);
|
|
10865
11202
|
const refusalRecovery = {
|
|
10866
11203
|
profile: ctx.profile,
|
|
10867
11204
|
stateBucket: ctx.stateBucket,
|
|
@@ -10884,6 +11221,15 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
10884
11221
|
const resourceCount = Object.keys(state.resources).length;
|
|
10885
11222
|
const orphanCount = (state.orphans ?? []).length;
|
|
10886
11223
|
refuseMalformedOutputsForDestroy(state, stackName, regionForState, refusalRecovery);
|
|
11224
|
+
if (crossPrefixScan) applyCrossPrefixScan(await crossPrefixScan, {
|
|
11225
|
+
stackName,
|
|
11226
|
+
region: regionForState,
|
|
11227
|
+
bucket: ctx.stateBucket,
|
|
11228
|
+
recovery: {
|
|
11229
|
+
profile: ctx.profile,
|
|
11230
|
+
stateBucket: ctx.stateBucket
|
|
11231
|
+
}
|
|
11232
|
+
}, "destroy", (message) => logger.warn(message), (message) => logger.info(message));
|
|
10887
11233
|
if (resourceCount === 0 && orphanCount === 0 && journaledOrphans.count === 0) {
|
|
10888
11234
|
logger.info(`Stack ${displayStackName(stackName)} has no resources, cleaning up state...`);
|
|
10889
11235
|
const emptyLock = await acquireStackLock({
|
|
@@ -10907,6 +11253,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
10907
11253
|
if (!(!recheck || recheckResources === 0 && recheckOrphans === 0)) throw new Error(`Stack ${displayStackName(stackName)} (${displaySafe(regionForState, { asciiOnly: true })}) was empty when this run started but now has ${recheckResources} resource(s) and ${recheckOrphans} rollback-orphaned resource(s) — another cdkd process wrote to it. Re-run the destroy to act on the current state.`);
|
|
10908
11254
|
await ctx.stateBackend.deleteState(stackName, regionForState);
|
|
10909
11255
|
logger.info(`${green("✓")} State deleted`);
|
|
11256
|
+
await Promise.all([recordRetainedForReadoption(ctx.stateBackend, stackName, regionForState, [], logger), releaseRegistryMarkerAfterDestroy(ctx, stackName, regionForState, logger)]);
|
|
10910
11257
|
} finally {
|
|
10911
11258
|
await emptyLock.release({ failureMessage: "Failed to release lock after empty-state cleanup" });
|
|
10912
11259
|
}
|
|
@@ -10994,11 +11341,14 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
10994
11341
|
}
|
|
10995
11342
|
const renderer = getLiveRenderer();
|
|
10996
11343
|
let statePreserved = false;
|
|
11344
|
+
let heldTail;
|
|
11345
|
+
let stackFinished = false;
|
|
10997
11346
|
let journaledOrphanFailures = 0;
|
|
10998
11347
|
let journaledOrphanSkips = 0;
|
|
10999
11348
|
const lock = await acquireStackLock({
|
|
11000
11349
|
...stackLockBase,
|
|
11001
11350
|
onFirstSignal: () => {
|
|
11351
|
+
if (stackFinished) return;
|
|
11002
11352
|
renderer.printAbove(() => {
|
|
11003
11353
|
process.stderr.write("\nInterrupted — finishing in-flight deletes, then flushing state and releasing the lock (press Ctrl-C again to force-quit)...\n");
|
|
11004
11354
|
});
|
|
@@ -11172,6 +11522,17 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11172
11522
|
if (shouldRetainResource(resource.deletionPolicy)) {
|
|
11173
11523
|
logger.info(` ⊘ ${displaySafe(logicalId)} (${displaySafe(resource.resourceType)}) retained — DeletionPolicy: ${displaySafe(resource.deletionPolicy)}`);
|
|
11174
11524
|
result.retainedCount++;
|
|
11525
|
+
if (keptForReadoption(resource)) {
|
|
11526
|
+
retainedForReadoption.push({
|
|
11527
|
+
logicalId,
|
|
11528
|
+
resourceType: resource.resourceType,
|
|
11529
|
+
physicalId: resource.physicalId
|
|
11530
|
+
});
|
|
11531
|
+
if (retainedEarlier === void 0) {
|
|
11532
|
+
retainedEarlier = Promise.resolve().then(() => ctx.stateBackend.loadRetainedRecord(stackName, regionForState));
|
|
11533
|
+
retainedEarlier.catch(() => void 0);
|
|
11534
|
+
}
|
|
11535
|
+
}
|
|
11175
11536
|
recordDestroyEvent(ctx.eventRecorder, {
|
|
11176
11537
|
eventType: "RESOURCE_RETAINED",
|
|
11177
11538
|
stackName,
|
|
@@ -11383,7 +11744,16 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11383
11744
|
if (!preserveState) {
|
|
11384
11745
|
await ctx.stateBackend.deleteState(stackName, regionForState);
|
|
11385
11746
|
logger.debug("State deleted");
|
|
11386
|
-
|
|
11747
|
+
const writeKept = () => recordRetainedForReadoption(ctx.stateBackend, stackName, regionForState, retainedForReadoption, logger, retainedEarlier);
|
|
11748
|
+
const releaseMarker = () => releaseRegistryMarkerAfterDestroy(ctx, stackName, regionForState, logger);
|
|
11749
|
+
if (ctx.deferRegistryTail !== void 0) {
|
|
11750
|
+
heldTail = writeKept().then(releaseMarker);
|
|
11751
|
+
await ctx.exportIndexStore?.removeStack(stackName, regionForState);
|
|
11752
|
+
} else await Promise.all([
|
|
11753
|
+
writeKept(),
|
|
11754
|
+
releaseMarker(),
|
|
11755
|
+
ctx.exportIndexStore?.removeStack(stackName, regionForState)
|
|
11756
|
+
]);
|
|
11387
11757
|
} else {
|
|
11388
11758
|
try {
|
|
11389
11759
|
await ctx.stateBackend.saveState(stackName, regionForState, buildDestroySnapshot());
|
|
@@ -11430,6 +11800,10 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11430
11800
|
try {
|
|
11431
11801
|
await lock.release({
|
|
11432
11802
|
failureMessage: `Failed to release lock for stack ${displayStackName(stackName)}`,
|
|
11803
|
+
...heldTail !== void 0 && ctx.deferRegistryTail !== void 0 && { holdUntil: {
|
|
11804
|
+
work: heldTail,
|
|
11805
|
+
defer: ctx.deferRegistryTail
|
|
11806
|
+
} },
|
|
11433
11807
|
beforeRelease: async () => {
|
|
11434
11808
|
try {
|
|
11435
11809
|
renderer.stop();
|
|
@@ -11440,6 +11814,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11440
11814
|
logger.debug("Releasing lock...");
|
|
11441
11815
|
}
|
|
11442
11816
|
});
|
|
11817
|
+
stackFinished = true;
|
|
11443
11818
|
} finally {
|
|
11444
11819
|
restoreBaseRegionAndClients();
|
|
11445
11820
|
}
|
|
@@ -11490,6 +11865,10 @@ function orderConsumersBeforeProducers(stackNames, consumerToProducers) {
|
|
|
11490
11865
|
}
|
|
11491
11866
|
return ordered;
|
|
11492
11867
|
}
|
|
11868
|
+
function plannedDestroyRegion(refs, synthRegion, cliRegion) {
|
|
11869
|
+
if (refs.length === 1) return refs[0]?.region || cliRegion;
|
|
11870
|
+
if (refs.length > 1 && synthRegion && refs.some((r) => r.region === synthRegion)) return synthRegion;
|
|
11871
|
+
}
|
|
11493
11872
|
async function purgeEventsAfterDestroy(reader, stackName, region, opts, logger) {
|
|
11494
11873
|
if (opts.purgeEvents !== true || opts.runResult !== "SUCCEEDED" || opts.interrupted) return null;
|
|
11495
11874
|
try {
|
|
@@ -11547,6 +11926,9 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11547
11926
|
interruptWatch.dispose();
|
|
11548
11927
|
throw error;
|
|
11549
11928
|
}
|
|
11929
|
+
let stateBackendForCleanup;
|
|
11930
|
+
const deferredTails = [];
|
|
11931
|
+
let deferRegistryTail;
|
|
11550
11932
|
try {
|
|
11551
11933
|
const stateConfig = {
|
|
11552
11934
|
bucket: stateBucket,
|
|
@@ -11556,6 +11938,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11556
11938
|
...options.region && { region: options.region },
|
|
11557
11939
|
...options.profile && { profile: options.profile }
|
|
11558
11940
|
});
|
|
11941
|
+
stateBackendForCleanup = stateBackend;
|
|
11559
11942
|
await stateBackend.verifyBucketExists();
|
|
11560
11943
|
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
11561
11944
|
const exportIndexStore = new ExportIndexStore(awsClients.s3, stateBucket, options.statePrefix, region, stateBackend, { profile: options.profile });
|
|
@@ -11698,6 +12081,14 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11698
12081
|
arr.push(ref);
|
|
11699
12082
|
stateRefsByName.set(ref.stackName, arr);
|
|
11700
12083
|
}
|
|
12084
|
+
const crossPrefixCheck = { cache: new CrossPrefixGuard(stateBackend) };
|
|
12085
|
+
if (stackNames.length > 1) deferRegistryTail = (released) => deferredTails.push(released);
|
|
12086
|
+
for (const name of stackNames) {
|
|
12087
|
+
const synth = appStacks.find((s) => s.stackName === name);
|
|
12088
|
+
if (synth?.terminationProtection === true && !options.removeProtection) continue;
|
|
12089
|
+
const planned = plannedDestroyRegion(stateRefsByName.get(name) ?? [], synth?.region, region);
|
|
12090
|
+
if (planned !== void 0) crossPrefixCheck.cache.full(name, planned, "prestart");
|
|
12091
|
+
}
|
|
11701
12092
|
for (const [stackIndex, stackName] of stackNames.entries()) {
|
|
11702
12093
|
logger.info(`\nPreparing to destroy stack: ${displaySafe(stackName)}`);
|
|
11703
12094
|
const refs = stateRefsByName.get(stackName) ?? [];
|
|
@@ -11715,15 +12106,12 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11715
12106
|
continue;
|
|
11716
12107
|
}
|
|
11717
12108
|
}
|
|
12109
|
+
const plannedRegion = plannedDestroyRegion(refs, synthRegion, region);
|
|
11718
12110
|
let stackTargetRegion;
|
|
11719
12111
|
if (refs.length === 0) {
|
|
11720
12112
|
logger.warn(`No state found for stack ${displaySafe(stackName)}, skipping`);
|
|
11721
12113
|
continue;
|
|
11722
|
-
} else if (
|
|
11723
|
-
const onlyRegion = refs[0]?.region;
|
|
11724
|
-
if (!onlyRegion) stackTargetRegion = region;
|
|
11725
|
-
else stackTargetRegion = onlyRegion;
|
|
11726
|
-
} else if (synthRegion && refs.some((r) => r.region === synthRegion)) stackTargetRegion = synthRegion;
|
|
12114
|
+
} else if (plannedRegion !== void 0) stackTargetRegion = plannedRegion;
|
|
11727
12115
|
else {
|
|
11728
12116
|
const regions = refs.map((r) => r.region === void 0 ? "(legacy)" : plainOrDescribed(r.region, "region")).join(", ");
|
|
11729
12117
|
const orphanOneClause = withheldAccountClause(accountRecovery, "the command below prints").trimEnd();
|
|
@@ -11801,6 +12189,8 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11801
12189
|
skipFinalSnapshot: options.skipFinalSnapshot === true,
|
|
11802
12190
|
resolveSecretDerivedPrincipals: {},
|
|
11803
12191
|
stackDestroy: true,
|
|
12192
|
+
crossPrefixCheck,
|
|
12193
|
+
...deferRegistryTail !== void 0 && { deferRegistryTail },
|
|
11804
12194
|
exportIndexStore,
|
|
11805
12195
|
...TemplateNoEchoReresolver.usable(synthStack?.template) && (synthStack.region === void 0 || synthStack.region === stackTargetRegion) && { noEchoReresolver: new TemplateNoEchoReresolver({
|
|
11806
12196
|
template: synthStack.template,
|
|
@@ -11854,9 +12244,11 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11854
12244
|
if (interrupted || interruptWatch.interrupted() && stoppedEarly) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd destroy' to finish.`);
|
|
11855
12245
|
if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} whose delete cdkd did not confirm, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). The per-resource 'skipped (...)' lines and their warnings name each cause and whether repairing the record in state.json helps: where it does, repair it and re-run 'cdkd destroy'; otherwise (for example a custom-resource Delete handler that reported FAILED), delete the resources by hand and drop the records with 'cdkd state orphan <stack> --stack-region <region>'.`);
|
|
11856
12246
|
} finally {
|
|
12247
|
+
await Promise.allSettled(deferredTails);
|
|
11857
12248
|
unforwardSigterm();
|
|
11858
12249
|
interruptWatch.dispose();
|
|
11859
12250
|
awsClients.destroy();
|
|
12251
|
+
stateBackendForCleanup?.destroyClient();
|
|
11860
12252
|
}
|
|
11861
12253
|
}
|
|
11862
12254
|
function createDestroyCommand() {
|
|
@@ -14004,7 +14396,7 @@ async function exportCommand(stackArg, options) {
|
|
|
14004
14396
|
2. Re-run the phase 2 UPDATE manually with the full synth template:
|
|
14005
14397
|
${phase2RetryCommand(cfnStackName)}\n 3. Once phase 2 succeeds, clean up cdkd's stale state record.${orphan.note}\n Run: ${orphan.command}`);
|
|
14006
14398
|
}
|
|
14007
|
-
await stateBackend
|
|
14399
|
+
await removeExportedStackRecord(stateBackend, resolvedStackName, targetRegion, logger);
|
|
14008
14400
|
logger.info(`cdkd state for ${quotedOrNotShown(resolvedStackName)} (${quotedRegion(targetRegion)}) removed. Manage the stack with 'cdk deploy' or 'aws cloudformation' from here on.`);
|
|
14009
14401
|
printNextSteps({
|
|
14010
14402
|
cfnStackName,
|
|
@@ -15608,6 +16000,11 @@ async function buildResolvedParametersPerStack(args) {
|
|
|
15608
16000
|
intrinsicSkippedByCdkdName
|
|
15609
16001
|
};
|
|
15610
16002
|
}
|
|
16003
|
+
async function removeExportedStackRecord(stateBackend, stackName, region, logger) {
|
|
16004
|
+
await stateBackend.deleteState(stackName, region);
|
|
16005
|
+
await recordRetainedForReadoption(stateBackend, stackName, region, [], logger);
|
|
16006
|
+
await releaseRegistryMarkerQuietly(stateBackend, stackName, region, logger);
|
|
16007
|
+
}
|
|
15611
16008
|
async function runPerStackImportLoop(args) {
|
|
15612
16009
|
const logger = getLogger();
|
|
15613
16010
|
const { rootStackName, rootRegion, rootStackInfoNestedTemplates, rootTemplateFormat, tree, rootTemplate, cfnStackNameOverrides, rootParameters, deps, options } = args;
|
|
@@ -15885,7 +16282,7 @@ async function runPerStackImportLoop(args) {
|
|
|
15885
16282
|
}
|
|
15886
16283
|
const stateDeletionFailures = [];
|
|
15887
16284
|
for (const node of leafFirst) try {
|
|
15888
|
-
await deps.stateBackend
|
|
16285
|
+
await removeExportedStackRecord(deps.stateBackend, node.stackName, node.region, logger);
|
|
15889
16286
|
logger.info(`cdkd state for ${quotedOrNotShown(node.stackName)} (${quotedRegion(node.region)}) removed.`);
|
|
15890
16287
|
} catch (err) {
|
|
15891
16288
|
stateDeletionFailures.push({
|
|
@@ -16111,6 +16508,10 @@ const STATE_READ_REASONS = {
|
|
|
16111
16508
|
"read-failed": STATE_READ_FAILED_REASON,
|
|
16112
16509
|
"resources-malformed": "resources is not a JSON object; run `cdkd state show --json` to see the record"
|
|
16113
16510
|
};
|
|
16511
|
+
function stateDestroyTargets(refs, stackRegion) {
|
|
16512
|
+
if (stackRegion) return refs.filter((r) => r.region === stackRegion || !r.region);
|
|
16513
|
+
return refs.length === 1 ? [...refs] : void 0;
|
|
16514
|
+
}
|
|
16114
16515
|
function resourceCountOrNull(resources) {
|
|
16115
16516
|
if (resources === void 0 || resources === null) return 0;
|
|
16116
16517
|
if (typeof resources !== "object" || Array.isArray(resources)) return null;
|
|
@@ -16231,7 +16632,10 @@ async function setupStateBackend(options) {
|
|
|
16231
16632
|
bucket,
|
|
16232
16633
|
prefix,
|
|
16233
16634
|
exportIndexStore: new ExportIndexStore(awsClients.s3, bucket, prefix, region, stateBackend, { profile: options.profile }),
|
|
16234
|
-
dispose: () =>
|
|
16635
|
+
dispose: () => {
|
|
16636
|
+
awsClients.destroy();
|
|
16637
|
+
stateBackend.destroyClient();
|
|
16638
|
+
}
|
|
16235
16639
|
};
|
|
16236
16640
|
}
|
|
16237
16641
|
function renderRecovery(options, setup) {
|
|
@@ -16672,6 +17076,43 @@ function createStateShowCommand() {
|
|
|
16672
17076
|
cmd.addOption(deprecatedRegionOption);
|
|
16673
17077
|
return cmd;
|
|
16674
17078
|
}
|
|
17079
|
+
async function clearRetainedQuietly(backend, stackName, region, logger) {
|
|
17080
|
+
try {
|
|
17081
|
+
await backend.saveRetainedResources(stackName, region, []);
|
|
17082
|
+
return true;
|
|
17083
|
+
} catch (error) {
|
|
17084
|
+
logger.warn(safeMsg`Could not empty the kept-resource record of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}): a later deploy here may still take a kept ` + `resource back. Re-run 'cdkd state orphan' once it can write.`);
|
|
17085
|
+
return false;
|
|
17086
|
+
}
|
|
17087
|
+
}
|
|
17088
|
+
async function clearRetainedWithoutRecord(backend, stackName, stackRegion, logger) {
|
|
17089
|
+
if (stackName.includes("/")) return {
|
|
17090
|
+
cleared: [],
|
|
17091
|
+
attempted: 0
|
|
17092
|
+
};
|
|
17093
|
+
const base = `${backend.prefix}/${stackName}/`;
|
|
17094
|
+
let regions;
|
|
17095
|
+
try {
|
|
17096
|
+
const keys = (await backend.listRawKeys(base)).map((key) => key.slice(base.length).split("/")).filter((parts) => parts.length >= 2 && parts[0] !== "");
|
|
17097
|
+
const recorded = new Set(keys.filter((parts) => parts.length === 2 && parts[1] === "state.json").map((parts) => parts[0]));
|
|
17098
|
+
regions = [...new Set(keys.map((parts) => parts[0]).filter((region) => stackRegion === void 0 || region === stackRegion).filter((region) => !recorded.has(region)))];
|
|
17099
|
+
} catch (error) {
|
|
17100
|
+
logger.warn(safeMsg`Could not look for a kept-resource record of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}).`);
|
|
17101
|
+
return {
|
|
17102
|
+
cleared: [],
|
|
17103
|
+
attempted: 0
|
|
17104
|
+
};
|
|
17105
|
+
}
|
|
17106
|
+
const cleared = [];
|
|
17107
|
+
for (const region of regions) {
|
|
17108
|
+
if (await clearRetainedQuietly(backend, stackName, region, logger)) cleared.push(region);
|
|
17109
|
+
await releaseRegistryMarkerQuietly(backend, stackName, region, logger);
|
|
17110
|
+
}
|
|
17111
|
+
return {
|
|
17112
|
+
cleared,
|
|
17113
|
+
attempted: regions.length
|
|
17114
|
+
};
|
|
17115
|
+
}
|
|
16675
17116
|
async function stateOrphanCommand(stackArgs, options) {
|
|
16676
17117
|
const logger = getLogger();
|
|
16677
17118
|
if (options.verbose) logger.setLevel("debug");
|
|
@@ -16687,6 +17128,12 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
16687
17128
|
for (const stackName of stackArgs) {
|
|
16688
17129
|
const stackRefs = refs.filter((r) => r.stackName === stackName);
|
|
16689
17130
|
if (stackRefs.length === 0) {
|
|
17131
|
+
const { cleared, attempted } = await clearRetainedWithoutRecord(setup.stateBackend, stackName, options.stackRegion, logger);
|
|
17132
|
+
if (attempted > 0 && cleared.length === 0) continue;
|
|
17133
|
+
if (cleared.length > 0) {
|
|
17134
|
+
logger.info(safeMsg`Cleared the kept-resource record of ${plainOrDescribed(stackName, "stack name")} ` + safeMsg`(${cleared.map((r) => displaySafe(r, { asciiOnly: true })).join(", ")}): ` + `a later deploy here no longer takes a kept resource back.`);
|
|
17135
|
+
continue;
|
|
17136
|
+
}
|
|
16690
17137
|
logger.info(safeMsg`No state found for stack: ${plainOrDescribed(stackName, "stack name")}, skipping` + (isPasteableIdent(stackName) ? "" : safeMsg`. ${STATE_LIST_POINTER}`));
|
|
16691
17138
|
continue;
|
|
16692
17139
|
}
|
|
@@ -16730,10 +17177,13 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
16730
17177
|
await warnOnLiveForeignLock(setup.lockManager, stackName, target.region, logger);
|
|
16731
17178
|
await setup.stateBackend.deleteState(stackName, target.region);
|
|
16732
17179
|
await setup.lockManager.forceReleaseLock(stackName, target.region);
|
|
17180
|
+
await clearRetainedQuietly(setup.stateBackend, stackName, target.region, logger);
|
|
17181
|
+
await releaseRegistryMarkerQuietly(setup.stateBackend, stackName, target.region, logger);
|
|
16733
17182
|
} else {
|
|
16734
17183
|
await warnOnLiveForeignLock(setup.lockManager, stackName, void 0, logger);
|
|
16735
17184
|
await setup.stateBackend.deleteLegacyState(stackName);
|
|
16736
17185
|
await setup.lockManager.forceReleaseLock(stackName, void 0);
|
|
17186
|
+
await clearRetainedWithoutRecord(setup.stateBackend, stackName, void 0, logger);
|
|
16737
17187
|
}
|
|
16738
17188
|
logger.info(safeMsg`✓ Removed state for stack: ${describedStackRef(target)}` + ((options.yes || options.force) && refIsDescribed(target) ? safeMsg`. ${STATE_LIST_POINTER}` : ""));
|
|
16739
17189
|
}
|
|
@@ -16881,6 +17331,8 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
16881
17331
|
interruptWatch.dispose();
|
|
16882
17332
|
throw error;
|
|
16883
17333
|
}
|
|
17334
|
+
const deferredTails = [];
|
|
17335
|
+
let deferRegistryTail;
|
|
16884
17336
|
try {
|
|
16885
17337
|
const stateRefs = await setup.stateBackend.listStacks();
|
|
16886
17338
|
const knownStackNames = new Set(stateRefs.map((r) => r.stackName));
|
|
@@ -16898,16 +17350,23 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
16898
17350
|
if (!options.stackRegion) return laterRefs.length > 0;
|
|
16899
17351
|
return laterRefs.some((r) => r.region === options.stackRegion || !r.region);
|
|
16900
17352
|
});
|
|
17353
|
+
const crossPrefixCheck = { cache: new CrossPrefixGuard(setup.stateBackend) };
|
|
17354
|
+
if (stackNames.length > 1) deferRegistryTail = (released) => deferredTails.push(released);
|
|
17355
|
+
for (const name of stackNames) {
|
|
17356
|
+
const refs = stateRefs.filter((r) => r.stackName === name);
|
|
17357
|
+
for (const ref of stateDestroyTargets(refs, options.stackRegion) ?? []) crossPrefixCheck.cache.full(name, ref.region ?? setup.region, "prestart");
|
|
17358
|
+
}
|
|
16901
17359
|
for (const [stackIndex, stackName] of stackNames.entries()) {
|
|
16902
17360
|
const refs = stateRefs.filter((r) => r.stackName === stackName);
|
|
16903
17361
|
let targets;
|
|
17362
|
+
const planned = stateDestroyTargets(refs, options.stackRegion);
|
|
16904
17363
|
if (options.stackRegion) {
|
|
16905
|
-
targets =
|
|
17364
|
+
targets = planned ?? [];
|
|
16906
17365
|
if (targets.length === 0) {
|
|
16907
17366
|
logger.warn(safeMsg`Skipping ${plainOrDescribed(stackName, "stack name")} (no state record matches ` + safeMsg`--stack-region ${displayIdent(options.stackRegion)})`);
|
|
16908
17367
|
continue;
|
|
16909
17368
|
}
|
|
16910
|
-
} else if (
|
|
17369
|
+
} else if (planned !== void 0) targets = planned;
|
|
16911
17370
|
else throw multipleRegionsError(stackName, refs, `Use --stack-region ${commandHole("region")} to pick one.`);
|
|
16912
17371
|
for (const [refIndex, ref] of targets.entries()) {
|
|
16913
17372
|
logger.info(safeMsg`\nPreparing to destroy stack: ${formatStackRefSafe(ref)}`);
|
|
@@ -16964,6 +17423,8 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
16964
17423
|
skipFinalSnapshot: options.skipFinalSnapshot === true,
|
|
16965
17424
|
resolveSecretDerivedPrincipals: {},
|
|
16966
17425
|
stackDestroy: true,
|
|
17426
|
+
crossPrefixCheck,
|
|
17427
|
+
...deferRegistryTail !== void 0 && { deferRegistryTail },
|
|
16967
17428
|
exportIndexStore: setup.exportIndexStore,
|
|
16968
17429
|
...options.allowUnsupportedTypes?.length && { allowUnsupportedTypes: options.allowUnsupportedTypes },
|
|
16969
17430
|
...options.resourceWarnAfter?.globalMs !== void 0 && { resourceWarnAfterMs: options.resourceWarnAfter.globalMs },
|
|
@@ -17004,6 +17465,7 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
17004
17465
|
if (interrupted || interruptWatch.interrupted() && stoppedEarly) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd state destroy' to finish.`);
|
|
17005
17466
|
if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} whose delete cdkd did not confirm, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). The per-resource 'skipped (...)' lines and their warnings name each cause and whether repairing the record in state.json helps: where it does, repair it and re-run 'cdkd state destroy'; otherwise (for example a custom-resource Delete handler that reported FAILED), delete the resources by hand and drop the records with 'cdkd state orphan <stack> --stack-region <region>'.`);
|
|
17006
17467
|
} finally {
|
|
17468
|
+
await Promise.allSettled(deferredTails);
|
|
17007
17469
|
unforwardSigterm();
|
|
17008
17470
|
interruptWatch.dispose();
|
|
17009
17471
|
setup.dispose();
|
|
@@ -17666,6 +18128,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17666
18128
|
});
|
|
17667
18129
|
return;
|
|
17668
18130
|
}
|
|
18131
|
+
const crossPrefixScan = new CrossPrefixGuard(setup.stateBackend).full(stackName, region);
|
|
17669
18132
|
stackAwsClients = new AwsClients({
|
|
17670
18133
|
region,
|
|
17671
18134
|
...options.profile && { profile: options.profile }
|
|
@@ -17700,6 +18163,15 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17700
18163
|
segments: journal.segments.filter((s) => s.reason !== NESTED_PENDING_PARENT_REASON)
|
|
17701
18164
|
};
|
|
17702
18165
|
if (!journal || journal.segments.length === 0 && orphanedPending === 0) throw new Error(`Nothing to roll back for ${plainOrDescribed(stackName, "stack name")} (${plainOrDescribed(region, "region")}). Run 'cdkd deploy' to (re)deploy, or 'cdkd destroy' to clean up.`);
|
|
18166
|
+
applyCrossPrefixScan(await crossPrefixScan, {
|
|
18167
|
+
stackName,
|
|
18168
|
+
region,
|
|
18169
|
+
bucket: setup.bucket,
|
|
18170
|
+
recovery: {
|
|
18171
|
+
profile: options.profile,
|
|
18172
|
+
stateBucket: setup.bucket
|
|
18173
|
+
}
|
|
18174
|
+
}, "rollback", (message) => logger.warn(message), (message) => logger.info(message));
|
|
17703
18175
|
if (!stateData) throw new Error(`Rollback journal exists for ${safeStack(stackName)} (${safe(region)}) but its state.json is missing (keys: ${safe(setup.prefix)}/${safeStack(stackName)}/${safe(region)}/state.json and .../rollback-journal.json). State appears corrupted — inspect the bucket manually.`);
|
|
17704
18176
|
demoteSupersededOrphans(journal.segments, Array.isArray(stateData.state.orphans) ? stateData.state.orphans : []);
|
|
17705
18177
|
if (!options.revertFailed) for (const segment of journal.segments) {
|
|
@@ -17869,6 +18341,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17869
18341
|
let failedOpFailures = 0;
|
|
17870
18342
|
let failedOpWarnings = 0;
|
|
17871
18343
|
const failedOps = splitImportedOps(segment.failedOperations ?? [], segment);
|
|
18344
|
+
const failedForGuard = segment.failedOperations ?? [];
|
|
17872
18345
|
const failedToReplay = failedOpsToReplay(failedOps.replay, options.revertFailed === true);
|
|
17873
18346
|
if (failedToReplay.length > 0) {
|
|
17874
18347
|
const failedResult = await withPrintingSecrets(failedOpsPrinting, () => withPrintingSecrets(journaledOrphanPrintingBag(failedToReplay, stateResources), () => replayFailedOperations(failedToReplay, stateResources, stackName, ctx, {
|
|
@@ -17885,7 +18358,8 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17885
18358
|
...failedOps.imported,
|
|
17886
18359
|
...failedOps.displaced,
|
|
17887
18360
|
...failedOps.replay.filter((op) => !failedToReplay.includes(op)),
|
|
17888
|
-
...failedResult.remainingFailedOps
|
|
18361
|
+
...failedResult.remainingFailedOps,
|
|
18362
|
+
...completedOps.length > 0 ? failedToReplay.filter((op) => seedsDeleteFirstGuard(op) && !failedResult.remainingFailedOps.includes(op)) : []
|
|
17889
18363
|
];
|
|
17890
18364
|
if (!declinedDivergentRewrite && remaining.length !== (segment.failedOperations ?? []).length) try {
|
|
17891
18365
|
await setup.stateBackend.setRollbackJournalFailedOperations(stackName, region, remaining);
|
|
@@ -17905,7 +18379,8 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17905
18379
|
afterOp: saveState,
|
|
17906
18380
|
isInterrupted: () => interrupted,
|
|
17907
18381
|
onOrphan: (record) => mintedOrphans.push(record),
|
|
17908
|
-
inlinePolicyWriters
|
|
18382
|
+
inlinePolicyWriters,
|
|
18383
|
+
failedOperations: failedForGuard
|
|
17909
18384
|
}));
|
|
17910
18385
|
return {
|
|
17911
18386
|
failures: replayResult.failures + failedOpFailures,
|
|
@@ -17940,6 +18415,8 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17940
18415
|
const survivingOrphans = orphansAfterRollback(baseState, mintedOrphans).orphans ?? [];
|
|
17941
18416
|
if (journal.segments.length === 0 && oldestInitialDeploy && Object.keys(stateResources).length === 0 && survivingOrphans.length === 0) {
|
|
17942
18417
|
await setup.stateBackend.deleteState(stackName, region);
|
|
18418
|
+
await recordRetainedForReadoption(setup.stateBackend, stackName, region, [], logger);
|
|
18419
|
+
await releaseRegistryMarkerQuietly(setup.stateBackend, stackName, region, logger);
|
|
17943
18420
|
logger.info(`State for ${stackRegionShown(stackName, region)} removed (stack fully rolled back).`);
|
|
17944
18421
|
}
|
|
17945
18422
|
if (declinedDivergentRewrite) throw new PartialFailureError(`Rollback stopped: ${declinedDivergentReason}.` + (totalFailures > 0 ? ` ${totalFailures} operation(s) also failed.` : "") + " Journal preserved (this segment, any older ones, and their failed operations) — re-run the rollback once the record's region field matches its key.");
|
|
@@ -19087,8 +19564,20 @@ async function forceUnlockCommand(stackArgs, options) {
|
|
|
19087
19564
|
const where = r ? `${displayStackName(stackName)} (${displayIdent(r)})` : `${displayStackName(stackName)} (legacy lock key)`;
|
|
19088
19565
|
logger.info(`Force-unlocking stack: ${where}`);
|
|
19089
19566
|
try {
|
|
19090
|
-
|
|
19567
|
+
let ledgerError;
|
|
19568
|
+
let recorded = false;
|
|
19569
|
+
await lockManager.forceReleaseLock(stackName, r, async (horizon) => {
|
|
19570
|
+
if (r === void 0) return;
|
|
19571
|
+
const ledger = ledgerForStack(stateBackend, stackName, r);
|
|
19572
|
+
for (let attempt = 0; attempt < 2 && !recorded; attempt++) try {
|
|
19573
|
+
await ledger.noteAbandoned(horizon);
|
|
19574
|
+
recorded = true;
|
|
19575
|
+
} catch (error) {
|
|
19576
|
+
ledgerError = error;
|
|
19577
|
+
}
|
|
19578
|
+
});
|
|
19091
19579
|
logger.info(`✓ Lock released for stack: ${where}`);
|
|
19580
|
+
if (!recorded && ledgerError !== void 0) logger.warn(safeMsg`Lock released, but the create-token ledger of ${where} could not record when the ` + safeMsg`abandoned run stopped: ${describeAwsFailure(ledgerError).summary}. ` + "A later deploy may take back a resource of those names that another deployment creates.");
|
|
19092
19581
|
} catch (error) {
|
|
19093
19582
|
const message = describeAwsFailure(error).detail;
|
|
19094
19583
|
if (message.includes("No lock found") || message.includes("NoSuchKey")) logger.info(`No lock found for stack: ${where}`);
|
|
@@ -19198,6 +19687,20 @@ var ObservedBaselineRefusals = class extends Set {
|
|
|
19198
19687
|
unverifiableParameter = /* @__PURE__ */ new Set();
|
|
19199
19688
|
hadDeployedParameterSource = false;
|
|
19200
19689
|
};
|
|
19690
|
+
async function claimRegistryMarkerAfterImport(backend, stackName, region, logger) {
|
|
19691
|
+
const answer = await new CrossPrefixGuard(backend).full(stackName, region);
|
|
19692
|
+
const regionShown = displaySafe(region, { asciiOnly: true });
|
|
19693
|
+
switch (answer.kind) {
|
|
19694
|
+
case "clear": return;
|
|
19695
|
+
case "found":
|
|
19696
|
+
logger.warn(safeMsg`The state bucket also records ${displayStackName(stackName)} (${regionShown}) under another state prefix ` + safeMsg`(${answer.prefixes.map((p) => displayIdent(p)).join(", ")}). One stack name per ` + "account and region is supported: drop one of the records with 'cdkd state orphan' before deploying or destroying either.");
|
|
19697
|
+
return;
|
|
19698
|
+
case "in-progress":
|
|
19699
|
+
logger.warn(safeMsg`A deploy of ${displayStackName(stackName)} (${regionShown}) holds a lock under another state prefix ` + safeMsg`(${displayIdent(answer.prefix)}). One stack name per account and region is ` + `supported: keep one of the two before deploying or destroying either.`);
|
|
19700
|
+
return;
|
|
19701
|
+
default: logger.warn(safeMsg`Could not record ${displayStackName(stackName)} (${regionShown}) in the state bucket's stack registry` + (answer.kind === "denied" || answer.kind === "failed" ? safeMsg` (${describeAwsFailure(answer.error).summary})` : "") + `. Its next guarded command records it.`);
|
|
19702
|
+
}
|
|
19703
|
+
}
|
|
19201
19704
|
async function importCommand(stackArg, options) {
|
|
19202
19705
|
const providerClasses = await loadProviderClasses();
|
|
19203
19706
|
const logger = getLogger();
|
|
@@ -19418,6 +19921,7 @@ async function importCommand(stackArg, options) {
|
|
|
19418
19921
|
await recordImportOnRollbackJournal(stateBackend, stackInfo.stackName, targetRegion, importedRows.map((r) => r.logicalId), stackState.resources, logger);
|
|
19419
19922
|
await stateBackend.saveState(stackInfo.stackName, targetRegion, stackState, saveOptions);
|
|
19420
19923
|
logger.info(`✓ State written: ${stackInfo.stackName} (${targetRegion})`);
|
|
19924
|
+
await claimRegistryMarkerAfterImport(stateBackend, stackInfo.stackName, targetRegion, logger);
|
|
19421
19925
|
logger.info(` ${importedRows.length} resource(s) imported. Run 'cdkd diff' to see how the imported state lines up with the template.`);
|
|
19422
19926
|
if (migrationCfnStackName && migrationTree && accountIdForNestedSynth) await importNestedStackChildrenRecursive({
|
|
19423
19927
|
lockRecovery,
|
|
@@ -27745,4 +28249,4 @@ function collectVerbFlags(program) {
|
|
|
27745
28249
|
|
|
27746
28250
|
//#endregion
|
|
27747
28251
|
export { canonicalizeIpProtocolValue as a, buildProgram, resolveSecretDerivedPrincipals as i, runDestroyForStack as n, resolvedResourceTimeoutMs as o, isResolvableSecretPrincipalList as r, canonicalizeIpv4Cidr as t };
|
|
27748
|
-
//# sourceMappingURL=program-
|
|
28252
|
+
//# sourceMappingURL=program-CN7Dqb3j.js.map
|