@go-to-k/cdkd 0.280.29 → 0.280.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as requireConfigObject, $t as AssemblyReader, A as green, At as runDockerForeground, B as disableInstanceApiTermination, Bt as resolveCaptureObservedState, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackTerminationProtectionError, Ct as getBootstrapMarkerKey, D as bold, Dt as buildDockerImage, E as formatResourceLine, Et as validateContainerRepoName, F as clearOnUpdateRemoval, Ft as synthesisStatusMessage, G as WAFv2WebACLProvider, Gt as stateBucketExistenceConfirmed, H as IntrinsicFunctionResolver, Ht as resolveStateBucketWithDefault, I as ProviderRegistry, It as getDefaultStateBucketName, J as assertRegionMatch, Jt as CFN_TEMPLATE_URL_LIMIT, K as normalizeAwsTagsToCfn, Kt as warnDeprecatedNoPrefixCliFlag, L as findActionableSilentDrops, Lt as getLegacyStateBucketName, M as yellow, Mt as AssetManifestLoader, N as IAMRoleProvider, Nt as getDockerImageBySourceHash, O as cyan, On as normalizeAwsError, Ot as formatDockerLoginError, P as collectInlinePolicyNamesManagedBySiblings, Pt as Synthesizer, Q as requireConfigArray, Qt as expectedOwnerParam, R as CloudControlProvider, Rt as resolveApp, S as extractDeploymentEventError, Sn as StackHasActiveImportsError, St as ensureAssetStorage, T as renderStatefulReason, Tt as validateAssetBucketName, U as cfnRefValueFromPhysicalId, Ut as resolveStateBucketWithDefaultAndSource, V as isTerminationProtectionPropagationError, Vt as resolveSkipPrefix, W as refStateLookupFromResource, Wt as resolveUseCdkBootstrapAssets, X as readConfigString, Xt as findLargeInlineResources, Y as configStringRefusal, Yt as MIGRATE_TMP_PREFIX, Z as replayWarn, Zt as uploadCfnTemplate, _ as createPreDeleteFinalSnapshot, _n as NestedStackChildDirectDestroyError, _t as createAssetRedirectResolver, a as DeploymentEventsStore, an as resetAwsClients, at as isRetryableTransientError, b as unsupportedFinalSnapshotError, bn as ResourceTimeoutError, bt as AssetModeResolver, c as replayFailedOperations, cn as CdkdError, ct as TemplateParser, d as IMPLICIT_DELETE_DEPENDENCIES, dn as DeployCancelledError, dt as rebuildClientForBucketRegion, en as processStackMessages, et as requireConfigString, f as computeImplicitDeleteEdges, fn as LocalInvokeBuildError$1, ft as shouldRetainResource, g as ccRoutedFinalSnapshotError, gn as MissingCdkCliError, gt as buildAssetRedirectMap, h as buildFinalSnapshotIdentifier, ht as WorkGraph, i as DeploymentEventsReader, in as getAwsClients, it as withRetry, j as red, jt as runDockerStreaming, k as gray, kn as withErrorHandling, kt as getDockerCmd, l as replayRollback, lt as LockManager, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalStartServiceError, mt as stringifyValue, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resolveBucketRegion, nt as DiffCalculator, o as planFailedOps, on as setAwsClients, ot as isThrottlingError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalMigrateError, pt as AssetPublisher, q as resolveExplicitPhysicalId, qt as CFN_TEMPLATE_BODY_LIMIT, r as DeployEngine, rn as AwsClients, rt as describeTypeWithThrottleRetry, s as planRollback, st as DagBuilder, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as applyRoleArnIfSet, u as withResourceDeadline, ut as S3StateBackend, v as isFinalSnapshotError, vn as PartialFailureError, vt as loadPublishableAssetManifest, w as isStatefulRecreateTargetSync, wt as parseBootstrapMarker, x as makeCanonicalizePropertiesFn, xn as ResourceUpdateNotSupportedError, xt as BOOTSTRAP_MARKER_PREFIX, y as refusesFinalSnapshot, yn as ProvisioningError, yt as rewriteTemplateAssetReferences, z as slowCcOperationTimeoutMs, zt as resolveAutoAssetStorage } from "./deploy-engine-wfKhhyCg.js";
2
+ import { $ as requireConfigObject, $t as AssemblyReader, A as green, At as runDockerForeground, B as disableInstanceApiTermination, Bt as resolveCaptureObservedState, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackTerminationProtectionError, Ct as getBootstrapMarkerKey, D as bold, Dt as buildDockerImage, E as formatResourceLine, Et as validateContainerRepoName, F as clearOnUpdateRemoval, Ft as synthesisStatusMessage, G as WAFv2WebACLProvider, Gt as stateBucketExistenceConfirmed, H as IntrinsicFunctionResolver, Ht as resolveStateBucketWithDefault, I as ProviderRegistry, It as getDefaultStateBucketName, J as assertRegionMatch, Jt as CFN_TEMPLATE_URL_LIMIT, K as normalizeAwsTagsToCfn, Kt as warnDeprecatedNoPrefixCliFlag, L as findActionableSilentDrops, Lt as getLegacyStateBucketName, M as yellow, Mt as AssetManifestLoader, N as IAMRoleProvider, Nt as getDockerImageBySourceHash, O as cyan, On as normalizeAwsError, Ot as formatDockerLoginError, P as collectInlinePolicyNamesManagedBySiblings, Pt as Synthesizer, Q as requireConfigArray, Qt as expectedOwnerParam, R as CloudControlProvider, Rt as resolveApp, S as extractDeploymentEventError, Sn as StackHasActiveImportsError, St as ensureAssetStorage, T as renderStatefulReason, Tt as validateAssetBucketName, U as cfnRefValueFromPhysicalId, Ut as resolveStateBucketWithDefaultAndSource, V as isTerminationProtectionPropagationError, Vt as resolveSkipPrefix, W as refStateLookupFromResource, Wt as resolveUseCdkBootstrapAssets, X as readConfigString, Xt as findLargeInlineResources, Y as configStringRefusal, Yt as MIGRATE_TMP_PREFIX, Z as replayWarn, Zt as uploadCfnTemplate, _ as createPreDeleteFinalSnapshot, _n as NestedStackChildDirectDestroyError, _t as createAssetRedirectResolver, a as DeploymentEventsStore, an as resetAwsClients, at as isRetryableTransientError, b as unsupportedFinalSnapshotError, bn as ResourceTimeoutError, bt as AssetModeResolver, c as replayFailedOperations, cn as CdkdError, ct as TemplateParser, d as IMPLICIT_DELETE_DEPENDENCIES, dn as DeployCancelledError, dt as rebuildClientForBucketRegion, en as processStackMessages, et as requireConfigString, f as computeImplicitDeleteEdges, fn as LocalInvokeBuildError$1, ft as shouldRetainResource, g as ccRoutedFinalSnapshotError, gn as MissingCdkCliError, gt as buildAssetRedirectMap, h as buildFinalSnapshotIdentifier, ht as WorkGraph, i as DeploymentEventsReader, in as getAwsClients, it as withRetry, j as red, jt as runDockerStreaming, k as gray, kn as withErrorHandling, kt as getDockerCmd, l as replayRollback, lt as LockManager, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalStartServiceError, mt as stringifyValue, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resolveBucketRegion, nt as DiffCalculator, o as planFailedOps, on as setAwsClients, ot as isThrottlingError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalMigrateError, pt as AssetPublisher, q as resolveExplicitPhysicalId, qt as CFN_TEMPLATE_BODY_LIMIT, r as DeployEngine, rn as AwsClients, rt as describeTypeWithThrottleRetry, s as planRollback, st as DagBuilder, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as applyRoleArnIfSet, u as withResourceDeadline, ut as S3StateBackend, v as isFinalSnapshotError, vn as PartialFailureError, vt as loadPublishableAssetManifest, w as isStatefulRecreateTargetSync, wt as parseBootstrapMarker, x as makeCanonicalizePropertiesFn, xn as ResourceUpdateNotSupportedError, xt as BOOTSTRAP_MARKER_PREFIX, y as refusesFinalSnapshot, yn as ProvisioningError, yt as rewriteTemplateAssetReferences, z as slowCcOperationTimeoutMs, zt as resolveAutoAssetStorage } from "./deploy-engine-POCXyXPl.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BYMEE-BS.js";
4
- import { t as ASGProvider } from "./asg-provider-CcomwF89.js";
4
+ import { t as ASGProvider } from "./asg-provider-DZ05yRbJ.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";
@@ -17989,6 +17989,67 @@ function narrowRouteDestinations(properties) {
17989
17989
  narrowed
17990
17990
  };
17991
17991
  }
17992
+ /** The `AuthorizeSecurityGroupIngress` default protocol: "all protocols". */
17993
+ const SG_INGRESS_IP_PROTOCOL_DEFAULT = "-1";
17994
+ /** The refusal path both the create guard and the canonicalizer report under. */
17995
+ const SG_INGRESS_IP_PROTOCOL_PATH = "AWS::EC2::SecurityGroupIngress IpProtocol";
17996
+ /**
17997
+ * Resolve the `IpProtocol` an `AWS::EC2::SecurityGroupIngress` rule actually
17998
+ * SENDS, plus the bag that describes it (issue #1633).
17999
+ *
18000
+ * ONE source for a decision three call sites have to agree on, exactly as
18001
+ * `narrowRouteDestinations` is for the Route destinations: the create arm
18002
+ * (which authorizes the rule), the update arm (which revokes then re-creates
18003
+ * it), and the DIFF-side canonicalizer. If those disagreed, state and template
18004
+ * would each be normalized to a different protocol and the fix would become
18005
+ * the bug — the lesson `.claude/rules/providers.md` records from #1591.
18006
+ *
18007
+ * Two shapes reach the wire as something other than what the template wrote,
18008
+ * and BOTH have to be recorded or they become permanent phantom drift, because
18009
+ * `readSecurityGroupIngressCurrentState` can only ever return what AWS holds:
18010
+ *
18011
+ * - a MALFORMED value (`''` / `{}` / `true` / an explicit `null`), which
18012
+ * `requireConfigString` refuses on the template-path create and — under
18013
+ * `onUnusable` — warn-substitutes the default on the replay-reachable paths;
18014
+ * - a finite NUMBER, the accepted-by-design shape from an unquoted YAML
18015
+ * `IpProtocol: -1` (issue #1513), which is stringified before it is sent.
18016
+ *
18017
+ * The second is not announced by a warning, and does not need to be: unlike a
18018
+ * dropped destination key it loses NOTHING — `-1` and `'-1'` name the same
18019
+ * protocol — so there is no silent loss for `effectiveProperties` to launder
18020
+ * into a clean record, which is the hazard the "already ANNOUNCED" clause of
18021
+ * the `effectiveProperties` contract exists to guard against. Recording the
18022
+ * string additionally fixes the delete path, which forwards the state record
18023
+ * to `buildIpPermission` and would otherwise hand the EC2 API a number.
18024
+ *
18025
+ * `narrowed` is a FRESH object only when the sent value differs from the
18026
+ * declared one, so an ordinary `IpProtocol: 'tcp'` bag is returned untouched
18027
+ * and compares byte-for-byte as before.
18028
+ *
18029
+ * @param onUnusable Passed straight through to `requireConfigString`: absent,
18030
+ * a malformed value THROWS (the template-path create, where the user can fix
18031
+ * the template); supplied, it warns and takes the default. The canonicalizer
18032
+ * passes a no-op — a diff must never throw, and it must never warn either,
18033
+ * since the provisioning path already announces the same substitution.
18034
+ */
18035
+ function narrowIngressIpProtocol(properties, onUnusable) {
18036
+ const declared = properties["IpProtocol"];
18037
+ const ipProtocol = requireConfigString(declared, SG_INGRESS_IP_PROTOCOL_DEFAULT, SG_INGRESS_IP_PROTOCOL_PATH, {
18038
+ coerceNumber: true,
18039
+ ...onUnusable && { onUnusable }
18040
+ });
18041
+ if (declared === void 0 || declared === ipProtocol) return {
18042
+ ipProtocol,
18043
+ narrowed: properties
18044
+ };
18045
+ return {
18046
+ ipProtocol,
18047
+ narrowed: {
18048
+ ...properties,
18049
+ IpProtocol: ipProtocol
18050
+ }
18051
+ };
18052
+ }
17992
18053
  /**
17993
18054
  * AWS EC2 Networking Provider
17994
18055
  *
@@ -19170,10 +19231,8 @@ var EC2Provider = class {
19170
19231
  this.logger.debug(`Creating SecurityGroupIngress ${logicalId}`);
19171
19232
  const groupId = properties["GroupId"];
19172
19233
  if (!groupId) throw new ProvisioningError(`GroupId is required for SecurityGroupIngress ${logicalId}`, resourceType, logicalId);
19173
- const ipProtocol = requireConfigString(properties["IpProtocol"], "-1", "AWS::EC2::SecurityGroupIngress IpProtocol", {
19174
- coerceNumber: true,
19175
- ...onUnusableProtocol && { onUnusable: onUnusableProtocol }
19176
- });
19234
+ const { ipProtocol, narrowed } = narrowIngressIpProtocol(properties, onUnusableProtocol);
19235
+ const effectiveProperties = narrowed === properties ? void 0 : narrowed;
19177
19236
  const fromPort = properties["FromPort"];
19178
19237
  const toPort = properties["ToPort"];
19179
19238
  try {
@@ -19188,7 +19247,8 @@ var EC2Provider = class {
19188
19247
  this.logger.debug(`Successfully created SecurityGroupIngress ${logicalId}: ${physicalId}`);
19189
19248
  return {
19190
19249
  physicalId,
19191
- attributes: {}
19250
+ attributes: {},
19251
+ ...effectiveProperties && { effectiveProperties }
19192
19252
  };
19193
19253
  } catch (error) {
19194
19254
  if (error instanceof Error && error.message.includes("already exists")) {
@@ -19196,7 +19256,8 @@ var EC2Provider = class {
19196
19256
  this.logger.debug(`SecurityGroupIngress ${logicalId} already exists, treating as success`);
19197
19257
  return {
19198
19258
  physicalId,
19199
- attributes: {}
19259
+ attributes: {},
19260
+ ...effectiveProperties && { effectiveProperties }
19200
19261
  };
19201
19262
  }
19202
19263
  const cause = error instanceof Error ? error : void 0;
@@ -19215,7 +19276,8 @@ var EC2Provider = class {
19215
19276
  return {
19216
19277
  physicalId: createResult.physicalId,
19217
19278
  wasReplaced: true,
19218
- ...createResult.attributes && { attributes: createResult.attributes }
19279
+ ...createResult.attributes && { attributes: createResult.attributes },
19280
+ ...createResult.effectiveProperties && { effectiveProperties: createResult.effectiveProperties }
19219
19281
  };
19220
19282
  } catch (error) {
19221
19283
  if (error instanceof CdkdError) throw error;
@@ -20293,7 +20355,9 @@ var EC2Provider = class {
20293
20355
  }
20294
20356
  }
20295
20357
  /**
20296
- * The diff-side half of the Route multi-destination narrowing (issue #1591).
20358
+ * The diff-side half of the two EC2 narrowings that report
20359
+ * `effectiveProperties` — Route multi-destination (issue #1591) and
20360
+ * SecurityGroupIngress `IpProtocol` (issue #1633).
20297
20361
  *
20298
20362
  * `createRoute` sends exactly one destination key and reports the narrowed
20299
20363
  * bag via `effectiveProperties`, so state carries one key. Without the same
@@ -20306,8 +20370,21 @@ var EC2Provider = class {
20306
20370
  *
20307
20371
  * Shares `narrowRouteDestinations` with the provisioning path so the two
20308
20372
  * cannot disagree about which key survives.
20373
+ *
20374
+ * The SecurityGroupIngress arm is the same shape and needs the same second
20375
+ * half for the same reason: `IpProtocol` is create-only on that type in the
20376
+ * registry schema, so normalizing state alone would make the template's
20377
+ * original value read as a changed immutable property — a REPLACEMENT, whose
20378
+ * create passes no context and so gets no `onUnusable` downgrade, turning a
20379
+ * previously-green no-op deploy into a hard failure. Normalizing BOTH sides
20380
+ * is also what keeps the fix correct for records written BEFORE it existed,
20381
+ * which still carry the un-narrowed value.
20309
20382
  */
20310
20383
  canonicalizeDesiredProperties(resourceType, properties) {
20384
+ if (resourceType === "AWS::EC2::SecurityGroupIngress") {
20385
+ const { narrowed } = narrowIngressIpProtocol(properties, () => {});
20386
+ return narrowed;
20387
+ }
20311
20388
  if (resourceType !== "AWS::EC2::Route") return properties;
20312
20389
  const { declared, narrowed } = narrowRouteDestinations(properties);
20313
20390
  return declared.length > 1 ? narrowed : properties;
@@ -20789,12 +20866,33 @@ function flattenIpPermissions(perms, direction) {
20789
20866
  * Direction-sensitive: ingress uses `Source*` fields, egress uses
20790
20867
  * `Destination*`.
20791
20868
  */
20869
+ /**
20870
+ * The `IpProtocol` component of a security-group rule identity key.
20871
+ *
20872
+ * A NUMBER is stringified so a record written BEFORE issue #1633 still matches:
20873
+ * AWS always reports the protocol as a string, so a legacy record holding the
20874
+ * number `-1` keyed as `{"p":-1}` against AWS's `{"p":"-1"}` and matched
20875
+ * nothing — `readSecurityGroupIngressCurrentState` returned `undefined` and
20876
+ * `cdkd drift` reported the rule as GONE, forever. The canonicalizer makes such
20877
+ * a record's diff NO_CHANGE, so no deploy ever rewrites it either; normalizing
20878
+ * at the KEY is what heals the existing population with no migration.
20879
+ *
20880
+ * Anything that is neither a string nor a number is passed through UNCHANGED
20881
+ * rather than blanket-`String()`-ed: a malformed object would otherwise key as
20882
+ * the useless `'[object Object]'`, silently collapsing every malformed record
20883
+ * onto one bucket. Such a rule matches nothing either way — this keeps the
20884
+ * non-match honest instead of manufacturing a fake identity.
20885
+ */
20886
+ function sgProtocolKey(value) {
20887
+ if (typeof value === "number") return String(value);
20888
+ return value ?? "-1";
20889
+ }
20792
20890
  function sgRuleKey(rule, direction) {
20793
20891
  const peerKey = direction === "egress" ? rule["DestinationSecurityGroupId"] : rule["SourceSecurityGroupId"];
20794
20892
  const prefixKey = direction === "egress" ? rule["DestinationPrefixListId"] : rule["SourcePrefixListId"];
20795
20893
  const peerOwner = direction === "ingress" ? rule["SourceSecurityGroupOwnerId"] : void 0;
20796
20894
  return JSON.stringify({
20797
- p: rule["IpProtocol"] ?? "-1",
20895
+ p: sgProtocolKey(rule["IpProtocol"]),
20798
20896
  f: rule["FromPort"] ?? null,
20799
20897
  t: rule["ToPort"] ?? null,
20800
20898
  c4: rule["CidrIp"] ?? null,
@@ -70704,7 +70802,7 @@ function createMigrateCommand() {
70704
70802
  */
70705
70803
  function buildProgram() {
70706
70804
  const program = new Command();
70707
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.29");
70805
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.30");
70708
70806
  program.hook("preAction", (_thisCommand, actionCommand) => {
70709
70807
  const { profile } = actionCommand.optsWithGlobals();
70710
70808
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;