@go-to-k/cdkd 0.296.28 → 0.296.30
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-B3zcS87C.js → asg-provider-BaabA371.js} +3 -3
- package/dist/{asg-provider-B3zcS87C.js.map → asg-provider-BaabA371.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-D4FdwPCi.js → deploy-engine-BuPc2Dfc.js} +1951 -60
- package/dist/deploy-engine-BuPc2Dfc.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-0U4kMuzh.js → iam-role-provider-CAiMUBcP.js} +3 -3
- package/dist/{iam-role-provider-0U4kMuzh.js.map → iam-role-provider-CAiMUBcP.js.map} +1 -1
- package/dist/index.d.ts +121 -55
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{neptune-provider-DF6Eh4Tl.js → neptune-provider-5yc_bOJ-.js} +3 -3
- package/dist/{neptune-provider-DF6Eh4Tl.js.map → neptune-provider-5yc_bOJ-.js.map} +1 -1
- package/dist/{program-v_QNBjtZ.js → program-CIxuz2zX.js} +557 -41
- package/dist/program-CIxuz2zX.js.map +1 -0
- package/dist/{provider-classes-wbKBBEol.js → provider-classes-DmZ0J68L.js} +216 -26
- package/dist/provider-classes-DmZ0J68L.js.map +1 -0
- package/dist/{rds-provider-BfQsw4hw.js → rds-provider-IBY6fDvN.js} +3 -3
- package/dist/{rds-provider-BfQsw4hw.js.map → rds-provider-IBY6fDvN.js.map} +1 -1
- package/dist/{version-B0JEGOLV.js → version-B__YmKBy.js} +2 -2
- package/dist/{version-B0JEGOLV.js.map → version-B__YmKBy.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-D4FdwPCi.js.map +0 -1
- package/dist/program-v_QNBjtZ.js.map +0 -1
- package/dist/provider-classes-wbKBBEol.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 prefetchCreateOnlyPropertyPaths, $i as refuseMalformedOutputs, $o as wholeStringLeavesOf, $r as getAccountInfo, $s as partitionSensitiveEnv, A as perType, Aa as NO_CC_HANDLERS_REASON, Ac as decodeListingKey, Ai as malformedLocalResourceEntriesWarning, An as buildFinalSnapshotIdentifier, Ao as shareLogOnlyValues, Ar as poisonRenderedSpellingsCollidingIn, As as rewriteTemplateAssetReferences, Bc as hasPlainPrototype, Bi as malformedResourceEntriesWarning, Bn as formatDestructiveChange, Bo as isUncertifiedBaselineMaskPosition, Br as AWS_CREDENTIAL_ENV_KEYS, Bs as validateContainerRepoName, Bt as planRollback, C as noEchoComparisonForTemplate, Ca as unreadableOrphanRecords, Cc as ssmResolvedValueType, Ci as hasReadableResources, Cn as maskEventTextWithBoundBags, Co as createUnionSecretMasker, Cs as AssetPublisher, Ct as isHandledOrphan, D as recordedProtectionNote, Dc as findLargeInlineResources, Di as malformedExportNamesWarning, Dn as extractDeploymentEventError, Do as printingCorpusOf, Dr as DiffCalculator, Ds as buildAssetRedirectMap, Dt as sameJournaledOrphans, E as recordedProtectionEvidence, Ea as findActionableSilentDrops, Ec as MIGRATE_TMP_PREFIX, Ei as malformedDriftResourcePropertiesWarning, En as stateSecretNameNeedles, Eo as logOnlyValueCount, Es as WorkGraph, Et as makeForeignHolderScan, Fa as isStatefulRecreateTargetForReplace, Fc as AssemblyReader, Fi as malformedOrphansRefusalMessage, Fn as refusesFinalSnapshot, Fo as markSameGenerationBag, Fr as assertFlagRoleArn, Fs as getBootstrapMarkerKey, Ft as recordAfterRollbackUpdate, Gc as displayAssemblyPath, Gi as previewableOrphanRecords, Gn as withCreateTokenLedger, Gs as describeDockerExecFailure, Gt as seedsDeleteFirstGuard, Hc as ownValue, Hi as malformedResourcesWarning, Ho as identityKeyFor, Hr as callerEnvCredentials, Hs as buildDockerImage, Ht as recordUnderIdIsNotOwn, Ia as isStatefulRecreateTargetSync, Ic as StageLoadError, Ii as malformedOrphansWarning, In as unsupportedFinalSnapshotError, Io as redactSecretsForState, Ir as assertSendableRoleArn, Is as isCrossRegionRedirect, It as demoteSupersededOrphans, Ji as refuseMalformedOrphanRecords, Jo as recordMaskOnlyValue, Js as finchSecretArgvRefusal, Kc as renderAssemblyPathEscape, Ki as refuseDivergentRecordRegionForDestroy, Ko as carriesSecretMask, Ks as describeDockerFailure, Kt as orphanDeleteNeedsIdentity, La as renderStatefulReason, Lc as processStackMessages, Li as malformedOutputsRefusalMessage, Ln as maskingRetryLogger, Lo as scrubResourceRecord, Lr as explicitRoleArnOrThrow, Ls as parseBootstrapMarker, Lt as isJournaledOrphan, Ma as findReplacedReadersOfRecreateTargets, Mc as PARTITION_TABLE, Mi as malformedOrphanRecordsRefusalMessage, Mn as createPreDeleteFinalSnapshot, Mo as errorCauseChain, Mr as producerRegionsFromState, Ms as BOOTSTRAP_MARKER_PREFIX, Na as shownType, Nc as canonicalizeRegion, Ni as malformedOrphanRecordsWarning, Nn as effectiveDeletionPolicy, No as maskSecretsInError, Nr as regionLessSecretName, Ns as assertAssetBucketRegion, Nt as withStackRecords, O as PROTECTION_PROPERTY_BY_TYPE, Oa as unwrittenCreateOnlyReplacement, Oc as uploadCfnTemplate, Oi as malformedExportSourceWarning, On as ATOMIC_FINAL_SNAPSHOT_TYPES, Oo as recordLogOnlyParameterValue, Or as INTRINSIC_KEYS, Os as createAssetRedirectResolver, Ot as replayFailedOperations, Pa as MULTI_REGION_RECREATE_BLOCKED_TYPES, Pc as derivePartitionAndUrlSuffix, Pi as malformedOrphanRowsKeptWarning, Pn as isFinalSnapshotError, Po as maskSecretsInText, Pr as applyRoleArnIfSet, Ps as ensureAssetStorage, Pt as removeProtectionTypeList, Q as cyan, Qi as refuseMalformedOrphansForOrphan, Qo as recordProvenPublicExpression, Qr as parameterTypeMayLoseSecretIdentity, Qs as isMalformedEnvKey, Rc as defineOwnKey, Ri as malformedOutputsWarning, Rn as constructPathOf, Ro as DYNAMIC_REFERENCE_TOKEN_SCAN, Rr as isIamRoleArn, Rs as readBootstrapMarkerBody, Rt as isReplacementOrphan, S as noEchoAttributeNamesOf, Sa as unpreviewableOrphanRecords, Sc as warnDeprecatedNoPrefixCliFlag, Si as hasReadableOutputs, Sn as journaledOrphanPrintingBag, So as carryLogOnlyValues, Ss as shouldRetainResource, St as dropFailedHint, T as noEchoParameterNamesOf, Ta as withheldAccountClause, Tc as CFN_TEMPLATE_URL_LIMIT, Ti as isReadableResourceEntry, Tn as secretNamePrintingBag, To as literalSplitDelimitersOf, Ts as stringifyValue, Tt as loadJournaledOrphans, Uc as absoluteAssemblyPathEscape, Ui as malformedScrubResourceEntriesRefusalMessage, Un as ledgerForStack, Uo as inheritNestedStackParameterAssociations, Ur as envCredentialsAreAssumedRole, Us as resolveDockerContextDirectory, Ut as replacementNeverSwapped, Vc as nullPrototypeRecord, Vi as malformedResourcePropertiesWarning, Vn as RollbackInlinePolicyWriters, Vo as pathCrossesDottedKey, Vr as applyCallerIdentityCredentials, Vs as buildDenyExternalAccessPolicy, Vt as recheckFailedPlan, Wc as describeFileReadFailure, Wi as malformedStateRefusalMessage, Wo as recordNestedStackParameterExpressions, Ws as describeDockerCapturedOutput, Wt as resolveReplacementOldType, X as createReadOnlyAttributeHealerFactory, Xi as refuseMalformedOrphans, Xo as recordNoEchoAttributeValues, Xr as coerceParameterTypedValue, Xs as getDockerCmd, Y as formatResourceLine, Yc as resolveBucketRegion, Yi as refuseMalformedOrphanRecordsForDestroy, Yo as recordMaskOnlyValuesIn, Ys as formatDockerLoginError, Yt as inheritProducerRegions, Z as bold, Zi as refuseMalformedOrphansForDestroy, Zo as recordNoEchoParameterFreshValue, Zr as isUnboundTemplateParameter, Zs as isDockerClientEnvKey, _ as makeCanonicalizePropertiesFn, _a as repairMalformedOrphansForReadOnly, _c as resolveSkipPrefix, _i as UNREADABLE_RESOURCES_MAP_ROW, _n as isExportAliasCollision, _r as deleteSkipReason, _s as importableOutputKeys, _t as revertedNestedRowIds, a as findNestedTemplateTreeDefect, aa as refuseMalformedResourceEntriesForImport, ac as escapeRegExp, ai as AWS_NO_VALUE, an as displayTextOrWithheld, ar as isCustomResource, as as isSingleDynamicReferenceToken, at as reachableDivergentParameters, b as serviceTokenBlockingReason, ba as repairMalformedResourcePropertiesForReadOnly, bc as resolveUseCdkBootstrapAssets, bi as displayLogicalId, bn as DEFAULT_RESOURCE_WARN_AFTER_MS, bo as valueAtCoordinate, bs as orphansAfterRollback, bt as withNestedStackContext, c as renderNestedTemplateTreeDefect, ca as refuseMalformedResourcePropertiesForDestroy, cc as getDockerImageBySourceHash, ci as refStateLookupFromResource, cn as secretBearingStateKeyWarning, co as canonicalCoordinates, cr as readsNoEchoDeleteValues, cs as S3StateBackend, ct as planOrphanAdoption, d as conditionInputsFrom, da as refuseMalformedResourcePropertiesForOrphan, dc as getDefaultStateBucketName, di as parameterInputsFor, dn as exportNameNoEchoParameters, do as maskReadbackAtCoordinates, dr as withPrintingSecrets, ds as acceptedCreateOnlyDropsOf, dt as displacedPhysicalIdShown, ea as refuseMalformedOutputsForDestroy, ec as redactDockerArgvValues, ei as isImpossibleEmptyStoredAttribute, en as updatePartialMessage, eo as templateResourceTypes, es as STATE_SOURCED_BASELINE_RULES, et as green, f as parentSuppliedValues, fa as refuseMalformedResourcesForDeploy, fc as getLegacyStateBucketName, fn as exportNameSecretExposure, fo as maskWholeValue, fr as CloudControlProvider, fs as describeRegionValueKind, ft as dropSettledNestedJournals, g as mergeNoChangeOutputs, ga as repairMalformedOrphanRecordsForReadOnly, gc as resolveCaptureObservedState, gi as UNREADABLE_ORPHANS_CONTAINER_ROW, gn as collectPublishedOutputNames, go as noEchoOutputsComparison, gr as deleteIndeterminateGuards, gs as hasUnverifiableParameterRefusal, h as keptWholeReasonText, ha as refuseMalformedState, hc as resolveAutoAssetStorage, hi as STATE_RESOURCES_MALFORMED, hn as collectDeclaredOutputNames, ho as noEchoLeavesOf, hr as UNSPECIFIED_SKIP_REASON, hs as hasReasonlessBaselineRefusal, ht as recordDisplacedSkips, i as childTemplateLoader, ia as refuseMalformedResourceEntriesForDestroy, ic as warnFinchArgvExposure, ii as keepsSecretReferenceToken, in as WITHHELD_NAME_DISPLAY, ir as ccBrokenReason, is as WHOLE_DYNAMIC_REFERENCE_PATTERN, it as namesAnyDeclaredParameter, j as readProtection, ja as hasNoCloudControlHandlers, jc as expectedOwnerParam, ji as malformedLocalResourcesWarning, jn as ccRoutedFinalSnapshotError, jo as createSecretMasker, jr as classifyReplaySecretRegion, js as AssetModeResolver, jt as destroyStackRecordsView, k as isProtectionValueActive, kc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, ki as malformedLocalOutputsWarning, kn as PRE_DELETE_SNAPSHOT_TYPES, ko as recordLogOnlyValue, kr as IntrinsicFunctionResolver, ks as loadPublishableAssetManifest, kt as replayRollback, l as templateIdentity, la as refuseMalformedResourcePropertiesForDrift, lc as Synthesizer, ln as secretSafeKeyDisplay, lo as isMarkedCoordinate, lr as isCustomResourceType$1, ls as rebuildClientForBucketRegion, lt as NESTED_PENDING_PARENT_REASON, m as isSecretBearingReferenceString, ma as refuseMalformedResourcesForExport, mc as resolveApp, mi as STATE_REGION_DIVERGED, mn as noEchoParameterValueSeed, mo as noEchoCoordinatesOf, ms as hasReadableExportSet, mt as nestedChildStackName$1, n as IMPLICIT_DELETE_DEPENDENCIES, na as refuseMalformedResourceEntries, nc as runDockerForeground, ni as carriesFetchableDynamicReference, nn as DeploymentEventsReader, no as withRetry, nr as CC_BROKEN_REASON, ns as STATE_SOURCED_READBACK_RULES, nt as yellow, o as isAbsoluteAssetPath, oa as refuseMalformedResourceEntriesForImportSave, oc as stripControlChars, oi as cfnRefValueFromPhysicalId, on as exportAliasCollisionScrubWarning, oo as DagBuilder, or as wouldReturnToSdkProvider, os as LockManager, ot as resourcesNamingDeclaredParameter, p as readRecordedConditionVerdicts, pa as refuseMalformedResourcesForDestroy, pc as loadCdkJson, pi as JSON_LISTING_HOLE_VALUE, pn as isWholeDynamicReferenceValue, po as maskedLeafCoordinatesOf, pr as slowCcOperationTimeoutMs, ps as exportNamesCarriedFrom, qc as resolveAssemblyPath, qo as provenPublicValue, qs as dockerSpawnEnvWithSensitive, qt as findNestedStackTypeChanges, r as computeImplicitDeleteEdges, ra as refuseMalformedResourceEntriesForDeploy, rc as runDockerStreaming, ri as isNamelessDynamicReferenceError, rn as DeploymentEventsStore, rr as ProviderRegistry, rs as TEMPLATE_SOURCED_RULES, rt as computeParameterTaint, s as listNestedTemplateRows, sa as refuseMalformedResourceEntriesForOrphan, sc as AssetManifestLoader, si as isStalePlaceholderArnAttribute, sn as secretBearing, so as TemplateParser, sr as TemplateNoEchoReresolver, ss as isLockInfoExpired, st as makeSiblingClaimReader, t as DeployEngine, ta as refuseMalformedResourceAttributesForOrphan, tc as redactedDockerCause, ti as carriesDynamicReference, tn as updatePartialReason, to as describeTypeWithThrottleRetry, ts as STATE_SOURCED_CROSS_GENERATION_RULES, tt as red, u as conditionFingerprint, ua as refuseMalformedResourcePropertiesForExport, uc as synthesisStatusMessage, ui as withSharedDrainBudget, un as carriedExportAliasExposure, uo as maskAtCoordinates, us as splitImportedOps, ut as displacedOpClause, v as deferredServiceTokenWarning, va as repairMalformedOutputsForReadOnly, vc as resolveStateBucketWithDefault, vi as accountArgs, vn as bindingSkippedOutputs, vo as readbackPathFor, vs as importableOutputs, vt as withNestedRevertRun, w as noEchoExactEchoLeavesOf, wa as unreadableResourceEntries, wc as CFN_TEMPLATE_BODY_LIMIT, wi as isReadableOrphanRecord, wn as orphanRecordsPrintingBag, wo as hasMaskableValues, ws as isSensitiveAttributeName, wt as journaledOrphanLines, x as withResourceDeadline, xa as repairMalformedResourcesForReadOnly, xc as stateBucketExistenceConfirmed, xi as hasReadableOrphans, xn as completedReplayEntries, xo as liveMatchesUnresolvedTokenFrame, xs as orphansCarriedFrom, xt as deleteJournaledOrphans, y as findServiceTokenRefusals, ya as repairMalformedResourceEntriesForReadOnly, yc as resolveStateBucketWithDefaultAndSource, yi as deployRefusesOrphanRowsReason, yn as DEFAULT_RESOURCE_TIMEOUT_MS, yo as readsNoEchoSource, yr as isWaitAbandonedError, ys as isReadableBag, zc as hasOwnKey, zi as malformedRenderedContainersWarning, zn as findDestructiveChanges, zo as dynamicReferenceTokens, zr as sendableAssumeRoleCommand, zs as validateAssetBucketName, zt as planFailedOps } from "./deploy-engine-D4FdwPCi.js";
|
|
6
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
+
import { $c as hasOwnKey, $i as previewableOrphanRecords, $s as validateAssetBucketName, $t as orphanDeleteNeedsIdentity, A as noEchoExactEchoLeavesOf, Aa as unpreviewableOrphanRecords, Ac as resolveCaptureObservedState, Ai as hasReadableOutputs, An as maskEventTextWithBoundBags, Ao as carryLogOnlyValues, As as hasUnverifiableParameterRefusal, At as isHandledOrphan, Ba as findReplacedReadersOfRecreateTargets, Bc as MIGRATE_TMP_PREFIX, Bi as malformedOrphanRecordsRefusalMessage, Bn as effectiveDeletionPolicy, Bo as errorCauseChain, Br as producerRegionsFromState, Bs as WorkGraph, Bt as withStackRecords, C as recordRetainedForReadoption, Ca as refuseMalformedState, Cc as Synthesizer, Ci as STATE_RESOURCES_MALFORMED, Cn as collectPublishedOutputNames, Co as noEchoLeavesOf, Cr as deleteIndeterminateGuards, Cs as isNotImplemented, Ct as revertedNestedRowIds, D as withResourceDeadline, Da as repairMalformedResourceEntriesForReadOnly, Dc as loadCdkJson, Di as deployRefusesOrphanRowsReason, Dn as DEFAULT_RESOURCE_WARN_AFTER_MS, Do as readsNoEchoSource, Dr as isWaitAbandonedError, Ds as exportNamesCarriedFrom, Dt as withNestedStackContext, E as serviceTokenBlockingReason, Ea as repairMalformedOutputsForReadOnly, Ec as getLegacyStateBucketName, Ei as accountArgs, En as DEFAULT_RESOURCE_TIMEOUT_MS, Eo as readbackPathFor, Es as describeRegionValueKind, F as isProtectionValueActive, Fc as stateBucketExistenceConfirmed, Fi as malformedExportNamesWarning, Fn as ATOMIC_FINAL_SNAPSHOT_TYPES, Fo as printingCorpusOf, Fr as DiffCalculator, Fs as orphansCarriedFrom, Ft as replayFailedOperations, Ga as renderStatefulReason, Gc as expectedOwnerParam, Gi as malformedOutputsRefusalMessage, Gn as constructPathOf, Go as scrubResourceRecord, Gr as explicitRoleArnOrThrow, Gs as AssetModeResolver, Gt as isReplacementOrphan, Ha as MULTI_REGION_RECREATE_BLOCKED_TYPES, Hc as uploadCfnTemplate, Hi as malformedOrphanRowsKeptWarning, Hn as refusesFinalSnapshot, Ho as maskSecretsInText, Hr as applyRoleArnIfSet, Hs as createAssetRedirectResolver, Ht as recordAfterRollbackUpdate, I as perType, Ia as unwrittenCreateOnlyReplacement, Ic as warnDeprecatedNoPrefixCliFlag, Ii as malformedExportSourceWarning, In as PRE_DELETE_SNAPSHOT_TYPES, Io as recordLogOnlyParameterValue, Ir as INTRINSIC_KEYS, Is as shouldRetainResource, It as replayRollback, Jc as derivePartitionAndUrlSuffix, Ji as malformedResourceEntriesWarning, Jn as RollbackInlinePolicyWriters, Jo as isUncertifiedBaselineMaskPosition, Jr as AWS_CREDENTIAL_ENV_KEYS, Js as ensureAssetStorage, Jt as recheckFailedPlan, Kc as PARTITION_TABLE, Ki as malformedOutputsWarning, Kn as findDestructiveChanges, Ko as DYNAMIC_REFERENCE_TOKEN_SCAN, Kr as isIamRoleArn, Ks as BOOTSTRAP_MARKER_PREFIX, Kt as planFailedOps, L as readProtection, Lc as ssmResolvedValueType, Li as malformedLocalOutputsWarning, Ln as buildFinalSnapshotIdentifier, Lo as recordLogOnlyValue, Lr as IntrinsicFunctionResolver, Ls as AssetPublisher, M as recordedProtectionEvidence, Ma as unreadableResourceEntries, Mc as resolveStateBucketWithDefault, Mi as isReadableOrphanRecord, Mn as secretNamePrintingBag, Mo as hasMaskableValues, Ms as importableOutputs, Mt as loadJournaledOrphans, N as recordedProtectionNote, Na as withheldAccountClause, Nc as resolveStateBucketWithDefaultAndSource, Ni as isReadableResourceEntry, Nn as stateSecretNameNeedles, No as literalSplitDelimitersOf, Ns as isReadableBag, Nt as makeForeignHolderScan, O as noEchoAttributeNamesOf, Oa as repairMalformedResourcePropertiesForReadOnly, Oc as resolveApp, Oi as displayLogicalId, On as completedReplayEntries, Oo as valueAtCoordinate, Os as hasReadableExportSet, Ot as deleteJournaledOrphans, P as PROTECTION_PROPERTY_BY_TYPE, Pa as findActionableSilentDrops, Pc as resolveUseCdkBootstrapAssets, Pi as malformedDriftResourcePropertiesWarning, Pn as extractDeploymentEventError, Po as logOnlyValueCount, Ps as orphansAfterRollback, Pt as sameJournaledOrphans, Qc as defineOwnKey, Qi as malformedStateRefusalMessage, Qn as withCreateTokenLedger, Qo as recordNestedStackParameterExpressions, Qs as readBootstrapMarkerBody, Qt as seedsDeleteFirstGuard, Ra as NO_CC_HANDLERS_REASON, Rc as CFN_TEMPLATE_BODY_LIMIT, Ri as malformedLocalResourceEntriesWarning, Rn as ccRoutedFinalSnapshotError, Ro as shareLogOnlyValues, Rr as poisonRenderedSpellingsCollidingIn, Rs as isSensitiveAttributeName, Rt as destroyStackRecordsView, S as keptForReadoption, Sa as refuseMalformedResourcesForExport, Sc as getDockerImageBySourceHash, Si as STATE_REGION_DIVERGED, Sn as collectDeclaredOutputNames, So as noEchoCoordinatesOf, Sr as UNSPECIFIED_SKIP_REASON, Ss as isAccessDenied, T as findServiceTokenRefusals, Ta as repairMalformedOrphansForReadOnly, Tc as getDefaultStateBucketName, Ti as UNREADABLE_RESOURCES_MAP_ROW, Tn as bindingSkippedOutputs, Tr as deleteSkipReason, Ts as acceptedCreateOnlyDropsOf, Tt as collectNestedChildUnaddressed, Ua as isStatefulRecreateTargetForReplace, Uc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Ui as malformedOrphansRefusalMessage, Un as unsupportedFinalSnapshotError, Uo as markSameGenerationBag, Ur as assertFlagRoleArn, Us as loadPublishableAssetManifest, Ut as demoteSupersededOrphans, Va as shownType, Vc as findLargeInlineResources, Vi as malformedOrphanRecordsWarning, Vn as isFinalSnapshotError, Vo as maskSecretsInError, Vr as regionLessSecretName, Vs as buildAssetRedirectMap, Vt as removeProtectionTypeList, Wa as isStatefulRecreateTargetSync, Wc as decodeListingKey, Wi as malformedOrphansWarning, Wn as maskingRetryLogger, Wo as redactSecretsForState, Wr as assertSendableRoleArn, Ws as rewriteTemplateAssetReferences, Wt as isJournaledOrphan, Xc as StageLoadError, Xi as malformedResourcesWarning, Xn as ledgerForStack, Xo as identityKeyFor, Xr as callerEnvCredentials, Xs as isCrossRegionRedirect, Xt as replacementNeverSwapped, Yc as AssemblyReader, Yi as malformedResourcePropertiesWarning, Yo as pathCrossesDottedKey, Yr as applyCallerIdentityCredentials, Ys as getBootstrapMarkerKey, Yt as recordUnderIdIsNotOwn, Zc as processStackMessages, Zi as malformedScrubResourceEntriesRefusalMessage, Zo as inheritNestedStackParameterAssociations, Zr as envCredentialsAreAssumedRole, Zs as parseBootstrapMarker, Zt as resolveReplacementOldType, _ as makeCanonicalizePropertiesFn, _a as refuseMalformedResourcePropertiesForDrift, _c as runDockerStreaming, _n as carriedExportAliasExposure, _o as isMarkedCoordinate, _s as rebuildClientForBucketRegion, _t as displacedPhysicalIdShown, a as findNestedTemplateTreeDefect, aa as refuseMalformedOrphansForDestroy, ac as describeDockerExecFailure, ai as isUnboundTemplateParameter, al as displayAssemblyPath, as as recordNoEchoParameterFreshValue, at as gray, ba as refuseMalformedResourcesForDeploy, bc as stripControlChars, bn as isWholeDynamicReferenceValue, bo as maskWholeValue, br as slowCcOperationTimeoutMs, bs as applyCrossPrefixScan, bt as nestedChildStackName$1, c as renderNestedTemplateTreeDefect, ca as refuseMalformedOutputsForDestroy, cc as finchSecretArgvRefusal, ci as isImpossibleEmptyStoredAttribute, cn as updatePartialReason, co as templateResourceTypes, cs as STATE_SOURCED_BASELINE_RULES, ct as yellow, d as conditionInputsFrom, da as refuseMalformedResourceEntriesForDeploy, dc as isDockerClientEnvKey, di as isNamelessDynamicReferenceError, dn as WITHHELD_NAME_DISPLAY, dr as ccBrokenReason, ds as TEMPLATE_SOURCED_RULES, dt as reachableDivergentParameters, ea as refuseDivergentRecordRegionForDestroy, ec as validateContainerRepoName, el as hasPlainPrototype, en as findNestedStackTypeChanges, es as carriesSecretMask, f as parentSuppliedValues, fa as refuseMalformedResourceEntriesForDestroy, fc as isMalformedEnvKey, fi as keepsSecretReferenceToken, fn as displayTextOrWithheld, fr as isCustomResource, fs as WHOLE_DYNAMIC_REFERENCE_PATTERN, ft as resourcesNamingDeclaredParameter, g as mergeNoChangeOutputs, ga as refuseMalformedResourcePropertiesForDestroy, gc as runDockerForeground, gi as refStateLookupFromResource, gn as secretSafeKeyDisplay, go as canonicalCoordinates, gr as isCustomResourceType$1, gs as S3StateBackend, gt as displacedOpClause, h as keptWholeReasonText, ha as refuseMalformedResourceEntriesForOrphan, hc as redactedDockerCause, hi as isStalePlaceholderArnAttribute, hn as secretBearingStateKeyWarning, ho as TemplateParser, hr as readsNoEchoDeleteValues, hs as isLockInfoExpired, ht as NESTED_PENDING_PARENT_REASON, i as childTemplateLoader, ia as refuseMalformedOrphans, ic as describeDockerCapturedOutput, ii as coerceParameterTypedValue, il as describeFileReadFailure, is as recordNoEchoAttributeValues, it as cyan, j as noEchoParameterNamesOf, ja as unreadableOrphanRecords, jc as resolveSkipPrefix, ji as hasReadableResources, jn as orphanRecordsPrintingBag, jo as createUnionSecretMasker, js as importableOutputKeys, jt as journaledOrphanLines, k as noEchoComparisonForTemplate, ka as repairMalformedResourcesForReadOnly, kc as resolveAutoAssetStorage, ki as hasReadableOrphans, kn as journaledOrphanPrintingBag, ko as liveMatchesUnresolvedTokenFrame, ks as hasReasonlessBaselineRefusal, kt as dropFailedHint, l as templateIdentity, la as refuseMalformedResourceAttributesForOrphan, lc as formatDockerLoginError, li as carriesDynamicReference, ll as resolveBucketRegion, ln as DeploymentEventsReader, lo as describeTypeWithThrottleRetry, lr as CC_BROKEN_REASON, ls as STATE_SOURCED_CROSS_GENERATION_RULES, lt as computeParameterTaint, m as isSecretBearingReferenceString, ma as refuseMalformedResourceEntriesForImportSave, mc as redactDockerArgvValues, mi as cfnRefValueFromPhysicalId, mn as secretBearing, mo as DagBuilder, mr as TemplateNoEchoReresolver, ms as LockManager, mt as planOrphanAdoption, n as IMPLICIT_DELETE_DEPENDENCIES, na as refuseMalformedOrphanRecords, nc as buildDockerImage, nl as ownValue, nn as inheritProducerRegions, ns as recordMaskOnlyValue, nt as createReadOnlyAttributeHealerFactory, o as isAbsoluteAssetPath, oa as refuseMalformedOrphansForOrphan, oc as describeDockerFailure, oi as parameterTypeMayLoseSecretIdentity, ol as renderAssemblyPathEscape, os as recordProvenPublicExpression, ot as green, p as readRecordedConditionVerdicts, pa as refuseMalformedResourceEntriesForImport, pc as partitionSensitiveEnv, pi as AWS_NO_VALUE, pn as exportAliasCollisionScrubWarning, pr as wouldReturnToSdkProvider, ps as isSingleDynamicReferenceToken, pt as makeSiblingClaimReader, qc as canonicalizeRegion, qi as malformedRenderedContainersWarning, qn as formatDestructiveChange, qo as dynamicReferenceTokens, qr as sendableAssumeRoleCommand, qs as assertAssetBucketRegion, qt as planRollback, r as computeImplicitDeleteEdges, ra as refuseMalformedOrphanRecordsForDestroy, rc as resolveDockerContextDirectory, rl as absoluteAssemblyPathEscape, rs as recordMaskOnlyValuesIn, rt as bold, s as listNestedTemplateRows, sa as refuseMalformedOutputs, sc as dockerSpawnEnvWithSensitive, si as getAccountInfo, sl as resolveAssemblyPath, sn as updatePartialMessage, so as prefetchCreateOnlyPropertyPaths, ss as wholeStringLeavesOf, st as red, t as DeployEngine, tc as buildDenyExternalAccessPolicy, tl as nullPrototypeRecord, ts as provenPublicValue, tt as formatResourceLine, u as conditionFingerprint, ua as refuseMalformedResourceEntries, uc as getDockerCmd, ui as carriesFetchableDynamicReference, un as DeploymentEventsStore, uo as withRetry, ur as ProviderRegistry, us as STATE_SOURCED_READBACK_RULES, ut as namesAnyDeclaredParameter, va as refuseMalformedResourcePropertiesForExport, vc as warnFinchArgvExposure, vi as withSharedDrainBudget, vn as exportNameNoEchoParameters, vo as maskAtCoordinates, vr as withPrintingSecrets, vs as CrossPrefixReadError, vt as dropSettledNestedJournals, w as deferredServiceTokenWarning, wa as repairMalformedOrphanRecordsForReadOnly, wc as synthesisStatusMessage, wi as UNREADABLE_ORPHANS_CONTAINER_ROW, wn as isExportAliasCollision, wo as noEchoOutputsComparison, wr as deleteLeftInPlace, ws as splitImportedOps, wt as withNestedRevertRun, xa as refuseMalformedResourcesForDestroy, xc as AssetManifestLoader, xi as JSON_LISTING_HOLE_VALUE, xn as noEchoParameterValueSeed, xo as maskedLeafCoordinatesOf, xs as crossPrefixDeniedWarning, xt as recordDisplacedSkips, ya as refuseMalformedResourcePropertiesForOrphan, yc as escapeRegExp, yi as parameterInputsFor, yn as exportNameSecretExposure, yo as maskReadbackAtCoordinates, yr as CloudControlProvider, ys as CrossPrefixScanCache, za as hasNoCloudControlHandlers, zc as CFN_TEMPLATE_URL_LIMIT, zi as malformedLocalResourcesWarning, zn as createPreDeleteFinalSnapshot, zo as createSecretMasker, zr as classifyReplaySecretRegion, zs as stringifyValue } from "./deploy-engine-BuPc2Dfc.js";
|
|
6
|
+
import { t as getCdkdVersion } from "./version-B__YmKBy.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-DmZ0J68L.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() {
|
|
@@ -10744,19 +11029,40 @@ async function acquireStackLock(opts) {
|
|
|
10744
11029
|
get interrupted() {
|
|
10745
11030
|
return interrupted;
|
|
10746
11031
|
},
|
|
10747
|
-
async release({ failureMessage, beforeRelease }) {
|
|
11032
|
+
async release({ failureMessage, beforeRelease, holdUntil }) {
|
|
10748
11033
|
if (released) return;
|
|
10749
11034
|
released = true;
|
|
10750
|
-
|
|
10751
|
-
await beforeRelease?.();
|
|
11035
|
+
const releaseNow = async () => {
|
|
10752
11036
|
try {
|
|
10753
11037
|
await lockManager.releaseLock(stackName, region);
|
|
10754
11038
|
lockHeld = false;
|
|
10755
11039
|
} catch (releaseErr) {
|
|
10756
11040
|
getLogger().warn(safeMsg`${failureMessage}: ${describeAwsFailure(releaseErr).detail}`);
|
|
10757
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();
|
|
10758
11064
|
} finally {
|
|
10759
|
-
process.removeListener("SIGINT", sigintHandler);
|
|
11065
|
+
if (!deferred) process.removeListener("SIGINT", sigintHandler);
|
|
10760
11066
|
}
|
|
10761
11067
|
}
|
|
10762
11068
|
};
|
|
@@ -10864,6 +11170,16 @@ function countProtectedJournaledOrphans(orphans, region) {
|
|
|
10864
11170
|
}
|
|
10865
11171
|
return count;
|
|
10866
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
|
+
}
|
|
10867
11183
|
async function runDestroyForStack(stackName, state, ctx) {
|
|
10868
11184
|
const providerClasses = await loadProviderClasses();
|
|
10869
11185
|
const logger = getLogger();
|
|
@@ -10875,11 +11191,16 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
10875
11191
|
retainedCount: 0,
|
|
10876
11192
|
skippedCount: 0,
|
|
10877
11193
|
guardIndeterminateCount: 0,
|
|
11194
|
+
journaledOrphanSkips: 0,
|
|
11195
|
+
stateDeleted: false,
|
|
10878
11196
|
errorCount: 0,
|
|
10879
11197
|
interrupted: false
|
|
10880
11198
|
};
|
|
11199
|
+
const retainedForReadoption = [];
|
|
11200
|
+
let retainedEarlier;
|
|
10881
11201
|
const guardIndeterminateTargets = /* @__PURE__ */ new Set();
|
|
10882
11202
|
const regionForState = state.region ?? ctx.baseRegion;
|
|
11203
|
+
const crossPrefixScan = ctx.crossPrefixCheck?.cache.full(stackName, regionForState);
|
|
10883
11204
|
const refusalRecovery = {
|
|
10884
11205
|
profile: ctx.profile,
|
|
10885
11206
|
stateBucket: ctx.stateBucket,
|
|
@@ -10902,6 +11223,15 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
10902
11223
|
const resourceCount = Object.keys(state.resources).length;
|
|
10903
11224
|
const orphanCount = (state.orphans ?? []).length;
|
|
10904
11225
|
refuseMalformedOutputsForDestroy(state, stackName, regionForState, refusalRecovery);
|
|
11226
|
+
if (crossPrefixScan) applyCrossPrefixScan(await crossPrefixScan, {
|
|
11227
|
+
stackName,
|
|
11228
|
+
region: regionForState,
|
|
11229
|
+
bucket: ctx.stateBucket,
|
|
11230
|
+
recovery: {
|
|
11231
|
+
profile: ctx.profile,
|
|
11232
|
+
stateBucket: ctx.stateBucket
|
|
11233
|
+
}
|
|
11234
|
+
}, "destroy", (message) => logger.warn(message), (message) => logger.info(message));
|
|
10905
11235
|
if (resourceCount === 0 && orphanCount === 0 && journaledOrphans.count === 0) {
|
|
10906
11236
|
logger.info(`Stack ${displayStackName(stackName)} has no resources, cleaning up state...`);
|
|
10907
11237
|
const emptyLock = await acquireStackLock({
|
|
@@ -10924,7 +11254,9 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
10924
11254
|
if (recheckJournaled > 0) throw new Error(`Stack ${displayStackName(stackName)} (${displaySafe(regionForState, { asciiOnly: true })}) was empty when this run started but its rollback journal now records ${recheckJournaled} resource(s) a failed deploy created — another cdkd process wrote to it. Re-run the destroy to act on the current state.`);
|
|
10925
11255
|
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.`);
|
|
10926
11256
|
await ctx.stateBackend.deleteState(stackName, regionForState);
|
|
11257
|
+
result.stateDeleted = true;
|
|
10927
11258
|
logger.info(`${green("✓")} State deleted`);
|
|
11259
|
+
await Promise.all([recordRetainedForReadoption(ctx.stateBackend, stackName, regionForState, [], logger), releaseRegistryMarkerAfterDestroy(ctx, stackName, regionForState, logger)]);
|
|
10928
11260
|
} finally {
|
|
10929
11261
|
await emptyLock.release({ failureMessage: "Failed to release lock after empty-state cleanup" });
|
|
10930
11262
|
}
|
|
@@ -11012,11 +11344,13 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11012
11344
|
}
|
|
11013
11345
|
const renderer = getLiveRenderer();
|
|
11014
11346
|
let statePreserved = false;
|
|
11347
|
+
let heldTail;
|
|
11348
|
+
let stackFinished = false;
|
|
11015
11349
|
let journaledOrphanFailures = 0;
|
|
11016
|
-
let journaledOrphanSkips = 0;
|
|
11017
11350
|
const lock = await acquireStackLock({
|
|
11018
11351
|
...stackLockBase,
|
|
11019
11352
|
onFirstSignal: () => {
|
|
11353
|
+
if (stackFinished) return;
|
|
11020
11354
|
renderer.printAbove(() => {
|
|
11021
11355
|
process.stderr.write("\nInterrupted — finishing in-flight deletes, then flushing state and releasing the lock (press Ctrl-C again to force-quit)...\n");
|
|
11022
11356
|
});
|
|
@@ -11114,7 +11448,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11114
11448
|
result.errorCount += orphanOutcome.failures;
|
|
11115
11449
|
journaledOrphanFailures = orphanOutcome.failures;
|
|
11116
11450
|
result.skippedCount += orphanOutcome.skipped;
|
|
11117
|
-
journaledOrphanSkips
|
|
11451
|
+
result.journaledOrphanSkips += orphanOutcome.skipped;
|
|
11118
11452
|
if (orphanOutcome.handled.length > 0) try {
|
|
11119
11453
|
await ctx.stateBackend.dropRollbackJournalFailedOperations(stackName, regionForState, (op, segment) => isHandledOrphan(orphanOutcome.handled, segment, op));
|
|
11120
11454
|
} catch (stripError) {
|
|
@@ -11190,6 +11524,17 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11190
11524
|
if (shouldRetainResource(resource.deletionPolicy)) {
|
|
11191
11525
|
logger.info(` ⊘ ${displaySafe(logicalId)} (${displaySafe(resource.resourceType)}) retained — DeletionPolicy: ${displaySafe(resource.deletionPolicy)}`);
|
|
11192
11526
|
result.retainedCount++;
|
|
11527
|
+
if (keptForReadoption(resource)) {
|
|
11528
|
+
retainedForReadoption.push({
|
|
11529
|
+
logicalId,
|
|
11530
|
+
resourceType: resource.resourceType,
|
|
11531
|
+
physicalId: resource.physicalId
|
|
11532
|
+
});
|
|
11533
|
+
if (retainedEarlier === void 0) {
|
|
11534
|
+
retainedEarlier = Promise.resolve().then(() => ctx.stateBackend.loadRetainedRecord(stackName, regionForState));
|
|
11535
|
+
retainedEarlier.catch(() => void 0);
|
|
11536
|
+
}
|
|
11537
|
+
}
|
|
11193
11538
|
recordDestroyEvent(ctx.eventRecorder, {
|
|
11194
11539
|
eventType: "RESOURCE_RETAINED",
|
|
11195
11540
|
stackName,
|
|
@@ -11247,6 +11592,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11247
11592
|
const slowTypeMinTimeoutMs = slowCcOperationTimeoutMs(resource.resourceType, "DELETE");
|
|
11248
11593
|
const timeoutMs = ctx.resourceTimeoutByType?.[resource.resourceType] ?? Math.max(providerMinTimeoutMs, slowTypeMinTimeoutMs, globalTimeoutMs);
|
|
11249
11594
|
let deleteResult;
|
|
11595
|
+
let childLeftInAws = 0;
|
|
11250
11596
|
const secretPrincipalOptIn = secretPrincipalRegions !== void 0 ? {
|
|
11251
11597
|
importedProducerRegions: secretPrincipalRegions,
|
|
11252
11598
|
retryMemo: { detached: /* @__PURE__ */ new Set() }
|
|
@@ -11256,7 +11602,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11256
11602
|
const noEchoDeleteValues = readsNoEchoDeleteValues(resource.resourceType) ? await ctx.noEchoReresolver?.valuesFor(logicalId, resource) : void 0;
|
|
11257
11603
|
let lastDeleteError;
|
|
11258
11604
|
for (let attempt = 0; attempt <= maxAttempts; attempt++) try {
|
|
11259
|
-
|
|
11605
|
+
const { value: outcome, unaddressed } = await runDeleteAttempt(attempt >= maxAttempts, () => collectNestedChildUnaddressed(() => withStackRecords(destroyStackRecordsView(state.resources), () => provider.delete(logicalId, resource.physicalId, resource.resourceType, resource.properties, {
|
|
11260
11606
|
...state.region !== void 0 && { expectedRegion: state.region },
|
|
11261
11607
|
...ctx.removeProtection === true && { removeProtection: true },
|
|
11262
11608
|
...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier },
|
|
@@ -11268,7 +11614,9 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11268
11614
|
...noEchoDeleteValues !== void 0 && { noEchoDeleteValues },
|
|
11269
11615
|
...ctx.noEchoReresolver !== void 0 && { noEchoReresolver: ctx.noEchoReresolver },
|
|
11270
11616
|
...ctx.stackDestroy === true && { stackDestroy: true }
|
|
11271
|
-
})))
|
|
11617
|
+
}))));
|
|
11618
|
+
deleteResult = outcome ?? void 0;
|
|
11619
|
+
childLeftInAws = unaddressed?.deleteSkipped ?? 0;
|
|
11272
11620
|
lastDeleteError = null;
|
|
11273
11621
|
break;
|
|
11274
11622
|
} catch (retryError) {
|
|
@@ -11326,7 +11674,11 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11326
11674
|
});
|
|
11327
11675
|
return;
|
|
11328
11676
|
}
|
|
11329
|
-
|
|
11677
|
+
const leftInAws = childLeftInAws > 0 ? deleteLeftInPlace(deleteResult) ?? `${childLeftInAws} resource(s) a failed deploy created were left in AWS` : void 0;
|
|
11678
|
+
const deletedLine = leftInAws !== void 0 ? formatResourceLine("skipped", logicalId, resource.resourceType, `deleted (${leftInAws})`) : formatResourceLine("deleted", logicalId, resource.resourceType);
|
|
11679
|
+
logger.info(` ${deletedLine}`);
|
|
11680
|
+
result.skippedCount += childLeftInAws;
|
|
11681
|
+
result.journaledOrphanSkips += childLeftInAws;
|
|
11330
11682
|
result.deletedCount++;
|
|
11331
11683
|
recordDestroyEvent(ctx.eventRecorder, {
|
|
11332
11684
|
eventType: "RESOURCE_SUCCEEDED",
|
|
@@ -11338,6 +11690,16 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11338
11690
|
...resource.physicalId && { physicalId: resource.physicalId },
|
|
11339
11691
|
durationMs: Date.now() - resourceStartedAt
|
|
11340
11692
|
});
|
|
11693
|
+
if (leftInAws !== void 0) recordDestroyEvent(ctx.eventRecorder, {
|
|
11694
|
+
eventType: "RESOURCE_SKIPPED",
|
|
11695
|
+
stackName,
|
|
11696
|
+
operation: "DELETE",
|
|
11697
|
+
logicalId,
|
|
11698
|
+
resourceType: resource.resourceType,
|
|
11699
|
+
...resource.provisionedBy && { provisionedBy: resource.provisionedBy },
|
|
11700
|
+
reason: leftInAws,
|
|
11701
|
+
durationMs: Date.now() - resourceStartedAt
|
|
11702
|
+
});
|
|
11341
11703
|
delete remainingResources[logicalId];
|
|
11342
11704
|
persistStateAfterDelete(logicalId);
|
|
11343
11705
|
} catch (error) {
|
|
@@ -11396,12 +11758,22 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11396
11758
|
}
|
|
11397
11759
|
result.interrupted = lock.interrupted;
|
|
11398
11760
|
await saveChain;
|
|
11399
|
-
const preserveState = result.errorCount > 0 || result.interrupted || result.skippedCount > journaledOrphanSkips;
|
|
11761
|
+
const preserveState = result.errorCount > 0 || result.interrupted || result.skippedCount > result.journaledOrphanSkips;
|
|
11400
11762
|
statePreserved = preserveState;
|
|
11401
11763
|
if (!preserveState) {
|
|
11402
11764
|
await ctx.stateBackend.deleteState(stackName, regionForState);
|
|
11765
|
+
result.stateDeleted = true;
|
|
11403
11766
|
logger.debug("State deleted");
|
|
11404
|
-
|
|
11767
|
+
const writeKept = () => recordRetainedForReadoption(ctx.stateBackend, stackName, regionForState, retainedForReadoption, logger, retainedEarlier);
|
|
11768
|
+
const releaseMarker = () => releaseRegistryMarkerAfterDestroy(ctx, stackName, regionForState, logger);
|
|
11769
|
+
if (ctx.deferRegistryTail !== void 0) {
|
|
11770
|
+
heldTail = writeKept().then(releaseMarker);
|
|
11771
|
+
await ctx.exportIndexStore?.removeStack(stackName, regionForState);
|
|
11772
|
+
} else await Promise.all([
|
|
11773
|
+
writeKept(),
|
|
11774
|
+
releaseMarker(),
|
|
11775
|
+
ctx.exportIndexStore?.removeStack(stackName, regionForState)
|
|
11776
|
+
]);
|
|
11405
11777
|
} else {
|
|
11406
11778
|
try {
|
|
11407
11779
|
await ctx.stateBackend.saveState(stackName, regionForState, buildDestroySnapshot());
|
|
@@ -11410,7 +11782,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11410
11782
|
}
|
|
11411
11783
|
if (result.interrupted) logger.warn(`Destroy interrupted — ${Object.keys(remainingResources).length} resource(s) not deleted. State preserved.`);
|
|
11412
11784
|
else if (result.errorCount > 0) logger.warn(`${result.errorCount} resource(s) failed to delete` + (journaledOrphanFailures > 0 ? ` (${journaledOrphanFailures} of them recorded only in the rollback journal)` : "") + `. State preserved.`);
|
|
11413
|
-
else logger.warn(`${result.skippedCount} resource(s) skipped — cdkd did not confirm they were deleted, so they may still exist in AWS. State preserved (the records are kept so the resources stay traceable).`);
|
|
11785
|
+
else logger.warn(`${result.skippedCount - result.journaledOrphanSkips} resource(s) skipped — cdkd did not confirm they were deleted, so they may still exist in AWS. State preserved (the records are kept so the resources stay traceable).`);
|
|
11414
11786
|
}
|
|
11415
11787
|
const retainedSuffix = result.retainedCount > 0 ? `, ${result.retainedCount} retained` : "";
|
|
11416
11788
|
const skippedSuffix = result.skippedCount > 0 ? `, ${yellow(result.skippedCount)} skipped` : "";
|
|
@@ -11424,9 +11796,9 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11424
11796
|
const durablePointer = ctx.eventRecorder === void 0 ? "This summary is the only record: this run wrote no deployment events, because it destroyed a nested-stack child, which threads no event recorder." : "The RESOURCE_GUARD_INDETERMINATE entries name the check and the reason and survive the run." + withheldTargetClause(eventsCommand, "stack", "cdkd events", "This stack's name") + `\nRead them with: ${eventsCommand.command}`;
|
|
11425
11797
|
logger.warn(`\n${yellow("⚠")} ${result.guardIndeterminateCount} pre-flight safety check(s) could NOT be completed during this destroy and cdkd proceeded anyway: ${[...guardIndeterminateTargets].map((t) => plainOrDescribed(t, "logical id")).join(", ")}. A check can be suppressed by DENYING the permission it needs, so treat this as unconfirmed rather than benign. ${durablePointer}`);
|
|
11426
11798
|
}
|
|
11427
|
-
if (journaledOrphanSkips > 0) logger.warn(safeMsg`${journaledOrphanSkips} resource(s) a failed deploy created were left in AWS (each named in a ` + "warning above, which says what to do with it). This stack no longer records them.");
|
|
11799
|
+
if (result.journaledOrphanSkips > 0) logger.warn(safeMsg`${result.journaledOrphanSkips} resource(s) a failed deploy created were left in AWS (each named in a ` + "warning above, which says what to do with it). This stack no longer records them.");
|
|
11428
11800
|
if (!preserveState) {
|
|
11429
|
-
const leftInAws = journaledOrphanSkips > 0;
|
|
11801
|
+
const leftInAws = result.journaledOrphanSkips > 0;
|
|
11430
11802
|
logger.info(`\n${leftInAws ? yellow("⚠") : green("✓")} ${bold(`Stack ${plainOrDescribed(stackName, "stack name")} ${leftInAws ? "destroyed, with resources left in AWS" : "destroyed"}`)} (${green(result.deletedCount)} deleted${retainedSuffix}${leftInAws ? skippedSuffix : ""}${guardSuffix}, ${result.errorCount} errors)`);
|
|
11431
11803
|
} else if (result.interrupted && result.errorCount === 0) logger.warn(`\n${yellow("⚠")} ${bold(`Stack ${plainOrDescribed(stackName, "stack name")} destroy interrupted`)} (${green(result.deletedCount)} deleted${retainedSuffix}${skippedSuffix}${guardSuffix}, ${result.errorCount} errors). State preserved — re-run 'cdkd destroy' / 'cdkd state destroy' to finish.`);
|
|
11432
11804
|
else if (result.errorCount === 0) {
|
|
@@ -11448,6 +11820,10 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11448
11820
|
try {
|
|
11449
11821
|
await lock.release({
|
|
11450
11822
|
failureMessage: `Failed to release lock for stack ${displayStackName(stackName)}`,
|
|
11823
|
+
...heldTail !== void 0 && ctx.deferRegistryTail !== void 0 && { holdUntil: {
|
|
11824
|
+
work: heldTail,
|
|
11825
|
+
defer: ctx.deferRegistryTail
|
|
11826
|
+
} },
|
|
11451
11827
|
beforeRelease: async () => {
|
|
11452
11828
|
try {
|
|
11453
11829
|
renderer.stop();
|
|
@@ -11458,6 +11834,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
11458
11834
|
logger.debug("Releasing lock...");
|
|
11459
11835
|
}
|
|
11460
11836
|
});
|
|
11837
|
+
stackFinished = true;
|
|
11461
11838
|
} finally {
|
|
11462
11839
|
restoreBaseRegionAndClients();
|
|
11463
11840
|
}
|
|
@@ -11486,6 +11863,15 @@ async function scanActiveConsumers(producerStack, producerRegion, ctx) {
|
|
|
11486
11863
|
}))).filter((r) => r !== null).flat();
|
|
11487
11864
|
}
|
|
11488
11865
|
|
|
11866
|
+
//#endregion
|
|
11867
|
+
//#region src/cli/commands/destroy-skip-message.ts
|
|
11868
|
+
function skippedDestroyMessage(totalSkipped, totalOrphanSkips, rerunCommand) {
|
|
11869
|
+
const recordSkips = totalSkipped - totalOrphanSkips;
|
|
11870
|
+
const orphanSentence = `${totalOrphanSkips} resource(s) a failed deploy created were left in AWS, and no state records them any more. The warning naming each says what to do with it.`;
|
|
11871
|
+
if (recordSkips <= 0) return `Destroy finished, but ${orphanSentence}`;
|
|
11872
|
+
return `Destroy skipped ${recordSkips} entr${recordSkips === 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 '${rerunCommand}'; 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>'.` + (totalOrphanSkips > 0 ? ` Separately, ${orphanSentence}` : "");
|
|
11873
|
+
}
|
|
11874
|
+
|
|
11489
11875
|
//#endregion
|
|
11490
11876
|
//#region src/cli/commands/destroy.ts
|
|
11491
11877
|
function orderConsumersBeforeProducers(stackNames, consumerToProducers) {
|
|
@@ -11508,6 +11894,10 @@ function orderConsumersBeforeProducers(stackNames, consumerToProducers) {
|
|
|
11508
11894
|
}
|
|
11509
11895
|
return ordered;
|
|
11510
11896
|
}
|
|
11897
|
+
function plannedDestroyRegion(refs, synthRegion, cliRegion) {
|
|
11898
|
+
if (refs.length === 1) return refs[0]?.region || cliRegion;
|
|
11899
|
+
if (refs.length > 1 && synthRegion && refs.some((r) => r.region === synthRegion)) return synthRegion;
|
|
11900
|
+
}
|
|
11511
11901
|
async function purgeEventsAfterDestroy(reader, stackName, region, opts, logger) {
|
|
11512
11902
|
if (opts.purgeEvents !== true || opts.runResult !== "SUCCEEDED" || opts.interrupted) return null;
|
|
11513
11903
|
try {
|
|
@@ -11565,6 +11955,9 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11565
11955
|
interruptWatch.dispose();
|
|
11566
11956
|
throw error;
|
|
11567
11957
|
}
|
|
11958
|
+
let stateBackendForCleanup;
|
|
11959
|
+
const deferredTails = [];
|
|
11960
|
+
let deferRegistryTail;
|
|
11568
11961
|
try {
|
|
11569
11962
|
const stateConfig = {
|
|
11570
11963
|
bucket: stateBucket,
|
|
@@ -11574,6 +11967,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11574
11967
|
...options.region && { region: options.region },
|
|
11575
11968
|
...options.profile && { profile: options.profile }
|
|
11576
11969
|
});
|
|
11970
|
+
stateBackendForCleanup = stateBackend;
|
|
11577
11971
|
await stateBackend.verifyBucketExists();
|
|
11578
11972
|
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
11579
11973
|
const exportIndexStore = new ExportIndexStore(awsClients.s3, stateBucket, options.statePrefix, region, stateBackend, { profile: options.profile });
|
|
@@ -11650,6 +12044,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11650
12044
|
} else throw new CdkdError("Could not determine which stacks belong to this app. Specify stack names explicitly, or ensure --app / cdk.json is configured.", "DESTROY_NO_STACK_SELECTED", synthError);
|
|
11651
12045
|
let totalErrors = 0;
|
|
11652
12046
|
let totalSkipped = 0;
|
|
12047
|
+
let totalOrphanSkips = 0;
|
|
11653
12048
|
let interrupted = false;
|
|
11654
12049
|
const runInterrupted = () => interrupted || interruptWatch.interrupted();
|
|
11655
12050
|
let stoppedEarly = false;
|
|
@@ -11716,6 +12111,14 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11716
12111
|
arr.push(ref);
|
|
11717
12112
|
stateRefsByName.set(ref.stackName, arr);
|
|
11718
12113
|
}
|
|
12114
|
+
const crossPrefixCheck = { cache: new CrossPrefixGuard(stateBackend) };
|
|
12115
|
+
if (stackNames.length > 1) deferRegistryTail = (released) => deferredTails.push(released);
|
|
12116
|
+
for (const name of stackNames) {
|
|
12117
|
+
const synth = appStacks.find((s) => s.stackName === name);
|
|
12118
|
+
if (synth?.terminationProtection === true && !options.removeProtection) continue;
|
|
12119
|
+
const planned = plannedDestroyRegion(stateRefsByName.get(name) ?? [], synth?.region, region);
|
|
12120
|
+
if (planned !== void 0) crossPrefixCheck.cache.full(name, planned, "prestart");
|
|
12121
|
+
}
|
|
11719
12122
|
for (const [stackIndex, stackName] of stackNames.entries()) {
|
|
11720
12123
|
logger.info(`\nPreparing to destroy stack: ${displaySafe(stackName)}`);
|
|
11721
12124
|
const refs = stateRefsByName.get(stackName) ?? [];
|
|
@@ -11733,15 +12136,12 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11733
12136
|
continue;
|
|
11734
12137
|
}
|
|
11735
12138
|
}
|
|
12139
|
+
const plannedRegion = plannedDestroyRegion(refs, synthRegion, region);
|
|
11736
12140
|
let stackTargetRegion;
|
|
11737
12141
|
if (refs.length === 0) {
|
|
11738
12142
|
logger.warn(`No state found for stack ${displaySafe(stackName)}, skipping`);
|
|
11739
12143
|
continue;
|
|
11740
|
-
} else if (
|
|
11741
|
-
const onlyRegion = refs[0]?.region;
|
|
11742
|
-
if (!onlyRegion) stackTargetRegion = region;
|
|
11743
|
-
else stackTargetRegion = onlyRegion;
|
|
11744
|
-
} else if (synthRegion && refs.some((r) => r.region === synthRegion)) stackTargetRegion = synthRegion;
|
|
12144
|
+
} else if (plannedRegion !== void 0) stackTargetRegion = plannedRegion;
|
|
11745
12145
|
else {
|
|
11746
12146
|
const regions = refs.map((r) => r.region === void 0 ? "(legacy)" : plainOrDescribed(r.region, "region")).join(", ");
|
|
11747
12147
|
const orphanOneClause = withheldAccountClause(accountRecovery, "the command below prints").trimEnd();
|
|
@@ -11819,6 +12219,8 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11819
12219
|
skipFinalSnapshot: options.skipFinalSnapshot === true,
|
|
11820
12220
|
resolveSecretDerivedPrincipals: {},
|
|
11821
12221
|
stackDestroy: true,
|
|
12222
|
+
crossPrefixCheck,
|
|
12223
|
+
...deferRegistryTail !== void 0 && { deferRegistryTail },
|
|
11822
12224
|
exportIndexStore,
|
|
11823
12225
|
...TemplateNoEchoReresolver.usable(synthStack?.template) && (synthStack.region === void 0 || synthStack.region === stackTargetRegion) && { noEchoReresolver: new TemplateNoEchoReresolver({
|
|
11824
12226
|
template: synthStack.template,
|
|
@@ -11835,6 +12237,7 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11835
12237
|
})));
|
|
11836
12238
|
totalErrors += result.errorCount;
|
|
11837
12239
|
totalSkipped += result.skippedCount;
|
|
12240
|
+
totalOrphanSkips += result.journaledOrphanSkips;
|
|
11838
12241
|
stackInterrupted = result.interrupted;
|
|
11839
12242
|
stackCancelled = result.cancelled === true;
|
|
11840
12243
|
if (result.interrupted) interrupted = true;
|
|
@@ -11870,11 +12273,13 @@ async function destroyCommand(stackArgs, options) {
|
|
|
11870
12273
|
}
|
|
11871
12274
|
if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd destroy' to retry. If the same resource keeps failing, 'cdkd state orphan <stack> --stack-region <region>' removes the stack's state in that region (every resource's record) without deleting AWS resources.`);
|
|
11872
12275
|
if (interrupted || interruptWatch.interrupted() && stoppedEarly) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd destroy' to finish.`);
|
|
11873
|
-
if (totalSkipped > 0) throw new PartialFailureError(
|
|
12276
|
+
if (totalSkipped > 0) throw new PartialFailureError(skippedDestroyMessage(totalSkipped, totalOrphanSkips, "cdkd destroy"));
|
|
11874
12277
|
} finally {
|
|
12278
|
+
await Promise.allSettled(deferredTails);
|
|
11875
12279
|
unforwardSigterm();
|
|
11876
12280
|
interruptWatch.dispose();
|
|
11877
12281
|
awsClients.destroy();
|
|
12282
|
+
stateBackendForCleanup?.destroyClient();
|
|
11878
12283
|
}
|
|
11879
12284
|
}
|
|
11880
12285
|
function createDestroyCommand() {
|
|
@@ -14022,7 +14427,7 @@ async function exportCommand(stackArg, options) {
|
|
|
14022
14427
|
2. Re-run the phase 2 UPDATE manually with the full synth template:
|
|
14023
14428
|
${phase2RetryCommand(cfnStackName)}\n 3. Once phase 2 succeeds, clean up cdkd's stale state record.${orphan.note}\n Run: ${orphan.command}`);
|
|
14024
14429
|
}
|
|
14025
|
-
await stateBackend
|
|
14430
|
+
await removeExportedStackRecord(stateBackend, resolvedStackName, targetRegion, logger);
|
|
14026
14431
|
logger.info(`cdkd state for ${quotedOrNotShown(resolvedStackName)} (${quotedRegion(targetRegion)}) removed. Manage the stack with 'cdk deploy' or 'aws cloudformation' from here on.`);
|
|
14027
14432
|
printNextSteps({
|
|
14028
14433
|
cfnStackName,
|
|
@@ -15626,6 +16031,11 @@ async function buildResolvedParametersPerStack(args) {
|
|
|
15626
16031
|
intrinsicSkippedByCdkdName
|
|
15627
16032
|
};
|
|
15628
16033
|
}
|
|
16034
|
+
async function removeExportedStackRecord(stateBackend, stackName, region, logger) {
|
|
16035
|
+
await stateBackend.deleteState(stackName, region);
|
|
16036
|
+
await recordRetainedForReadoption(stateBackend, stackName, region, [], logger);
|
|
16037
|
+
await releaseRegistryMarkerQuietly(stateBackend, stackName, region, logger);
|
|
16038
|
+
}
|
|
15629
16039
|
async function runPerStackImportLoop(args) {
|
|
15630
16040
|
const logger = getLogger();
|
|
15631
16041
|
const { rootStackName, rootRegion, rootStackInfoNestedTemplates, rootTemplateFormat, tree, rootTemplate, cfnStackNameOverrides, rootParameters, deps, options } = args;
|
|
@@ -15903,7 +16313,7 @@ async function runPerStackImportLoop(args) {
|
|
|
15903
16313
|
}
|
|
15904
16314
|
const stateDeletionFailures = [];
|
|
15905
16315
|
for (const node of leafFirst) try {
|
|
15906
|
-
await deps.stateBackend
|
|
16316
|
+
await removeExportedStackRecord(deps.stateBackend, node.stackName, node.region, logger);
|
|
15907
16317
|
logger.info(`cdkd state for ${quotedOrNotShown(node.stackName)} (${quotedRegion(node.region)}) removed.`);
|
|
15908
16318
|
} catch (err) {
|
|
15909
16319
|
stateDeletionFailures.push({
|
|
@@ -16129,6 +16539,10 @@ const STATE_READ_REASONS = {
|
|
|
16129
16539
|
"read-failed": STATE_READ_FAILED_REASON,
|
|
16130
16540
|
"resources-malformed": "resources is not a JSON object; run `cdkd state show --json` to see the record"
|
|
16131
16541
|
};
|
|
16542
|
+
function stateDestroyTargets(refs, stackRegion) {
|
|
16543
|
+
if (stackRegion) return refs.filter((r) => r.region === stackRegion || !r.region);
|
|
16544
|
+
return refs.length === 1 ? [...refs] : void 0;
|
|
16545
|
+
}
|
|
16132
16546
|
function resourceCountOrNull(resources) {
|
|
16133
16547
|
if (resources === void 0 || resources === null) return 0;
|
|
16134
16548
|
if (typeof resources !== "object" || Array.isArray(resources)) return null;
|
|
@@ -16249,7 +16663,10 @@ async function setupStateBackend(options) {
|
|
|
16249
16663
|
bucket,
|
|
16250
16664
|
prefix,
|
|
16251
16665
|
exportIndexStore: new ExportIndexStore(awsClients.s3, bucket, prefix, region, stateBackend, { profile: options.profile }),
|
|
16252
|
-
dispose: () =>
|
|
16666
|
+
dispose: () => {
|
|
16667
|
+
awsClients.destroy();
|
|
16668
|
+
stateBackend.destroyClient();
|
|
16669
|
+
}
|
|
16253
16670
|
};
|
|
16254
16671
|
}
|
|
16255
16672
|
function renderRecovery(options, setup) {
|
|
@@ -16690,6 +17107,43 @@ function createStateShowCommand() {
|
|
|
16690
17107
|
cmd.addOption(deprecatedRegionOption);
|
|
16691
17108
|
return cmd;
|
|
16692
17109
|
}
|
|
17110
|
+
async function clearRetainedQuietly(backend, stackName, region, logger) {
|
|
17111
|
+
try {
|
|
17112
|
+
await backend.saveRetainedResources(stackName, region, []);
|
|
17113
|
+
return true;
|
|
17114
|
+
} catch (error) {
|
|
17115
|
+
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.`);
|
|
17116
|
+
return false;
|
|
17117
|
+
}
|
|
17118
|
+
}
|
|
17119
|
+
async function clearRetainedWithoutRecord(backend, stackName, stackRegion, logger) {
|
|
17120
|
+
if (stackName.includes("/")) return {
|
|
17121
|
+
cleared: [],
|
|
17122
|
+
attempted: 0
|
|
17123
|
+
};
|
|
17124
|
+
const base = `${backend.prefix}/${stackName}/`;
|
|
17125
|
+
let regions;
|
|
17126
|
+
try {
|
|
17127
|
+
const keys = (await backend.listRawKeys(base)).map((key) => key.slice(base.length).split("/")).filter((parts) => parts.length >= 2 && parts[0] !== "");
|
|
17128
|
+
const recorded = new Set(keys.filter((parts) => parts.length === 2 && parts[1] === "state.json").map((parts) => parts[0]));
|
|
17129
|
+
regions = [...new Set(keys.map((parts) => parts[0]).filter((region) => stackRegion === void 0 || region === stackRegion).filter((region) => !recorded.has(region)))];
|
|
17130
|
+
} catch (error) {
|
|
17131
|
+
logger.warn(safeMsg`Could not look for a kept-resource record of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}).`);
|
|
17132
|
+
return {
|
|
17133
|
+
cleared: [],
|
|
17134
|
+
attempted: 0
|
|
17135
|
+
};
|
|
17136
|
+
}
|
|
17137
|
+
const cleared = [];
|
|
17138
|
+
for (const region of regions) {
|
|
17139
|
+
if (await clearRetainedQuietly(backend, stackName, region, logger)) cleared.push(region);
|
|
17140
|
+
await releaseRegistryMarkerQuietly(backend, stackName, region, logger);
|
|
17141
|
+
}
|
|
17142
|
+
return {
|
|
17143
|
+
cleared,
|
|
17144
|
+
attempted: regions.length
|
|
17145
|
+
};
|
|
17146
|
+
}
|
|
16693
17147
|
async function stateOrphanCommand(stackArgs, options) {
|
|
16694
17148
|
const logger = getLogger();
|
|
16695
17149
|
if (options.verbose) logger.setLevel("debug");
|
|
@@ -16705,6 +17159,12 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
16705
17159
|
for (const stackName of stackArgs) {
|
|
16706
17160
|
const stackRefs = refs.filter((r) => r.stackName === stackName);
|
|
16707
17161
|
if (stackRefs.length === 0) {
|
|
17162
|
+
const { cleared, attempted } = await clearRetainedWithoutRecord(setup.stateBackend, stackName, options.stackRegion, logger);
|
|
17163
|
+
if (attempted > 0 && cleared.length === 0) continue;
|
|
17164
|
+
if (cleared.length > 0) {
|
|
17165
|
+
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.`);
|
|
17166
|
+
continue;
|
|
17167
|
+
}
|
|
16708
17168
|
logger.info(safeMsg`No state found for stack: ${plainOrDescribed(stackName, "stack name")}, skipping` + (isPasteableIdent(stackName) ? "" : safeMsg`. ${STATE_LIST_POINTER}`));
|
|
16709
17169
|
continue;
|
|
16710
17170
|
}
|
|
@@ -16748,10 +17208,13 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
16748
17208
|
await warnOnLiveForeignLock(setup.lockManager, stackName, target.region, logger);
|
|
16749
17209
|
await setup.stateBackend.deleteState(stackName, target.region);
|
|
16750
17210
|
await setup.lockManager.forceReleaseLock(stackName, target.region);
|
|
17211
|
+
await clearRetainedQuietly(setup.stateBackend, stackName, target.region, logger);
|
|
17212
|
+
await releaseRegistryMarkerQuietly(setup.stateBackend, stackName, target.region, logger);
|
|
16751
17213
|
} else {
|
|
16752
17214
|
await warnOnLiveForeignLock(setup.lockManager, stackName, void 0, logger);
|
|
16753
17215
|
await setup.stateBackend.deleteLegacyState(stackName);
|
|
16754
17216
|
await setup.lockManager.forceReleaseLock(stackName, void 0);
|
|
17217
|
+
await clearRetainedWithoutRecord(setup.stateBackend, stackName, void 0, logger);
|
|
16755
17218
|
}
|
|
16756
17219
|
logger.info(safeMsg`✓ Removed state for stack: ${describedStackRef(target)}` + ((options.yes || options.force) && refIsDescribed(target) ? safeMsg`. ${STATE_LIST_POINTER}` : ""));
|
|
16757
17220
|
}
|
|
@@ -16899,6 +17362,8 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
16899
17362
|
interruptWatch.dispose();
|
|
16900
17363
|
throw error;
|
|
16901
17364
|
}
|
|
17365
|
+
const deferredTails = [];
|
|
17366
|
+
let deferRegistryTail;
|
|
16902
17367
|
try {
|
|
16903
17368
|
const stateRefs = await setup.stateBackend.listStacks();
|
|
16904
17369
|
const knownStackNames = new Set(stateRefs.map((r) => r.stackName));
|
|
@@ -16908,6 +17373,7 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
16908
17373
|
logger.info(safeMsg`Found ${stackNames.length} stack(s) to destroy: ${stackNames.map(listedStackName).join(", ")}`);
|
|
16909
17374
|
let totalErrors = 0;
|
|
16910
17375
|
let totalSkipped = 0;
|
|
17376
|
+
let totalOrphanSkips = 0;
|
|
16911
17377
|
let interrupted = false;
|
|
16912
17378
|
const runInterrupted = () => interrupted || interruptWatch.interrupted();
|
|
16913
17379
|
let stoppedEarly = false;
|
|
@@ -16916,16 +17382,23 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
16916
17382
|
if (!options.stackRegion) return laterRefs.length > 0;
|
|
16917
17383
|
return laterRefs.some((r) => r.region === options.stackRegion || !r.region);
|
|
16918
17384
|
});
|
|
17385
|
+
const crossPrefixCheck = { cache: new CrossPrefixGuard(setup.stateBackend) };
|
|
17386
|
+
if (stackNames.length > 1) deferRegistryTail = (released) => deferredTails.push(released);
|
|
17387
|
+
for (const name of stackNames) {
|
|
17388
|
+
const refs = stateRefs.filter((r) => r.stackName === name);
|
|
17389
|
+
for (const ref of stateDestroyTargets(refs, options.stackRegion) ?? []) crossPrefixCheck.cache.full(name, ref.region ?? setup.region, "prestart");
|
|
17390
|
+
}
|
|
16919
17391
|
for (const [stackIndex, stackName] of stackNames.entries()) {
|
|
16920
17392
|
const refs = stateRefs.filter((r) => r.stackName === stackName);
|
|
16921
17393
|
let targets;
|
|
17394
|
+
const planned = stateDestroyTargets(refs, options.stackRegion);
|
|
16922
17395
|
if (options.stackRegion) {
|
|
16923
|
-
targets =
|
|
17396
|
+
targets = planned ?? [];
|
|
16924
17397
|
if (targets.length === 0) {
|
|
16925
17398
|
logger.warn(safeMsg`Skipping ${plainOrDescribed(stackName, "stack name")} (no state record matches ` + safeMsg`--stack-region ${displayIdent(options.stackRegion)})`);
|
|
16926
17399
|
continue;
|
|
16927
17400
|
}
|
|
16928
|
-
} else if (
|
|
17401
|
+
} else if (planned !== void 0) targets = planned;
|
|
16929
17402
|
else throw multipleRegionsError(stackName, refs, `Use --stack-region ${commandHole("region")} to pick one.`);
|
|
16930
17403
|
for (const [refIndex, ref] of targets.entries()) {
|
|
16931
17404
|
logger.info(safeMsg`\nPreparing to destroy stack: ${formatStackRefSafe(ref)}`);
|
|
@@ -16982,6 +17455,8 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
16982
17455
|
skipFinalSnapshot: options.skipFinalSnapshot === true,
|
|
16983
17456
|
resolveSecretDerivedPrincipals: {},
|
|
16984
17457
|
stackDestroy: true,
|
|
17458
|
+
crossPrefixCheck,
|
|
17459
|
+
...deferRegistryTail !== void 0 && { deferRegistryTail },
|
|
16985
17460
|
exportIndexStore: setup.exportIndexStore,
|
|
16986
17461
|
...options.allowUnsupportedTypes?.length && { allowUnsupportedTypes: options.allowUnsupportedTypes },
|
|
16987
17462
|
...options.resourceWarnAfter?.globalMs !== void 0 && { resourceWarnAfterMs: options.resourceWarnAfter.globalMs },
|
|
@@ -17007,6 +17482,7 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
17007
17482
|
}
|
|
17008
17483
|
totalErrors += result.errorCount;
|
|
17009
17484
|
totalSkipped += result.skippedCount;
|
|
17485
|
+
totalOrphanSkips += result.journaledOrphanSkips;
|
|
17010
17486
|
if (result.interrupted) interrupted = true;
|
|
17011
17487
|
if (runInterrupted()) {
|
|
17012
17488
|
if (refIndex < targets.length - 1) stoppedEarly = true;
|
|
@@ -17020,8 +17496,9 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
17020
17496
|
}
|
|
17021
17497
|
if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd state destroy' to retry. If the same resource keeps failing, 'cdkd state orphan <stack> --stack-region <region>' removes the stack's state in that region (every resource's record) without deleting AWS resources.`);
|
|
17022
17498
|
if (interrupted || interruptWatch.interrupted() && stoppedEarly) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd state destroy' to finish.`);
|
|
17023
|
-
if (totalSkipped > 0) throw new PartialFailureError(
|
|
17499
|
+
if (totalSkipped > 0) throw new PartialFailureError(skippedDestroyMessage(totalSkipped, totalOrphanSkips, "cdkd state destroy"));
|
|
17024
17500
|
} finally {
|
|
17501
|
+
await Promise.allSettled(deferredTails);
|
|
17025
17502
|
unforwardSigterm();
|
|
17026
17503
|
interruptWatch.dispose();
|
|
17027
17504
|
setup.dispose();
|
|
@@ -17684,6 +18161,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17684
18161
|
});
|
|
17685
18162
|
return;
|
|
17686
18163
|
}
|
|
18164
|
+
const crossPrefixScan = new CrossPrefixGuard(setup.stateBackend).full(stackName, region);
|
|
17687
18165
|
stackAwsClients = new AwsClients({
|
|
17688
18166
|
region,
|
|
17689
18167
|
...options.profile && { profile: options.profile }
|
|
@@ -17718,6 +18196,15 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17718
18196
|
segments: journal.segments.filter((s) => s.reason !== NESTED_PENDING_PARENT_REASON)
|
|
17719
18197
|
};
|
|
17720
18198
|
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.`);
|
|
18199
|
+
applyCrossPrefixScan(await crossPrefixScan, {
|
|
18200
|
+
stackName,
|
|
18201
|
+
region,
|
|
18202
|
+
bucket: setup.bucket,
|
|
18203
|
+
recovery: {
|
|
18204
|
+
profile: options.profile,
|
|
18205
|
+
stateBucket: setup.bucket
|
|
18206
|
+
}
|
|
18207
|
+
}, "rollback", (message) => logger.warn(message), (message) => logger.info(message));
|
|
17721
18208
|
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.`);
|
|
17722
18209
|
demoteSupersededOrphans(journal.segments, Array.isArray(stateData.state.orphans) ? stateData.state.orphans : []);
|
|
17723
18210
|
if (!options.revertFailed) for (const segment of journal.segments) {
|
|
@@ -17961,6 +18448,8 @@ async function rollbackCommand(stackArg, options) {
|
|
|
17961
18448
|
const survivingOrphans = orphansAfterRollback(baseState, mintedOrphans).orphans ?? [];
|
|
17962
18449
|
if (journal.segments.length === 0 && oldestInitialDeploy && Object.keys(stateResources).length === 0 && survivingOrphans.length === 0) {
|
|
17963
18450
|
await setup.stateBackend.deleteState(stackName, region);
|
|
18451
|
+
await recordRetainedForReadoption(setup.stateBackend, stackName, region, [], logger);
|
|
18452
|
+
await releaseRegistryMarkerQuietly(setup.stateBackend, stackName, region, logger);
|
|
17964
18453
|
logger.info(`State for ${stackRegionShown(stackName, region)} removed (stack fully rolled back).`);
|
|
17965
18454
|
}
|
|
17966
18455
|
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.");
|
|
@@ -19108,8 +19597,20 @@ async function forceUnlockCommand(stackArgs, options) {
|
|
|
19108
19597
|
const where = r ? `${displayStackName(stackName)} (${displayIdent(r)})` : `${displayStackName(stackName)} (legacy lock key)`;
|
|
19109
19598
|
logger.info(`Force-unlocking stack: ${where}`);
|
|
19110
19599
|
try {
|
|
19111
|
-
|
|
19600
|
+
let ledgerError;
|
|
19601
|
+
let recorded = false;
|
|
19602
|
+
await lockManager.forceReleaseLock(stackName, r, async (horizon) => {
|
|
19603
|
+
if (r === void 0) return;
|
|
19604
|
+
const ledger = ledgerForStack(stateBackend, stackName, r);
|
|
19605
|
+
for (let attempt = 0; attempt < 2 && !recorded; attempt++) try {
|
|
19606
|
+
await ledger.noteAbandoned(horizon);
|
|
19607
|
+
recorded = true;
|
|
19608
|
+
} catch (error) {
|
|
19609
|
+
ledgerError = error;
|
|
19610
|
+
}
|
|
19611
|
+
});
|
|
19112
19612
|
logger.info(`✓ Lock released for stack: ${where}`);
|
|
19613
|
+
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.");
|
|
19113
19614
|
} catch (error) {
|
|
19114
19615
|
const message = describeAwsFailure(error).detail;
|
|
19115
19616
|
if (message.includes("No lock found") || message.includes("NoSuchKey")) logger.info(`No lock found for stack: ${where}`);
|
|
@@ -19219,6 +19720,20 @@ var ObservedBaselineRefusals = class extends Set {
|
|
|
19219
19720
|
unverifiableParameter = /* @__PURE__ */ new Set();
|
|
19220
19721
|
hadDeployedParameterSource = false;
|
|
19221
19722
|
};
|
|
19723
|
+
async function claimRegistryMarkerAfterImport(backend, stackName, region, logger) {
|
|
19724
|
+
const answer = await new CrossPrefixGuard(backend).full(stackName, region);
|
|
19725
|
+
const regionShown = displaySafe(region, { asciiOnly: true });
|
|
19726
|
+
switch (answer.kind) {
|
|
19727
|
+
case "clear": return;
|
|
19728
|
+
case "found":
|
|
19729
|
+
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.");
|
|
19730
|
+
return;
|
|
19731
|
+
case "in-progress":
|
|
19732
|
+
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.`);
|
|
19733
|
+
return;
|
|
19734
|
+
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.`);
|
|
19735
|
+
}
|
|
19736
|
+
}
|
|
19222
19737
|
async function importCommand(stackArg, options) {
|
|
19223
19738
|
const providerClasses = await loadProviderClasses();
|
|
19224
19739
|
const logger = getLogger();
|
|
@@ -19439,6 +19954,7 @@ async function importCommand(stackArg, options) {
|
|
|
19439
19954
|
await recordImportOnRollbackJournal(stateBackend, stackInfo.stackName, targetRegion, importedRows.map((r) => r.logicalId), stackState.resources, logger);
|
|
19440
19955
|
await stateBackend.saveState(stackInfo.stackName, targetRegion, stackState, saveOptions);
|
|
19441
19956
|
logger.info(`✓ State written: ${stackInfo.stackName} (${targetRegion})`);
|
|
19957
|
+
await claimRegistryMarkerAfterImport(stateBackend, stackInfo.stackName, targetRegion, logger);
|
|
19442
19958
|
logger.info(` ${importedRows.length} resource(s) imported. Run 'cdkd diff' to see how the imported state lines up with the template.`);
|
|
19443
19959
|
if (migrationCfnStackName && migrationTree && accountIdForNestedSynth) await importNestedStackChildrenRecursive({
|
|
19444
19960
|
lockRecovery,
|
|
@@ -27766,4 +28282,4 @@ function collectVerbFlags(program) {
|
|
|
27766
28282
|
|
|
27767
28283
|
//#endregion
|
|
27768
28284
|
export { canonicalizeIpProtocolValue as a, buildProgram, resolveSecretDerivedPrincipals as i, runDestroyForStack as n, resolvedResourceTimeoutMs as o, isResolvableSecretPrincipalList as r, canonicalizeIpv4Cidr as t };
|
|
27769
|
-
//# sourceMappingURL=program-
|
|
28285
|
+
//# sourceMappingURL=program-CIxuz2zX.js.map
|