@go-to-k/cdkd 0.281.21 → 0.281.22

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/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as configStringRefusal, $t as CFN_TEMPLATE_URL_LIMIT, A as green, At as validateContainerRepoName, B as slowCcOperationTimeoutMs, Bt as synthesisStatusMessage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as PartialFailureError, Ct as rewriteTemplateAssetReferences, D as bold, Dn as StackHasActiveImportsError, Dt as getBootstrapMarkerKey, E as formatResourceLine, En as ResourceUpdateNotSupportedError, Et as ensureAssetStorage, F as clearOnUpdateRemoval, Ft as runDockerForeground, G as getAccountInfo, Gt as resolveCaptureObservedState, H as isTerminationProtectionPropagationError, Ht as getLegacyStateBucketName, I as ProviderRegistry, It as runDockerStreaming, J as normalizeAwsTagsToCfn, Jt as resolveStateBucketWithDefaultAndSource, K as refStateLookupFromResource, Kt as resolveSkipPrefix, L as findActionableSilentDrops, Lt as AssetManifestLoader, M as yellow, Mt as buildDockerImage, N as IAMRoleProvider, Nn as normalizeAwsError, Nt as formatDockerLoginError, O as cyan, On as StackTerminationProtectionError, Ot as parseBootstrapMarker, P as collectInlinePolicyNamesManagedBySiblings, Pn as withErrorHandling, Pt as getDockerCmd, Q as configBooleanRefusal, Qt as CFN_TEMPLATE_BODY_LIMIT, R as findSilentDropProperties, Rt as getDockerImageBySourceHash, S as extractDeploymentEventError, Sn as NestedStackChildDirectDestroyError, St as loadPublishableAssetManifest, T as renderStatefulReason, Tn as ResourceTimeoutError, Tt as BOOTSTRAP_MARKER_PREFIX, U as IntrinsicFunctionResolver, Ut as resolveApp, V as disableInstanceApiTermination, Vt as getDefaultStateBucketName, W as cfnRefValueFromPhysicalId, Wt as resolveAutoAssetStorage, X as assertRegionMatch, Xt as stateBucketExistenceConfirmed, Y as resolveExplicitPhysicalId, Yt as resolveUseCdkBootstrapAssets, Z as coerceCfnBoolean, Zt as warnDeprecatedNoPrefixCliFlag, _ as createPreDeleteFinalSnapshot, _n as LocalInvokeBuildError$1, _t as AssetPublisher, a as DeploymentEventsStore, an as processStackMessages, at as applyRoleArnIfSet, b as unsupportedFinalSnapshotError, bt as buildAssetRedirectMap, c as replayFailedOperations, cn as AwsClients, ct as withRetry, d as IMPLICIT_DELETE_DEPENDENCIES, dn as setAwsClients, dt as DagBuilder, en as MIGRATE_TMP_PREFIX, et as readConfigString, f as computeImplicitDeleteEdges, ft as TemplateParser, g as ccRoutedFinalSnapshotError, gn as DeployCancelledError, gt as shouldRetainResource, h as buildFinalSnapshotIdentifier, ht as rebuildClientForBucketRegion, i as DeploymentEventsReader, in as AssemblyReader, it as requireConfigString, j as red, jt as derivePartitionAndUrlSuffix, k as gray, kt as validateAssetBucketName, l as replayRollback, ln as getAwsClients, lt as isRetryableTransientError, m as PRE_DELETE_SNAPSHOT_TYPES, mt as S3StateBackend, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as uploadCfnTemplate, nt as requireConfigArray, o as planFailedOps, ot as DiffCalculator, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as CdkdError, pt as LockManager, q as WAFv2WebACLProvider, qt as resolveStateBucketWithDefault, r as DeployEngine, rn as expectedOwnerParam, rt as requireConfigObject, s as planRollback, sn as resolveBucketRegion, st as describeTypeWithThrottleRetry, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as findLargeInlineResources, tt as replayWarn, u as withResourceDeadline, un as resetAwsClients, ut as isThrottlingError, v as isFinalSnapshotError, vn as LocalMigrateError, vt as stringifyValue, w as isStatefulRecreateTargetSync, wn as ProvisioningError, wt as AssetModeResolver, x as makeCanonicalizePropertiesFn, xn as MissingCdkCliError, xt as createAssetRedirectResolver, y as refusesFinalSnapshot, yn as LocalStartServiceError, yt as WorkGraph, z as CloudControlProvider, zt as Synthesizer } from "./deploy-engine-Cx48pqGQ.js";
2
+ import { $ as configStringRefusal, $t as MIGRATE_TMP_PREFIX, A as green, At as validateContainerRepoName, B as slowCcOperationTimeoutMs, Bt as getDefaultStateBucketName, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as PartialFailureError, Ct as rewriteTemplateAssetReferences, D as bold, Dn as StackHasActiveImportsError, Dt as getBootstrapMarkerKey, E as formatResourceLine, En as ResourceUpdateNotSupportedError, Et as ensureAssetStorage, F as clearOnUpdateRemoval, Ft as runDockerStreaming, G as getAccountInfo, Gt as resolveSkipPrefix, H as isTerminationProtectionPropagationError, Ht as resolveApp, I as ProviderRegistry, It as AssetManifestLoader, J as normalizeAwsTagsToCfn, Jt as resolveUseCdkBootstrapAssets, K as refStateLookupFromResource, Kt as resolveStateBucketWithDefault, L as findActionableSilentDrops, Lt as getDockerImageBySourceHash, M as yellow, Mt as formatDockerLoginError, N as IAMRoleProvider, Nn as normalizeAwsError, Nt as getDockerCmd, O as cyan, On as StackTerminationProtectionError, Ot as parseBootstrapMarker, P as collectInlinePolicyNamesManagedBySiblings, Pn as withErrorHandling, Pt as runDockerForeground, Q as configBooleanRefusal, Qt as CFN_TEMPLATE_URL_LIMIT, R as findSilentDropProperties, Rt as Synthesizer, S as extractDeploymentEventError, Sn as NestedStackChildDirectDestroyError, St as loadPublishableAssetManifest, T as renderStatefulReason, Tn as ResourceTimeoutError, Tt as BOOTSTRAP_MARKER_PREFIX, U as IntrinsicFunctionResolver, Ut as resolveAutoAssetStorage, V as disableInstanceApiTermination, Vt as getLegacyStateBucketName, W as cfnRefValueFromPhysicalId, Wt as resolveCaptureObservedState, X as assertRegionMatch, Xt as warnDeprecatedNoPrefixCliFlag, Y as resolveExplicitPhysicalId, Yt as stateBucketExistenceConfirmed, Z as coerceCfnBoolean, Zt as CFN_TEMPLATE_BODY_LIMIT, _ as createPreDeleteFinalSnapshot, _n as LocalInvokeBuildError$1, _t as AssetPublisher, a as DeploymentEventsStore, an as processStackMessages, at as applyRoleArnIfSet, b as unsupportedFinalSnapshotError, bt as buildAssetRedirectMap, c as replayFailedOperations, cn as AwsClients, ct as withRetry, d as IMPLICIT_DELETE_DEPENDENCIES, dn as setAwsClients, dt as DagBuilder, en as findLargeInlineResources, et as readConfigString, f as computeImplicitDeleteEdges, ft as TemplateParser, g as ccRoutedFinalSnapshotError, gn as DeployCancelledError, gt as shouldRetainResource, h as buildFinalSnapshotIdentifier, ht as rebuildClientForBucketRegion, i as DeploymentEventsReader, in as AssemblyReader, it as requireConfigString, j as red, jt as buildDockerImage, k as gray, kt as validateAssetBucketName, l as replayRollback, ln as getAwsClients, lt as isRetryableTransientError, m as PRE_DELETE_SNAPSHOT_TYPES, mt as S3StateBackend, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as expectedOwnerParam, nt as requireConfigArray, o as planFailedOps, ot as DiffCalculator, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as CdkdError, pt as LockManager, q as WAFv2WebACLProvider, qt as resolveStateBucketWithDefaultAndSource, r as DeployEngine, rn as derivePartitionAndUrlSuffix, rt as requireConfigObject, s as planRollback, sn as resolveBucketRegion, st as describeTypeWithThrottleRetry, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as uploadCfnTemplate, tt as replayWarn, u as withResourceDeadline, un as resetAwsClients, ut as isThrottlingError, v as isFinalSnapshotError, vn as LocalMigrateError, vt as stringifyValue, w as isStatefulRecreateTargetSync, wn as ProvisioningError, wt as AssetModeResolver, x as makeCanonicalizePropertiesFn, xn as MissingCdkCliError, xt as createAssetRedirectResolver, y as refusesFinalSnapshot, yn as LocalStartServiceError, yt as WorkGraph, z as CloudControlProvider, zt as synthesisStatusMessage } from "./deploy-engine-DQd1PUUv.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, 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-CH0YfbOn.js";
4
+ import { t as ASGProvider } from "./asg-provider-pvAc9MXZ.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";
@@ -65827,6 +65827,61 @@ function notFoundError$1(target, stack, resources) {
65827
65827
  return new LocalInvokeResolutionError(msg.trimEnd());
65828
65828
  }
65829
65829
 
65830
+ //#endregion
65831
+ //#region src/utils/ecr-uri.ts
65832
+ /**
65833
+ * Matching the HOST half of an ECR image URI:
65834
+ * `<acct>.dkr.ecr.<region>.<urlSuffix>/`.
65835
+ *
65836
+ * The suffix is CAPTURED rather than spelled out (issue #1758): the previous
65837
+ * pattern hardcoded `amazonaws.com` with an optional `.cn` tail, so a `us-iso*`
65838
+ * registry (`c2s.ic.gov` / `sc2s.sgov.gov`) never matched and the caller
65839
+ * silently classified a real ECR image as a user-managed one — skipping the
65840
+ * `docker login` it needs.
65841
+ */
65842
+ const ECR_URI_HOST_REGEX = /^(\d{12})\.dkr\.ecr\.([^.]+)\.([^/]+)\//;
65843
+ /**
65844
+ * The account + region of an ECR image URI, or `undefined` when the URI is not
65845
+ * an ECR registry host for the region it names.
65846
+ *
65847
+ * Lives in `src/utils/` rather than beside its first caller because it has TWO
65848
+ * consumers in different layers — `src/local/ecr-puller.ts` (which needs the
65849
+ * `:tag` tail too) and `src/local/ecs-task-resolver.ts` (which classifies an
65850
+ * image that may carry a digest or no tag at all). Before issue #1758 they each
65851
+ * carried their own copy of the hardcoded commercial pattern, and fixing only
65852
+ * the pull path left `cdkd local run-task` broken outside the commercial
65853
+ * partition; ONE definition is what stops them drifting apart again.
65854
+ *
65855
+ * The module is deliberately free of AWS SDK imports, which is what lets
65856
+ * `ecs-task-resolver.ts` consume it without breaking the invariant that module
65857
+ * documents about itself (it resolves secrets through a separate module for
65858
+ * exactly that reason).
65859
+ */
65860
+ function parseEcrRegistryHost(imageUri) {
65861
+ const m = ECR_URI_HOST_REGEX.exec(imageUri);
65862
+ if (!m) return void 0;
65863
+ const region = m[2];
65864
+ if (m[3] !== derivePartitionAndUrlSuffix(region).urlSuffix) return void 0;
65865
+ return {
65866
+ accountId: m[1],
65867
+ region
65868
+ };
65869
+ }
65870
+ /**
65871
+ * True when the URI has the ECR HOST SHAPE but its suffix does not belong to
65872
+ * the region it names — i.e. exactly the case {@link parseEcrRegistryHost}
65873
+ * rejects for a reason the caller may want to report.
65874
+ *
65875
+ * The two rejections are worth telling apart at a call site that degrades
65876
+ * silently: a genuinely public image and a registry in a partition
65877
+ * `derivePartitionAndUrlSuffix` does not know yet (issue #1764) both come back
65878
+ * `undefined`, and only the second is a cdkd gap rather than a user choice.
65879
+ */
65880
+ function looksLikeEcrHostWithForeignSuffix(imageUri) {
65881
+ const m = ECR_URI_HOST_REGEX.exec(imageUri);
65882
+ return m !== null && m[3] !== derivePartitionAndUrlSuffix(m[2]).urlSuffix;
65883
+ }
65884
+
65830
65885
  //#endregion
65831
65886
  //#region src/local/ecs-task-resolver.ts
65832
65887
  function detectEcsImageResolutionNeeds(stack) {
@@ -66446,13 +66501,14 @@ function parseContainerImage(raw, containerName, taskLogicalId, resources, _stac
66446
66501
  if (substituted.includes("AWS::")) throw new EcsTaskResolutionError(`Container '${containerName}' in task '${taskLogicalId}' has an Image that references AWS pseudo parameters (${substituted}). cdkd could not resolve them: confirm AWS credentials are configured so STS GetCallerIdentity succeeds, and that --region / AWS_REGION names the target region. Workaround: build the image locally (ContainerImage.fromAsset) or pin a public image.`);
66447
66502
  throw new EcsTaskResolutionError(`Container '${containerName}' in task '${taskLogicalId}' has an Image with unresolved \${...} placeholders (${substituted}). cdkd local run-task v1 only resolves AWS pseudo parameters and same-stack AWS::ECR::Repository refs.`);
66448
66503
  }
66449
- const ecrMatch = /^(\d{12})\.dkr\.ecr\.([^.]+)\.amazonaws\.com(?:\.cn)?\//.exec(substituted);
66450
- if (ecrMatch) return {
66504
+ const ecrHost = parseEcrRegistryHost(substituted);
66505
+ if (ecrHost) return {
66451
66506
  kind: "ecr",
66452
66507
  uri: substituted,
66453
- account: ecrMatch[1],
66454
- region: ecrMatch[2]
66508
+ account: ecrHost.accountId,
66509
+ region: ecrHost.region
66455
66510
  };
66511
+ if (looksLikeEcrHostWithForeignSuffix(substituted)) getLogger().child("ecs-task-resolver").debug(`Image '${substituted}' has an ECR host shape but a URL suffix that does not belong to its region's partition; treating it as a public image (no docker login).`);
66456
66512
  return {
66457
66513
  kind: "public",
66458
66514
  uri: substituted
@@ -66489,12 +66545,12 @@ function classifyResolvedImage(uri, cdkAssetContainerRepo) {
66489
66545
  if (hashMatch) out.assetHash = hashMatch[1];
66490
66546
  return out;
66491
66547
  }
66492
- const ecrMatch = /^(\d{12})\.dkr\.ecr\.([^.]+)\.amazonaws\.com(?:\.cn)?\//.exec(uri);
66493
- if (ecrMatch) return {
66548
+ const ecrHost = parseEcrRegistryHost(uri);
66549
+ if (ecrHost) return {
66494
66550
  kind: "ecr",
66495
66551
  uri,
66496
- account: ecrMatch[1],
66497
- region: ecrMatch[2]
66552
+ account: ecrHost.accountId,
66553
+ region: ecrHost.region
66498
66554
  };
66499
66555
  return {
66500
66556
  kind: "public",
@@ -67080,50 +67136,25 @@ async function buildContainerImage$1(...args) {
67080
67136
 
67081
67137
  //#endregion
67082
67138
  //#region src/local/ecr-puller.ts
67083
- /**
67084
- * ECR pull fallback for `cdkd local invoke` / `cdkd local start-api` /
67085
- * `cdkd local run-task`. When the image URI resolves to an ECR repo but
67086
- * doesn't match any cdk.out asset (typical when invoking a stack
67087
- * deployed elsewhere or sharing a centralized registry), cdkd
67088
- * authenticates against the target registry and runs `docker pull`.
67089
- *
67090
- * **Cross-account / cross-region** (#455):
67091
- * - Same-account, same-region: fast path. No STS hop. The default
67092
- * credential chain is used directly for `ecr:GetAuthorizationToken`.
67093
- * - `ecrRoleArn` is provided: `sts:AssumeRole` is issued via the
67094
- * default credential chain to obtain temporary credentials for the
67095
- * target account. The resulting credentials authenticate the ECR
67096
- * client (regardless of region — the ECR client is built for the
67097
- * URI's region, which can differ from the caller's profile region).
67098
- * - Cross-account, NO `ecrRoleArn`: cdkd falls through to the
67099
- * default credential chain. This works when the caller has been
67100
- * granted cross-account `ecr:GetAuthorizationToken` +
67101
- * `ecr:BatchGetImage` permissions on the target repository via an
67102
- * IAM policy; otherwise AWS rejects the call with `AccessDenied`
67103
- * and the user is pointed at `--ecr-role-arn`.
67104
- *
67105
- * The `--no-pull` semantics (C3 in the design doc):
67106
- * - When NOT set: `ecrLogin` + `docker pull <uri>`.
67107
- * - When set: skip `docker pull`. If the image isn't in the local
67108
- * cache, the subsequent `docker run` will fail; we surface a clearer
67109
- * "image not in local cache" error here so the user knows to drop
67110
- * `--no-pull` or pre-pull manually.
67111
- */
67112
- /** Regex matching the `<acct>.dkr.ecr.<region>.amazonaws.com/<repo>:<tag>` shape. */
67113
- const ECR_URI_REGEX = /^(\d{12})\.dkr\.ecr\.([^.]+)\.amazonaws\.com(?:\.cn)?\/([^:]+):(.+)$/;
67139
+ /** The URL suffix an ECR registry host uses in `region`'s partition (issue #1758). */
67140
+ function ecrUrlSuffix(region) {
67141
+ return derivePartitionAndUrlSuffix(region).urlSuffix;
67142
+ }
67114
67143
  /**
67115
67144
  * Parse an ECR image URI. Returns `undefined` for non-ECR URIs (typically:
67116
67145
  * Docker Hub, public.ecr.aws, gcr.io, ...) — those are user-managed
67117
67146
  * images we don't try to authenticate against.
67118
67147
  */
67119
67148
  function parseEcrUri(imageUri) {
67120
- const m = ECR_URI_REGEX.exec(imageUri);
67149
+ const host = parseEcrRegistryHost(imageUri);
67150
+ if (!host) return void 0;
67151
+ const m = /^([^:]+):(.+)$/.exec(imageUri.slice(imageUri.indexOf("/") + 1));
67121
67152
  if (!m) return void 0;
67122
67153
  return {
67123
- accountId: m[1],
67124
- region: m[2],
67125
- repository: m[3],
67126
- tag: m[4]
67154
+ accountId: host.accountId,
67155
+ region: host.region,
67156
+ repository: m[1],
67157
+ tag: m[2]
67127
67158
  };
67128
67159
  }
67129
67160
  /**
@@ -67262,7 +67293,7 @@ async function ecrLogin(client, accountId, region) {
67262
67293
  if (!authData?.authorizationToken) throw new LocalInvokeBuildError$1("Failed to get ECR authorization token");
67263
67294
  const [username, password] = Buffer.from(authData.authorizationToken, "base64").toString().split(":");
67264
67295
  if (!username || password === void 0) throw new LocalInvokeBuildError$1("ECR authorization token has unexpected shape (missing username/password)");
67265
- const endpoint = authData.proxyEndpoint || `https://${accountId}.dkr.ecr.${region}.amazonaws.com`;
67296
+ const endpoint = authData.proxyEndpoint || `https://${accountId}.dkr.ecr.${region}.${ecrUrlSuffix(region)}`;
67266
67297
  try {
67267
67298
  await runDockerStreaming([
67268
67299
  "login",
@@ -74474,7 +74505,7 @@ function createMigrateCommand() {
74474
74505
  */
74475
74506
  function buildProgram() {
74476
74507
  const program = new Command();
74477
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.21");
74508
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.22");
74478
74509
  program.hook("preAction", (_thisCommand, actionCommand) => {
74479
74510
  const { profile } = actionCommand.optsWithGlobals();
74480
74511
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;