@go-to-k/cdkd 0.291.16 → 0.291.18
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-DAvRcbyS.js → asg-provider-DR5gOGbi.js} +3 -3
- package/dist/{asg-provider-DAvRcbyS.js.map → asg-provider-DR5gOGbi.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-yukC8N_f.js → deploy-engine-BwDlgFRs.js} +578 -133
- package/dist/deploy-engine-BwDlgFRs.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{logger-GASr9bAF.js → logger-Bt0RGDfb.js} +12 -2
- package/dist/logger-Bt0RGDfb.js.map +1 -0
- package/dist/{program-DjkAPWi0.js → program-DxyHPT8E.js} +692 -386
- package/dist/{program-DjkAPWi0.js.map → program-DxyHPT8E.js.map} +1 -1
- package/dist/{version-Qigb_6I0.js → version-CJkb2usU.js} +2 -2
- package/dist/{version-Qigb_6I0.js.map → version-CJkb2usU.js.map} +1 -1
- package/package.json +2 -2
- package/dist/deploy-engine-yukC8N_f.js.map +0 -1
- package/dist/logger-GASr9bAF.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as yellow, $i as MIGRATE_TMP_PREFIX, $n as repairMalformedOutputsForReadOnly, $r as WorkGraph, $t as replayWarn, A as createPreDeleteFinalSnapshot, Aa as runWithStackAwsClients, Ai as runDockerForeground, An as malformedOrphansRefusalMessage, Ar as scrubResourceRecord, At as isTerminationProtectionPropagationError, B as isStatefulRecreateTargetSync, Ba as LocalInvokeBuildError$1, Bi as getLegacyStateBucketName, Bn as refuseMalformedNestedChildOutputs, Br as DEFAULT_STATE_PREFIX, Bt as parameterTypeMayLoseSecretIdentity, C as namesAnyDeclaredParameter, Ca as renderAssemblyPathEscape, Ci as finchSecretArgvRefusal, Cn as hasReadableOutputs, Cr as maskSecretsInError, Ct as CloudControlProvider, D as PRE_DELETE_SNAPSHOT_TYPES, Da as AwsClients, Di as isMalformedEnvKey, Dn as malformedExportSourceWarning, Dr as recordMaskOnlyValuesIn, Dt as deleteSkipReason, E as ATOMIC_FINAL_SNAPSHOT_TYPES, Ea as resolveBucketRegion, Ei as isDockerClientEnvKey, En as malformedExportNamesWarning, Er as recordMaskOnlyValue, Et as deleteIndeterminateGuards, F as extractDeploymentEventError, Fa as CrossAccountSecretRefusalError, Fi as AssetManifestLoader, Fn as malformedResourceEntriesWarning, Fr as buildForceUnlockCommand, Ft as coerceParameterTypedValue, G as toCfnInteger, Ga as PartialFailureError, Gi as resolveStateBucketWithDefault, Gn as refuseMalformedOutputsForDestroy, Gr as importableOutputKeys, Gt as resolveExplicitPhysicalId, H as WARM_THROUGHPUT_MEMBERS, Hi as resolveAutoAssetStorage, Hn as refuseMalformedOrphansForDestroy, Hr as hasReadableExportSet, Ht as isSettledInstanceState, I as makeSiblingClaimReader, Ii as getDockerImageBySourceHash, In as malformedResourcePropertiesWarning, Ir as buildLockContentionMessage, It as getAccountInfo, J as bold, Ja as ResourceUpdateNotSupportedError, Ji as stateBucketExistenceConfirmed, Jn as refuseMalformedResourceEntriesForOrphan, Jr as orphansAfterRollback, Jt as coerceCfnInteger, K as toFiniteNumber, Ka as ProvisioningError, Ki as resolveStateBucketWithDefaultAndSource, Kn as refuseMalformedResourceAttributesForOrphan, Kr as importableOutputs, Kt as assertRegionMatch, L as planOrphanAdoption, La as DeployCancelledError, Li as Synthesizer, Ln as malformedResourcesWarning, Lr as forceQuitRecoveryClause, Lt as isImpossibleEmptyStoredAttribute, M as refusesFinalSnapshot, Mi as warnFinchArgvExposure, Mn as malformedOutputsRefusalMessage, Mr as S3StateBackend, Mt as carriesDynamicReference, N as unsupportedFinalSnapshotError, Na as CdkdError, Ni as escapeRegExp, Nn as malformedOutputsWarning, Nr as rebuildClientForBucketRegion, Nt as carriesFetchableDynamicReference, O as buildFinalSnapshotIdentifier, Oa as getAwsClients, Oi as partitionSensitiveEnv, On as malformedLocalOutputsWarning, Or as recoverMaskedOutput, Ot as isWaitAbandonedError, P as makeCanonicalizePropertiesFn, Pi as stripControlChars, Pn as malformedRenderedContainersWarning, Pr as UNREPRODUCIBLE_LOCK_CLAUSE, Pt as cfnRefValueFromPhysicalId, Q as red, Qa as SynthesisError, Qi as CFN_TEMPLATE_URL_LIMIT, Qn as repairMalformedOrphansForReadOnly, Qr as stringifyValue, Qt as readConfigString, R as MULTI_REGION_RECREATE_BLOCKED_TYPES, Ra as DynamicReferenceRegionAmbiguousError, Ri as synthesisStatusMessage, Rn as malformedStateRefusalMessage, Rr as formatLockExpiry, Rt as isNamelessDynamicReferenceError, S as computeParameterTaint, Sa as displayAssemblyPath, Si as dockerSpawnEnvWithSensitive, Sn as hasReadableOrphans, Sr as markSameGenerationBag, St as startInterruptWatch, T as resourcesNamingDeclaredParameter, Ti as getDockerCmd, Tn as isReadableResourceEntry, Tr as pathCrossesDottedKey, Tt as UNSPECIFIED_SKIP_REASON, U as coerceWarmThroughput$1, Ua as MalformedProducerRecordRefusalError, Ui as resolveCaptureObservedState, Un as refuseMalformedOrphansForOrphan, Ur as hasReasonlessBaselineRefusal, Ut as WAFv2WebACLProvider, V as renderStatefulReason, Va as LocalStartServiceError, Vi as resolveApp, Vn as refuseMalformedOrphans, Vr as exportNamesCarriedFrom, Vt as refStateLookupFromResource, W as isWarmThroughputDecrease, Wa as NestedStackChildDirectDestroyError, Wi as resolveSkipPrefix, Wn as refuseMalformedOutputs, Wr as hasUnverifiableParameterRefusal, Wt as normalizeAwsTagsToCfn, X as gray, Xa as StackTerminationProtectionError, Xi as ssmResolvedValueType, Xn as refuseMalformedResourcesForDestroy, Xr as shouldRetainResource, Xt as configIntegerRefusal, Y as cyan, Ya as StackHasActiveImportsError, Yi as warnDeprecatedNoPrefixCliFlag, Yn as refuseMalformedResourcePropertiesForOrphan, Yr as orphansCarriedFrom, Yt as configBooleanRefusal, Z as green, Zi as CFN_TEMPLATE_BODY_LIMIT, Zn as refuseMalformedState, Zr as AssetPublisher, Zt as configStringRefusal, _ as bagHoldsSecretExpression, _a as hasOwnKey, _i as resolveDockerContextDirectory, _n as INTRINSIC_KEYS, _r as dynamicReferenceTokens, _t as maskerOrIdentity, a as DeploymentEventsStore, aa as producerCoordinateKey, ai as BOOTSTRAP_MARKER_PREFIX, an as withSharedDrainBudget, ao as isMarkedNonRetryable, ar as findActionableSilentDrops, at as secretBearingStateKeyWarning, b as mergeNoChangeOutputs, ba as ownValue, bi as describeDockerExecFailure, bn as UNREADABLE_RESOURCES_MAP_ROW, br as isSingleDynamicReferenceToken, bt as interruptWatchListenerCount, c as replayFailedOperations, ca as expectedOwnerParam, ci as getBootstrapMarkerKey, cn as s3BucketDualStackDomainName, co as isTransientServerError, cr as withRetry, ct as IAMRoleProvider, d as updatePartialMessage, da as derivePartitionAndUrlSuffix, di as readBootstrapMarkerBody, dn as applyRoleArnIfSet, do as retryClassificationText, dr as STATE_SOURCED_BASELINE_RULES, dt as definedAttributes, ea as findLargeInlineResources, ei as buildAssetRedirectMap, en as requireConfigArray, er as repairMalformedResourceEntriesForReadOnly, et as collectDeclaredOutputNames, f as updatePartialReason, fa as AssemblyReader, fi as validateAssetBucketName, fn as AWS_CREDENTIAL_ENV_KEYS, fo as describeAwsFailure, fr as STATE_SOURCED_CROSS_GENERATION_RULES, ft as stringifyIfAssigned, g as computeImplicitDeleteEdges, ga as defineOwnKey, gi as buildDockerImage, gn as DiffCalculator, gr as createSecretMasker, gt as maskDeep, h as IMPLICIT_DELETE_DEPENDENCIES, ha as processStackMessages, hi as assertCdkLocalDockerContextContained, hn as envCredentialsAreAssumedRole, hr as carriesSecretMask, ht as createMaskedRetryLogger, i as DeploymentEventsReader, ia as injectiveKeyPrefix, ii as AssetModeResolver, in as producerRegionsFromState, io as shellQuote, ir as safeStackName, it as secretBearing, j as isFinalSnapshotError, ja as setAwsClients, ji as runDockerStreaming, jn as malformedOrphansWarning, jr as LockManager, jt as IntrinsicFunctionResolver, k as ccRoutedFinalSnapshotError, ka as resetAwsClients, ki as redactDockerArgvValues, kn as malformedOrphanRecordsWarning, kr as redactSecretsForState, kt as disableInstanceApiTermination, l as replayRollback, la as PARTITION_TABLE, li as isCrossRegionRedirect, ln as s3BucketRegionalDomainName, lo as markNonRetryable, lr as DagBuilder, lt as collectInlinePolicyNamesManagedBySiblings, m as maskingRetryLogger, ma as globMatches, mi as buildDenyExternalAccessPolicy, mn as callerEnvCredentials, mr as TEMPLATE_SOURCED_RULES, mt as wouldReturnToSdkProvider, n as DEFAULT_RESOURCE_WARN_AFTER_MS, na as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, ni as loadPublishableAssetManifest, nn as requireConfigString, no as withErrorHandling, nr as repairMalformedResourcesForReadOnly, nt as exportAliasCollisionScrubWarning, o as planFailedOps, oa as producerRecordKey, oi as assertAssetBucketRegion, on as s3BucketArn, oo as isRetryableTransientError, or as findSilentDropProperties, ot as secretSafeKeyDisplay, p as withResourceDeadline, pa as failedStageNote, pi as validateContainerRepoName, pn as applyCallerIdentityCredentials, po as safeStringify, pr as STATE_SOURCED_READBACK_RULES, pt as ProviderRegistry, q as formatResourceLine, qa as ResourceTimeoutError, qi as resolveUseCdkBootstrapAssets, qn as refuseMalformedResourceEntries, qr as isReadableBag, qt as coerceCfnBoolean, r as DeployEngine, ra as injectiveKey, ri as rewriteTemplateAssetReferences, rn as classifyReplaySecretRegion, ro as pasteableCommand, rr as safeRegion, rt as isExportAliasCollision, s as planRollback, sa as decodeListingKey, si as ensureAssetStorage, sn as s3BucketDomainName, so as isThrottlingError, sr as describeTypeWithThrottleRetry, st as getCurrentResourceSecrets, t as DEFAULT_RESOURCE_TIMEOUT_MS, ta as uploadCfnTemplate, ti as createAssetRedirectResolver, tn as requireConfigObject, to as normalizeAwsError, tr as repairMalformedResourcePropertiesForReadOnly, tt as collectPublishedOutputNames, u as resolveReplacementOldType, ua as canonicalizeRegion, ui as parseBootstrapMarker, un as s3BucketWebsiteUrl, uo as markRedactedCause, ur as TemplateParser, ut as clearOnUpdateRemoval, v as isSecretBearingReferenceString, va as hasPlainPrototype, vi as warnManifestExecutable, vn as STATE_RESOURCES_MALFORMED, vr as errorCauseChain, vt as beginCommandInterruptScope, w as reachableDivergentParameters, wa as resolveAssemblyPath, wi as formatDockerLoginError, wn as hasReadableResources, wr as maskSecretsInText, wt as slowCcOperationTimeoutMs, x as bindingSkippedOutputs, xa as absoluteAssemblyPathEscape, xi as describeDockerFailure, xn as displayLogicalId, xr as isUncertifiedBaselineMaskPosition, xt as isInterruptedWaitError, y as keptWholeReasonText, ya as nullPrototypeRecord, yi as describeDockerCapturedOutput, yn as UNREADABLE_ORPHANS_CONTAINER_ROW, yr as identityKeyFor, yt as endCommandInterruptScope, z as isStatefulRecreateTargetForReplace, za as IntrinsicResolutionRefusalError, zi as getDefaultStateBucketName, zn as refuseDivergentRecordRegionForDestroy, zr as CUSTOM_RESOURCE_RESPONSE_PREFIX, zt as isUnboundTemplateParameter } from "./deploy-engine-yukC8N_f.js";
|
|
2
|
-
import { C as displayAwsMessage, D as
|
|
1
|
+
import { $ as yellow, $a as NestedStackChildDirectDestroyError, $i as resolveSkipPrefix, $n as refuseMalformedOutputsForDestroy, $r as hasReadableExportSet, $t as readConfigString, A as createPreDeleteFinalSnapshot, Aa as absoluteAssemblyPathEscape, Ai as describeDockerFailure, An as malformedExportSourceWarning, Ar as identityKeyFor, At as disableInstanceApiTermination, B as isStatefulRecreateTargetSync, Ba as setAwsClients, Bi as runDockerStreaming, Bn as malformedResourceEntriesWarning, Br as redactSecretsForState, Bt as isUnboundTemplateParameter, C as namesAnyDeclaredParameter, Ca as globMatches, Ci as validateAssetBucketName, Cn as displayLogicalId, Cr as STATE_SOURCED_CROSS_GENERATION_RULES, Ct as CloudControlProvider, D as PRE_DELETE_SNAPSHOT_TYPES, Da as hasPlainPrototype, Di as resolveDockerContextDirectory, Dn as isReadableOrphanRecord, Dr as createSecretMasker, Dt as deleteIndeterminateGuards, E as ATOMIC_FINAL_SNAPSHOT_TYPES, Ea as hasOwnKey, Ei as buildDockerImage, En as hasReadableResources, Er as carriesSecretMask, Et as UNSPECIFIED_SKIP_REASON, F as extractDeploymentEventError, Fa as resolveBucketRegion, Fi as isDockerClientEnvKey, Fn as malformedOrphansRefusalMessage, Fr as maskSecretsInText, Ft as cfnRefValueFromPhysicalId, G as toCfnInteger, Gi as getDockerImageBySourceHash, Gn as refuseDivergentRecordRegionForDestroy, Gr as UNREPRODUCIBLE_LOCK_CLAUSE, Gt as normalizeAwsTagsToCfn, H as WARM_THROUGHPUT_MEMBERS, Ha as CdkdError, Hi as escapeRegExp, Hn as malformedResourcesWarning, Hr as LockManager, Ht as refStateLookupFromResource, I as makeSiblingClaimReader, Ia as AwsClients, Ii as isMalformedEnvKey, In as malformedOrphansWarning, Ir as pathCrossesDottedKey, It as coerceParameterTypedValue, J as bold, Ja as IntrinsicResolutionRefusalError, Ji as getDefaultStateBucketName, Jn as refuseMalformedOrphanRecordsForDestroy, Jr as forceQuitRecoveryClause, Jt as coerceCfnBoolean, K as toFiniteNumber, Ka as DeployCancelledError, Ki as Synthesizer, Kn as refuseMalformedNestedChildOutputs, Kr as buildForceUnlockCommand, Kt as resolveExplicitPhysicalId, L as planOrphanAdoption, La as getAwsClients, Li as partitionSensitiveEnv, Ln as malformedOutputsRefusalMessage, Lr as recordMaskOnlyValue, Lt as getAccountInfo, M as refusesFinalSnapshot, Ma as renderAssemblyPathEscape, Mi as finchSecretArgvRefusal, Mn as malformedOrphanRecordsRefusalMessage, Mr as isUncertifiedBaselineMaskPosition, Mt as IntrinsicFunctionResolver, N as unsupportedFinalSnapshotError, Na as resolveAssemblyPath, Ni as formatDockerLoginError, Nn as malformedOrphanRecordsWarning, Nr as markSameGenerationBag, Nt as carriesDynamicReference, O as buildFinalSnapshotIdentifier, Oa as nullPrototypeRecord, Oi as describeDockerCapturedOutput, On as isReadableResourceEntry, Or as dynamicReferenceTokens, Ot as deleteSkipReason, P as makeCanonicalizePropertiesFn, Pi as getDockerCmd, Pn as malformedOrphanRowsKeptWarning, Pr as maskSecretsInError, Pt as carriesFetchableDynamicReference, Q as red, Qa as MalformedProducerRecordRefusalError, Qi as resolveCaptureObservedState, Qn as refuseMalformedOutputs, Qr as exportNamesCarriedFrom, Qt as configStringRefusal, R as MULTI_REGION_RECREATE_BLOCKED_TYPES, Ra as resetAwsClients, Ri as redactDockerArgvValues, Rn as malformedOutputsWarning, Rr as recordMaskOnlyValuesIn, Rt as isImpossibleEmptyStoredAttribute, S as computeParameterTaint, Sa as failedStageNote, Si as readBootstrapMarkerBody, Sn as deployRefusesOrphanRowsReason, So as safeStringify, Sr as STATE_SOURCED_BASELINE_RULES, St as startInterruptWatch, T as resourcesNamingDeclaredParameter, Ta as defineOwnKey, Ti as buildDenyExternalAccessPolicy, Tn as hasReadableOutputs, Tr as TEMPLATE_SOURCED_RULES, Tt as ccProtectionRegistryTypes, U as coerceWarmThroughput$1, Ui as stripControlChars, Un as malformedStateRefusalMessage, Ur as S3StateBackend, Ut as isSettledInstanceState, V as renderStatefulReason, Vi as warnFinchArgvExposure, Vn as malformedResourcePropertiesWarning, Vr as scrubResourceRecord, Vt as parameterTypeMayLoseSecretIdentity, W as isWarmThroughputDecrease, Wa as CrossAccountSecretRefusalError, Wi as AssetManifestLoader, Wn as previewableOrphanRecords, Wr as rebuildClientForBucketRegion, Wt as WAFv2WebACLProvider, X as gray, Xa as LocalStartServiceError, Xi as resolveApp, Xn as refuseMalformedOrphansForDestroy, Xr as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xt as configBooleanRefusal, Y as cyan, Ya as LocalInvokeBuildError$1, Yi as getLegacyStateBucketName, Yn as refuseMalformedOrphans, Yr as formatLockExpiry, Yt as coerceCfnInteger, Z as green, Zi as resolveAutoAssetStorage, Zn as refuseMalformedOrphansForOrphan, Zr as DEFAULT_STATE_PREFIX, Zt as configIntegerRefusal, _ as bagHoldsSecretExpression, _a as expectedOwnerParam, _i as assertAssetBucketRegion, _n as DiffCalculator, _o as isTransientServerError, _r as findSilentDropProperties, _t as maskerOrIdentity, a as DeploymentEventsStore, aa as ssmResolvedValueType, ai as orphansAfterRollback, an as producerRegionsFromState, ao as StackTerminationProtectionError, ar as refuseMalformedState, at as secretBearingStateKeyWarning, b as mergeNoChangeOutputs, ba as derivePartitionAndUrlSuffix, bi as isCrossRegionRedirect, bn as UNREADABLE_ORPHANS_CONTAINER_ROW, bo as retryClassificationText, br as DagBuilder, bt as interruptWatchListenerCount, c as replayFailedOperations, ca as MIGRATE_TMP_PREFIX, ci as AssetPublisher, cn as s3BucketDomainName, cr as repairMalformedOutputsForReadOnly, ct as IAMRoleProvider, d as updatePartialMessage, da as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, di as buildAssetRedirectMap, dn as s3BucketWebsiteUrl, do as withErrorHandling, dr as repairMalformedResourcesForReadOnly, dt as definedAttributes, ea as resolveStateBucketWithDefault, ei as hasReasonlessBaselineRefusal, en as replayWarn, eo as PartialFailureError, er as refuseMalformedResourceAttributesForOrphan, et as collectDeclaredOutputNames, f as updatePartialReason, fa as injectiveKey, fi as createAssetRedirectResolver, fn as applyRoleArnIfSet, fo as pasteableCommand, fr as safeRegion, ft as stringifyIfAssigned, g as computeImplicitDeleteEdges, ga as decodeListingKey, gi as BOOTSTRAP_MARKER_PREFIX, gn as envCredentialsAreAssumedRole, go as isThrottlingError, gr as findActionableSilentDrops, gt as maskDeep, h as IMPLICIT_DELETE_DEPENDENCIES, ha as producerRecordKey, hi as AssetModeResolver, hn as callerEnvCredentials, ho as isRetryableTransientError, hr as unreadableOrphanRecords, ht as createMaskedRetryLogger, i as DeploymentEventsReader, ia as warnDeprecatedNoPrefixCliFlag, ii as isReadableBag, in as classifyReplaySecretRegion, io as StackHasActiveImportsError, ir as refuseMalformedResourcesForDestroy, it as secretBearing, j as isFinalSnapshotError, ja as displayAssemblyPath, ji as dockerSpawnEnvWithSensitive, jn as malformedLocalOutputsWarning, jr as isSingleDynamicReferenceToken, jt as isTerminationProtectionPropagationError, k as ccRoutedFinalSnapshotError, ka as ownValue, ki as describeDockerExecFailure, kn as malformedExportNamesWarning, kr as errorCauseChain, kt as isWaitAbandonedError, l as replayRollback, la as findLargeInlineResources, li as stringifyValue, ln as s3BucketDualStackDomainName, lr as repairMalformedResourceEntriesForReadOnly, lt as collectInlinePolicyNamesManagedBySiblings, m as maskingRetryLogger, ma as producerCoordinateKey, mi as rewriteTemplateAssetReferences, mn as applyCallerIdentityCredentials, mo as isMarkedNonRetryable, mr as unpreviewableOrphanRecords, mt as wouldReturnToSdkProvider, n as DEFAULT_RESOURCE_WARN_AFTER_MS, na as resolveUseCdkBootstrapAssets, ni as importableOutputKeys, nn as requireConfigObject, no as ResourceTimeoutError, nr as refuseMalformedResourceEntriesForOrphan, nt as exportAliasCollisionScrubWarning, o as planFailedOps, oa as CFN_TEMPLATE_BODY_LIMIT, oi as orphansCarriedFrom, on as withSharedDrainBudget, or as repairMalformedOrphanRecordsForReadOnly, ot as secretSafeKeyDisplay, p as withResourceDeadline, pa as injectiveKeyPrefix, pi as loadPublishableAssetManifest, pn as AWS_CREDENTIAL_ENV_KEYS, po as shellQuote, pr as safeStackName, pt as ProviderRegistry, q as formatResourceLine, qa as DynamicReferenceRegionAmbiguousError, qi as synthesisStatusMessage, qn as refuseMalformedOrphanRecords, qr as buildLockContentionMessage, qt as assertRegionMatch, r as DeployEngine, ra as stateBucketExistenceConfirmed, ri as importableOutputs, rn as requireConfigString, ro as ResourceUpdateNotSupportedError, rr as refuseMalformedResourcePropertiesForOrphan, rt as isExportAliasCollision, s as planRollback, sa as CFN_TEMPLATE_URL_LIMIT, si as shouldRetainResource, sn as s3BucketArn, so as SynthesisError, sr as repairMalformedOrphansForReadOnly, st as getCurrentResourceSecrets, t as DEFAULT_RESOURCE_TIMEOUT_MS, ta as resolveStateBucketWithDefaultAndSource, ti as hasUnverifiableParameterRefusal, tn as requireConfigArray, to as ProvisioningError, tr as refuseMalformedResourceEntries, tt as collectPublishedOutputNames, u as resolveReplacementOldType, ua as uploadCfnTemplate, ui as WorkGraph, un as s3BucketRegionalDomainName, uo as normalizeAwsError, ur as repairMalformedResourcePropertiesForReadOnly, ut as clearOnUpdateRemoval, v as isSecretBearingReferenceString, va as PARTITION_TABLE, vi as ensureAssetStorage, vn as INTRINSIC_KEYS, vo as markNonRetryable, vr as describeTypeWithThrottleRetry, vt as beginCommandInterruptScope, w as reachableDivergentParameters, wa as processStackMessages, wi as validateContainerRepoName, wn as hasReadableOrphans, wr as STATE_SOURCED_READBACK_RULES, wt as slowCcOperationTimeoutMs, x as bindingSkippedOutputs, xa as AssemblyReader, xi as parseBootstrapMarker, xn as UNREADABLE_RESOURCES_MAP_ROW, xo as describeAwsFailure, xr as TemplateParser, xt as isInterruptedWaitError, y as keptWholeReasonText, ya as canonicalizeRegion, yi as getBootstrapMarkerKey, yn as STATE_RESOURCES_MALFORMED, yo as markRedactedCause, yr as withRetry, yt as endCommandInterruptScope, z as isStatefulRecreateTargetForReplace, za as runWithStackAwsClients, zi as runDockerForeground, zn as malformedRenderedContainersWarning, zr as recoverMaskedOutput, zt as isNamelessDynamicReferenceError } from "./deploy-engine-BwDlgFRs.js";
|
|
2
|
+
import { C as displayAwsMessage, D as isPasteableIdent, E as displayStackName, O as truncateCodePoints, S as UNRENDERABLE, T as displaySafe, _ as withSkipPrefix, b as SECRET_REF_MAX_CODE_POINTS, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName, w as displayIdent, x as STACK_REF_MAX_CODE_POINTS } from "./logger-Bt0RGDfb.js";
|
|
3
3
|
import { n as awsClientDefaults, s as ambientRegion } from "./aws-client-defaults-jISU4PHo.js";
|
|
4
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
-
import { a as renderDisableCommand, i as protectedReplacementAdvice, r as UNNAMEABLE_ID_CLAUSE, t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as getCdkdVersion } from "./version-CJkb2usU.js";
|
|
5
|
+
import { a as renderDisableCommand, i as protectedReplacementAdvice, r as UNNAMEABLE_ID_CLAUSE, t as ASGProvider } from "./asg-provider-DR5gOGbi.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
8
8
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, NotFound, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -284,6 +284,51 @@ function describeStateKey(key, suffix = STATE_FILE_SUFFIX, knownPrefix) {
|
|
|
284
284
|
*/
|
|
285
285
|
const STATE_KEY_MAX_CODE_POINTS = STACK_REF_MAX_CODE_POINTS + 64;
|
|
286
286
|
|
|
287
|
+
//#endregion
|
|
288
|
+
//#region src/provisioning/remove-protection-types.ts
|
|
289
|
+
/**
|
|
290
|
+
* The resource types whose SDK provider's `delete()` flips a protection flag
|
|
291
|
+
* off under `DeleteContext.removeProtection` (issue
|
|
292
|
+
* [#2660](https://github.com/go-to-k/cdkd/issues/2660)).
|
|
293
|
+
*
|
|
294
|
+
* This is the ONE list the `--remove-protection` help strings render from, on
|
|
295
|
+
* `cdkd destroy` and `cdkd state destroy`. The Cloud Control half comes from
|
|
296
|
+
* {@link ccProtectionRegistryTypes}. Both copies of the help were hand-written
|
|
297
|
+
* before, and two types the providers honour (`AWS::EMR::Cluster`,
|
|
298
|
+
* `AWS::DynamoDB::GlobalTable`) were missing from both.
|
|
299
|
+
*
|
|
300
|
+
* `tests/unit/provisioning/remove-protection-types.test.ts` binds this list to
|
|
301
|
+
* the provider tree in both directions: each type's registered provider reads
|
|
302
|
+
* `removeProtection`, and each provider file that reads it registers at least
|
|
303
|
+
* one type here. A new provider gaining the flip fails that test until its type
|
|
304
|
+
* is added.
|
|
305
|
+
*/
|
|
306
|
+
const SDK_REMOVE_PROTECTION_TYPES = [
|
|
307
|
+
"AWS::Logs::LogGroup",
|
|
308
|
+
"AWS::RDS::DBInstance",
|
|
309
|
+
"AWS::RDS::DBCluster",
|
|
310
|
+
"AWS::DocDB::DBCluster",
|
|
311
|
+
"AWS::Neptune::DBCluster",
|
|
312
|
+
"AWS::Neptune::DBInstance",
|
|
313
|
+
"AWS::DynamoDB::Table",
|
|
314
|
+
"AWS::DynamoDB::GlobalTable",
|
|
315
|
+
"AWS::EC2::Instance",
|
|
316
|
+
"AWS::Cognito::UserPool",
|
|
317
|
+
"AWS::AutoScaling::AutoScalingGroup",
|
|
318
|
+
"AWS::ElasticLoadBalancingV2::LoadBalancer",
|
|
319
|
+
"AWS::EMR::Cluster"
|
|
320
|
+
];
|
|
321
|
+
/** Every type `--remove-protection` covers: the SDK list, then the Cloud Control registry. */
|
|
322
|
+
function removeProtectionTypes() {
|
|
323
|
+
return [...SDK_REMOVE_PROTECTION_TYPES, ...ccProtectionRegistryTypes()];
|
|
324
|
+
}
|
|
325
|
+
/** The types as the help prints them: `A, B, and C`. */
|
|
326
|
+
function removeProtectionTypeList() {
|
|
327
|
+
const types = removeProtectionTypes();
|
|
328
|
+
if (types.length < 2) return types.join("");
|
|
329
|
+
return `${types.slice(0, -1).join(", ")}, and ${types[types.length - 1]}`;
|
|
330
|
+
}
|
|
331
|
+
|
|
287
332
|
//#endregion
|
|
288
333
|
//#region src/cli/options.ts
|
|
289
334
|
/**
|
|
@@ -1127,7 +1172,7 @@ function effectiveAssumeRoleArn(logicalId, opt) {
|
|
|
1127
1172
|
*/
|
|
1128
1173
|
const destroyOptions = [
|
|
1129
1174
|
new Option("-f, --force", "Do not ask for confirmation before destroying the stacks").default(false),
|
|
1130
|
-
new Option("--remove-protection",
|
|
1175
|
+
new Option("--remove-protection", `Bypass deletion protection on protected resources by flipping the per-resource protection flag off in-place before delete. Covers stack-level terminationProtection (CDK property) and resource-level protection on ${removeProtectionTypeList()}.`).default(false),
|
|
1131
1176
|
allowUnsupportedTypesOption
|
|
1132
1177
|
];
|
|
1133
1178
|
/**
|
|
@@ -2392,12 +2437,12 @@ function countDeployableResources(template) {
|
|
|
2392
2437
|
*/
|
|
2393
2438
|
function resolveVerboseTemplatePath(outputDir, stackName) {
|
|
2394
2439
|
const resolved = resolveAssemblyPath(outputDir, `${stackName}.template.json`);
|
|
2395
|
-
if (!resolved.contained) throw new SynthesisError(`Stack
|
|
2440
|
+
if (!resolved.contained) throw new SynthesisError(`Stack ${displayStackName(stackName)} would write its template to a path that ${renderAssemblyPathEscape(resolved, outputDir, "write it")}`);
|
|
2396
2441
|
let linked = false;
|
|
2397
2442
|
try {
|
|
2398
2443
|
linked = lstatSync(resolved.path).isSymbolicLink();
|
|
2399
2444
|
} catch {}
|
|
2400
|
-
if (linked) throw new SynthesisError(`Stack
|
|
2445
|
+
if (linked) throw new SynthesisError(`Stack ${displayStackName(stackName)} would write its template over a symbolic link at ${displayAssemblyPath(resolved.path)}. cdkd writes a stack's template as a regular file beside the assembly; a symbolic link there redirects the write to wherever it points, so this indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to write it.`);
|
|
2401
2446
|
return resolved.path;
|
|
2402
2447
|
}
|
|
2403
2448
|
/**
|
|
@@ -3789,15 +3834,16 @@ function findNestedTemplateTreeDefect(nestedTemplates, ancestorTemplatePaths = [
|
|
|
3789
3834
|
/** Hops rendered in full before the middle of a long chain is elided. */
|
|
3790
3835
|
const MAX_RENDERED_HOPS = 8;
|
|
3791
3836
|
/**
|
|
3792
|
-
* `
|
|
3793
|
-
* `
|
|
3837
|
+
* `A (/x/a.json) -> B (/x/b.json)`. The logical id renders through
|
|
3838
|
+
* `displayIdent` and the path through `displayAssemblyPath`, each supplying its
|
|
3839
|
+
* own boundary: this text exists FOR a hand-modified assembly, so a logical id
|
|
3794
3840
|
* (a template key) and a path (derived from `aws:asset:path`) are both
|
|
3795
3841
|
* attacker-controlled, and a bare `Error` message is not sanitized downstream.
|
|
3796
3842
|
* A long chain keeps both ends, since the entry row and the closing row are
|
|
3797
3843
|
* the two a reader needs.
|
|
3798
3844
|
*/
|
|
3799
3845
|
function renderChain(chain) {
|
|
3800
|
-
const hop = (h) =>
|
|
3846
|
+
const hop = (h) => `${displayIdent(h.logicalId)} (${displayAssemblyPath(h.templatePath)})`;
|
|
3801
3847
|
if (chain.length <= MAX_RENDERED_HOPS) return chain.map(hop).join(" -> ");
|
|
3802
3848
|
const keep = MAX_RENDERED_HOPS / 2;
|
|
3803
3849
|
return [
|
|
@@ -3815,21 +3861,19 @@ function renderNestedTemplateTreeDefect(defect, stackName, action) {
|
|
|
3815
3861
|
const owner = (chain) => {
|
|
3816
3862
|
const ids = chain.slice(0, -1).map((h) => h.logicalId);
|
|
3817
3863
|
const keep = MAX_RENDERED_HOPS / 2;
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
];
|
|
3823
|
-
return displaySafe([stackName, ...shown].join("~"));
|
|
3864
|
+
if (ids.length <= MAX_RENDERED_HOPS) return displayStackName([stackName, ...ids].join("~"));
|
|
3865
|
+
const head = displayStackName([stackName, ...ids.slice(0, keep)].join("~"));
|
|
3866
|
+
const tail = displayStackName(ids.slice(-4).join("~"));
|
|
3867
|
+
return `${head}~...${ids.length - 8} more...~${tail}`;
|
|
3824
3868
|
};
|
|
3825
3869
|
if (defect.kind === "cycle") {
|
|
3826
3870
|
const closing = defect.chain[defect.chain.length - 1];
|
|
3827
|
-
return `The nested template tree under stack
|
|
3871
|
+
return `The nested template tree under stack ${displayStackName(stackName)} contains a cycle: ${renderChain(defect.chain)}. Nested stack ${displayIdent(closing.logicalId)} (declared in stack ${owner(defect.chain)}) resolves to a template that is already on that nesting chain, so its Metadata['aws:asset:path'] closes a cycle. ${provenance}`;
|
|
3828
3872
|
}
|
|
3829
|
-
if (defect.kind === "too-large") return `The nested template tree under stack
|
|
3830
|
-
if (defect.kind === "too-deep") return `The nested template tree under stack
|
|
3831
|
-
if (defect.kind === "escaping-path") return `The nested template tree under stack
|
|
3832
|
-
return `The nested template tree under stack
|
|
3873
|
+
if (defect.kind === "too-large") return `The nested template tree under stack ${displayStackName(stackName)} has more than ${MAX_ROWS_FOLLOWED} nested-stack rows to follow (the walk stopped at ${renderChain(defect.chain)}). That is far beyond any CDK-generated assembly. Symlinked directories can give one template file many paths, which multiplies the tree without ever repeating on one chain. Refusing to ${action}.`;
|
|
3874
|
+
if (defect.kind === "too-deep") return `The nested template tree under stack ${displayStackName(stackName)} nests more than ${512} levels deep: ${renderChain(defect.chain)}. No tree that deep can deploy, because each level lengthens the child's state key and S3 caps a key at 1024 bytes. ${provenance}`;
|
|
3875
|
+
if (defect.kind === "escaping-path") return `The nested template tree under stack ${displayStackName(stackName)} has nested stack ${displayIdent(defect.logicalId)} (reached through ${renderChain(defect.chain)}) with Metadata['aws:asset:path']=${displayAssemblyPath(defect.assetPath)} which ${renderAssemblyPathEscape(defect.escape, defect.dir, action)}`;
|
|
3876
|
+
return `The nested template tree under stack ${displayStackName(stackName)} has nested stack ${displayIdent(defect.logicalId)} (reached through ${renderChain(defect.chain)}) with Metadata['aws:asset:path']=${displayAssemblyPath(defect.assetPath)} which is absolute. ${provenance}`;
|
|
3833
3877
|
}
|
|
3834
3878
|
|
|
3835
3879
|
//#endregion
|
|
@@ -4598,8 +4642,8 @@ var ExportIndexStore = class {
|
|
|
4598
4642
|
*/
|
|
4599
4643
|
warnOnForeignOverwrite(existing, exportName, stackName, producerRegion) {
|
|
4600
4644
|
if (!existing || existing.producerStack === stackName) return;
|
|
4601
|
-
const
|
|
4602
|
-
this.logger.warn(`Export
|
|
4645
|
+
const theirs = displayStackName(existing.producerStack);
|
|
4646
|
+
this.logger.warn(`Export ${displayIdent(exportName)} is published by both ${theirs} (${displayIdent(existing.producerRegion)}) and ${displayStackName(stackName)} (${displayIdent(producerRegion)}); the exports index keeps the latest writer, so an Fn::ImportValue on it binds to whichever deployed last. CloudFormation refuses a second producer of the same export name — rename one of the two exports. (If ${theirs} predates cdkd's state schema v9, this is its stale entry for a plain output of that name, and its next deploy clears it.)`);
|
|
4603
4647
|
}
|
|
4604
4648
|
async applyPatch(exportName, entry, requireOwner) {
|
|
4605
4649
|
await this.ensureLoaded();
|
|
@@ -4607,7 +4651,7 @@ var ExportIndexStore = class {
|
|
|
4607
4651
|
if (requireOwner) {
|
|
4608
4652
|
const current = this.loadState.entries.get(exportName);
|
|
4609
4653
|
if (!current || current.producerStack !== requireOwner.producerStack || current.producerRegion !== requireOwner.producerRegion) {
|
|
4610
|
-
this.logger.warn(`Exports index entry ownership changed under a patch; refusing to write it. Expected producer
|
|
4654
|
+
this.logger.warn(`Exports index entry ownership changed under a patch; refusing to write it. Expected producer ${displayStackName(requireOwner.producerStack)} (${displayIdent(requireOwner.producerRegion)}), found ${current ? `${displayStackName(current.producerStack)} (${displayIdent(current.producerRegion)})` : "no entry"}.`);
|
|
4611
4655
|
return false;
|
|
4612
4656
|
}
|
|
4613
4657
|
}
|
|
@@ -5862,10 +5906,10 @@ var IAMInstanceProfileProvider = class {
|
|
|
5862
5906
|
async import(input) {
|
|
5863
5907
|
const explicit = resolveExplicitPhysicalId(input, "InstanceProfileName");
|
|
5864
5908
|
if (explicit) try {
|
|
5865
|
-
await this.iamClient.send(new GetInstanceProfileCommand({ InstanceProfileName: explicit }));
|
|
5909
|
+
const resp = await this.iamClient.send(new GetInstanceProfileCommand({ InstanceProfileName: explicit }));
|
|
5866
5910
|
return {
|
|
5867
5911
|
physicalId: explicit,
|
|
5868
|
-
attributes: {}
|
|
5912
|
+
attributes: definedAttributes({ Arn: resp.InstanceProfile?.Arn })
|
|
5869
5913
|
};
|
|
5870
5914
|
} catch (err) {
|
|
5871
5915
|
if (err instanceof NoSuchEntityException) return null;
|
|
@@ -7199,10 +7243,10 @@ var IAMUserGroupProvider = class {
|
|
|
7199
7243
|
async importUser(input) {
|
|
7200
7244
|
const explicit = resolveExplicitPhysicalId(input, "UserName");
|
|
7201
7245
|
if (explicit) try {
|
|
7202
|
-
await this.iamClient.send(new GetUserCommand({ UserName: explicit }));
|
|
7246
|
+
const resp = await this.iamClient.send(new GetUserCommand({ UserName: explicit }));
|
|
7203
7247
|
return {
|
|
7204
7248
|
physicalId: explicit,
|
|
7205
|
-
attributes: {}
|
|
7249
|
+
attributes: definedAttributes({ Arn: resp.User?.Arn })
|
|
7206
7250
|
};
|
|
7207
7251
|
} catch (err) {
|
|
7208
7252
|
if (err instanceof NoSuchEntityException) return null;
|
|
@@ -7213,10 +7257,10 @@ var IAMUserGroupProvider = class {
|
|
|
7213
7257
|
async importGroup(input) {
|
|
7214
7258
|
const explicit = resolveExplicitPhysicalId(input, "GroupName");
|
|
7215
7259
|
if (explicit) try {
|
|
7216
|
-
await this.iamClient.send(new GetGroupCommand({ GroupName: explicit }));
|
|
7260
|
+
const resp = await this.iamClient.send(new GetGroupCommand({ GroupName: explicit }));
|
|
7217
7261
|
return {
|
|
7218
7262
|
physicalId: explicit,
|
|
7219
|
-
attributes: {}
|
|
7263
|
+
attributes: definedAttributes({ Arn: resp.Group?.Arn })
|
|
7220
7264
|
};
|
|
7221
7265
|
} catch (err) {
|
|
7222
7266
|
if (err instanceof NoSuchEntityException) return null;
|
|
@@ -13868,6 +13912,29 @@ function isSnsTopicArnList(value) {
|
|
|
13868
13912
|
*/
|
|
13869
13913
|
const LAMBDA_CLEANUP_DELETE_MAX_ATTEMPTS = 3;
|
|
13870
13914
|
/**
|
|
13915
|
+
* Refuse `CodeSigningConfigArn` / `RuntimeManagementConfig` on a
|
|
13916
|
+
* container-image function (`PackageType: Image`), BEFORE any Lambda call.
|
|
13917
|
+
* AWS rejects both there with `InvalidParameterValueException`: the image
|
|
13918
|
+
* carries its own runtime, so there are no runtime-management controls, and
|
|
13919
|
+
* Lambda code signing does not apply to images (issue
|
|
13920
|
+
* [#1894](https://github.com/go-to-k/cdkd/issues/1894)). The READ side skips
|
|
13921
|
+
* the matching `Get*` calls for the same reason (see `readCurrentState`). Without it the create either
|
|
13922
|
+
* fails on `CreateFunction` (code signing) or creates the function, fails the
|
|
13923
|
+
* post-create `PutRuntimeManagementConfig` and deletes it again; the update
|
|
13924
|
+
* fails part-way through on the Put.
|
|
13925
|
+
*
|
|
13926
|
+
* Unconditional, including on a rollback replay (`replayingState`): AWS
|
|
13927
|
+
* rejects the combination every time, so no state record can carry it and a
|
|
13928
|
+
* downgraded warning could only report success over a call that then fails
|
|
13929
|
+
* (the `.claude/rules/provider-replay-and-refusals.md` exception).
|
|
13930
|
+
*/
|
|
13931
|
+
function refuseImageFunctionUnsupported(logicalId, resourceType, properties, physicalId) {
|
|
13932
|
+
if (properties["PackageType"] !== "Image") return;
|
|
13933
|
+
const declared = [properties["CodeSigningConfigArn"] !== void 0 ? "CodeSigningConfigArn" : void 0, properties["RuntimeManagementConfig"] !== void 0 ? "RuntimeManagementConfig" : void 0].filter((key) => key !== void 0);
|
|
13934
|
+
if (declared.length === 0) return;
|
|
13935
|
+
throw markNonRetryable(new ProvisioningError(`Lambda function ${logicalId} is a container-image function (PackageType: Image), and AWS rejects ${declared.join(" and ")} on one: an image carries its own runtime and Lambda code signing does not apply to images. Remove ${declared.length === 1 ? "it" : "them"} from the function's properties.`, resourceType, logicalId, physicalId));
|
|
13936
|
+
}
|
|
13937
|
+
/**
|
|
13871
13938
|
* Pick the inline-code filename for a Lambda runtime.
|
|
13872
13939
|
*
|
|
13873
13940
|
* CloudFormation's `Code.ZipFile` auto-zips inline code into a file named
|
|
@@ -13962,6 +14029,7 @@ var LambdaFunctionProvider = class {
|
|
|
13962
14029
|
const role = properties["Role"];
|
|
13963
14030
|
if (!code) throw new ProvisioningError(`Code is required for Lambda function ${logicalId}`, resourceType, logicalId);
|
|
13964
14031
|
if (!role) throw new ProvisioningError(`Role is required for Lambda function ${logicalId}`, resourceType, logicalId);
|
|
14032
|
+
refuseImageFunctionUnsupported(logicalId, resourceType, properties);
|
|
13965
14033
|
try {
|
|
13966
14034
|
let tags;
|
|
13967
14035
|
if (properties["Tags"]) {
|
|
@@ -14112,6 +14180,7 @@ var LambdaFunctionProvider = class {
|
|
|
14112
14180
|
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
14113
14181
|
const debug = (message) => this.logger.debug(mask(message));
|
|
14114
14182
|
this.logger.debug(`Updating Lambda function ${logicalId}: ${physicalId}`);
|
|
14183
|
+
refuseImageFunctionUnsupported(logicalId, resourceType, properties, physicalId);
|
|
14115
14184
|
try {
|
|
14116
14185
|
const configFields = [
|
|
14117
14186
|
"Role",
|
|
@@ -27953,10 +28022,17 @@ var SSMParameterProvider = class {
|
|
|
27953
28022
|
if (explicit) {
|
|
27954
28023
|
this.refuseUnwritableParameterId(input, explicit);
|
|
27955
28024
|
try {
|
|
27956
|
-
const
|
|
28025
|
+
const resp = await this.ssmClient.send(new GetParameterCommand({ Name: explicit }));
|
|
28026
|
+
const arn = resp.Parameter?.ARN;
|
|
28027
|
+
const declared = input.properties?.["Value"];
|
|
28028
|
+
const literalValue = typeof declared === "string" && !declared.includes("{{resolve:");
|
|
27957
28029
|
return {
|
|
27958
28030
|
physicalId: explicit,
|
|
27959
|
-
attributes: {
|
|
28031
|
+
attributes: definedAttributes({
|
|
28032
|
+
Type: resp.Parameter?.Type,
|
|
28033
|
+
...literalValue && { Value: resp.Parameter?.Value },
|
|
28034
|
+
Arn: arn
|
|
28035
|
+
})
|
|
27960
28036
|
};
|
|
27961
28037
|
} catch (err) {
|
|
27962
28038
|
if (err instanceof ParameterNotFound) return null;
|
|
@@ -28701,6 +28777,39 @@ var EventBridgeBusProvider = class {
|
|
|
28701
28777
|
}
|
|
28702
28778
|
};
|
|
28703
28779
|
|
|
28780
|
+
//#endregion
|
|
28781
|
+
//#region src/utils/ipv4-cidr.ts
|
|
28782
|
+
/**
|
|
28783
|
+
* Return the host-bit-cleared form of an IPv4 CIDR (`100.68.0.18/18` ->
|
|
28784
|
+
* `100.68.0.0/18`), or `undefined` when the input is not an IPv4 CIDR at all
|
|
28785
|
+
* (an IPv6 CIDR, a `pl-…` prefix-list id, or anything malformed).
|
|
28786
|
+
*
|
|
28787
|
+
* AWS rewrites a non-canonical CIDR on `CreateRoute`, so a route id that
|
|
28788
|
+
* spells the template's CIDR can differ from the destination AWS reports
|
|
28789
|
+
* (issue #1771). `EC2Provider`'s import compares through this (issue #3661).
|
|
28790
|
+
* `src/cli/commands/export.ts` still carries a private copy of the same
|
|
28791
|
+
* function; fold it onto this one once the open PR holding that file lands.
|
|
28792
|
+
*/
|
|
28793
|
+
function canonicalizeIpv4Cidr$1(value) {
|
|
28794
|
+
const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/.exec(value);
|
|
28795
|
+
if (!match) return void 0;
|
|
28796
|
+
const octets = [
|
|
28797
|
+
match[1],
|
|
28798
|
+
match[2],
|
|
28799
|
+
match[3],
|
|
28800
|
+
match[4]
|
|
28801
|
+
].map(Number);
|
|
28802
|
+
const prefixLength = Number(match[5]);
|
|
28803
|
+
if (prefixLength > 32 || octets.some((octet) => octet > 255)) return void 0;
|
|
28804
|
+
const network = ((octets[0] << 24 | octets[1] << 16 | octets[2] << 8 | octets[3]) >>> 0 & (prefixLength === 0 ? 0 : 4294967295 << 32 - prefixLength >>> 0)) >>> 0;
|
|
28805
|
+
return `${[
|
|
28806
|
+
network >>> 24,
|
|
28807
|
+
network >>> 16 & 255,
|
|
28808
|
+
network >>> 8 & 255,
|
|
28809
|
+
network & 255
|
|
28810
|
+
].join(".")}/${prefixLength}`;
|
|
28811
|
+
}
|
|
28812
|
+
|
|
28704
28813
|
//#endregion
|
|
28705
28814
|
//#region src/provisioning/providers/idempotency-token.ts
|
|
28706
28815
|
/**
|
|
@@ -30225,12 +30334,16 @@ var EC2Provider = class {
|
|
|
30225
30334
|
try {
|
|
30226
30335
|
const ingressRules = properties["SecurityGroupIngress"];
|
|
30227
30336
|
const egressRules = properties["SecurityGroupEgress"];
|
|
30228
|
-
|
|
30229
|
-
|
|
30230
|
-
|
|
30231
|
-
|
|
30232
|
-
|
|
30233
|
-
|
|
30337
|
+
let firstRejection;
|
|
30338
|
+
const recordRejection = (branch) => branch.catch((error) => {
|
|
30339
|
+
firstRejection ??= { error };
|
|
30340
|
+
});
|
|
30341
|
+
await Promise.all([
|
|
30342
|
+
recordRejection(this.applyTags(groupId, properties, logicalId)),
|
|
30343
|
+
recordRejection(this.authorizeInlineIngress(groupId, ingressRules)),
|
|
30344
|
+
recordRejection(this.applyInlineEgress(groupId, egressRules))
|
|
30345
|
+
]);
|
|
30346
|
+
if (firstRejection !== void 0) throw firstRejection.error;
|
|
30234
30347
|
} catch (innerError) {
|
|
30235
30348
|
try {
|
|
30236
30349
|
await this.ec2Client.send(new DeleteSecurityGroupCommand({ GroupId: groupId }));
|
|
@@ -31572,12 +31685,14 @@ var EC2Provider = class {
|
|
|
31572
31685
|
* id, and records cdkd's composite `<groupId>|<ipProtocol>|<fromPort>|<toPort>`
|
|
31573
31686
|
* plus the rule id as the `Id` attribute (issue #1761).
|
|
31574
31687
|
*
|
|
31575
|
-
*
|
|
31576
|
-
*
|
|
31577
|
-
*
|
|
31578
|
-
*
|
|
31579
|
-
*
|
|
31580
|
-
*
|
|
31688
|
+
* - RouteTable, Route, InternetGateway, VPCGatewayAttachment, NetworkAcl,
|
|
31689
|
+
* NetworkAclEntry, SubnetRouteTableAssociation, SubnetNetworkAclAssociation,
|
|
31690
|
+
* Instance (issue #3661) — they used to return `null` on the premise that
|
|
31691
|
+
* cdkd reconstructs them at deploy time, which `--migrate-from-cloudformation`
|
|
31692
|
+
* breaks: the CloudFormation stack is retired with them live, and the
|
|
31693
|
+
* re-create duplicates or conflicts. VPCGatewayAttachment and
|
|
31694
|
+
* NetworkAclEntry rebuild cdkd's composite from the template, since
|
|
31695
|
+
* CloudFormation's id for them does not carry it.
|
|
31581
31696
|
*
|
|
31582
31697
|
* There is no `aws:cdk:path` tag lookup: AWS rejects `aws:`-prefixed tag
|
|
31583
31698
|
* writes, so that tag never exists on a real resource and a
|
|
@@ -31587,7 +31702,7 @@ var EC2Provider = class {
|
|
|
31587
31702
|
* physical-name property instead.
|
|
31588
31703
|
*/
|
|
31589
31704
|
async import(input) {
|
|
31590
|
-
if (input.knownPhysicalId) return this.verifyExplicit(input.logicalId, input.resourceType, input.knownPhysicalId);
|
|
31705
|
+
if (input.knownPhysicalId) return this.verifyExplicit(input.logicalId, input.resourceType, input.knownPhysicalId, input.properties ?? {});
|
|
31591
31706
|
return null;
|
|
31592
31707
|
}
|
|
31593
31708
|
/**
|
|
@@ -32150,17 +32265,23 @@ var EC2Provider = class {
|
|
|
32150
32265
|
}
|
|
32151
32266
|
}
|
|
32152
32267
|
}
|
|
32153
|
-
async verifyExplicit(logicalId, resourceType, physicalId) {
|
|
32268
|
+
async verifyExplicit(logicalId, resourceType, physicalId, properties) {
|
|
32154
32269
|
try {
|
|
32155
32270
|
switch (resourceType) {
|
|
32156
32271
|
case "AWS::EC2::VPC": return (await this.ec2Client.send(new DescribeVpcsCommand({ VpcIds: [physicalId] }))).Vpcs?.[0] ? {
|
|
32157
32272
|
physicalId,
|
|
32158
32273
|
attributes: {}
|
|
32159
32274
|
} : null;
|
|
32160
|
-
case "AWS::EC2::Subnet":
|
|
32161
|
-
physicalId
|
|
32162
|
-
|
|
32163
|
-
|
|
32275
|
+
case "AWS::EC2::Subnet": {
|
|
32276
|
+
const subnet = (await this.ec2Client.send(new DescribeSubnetsCommand({ SubnetIds: [physicalId] }))).Subnets?.[0];
|
|
32277
|
+
return subnet ? {
|
|
32278
|
+
physicalId,
|
|
32279
|
+
attributes: definedAttributes({
|
|
32280
|
+
SubnetId: physicalId,
|
|
32281
|
+
AvailabilityZone: subnet.AvailabilityZone
|
|
32282
|
+
})
|
|
32283
|
+
} : null;
|
|
32284
|
+
}
|
|
32164
32285
|
case "AWS::EC2::SecurityGroup": {
|
|
32165
32286
|
const group = (await this.ec2Client.send(new DescribeSecurityGroupsCommand({ GroupIds: [physicalId] }))).SecurityGroups?.[0];
|
|
32166
32287
|
if (!group) return null;
|
|
@@ -32233,6 +32354,125 @@ var EC2Provider = class {
|
|
|
32233
32354
|
}
|
|
32234
32355
|
};
|
|
32235
32356
|
}
|
|
32357
|
+
case "AWS::EC2::RouteTable":
|
|
32358
|
+
if (!/^rtb-[0-9a-f]+$/.test(physicalId)) return null;
|
|
32359
|
+
return (await this.ec2Client.send(new DescribeRouteTablesCommand({ RouteTableIds: [physicalId] }))).RouteTables?.[0] ? {
|
|
32360
|
+
physicalId,
|
|
32361
|
+
attributes: { RouteTableId: physicalId }
|
|
32362
|
+
} : null;
|
|
32363
|
+
case "AWS::EC2::InternetGateway":
|
|
32364
|
+
if (!/^igw-[0-9a-f]+$/.test(physicalId)) return null;
|
|
32365
|
+
return (await this.ec2Client.send(new DescribeInternetGatewaysCommand({ InternetGatewayIds: [physicalId] }))).InternetGateways?.[0] ? {
|
|
32366
|
+
physicalId,
|
|
32367
|
+
attributes: { InternetGatewayId: physicalId }
|
|
32368
|
+
} : null;
|
|
32369
|
+
case "AWS::EC2::NetworkAcl":
|
|
32370
|
+
if (!/^acl-[0-9a-f]+$/.test(physicalId)) return null;
|
|
32371
|
+
return (await this.ec2Client.send(new DescribeNetworkAclsCommand({ NetworkAclIds: [physicalId] }))).NetworkAcls?.[0] ? {
|
|
32372
|
+
physicalId,
|
|
32373
|
+
attributes: { Id: physicalId }
|
|
32374
|
+
} : null;
|
|
32375
|
+
case "AWS::EC2::Route": {
|
|
32376
|
+
const [routeTableId, destination, ...rest] = physicalId.split("|");
|
|
32377
|
+
if (rest.length > 0 || !routeTableId || !destination) return null;
|
|
32378
|
+
if (!/^rtb-[0-9a-f]+$/.test(routeTableId)) return null;
|
|
32379
|
+
const resp = await this.ec2Client.send(new DescribeRouteTablesCommand({ RouteTableIds: [routeTableId] }));
|
|
32380
|
+
const wanted = canonicalizeIpv4Cidr$1(destination) ?? destination;
|
|
32381
|
+
return resp.RouteTables?.[0]?.Routes?.some((r) => r.DestinationCidrBlock !== void 0 && (canonicalizeIpv4Cidr$1(r.DestinationCidrBlock) ?? r.DestinationCidrBlock) === wanted || r.DestinationIpv6CidrBlock === destination || r.DestinationPrefixListId === destination) ? {
|
|
32382
|
+
physicalId,
|
|
32383
|
+
attributes: {}
|
|
32384
|
+
} : null;
|
|
32385
|
+
}
|
|
32386
|
+
case "AWS::EC2::VPCGatewayAttachment": {
|
|
32387
|
+
const segments = physicalId.split("|");
|
|
32388
|
+
if (segments.length !== 2) return null;
|
|
32389
|
+
if (segments.includes("VGW") || properties["VpnGatewayId"] !== void 0) return null;
|
|
32390
|
+
const vpcId = segments.find((seg) => /^vpc-[0-9a-f]+$/.test(seg)) ?? (typeof properties["VpcId"] === "string" ? properties["VpcId"] : void 0);
|
|
32391
|
+
if (!vpcId || !/^vpc-[0-9a-f]+$/.test(vpcId)) return null;
|
|
32392
|
+
const declared = segments.find((seg) => /^igw-[0-9a-f]+$/.test(seg)) ?? (typeof properties["InternetGatewayId"] === "string" ? properties["InternetGatewayId"] : void 0);
|
|
32393
|
+
if (declared !== void 0 && !/^igw-[0-9a-f]+$/.test(declared)) return null;
|
|
32394
|
+
const gateway = (await this.ec2Client.send(new DescribeInternetGatewaysCommand(declared ? { InternetGatewayIds: [declared] } : { Filters: [{
|
|
32395
|
+
Name: "attachment.vpc-id",
|
|
32396
|
+
Values: [vpcId]
|
|
32397
|
+
}] }))).InternetGateways?.find((g) => g.Attachments?.some((a) => a.VpcId === vpcId && ["available", "attached"].includes(String(a.State))));
|
|
32398
|
+
if (!gateway?.InternetGatewayId) return null;
|
|
32399
|
+
const attachmentSegments = [{
|
|
32400
|
+
name: "internetGatewayId",
|
|
32401
|
+
value: gateway.InternetGatewayId
|
|
32402
|
+
}, {
|
|
32403
|
+
name: "vpcId",
|
|
32404
|
+
value: vpcId
|
|
32405
|
+
}];
|
|
32406
|
+
const refusal = compositeIdSeparatorRefusal(resourceType, logicalId, attachmentSegments);
|
|
32407
|
+
if (refusal !== void 0) {
|
|
32408
|
+
this.logger.warn(`${refusal} Skipping import.`);
|
|
32409
|
+
return null;
|
|
32410
|
+
}
|
|
32411
|
+
return {
|
|
32412
|
+
physicalId: packCompositeId(resourceType, logicalId, attachmentSegments),
|
|
32413
|
+
attributes: {}
|
|
32414
|
+
};
|
|
32415
|
+
}
|
|
32416
|
+
case "AWS::EC2::NetworkAclEntry": {
|
|
32417
|
+
const own = /^(acl-[0-9a-f]+)\|(\d+)\|(true|false)$/.exec(physicalId);
|
|
32418
|
+
const networkAclId = own ? own[1] : typeof properties["NetworkAclId"] === "string" ? properties["NetworkAclId"] : void 0;
|
|
32419
|
+
const ruleNumber = own ? Number(own[2]) : Number(properties["RuleNumber"]);
|
|
32420
|
+
const egress = own ? own[3] === "true" : properties["Egress"] === true || properties["Egress"] === "true";
|
|
32421
|
+
if (!networkAclId || !/^acl-[0-9a-f]+$/.test(networkAclId)) return null;
|
|
32422
|
+
if (!Number.isInteger(ruleNumber)) return null;
|
|
32423
|
+
if (!(await this.ec2Client.send(new DescribeNetworkAclsCommand({ NetworkAclIds: [networkAclId] }))).NetworkAcls?.[0]?.Entries?.find((e) => e.RuleNumber === ruleNumber && (e.Egress ?? false) === egress)) return null;
|
|
32424
|
+
const entrySegments = [
|
|
32425
|
+
{
|
|
32426
|
+
name: "networkAclId",
|
|
32427
|
+
value: networkAclId
|
|
32428
|
+
},
|
|
32429
|
+
{
|
|
32430
|
+
name: "ruleNumber",
|
|
32431
|
+
value: ruleNumber
|
|
32432
|
+
},
|
|
32433
|
+
{
|
|
32434
|
+
name: "egress",
|
|
32435
|
+
value: egress
|
|
32436
|
+
}
|
|
32437
|
+
];
|
|
32438
|
+
const refusal = compositeIdSeparatorRefusal(resourceType, logicalId, entrySegments);
|
|
32439
|
+
if (refusal !== void 0) {
|
|
32440
|
+
this.logger.warn(`${refusal} Skipping import.`);
|
|
32441
|
+
return null;
|
|
32442
|
+
}
|
|
32443
|
+
return {
|
|
32444
|
+
physicalId: packCompositeId(resourceType, logicalId, entrySegments),
|
|
32445
|
+
attributes: {}
|
|
32446
|
+
};
|
|
32447
|
+
}
|
|
32448
|
+
case "AWS::EC2::SubnetRouteTableAssociation":
|
|
32449
|
+
if (!/^rtbassoc-[0-9a-f]+$/.test(physicalId)) return null;
|
|
32450
|
+
return (await this.ec2Client.send(new DescribeRouteTablesCommand({ Filters: [{
|
|
32451
|
+
Name: "association.route-table-association-id",
|
|
32452
|
+
Values: [physicalId]
|
|
32453
|
+
}] }))).RouteTables?.[0] ? {
|
|
32454
|
+
physicalId,
|
|
32455
|
+
attributes: {}
|
|
32456
|
+
} : null;
|
|
32457
|
+
case "AWS::EC2::SubnetNetworkAclAssociation":
|
|
32458
|
+
if (!/^aclassoc-[0-9a-f]+$/.test(physicalId)) return null;
|
|
32459
|
+
return (await this.ec2Client.send(new DescribeNetworkAclsCommand({ Filters: [{
|
|
32460
|
+
Name: "association.association-id",
|
|
32461
|
+
Values: [physicalId]
|
|
32462
|
+
}] }))).NetworkAcls?.[0] ? {
|
|
32463
|
+
physicalId,
|
|
32464
|
+
attributes: { AssociationId: physicalId }
|
|
32465
|
+
} : null;
|
|
32466
|
+
case "AWS::EC2::Instance": {
|
|
32467
|
+
if (!/^i-[0-9a-f]+$/.test(physicalId)) return null;
|
|
32468
|
+
const instance = (await this.ec2Client.send(new DescribeInstancesCommand({ InstanceIds: [physicalId] }))).Reservations?.[0]?.Instances?.[0];
|
|
32469
|
+
const state = instance?.State?.Name;
|
|
32470
|
+
if (!instance || state === "terminated" || state === "shutting-down") return null;
|
|
32471
|
+
return {
|
|
32472
|
+
physicalId,
|
|
32473
|
+
attributes: describedInstanceAttributes(physicalId, instance)
|
|
32474
|
+
};
|
|
32475
|
+
}
|
|
32236
32476
|
default: return null;
|
|
32237
32477
|
}
|
|
32238
32478
|
} catch (error) {
|
|
@@ -35799,13 +36039,28 @@ var CloudFrontOAIProvider = class {
|
|
|
35799
36039
|
*
|
|
35800
36040
|
* Users adopting an existing OAI should pass
|
|
35801
36041
|
* `--resource <logicalId>=<oaiId>` (e.g. `E1ABCDEF123456`).
|
|
36042
|
+
*
|
|
36043
|
+
* The override is read back (issue #3627): `S3CanonicalUserId` is the
|
|
36044
|
+
* attribute an S3 bucket policy grants the OAI by, `create()` records it,
|
|
36045
|
+
* and the resolver cannot build it from the id. Returns `null` when no OAI
|
|
36046
|
+
* exists behind the id.
|
|
35802
36047
|
*/
|
|
35803
36048
|
async import(input) {
|
|
35804
|
-
if (input.knownPhysicalId) return
|
|
36049
|
+
if (!input.knownPhysicalId) return null;
|
|
36050
|
+
let resp;
|
|
36051
|
+
try {
|
|
36052
|
+
resp = await this.cloudFrontClient.send(new GetCloudFrontOriginAccessIdentityCommand({ Id: input.knownPhysicalId }));
|
|
36053
|
+
} catch (err) {
|
|
36054
|
+
if (err instanceof NoSuchCloudFrontOriginAccessIdentity) return null;
|
|
36055
|
+
throw err;
|
|
36056
|
+
}
|
|
36057
|
+
return {
|
|
35805
36058
|
physicalId: input.knownPhysicalId,
|
|
35806
|
-
attributes: {
|
|
36059
|
+
attributes: definedAttributes({
|
|
36060
|
+
Id: input.knownPhysicalId,
|
|
36061
|
+
S3CanonicalUserId: resp.CloudFrontOriginAccessIdentity?.S3CanonicalUserId
|
|
36062
|
+
})
|
|
35807
36063
|
};
|
|
35808
|
-
return null;
|
|
35809
36064
|
}
|
|
35810
36065
|
};
|
|
35811
36066
|
|
|
@@ -37933,20 +38188,24 @@ var AgentCoreEvaluatorProvider = class {
|
|
|
37933
38188
|
*/
|
|
37934
38189
|
async import(input) {
|
|
37935
38190
|
if (!input.knownPhysicalId) return null;
|
|
37936
|
-
|
|
37937
|
-
|
|
37938
|
-
|
|
37939
|
-
|
|
37940
|
-
|
|
37941
|
-
|
|
37942
|
-
|
|
37943
|
-
|
|
38191
|
+
const isArn = input.knownPhysicalId.includes(":evaluator/");
|
|
38192
|
+
let response;
|
|
38193
|
+
try {
|
|
38194
|
+
response = await this.client.send(new GetEvaluatorCommand({ evaluatorId: evaluatorIdFromArn(input.knownPhysicalId) }));
|
|
38195
|
+
} catch (err) {
|
|
38196
|
+
if (err instanceof ResourceNotFoundException$6) return null;
|
|
38197
|
+
throw err;
|
|
38198
|
+
}
|
|
38199
|
+
const evaluatorArn = isArn ? input.knownPhysicalId : response.evaluatorArn;
|
|
38200
|
+
if (!evaluatorArn) return null;
|
|
37944
38201
|
return {
|
|
37945
|
-
physicalId:
|
|
37946
|
-
attributes: {
|
|
37947
|
-
EvaluatorArn:
|
|
37948
|
-
EvaluatorId: response.evaluatorId ?? input.knownPhysicalId
|
|
37949
|
-
|
|
38202
|
+
physicalId: evaluatorArn,
|
|
38203
|
+
attributes: definedAttributes({
|
|
38204
|
+
EvaluatorArn: evaluatorArn,
|
|
38205
|
+
EvaluatorId: response.evaluatorId ?? evaluatorIdFromArn(input.knownPhysicalId),
|
|
38206
|
+
Status: response.status,
|
|
38207
|
+
CreatedAt: response.createdAt?.toISOString()
|
|
38208
|
+
})
|
|
37950
38209
|
};
|
|
37951
38210
|
}
|
|
37952
38211
|
};
|
|
@@ -40340,6 +40599,30 @@ const LOAD_BALANCER_ATTRIBUTE_DEFAULTS = {
|
|
|
40340
40599
|
/** @see LOAD_BALANCER_ATTRIBUTE_DEFAULTS — same rule, Listener key table. */
|
|
40341
40600
|
const LISTENER_ATTRIBUTE_DEFAULTS = { "routing.http.response.server.enabled": "true" };
|
|
40342
40601
|
/**
|
|
40602
|
+
* The attribute map a load balancer records, shared by `create()` and
|
|
40603
|
+
* `import()` (issue #3627).
|
|
40604
|
+
*/
|
|
40605
|
+
function loadBalancerAttributes(lb, lbArn) {
|
|
40606
|
+
return definedAttributes({
|
|
40607
|
+
DNSName: lb.DNSName,
|
|
40608
|
+
CanonicalHostedZoneID: lb.CanonicalHostedZoneId,
|
|
40609
|
+
LoadBalancerArn: lbArn,
|
|
40610
|
+
LoadBalancerFullName: lbArn.split("/").slice(1).join("/"),
|
|
40611
|
+
LoadBalancerName: lb.LoadBalancerName
|
|
40612
|
+
});
|
|
40613
|
+
}
|
|
40614
|
+
/**
|
|
40615
|
+
* The attribute map a target group records, shared by `create()`,
|
|
40616
|
+
* `update()` and `import()` (issue #3627).
|
|
40617
|
+
*/
|
|
40618
|
+
function targetGroupAttributes(tg, tgArn) {
|
|
40619
|
+
return definedAttributes({
|
|
40620
|
+
TargetGroupArn: tgArn,
|
|
40621
|
+
TargetGroupFullName: tgArn.split(":").pop(),
|
|
40622
|
+
TargetGroupName: tg.TargetGroupName
|
|
40623
|
+
});
|
|
40624
|
+
}
|
|
40625
|
+
/**
|
|
40343
40626
|
* AWS ELBv2 Provider
|
|
40344
40627
|
*
|
|
40345
40628
|
* Implements resource provisioning for ELBv2 resources:
|
|
@@ -40597,13 +40880,7 @@ var ELBv2Provider = class {
|
|
|
40597
40880
|
}
|
|
40598
40881
|
return {
|
|
40599
40882
|
physicalId: lbArn,
|
|
40600
|
-
attributes:
|
|
40601
|
-
DNSName: lb.DNSName,
|
|
40602
|
-
CanonicalHostedZoneID: lb.CanonicalHostedZoneId,
|
|
40603
|
-
LoadBalancerArn: lbArn,
|
|
40604
|
-
LoadBalancerFullName: lbArn.split("/").slice(1).join("/"),
|
|
40605
|
-
LoadBalancerName: lb.LoadBalancerName
|
|
40606
|
-
}
|
|
40883
|
+
attributes: loadBalancerAttributes(lb, lbArn)
|
|
40607
40884
|
};
|
|
40608
40885
|
} catch (error) {
|
|
40609
40886
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -40840,11 +41117,7 @@ var ELBv2Provider = class {
|
|
|
40840
41117
|
}
|
|
40841
41118
|
return {
|
|
40842
41119
|
physicalId: tgArn,
|
|
40843
|
-
attributes:
|
|
40844
|
-
TargetGroupArn: tgArn,
|
|
40845
|
-
TargetGroupFullName: tgArn.split(":").pop()?.replace("targetgroup/", ""),
|
|
40846
|
-
TargetGroupName: tg.TargetGroupName
|
|
40847
|
-
}
|
|
41120
|
+
attributes: targetGroupAttributes(tg, tgArn)
|
|
40848
41121
|
};
|
|
40849
41122
|
} catch (error) {
|
|
40850
41123
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -40922,11 +41195,7 @@ var ELBv2Provider = class {
|
|
|
40922
41195
|
return {
|
|
40923
41196
|
physicalId,
|
|
40924
41197
|
wasReplaced: false,
|
|
40925
|
-
attributes: {
|
|
40926
|
-
TargetGroupArn: physicalId,
|
|
40927
|
-
TargetGroupFullName: physicalId.split(":").pop()?.replace("targetgroup/", ""),
|
|
40928
|
-
TargetGroupName: tg?.TargetGroupName
|
|
40929
|
-
}
|
|
41198
|
+
attributes: targetGroupAttributes(tg ?? {}, physicalId)
|
|
40930
41199
|
};
|
|
40931
41200
|
} catch (error) {
|
|
40932
41201
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -41587,10 +41856,10 @@ var ELBv2Provider = class {
|
|
|
41587
41856
|
}
|
|
41588
41857
|
async importLoadBalancer(input) {
|
|
41589
41858
|
if (input.knownPhysicalId) try {
|
|
41590
|
-
const
|
|
41591
|
-
return
|
|
41592
|
-
physicalId:
|
|
41593
|
-
attributes:
|
|
41859
|
+
const lb = (await this.getClient().send(new DescribeLoadBalancersCommand({ LoadBalancerArns: [input.knownPhysicalId] }))).LoadBalancers?.[0];
|
|
41860
|
+
return lb?.LoadBalancerArn ? {
|
|
41861
|
+
physicalId: lb.LoadBalancerArn,
|
|
41862
|
+
attributes: loadBalancerAttributes(lb, lb.LoadBalancerArn)
|
|
41594
41863
|
} : null;
|
|
41595
41864
|
} catch (err) {
|
|
41596
41865
|
if (this.isNotFoundError(err)) return null;
|
|
@@ -41600,10 +41869,10 @@ var ELBv2Provider = class {
|
|
|
41600
41869
|
}
|
|
41601
41870
|
async importTargetGroup(input) {
|
|
41602
41871
|
if (input.knownPhysicalId) try {
|
|
41603
|
-
const
|
|
41604
|
-
return
|
|
41605
|
-
physicalId:
|
|
41606
|
-
attributes:
|
|
41872
|
+
const tg = (await this.getClient().send(new DescribeTargetGroupsCommand({ TargetGroupArns: [input.knownPhysicalId] }))).TargetGroups?.[0];
|
|
41873
|
+
return tg?.TargetGroupArn ? {
|
|
41874
|
+
physicalId: tg.TargetGroupArn,
|
|
41875
|
+
attributes: targetGroupAttributes(tg, tg.TargetGroupArn)
|
|
41607
41876
|
} : null;
|
|
41608
41877
|
} catch (err) {
|
|
41609
41878
|
if (this.isNotFoundError(err)) return null;
|
|
@@ -43367,6 +43636,39 @@ var RDSDBProxyTargetGroupProvider = class {
|
|
|
43367
43636
|
//#endregion
|
|
43368
43637
|
//#region src/provisioning/providers/docdb-provider.ts
|
|
43369
43638
|
/**
|
|
43639
|
+
* The attribute map a DocumentDB DB cluster records (issue #3650), under
|
|
43640
|
+
* CloudFormation's `Fn::GetAtt` names (`Endpoint`, `Port`, `ReadEndpoint`,
|
|
43641
|
+
* `ClusterResourceId`). The RDS-style dotted keys (`Endpoint.Address`, ...)
|
|
43642
|
+
* are kept for records and readers that already use them; no
|
|
43643
|
+
* `Fn::GetAtt` names them for this service, so on their own they left
|
|
43644
|
+
* `Fn::GetAtt [Cluster, Endpoint]` resolving to the cluster identifier.
|
|
43645
|
+
*/
|
|
43646
|
+
function clusterAttributes$1(cluster) {
|
|
43647
|
+
return definedAttributes({
|
|
43648
|
+
Endpoint: cluster?.Endpoint,
|
|
43649
|
+
Port: stringifyIfAssigned(cluster?.Port),
|
|
43650
|
+
ReadEndpoint: cluster?.ReaderEndpoint,
|
|
43651
|
+
"Endpoint.Address": cluster?.Endpoint,
|
|
43652
|
+
"Endpoint.Port": stringifyIfAssigned(cluster?.Port),
|
|
43653
|
+
"ReadEndpoint.Address": cluster?.ReaderEndpoint,
|
|
43654
|
+
Arn: cluster?.DBClusterArn,
|
|
43655
|
+
ClusterResourceId: cluster?.DbClusterResourceId
|
|
43656
|
+
});
|
|
43657
|
+
}
|
|
43658
|
+
/**
|
|
43659
|
+
* The attribute map a DocumentDB DB instance records (issue #3650): `Endpoint` /
|
|
43660
|
+
* `Port` are CloudFormation's `Fn::GetAtt` names, the dotted keys are kept.
|
|
43661
|
+
*/
|
|
43662
|
+
function instanceAttributes$1(instance) {
|
|
43663
|
+
return definedAttributes({
|
|
43664
|
+
Endpoint: instance?.Endpoint?.Address,
|
|
43665
|
+
Port: stringifyIfAssigned(instance?.Endpoint?.Port),
|
|
43666
|
+
"Endpoint.Address": instance?.Endpoint?.Address,
|
|
43667
|
+
"Endpoint.Port": stringifyIfAssigned(instance?.Endpoint?.Port),
|
|
43668
|
+
Arn: instance?.DBInstanceArn
|
|
43669
|
+
});
|
|
43670
|
+
}
|
|
43671
|
+
/**
|
|
43370
43672
|
* AWS DocumentDB Provider
|
|
43371
43673
|
*
|
|
43372
43674
|
* Implements resource provisioning for DocumentDB resources:
|
|
@@ -43549,16 +43851,9 @@ var DocDBProvider = class {
|
|
|
43549
43851
|
}))).DBCluster) throw new Error("CreateDBCluster did not return DBCluster");
|
|
43550
43852
|
this.logger.debug(`Successfully created DocDB DBCluster ${logicalId}: ${dbClusterIdentifier}`);
|
|
43551
43853
|
if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForClusterAvailable(dbClusterIdentifier);
|
|
43552
|
-
const described = await this.describeDBCluster(dbClusterIdentifier);
|
|
43553
43854
|
return {
|
|
43554
43855
|
physicalId: dbClusterIdentifier,
|
|
43555
|
-
attributes:
|
|
43556
|
-
"Endpoint.Address": described?.Endpoint,
|
|
43557
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Port),
|
|
43558
|
-
"ReadEndpoint.Address": described?.ReaderEndpoint,
|
|
43559
|
-
Arn: described?.DBClusterArn,
|
|
43560
|
-
ClusterResourceId: described?.DbClusterResourceId
|
|
43561
|
-
})
|
|
43856
|
+
attributes: clusterAttributes$1(await this.describeDBCluster(dbClusterIdentifier))
|
|
43562
43857
|
};
|
|
43563
43858
|
} catch (error) {
|
|
43564
43859
|
if (error instanceof ProvisioningError) throw error;
|
|
@@ -43590,13 +43885,7 @@ var DocDBProvider = class {
|
|
|
43590
43885
|
return {
|
|
43591
43886
|
physicalId,
|
|
43592
43887
|
wasReplaced: false,
|
|
43593
|
-
attributes:
|
|
43594
|
-
"Endpoint.Address": described?.Endpoint,
|
|
43595
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Port),
|
|
43596
|
-
"ReadEndpoint.Address": described?.ReaderEndpoint,
|
|
43597
|
-
Arn: described?.DBClusterArn,
|
|
43598
|
-
ClusterResourceId: described?.DbClusterResourceId
|
|
43599
|
-
})
|
|
43888
|
+
attributes: clusterAttributes$1(described)
|
|
43600
43889
|
};
|
|
43601
43890
|
} catch (error) {
|
|
43602
43891
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -43658,14 +43947,9 @@ var DocDBProvider = class {
|
|
|
43658
43947
|
}))).DBInstance) throw new Error("CreateDBInstance did not return DBInstance");
|
|
43659
43948
|
this.logger.debug(`Successfully created DocDB DBInstance ${logicalId}: ${dbInstanceIdentifier}`);
|
|
43660
43949
|
if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForInstanceAvailable(dbInstanceIdentifier);
|
|
43661
|
-
const described = await this.describeDBInstance(dbInstanceIdentifier);
|
|
43662
43950
|
return {
|
|
43663
43951
|
physicalId: dbInstanceIdentifier,
|
|
43664
|
-
attributes:
|
|
43665
|
-
"Endpoint.Address": described?.Endpoint?.Address,
|
|
43666
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Endpoint?.Port),
|
|
43667
|
-
Arn: described?.DBInstanceArn
|
|
43668
|
-
})
|
|
43952
|
+
attributes: instanceAttributes$1(await this.describeDBInstance(dbInstanceIdentifier))
|
|
43669
43953
|
};
|
|
43670
43954
|
} catch (error) {
|
|
43671
43955
|
if (error instanceof ProvisioningError) throw error;
|
|
@@ -43689,11 +43973,7 @@ var DocDBProvider = class {
|
|
|
43689
43973
|
return {
|
|
43690
43974
|
physicalId,
|
|
43691
43975
|
wasReplaced: false,
|
|
43692
|
-
attributes:
|
|
43693
|
-
"Endpoint.Address": described?.Endpoint?.Address,
|
|
43694
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Endpoint?.Port),
|
|
43695
|
-
Arn: described?.DBInstanceArn
|
|
43696
|
-
})
|
|
43976
|
+
attributes: instanceAttributes$1(described)
|
|
43697
43977
|
};
|
|
43698
43978
|
} catch (error) {
|
|
43699
43979
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -43962,11 +44242,7 @@ var DocDBProvider = class {
|
|
|
43962
44242
|
const described = (await this.getClient().send(new DescribeDBInstancesCommand$1({ DBInstanceIdentifier: explicit }))).DBInstances?.[0];
|
|
43963
44243
|
return {
|
|
43964
44244
|
physicalId: explicit,
|
|
43965
|
-
attributes:
|
|
43966
|
-
"Endpoint.Address": described?.Endpoint?.Address,
|
|
43967
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Endpoint?.Port),
|
|
43968
|
-
Arn: described?.DBInstanceArn
|
|
43969
|
-
})
|
|
44245
|
+
attributes: instanceAttributes$1(described)
|
|
43970
44246
|
};
|
|
43971
44247
|
} catch (err) {
|
|
43972
44248
|
if (err.name === "DBInstanceNotFoundFault") return null;
|
|
@@ -43977,10 +44253,9 @@ var DocDBProvider = class {
|
|
|
43977
44253
|
async importDBCluster(input) {
|
|
43978
44254
|
const explicit = resolveExplicitPhysicalId(input, "DBClusterIdentifier");
|
|
43979
44255
|
if (explicit) try {
|
|
43980
|
-
await this.getClient().send(new DescribeDBClustersCommand$1({ DBClusterIdentifier: explicit }));
|
|
43981
44256
|
return {
|
|
43982
44257
|
physicalId: explicit,
|
|
43983
|
-
attributes: {}
|
|
44258
|
+
attributes: clusterAttributes$1((await this.getClient().send(new DescribeDBClustersCommand$1({ DBClusterIdentifier: explicit }))).DBClusters?.[0])
|
|
43984
44259
|
};
|
|
43985
44260
|
} catch (err) {
|
|
43986
44261
|
if (err.name === "DBClusterNotFoundFault") return null;
|
|
@@ -44007,6 +44282,38 @@ var DocDBProvider = class {
|
|
|
44007
44282
|
//#endregion
|
|
44008
44283
|
//#region src/provisioning/providers/neptune-provider.ts
|
|
44009
44284
|
/**
|
|
44285
|
+
* The attribute map a Neptune DB cluster records (issue #3650), under
|
|
44286
|
+
* CloudFormation's `Fn::GetAtt` names (`Endpoint`, `Port`, `ReadEndpoint`,
|
|
44287
|
+
* `ClusterResourceId`). The RDS-style dotted keys (`Endpoint.Address`, ...)
|
|
44288
|
+
* are kept for records and readers that already use them; no
|
|
44289
|
+
* `Fn::GetAtt` names them for this service, so on their own they left
|
|
44290
|
+
* `Fn::GetAtt [Cluster, Endpoint]` resolving to the cluster identifier.
|
|
44291
|
+
*/
|
|
44292
|
+
function clusterAttributes(cluster) {
|
|
44293
|
+
return definedAttributes({
|
|
44294
|
+
Endpoint: cluster?.Endpoint,
|
|
44295
|
+
Port: stringifyIfAssigned(cluster?.Port),
|
|
44296
|
+
ReadEndpoint: cluster?.ReaderEndpoint,
|
|
44297
|
+
"Endpoint.Address": cluster?.Endpoint,
|
|
44298
|
+
"Endpoint.Port": stringifyIfAssigned(cluster?.Port),
|
|
44299
|
+
"ReadEndpoint.Address": cluster?.ReaderEndpoint,
|
|
44300
|
+
ClusterResourceId: cluster?.DbClusterResourceId
|
|
44301
|
+
});
|
|
44302
|
+
}
|
|
44303
|
+
/**
|
|
44304
|
+
* The attribute map a Neptune DB instance records (issue #3650): `Endpoint` /
|
|
44305
|
+
* `Port` are CloudFormation's `Fn::GetAtt` names, the dotted keys are kept.
|
|
44306
|
+
*/
|
|
44307
|
+
function instanceAttributes(instance) {
|
|
44308
|
+
return definedAttributes({
|
|
44309
|
+
Endpoint: instance?.Endpoint?.Address,
|
|
44310
|
+
Port: stringifyIfAssigned(instance?.Endpoint?.Port),
|
|
44311
|
+
"Endpoint.Address": instance?.Endpoint?.Address,
|
|
44312
|
+
"Endpoint.Port": stringifyIfAssigned(instance?.Endpoint?.Port),
|
|
44313
|
+
Arn: instance?.DBInstanceArn
|
|
44314
|
+
});
|
|
44315
|
+
}
|
|
44316
|
+
/**
|
|
44010
44317
|
* AWS Neptune Provider
|
|
44011
44318
|
*
|
|
44012
44319
|
* Implements resource provisioning for Neptune resources:
|
|
@@ -44192,15 +44499,9 @@ var NeptuneProvider = class {
|
|
|
44192
44499
|
}))).DBCluster) throw new Error("CreateDBCluster did not return DBCluster");
|
|
44193
44500
|
this.logger.debug(`Successfully created Neptune DBCluster ${logicalId}: ${dbClusterIdentifier}`);
|
|
44194
44501
|
if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForClusterAvailable(dbClusterIdentifier);
|
|
44195
|
-
const described = await this.describeDBCluster(dbClusterIdentifier);
|
|
44196
44502
|
return {
|
|
44197
44503
|
physicalId: dbClusterIdentifier,
|
|
44198
|
-
attributes:
|
|
44199
|
-
"Endpoint.Address": described?.Endpoint,
|
|
44200
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Port),
|
|
44201
|
-
"ReadEndpoint.Address": described?.ReaderEndpoint,
|
|
44202
|
-
ClusterResourceId: described?.DbClusterResourceId
|
|
44203
|
-
})
|
|
44504
|
+
attributes: clusterAttributes(await this.describeDBCluster(dbClusterIdentifier))
|
|
44204
44505
|
};
|
|
44205
44506
|
} catch (error) {
|
|
44206
44507
|
if (error instanceof ProvisioningError) throw error;
|
|
@@ -44232,12 +44533,7 @@ var NeptuneProvider = class {
|
|
|
44232
44533
|
return {
|
|
44233
44534
|
physicalId,
|
|
44234
44535
|
wasReplaced: false,
|
|
44235
|
-
attributes:
|
|
44236
|
-
"Endpoint.Address": described?.Endpoint,
|
|
44237
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Port),
|
|
44238
|
-
"ReadEndpoint.Address": described?.ReaderEndpoint,
|
|
44239
|
-
ClusterResourceId: described?.DbClusterResourceId
|
|
44240
|
-
})
|
|
44536
|
+
attributes: clusterAttributes(described)
|
|
44241
44537
|
};
|
|
44242
44538
|
} catch (error) {
|
|
44243
44539
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -44302,13 +44598,9 @@ var NeptuneProvider = class {
|
|
|
44302
44598
|
}))).DBInstance) throw new Error("CreateDBInstance did not return DBInstance");
|
|
44303
44599
|
this.logger.debug(`Successfully created Neptune DBInstance ${logicalId}: ${dbInstanceIdentifier}`);
|
|
44304
44600
|
if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForInstanceAvailable(dbInstanceIdentifier);
|
|
44305
|
-
const described = await this.describeDBInstance(dbInstanceIdentifier);
|
|
44306
44601
|
return {
|
|
44307
44602
|
physicalId: dbInstanceIdentifier,
|
|
44308
|
-
attributes:
|
|
44309
|
-
"Endpoint.Address": described?.Endpoint?.Address,
|
|
44310
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Endpoint?.Port)
|
|
44311
|
-
})
|
|
44603
|
+
attributes: instanceAttributes(await this.describeDBInstance(dbInstanceIdentifier))
|
|
44312
44604
|
};
|
|
44313
44605
|
} catch (error) {
|
|
44314
44606
|
if (error instanceof ProvisioningError) throw error;
|
|
@@ -44334,10 +44626,7 @@ var NeptuneProvider = class {
|
|
|
44334
44626
|
return {
|
|
44335
44627
|
physicalId,
|
|
44336
44628
|
wasReplaced: false,
|
|
44337
|
-
attributes:
|
|
44338
|
-
"Endpoint.Address": described?.Endpoint?.Address,
|
|
44339
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Endpoint?.Port)
|
|
44340
|
-
})
|
|
44629
|
+
attributes: instanceAttributes(described)
|
|
44341
44630
|
};
|
|
44342
44631
|
} catch (error) {
|
|
44343
44632
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -44609,11 +44898,7 @@ var NeptuneProvider = class {
|
|
|
44609
44898
|
const described = (await this.getClient().send(new DescribeDBInstancesCommand$2({ DBInstanceIdentifier: explicit }))).DBInstances?.[0];
|
|
44610
44899
|
return {
|
|
44611
44900
|
physicalId: explicit,
|
|
44612
|
-
attributes:
|
|
44613
|
-
"Endpoint.Address": described?.Endpoint?.Address,
|
|
44614
|
-
"Endpoint.Port": stringifyIfAssigned(described?.Endpoint?.Port),
|
|
44615
|
-
Arn: described?.DBInstanceArn
|
|
44616
|
-
})
|
|
44901
|
+
attributes: instanceAttributes(described)
|
|
44617
44902
|
};
|
|
44618
44903
|
} catch (err) {
|
|
44619
44904
|
if (err.name === "DBInstanceNotFoundFault") return null;
|
|
@@ -44624,10 +44909,9 @@ var NeptuneProvider = class {
|
|
|
44624
44909
|
async importDBCluster(input) {
|
|
44625
44910
|
const explicit = resolveExplicitPhysicalId(input, "DBClusterIdentifier");
|
|
44626
44911
|
if (explicit) try {
|
|
44627
|
-
await this.getClient().send(new DescribeDBClustersCommand$2({ DBClusterIdentifier: explicit }));
|
|
44628
44912
|
return {
|
|
44629
44913
|
physicalId: explicit,
|
|
44630
|
-
attributes: {}
|
|
44914
|
+
attributes: clusterAttributes((await this.getClient().send(new DescribeDBClustersCommand$2({ DBClusterIdentifier: explicit }))).DBClusters?.[0])
|
|
44631
44915
|
};
|
|
44632
44916
|
} catch (err) {
|
|
44633
44917
|
if (err.name === "DBClusterNotFoundFault") return null;
|
|
@@ -49291,10 +49575,14 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
|
|
|
49291
49575
|
}
|
|
49292
49576
|
async importServiceResource(input) {
|
|
49293
49577
|
if (input.knownPhysicalId) try {
|
|
49294
|
-
await this.getClient().send(new GetServiceCommand({ Id: input.knownPhysicalId }));
|
|
49578
|
+
const resp = await this.getClient().send(new GetServiceCommand({ Id: input.knownPhysicalId }));
|
|
49295
49579
|
return {
|
|
49296
49580
|
physicalId: input.knownPhysicalId,
|
|
49297
|
-
attributes: {
|
|
49581
|
+
attributes: definedAttributes({
|
|
49582
|
+
Id: input.knownPhysicalId,
|
|
49583
|
+
Arn: resp.Service?.Arn,
|
|
49584
|
+
Name: resp.Service?.Name
|
|
49585
|
+
})
|
|
49298
49586
|
};
|
|
49299
49587
|
} catch (err) {
|
|
49300
49588
|
if (err instanceof ServiceNotFound) return null;
|
|
@@ -56603,7 +56891,10 @@ var EFSProvider = class {
|
|
|
56603
56891
|
const ap = (await this.getClient().send(new DescribeAccessPointsCommand({ AccessPointId: input.knownPhysicalId }))).AccessPoints?.[0];
|
|
56604
56892
|
return ap?.AccessPointId ? {
|
|
56605
56893
|
physicalId: ap.AccessPointId,
|
|
56606
|
-
attributes: {
|
|
56894
|
+
attributes: definedAttributes({
|
|
56895
|
+
Arn: ap.AccessPointArn,
|
|
56896
|
+
AccessPointId: ap.AccessPointId
|
|
56897
|
+
})
|
|
56607
56898
|
} : null;
|
|
56608
56899
|
} catch (err) {
|
|
56609
56900
|
if (err instanceof AccessPointNotFound) return null;
|
|
@@ -64380,6 +64671,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
64380
64671
|
const regionForState = state.region ?? ctx.baseRegion;
|
|
64381
64672
|
refuseMalformedResourcesForDestroy(state, stackName, regionForState);
|
|
64382
64673
|
refuseMalformedOrphansForDestroy(state, stackName, regionForState);
|
|
64674
|
+
refuseMalformedOrphanRecordsForDestroy(state, stackName, regionForState);
|
|
64383
64675
|
refuseDivergentRecordRegionForDestroy(state, stackName, regionForState, ctx.divergentBodyRegion);
|
|
64384
64676
|
const resourceCount = Object.keys(state.resources).length;
|
|
64385
64677
|
const orphanCount = (state.orphans ?? []).length;
|
|
@@ -64433,6 +64725,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
64433
64725
|
if (recheck) {
|
|
64434
64726
|
refuseMalformedResourcesForDestroy(recheck.state, stackName, regionForState);
|
|
64435
64727
|
refuseMalformedOrphansForDestroy(recheck.state, stackName, regionForState);
|
|
64728
|
+
refuseMalformedOrphanRecordsForDestroy(recheck.state, stackName, regionForState);
|
|
64436
64729
|
}
|
|
64437
64730
|
const recheckResources = recheck ? Object.keys(recheck.state.resources).length : 0;
|
|
64438
64731
|
const recheckOrphans = recheck ? (recheck.state.orphans ?? []).length : 0;
|
|
@@ -64457,13 +64750,13 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
64457
64750
|
if (consumers.length > 0) throw new StackHasActiveImportsError(stackName, regionForState, consumers);
|
|
64458
64751
|
}
|
|
64459
64752
|
logger.info(`\nResources to be deleted (${resourceCount}):`);
|
|
64460
|
-
for (const [logicalId, resource] of Object.entries(state.resources)) logger.info(` - ${logicalId} (${resource.resourceType})`);
|
|
64753
|
+
for (const [logicalId, resource] of Object.entries(state.resources)) logger.info(` - ${displaySafe(logicalId)} (${displaySafe(resource.resourceType)})`);
|
|
64461
64754
|
const protectedCount = ctx.removeProtection ? countProtectedResources(state) : 0;
|
|
64462
64755
|
const orphansAtDestroy = state.orphans ?? [];
|
|
64463
64756
|
if (orphansAtDestroy.length > 0) {
|
|
64464
64757
|
logger.info(`\n${orphansAtDestroy.length} resource(s) are still in AWS from an earlier failed deploy. cdkd left them there because their DeletionPolicy is Retain (CDK's RemovalPolicy.RETAIN), and has been tracking them so a later deploy of this stack could adopt them back instead of colliding with their names.`);
|
|
64465
64758
|
logger.info("Destroying this stack deletes that record. The resources stay in AWS, may continue to incur charges, and cdkd will no longer know about them:");
|
|
64466
|
-
for (const entry of orphansAtDestroy) logger.info(` - ${entry.logicalId} (${entry.state.resourceType}) ${entry.state.physicalId}`);
|
|
64759
|
+
for (const entry of orphansAtDestroy) logger.info(` - ${displaySafe(entry.logicalId)} (${displaySafe(entry.state.resourceType)}) ${displaySafe(entry.state.physicalId)}`);
|
|
64467
64760
|
}
|
|
64468
64761
|
if (!ctx.skipConfirmation) {
|
|
64469
64762
|
if (process.stdin.isTTY !== true) throw new CdkdError(`The destroy confirmation prompt for stack "${stackName}" cannot run in a non-interactive environment. Pass --yes / -y to confirm the destroy (cdkd destroy also accepts -f / --force), or run the command from a real terminal.`, "NON_INTERACTIVE_CONFIRM");
|
|
@@ -65143,7 +65436,7 @@ var NestedStackProvider = class {
|
|
|
65143
65436
|
const ctx = this.requireContext();
|
|
65144
65437
|
this.requireDeployContext(ctx, "create");
|
|
65145
65438
|
const childTemplatePath = ctx.nestedTemplates[logicalId];
|
|
65146
|
-
if (!childTemplatePath) throw new Error(`Nested template file not found for AWS::CloudFormation::Stack
|
|
65439
|
+
if (!childTemplatePath) throw new Error(`Nested template file not found for AWS::CloudFormation::Stack ${displayIdent(logicalId)} under parent ${displayStackName(ctx.parentStackName)}. Verify the synth output emits Metadata['aws:asset:path'] on this resource (CDK 2.x cdk.NestedStack does so by default).`);
|
|
65147
65440
|
this.refuseMalformedNestedTemplateTree(ctx, logicalId, childTemplatePath);
|
|
65148
65441
|
const { template: childTemplate, grandchildTemplates } = this.readChildTemplate(childTemplatePath, ctx.assetRedirect);
|
|
65149
65442
|
const childStackName = this.deriveChildStackName(ctx.parentStackName, logicalId);
|
|
@@ -65163,7 +65456,7 @@ var NestedStackProvider = class {
|
|
|
65163
65456
|
const ctx = this.requireContext();
|
|
65164
65457
|
this.requireDeployContext(ctx, "update");
|
|
65165
65458
|
const childTemplatePath = ctx.nestedTemplates[logicalId];
|
|
65166
|
-
if (!childTemplatePath) throw new Error(`Nested template file not found for AWS::CloudFormation::Stack
|
|
65459
|
+
if (!childTemplatePath) throw new Error(`Nested template file not found for AWS::CloudFormation::Stack ${displayIdent(logicalId)} on update.`);
|
|
65167
65460
|
this.refuseMalformedNestedTemplateTree(ctx, logicalId, childTemplatePath);
|
|
65168
65461
|
const { template: childTemplate, grandchildTemplates } = this.readChildTemplate(childTemplatePath, ctx.assetRedirect);
|
|
65169
65462
|
const childStackName = this.deriveChildStackName(ctx.parentStackName, logicalId);
|
|
@@ -65235,7 +65528,7 @@ var NestedStackProvider = class {
|
|
|
65235
65528
|
}
|
|
65236
65529
|
}
|
|
65237
65530
|
async getAttribute(_physicalId, _resourceType, attributeName) {
|
|
65238
|
-
throw new Error(`AWS::CloudFormation::Stack: attribute
|
|
65531
|
+
throw new Error(`AWS::CloudFormation::Stack: attribute ${displayIdent(attributeName)} is not in the recorded Outputs map. Only 'Outputs.<Key>' references to declared Output names on the child template are supported.`);
|
|
65239
65532
|
}
|
|
65240
65533
|
async runChildDeploy(parentCtx, logicalId, childStackName, childRegion, childTemplate, childParameters, grandchildTemplates) {
|
|
65241
65534
|
const inheritedSecrets = getCurrentResourceSecrets();
|
|
@@ -65286,7 +65579,7 @@ var NestedStackProvider = class {
|
|
|
65286
65579
|
*/
|
|
65287
65580
|
async readChildOutputsAsAttributes(ctx, childStackName, childRegion) {
|
|
65288
65581
|
const childStateData = await ctx.stateBackend.getState(childStackName, childRegion);
|
|
65289
|
-
if (!childStateData) throw new Error(`Child stack state
|
|
65582
|
+
if (!childStateData) throw new Error(`Child stack state ${displayStackName(childStackName)} not found after deploy — NestedStackProvider invariant violated.`);
|
|
65290
65583
|
refuseMalformedNestedChildOutputs(childStateData.state, childStackName, childRegion);
|
|
65291
65584
|
const attributes = this.buildOutputsAttributes(childStateData.state.outputs ?? {});
|
|
65292
65585
|
const noEchoAttributeNames = [];
|
|
@@ -65389,7 +65682,7 @@ var NestedStackProvider = class {
|
|
|
65389
65682
|
* points at `[2]` rather than at the whole parameter.
|
|
65390
65683
|
*/
|
|
65391
65684
|
refuseNonScalarParameter(k, offender, where) {
|
|
65392
|
-
throw new Error(`NestedStackProvider: child Parameter
|
|
65685
|
+
throw new Error(`NestedStackProvider: child Parameter ${displayIdent(k)}${where} resolved to a non-scalar value (type=${offender === null ? "null" : typeof offender}). Parameters must be scalars (string / number / boolean), or an ARRAY of them from a list-typed parameter, by the time they reach the provider — an unresolved intrinsic here means IntrinsicFunctionResolver upstream did not handle the value, which is a bug. Surface the unresolved input rather than silently coercing to '[object Object]'.`);
|
|
65393
65686
|
}
|
|
65394
65687
|
/**
|
|
65395
65688
|
* The child template as the child engine deploys it, plus the grandchild
|
|
@@ -65432,9 +65725,9 @@ var NestedStackProvider = class {
|
|
|
65432
65725
|
const dir = path.dirname(childTemplatePath);
|
|
65433
65726
|
const result = Object.create(null);
|
|
65434
65727
|
for (const { logicalId: grandLogicalId, assetPath } of listNestedTemplateRows(childTemplate)) {
|
|
65435
|
-
if (isAbsoluteCrossPlatform$1(assetPath)) throw markNonRetryable(/* @__PURE__ */ new Error(`NestedStackProvider: nested-stack
|
|
65728
|
+
if (isAbsoluteCrossPlatform$1(assetPath)) throw markNonRetryable(/* @__PURE__ */ new Error(`NestedStackProvider: nested-stack ${displayIdent(grandLogicalId)} has Metadata['aws:asset:path']=${displayAssemblyPath(assetPath)} which is absolute. CDK emits relative asset paths for nested templates; an absolute path indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to load.`));
|
|
65436
65729
|
const resolved = resolveAssemblyPath(dir, assetPath);
|
|
65437
|
-
if (!resolved.contained) throw markNonRetryable(/* @__PURE__ */ new Error(`NestedStackProvider: nested-stack
|
|
65730
|
+
if (!resolved.contained) throw markNonRetryable(/* @__PURE__ */ new Error(`NestedStackProvider: nested-stack ${displayIdent(grandLogicalId)} has Metadata['aws:asset:path']=${displayAssemblyPath(assetPath)} which ${renderAssemblyPathEscape(resolved, dir)}`));
|
|
65438
65731
|
result[grandLogicalId] = resolved.path;
|
|
65439
65732
|
}
|
|
65440
65733
|
return result;
|
|
@@ -68551,13 +68844,10 @@ async function computeStackDiff(currentState, template, region, stackName, state
|
|
|
68551
68844
|
let stateForDiff = currentState;
|
|
68552
68845
|
const unreadableOrphans = [];
|
|
68553
68846
|
if (currentState.orphans?.length && options.previewOrphanAdoption) {
|
|
68554
|
-
const
|
|
68555
|
-
|
|
68556
|
-
|
|
68557
|
-
|
|
68558
|
-
return false;
|
|
68559
|
-
});
|
|
68560
|
-
if (unreadableOrphans.length > 0) logger.warn(malformedOrphanRecordsWarning(stackName, region, unreadableOrphans));
|
|
68847
|
+
for (const id of unpreviewableOrphanRecords(currentState)) unreadableOrphans.push(id);
|
|
68848
|
+
const readableOrphans = previewableOrphanRecords(currentState);
|
|
68849
|
+
if (unreadableOrphans.length > 0) logger.warn(malformedOrphanRecordsWarning(stackName, region, unreadableOrphans, false));
|
|
68850
|
+
let reportedByTheAdoptedPropertiesArm = [];
|
|
68561
68851
|
const plan = await options.previewOrphanAdoption({
|
|
68562
68852
|
...currentState,
|
|
68563
68853
|
orphans: readableOrphans
|
|
@@ -68574,11 +68864,18 @@ async function computeStackDiff(currentState, template, region, stackName, state
|
|
|
68574
68864
|
}
|
|
68575
68865
|
};
|
|
68576
68866
|
const tornAdopted = repairMalformedResourcePropertiesForReadOnly(stateForDiff);
|
|
68867
|
+
reportedByTheAdoptedPropertiesArm = tornAdopted;
|
|
68577
68868
|
if (tornAdopted.length > 0) {
|
|
68578
68869
|
logger.warn(malformedResourcePropertiesWarning(stackName, region, tornAdopted));
|
|
68579
68870
|
deployRefusals.push(deployRefusesPropertiesReason(tornAdopted));
|
|
68580
68871
|
}
|
|
68581
68872
|
}
|
|
68873
|
+
const alreadyReported = new Set(reportedByTheAdoptedPropertiesArm);
|
|
68874
|
+
const previewedRowsTheDeployRefuses = readableOrphans.filter((record) => !isReadableOrphanRecord(record)).map((record) => record.logicalId).filter((logicalId) => !alreadyReported.has(logicalId));
|
|
68875
|
+
if (previewedRowsTheDeployRefuses.length > 0) {
|
|
68876
|
+
logger.warn(malformedOrphanRowsKeptWarning(stackName, region, previewedRowsTheDeployRefuses));
|
|
68877
|
+
deployRefusals.push(deployRefusesOrphanRowsReason(previewedRowsTheDeployRefuses));
|
|
68878
|
+
}
|
|
68582
68879
|
}
|
|
68583
68880
|
const changes = await diffCalculator.calculateDiff(stateForDiff, effectiveTemplate, resolveFn, canonicalizeProperties);
|
|
68584
68881
|
const changedLogicalIds = new Set([...changes.values()].filter((c) => c.changeType !== "NO_CHANGE").map((c) => c.logicalId));
|
|
@@ -69854,7 +70151,7 @@ async function scrubCommand(stacks, options) {
|
|
|
69854
70151
|
} else if (scrubbed.secretBearingKeys === 0 && scrubbed.unverifiableReads === 0 && scrubbed.unverifiableLeaves === 0 && indexConverged === 0) logger.info(`No plaintext secrets found in ${stack.stackName}`);
|
|
69855
70152
|
if (scrubbed.malformedResources) malformedRecords.push(stack.stackName);
|
|
69856
70153
|
if (scrubbed.malformedOutputs) malformedOutputRecords.push(stack.stackName);
|
|
69857
|
-
if (scrubbed.malformedOrphans) malformedOrphanRecords.push(stack.stackName);
|
|
70154
|
+
if (scrubbed.malformedOrphans || scrubbed.malformedOrphanRows) malformedOrphanRecords.push(stack.stackName);
|
|
69858
70155
|
if (scrubbed.unverifiableLeaves > 0) {
|
|
69859
70156
|
totalStacksWithUnverifiableLeaves++;
|
|
69860
70157
|
logger.warn(`${scrubbed.unverifiableLeaves} scan(s) in ${stack.stackName} were ABANDONED mid-value because a {{resolve:...}} reference could not be resolved (see the warnings above). The resolver stops at the first failing token, so a real secret after it in the same value recorded no needle — this stack is not reported clean. The count is per abandoned SCAN, not per secret: one record can contribute more than once (an output whose Export.Name and Value both abandon), and one abandoned scan can hide several unexamined leaves.`);
|
|
@@ -70550,7 +70847,7 @@ function malformedRecordsAuditedError(stackNames, outputStackNames, orphanStackN
|
|
|
70550
70847
|
const parts = [];
|
|
70551
70848
|
if (stackNames.length > 0) parts.push(`${stackNames.length} stack(s) were audited with an EMPTY resource set because their state record has no readable 'resources' map: ${safeNames(stackNames)}. The report above describes their outputs only — nothing is known about their resources, so this run cannot certify them clean.`);
|
|
70552
70849
|
if (outputStackNames.length > 0) parts.push(`${outputStackNames.length} stack(s) were audited with an EMPTY outputs bag because their state record has no readable 'outputs' map: ${safeNames(outputStackNames)}. The report above describes their resources only — nothing is known about the values their outputs hold, and those values are what the exports index republishes to consumer stacks, so this run cannot certify them clean.`);
|
|
70553
|
-
if (orphanStackNames.length > 0) parts.push(`${orphanStackNames.length} stack(s) were audited with an
|
|
70850
|
+
if (orphanStackNames.length > 0) parts.push(`${orphanStackNames.length} stack(s) were audited with an INCOMPLETE orphan list because their state record has no readable 'orphans' list, or a record inside it that no reader can use: ${safeNames(orphanStackNames)}. Whichever it was, the warning above names it per stack. Nothing is known about the resources those records describe — resources an earlier failed deploy may have left live in AWS — so this run cannot certify them clean.`);
|
|
70554
70851
|
return new ScrubRefusalError(`${parts.join(" ")} See the warnings above for the record to inspect.`, STATE_RESOURCES_MALFORMED);
|
|
70555
70852
|
}
|
|
70556
70853
|
/**
|
|
@@ -71962,9 +72259,23 @@ async function scrubStack(stack, region, stateBackend, lockManager, opts) {
|
|
|
71962
72259
|
const outputSecrets = /* @__PURE__ */ new Map();
|
|
71963
72260
|
/**
|
|
71964
72261
|
* Needles derived from each rollback-orphan record's OWN recorded bag
|
|
71965
|
-
* (issue go-to-k/cdkd#2943)
|
|
71966
|
-
*
|
|
71967
|
-
*
|
|
72262
|
+
* (issue go-to-k/cdkd#2943) — per-record for the same reason
|
|
72263
|
+
* `perResourceSecrets` is per-resource: one record's secret must not rewrite
|
|
72264
|
+
* another's coinciding literal.
|
|
72265
|
+
*
|
|
72266
|
+
* Keyed by the row's INDEX in `orphans`, never by its `logicalId`
|
|
72267
|
+
* (go-to-k/cdkd#3500 security review). Two rows sharing an id are a MALFORMED
|
|
72268
|
+
* record — no cdkd writer produces one, since `orphansAfterRollback` keeps one
|
|
72269
|
+
* row per id — and both arms of this command meet it before this map is read:
|
|
72270
|
+
* a real run refuses the record and `--dry-run` drops every such row
|
|
72271
|
+
* (go-to-k/cdkd#3643). The index keying stays as defense in depth, because it
|
|
72272
|
+
* is still the only identity that cannot collide: on an id key the second row's
|
|
72273
|
+
* empty map REPLACED the first row's filled one. Both halves broke: the first
|
|
72274
|
+
* row's needles left the union that the rewrite and the error boundary read, and
|
|
72275
|
+
* its own lookup returned the OTHER row's map, so where two rows resolve one
|
|
72276
|
+
* plaintext through different expressions the wrong expression was written. The
|
|
72277
|
+
* index is the only identity the collecting loop and the rewrite can agree on,
|
|
72278
|
+
* since both walk `state.orphans` in order and neither reorders it.
|
|
71968
72279
|
*/
|
|
71969
72280
|
const orphanSecrets = /* @__PURE__ */ new Map();
|
|
71970
72281
|
const prePassFindings = {
|
|
@@ -72054,12 +72365,22 @@ async function scrubStack(stack, region, stateBackend, lockManager, opts) {
|
|
|
72054
72365
|
}
|
|
72055
72366
|
} else if (!hasReadableOutputs(state)) throw new ScrubRefusalError(malformedOutputsRefusalMessage(stack.stackName, region), STATE_RESOURCES_MALFORMED);
|
|
72056
72367
|
let malformedOrphans;
|
|
72368
|
+
let malformedOrphanRows;
|
|
72057
72369
|
if (opts.dryRun) {
|
|
72058
72370
|
if (repairMalformedOrphansForReadOnly(state)) {
|
|
72059
72371
|
malformedOrphans = true;
|
|
72060
72372
|
logger.warn(malformedOrphansWarning(stack.stackName, region));
|
|
72061
72373
|
}
|
|
72374
|
+
const droppedRows = repairMalformedOrphanRecordsForReadOnly(state);
|
|
72375
|
+
if (droppedRows.length > 0) {
|
|
72376
|
+
malformedOrphanRows = true;
|
|
72377
|
+
logger.warn(malformedOrphanRecordsWarning(stack.stackName, region, droppedRows, true));
|
|
72378
|
+
}
|
|
72062
72379
|
} else if (!hasReadableOrphans(state)) throw new ScrubRefusalError(malformedOrphansRefusalMessage(stack.stackName, region), STATE_RESOURCES_MALFORMED);
|
|
72380
|
+
else {
|
|
72381
|
+
const unreadableRows = unreadableOrphanRecords(state);
|
|
72382
|
+
if (unreadableRows.length > 0) throw new ScrubRefusalError(malformedOrphanRecordsRefusalMessage(stack.stackName, region, unreadableRows), STATE_RESOURCES_MALFORMED);
|
|
72383
|
+
}
|
|
72063
72384
|
const perResourceTemplateProps = /* @__PURE__ */ new Map();
|
|
72064
72385
|
const outputsTemplateSource = {};
|
|
72065
72386
|
const resolvers = new ScrubResolvers(region);
|
|
@@ -72142,9 +72463,9 @@ async function scrubStack(stack, region, stateBackend, lockManager, opts) {
|
|
|
72142
72463
|
}
|
|
72143
72464
|
perResourceTemplateProps.set(logicalId, templateResource.Properties);
|
|
72144
72465
|
}
|
|
72145
|
-
for (const record of state.orphans ?? []) {
|
|
72466
|
+
for (const [orphanIndex, record] of (state.orphans ?? []).entries()) {
|
|
72146
72467
|
const recordedSecretValues = /* @__PURE__ */ new Map();
|
|
72147
|
-
orphanSecrets.set(
|
|
72468
|
+
orphanSecrets.set(String(orphanIndex), recordedSecretValues);
|
|
72148
72469
|
const resolveInput = await pinCrossRegionSecrets({
|
|
72149
72470
|
properties: record.state.properties,
|
|
72150
72471
|
attributes: record.state.attributes ?? {},
|
|
@@ -72277,6 +72598,7 @@ async function scrubStack(stack, region, stateBackend, lockManager, opts) {
|
|
|
72277
72598
|
...malformedResources ? { malformedResources } : {},
|
|
72278
72599
|
...malformedOutputs ? { malformedOutputs } : {},
|
|
72279
72600
|
...malformedOrphans ? { malformedOrphans } : {},
|
|
72601
|
+
...malformedOrphanRows ? { malformedOrphanRows } : {},
|
|
72280
72602
|
outputs: state.outputs,
|
|
72281
72603
|
exportNameDisplay: (name) => secretSafeKeyDisplay(name, outputSecrets)
|
|
72282
72604
|
};
|
|
@@ -72295,8 +72617,8 @@ async function scrubStack(stack, region, stateBackend, lockManager, opts) {
|
|
|
72295
72617
|
if (JSON.stringify(scrubbed) !== JSON.stringify(record)) recordsChanged++;
|
|
72296
72618
|
newResources[logicalId] = scrubbed;
|
|
72297
72619
|
}
|
|
72298
|
-
const newOrphans = (state.orphans ?? []).map((record) => {
|
|
72299
|
-
const own = orphanSecrets.get(
|
|
72620
|
+
const newOrphans = (state.orphans ?? []).map((record, orphanIndex) => {
|
|
72621
|
+
const own = orphanSecrets.get(String(orphanIndex));
|
|
72300
72622
|
const needles = new Map(allRecordedSecrets(outputSecrets, perResourceSecrets, orphanSecrets));
|
|
72301
72623
|
for (const [plaintext, expression] of own ?? []) needles.set(plaintext, expression);
|
|
72302
72624
|
if (needles.size === 0) return record;
|
|
@@ -72356,6 +72678,7 @@ async function scrubStack(stack, region, stateBackend, lockManager, opts) {
|
|
|
72356
72678
|
...malformedResources ? { malformedResources } : {},
|
|
72357
72679
|
...malformedOutputs ? { malformedOutputs } : {},
|
|
72358
72680
|
...malformedOrphans ? { malformedOrphans } : {},
|
|
72681
|
+
...malformedOrphanRows ? { malformedOrphanRows } : {},
|
|
72359
72682
|
outputs: newOutputs,
|
|
72360
72683
|
exportNameDisplay: (name) => secretSafeKeyDisplay(name, outputSecrets)
|
|
72361
72684
|
};
|
|
@@ -82924,7 +83247,7 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
82924
83247
|
* Create the `state destroy` subcommand.
|
|
82925
83248
|
*/
|
|
82926
83249
|
function createStateDestroyCommand() {
|
|
82927
|
-
const cmd = new Command("destroy").description("Destroy a stack's AWS resources and remove its state record without requiring the CDK app. For removing only the state record (keeping AWS resources intact), use 'cdkd state orphan'.").argument("[stacks...]", "Stack name(s) to destroy (physical CloudFormation names)").option("--all", "Destroy every stack in the state bucket", false).option("--remove-protection",
|
|
83250
|
+
const cmd = new Command("destroy").description("Destroy a stack's AWS resources and remove its state record without requiring the CDK app. For removing only the state record (keeping AWS resources intact), use 'cdkd state orphan'.").argument("[stacks...]", "Stack name(s) to destroy (physical CloudFormation names)").option("--all", "Destroy every stack in the state bucket", false).option("--remove-protection", `Bypass deletion protection on protected resources by flipping the per-resource protection flag off in-place before delete. Covers ${removeProtectionTypeList()}.`, false).addOption(stackRegionOption$1()).addHelpText("after", [
|
|
82928
83251
|
"",
|
|
82929
83252
|
"Examples:",
|
|
82930
83253
|
" cdkd state destroy MyStack",
|
|
@@ -83872,6 +84195,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
83872
84195
|
const baseState = stateData.state;
|
|
83873
84196
|
refuseMalformedState(baseState, stackName, region);
|
|
83874
84197
|
refuseMalformedOrphans(baseState, stackName, region);
|
|
84198
|
+
refuseMalformedOrphanRecords(baseState, stackName, region);
|
|
83875
84199
|
const stateResources = { ...baseState.resources };
|
|
83876
84200
|
const mintedOrphans = [];
|
|
83877
84201
|
const orphanLogicalIds = new Set(options.orphan ?? []);
|
|
@@ -84531,23 +84855,45 @@ function createEventsPruneCommand() {
|
|
|
84531
84855
|
* The two dual-stack forms carry a FIXED suffix, so their check is that literal
|
|
84532
84856
|
* rather than the region's partition suffix — the TIGHTEST available check for
|
|
84533
84857
|
* them, not a relaxation: `on.aws` is an AWS-owned domain, so unlike a captured
|
|
84534
|
-
* suffix it cannot be substituted by a host someone else owns.
|
|
84535
|
-
*
|
|
84536
|
-
*
|
|
84537
|
-
*
|
|
84538
|
-
*
|
|
84539
|
-
*
|
|
84540
|
-
|
|
84858
|
+
* suffix it cannot be substituted by a host someone else owns.
|
|
84859
|
+
*
|
|
84860
|
+
* The three non-plain forms are accepted only for a region in the `aws` /
|
|
84861
|
+
* `aws-us-gov` partitions (issue #3670):
|
|
84862
|
+
*
|
|
84863
|
+
* - `on.aws` is the dual-stack DNS of those two partitions; the others serve
|
|
84864
|
+
* dual-stack under their own suffixes, which this table does not list.
|
|
84865
|
+
* - AWS's own endpoint data (botocore `endpoints.json`, service `ecr`) carries
|
|
84866
|
+
* the `fips-dkr-<region>` registry endpoints in those two partitions only;
|
|
84867
|
+
* `aws-cn`, the ISO partitions and `aws-eusc` list none. So
|
|
84868
|
+
* `<acct>.dkr.ecr-fips.cn-north-1.amazonaws.com.cn` is not a host AWS serves
|
|
84869
|
+
* either, although its suffix is the region's own.
|
|
84870
|
+
*
|
|
84871
|
+
* Such a host is refused rather than handed a `docker login`. An earlier
|
|
84872
|
+
* revision accepted `on.aws` for any region, reasoning that under-accepting
|
|
84873
|
+
* repeats the issue #1764 failure; that trade stops paying once the pull path
|
|
84874
|
+
* logs in to whatever host the reference names. The partition, not the six
|
|
84875
|
+
* FIPS regions, is the unit, so a new FIPS region in those partitions is not
|
|
84876
|
+
* refused before AWS documents it.
|
|
84877
|
+
*
|
|
84878
|
+
* `cdkd gc` builds its pattern from the LABELS and suffixes only and ignores
|
|
84879
|
+
* `partitions`, deliberately: over-matching there only ever KEEPS an asset.
|
|
84880
|
+
*/
|
|
84881
|
+
const COMMERCIAL_AND_GOVCLOUD = ["aws", "aws-us-gov"];
|
|
84541
84882
|
const ECR_REGISTRY_HOST_FORMS = [
|
|
84542
84883
|
{ labels: "dkr.ecr" },
|
|
84543
|
-
{
|
|
84884
|
+
{
|
|
84885
|
+
labels: "dkr.ecr-fips",
|
|
84886
|
+
partitions: COMMERCIAL_AND_GOVCLOUD
|
|
84887
|
+
},
|
|
84544
84888
|
{
|
|
84545
84889
|
labels: "dkr-ecr",
|
|
84546
|
-
fixedUrlSuffix: "on.aws"
|
|
84890
|
+
fixedUrlSuffix: "on.aws",
|
|
84891
|
+
partitions: COMMERCIAL_AND_GOVCLOUD
|
|
84547
84892
|
},
|
|
84548
84893
|
{
|
|
84549
84894
|
labels: "dkr-ecr-fips",
|
|
84550
|
-
fixedUrlSuffix: "on.aws"
|
|
84895
|
+
fixedUrlSuffix: "on.aws",
|
|
84896
|
+
partitions: COMMERCIAL_AND_GOVCLOUD
|
|
84551
84897
|
}
|
|
84552
84898
|
];
|
|
84553
84899
|
/**
|
|
@@ -84671,6 +85017,17 @@ function ecrRegistryHostPattern(segments) {
|
|
|
84671
85017
|
* MESSAGE was written for the #1764 partition-gap case and now over-claims for a
|
|
84672
85018
|
* form/suffix mispairing (`amazonaws.com` IS `us-east-1`'s partition suffix).
|
|
84673
85019
|
* `src/local/ecs-task-resolver.ts` owns that wording; recorded on issue #1846.
|
|
85020
|
+
*
|
|
85021
|
+
* `<r>` above is a commercial region. Issue #3670 then scoped the three
|
|
85022
|
+
* non-plain forms to the `aws` / `aws-us-gov` partitions, flipping more
|
|
85023
|
+
* verdicts: `<a>.dkr-ecr[-fips].<r>.on.aws` and `<a>.dkr.ecr-fips.<r>.S` for an
|
|
85024
|
+
* `aws-cn`, ISO or `aws-eusc` `<r>` went from `p=ok d=f` to `p=und d=TRUE`, a
|
|
85025
|
+
* form / partition mispairing reported like the form / suffix ones. The same
|
|
85026
|
+
* issue added the region-SHAPE guard ({@link AWS_REGION_ID}), which refuses a
|
|
85027
|
+
* service-name "region" such as `s3` at both entry points. That guard also
|
|
85028
|
+
* flips the diagnostic the other way for such a label: `<a>.dkr.ecr.s3.F` went
|
|
85029
|
+
* from `p=und d=TRUE` to `p=und d=f`. A region-shaped label no partition knows
|
|
85030
|
+
* (`nz-north-1`) went from `p=ok d=f` to `p=und d=TRUE`.
|
|
84674
85031
|
*/
|
|
84675
85032
|
const ECR_URI_HOST_REGEX = new RegExp(`^(\\d{12})\\.(${ECR_HOST_FORMS_LONGEST_FIRST.map((form) => escapeRegExp(form.labels)).join("|")})\\.([^.]+)\\.([^/]+)/`, "i");
|
|
84676
85033
|
/**
|
|
@@ -84731,6 +85088,54 @@ const CANONICAL_REGION_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
|
|
|
84731
85088
|
*/
|
|
84732
85089
|
const CANONICAL_URL_SUFFIX = /^[A-Za-z0-9][A-Za-z0-9.-]*$/;
|
|
84733
85090
|
/**
|
|
85091
|
+
* `<letters>(-<letters or digits>)+-<number>`: the generic shape every AWS
|
|
85092
|
+
* region id has had. A label matching it but not {@link AWS_REGION_ID} is a
|
|
85093
|
+
* region cdkd does not know yet, reported by the diagnostic rather than
|
|
85094
|
+
* silenced; `s3`, `lambda-url` and `s3-external-1` do not match it (the first
|
|
85095
|
+
* segment must be letters only).
|
|
85096
|
+
*/
|
|
85097
|
+
const GENERIC_REGION_SHAPE = /^[a-z]+(?:-[a-z0-9]+)+-\d+$/;
|
|
85098
|
+
/**
|
|
85099
|
+
* The SHAPE of an AWS region id, tested on the folded region AFTER the charset
|
|
85100
|
+
* guard above (issue #3670).
|
|
85101
|
+
*
|
|
85102
|
+
* The charset guard admits any `[A-Za-z0-9-]` label, so a SERVICE-name label
|
|
85103
|
+
* parsed as a region: `<acct>.dkr.ecr.s3.amazonaws.com` yielded the region
|
|
85104
|
+
* `s3`, whose partition falls back to commercial, so the suffix matched and the
|
|
85105
|
+
* host became a `docker login` target. Only TLS stopped the token there. A
|
|
85106
|
+
* region id is one of the partitions' region patterns, so anything else is not
|
|
85107
|
+
* a registry host this module recognizes.
|
|
85108
|
+
*
|
|
85109
|
+
* One alternative per partition, transcribed from each partition's
|
|
85110
|
+
* `regionRegex` in AWS's own endpoint data (botocore `partitions.json`, which
|
|
85111
|
+
* `@aws-sdk/util-endpoints` vendors), with `\w+` spelled `[a-z0-9]+`. That is
|
|
85112
|
+
* the same set once the charset guard has refused `_` and the fold has
|
|
85113
|
+
* lower-cased the segment:
|
|
85114
|
+
*
|
|
85115
|
+
* - `aws`: `^(us|eu|ap|sa|ca|me|af|il|mx)-\w+-\d+$`
|
|
85116
|
+
* - `aws-cn`: `^cn-\w+-\d+$`
|
|
85117
|
+
* - `aws-us-gov`: `^us-gov-\w+-\d+$`
|
|
85118
|
+
* - `aws-iso` / `-iso-b` / `-iso-e` / `-iso-f`: `^us-iso-`, `^us-isob-`,
|
|
85119
|
+
* `^eu-isoe-`, `^us-isof-`, each followed by `\w+-\d+`
|
|
85120
|
+
* - `aws-eusc`: `^eusc-(de)-\w+-\d+$`, widened here to any `eusc-<cc>-` country
|
|
85121
|
+
* code for the reason `PARTITION_TABLE` (`src/utils/aws-partition.ts`) gives
|
|
85122
|
+
* for its own broader `eusc-` prefix: a future sovereign-cloud country falling
|
|
85123
|
+
* through is the failure, and no other partition's regions begin `eusc-`.
|
|
85124
|
+
*
|
|
85125
|
+
* A future partition with a new prefix is refused until it is added here, the
|
|
85126
|
+
* same way `derivePartitionAndUrlSuffix` has to learn its suffix.
|
|
85127
|
+
*/
|
|
85128
|
+
const AWS_REGION_ID = new RegExp("^(?:" + [
|
|
85129
|
+
"(?:us|eu|ap|sa|ca|me|af|il|mx)-[a-z0-9]+-\\d+",
|
|
85130
|
+
"cn-[a-z0-9]+-\\d+",
|
|
85131
|
+
"us-gov-[a-z0-9]+-\\d+",
|
|
85132
|
+
"us-iso-[a-z0-9]+-\\d+",
|
|
85133
|
+
"us-isob-[a-z0-9]+-\\d+",
|
|
85134
|
+
"eu-isoe-[a-z0-9]+-\\d+",
|
|
85135
|
+
"us-isof-[a-z0-9]+-\\d+",
|
|
85136
|
+
"eusc-[a-z]+-[a-z0-9]+-\\d+"
|
|
85137
|
+
].join("|") + ")$");
|
|
85138
|
+
/**
|
|
84734
85139
|
* The ONE case-normalization boundary of this module (issue #1786).
|
|
84735
85140
|
*
|
|
84736
85141
|
* DNS is case-INSENSITIVE, so `US-ISO-EAST-1.amazonaws.com` and
|
|
@@ -84775,11 +85180,21 @@ function matchEcrRegistryHost(imageUri) {
|
|
|
84775
85180
|
const form = ECR_HOST_FORM_BY_LABELS.get(m[2].toLowerCase());
|
|
84776
85181
|
if (!form) return void 0;
|
|
84777
85182
|
const region = m[3].toLowerCase();
|
|
85183
|
+
if (!AWS_REGION_ID.test(region)) {
|
|
85184
|
+
if (!GENERIC_REGION_SHAPE.test(region)) return void 0;
|
|
85185
|
+
return {
|
|
85186
|
+
accountId: m[1],
|
|
85187
|
+
region,
|
|
85188
|
+
suffix: m[4].toLowerCase(),
|
|
85189
|
+
expectedSuffix: void 0
|
|
85190
|
+
};
|
|
85191
|
+
}
|
|
85192
|
+
const partition = derivePartitionAndUrlSuffix(region);
|
|
84778
85193
|
return {
|
|
84779
85194
|
accountId: m[1],
|
|
84780
85195
|
region,
|
|
84781
85196
|
suffix: m[4].toLowerCase(),
|
|
84782
|
-
expectedSuffix: (form.fixedUrlSuffix ??
|
|
85197
|
+
expectedSuffix: form.partitions && !form.partitions.includes(partition.partition) ? void 0 : (form.fixedUrlSuffix ?? partition.urlSuffix).toLowerCase()
|
|
84783
85198
|
};
|
|
84784
85199
|
}
|
|
84785
85200
|
/**
|
|
@@ -84809,7 +85224,7 @@ function matchEcrRegistryHost(imageUri) {
|
|
|
84809
85224
|
function parseEcrRegistryHost(imageUri) {
|
|
84810
85225
|
const m = matchEcrRegistryHost(imageUri);
|
|
84811
85226
|
if (!m) return void 0;
|
|
84812
|
-
if (m.suffix !== m.expectedSuffix) return void 0;
|
|
85227
|
+
if (m.expectedSuffix === void 0 || m.suffix !== m.expectedSuffix) return void 0;
|
|
84813
85228
|
return {
|
|
84814
85229
|
accountId: m.accountId,
|
|
84815
85230
|
region: m.region
|
|
@@ -86489,7 +86904,7 @@ async function orphanCommand(pathArgs, options) {
|
|
|
86489
86904
|
const stackInfo = resolved.stack;
|
|
86490
86905
|
const orphanLogicalIds = resolved.logicalIds;
|
|
86491
86906
|
const { region: targetRegion, recordRegion } = await pickStackRegion(stateBackend, stackInfo.stackName, stackInfo.region, options.stackRegion);
|
|
86492
|
-
logger.info(`Target: ${
|
|
86907
|
+
logger.info(`Target: ${displayStackName(stackInfo.stackName)} (${displayIdent(targetRegion)}); orphaning ${orphanLogicalIds.length} resource(s): ${displaySafeList(orphanLogicalIds)}`);
|
|
86493
86908
|
const owner = `${process.env["USER"] || "unknown"}@${process.env["HOSTNAME"] || "host"}:${process.pid}`;
|
|
86494
86909
|
const recovery = {
|
|
86495
86910
|
profile: options.profile,
|
|
@@ -86506,7 +86921,7 @@ async function orphanCommand(pathArgs, options) {
|
|
|
86506
86921
|
}
|
|
86507
86922
|
try {
|
|
86508
86923
|
const stateData = await stateBackend.getState(stackInfo.stackName, targetRegion);
|
|
86509
|
-
if (!stateData) throw new Error(`No state found for stack
|
|
86924
|
+
if (!stateData) throw new Error(`No state found for stack ${displayStackName(stackInfo.stackName)} (${displaySafe(targetRegion, { asciiOnly: true })}). Nothing to orphan. (Did the stack get deployed?)`);
|
|
86510
86925
|
const { state, etag, migrationPending } = stateData;
|
|
86511
86926
|
refuseMalformedState(state, stackInfo.stackName, recordRegion, recovery);
|
|
86512
86927
|
refuseMalformedOutputs(state, stackInfo.stackName, recordRegion, recovery);
|
|
@@ -86517,7 +86932,7 @@ async function orphanCommand(pathArgs, options) {
|
|
|
86517
86932
|
const missing = orphanLogicalIds.filter((id) => !Object.hasOwn(state.resources, id));
|
|
86518
86933
|
if (missing.length > 0) {
|
|
86519
86934
|
const have = displayIdentList(Object.keys(state.resources), ", ");
|
|
86520
|
-
throw new Error(`Resource(s) not in state for stack
|
|
86935
|
+
throw new Error(`Resource(s) not in state for stack ${displayStackName(stackInfo.stackName)} (${displaySafe(targetRegion, { asciiOnly: true })}): ${displayIdentList(missing, ", ")}.\nAvailable logical IDs: ${have}`);
|
|
86521
86936
|
}
|
|
86522
86937
|
const providerRegistry = new ProviderRegistry();
|
|
86523
86938
|
registerAllProviders(providerRegistry);
|
|
@@ -86536,7 +86951,7 @@ async function orphanCommand(pathArgs, options) {
|
|
|
86536
86951
|
return;
|
|
86537
86952
|
}
|
|
86538
86953
|
if (!options.yes && !options.force) {
|
|
86539
|
-
if (!await confirmPrompt$1(`Orphan ${orphanLogicalIds.length} resource(s) from cdkd state for ${
|
|
86954
|
+
if (!await confirmPrompt$1(`Orphan ${orphanLogicalIds.length} resource(s) from cdkd state for ${displayStackName(stackInfo.stackName)} (${displayIdent(targetRegion)})? AWS resources will NOT be deleted.`)) {
|
|
86540
86955
|
logger.info("Orphan cancelled.");
|
|
86541
86956
|
return;
|
|
86542
86957
|
}
|
|
@@ -86545,7 +86960,7 @@ async function orphanCommand(pathArgs, options) {
|
|
|
86545
86960
|
expectedEtag: etag,
|
|
86546
86961
|
...migrationPending && { migrateLegacy: true }
|
|
86547
86962
|
});
|
|
86548
|
-
logger.info(`Orphaned ${orphanLogicalIds.length} resource(s) from state: ${
|
|
86963
|
+
logger.info(`Orphaned ${orphanLogicalIds.length} resource(s) from state: ${displayStackName(stackInfo.stackName)} (${displayIdent(targetRegion)}). AWS resources are still in AWS; cdkd will no longer manage them.`);
|
|
86549
86964
|
} finally {
|
|
86550
86965
|
if (!options.dryRun) await lockManager.releaseLock(stackInfo.stackName, targetRegion).catch((err) => {
|
|
86551
86966
|
logger.warn(`Failed to release lock: ${displayAwsMessage(err instanceof Error ? err.message : String(err))}`);
|
|
@@ -86584,12 +86999,12 @@ function resolveConstructPaths(paths, stacks) {
|
|
|
86584
86999
|
throw new Error(`Construct path '${p}': stack '${head}' not found in synthesized app. Available: ${available}`);
|
|
86585
87000
|
}
|
|
86586
87001
|
if (stack === void 0) stack = candidate;
|
|
86587
|
-
else if (stack.stackName !== candidate.stackName) throw new Error(`All construct paths must reference the same stack. Got
|
|
87002
|
+
else if (stack.stackName !== candidate.stackName) throw new Error(`All construct paths must reference the same stack. Got ${displayStackName(stack.stackName)} and ${displayStackName(candidate.stackName)}. Run 'cdkd orphan' once per stack.`);
|
|
86588
87003
|
const index = buildCdkPathIndex(candidate.template);
|
|
86589
87004
|
const matches = resolveCdkPathToLogicalIds(p, index);
|
|
86590
87005
|
if (matches.length === 0) {
|
|
86591
87006
|
const available = displayIdentList([...index.keys()].sort(), "\n ");
|
|
86592
|
-
throw new Error(`Construct path '${p}' not found in template for stack
|
|
87007
|
+
throw new Error(`Construct path '${p}' not found in template for stack ${displayStackName(candidate.stackName)}.\nAvailable paths:\n ${available}`);
|
|
86593
87008
|
}
|
|
86594
87009
|
for (const { logicalId } of matches) if (!logicalIds.includes(logicalId)) logicalIds.push(logicalId);
|
|
86595
87010
|
}
|
|
@@ -86616,12 +87031,12 @@ async function pickStackRegion(stateBackend, stackName, synthRegion, flag) {
|
|
|
86616
87031
|
region: synthRegion,
|
|
86617
87032
|
recordRegion: synthRegion
|
|
86618
87033
|
};
|
|
86619
|
-
throw new Error(`No state found for stack
|
|
87034
|
+
throw new Error(`No state found for stack ${displayStackName(stackName)}. Run 'cdkd state list' to see available stacks.`);
|
|
86620
87035
|
}
|
|
86621
87036
|
if (flag) {
|
|
86622
87037
|
if (!refs.find((r) => r.region === flag)) {
|
|
86623
87038
|
const seen = displayRegionList(refs);
|
|
86624
|
-
throw new Error(`No state found for stack
|
|
87039
|
+
throw new Error(`No state found for stack ${displayStackName(stackName)} in region ${displayIdent(flag)}. Available regions: ${seen}.`);
|
|
86625
87040
|
}
|
|
86626
87041
|
return {
|
|
86627
87042
|
region: flag,
|
|
@@ -86642,7 +87057,7 @@ async function pickStackRegion(stateBackend, stackName, synthRegion, flag) {
|
|
|
86642
87057
|
};
|
|
86643
87058
|
}
|
|
86644
87059
|
const regions = displayRegionList(refs);
|
|
86645
|
-
throw new Error(`Stack
|
|
87060
|
+
throw new Error(`Stack ${displayStackName(stackName)} has state in multiple regions: ${regions}. Re-run with --stack-region <region> to disambiguate.`);
|
|
86646
87061
|
}
|
|
86647
87062
|
function printRewriteSummary(rewrites, orphanLogicalIds) {
|
|
86648
87063
|
const logger = getLogger();
|
|
@@ -87288,7 +87703,10 @@ async function importCommand(stackArg, options) {
|
|
|
87288
87703
|
const existingState = existingResult?.state ?? null;
|
|
87289
87704
|
if (existingState) refuseMalformedState(existingState, stackInfo.stackName, targetRegion);
|
|
87290
87705
|
if (existingState) refuseMalformedOutputs(existingState, stackInfo.stackName, targetRegion);
|
|
87291
|
-
if (existingState)
|
|
87706
|
+
if (existingState) {
|
|
87707
|
+
refuseMalformedOrphans(existingState, stackInfo.stackName, targetRegion);
|
|
87708
|
+
refuseMalformedOrphanRecords(existingState, stackInfo.stackName, targetRegion);
|
|
87709
|
+
}
|
|
87292
87710
|
const existingEtag = existingResult?.etag;
|
|
87293
87711
|
const migrationPending = existingResult?.migrationPending ?? false;
|
|
87294
87712
|
if (existingState) {
|
|
@@ -89642,12 +90060,12 @@ function resolveAssetCodeDirectory(opts) {
|
|
|
89642
90060
|
if (isAbsolute(assetPath)) {
|
|
89643
90061
|
const absolute = resolve(assetPath);
|
|
89644
90062
|
const escape = absoluteAssemblyPathEscape(assetOutdir, absolute);
|
|
89645
|
-
if (escape !== void 0) getLogger().warn(`Lambda
|
|
90063
|
+
if (escape !== void 0) getLogger().warn(`Lambda ${displayIdent(logicalId)} has an absolute Metadata['aws:asset:path'] pointing outside the assembly: ${displayAssemblyPath(absolute)}` + (escape.escape === "symlink" ? ` (through a symbolic link to ${displayAssemblyPath(escape.realPath)})` : "") + ". cdkd will bind-mount that directory into the container read-only, where the code in this assembly can read it. This is what cdk synth --no-staging emits, and is expected for it; if you did not synthesize with that flag, treat this assembly as untrusted.");
|
|
89646
90064
|
return absolute;
|
|
89647
90065
|
}
|
|
89648
90066
|
const resolved = resolveAssemblyPath(manifestDir, assetPath, { containWithin: assetOutdir });
|
|
89649
90067
|
if (!resolved.contained && resolved.escape === "lexical" && resolved.path === resolve(assetOutdir)) return resolved.path;
|
|
89650
|
-
if (!resolved.contained) throw wrapError(`Lambda
|
|
90068
|
+
if (!resolved.contained) throw wrapError(`Lambda ${displayIdent(logicalId)} has Metadata['aws:asset:path']=${displayAssemblyPath(assetPath)} which ${renderAssemblyPathEscape(resolved, assetOutdir, "mount it")}`);
|
|
89651
90069
|
return resolved.path;
|
|
89652
90070
|
}
|
|
89653
90071
|
/**
|
|
@@ -89676,9 +90094,8 @@ function resolveAssetCodeDirectory(opts) {
|
|
|
89676
90094
|
* `process.cwd()` survives only for a `StackInfo` carrying NEITHER field, where
|
|
89677
90095
|
* base and bound coincide again.
|
|
89678
90096
|
*
|
|
89679
|
-
* Exported for `local-start-api.ts`'s copy of the caller, for
|
|
89680
|
-
*
|
|
89681
|
-
* (which is why it takes only the two fields it reads), and for unit testing.
|
|
90097
|
+
* Exported for `local-start-api.ts`'s copy of the caller, and for unit
|
|
90098
|
+
* testing.
|
|
89682
90099
|
*/
|
|
89683
90100
|
function assetPathDirs(stack) {
|
|
89684
90101
|
const manifestDir = stack.assetManifestPath ? dirname(stack.assetManifestPath) : stack.assetOutdir ?? process.cwd();
|
|
@@ -89704,7 +90121,7 @@ function assetPathDirs(stack) {
|
|
|
89704
90121
|
*/
|
|
89705
90122
|
function resolveAssetCodePath$1(stack, logicalId, resource) {
|
|
89706
90123
|
const assetPath = resource.Metadata?.["aws:asset:path"];
|
|
89707
|
-
if (typeof assetPath !== "string" || assetPath.length === 0) throw new LocalInvokeResolutionError(`Lambda
|
|
90124
|
+
if (typeof assetPath !== "string" || assetPath.length === 0) throw new LocalInvokeResolutionError(`Lambda ${displayIdent(logicalId)} has no Metadata['aws:asset:path']. cdkd local invoke needs this hint to find the local asset directory. Re-synthesize the app (without \`--output <stale-dir>\`) and retry.`);
|
|
89708
90125
|
const { manifestDir, assetOutdir } = assetPathDirs(stack);
|
|
89709
90126
|
const abs = resolveAssetCodeDirectory({
|
|
89710
90127
|
manifestDir,
|
|
@@ -89713,7 +90130,7 @@ function resolveAssetCodePath$1(stack, logicalId, resource) {
|
|
|
89713
90130
|
assetOutdir,
|
|
89714
90131
|
logicalId
|
|
89715
90132
|
});
|
|
89716
|
-
if (!existsSync(abs) || !statSync(abs).isDirectory()) throw new LocalInvokeResolutionError(`Lambda
|
|
90133
|
+
if (!existsSync(abs) || !statSync(abs).isDirectory()) throw new LocalInvokeResolutionError(`Lambda ${displayIdent(logicalId)} asset directory ${displayAssemblyPath(abs)} does not exist or is not a directory. Re-synthesize the app and retry.`);
|
|
89717
90134
|
return abs;
|
|
89718
90135
|
}
|
|
89719
90136
|
/**
|
|
@@ -90736,7 +91153,7 @@ function parseContainerImage(raw, containerName, taskLogicalId, resources, _stac
|
|
|
90736
91153
|
account: ecrHost.accountId,
|
|
90737
91154
|
region: ecrHost.region
|
|
90738
91155
|
};
|
|
90739
|
-
if (looksLikeEcrHostWithForeignSuffix(substituted)) getLogger().child("ecs-task-resolver").debug(`Image '${substituted}' has an ECR host shape but
|
|
91156
|
+
if (looksLikeEcrHostWithForeignSuffix(substituted)) getLogger().child("ecs-task-resolver").debug(`Image '${substituted}' has an ECR host shape, but that host form and suffix are not an ECR registry endpoint for its region; treating it as a public image (no docker login).`);
|
|
90740
91157
|
return {
|
|
90741
91158
|
kind: "public",
|
|
90742
91159
|
uri: substituted
|
|
@@ -91319,24 +91736,19 @@ const SENSITIVE_ENV_KEYS = /* @__PURE__ */ new Set([
|
|
|
91319
91736
|
* boundary, so a local-invoke build failure still surfaces with cdkd's exit code
|
|
91320
91737
|
* / branding. `architectureToPlatform` is a pure helper (re-exported directly).
|
|
91321
91738
|
*
|
|
91322
|
-
*
|
|
91323
|
-
* `
|
|
91324
|
-
*
|
|
91325
|
-
*
|
|
91739
|
+
* The build context is CONTAINED by the engine, against the REQUIRED
|
|
91740
|
+
* `assetOutdir` bound this shim forwards (issues
|
|
91741
|
+
* [#3503](https://github.com/go-to-k/cdkd/issues/3503),
|
|
91742
|
+
* [#3597](https://github.com/go-to-k/cdkd/issues/3597)): without one the
|
|
91743
|
+
* engine narrows to the manifest directory and refuses a `cdk.Stage` image's
|
|
91744
|
+
* `../asset.<hash>`. The engine refuses an escaping `source.directory` before
|
|
91745
|
+
* it spawns anything, and renders the value display-safe since cdk-local
|
|
91746
|
+
* 0.149.4, so cdkd carries no copy of the check (go-to-k/cdkd#3652).
|
|
91326
91747
|
* See cdk-local's `src/local/docker-image-builder.ts`.
|
|
91327
91748
|
*/
|
|
91328
91749
|
async function buildContainerImage$1(asset, cdkOutDir, options) {
|
|
91329
|
-
const executable = asset?.source?.executable;
|
|
91330
|
-
if (executable && executable.length > 0) warnManifestExecutable(executable);
|
|
91331
|
-
const { assetOutdir, ...implOptions } = options;
|
|
91332
|
-
assertCdkLocalDockerContextContained({
|
|
91333
|
-
manifestDir: cdkOutDir,
|
|
91334
|
-
source: asset.source,
|
|
91335
|
-
assetOutdir,
|
|
91336
|
-
wrapError: (message) => new LocalInvokeBuildError$1(`Refusing to build the container image: ${message}`)
|
|
91337
|
-
});
|
|
91338
91750
|
try {
|
|
91339
|
-
return await buildContainerImage(asset, cdkOutDir,
|
|
91751
|
+
return await buildContainerImage(asset, cdkOutDir, options);
|
|
91340
91752
|
} catch (e) {
|
|
91341
91753
|
if (e instanceof LocalInvokeBuildError) throw new LocalInvokeBuildError$1(e.message);
|
|
91342
91754
|
throw e;
|
|
@@ -91345,10 +91757,6 @@ async function buildContainerImage$1(asset, cdkOutDir, options) {
|
|
|
91345
91757
|
|
|
91346
91758
|
//#endregion
|
|
91347
91759
|
//#region src/local/ecr-puller.ts
|
|
91348
|
-
/** The URL suffix an ECR registry host uses in `region`'s partition (issue #1758). */
|
|
91349
|
-
function ecrUrlSuffix(region) {
|
|
91350
|
-
return derivePartitionAndUrlSuffix(region).urlSuffix;
|
|
91351
|
-
}
|
|
91352
91760
|
/**
|
|
91353
91761
|
* Lower-case the REGISTRY HOST of an image reference and leave the repository
|
|
91354
91762
|
* path and tag byte-identical.
|
|
@@ -91380,7 +91788,25 @@ function canonicalizeImageUriHost(imageUri) {
|
|
|
91380
91788
|
if (slash < 0) return imageUri;
|
|
91381
91789
|
const host = imageUri.slice(0, slash);
|
|
91382
91790
|
if (!isRegistryHostComponent(host)) return imageUri;
|
|
91383
|
-
return host
|
|
91791
|
+
return foldAsciiUpperCase(host) + imageUri.slice(slash);
|
|
91792
|
+
}
|
|
91793
|
+
/**
|
|
91794
|
+
* Lower-case ONLY the ASCII letters `A`-`Z`, leaving every other code point
|
|
91795
|
+
* as written.
|
|
91796
|
+
*
|
|
91797
|
+
* `String.prototype.toLowerCase` performs full Unicode case folding, so the
|
|
91798
|
+
* Kelvin sign U+212A folds to a plain ASCII `k`. Folding with it here, BEFORE
|
|
91799
|
+
* `parseEcrRegistryHost`, handed that parser an already-ASCII host and defeated
|
|
91800
|
+
* the raw-capture charset guard it applies to the region and suffix (see
|
|
91801
|
+
* `CANONICAL_REGION_SEGMENT` in `src/utils/ecr-uri.ts`):
|
|
91802
|
+
* `<acct>.dkr.ecr-fips.us-<U+212A>east-1.amazonaws.com/...` parsed as the
|
|
91803
|
+
* region `us-keast-1`, a region the host does not name, and a Kelvin sign in
|
|
91804
|
+
* the LABELS resolved to the plain form. An ASCII-only fold keeps the case
|
|
91805
|
+
* fold the #1801 login / pull agreement needs (DNS case-insensitivity is
|
|
91806
|
+
* ASCII-only) while leaving any other code point for that guard to refuse.
|
|
91807
|
+
*/
|
|
91808
|
+
function foldAsciiUpperCase(value) {
|
|
91809
|
+
return value.replace(/[A-Z]+/g, (run) => run.toLowerCase());
|
|
91384
91810
|
}
|
|
91385
91811
|
/** Docker's rule for "component 1 is a registry, not a repository segment". */
|
|
91386
91812
|
function isRegistryHostComponent(component) {
|
|
@@ -91450,10 +91876,8 @@ function isCredentialFresh(creds) {
|
|
|
91450
91876
|
* pass to `docker run`: the input with its registry HOST lower-cased and
|
|
91451
91877
|
* its repository path + tag untouched (issue #1801). That is the SAME
|
|
91452
91878
|
* spelling `docker pull` / `docker image inspect` were handed here, and
|
|
91453
|
-
* the same one the
|
|
91454
|
-
*
|
|
91455
|
-
* a VPC-endpoint host), which is correct: AWS names the endpoint its own
|
|
91456
|
-
* token authenticates, and it reports it lower-cased.
|
|
91879
|
+
* the same one the `docker login` endpoint names, on every host form
|
|
91880
|
+
* (issues #1855 / #3670).
|
|
91457
91881
|
*/
|
|
91458
91882
|
async function pullEcrImage(imageUri, options) {
|
|
91459
91883
|
const logger = getLogger().child("ecr-puller");
|
|
@@ -91504,7 +91928,11 @@ async function pullEcrImage(imageUri, options) {
|
|
|
91504
91928
|
...assumed && { credentials: assumed }
|
|
91505
91929
|
});
|
|
91506
91930
|
try {
|
|
91507
|
-
await ecrLogin(ecr,
|
|
91931
|
+
await ecrLogin(ecr, {
|
|
91932
|
+
accountId: parsed.accountId,
|
|
91933
|
+
region: parsed.region,
|
|
91934
|
+
registryHost: canonicalUri.slice(0, canonicalUri.indexOf("/"))
|
|
91935
|
+
});
|
|
91508
91936
|
} finally {
|
|
91509
91937
|
ecr.destroy();
|
|
91510
91938
|
}
|
|
@@ -91553,16 +91981,30 @@ async function assumeRoleForEcr(roleArn, callerRegion, logger) {
|
|
|
91553
91981
|
}
|
|
91554
91982
|
/**
|
|
91555
91983
|
* Authenticate the local docker daemon against the target ECR registry.
|
|
91556
|
-
*
|
|
91557
|
-
*
|
|
91558
|
-
|
|
91559
|
-
|
|
91560
|
-
|
|
91984
|
+
* Kept apart from `DockerAssetPublisher.ecrLogin`, and it no longer mirrors it:
|
|
91985
|
+
* the publisher still prefers `proxyEndpoint`, which is right only because it
|
|
91986
|
+
* pushes to the CALLER's own registry, while a pull here can name any account
|
|
91987
|
+
* and any host form, so this one always logs in to the pull host.
|
|
91988
|
+
*
|
|
91989
|
+
* The login endpoint is ALWAYS the host the PULL targets (issues #1855 /
|
|
91990
|
+
* #3670): docker's credential store is keyed on the hostname verbatim, so a
|
|
91991
|
+
* login to any other host leaves the pull with no credentials (`no basic auth
|
|
91992
|
+
* credentials`). `GetAuthorizationToken`'s `proxyEndpoint` is therefore NOT
|
|
91993
|
+
* used. The request carries no `registryIds`, so it names the CALLER's default
|
|
91994
|
+
* registry on the plain host: the wrong host for a FIPS or dual-stack pull, and
|
|
91995
|
+
* the wrong ACCOUNT for a cross-account plain pull made on the caller's own
|
|
91996
|
+
* credentials (a repository-policy grant, no `--ecr-role-arn`). The token is
|
|
91997
|
+
* principal-scoped, not host-scoped: measured against real ECR, one token
|
|
91998
|
+
* authenticated `/v2/` on all four host forms `ECR_REGISTRY_HOST_FORMS` lists.
|
|
91999
|
+
*/
|
|
92000
|
+
async function ecrLogin(client, target) {
|
|
92001
|
+
const { accountId, region, registryHost } = target;
|
|
92002
|
+
getLogger().child("ecr-puller").debug(`ECR login (account=${accountId}, region=${region}, host=${registryHost})`);
|
|
91561
92003
|
const authData = (await client.send(new GetAuthorizationTokenCommand({}))).authorizationData?.[0];
|
|
91562
92004
|
if (!authData?.authorizationToken) throw new LocalInvokeBuildError$1("Failed to get ECR authorization token");
|
|
91563
92005
|
const [username, password] = Buffer.from(authData.authorizationToken, "base64").toString().split(":");
|
|
91564
92006
|
if (!username || password === void 0) throw new LocalInvokeBuildError$1("ECR authorization token has unexpected shape (missing username/password)");
|
|
91565
|
-
const endpoint =
|
|
92007
|
+
const endpoint = `https://${registryHost}`;
|
|
91566
92008
|
const loginArgs = [
|
|
91567
92009
|
"login",
|
|
91568
92010
|
"--username",
|
|
@@ -93811,7 +94253,7 @@ function resolveImageLambda(args) {
|
|
|
93811
94253
|
*/
|
|
93812
94254
|
function resolveAssetCodePath(stack, logicalId, resource) {
|
|
93813
94255
|
const assetPath = resource.Metadata?.["aws:asset:path"];
|
|
93814
|
-
if (typeof assetPath !== "string" || assetPath.length === 0) throw new Error(`Lambda
|
|
94256
|
+
if (typeof assetPath !== "string" || assetPath.length === 0) throw new Error(`Lambda ${displayIdent(logicalId)} has no Metadata['aws:asset:path']. cdkd local start-api needs this hint to find the local asset directory. Re-synthesize the app and retry.`);
|
|
93815
94257
|
const { manifestDir, assetOutdir } = assetPathDirs(stack);
|
|
93816
94258
|
return resolveAssetCodeDirectory({
|
|
93817
94259
|
manifestDir,
|
|
@@ -95740,130 +96182,6 @@ function createLocalRunTaskCommand() {
|
|
|
95740
96182
|
return cmd;
|
|
95741
96183
|
}
|
|
95742
96184
|
|
|
95743
|
-
//#endregion
|
|
95744
|
-
//#region src/cli/commands/emulator-docker-context.ts
|
|
95745
|
-
/**
|
|
95746
|
-
* Decorate an `EmulatorStrategy` so every Docker image asset the bundled
|
|
95747
|
-
* engine could build for this run is containment-checked BEFORE it builds one
|
|
95748
|
-
* (issue [#3503](https://github.com/go-to-k/cdkd/issues/3503)).
|
|
95749
|
-
*
|
|
95750
|
-
* `cdkd local start-service` / `start-alb` hand the whole run to cdk-local's
|
|
95751
|
-
* `runEcsServiceEmulator`, which reads each stack's asset manifest itself and
|
|
95752
|
-
* joins `source.directory` onto the manifest directory raw — for an ECS
|
|
95753
|
-
* container image and for an ALB Lambda target's container image alike. No
|
|
95754
|
-
* argument reaches that join, so cdkd judges the manifests here instead.
|
|
95755
|
-
*
|
|
95756
|
-
* `resolveBoots` is the seam because the engine calls it after every synth —
|
|
95757
|
-
* at boot, and again on every `--watch` reload — and before any image is
|
|
95758
|
-
* built on either path. A refusal at boot fails the command; on a reload the
|
|
95759
|
-
* engine logs it and keeps the previous replicas serving, which is the
|
|
95760
|
-
* fail-closed outcome.
|
|
95761
|
-
*
|
|
95762
|
-
* Every stack with a manifest is checked, not only the booted targets' stacks:
|
|
95763
|
-
* which stack a target resolves to is decided inside the engine, and the ALB
|
|
95764
|
-
* front door builds Lambda images from stacks no ECS boot names. An escaping
|
|
95765
|
-
* `source.directory` is never something a real `cdk synth` writes, so
|
|
95766
|
-
* refusing one anywhere in the assembly costs a legitimate run nothing, and
|
|
95767
|
-
* `cdkd deploy` refuses the same assembly.
|
|
95768
|
-
*/
|
|
95769
|
-
function containEmulatorDockerContexts(strategy) {
|
|
95770
|
-
return {
|
|
95771
|
-
...strategy,
|
|
95772
|
-
resolveBoots: (stacks, chosenTargets) => {
|
|
95773
|
-
assertEmulatorDockerContextsContained(stacks);
|
|
95774
|
-
return strategy.resolveBoots(stacks, chosenTargets);
|
|
95775
|
-
}
|
|
95776
|
-
};
|
|
95777
|
-
}
|
|
95778
|
-
/**
|
|
95779
|
-
* The check itself, over the manifests the engine will read. Exported for
|
|
95780
|
-
* unit testing.
|
|
95781
|
-
*
|
|
95782
|
-
* It reads the SAME file the engine does — `<manifest dir>/<stackName>.assets.json`,
|
|
95783
|
-
* not `assetManifestPath` verbatim — and refuses a `stackName` that would
|
|
95784
|
-
* carry that filename out of the manifest directory, as cdkd's own
|
|
95785
|
-
* `AssetManifestLoader.loadManifest` does.
|
|
95786
|
-
*
|
|
95787
|
-
* A manifest that is absent, unreadable or not JSON is skipped: the engine
|
|
95788
|
-
* reads it again and reports that failure itself, before building anything.
|
|
95789
|
-
*/
|
|
95790
|
-
function assertEmulatorDockerContextsContained(stacks) {
|
|
95791
|
-
for (const stack of stacks) {
|
|
95792
|
-
if (!stack.assetManifestPath) continue;
|
|
95793
|
-
const dirs = assetPathDirs(stack);
|
|
95794
|
-
const { manifestDir } = dirs;
|
|
95795
|
-
const assetOutdir = stack.assetOutdir === void 0 || stack.assetOutdir === "" ? dirs.assetOutdir : engineAssemblyRoot(stack.assetOutdir);
|
|
95796
|
-
const manifestFile = resolveAssemblyPath(manifestDir, `${stack.stackName}.assets.json`);
|
|
95797
|
-
if (!manifestFile.contained) throw new LocalInvokeBuildError$1(`Refusing to build container images: the asset manifest for stack '${displaySafe(stack.stackName)}' ${renderAssemblyPathEscape(manifestFile, manifestDir)}`);
|
|
95798
|
-
const dockerImages = readDockerImages(manifestFile.path);
|
|
95799
|
-
for (const [assetId, asset] of Object.entries(dockerImages)) {
|
|
95800
|
-
const source = asset?.source;
|
|
95801
|
-
if (source === null || typeof source !== "object") continue;
|
|
95802
|
-
const { directory } = source;
|
|
95803
|
-
if (typeof directory !== "string") continue;
|
|
95804
|
-
assertCdkLocalDockerContextContained({
|
|
95805
|
-
manifestDir,
|
|
95806
|
-
source,
|
|
95807
|
-
assetOutdir,
|
|
95808
|
-
wrapError: (message) => new LocalInvokeBuildError$1(`Refusing to build container image asset '${displaySafe(assetId)}' of stack '${displaySafe(stack.stackName)}': ${message}`)
|
|
95809
|
-
});
|
|
95810
|
-
}
|
|
95811
|
-
}
|
|
95812
|
-
}
|
|
95813
|
-
/**
|
|
95814
|
-
* The containment bound the ENGINE itself uses for a stack it synthesized: its
|
|
95815
|
-
* `assetOutdir`, climbed to the parent assembly when `--app` names a
|
|
95816
|
-
* `cdk.Stage` sub-assembly. cdk-local enumerates no Stage stacks from an app
|
|
95817
|
-
* root, so `--app cdk.out/assembly-<Stage>` is the only way these commands run
|
|
95818
|
-
* a Stage, and its assets are staged one level up as `../asset.<hash>`.
|
|
95819
|
-
*
|
|
95820
|
-
* A copy of cdk-local's `assemblyRootOf` (not exported by the package): climb
|
|
95821
|
-
* only while the directory is named `assembly-*` AND its parent's
|
|
95822
|
-
* `manifest.json` declares it as a `cdk:cloud-assembly` artifact, and WARN
|
|
95823
|
-
* whenever a climb happens, since the predicate is read from the tree being
|
|
95824
|
-
* judged. Replace with the upstream export once one exists (go-to-k/cdkd#3597).
|
|
95825
|
-
*/
|
|
95826
|
-
function engineAssemblyRoot(outdir) {
|
|
95827
|
-
let dir = resolve(outdir);
|
|
95828
|
-
let climbed = false;
|
|
95829
|
-
for (;;) {
|
|
95830
|
-
if (!basename(dir).startsWith("assembly-")) break;
|
|
95831
|
-
const parent = dirname(dir);
|
|
95832
|
-
if (parent === dir || !parentDeclaresNestedAssembly(parent, basename(dir))) break;
|
|
95833
|
-
dir = parent;
|
|
95834
|
-
climbed = true;
|
|
95835
|
-
}
|
|
95836
|
-
if (!climbed) return outdir;
|
|
95837
|
-
if (!warnedDerivedRoots.has(dir)) {
|
|
95838
|
-
warnedDerivedRoots.add(dir);
|
|
95839
|
-
getLogger().warn(`${displayAssemblyPath(outdir)} is a cdk.Stage sub-assembly, so cdkd is treating its parent ${displayAssemblyPath(dir)} as the assembly root when it checks Docker build contexts — that is where cdk synth stages a Stage's assets. Everything under that parent is now inside the containment bound, including siblings of the directory you named.`);
|
|
95840
|
-
}
|
|
95841
|
-
return dir;
|
|
95842
|
-
}
|
|
95843
|
-
const warnedDerivedRoots = /* @__PURE__ */ new Set();
|
|
95844
|
-
function parentDeclaresNestedAssembly(parent, child) {
|
|
95845
|
-
try {
|
|
95846
|
-
const artifacts = JSON.parse(readFileSync(join(parent, "manifest.json"), "utf-8")).artifacts;
|
|
95847
|
-
if (artifacts === null || typeof artifacts !== "object") return false;
|
|
95848
|
-
return Object.values(artifacts).some((a) => {
|
|
95849
|
-
const art = a;
|
|
95850
|
-
return art?.type === "cdk:cloud-assembly" && art.properties?.directoryName === child;
|
|
95851
|
-
});
|
|
95852
|
-
} catch {
|
|
95853
|
-
return false;
|
|
95854
|
-
}
|
|
95855
|
-
}
|
|
95856
|
-
function readDockerImages(manifestPath) {
|
|
95857
|
-
let parsed;
|
|
95858
|
-
try {
|
|
95859
|
-
parsed = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
95860
|
-
} catch {
|
|
95861
|
-
return {};
|
|
95862
|
-
}
|
|
95863
|
-
const dockerImages = parsed?.dockerImages;
|
|
95864
|
-
return dockerImages !== null && typeof dockerImages === "object" ? dockerImages : {};
|
|
95865
|
-
}
|
|
95866
|
-
|
|
95867
96185
|
//#endregion
|
|
95868
96186
|
//#region src/cli/commands/local-start-service.ts
|
|
95869
96187
|
/**
|
|
@@ -95891,17 +96209,6 @@ function serviceStrategy() {
|
|
|
95891
96209
|
};
|
|
95892
96210
|
}
|
|
95893
96211
|
/**
|
|
95894
|
-
* The `EmulatorStrategy` `cdkd local start-service` runs with:
|
|
95895
|
-
* {@link serviceStrategy}, decorated by `containEmulatorDockerContexts` so the
|
|
95896
|
-
* engine's own Docker builds are containment-checked (issue
|
|
95897
|
-
* [#3503](https://github.com/go-to-k/cdkd/issues/3503)). A NAMED seam for the
|
|
95898
|
-
* same reason `buildAlbEmulatorStrategy` is one: inline in the action, the
|
|
95899
|
-
* decorator was deletable at its only call site.
|
|
95900
|
-
*/
|
|
95901
|
-
function buildServiceEmulatorStrategy() {
|
|
95902
|
-
return containEmulatorDockerContexts(serviceStrategy());
|
|
95903
|
-
}
|
|
95904
|
-
/**
|
|
95905
96212
|
* `cdkl start-service <Stack/Service>...` — run one or more `AWS::ECS::Service`
|
|
95906
96213
|
* resources locally as a long-running emulator. Spins up DesiredCount task
|
|
95907
96214
|
* replicas per service (clamped by --max-tasks) using the same per-task
|
|
@@ -95914,7 +96221,7 @@ function buildServiceEmulatorStrategy() {
|
|
|
95914
96221
|
*/
|
|
95915
96222
|
function createLocalStartServiceCommand() {
|
|
95916
96223
|
const cmd = new Command("start-service").description("Run one or more AWS::ECS::Service resources locally as a long-running emulator. Spins up DesiredCount task replicas per service (clamped by --max-tasks) using the same per-task docker network + metadata sidecar pattern as `cdkd local run-task`, then keeps each replica running and restarts it on exit per --restart-policy. ^C tears every replica + sidecar + network down. Each <target> accepts a CDK display path (MyStack/MyService) or stack-qualified logical ID (MyStack:MyServiceXYZ); single-stack apps may omit the stack prefix. When two or more <target>s are supplied, every service is booted into a shared Cloud Map / Service Connect registry so peer services discover each other via docker --add-host overlay (Issue #460). Omit <targets> in an interactive terminal to multi-select the ECS services from a list.").argument("[targets...]", "One or more CDK display paths or stack-qualified logical IDs of the AWS::ECS::Service resources to run (omit to multi-select interactively in a TTY)").addOption(new Option("--from-state", "Read cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue / Fn::GetStackOutput intrinsics in container images, environment variables, secrets, role ARNs, and volumes. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--state-bucket <bucket>", "S3 bucket for --from-state. Falls back to CDKD_STATE_BUCKET env or cdk.json context.cdkd.stateBucket.")).addOption(new Option("--state-prefix <prefix>", "S3 key prefix for --from-state state files.").default("cdkd")).action(withErrorHandling(async (targets, options) => {
|
|
95917
|
-
await runEcsServiceEmulator(targets, options,
|
|
96224
|
+
await runEcsServiceEmulator(targets, options, serviceStrategy(), cdkdExtraStateProviders);
|
|
95918
96225
|
}));
|
|
95919
96226
|
addStartServiceSpecificOptions(cmd);
|
|
95920
96227
|
return adoptDeprecatedRegionFlag(addCommonEcsServiceOptions(cmd));
|
|
@@ -96846,12 +97153,12 @@ async function resolveAgentCoreCodeImage(resolved, code, options, architecture,
|
|
|
96846
97153
|
const manifest = await loader.loadManifest(cdkOutDir, resolved.stack.stackName);
|
|
96847
97154
|
const fileAssets = manifest ? loader.getFileAssets(manifest) : void 0;
|
|
96848
97155
|
const asset = fileAssets ? fileAssets.get(code.codeAssetHash) ?? findFileAssetByObjectKey(fileAssets, code.codeAssetHash) : void 0;
|
|
96849
|
-
if (!asset) throw new CdkdError(`AgentCore Runtime
|
|
97156
|
+
if (!asset) throw new CdkdError(`AgentCore Runtime ${displayIdent(resolved.logicalId)} code bundle (asset ${displaySafe(code.codeAssetHash)}) was not found in the cdk.out asset manifest. ${getEmbedConfig().cliName} invoke-agentcore runs a local from-source build of a fromCodeAsset bundle — re-synthesize the app so the asset is staged in cdk.out and retry. (A fromS3 bundle is downloaded from S3 instead; this runtime has no literal Code.S3.Bucket.)`, "LOCAL_INVOKE_AGENTCORE_CODE_ASSET_NOT_FOUND");
|
|
96850
97157
|
const sourceDir = loader.getAssetSourcePath(cdkOutDir, asset, {
|
|
96851
97158
|
assetOutdir: assemblyDir,
|
|
96852
97159
|
sink: "read that directory and build a local image from it"
|
|
96853
97160
|
});
|
|
96854
|
-
if (!existsSync(sourceDir) || !statSync(sourceDir).isDirectory()) throw new CdkdError(`AgentCore Runtime
|
|
97161
|
+
if (!existsSync(sourceDir) || !statSync(sourceDir).isDirectory()) throw new CdkdError(`AgentCore Runtime ${displayIdent(resolved.logicalId)} code bundle source ${displayAssemblyPath(sourceDir)} does not exist or is not a directory. Re-synthesize the app and retry.`, "LOCAL_INVOKE_AGENTCORE_CODE_SOURCE_MISSING");
|
|
96855
97162
|
return buildAgentCoreCodeImage({
|
|
96856
97163
|
sourceDir,
|
|
96857
97164
|
runtime: code.runtime,
|
|
@@ -97603,8 +97910,7 @@ function warnUnresolvedLambdaTargetEnv(strategy, options) {
|
|
|
97603
97910
|
}
|
|
97604
97911
|
/**
|
|
97605
97912
|
* The `EmulatorStrategy` `cdkd local start-alb` runs with: cdk-local's ALB
|
|
97606
|
-
* strategy, decorated by {@link warnUnresolvedLambdaTargetEnv}
|
|
97607
|
-
* `containEmulatorDockerContexts` (issue go-to-k/cdkd#3503).
|
|
97913
|
+
* strategy, decorated by {@link warnUnresolvedLambdaTargetEnv}.
|
|
97608
97914
|
*
|
|
97609
97915
|
* Extracted from the command's action for ONE reason, and it is the finding
|
|
97610
97916
|
* that produced it: with the composition written inline in the `.action(...)`
|
|
@@ -97624,7 +97930,7 @@ function warnUnresolvedLambdaTargetEnv(strategy, options) {
|
|
|
97624
97930
|
* can satisfy reads as coverage while providing none.
|
|
97625
97931
|
*/
|
|
97626
97932
|
function buildAlbEmulatorStrategy(options) {
|
|
97627
|
-
return
|
|
97933
|
+
return warnUnresolvedLambdaTargetEnv(albStrategy(options), options);
|
|
97628
97934
|
}
|
|
97629
97935
|
/**
|
|
97630
97936
|
* `cdkl start-alb <Stack/Alb>` — Issue #86 v1. Names an
|
|
@@ -98762,4 +99068,4 @@ function buildProgram() {
|
|
|
98762
99068
|
|
|
98763
99069
|
//#endregion
|
|
98764
99070
|
export { buildProgram };
|
|
98765
|
-
//# sourceMappingURL=program-
|
|
99071
|
+
//# sourceMappingURL=program-DxyHPT8E.js.map
|