@go-to-k/cdkd 0.283.7 → 0.283.9
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-o7QsopaI.js → asg-provider-D5ZBSgh2.js} +2 -2
- package/dist/{asg-provider-o7QsopaI.js.map → asg-provider-D5ZBSgh2.js.map} +1 -1
- package/dist/cli.js +160 -25
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-CKpBSlde.js → deploy-engine-CWt7h7Nc.js} +816 -655
- package/dist/deploy-engine-CWt7h7Nc.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-CKpBSlde.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as coerceCfnBoolean, $t as resolveStateBucketWithDefaultAndSource, A as cyan, An as NestedStackChildDirectDestroyError, At as BOOTSTRAP_MARKER_PREFIX, B as findSilentDropProperties, Bt as runDockerForeground, C as makeCanonicalizePropertiesFn, Ct as stringifyValue, D as renderStatefulReason, Dn as LocalStartServiceError, Dt as loadPublishableAssetManifest, E as isStatefulRecreateTargetSync, En as LocalMigrateError, Et as createAssetRedirectResolver, F as IAMRoleProvider, Fn as StackHasActiveImportsError, Ft as validateContainerRepoName, G as IntrinsicFunctionResolver, Gn as isThrottlingError, Gt as synthesisStatusMessage, H as slowCcOperationTimeoutMs, Hn as withErrorHandling, Ht as AssetManifestLoader, I as collectInlinePolicyNamesManagedBySiblings, In as StackTerminationProtectionError, It as buildDenyExternalAccessPolicy, J as refStateLookupFromResource, Jt as resolveApp, K as cfnRefValueFromPhysicalId, Kn as markNonRetryable, Kt as getDefaultStateBucketName, L as clearOnUpdateRemoval, Lt as buildDockerImage, M as green, Mn as ProvisioningError, Mt as getBootstrapMarkerKey, N as red, Nn as ResourceTimeoutError, Nt as parseBootstrapMarker, O as formatResourceLine, Ot as rewriteTemplateAssetReferences, P as yellow, Pn as ResourceUpdateNotSupportedError, Pt as validateAssetBucketName, Q as assertRegionMatch, Qt as resolveStateBucketWithDefault, R as ProviderRegistry, Rt as formatDockerLoginError, S as unsupportedFinalSnapshotError, St as AssetPublisher, T as MULTI_REGION_RECREATE_BLOCKED_TYPES, Tn as LocalInvokeBuildError$1, Tt as buildAssetRedirectMap, U as disableInstanceApiTermination, Un as isMarkedNonRetryable, Ut as getDockerImageBySourceHash, V as CloudControlProvider, Vn as normalizeAwsError, Vt as runDockerStreaming, W as isTerminationProtectionPropagationError, Wn as isRetryableTransientError, Wt as Synthesizer, X as normalizeAwsTagsToCfn, Xt as resolveCaptureObservedState, Y as WAFv2WebACLProvider, Yt as resolveAutoAssetStorage, Z as resolveExplicitPhysicalId, Zt as resolveSkipPrefix, _ as buildFinalSnapshotIdentifier, _n as getAwsClients, _t as TemplateParser, a as DeploymentEventsStore, an as MIGRATE_TMP_PREFIX, at as requireConfigObject, b as isFinalSnapshotError, bt as rebuildClientForBucketRegion, c as replayFailedOperations, cn as expectedOwnerParam, ct as s3BucketDomainName, d as deleteSkipReason, dn as derivePartitionAndUrlSuffix, dt as s3BucketWebsiteUrl, en as resolveUseCdkBootstrapAssets, et as configBooleanRefusal, f as withResourceDeadline, fn as AssemblyReader, ft as applyRoleArnIfSet, g as PRE_DELETE_SNAPSHOT_TYPES, gn as AwsClients, gt as DagBuilder, h as ATOMIC_FINAL_SNAPSHOT_TYPES, hn as resolveBucketRegion, ht as withRetry, i as DeploymentEventsReader, in as CFN_TEMPLATE_URL_LIMIT, it as requireConfigArray, j as gray, jn as PartialFailureError, jt as ensureAssetStorage, k as bold, kn as MissingCdkCliError, kt as AssetModeResolver, l as replayRollback, ln as PARTITION_TABLE, lt as s3BucketDualStackDomainName, m as computeImplicitDeleteEdges, mt as describeTypeWithThrottleRetry, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as warnDeprecatedNoPrefixCliFlag, nt as readConfigString, o as planFailedOps, on as findLargeInlineResources, ot as requireConfigString, p as IMPLICIT_DELETE_DEPENDENCIES, pn as processStackMessages, pt as DiffCalculator, q as getAccountInfo, qt as getLegacyStateBucketName, r as DeployEngine, rn as CFN_TEMPLATE_BODY_LIMIT, rt as replayWarn, s as planRollback, sn as uploadCfnTemplate, st as s3BucketArn, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as stateBucketExistenceConfirmed, tt as configStringRefusal, u as UNSPECIFIED_SKIP_REASON, un as canonicalizeRegion, ut as s3BucketRegionalDomainName, v as ccRoutedFinalSnapshotError, vn as resetAwsClients, vt as LockManager, w as extractDeploymentEventError, wn as DeployCancelledError, wt as WorkGraph, x as refusesFinalSnapshot, xn as CdkdError, xt as shouldRetainResource, y as createPreDeleteFinalSnapshot, yn as setAwsClients, yt as S3StateBackend, z as findActionableSilentDrops, zt as getDockerCmd } from "./deploy-engine-CWt7h7Nc.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-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-D5ZBSgh2.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";
|
|
@@ -2649,7 +2649,7 @@ const POLICY_NO_TARGET_SKIP_REASON = "no Roles/Groups/Users in state — no dele
|
|
|
2649
2649
|
* removed by hand. Mirrors the caveat `compositeIdFormatMessage` already
|
|
2650
2650
|
* carries for the composite-id family.
|
|
2651
2651
|
*/
|
|
2652
|
-
const DEPLOY_SKIP_CAVEAT$3 = "NOTE this arm is ALSO reached from cdkd deploy
|
|
2652
|
+
const DEPLOY_SKIP_CAVEAT$3 = "NOTE this arm is ALSO reached from cdkd deploy. Since issue 1762 the DELETE of a resource removed from the template behaves like destroy — the record is KEPT and the next deploy re-attempts it — but a REPLACEMENT / rollback delete FAILS the resource instead (https://github.com/go-to-k/cdkd/issues/1762), leaving the old one untracked; there, remove the resource by hand.";
|
|
2653
2653
|
/**
|
|
2654
2654
|
* AWS IAM Policy Provider
|
|
2655
2655
|
*
|
|
@@ -3966,7 +3966,7 @@ const MEMBERSHIP_MISSING_FIELDS_SKIP_REASON = "GroupName/Users missing from stat
|
|
|
3966
3966
|
* be removed by hand. Mirrors the caveat `compositeIdFormatMessage` already
|
|
3967
3967
|
* carries for the composite-id family.
|
|
3968
3968
|
*/
|
|
3969
|
-
const DEPLOY_SKIP_CAVEAT$2 = "NOTE this arm is ALSO reached from cdkd deploy
|
|
3969
|
+
const DEPLOY_SKIP_CAVEAT$2 = "NOTE this arm is ALSO reached from cdkd deploy. Since issue 1762 the DELETE of a resource removed from the template behaves like destroy — the record is KEPT and the next deploy re-attempts it — but a REPLACEMENT / rollback delete FAILS the resource instead (https://github.com/go-to-k/cdkd/issues/1762), leaving the old one untracked; there, remove the memberships by hand.";
|
|
3970
3970
|
/**
|
|
3971
3971
|
* AWS IAM User / Group / UserToGroupAddition Provider
|
|
3972
3972
|
*
|
|
@@ -11857,7 +11857,7 @@ const PERMISSION_STATEMENT_ID_SKIP_REASON = "empty StatementId in state physical
|
|
|
11857
11857
|
* carries for the composite-id family; a remedy that is impossible on the path
|
|
11858
11858
|
* the user is actually on is worse than no remedy.
|
|
11859
11859
|
*/
|
|
11860
|
-
const DEPLOY_SKIP_CAVEAT$1 = "NOTE this arm is ALSO reached from cdkd deploy
|
|
11860
|
+
const DEPLOY_SKIP_CAVEAT$1 = "NOTE this arm is ALSO reached from cdkd deploy. Since issue 1762 the DELETE of a resource removed from the template behaves like destroy — the record is KEPT and the next deploy re-attempts it — but a REPLACEMENT / rollback delete FAILS the resource instead (https://github.com/go-to-k/cdkd/issues/1762), leaving the old one untracked; there, remove the resource by hand.";
|
|
11861
11861
|
/**
|
|
11862
11862
|
* AWS Lambda Permission Provider
|
|
11863
11863
|
*
|
|
@@ -12834,14 +12834,14 @@ const LAYER_VERSION_SKIP_REASON = "unparsable version in state LayerVersionArn
|
|
|
12834
12834
|
* The deploy-side caveat both skip warnings in this file carry (issue
|
|
12835
12835
|
* [#1762](https://github.com/go-to-k/cdkd/issues/1762)).
|
|
12836
12836
|
*
|
|
12837
|
-
* "Repair state.json and re-run"
|
|
12838
|
-
*
|
|
12839
|
-
*
|
|
12840
|
-
*
|
|
12841
|
-
* removed by hand. Mirrors the caveat
|
|
12842
|
-
* carries for the composite-id family.
|
|
12837
|
+
* "Repair state.json and re-run" holds on DESTROY and, since #1762, on the
|
|
12838
|
+
* deploy engine's template-removal DELETE — both keep the record. It does NOT
|
|
12839
|
+
* hold for a deploy-side REPLACEMENT or rollback delete: those now FAIL the
|
|
12840
|
+
* resource rather than reporting success, and the old resource can be left
|
|
12841
|
+
* untracked, so it has to be removed by hand. Mirrors the caveat
|
|
12842
|
+
* `compositeIdFormatMessage` carries for the composite-id family.
|
|
12843
12843
|
*/
|
|
12844
|
-
const DEPLOY_SKIP_CAVEAT = "NOTE this arm is ALSO reached from cdkd deploy
|
|
12844
|
+
const DEPLOY_SKIP_CAVEAT = "NOTE this arm is ALSO reached from cdkd deploy. Since issue 1762 the DELETE of a resource removed from the template behaves like destroy — the record is KEPT and the next deploy re-attempts it — but a REPLACEMENT / rollback delete FAILS the resource instead (https://github.com/go-to-k/cdkd/issues/1762), leaving the old one untracked; there, remove the resource by hand.";
|
|
12845
12845
|
/**
|
|
12846
12846
|
* AWS Lambda LayerVersion Provider
|
|
12847
12847
|
*
|
|
@@ -13194,19 +13194,20 @@ function formatShape(segments) {
|
|
|
13194
13194
|
* prints a `⚠ … skipped` line instead of `✓ … deleted`, reports
|
|
13195
13195
|
* `N deleted, 1 skipped`, KEEPS the state record, and exits non-zero. The
|
|
13196
13196
|
* wording here changed accordingly — it used to promise unconditionally that
|
|
13197
|
-
* cdkd "will report this delete as successful", which is no longer true on
|
|
13198
|
-
*
|
|
13199
|
-
*
|
|
13200
|
-
*
|
|
13201
|
-
*
|
|
13202
|
-
*
|
|
13203
|
-
*
|
|
13197
|
+
* cdkd "will report this delete as successful", which is no longer true on
|
|
13198
|
+
* either path. Issue [#1762](https://github.com/go-to-k/cdkd/issues/1762) then
|
|
13199
|
+
* taught the deploy engine to consume the outcome too, so the message no longer
|
|
13200
|
+
* warns that deploy drops the record: the template-removal DELETE keeps it,
|
|
13201
|
+
* exactly like destroy. What it DOES still distinguish is the replacement /
|
|
13202
|
+
* rollback delete, which fails the resource and can leave the old one
|
|
13203
|
+
* untracked — there "drop the record with 'cdkd state orphan'" is not the
|
|
13204
|
+
* remedy, deleting the resource by hand is.
|
|
13204
13205
|
*/
|
|
13205
13206
|
function compositeIdFormatMessage(format, logicalId, physicalId, options) {
|
|
13206
13207
|
const accepted = format.alsoAccepts ? `"${formatShape(format.segments)}" or ${format.alsoAccepts}` : `"${formatShape(format.segments)}"`;
|
|
13207
13208
|
const head = `Invalid physicalId format for ${format.label} ${logicalId}: expected ${accepted}, got "${physicalId}"`;
|
|
13208
13209
|
if (!options?.skipping) return head;
|
|
13209
|
-
return `${head}. Skipping the delete — no AWS call is issued, so the resource is LEFT IN PLACE.
|
|
13210
|
+
return `${head}. Skipping the delete — no AWS call is issued, so the resource is LEFT IN PLACE. The state record is KEPT and the run reports the skip: on 'cdkd destroy' / 'cdkd state destroy' (which exits non-zero) and, since issue 1762, on the plain DELETE of a resource removed from the template during cdkd deploy (which re-attempts it on the next deploy). So repair the id in state.json and re-run, or delete the resource by hand and drop the record with 'cdkd state orphan'. NOTE a deploy-side REPLACEMENT or rollback delete instead FAILS the resource (https://github.com/go-to-k/cdkd/issues/1762) — the old resource is left untracked there, so delete it by hand.`;
|
|
13210
13211
|
}
|
|
13211
13212
|
/**
|
|
13212
13213
|
* The short `ResourceDeleteResult.reason` every malformed-composite-id DELETE
|
|
@@ -15181,6 +15182,23 @@ var DynamoDBTableProvider = class {
|
|
|
15181
15182
|
//#endregion
|
|
15182
15183
|
//#region src/provisioning/providers/dynamodb-globaltable-provider.ts
|
|
15183
15184
|
/**
|
|
15185
|
+
* The CLOSED path table {@link DynamoDBGlobalTableProvider.canonicalizeDriftProperties}
|
|
15186
|
+
* strips from BOTH drift comparison sides (issue #1742).
|
|
15187
|
+
*
|
|
15188
|
+
* One entry today: the AWS-computed `GlobalSecondaryIndexes[].WarmThroughput`.
|
|
15189
|
+
* A table rather than an inline check so a second per-array-element member
|
|
15190
|
+
* lands as a row instead of a second walk — and so the scope is READABLE as a
|
|
15191
|
+
* list of paths, which is what "closed table" means here. Deliberately does
|
|
15192
|
+
* NOT include `LocalSecondaryIndexes` (this provider's readback assigns the
|
|
15193
|
+
* raw SDK descriptions there, a wider divergence than one member) or
|
|
15194
|
+
* `Replicas[].GlobalSecondaryIndexes` (whose entries carry only the read-half
|
|
15195
|
+
* throughput blocks — no `WarmThroughput` is emitted or accepted there).
|
|
15196
|
+
*/
|
|
15197
|
+
const DRIFT_STRIPPED_INDEX_MEMBERS = [{
|
|
15198
|
+
listKey: "GlobalSecondaryIndexes",
|
|
15199
|
+
member: "WarmThroughput"
|
|
15200
|
+
}];
|
|
15201
|
+
/**
|
|
15184
15202
|
* AWS DynamoDB GlobalTable Provider
|
|
15185
15203
|
*
|
|
15186
15204
|
* Implements resource provisioning for AWS::DynamoDB::GlobalTable using the
|
|
@@ -16634,7 +16652,12 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
16634
16652
|
const entry = { IndexName: gsi.IndexName };
|
|
16635
16653
|
if (gsi.KeySchema) entry["KeySchema"] = gsi.KeySchema;
|
|
16636
16654
|
if (gsi.Projection) entry["Projection"] = gsi.Projection;
|
|
16637
|
-
if (gsi.WarmThroughput)
|
|
16655
|
+
if (gsi.WarmThroughput) {
|
|
16656
|
+
const warm = {};
|
|
16657
|
+
if (gsi.WarmThroughput.ReadUnitsPerSecond !== void 0) warm["ReadUnitsPerSecond"] = gsi.WarmThroughput.ReadUnitsPerSecond;
|
|
16658
|
+
if (gsi.WarmThroughput.WriteUnitsPerSecond !== void 0) warm["WriteUnitsPerSecond"] = gsi.WarmThroughput.WriteUnitsPerSecond;
|
|
16659
|
+
if (Object.keys(warm).length > 0) entry["WarmThroughput"] = warm;
|
|
16660
|
+
}
|
|
16638
16661
|
const replicaEntry = { IndexName: gsi.IndexName };
|
|
16639
16662
|
if (billingMode === "PROVISIONED") {
|
|
16640
16663
|
const writeAutoScaling = await this.readAutoScalingSettings(tableNameForSubs, "dynamodb:index:WriteCapacityUnits", void 0, gsi.IndexName);
|
|
@@ -16887,6 +16910,115 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
16887
16910
|
return ["AttributeDefinitions"];
|
|
16888
16911
|
}
|
|
16889
16912
|
/**
|
|
16913
|
+
* Strip the AWS-computed per-index `WarmThroughput` from BOTH drift
|
|
16914
|
+
* comparison sides (issue #1742 defect 2, on the #1784 seam).
|
|
16915
|
+
*
|
|
16916
|
+
* `DescribeTable` reports a `WarmThroughput` for EVERY index whether or not
|
|
16917
|
+
* the template asked for one — a default `{ReadUnitsPerSecond: 12000,
|
|
16918
|
+
* WriteUnitsPerSecond: 4000, Status: 'ACTIVE'}`, measured us-east-1
|
|
16919
|
+
* 2026-08-13 on the `rollback-replay-effective-props` fixture — so on a
|
|
16920
|
+
* `properties`-only baseline (what a reverse-replacement rollback leaves
|
|
16921
|
+
* behind, since `rollback-executor.ts` strips `observedProperties`) the
|
|
16922
|
+
* member is a permanent one-sided difference: `cdkd drift` reports the table
|
|
16923
|
+
* forever and `--revert` re-issues calls for it.
|
|
16924
|
+
*
|
|
16925
|
+
* Why this mechanism and not the two cheaper ones:
|
|
16926
|
+
*
|
|
16927
|
+
* - `getDriftUnknownPaths` (the #1760 answer for the sibling type's
|
|
16928
|
+
* TOP-LEVEL member) cannot express it. `calculateResourceDrift` compares
|
|
16929
|
+
* arrays wholesale, so `isIgnoredPath` is never asked about a path that
|
|
16930
|
+
* crosses one; the only expressible suppression is the WHOLE
|
|
16931
|
+
* `GlobalSecondaryIndexes` subtree, i.e. never detecting an index add /
|
|
16932
|
+
* remove / capacity change again — the #1420 stopgap already refused.
|
|
16933
|
+
* - Gating the READBACK emission on the desired side (this issue's own
|
|
16934
|
+
* second candidate answer) removes the phantom for the `properties`
|
|
16935
|
+
* baseline and CREATES one for the far larger `observedProperties`
|
|
16936
|
+
* population: every bag already in S3 was written by a binary that emitted
|
|
16937
|
+
* the computed member, so the first `cdkd drift` after upgrading compares
|
|
16938
|
+
* a baseline that HAS it against a readback that does not, and reports the
|
|
16939
|
+
* whole array on an untouched table. It does not self-heal — the observed
|
|
16940
|
+
* capture only runs on CREATE / UPDATE. That attempt was implemented,
|
|
16941
|
+
* reviewed and REVERTED; do not re-propose it.
|
|
16942
|
+
*
|
|
16943
|
+
* Stripping from BOTH sides is what converges the two populations at once: a
|
|
16944
|
+
* stale observed record and a fresh readback both lose the member, and a
|
|
16945
|
+
* `properties` baseline that never had it now faces an AWS side without it.
|
|
16946
|
+
*
|
|
16947
|
+
* ACCEPTED COST, stated because it is a real loss: a template that DECLARES
|
|
16948
|
+
* a per-index `WarmThroughput` no longer has changes to it REPORTED by
|
|
16949
|
+
* `cdkd drift`. The value is still SENT (`toSdkGlobalSecondaryIndexes`
|
|
16950
|
+
* forwards it on create and on a new index), so this is a detection gap, not
|
|
16951
|
+
* a delivery one, and it is bounded by what cdkd could do about a difference
|
|
16952
|
+
* anyway: warm throughput only ever GROWS on the AWS side and cannot be
|
|
16953
|
+
* lowered, so `--revert` would issue a decrease AWS rejects — the residual
|
|
16954
|
+
* issue #1768 records for the sibling type's declared arm. A per-index
|
|
16955
|
+
* declared-gate is not expressible here in any case: this hook sees ONE bag
|
|
16956
|
+
* with no `side` argument and no reference to the desired side, which is the
|
|
16957
|
+
* symmetry the #1784 contract requires and the reason one-sided
|
|
16958
|
+
* normalization is refused.
|
|
16959
|
+
*
|
|
16960
|
+
* Scope is a CLOSED table rather than a walk for any key named
|
|
16961
|
+
* `WarmThroughput`: `Replicas[].GlobalSecondaryIndexes[]` entries carry only
|
|
16962
|
+
* the read-half throughput blocks (no `WarmThroughput` is emitted or
|
|
16963
|
+
* accepted there), and a blanket strip would remove a member from a path
|
|
16964
|
+
* nobody measured. The table is a FLAT list of `{listKey, member}` pairs —
|
|
16965
|
+
* the type is hardcoded one line below, not a key of it — and nothing
|
|
16966
|
+
* mechanically fences it against `readCurrentState`: a future per-replica
|
|
16967
|
+
* `WarmThroughput` emission would desync silently, so a member added to the
|
|
16968
|
+
* readback needs a row added here in the same change.
|
|
16969
|
+
*
|
|
16970
|
+
* The `resourceType` guard is kept but is UNREACHABLE, and the earlier
|
|
16971
|
+
* claim that it followed the #1784 CC-API-fallback caveat was WRONG — that
|
|
16972
|
+
* caveat is about the BAG SHAPE when a type has no `readCurrentState`, and
|
|
16973
|
+
* never produces a foreign `resourceType`. `drift.ts` resolves the provider
|
|
16974
|
+
* by `(resourceType, provisionedBy)` and then passes that SAME type back in,
|
|
16975
|
+
* and this provider is registered for exactly one type, so the `!==` arm
|
|
16976
|
+
* cannot fire. It stays as a cheap shape guard for a future second
|
|
16977
|
+
* registration, not because anything routes a foreign type here.
|
|
16978
|
+
*
|
|
16979
|
+
* UNCOVERED POPULATION, stated because the fix does NOT reach it: a
|
|
16980
|
+
* cc-api-routed GlobalTable gets neither half. Top-level `WarmThroughput` is
|
|
16981
|
+
* a `silentDrop` property for this type, so a template declaring it
|
|
16982
|
+
* auto-routes the whole resource through Cloud Control (the #614 routing)
|
|
16983
|
+
* and the route is STICKY — `drift.ts` then resolves `provider` to
|
|
16984
|
+
* `CloudControlProvider`, this hook is never invoked, and the AWS side comes
|
|
16985
|
+
* from CC's `GetResource`. So the `properties`-only-baseline phantom drift
|
|
16986
|
+
* this closes survives there. Pre-existing, not introduced here.
|
|
16987
|
+
*
|
|
16988
|
+
* Note the trigger is the TOP-LEVEL `WarmThroughput`, NOT the per-index
|
|
16989
|
+
* member this strips: a template declaring only the per-index member keeps
|
|
16990
|
+
* `GlobalSecondaryIndexes` (a handled property), stays SDK-routed, and IS
|
|
16991
|
+
* covered. Do not read this bound as "warm-throughput templates are
|
|
16992
|
+
* uncovered" — an earlier draft of this comment said so and was wrong.
|
|
16993
|
+
*
|
|
16994
|
+
* Pure, non-mutating, and identity-returning when nothing applies: the input
|
|
16995
|
+
* bag is the caller's state record / readback, an unaffected table pays
|
|
16996
|
+
* nothing, and only the index entries that actually carry the member are
|
|
16997
|
+
* rebuilt.
|
|
16998
|
+
*/
|
|
16999
|
+
canonicalizeDriftProperties(resourceType, properties) {
|
|
17000
|
+
if (resourceType !== "AWS::DynamoDB::GlobalTable") return properties;
|
|
17001
|
+
let result = properties;
|
|
17002
|
+
for (const { listKey, member } of DRIFT_STRIPPED_INDEX_MEMBERS) {
|
|
17003
|
+
const list = result[listKey];
|
|
17004
|
+
if (!Array.isArray(list)) continue;
|
|
17005
|
+
let stripped = false;
|
|
17006
|
+
const canonical = list.map((element) => {
|
|
17007
|
+
const entry = asRecord$1(element);
|
|
17008
|
+
if (!entry || !(member in entry)) return element;
|
|
17009
|
+
stripped = true;
|
|
17010
|
+
const copy = { ...entry };
|
|
17011
|
+
delete copy[member];
|
|
17012
|
+
return copy;
|
|
17013
|
+
});
|
|
17014
|
+
if (stripped) result = {
|
|
17015
|
+
...result,
|
|
17016
|
+
[listKey]: canonical
|
|
17017
|
+
};
|
|
17018
|
+
}
|
|
17019
|
+
return result;
|
|
17020
|
+
}
|
|
17021
|
+
/**
|
|
16890
17022
|
* Adopt an existing DynamoDB GlobalTable into cdkd state.
|
|
16891
17023
|
*
|
|
16892
17024
|
* Lookup order:
|
|
@@ -53907,7 +54039,8 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
53907
54039
|
});
|
|
53908
54040
|
renderer.removeTask(logicalId);
|
|
53909
54041
|
if (deleteResult?.outcome === "skipped") {
|
|
53910
|
-
|
|
54042
|
+
const skipReason = deleteSkipReason(deleteResult) ?? "no reason reported by the provider";
|
|
54043
|
+
logger.info(` ${formatResourceLine("skipped", logicalId, resource.resourceType, `skipped (${skipReason})`)}`);
|
|
53911
54044
|
result.skippedCount++;
|
|
53912
54045
|
skippedStateTargets.add(stateTargetFor(logicalId, resource.resourceType));
|
|
53913
54046
|
ctx.eventRecorder?.record({
|
|
@@ -53918,7 +54051,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
53918
54051
|
resourceType: resource.resourceType,
|
|
53919
54052
|
...resource.provisionedBy && { provisionedBy: resource.provisionedBy },
|
|
53920
54053
|
...resource.physicalId && { physicalId: resource.physicalId },
|
|
53921
|
-
reason:
|
|
54054
|
+
reason: skipReason,
|
|
53922
54055
|
durationMs: Date.now() - resourceStartedAt
|
|
53923
54056
|
});
|
|
53924
54057
|
return;
|
|
@@ -55458,6 +55591,7 @@ async function deployCommand(stacks, options) {
|
|
|
55458
55591
|
logger.info(` Created: ${deployResult.created > 0 ? green(deployResult.created) : gray(deployResult.created)}`);
|
|
55459
55592
|
logger.info(` Updated: ${deployResult.updated > 0 ? yellow(deployResult.updated) : gray(deployResult.updated)}`);
|
|
55460
55593
|
logger.info(` Deleted: ${deployResult.deleted > 0 ? red(deployResult.deleted) : gray(deployResult.deleted)}`);
|
|
55594
|
+
if (deployResult.deleteSkipped > 0) logger.info(` Skipped (not deleted): ${yellow(deployResult.deleteSkipped)}`);
|
|
55461
55595
|
logger.info(` Unchanged: ${gray(deployResult.unchanged)}`);
|
|
55462
55596
|
logger.info(` Duration: ${cyan((deployResult.durationMs / 1e3).toFixed(2) + "s")}`);
|
|
55463
55597
|
if (deployResult.attributeFallbackCount > 0) logger.warn(`${deployResult.attributeFallbackCount} attribute resolution(s) fell back to the physical ID (potentially wrong values); re-run with --strict-getatt to fail on these`);
|
|
@@ -55470,7 +55604,8 @@ async function deployCommand(stacks, options) {
|
|
|
55470
55604
|
recordRunSucceeded(eventRecorder, stackInfo.stackName, {
|
|
55471
55605
|
created: deployResult.created,
|
|
55472
55606
|
updated: deployResult.updated,
|
|
55473
|
-
deleted: deployResult.deleted
|
|
55607
|
+
deleted: deployResult.deleted,
|
|
55608
|
+
...deployResult.deleteSkipped > 0 && { skipped: deployResult.deleteSkipped }
|
|
55474
55609
|
}, deployResult.durationMs);
|
|
55475
55610
|
} catch (deployError) {
|
|
55476
55611
|
if (deployError instanceof DeployCancelledError) return;
|
|
@@ -77185,7 +77320,7 @@ function createMigrateCommand() {
|
|
|
77185
77320
|
*/
|
|
77186
77321
|
function buildProgram() {
|
|
77187
77322
|
const program = new Command();
|
|
77188
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.283.
|
|
77323
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.283.9");
|
|
77189
77324
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
77190
77325
|
const { profile } = actionCommand.optsWithGlobals();
|
|
77191
77326
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|