@go-to-k/cdkd 0.284.25 → 0.284.26
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-B2lPfJBN.js → asg-provider-CS5j-5z6.js} +2 -2
- package/dist/{asg-provider-B2lPfJBN.js.map → asg-provider-CS5j-5z6.js.map} +1 -1
- package/dist/cli.js +252 -21
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-BpZWPiaL.js → deploy-engine-DNCs229s.js} +16 -3
- package/dist/deploy-engine-DNCs229s.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BpZWPiaL.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as isInterruptedWaitError, $n as LocalMigrateError, $t as escapeRegExp, A as isStatefulRecreateTargetSync, An as CFN_TEMPLATE_BODY_LIMIT, At as s3BucketArn, B as collectPublishedOutputNames, Bn as processStackMessages, Bt as DagBuilder, C as createPreDeleteFinalSnapshot, Cn as resolveCaptureObservedState, Ct as TEMPLATE_SOURCED_RULES, D as makeCanonicalizePropertiesFn, Dn as resolveUseCdkBootstrapAssets, Dt as maskSecretsInText, E as unsupportedFinalSnapshotError, En as resolveStateBucketWithDefaultAndSource, Et as isSingleDynamicReferenceToken, F as gray, Fn as expectedOwnerParam, Ft as applyRoleArnIfSet, G as IAMRoleProvider, Gn as resetAwsClients, Gt as shouldRetainResource, H as isExportAliasCollision, Hn as resolveBucketRegion, Ht as LockManager, I as green, In as PARTITION_TABLE, It as DiffCalculator, J as ProviderRegistry, Jn as CdkdError, Jt as WorkGraph, K as collectInlinePolicyNamesManagedBySiblings, Kn as setAwsClients, Kt as AssetPublisher, L as red, Ln as canonicalizeRegion, Lt as INTRINSIC_KEYS, M as formatResourceLine, Mn as MIGRATE_TMP_PREFIX, Mt as s3BucketDualStackDomainName, N as bold, Nn as findLargeInlineResources, Nt as s3BucketRegionalDomainName, O as extractDeploymentEventError, On as stateBucketExistenceConfirmed, Ot as redactSecretsForState, P as cyan, Pn as uploadCfnTemplate, Pt as s3BucketWebsiteUrl, Q as endCommandInterruptScope, Qn as LocalInvokeBuildError$1, Qt as rewriteTemplateAssetReferences, R as yellow, Rn as derivePartitionAndUrlSuffix, Rt as describeTypeWithThrottleRetry, S as ccRoutedFinalSnapshotError, Sn as resolveAutoAssetStorage, St as STATE_SOURCED_READBACK_RULES, T as refusesFinalSnapshot, Tn as resolveStateBucketWithDefault, Tt as dynamicReferenceTokens, U as secretBearingStateKeyWarning, Un as AwsClients, Ut as S3StateBackend, V as exportAliasCollisionScrubWarning, Vt as TemplateParser, W as stateKeySecretExposure, Wn as getAwsClients, Wt as rebuildClientForBucketRegion, X as findSilentDropProperties, Xt as createAssetRedirectResolver, Y as findActionableSilentDrops, Yt as buildAssetRedirectMap, Z as beginCommandInterruptScope, Zn as DeployCancelledError, Zt as loadPublishableAssetManifest, _ as IMPLICIT_DELETE_DEPENDENCIES, _n as Synthesizer, _r as isRetryableTransientError, _t as replayWarn, a as DeploymentEventsStore, an as parseBootstrapMarker, ar as ProvisioningError, at as IntrinsicFunctionResolver, b as PRE_DELETE_SNAPSHOT_TYPES, bn as getLegacyStateBucketName, bt as requireConfigString, c as producerRegionsFromState, cn as validateContainerRepoName, cr as StackHasActiveImportsError, ct as refStateLookupFromResource, d as updatePartialMessage, dn as formatDockerLoginError, dt as resolveExplicitPhysicalId, en as stripControlChars, er as LocalStartServiceError, et as startInterruptWatch, f as updatePartialReason, fn as getDockerCmd, ft as assertRegionMatch, g as maskingRetryLogger, gn as getDockerImageBySourceHash, gr as isMarkedNonRetryable, gt as readConfigString, h as withResourceDeadline, hn as AssetManifestLoader, hr as withErrorHandling, ht as configStringRefusal, i as DeploymentEventsReader, in as getBootstrapMarkerKey, ir as PartialFailureError, it as isTerminationProtectionPropagationError, j as renderStatefulReason, jn as CFN_TEMPLATE_URL_LIMIT, jt as s3BucketDomainName, k as MULTI_REGION_RECREATE_BLOCKED_TYPES, kn as warnDeprecatedNoPrefixCliFlag, kt as scrubResourceRecord, l as replayFailedOperations, ln as buildDenyExternalAccessPolicy, lr as StackTerminationProtectionError, lt as WAFv2WebACLProvider, m as deleteSkipReason, mn as runDockerStreaming, mr as normalizeAwsError, mt as configBooleanRefusal, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as BOOTSTRAP_MARKER_PREFIX, nr as MissingCdkCliError, nt as slowCcOperationTimeoutMs, o as planFailedOps, on as readBootstrapMarkerBody, or as ResourceTimeoutError, ot as cfnRefValueFromPhysicalId, p as UNSPECIFIED_SKIP_REASON, pn as runDockerForeground, pt as coerceCfnBoolean, q as clearOnUpdateRemoval, qt as stringifyValue, r as DeployEngine, rn as ensureAssetStorage, rr as NestedStackChildDirectDestroyError, rt as disableInstanceApiTermination, s as planRollback, sn as validateAssetBucketName, sr as ResourceUpdateNotSupportedError, st as getAccountInfo, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as AssetModeResolver, tt as CloudControlProvider, u as replayRollback, un as buildDockerImage, ut as normalizeAwsTagsToCfn, v as computeImplicitDeleteEdges, vn as synthesisStatusMessage, vr as isThrottlingError, vt as requireConfigArray, w as isFinalSnapshotError, wn as resolveSkipPrefix, wt as createSecretMasker, x as buildFinalSnapshotIdentifier, xn as resolveApp, xt as STATE_SOURCED_CROSS_GENERATION_RULES, y as ATOMIC_FINAL_SNAPSHOT_TYPES, yn as getDefaultStateBucketName, yr as markNonRetryable, yt as requireConfigObject, z as collectDeclaredOutputNames, zn as AssemblyReader, zt as withRetry } from "./deploy-engine-
|
|
2
|
+
import { $ as isInterruptedWaitError, $n as LocalMigrateError, $t as escapeRegExp, A as isStatefulRecreateTargetSync, An as CFN_TEMPLATE_BODY_LIMIT, At as s3BucketArn, B as collectPublishedOutputNames, Bn as processStackMessages, Bt as DagBuilder, C as createPreDeleteFinalSnapshot, Cn as resolveCaptureObservedState, Ct as TEMPLATE_SOURCED_RULES, D as makeCanonicalizePropertiesFn, Dn as resolveUseCdkBootstrapAssets, Dt as maskSecretsInText, E as unsupportedFinalSnapshotError, En as resolveStateBucketWithDefaultAndSource, Et as isSingleDynamicReferenceToken, F as gray, Fn as expectedOwnerParam, Ft as applyRoleArnIfSet, G as IAMRoleProvider, Gn as resetAwsClients, Gt as shouldRetainResource, H as isExportAliasCollision, Hn as resolveBucketRegion, Ht as LockManager, I as green, In as PARTITION_TABLE, It as DiffCalculator, J as ProviderRegistry, Jn as CdkdError, Jt as WorkGraph, K as collectInlinePolicyNamesManagedBySiblings, Kn as setAwsClients, Kt as AssetPublisher, L as red, Ln as canonicalizeRegion, Lt as INTRINSIC_KEYS, M as formatResourceLine, Mn as MIGRATE_TMP_PREFIX, Mt as s3BucketDualStackDomainName, N as bold, Nn as findLargeInlineResources, Nt as s3BucketRegionalDomainName, O as extractDeploymentEventError, On as stateBucketExistenceConfirmed, Ot as redactSecretsForState, P as cyan, Pn as uploadCfnTemplate, Pt as s3BucketWebsiteUrl, Q as endCommandInterruptScope, Qn as LocalInvokeBuildError$1, Qt as rewriteTemplateAssetReferences, R as yellow, Rn as derivePartitionAndUrlSuffix, Rt as describeTypeWithThrottleRetry, S as ccRoutedFinalSnapshotError, Sn as resolveAutoAssetStorage, St as STATE_SOURCED_READBACK_RULES, T as refusesFinalSnapshot, Tn as resolveStateBucketWithDefault, Tt as dynamicReferenceTokens, U as secretBearingStateKeyWarning, Un as AwsClients, Ut as S3StateBackend, V as exportAliasCollisionScrubWarning, Vt as TemplateParser, W as stateKeySecretExposure, Wn as getAwsClients, Wt as rebuildClientForBucketRegion, X as findSilentDropProperties, Xt as createAssetRedirectResolver, Y as findActionableSilentDrops, Yt as buildAssetRedirectMap, Z as beginCommandInterruptScope, Zn as DeployCancelledError, Zt as loadPublishableAssetManifest, _ as IMPLICIT_DELETE_DEPENDENCIES, _n as Synthesizer, _r as isRetryableTransientError, _t as replayWarn, a as DeploymentEventsStore, an as parseBootstrapMarker, ar as ProvisioningError, at as IntrinsicFunctionResolver, b as PRE_DELETE_SNAPSHOT_TYPES, bn as getLegacyStateBucketName, bt as requireConfigString, c as producerRegionsFromState, cn as validateContainerRepoName, cr as StackHasActiveImportsError, ct as refStateLookupFromResource, d as updatePartialMessage, dn as formatDockerLoginError, dt as resolveExplicitPhysicalId, en as stripControlChars, er as LocalStartServiceError, et as startInterruptWatch, f as updatePartialReason, fn as getDockerCmd, ft as assertRegionMatch, g as maskingRetryLogger, gn as getDockerImageBySourceHash, gr as isMarkedNonRetryable, gt as readConfigString, h as withResourceDeadline, hn as AssetManifestLoader, hr as withErrorHandling, ht as configStringRefusal, i as DeploymentEventsReader, in as getBootstrapMarkerKey, ir as PartialFailureError, it as isTerminationProtectionPropagationError, j as renderStatefulReason, jn as CFN_TEMPLATE_URL_LIMIT, jt as s3BucketDomainName, k as MULTI_REGION_RECREATE_BLOCKED_TYPES, kn as warnDeprecatedNoPrefixCliFlag, kt as scrubResourceRecord, l as replayFailedOperations, ln as buildDenyExternalAccessPolicy, lr as StackTerminationProtectionError, lt as WAFv2WebACLProvider, m as deleteSkipReason, mn as runDockerStreaming, mr as normalizeAwsError, mt as configBooleanRefusal, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as BOOTSTRAP_MARKER_PREFIX, nr as MissingCdkCliError, nt as slowCcOperationTimeoutMs, o as planFailedOps, on as readBootstrapMarkerBody, or as ResourceTimeoutError, ot as cfnRefValueFromPhysicalId, p as UNSPECIFIED_SKIP_REASON, pn as runDockerForeground, pt as coerceCfnBoolean, q as clearOnUpdateRemoval, qt as stringifyValue, r as DeployEngine, rn as ensureAssetStorage, rr as NestedStackChildDirectDestroyError, rt as disableInstanceApiTermination, s as planRollback, sn as validateAssetBucketName, sr as ResourceUpdateNotSupportedError, st as getAccountInfo, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as AssetModeResolver, tt as CloudControlProvider, u as replayRollback, un as buildDockerImage, ut as normalizeAwsTagsToCfn, v as computeImplicitDeleteEdges, vn as synthesisStatusMessage, vr as isThrottlingError, vt as requireConfigArray, w as isFinalSnapshotError, wn as resolveSkipPrefix, wt as createSecretMasker, x as buildFinalSnapshotIdentifier, xn as resolveApp, xt as STATE_SOURCED_CROSS_GENERATION_RULES, y as ATOMIC_FINAL_SNAPSHOT_TYPES, yn as getDefaultStateBucketName, yr as markNonRetryable, yt as requireConfigObject, z as collectDeclaredOutputNames, zn as AssemblyReader, zt as withRetry } from "./deploy-engine-DNCs229s.js";
|
|
3
3
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as getCurrentStackName, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-CS5j-5z6.js";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
7
|
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, 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";
|
|
@@ -865,6 +865,165 @@ function namedCliRegion(optionRegion) {
|
|
|
865
865
|
function rawCliRegion(optionRegion) {
|
|
866
866
|
return optionRegion || process.env["AWS_REGION"] || void 0;
|
|
867
867
|
}
|
|
868
|
+
/**
|
|
869
|
+
* The region a command OPERATES on.
|
|
870
|
+
*
|
|
871
|
+
* Order: `--region` -> `AWS_REGION` -> `AWS_DEFAULT_REGION` -> the region the
|
|
872
|
+
* AWS SDK's own chain resolves (i.e. the selected profile's `region =` line)
|
|
873
|
+
* -> `us-east-1`.
|
|
874
|
+
*
|
|
875
|
+
* The profile step is what issue
|
|
876
|
+
* [#2029](https://github.com/go-to-k/cdkd/issues/2029) adds, and it removes an
|
|
877
|
+
* incoherence rather than adding a preference. cdkd ALREADY consulted the
|
|
878
|
+
* profile: every command builds its pre-flight bag as
|
|
879
|
+
* `new AwsClients({ ...(options.region && { region }) })`, so with no flag the
|
|
880
|
+
* bag is region-less and the SDK resolves the profile. Only the region VALUE -
|
|
881
|
+
* the one that keys the state file, keys the bootstrap marker and answers
|
|
882
|
+
* `AWS::Region` in every user template - fell back to the literal. Measured on
|
|
883
|
+
* an env-agnostic stack with `region = ap-northeast-1` in the profile and no
|
|
884
|
+
* flag or env var:
|
|
885
|
+
*
|
|
886
|
+
* ```text
|
|
887
|
+
* State bucket '...' is in 'us-east-1' (client was 'ap-northeast-1'); rebuilding S3 client.
|
|
888
|
+
* Getting state for stack: CdkdBasicExample (us-east-1)
|
|
889
|
+
* Resolved Ref to pseudo parameter: AWS::Region -> us-east-1
|
|
890
|
+
* ```
|
|
891
|
+
*
|
|
892
|
+
* One command, two regions: the pre-flight talked to the profile's region
|
|
893
|
+
* while the resources, their ARNs and their state landed in us-east-1. Only an
|
|
894
|
+
* ENV-AGNOSTIC stack is affected - a stack with `env: { region }` pinned in CDK
|
|
895
|
+
* carries its own region through the Cloud Assembly and never reaches this
|
|
896
|
+
* fallback (`assembly-reader.ts` maps CDK's `unknown-region` to `undefined`).
|
|
897
|
+
*
|
|
898
|
+
* `AWS_DEFAULT_REGION` sits between `AWS_REGION` and the profile because the
|
|
899
|
+
* AWS CLI honours it and the JS SDK does NOT (measured: with only that variable
|
|
900
|
+
* set, `STSClient({}).config.region()` returns the PROFILE's region, not the
|
|
901
|
+
* variable's). Reading it here is what stops cdkd disagreeing with the CLI a
|
|
902
|
+
* user just ran.
|
|
903
|
+
*
|
|
904
|
+
* Returning the SOURCE, not just the region, is what lets a caller tell "the
|
|
905
|
+
* user asked for this region" from "we inferred it" - which is the difference
|
|
906
|
+
* that decides whether the reconciliation in
|
|
907
|
+
* {@link reconcileRegionWithLegacyDefault} may move the answer back.
|
|
908
|
+
*/
|
|
909
|
+
async function resolveEffectiveRegion(options) {
|
|
910
|
+
const flag = canonicalizeRegion(options.region);
|
|
911
|
+
if (flag) return {
|
|
912
|
+
region: flag,
|
|
913
|
+
source: "flag"
|
|
914
|
+
};
|
|
915
|
+
const awsRegion = canonicalizeRegion(process.env["AWS_REGION"]);
|
|
916
|
+
if (awsRegion) return {
|
|
917
|
+
region: awsRegion,
|
|
918
|
+
source: "env"
|
|
919
|
+
};
|
|
920
|
+
const defaultRegionEnv = canonicalizeRegion(process.env["AWS_DEFAULT_REGION"]);
|
|
921
|
+
if (defaultRegionEnv) return {
|
|
922
|
+
region: defaultRegionEnv,
|
|
923
|
+
source: "default-env"
|
|
924
|
+
};
|
|
925
|
+
const fromProfile = canonicalizeRegion(await resolveSdkDefaultRegion(options.profile));
|
|
926
|
+
if (fromProfile) return {
|
|
927
|
+
region: fromProfile,
|
|
928
|
+
source: "profile"
|
|
929
|
+
};
|
|
930
|
+
return {
|
|
931
|
+
region: LEGACY_DEFAULT_REGION,
|
|
932
|
+
source: "default"
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* The region cdkd used to fall back to before issue #2029, and still falls
|
|
937
|
+
* back to when nothing at all answers.
|
|
938
|
+
*
|
|
939
|
+
* Named rather than inlined because the reconciliation below has to ask
|
|
940
|
+
* "is there state under the OLD default?", and that question only means
|
|
941
|
+
* something while the two are the same constant.
|
|
942
|
+
*/
|
|
943
|
+
const LEGACY_DEFAULT_REGION = "us-east-1";
|
|
944
|
+
/**
|
|
945
|
+
* Ask the AWS SDK's own chain which region it would use.
|
|
946
|
+
*
|
|
947
|
+
* A throwaway client, sampled once and destroyed: `src/utils/aws-clients.ts`
|
|
948
|
+
* is explicit that a region-less bag's lazy members resolve independently and
|
|
949
|
+
* need not agree with each other, so nothing here is reused for real work.
|
|
950
|
+
* Returns `undefined` rather than throwing when the chain answers nothing -
|
|
951
|
+
* a client with no resolvable region REJECTS, and that rejection is the normal
|
|
952
|
+
* "no region configured" signal rather than an error worth surfacing.
|
|
953
|
+
*/
|
|
954
|
+
async function resolveSdkDefaultRegion(profile) {
|
|
955
|
+
const { STSClient } = await import("@aws-sdk/client-sts");
|
|
956
|
+
let client;
|
|
957
|
+
try {
|
|
958
|
+
client = new STSClient({ ...profile && { profile } });
|
|
959
|
+
return await client.config.region() || void 0;
|
|
960
|
+
} catch {
|
|
961
|
+
return;
|
|
962
|
+
} finally {
|
|
963
|
+
client?.destroy?.();
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* The marker-key twin of {@link reconcileRegionWithLegacyDefault}.
|
|
968
|
+
*
|
|
969
|
+
* `cdkd bootstrap` WRITES `cdkd-bootstrap/{region}.json`; `cdkd gc` and
|
|
970
|
+
* `cdkd bootstrap --destroy` READ it. Issue
|
|
971
|
+
* [#2029](https://github.com/go-to-k/cdkd/issues/2029) moves what `{region}`
|
|
972
|
+
* resolves to when the user names none, and a previous attempt at it moved the
|
|
973
|
+
* READ side alone — which silently broke that pairing: for a user with a
|
|
974
|
+
* non-us-east-1 profile, `cdkd gc` reported "not opted in" and the teardown
|
|
975
|
+
* "nothing to delete" while the asset bucket and ECR repo stayed alive and
|
|
976
|
+
* billing. So all three commands resolve through THIS function, and the pairing
|
|
977
|
+
* holds by construction rather than by three call sites agreeing.
|
|
978
|
+
*
|
|
979
|
+
* The reconciliation itself is the same rule as the state-key one: an inferred
|
|
980
|
+
* region yields to an existing marker under the old default, a named region
|
|
981
|
+
* never does, and a first bootstrap goes to the profile's region because there
|
|
982
|
+
* is nothing to strand.
|
|
983
|
+
*
|
|
984
|
+
* Note this is deliberately NOT `readBootstrapMarkerBody`: that helper answers
|
|
985
|
+
* "read the marker for THIS region, trying both spellings", which is a
|
|
986
|
+
* different question and would conflate a case difference with a region
|
|
987
|
+
* difference. Here both probes use the canonical key, because the question is
|
|
988
|
+
* only which REGION owns a marker.
|
|
989
|
+
*/
|
|
990
|
+
async function reconcileMarkerRegionWithLegacyDefault(input) {
|
|
991
|
+
const { effective, probe, markerKeyFor, logger } = input;
|
|
992
|
+
if (!regionNeedsReconciliation(effective)) return effective.region;
|
|
993
|
+
const markerExists = async (region) => {
|
|
994
|
+
try {
|
|
995
|
+
return await probe.getRawObject(markerKeyFor(region)) !== null;
|
|
996
|
+
} catch (error) {
|
|
997
|
+
if (error.name !== "NoSuchBucket") throw error;
|
|
998
|
+
logger.debug(`[region] no state bucket yet, so no bootstrap marker for ${region} (first bootstrap).`);
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
if (await markerExists(effective.region)) {
|
|
1003
|
+
logger.debug(`[region] asset storage exists in ${effective.region} (from your AWS profile); using it.`);
|
|
1004
|
+
return effective.region;
|
|
1005
|
+
}
|
|
1006
|
+
if (!await markerExists("us-east-1")) return effective.region;
|
|
1007
|
+
logger.info(`cdkd asset storage exists in ${LEGACY_DEFAULT_REGION}, but your AWS profile resolves ${effective.region}. Continuing to use ${LEGACY_DEFAULT_REGION} so the existing storage is not orphaned. Pass '--region ${effective.region}' to target your profile's region, or '--region ${LEGACY_DEFAULT_REGION}' to silence this message.`);
|
|
1008
|
+
return LEGACY_DEFAULT_REGION;
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Whether {@link resolveEffectiveRegion}'s answer is subject to the
|
|
1012
|
+
* reconciliation — i.e. whether cdkd INFERRED it rather than being told.
|
|
1013
|
+
*
|
|
1014
|
+
* `flag` and `env` (`AWS_REGION`) are the user speaking, and are obeyed as
|
|
1015
|
+
* given. `default-env` (`AWS_DEFAULT_REGION`) is NOT: cdkd never read that
|
|
1016
|
+
* variable before, so acting on it is a new inference. `default` is already
|
|
1017
|
+
* the legacy region, so there is nothing to reconcile against.
|
|
1018
|
+
*
|
|
1019
|
+
* Exported so a caller can skip CONSTRUCTING a probe client it will not use —
|
|
1020
|
+
* the reconciliation functions return early on the same condition, but by then
|
|
1021
|
+
* the caller has already paid for an S3 client and a state backend.
|
|
1022
|
+
*/
|
|
1023
|
+
function regionNeedsReconciliation(effective) {
|
|
1024
|
+
if (effective.source === "flag" || effective.source === "env") return false;
|
|
1025
|
+
return effective.region !== LEGACY_DEFAULT_REGION;
|
|
1026
|
+
}
|
|
868
1027
|
|
|
869
1028
|
//#endregion
|
|
870
1029
|
//#region src/cli/commands/state-file-keys.ts
|
|
@@ -1159,15 +1318,43 @@ async function bootstrapDestroyCommand(options) {
|
|
|
1159
1318
|
roleArn: options.roleArn,
|
|
1160
1319
|
region: namedCliRegion(options.region)
|
|
1161
1320
|
});
|
|
1162
|
-
const
|
|
1321
|
+
const effective = await resolveEffectiveRegion(options);
|
|
1322
|
+
const accountClients = new AwsClients({
|
|
1323
|
+
region: effective.region,
|
|
1324
|
+
...options.profile && { profile: options.profile }
|
|
1325
|
+
});
|
|
1326
|
+
const accountId = (await accountClients.sts.send(new GetCallerIdentityCommand({}))).Account;
|
|
1327
|
+
const bucketName = options.stateBucket ?? getDefaultStateBucketName(accountId);
|
|
1328
|
+
let region = effective.region;
|
|
1329
|
+
if (regionNeedsReconciliation(effective)) {
|
|
1330
|
+
const probeBackend = new S3StateBackend(new S3Client({
|
|
1331
|
+
region: effective.region,
|
|
1332
|
+
...options.profile && { profile: options.profile }
|
|
1333
|
+
}), {
|
|
1334
|
+
bucket: bucketName,
|
|
1335
|
+
prefix: STATE_PREFIX
|
|
1336
|
+
}, {
|
|
1337
|
+
region: effective.region,
|
|
1338
|
+
...options.profile && { profile: options.profile }
|
|
1339
|
+
});
|
|
1340
|
+
try {
|
|
1341
|
+
region = await reconcileMarkerRegionWithLegacyDefault({
|
|
1342
|
+
effective,
|
|
1343
|
+
probe: probeBackend,
|
|
1344
|
+
markerKeyFor: getBootstrapMarkerKey,
|
|
1345
|
+
logger
|
|
1346
|
+
});
|
|
1347
|
+
} finally {
|
|
1348
|
+
probeBackend.destroyClient();
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1163
1351
|
const rawRegion = rawCliRegion(options.region) ?? region;
|
|
1164
|
-
const awsClients = new AwsClients({
|
|
1352
|
+
const awsClients = region === effective.region ? accountClients : new AwsClients({
|
|
1165
1353
|
region,
|
|
1166
1354
|
...options.profile && { profile: options.profile }
|
|
1167
1355
|
});
|
|
1356
|
+
if (awsClients !== accountClients) accountClients.destroy();
|
|
1168
1357
|
setAwsClients(awsClients);
|
|
1169
|
-
const accountId = (await awsClients.sts.send(new GetCallerIdentityCommand({}))).Account;
|
|
1170
|
-
const bucketName = options.stateBucket ?? getDefaultStateBucketName(accountId);
|
|
1171
1358
|
const markerS3Client = new S3Client({
|
|
1172
1359
|
region,
|
|
1173
1360
|
...options.profile && { profile: options.profile }
|
|
@@ -1291,19 +1478,19 @@ async function bootstrapCommand(options) {
|
|
|
1291
1478
|
if (options.verbose) logger.setLevel("debug");
|
|
1292
1479
|
logger.info("Starting cdkd bootstrap...");
|
|
1293
1480
|
logger.debug("Options:", options);
|
|
1294
|
-
const rawRegion = rawCliRegion(options.region)
|
|
1481
|
+
const rawRegion = rawCliRegion(options.region);
|
|
1295
1482
|
foldRegionOption(options);
|
|
1296
1483
|
await applyRoleArnIfSet({
|
|
1297
1484
|
roleArn: options.roleArn,
|
|
1298
1485
|
region: options.region
|
|
1299
1486
|
});
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1487
|
+
const effective = await resolveEffectiveRegion(options);
|
|
1488
|
+
let awsClients = new AwsClients({
|
|
1489
|
+
region: effective.region,
|
|
1302
1490
|
...options.profile && { profile: options.profile }
|
|
1303
1491
|
});
|
|
1304
1492
|
setAwsClients(awsClients);
|
|
1305
|
-
|
|
1306
|
-
const region = namedCliRegion(options.region) ?? "us-east-1";
|
|
1493
|
+
let s3Client = awsClients.s3;
|
|
1307
1494
|
let bucketName;
|
|
1308
1495
|
let accountId;
|
|
1309
1496
|
if (options.stateBucket) {
|
|
@@ -1315,6 +1502,39 @@ async function bootstrapCommand(options) {
|
|
|
1315
1502
|
bucketName = getDefaultStateBucketName(accountId);
|
|
1316
1503
|
logger.info(`Using default state bucket: ${bucketName}`);
|
|
1317
1504
|
}
|
|
1505
|
+
let region = effective.region;
|
|
1506
|
+
if (regionNeedsReconciliation(effective)) {
|
|
1507
|
+
const probeBackend = new S3StateBackend(new S3Client({
|
|
1508
|
+
region: effective.region,
|
|
1509
|
+
...options.profile && { profile: options.profile }
|
|
1510
|
+
}), {
|
|
1511
|
+
bucket: bucketName,
|
|
1512
|
+
prefix: "cdkd"
|
|
1513
|
+
}, {
|
|
1514
|
+
region: effective.region,
|
|
1515
|
+
...options.profile && { profile: options.profile }
|
|
1516
|
+
});
|
|
1517
|
+
try {
|
|
1518
|
+
region = await reconcileMarkerRegionWithLegacyDefault({
|
|
1519
|
+
effective,
|
|
1520
|
+
probe: probeBackend,
|
|
1521
|
+
markerKeyFor: getBootstrapMarkerKey,
|
|
1522
|
+
logger
|
|
1523
|
+
});
|
|
1524
|
+
} finally {
|
|
1525
|
+
probeBackend.destroyClient();
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
if (region !== effective.region) {
|
|
1529
|
+
const held = new AwsClients({
|
|
1530
|
+
region,
|
|
1531
|
+
...options.profile && { profile: options.profile }
|
|
1532
|
+
});
|
|
1533
|
+
awsClients.destroy();
|
|
1534
|
+
awsClients = held;
|
|
1535
|
+
setAwsClients(awsClients);
|
|
1536
|
+
s3Client = awsClients.s3;
|
|
1537
|
+
}
|
|
1318
1538
|
const rebuiltStateBucketClient = await rebuildClientForBucketRegion(s3Client, bucketName, { ...options.profile && { profile: options.profile } });
|
|
1319
1539
|
const stateBucketS3 = rebuiltStateBucketClient ?? s3Client;
|
|
1320
1540
|
try {
|
|
@@ -1401,7 +1621,7 @@ async function bootstrapCommand(options) {
|
|
|
1401
1621
|
ecrClient,
|
|
1402
1622
|
stateBackend,
|
|
1403
1623
|
accountId,
|
|
1404
|
-
region: rawRegion,
|
|
1624
|
+
region: rawRegion ?? region,
|
|
1405
1625
|
force: options.force,
|
|
1406
1626
|
...options.assetBucket && { assetBucketName: options.assetBucket },
|
|
1407
1627
|
...options.containerRepo && { containerRepoName: options.containerRepo }
|
|
@@ -72155,26 +72375,37 @@ async function gcCommand(options) {
|
|
|
72155
72375
|
roleArn: options.roleArn,
|
|
72156
72376
|
region: namedCliRegion(options.region)
|
|
72157
72377
|
});
|
|
72158
|
-
const
|
|
72159
|
-
const
|
|
72160
|
-
|
|
72161
|
-
region,
|
|
72378
|
+
const effective = await resolveEffectiveRegion(options);
|
|
72379
|
+
const accountClients = new AwsClients({
|
|
72380
|
+
region: effective.region,
|
|
72162
72381
|
...options.profile && { profile: options.profile }
|
|
72163
72382
|
});
|
|
72164
|
-
|
|
72165
|
-
const accountId = (await awsClients.sts.send(new GetCallerIdentityCommand({}))).Account;
|
|
72383
|
+
const accountId = (await accountClients.sts.send(new GetCallerIdentityCommand({}))).Account;
|
|
72166
72384
|
const bucketName = options.stateBucket ?? getDefaultStateBucketName(accountId);
|
|
72167
72385
|
const markerS3Client = new S3Client({
|
|
72168
|
-
region,
|
|
72386
|
+
region: effective.region,
|
|
72169
72387
|
...options.profile && { profile: options.profile }
|
|
72170
72388
|
});
|
|
72171
72389
|
const stateBackend = new S3StateBackend(markerS3Client, {
|
|
72172
72390
|
bucket: bucketName,
|
|
72173
72391
|
prefix: "cdkd"
|
|
72174
72392
|
}, {
|
|
72393
|
+
region: effective.region,
|
|
72394
|
+
...options.profile && { profile: options.profile }
|
|
72395
|
+
});
|
|
72396
|
+
const region = regionNeedsReconciliation(effective) ? await reconcileMarkerRegionWithLegacyDefault({
|
|
72397
|
+
effective,
|
|
72398
|
+
probe: stateBackend,
|
|
72399
|
+
markerKeyFor: getBootstrapMarkerKey,
|
|
72400
|
+
logger
|
|
72401
|
+
}) : effective.region;
|
|
72402
|
+
const rawRegion = rawCliRegion(options.region) ?? region;
|
|
72403
|
+
const awsClients = region === effective.region ? accountClients : new AwsClients({
|
|
72175
72404
|
region,
|
|
72176
72405
|
...options.profile && { profile: options.profile }
|
|
72177
72406
|
});
|
|
72407
|
+
if (awsClients !== accountClients) accountClients.destroy();
|
|
72408
|
+
setAwsClients(awsClients);
|
|
72178
72409
|
const ecrClient = new ECRClient({
|
|
72179
72410
|
region,
|
|
72180
72411
|
...options.profile && { profile: options.profile }
|
|
@@ -72253,7 +72484,7 @@ async function gcCommand(options) {
|
|
|
72253
72484
|
* Create the `cdkd gc` command (upstream `cdk gc` parity naming).
|
|
72254
72485
|
*/
|
|
72255
72486
|
function createGcCommand() {
|
|
72256
|
-
const cmd = new Command("gc").description("Garbage-collect unreferenced objects / images from ONE region's cdkd-owned asset storage (asset bucket + container-asset ECR repo). References are collected from every cdkd state file; CDK bootstrap storage is never touched (use cdk gc for that).").option("--state-bucket <bucket>", "S3 bucket holding cdkd state (default: cdkd-state-{accountId})").addOption(new Option("--older-than <duration>", "Never delete an object / image newer than this age, even when unreferenced (protects in-flight publishes and recent rollback targets). Accepts <n>d / <n>h.").default(DEFAULT_OLDER_THAN_MS, "30d").argParser(parseOlderThan)).option("--dry-run", "Print the reclaim plan (per-item list + totals) without deleting", false).addOption(new Option("--region <region>", "Region whose cdkd asset storage to garbage-collect (defaults to AWS_REGION
|
|
72487
|
+
const cmd = new Command("gc").description("Garbage-collect unreferenced objects / images from ONE region's cdkd-owned asset storage (asset bucket + container-asset ECR repo). References are collected from every cdkd state file; CDK bootstrap storage is never touched (use cdk gc for that).").option("--state-bucket <bucket>", "S3 bucket holding cdkd state (default: cdkd-state-{accountId})").addOption(new Option("--older-than <duration>", "Never delete an object / image newer than this age, even when unreferenced (protects in-flight publishes and recent rollback targets). Accepts <n>d / <n>h.").default(DEFAULT_OLDER_THAN_MS, "30d").argParser(parseOlderThan)).option("--dry-run", "Print the reclaim plan (per-item list + totals) without deleting", false).addOption(new Option("--region <region>", "Region whose cdkd asset storage to garbage-collect (defaults to AWS_REGION, then AWS_DEFAULT_REGION, then your AWS profile's region, then us-east-1)")).action(withErrorHandling(async (options) => {
|
|
72257
72488
|
await gcCommand(options);
|
|
72258
72489
|
}));
|
|
72259
72490
|
commonOptions.forEach((opt) => cmd.addOption(opt));
|
|
@@ -84028,7 +84259,7 @@ function createMigrateCommand() {
|
|
|
84028
84259
|
*/
|
|
84029
84260
|
function buildProgram() {
|
|
84030
84261
|
const program = new Command();
|
|
84031
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.284.
|
|
84262
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.284.26");
|
|
84032
84263
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
84033
84264
|
const { profile } = actionCommand.optsWithGlobals();
|
|
84034
84265
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|