@go-to-k/cdkd 0.104.0 → 0.105.0
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 +171 -36
- package/dist/cli.js.map +1 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -35,6 +35,7 @@ import { Command, Option } from "commander";
|
|
|
35
35
|
import { writeFileSync as writeFileSync$1 } from "fs";
|
|
36
36
|
import { join as join$1 } from "path";
|
|
37
37
|
import * as zlib from "node:zlib";
|
|
38
|
+
import { ApplicationAutoScalingClient, DescribeScalingPoliciesCommand } from "@aws-sdk/client-application-auto-scaling";
|
|
38
39
|
import { ApiGatewayV2Client, CreateApiCommand, CreateAuthorizerCommand as CreateAuthorizerCommand$1, CreateIntegrationCommand, CreateRouteCommand as CreateRouteCommand$1, CreateStageCommand as CreateStageCommand$1, DeleteApiCommand, DeleteAuthorizerCommand as DeleteAuthorizerCommand$1, DeleteIntegrationCommand, DeleteRouteCommand as DeleteRouteCommand$1, DeleteStageCommand as DeleteStageCommand$1, GetApiCommand, GetApisCommand, GetAuthorizerCommand as GetAuthorizerCommand$1, GetIntegrationCommand, GetRouteCommand, GetStageCommand as GetStageCommand$1, NotFoundException as NotFoundException$3, UpdateApiCommand, UpdateAuthorizerCommand as UpdateAuthorizerCommand$1, UpdateIntegrationCommand, UpdateRouteCommand, UpdateStageCommand as UpdateStageCommand$1 } from "@aws-sdk/client-apigatewayv2";
|
|
39
40
|
import { CreateStateMachineCommand, DeleteStateMachineCommand, DescribeStateMachineCommand, ListStateMachinesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$9, SFNClient, StateMachineDoesNotExist, TagResourceCommand as TagResourceCommand$10, UntagResourceCommand as UntagResourceCommand$9, UpdateStateMachineCommand } from "@aws-sdk/client-sfn";
|
|
40
41
|
import { CreateClusterCommand, CreateServiceCommand, DeleteClusterCommand, DeleteServiceCommand, DeregisterTaskDefinitionCommand, DescribeClustersCommand, DescribeServicesCommand, DescribeTaskDefinitionCommand, ECSClient, ListClustersCommand, ListServicesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$10, PutClusterCapacityProvidersCommand, RegisterTaskDefinitionCommand, TagResourceCommand as TagResourceCommand$11, UntagResourceCommand as UntagResourceCommand$10, UpdateClusterCommand, UpdateServiceCommand } from "@aws-sdk/client-ecs";
|
|
@@ -7878,13 +7879,26 @@ var DynamoDBTableProvider = class {
|
|
|
7878
7879
|
* calling `update()`, but the guard is defense-in-depth.
|
|
7879
7880
|
* - Per-replica drift (`ContributorInsightsSpecification` /
|
|
7880
7881
|
* `PointInTimeRecoverySpecification` / `KinesisStreamSpecification`)
|
|
7881
|
-
* is surfaced for the LOCAL replica
|
|
7882
|
-
*
|
|
7882
|
+
* is surfaced for BOTH the LOCAL replica AND cross-region replicas
|
|
7883
|
+
* via per-region SDK clients (cached in `regionalClientCache` for
|
|
7884
|
+
* the deploy run). Issue #389 lifted the v1 LOCAL-only limitation.
|
|
7885
|
+
* - Cross-region replica Tags propagation (Issue #389): when the
|
|
7886
|
+
* update path detects a Tags-only diff on a non-local replica,
|
|
7887
|
+
* cdkd resolves the replica's table ARN by swapping the region
|
|
7888
|
+
* segment of the local ARN and issues `TagResource` /
|
|
7889
|
+
* `UntagResource` against a per-region client.
|
|
7883
7890
|
*/
|
|
7884
7891
|
var DynamoDBGlobalTableProvider = class {
|
|
7885
7892
|
dynamoDBClient;
|
|
7886
7893
|
logger = getLogger().child("DynamoDBGlobalTableProvider");
|
|
7887
7894
|
/**
|
|
7895
|
+
* Caches per-region `DynamoDBClient` instances for cross-region drift
|
|
7896
|
+
* reads (`readCurrentState`) and cross-region Tag propagation
|
|
7897
|
+
* (`update()`). Keyed by region string; reuses the default credential
|
|
7898
|
+
* chain. Lifetime is the provider instance — one deploy run.
|
|
7899
|
+
*/
|
|
7900
|
+
regionalClientCache = /* @__PURE__ */ new Map();
|
|
7901
|
+
/**
|
|
7888
7902
|
* Caches `getAttribute(physicalId, attribute)` results for the lifetime
|
|
7889
7903
|
* of this provider instance (one deploy run). Safe under the current
|
|
7890
7904
|
* `update()` contract because `update()` cannot mid-deploy mutate
|
|
@@ -7916,6 +7930,50 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
7916
7930
|
this.dynamoDBClient = awsClients.dynamoDB;
|
|
7917
7931
|
}
|
|
7918
7932
|
/**
|
|
7933
|
+
* Return a `DynamoDBClient` pinned to the given region, caching per
|
|
7934
|
+
* region for the lifetime of this provider instance. Uses the default
|
|
7935
|
+
* credential chain (env / shared config / IAM role) — no explicit
|
|
7936
|
+
* credential plumbing needed.
|
|
7937
|
+
*
|
|
7938
|
+
* Used by `readCurrentState` (cross-region per-replica sub-spec reads)
|
|
7939
|
+
* and `update()` (cross-region replica Tag propagation). Both code
|
|
7940
|
+
* paths fire region-scoped DynamoDB APIs (`DescribeContributorInsights`
|
|
7941
|
+
* / `DescribeContinuousBackups` / `DescribeKinesisStreamingDestination`
|
|
7942
|
+
* / `TagResource` / `UntagResource`) against the replica's region.
|
|
7943
|
+
*
|
|
7944
|
+
* The cache may return `this.dynamoDBClient` when `region` happens to
|
|
7945
|
+
* match the local client's region — in tests the local mock is
|
|
7946
|
+
* intercepted via `vi.mock('../../utils/aws-clients.js')` so reuse
|
|
7947
|
+
* is safe (and explicitly desired so the mock catches the call).
|
|
7948
|
+
*/
|
|
7949
|
+
getRegionalClient(region) {
|
|
7950
|
+
const cached = this.regionalClientCache.get(region);
|
|
7951
|
+
if (cached) return cached;
|
|
7952
|
+
const client = new DynamoDBClient({ region });
|
|
7953
|
+
this.regionalClientCache.set(region, client);
|
|
7954
|
+
return client;
|
|
7955
|
+
}
|
|
7956
|
+
/**
|
|
7957
|
+
* Construct the regional table ARN for a cross-region replica of a
|
|
7958
|
+
* GlobalTable. AWS replicates the same `TableName` across every
|
|
7959
|
+
* replica region, with each replica's ARN differing only in the
|
|
7960
|
+
* `:<region>:` segment. Cheaper than a second `DescribeTable` round-
|
|
7961
|
+
* trip on the regional client.
|
|
7962
|
+
*
|
|
7963
|
+
* Example:
|
|
7964
|
+
* local ARN: arn:aws:dynamodb:us-east-1:123:table/Foo
|
|
7965
|
+
* for eu-west-1 → arn:aws:dynamodb:eu-west-1:123:table/Foo
|
|
7966
|
+
*
|
|
7967
|
+
* Returns `undefined` when the local ARN is malformed (defensive —
|
|
7968
|
+
* downstream callers omit the offending operation rather than throw).
|
|
7969
|
+
*/
|
|
7970
|
+
replicaArnForRegion(localTableArn, targetRegion) {
|
|
7971
|
+
const segments = localTableArn.split(":");
|
|
7972
|
+
if (segments.length < 6) return void 0;
|
|
7973
|
+
segments[3] = targetRegion;
|
|
7974
|
+
return segments.join(":");
|
|
7975
|
+
}
|
|
7976
|
+
/**
|
|
7919
7977
|
* Create a DynamoDB Global Table (CDK TableV2).
|
|
7920
7978
|
*
|
|
7921
7979
|
* GlobalTable is built on the regular DynamoDB Table primitive: cdkd issues
|
|
@@ -8167,12 +8225,24 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
8167
8225
|
for (const replica of replicaDiff.modified) {
|
|
8168
8226
|
const region = replica["Region"];
|
|
8169
8227
|
if (!region || region === currentRegion) continue;
|
|
8228
|
+
const oldReplicaTags = (previousProperties["Replicas"] ?? []).find((r) => r["Region"] === region)?.["Tags"];
|
|
8229
|
+
const newReplicaTags = replica["Tags"];
|
|
8230
|
+
if (!deepEqual$1(oldReplicaTags, newReplicaTags)) if (tableArn) {
|
|
8231
|
+
const replicaArn = this.replicaArnForRegion(tableArn, region);
|
|
8232
|
+
if (replicaArn) try {
|
|
8233
|
+
const regionalClient = this.getRegionalClient(region);
|
|
8234
|
+
await this.applyTagDiffOnClient(regionalClient, replicaArn, oldReplicaTags, newReplicaTags);
|
|
8235
|
+
} catch (tagErr) {
|
|
8236
|
+
this.logger.warn(`Could not apply Tags diff to cross-region replica ${region} of ${physicalId}: ${tagErr instanceof Error ? tagErr.message : String(tagErr)}. The replica's Tags state will surface as drift until the next successful deploy.`);
|
|
8237
|
+
}
|
|
8238
|
+
else this.logger.warn(`Could not derive replica ARN for region ${region} from ${tableArn} — skipping Tags propagation for ${physicalId}`);
|
|
8239
|
+
} else this.logger.warn(`Local DescribeTable returned no TableArn — cannot propagate Tags to cross-region replica ${region} of ${physicalId}`);
|
|
8170
8240
|
const updateAction = { RegionName: region };
|
|
8171
8241
|
if (replica["KMSMasterKeyId"] !== void 0) updateAction.KMSMasterKeyId = replica["KMSMasterKeyId"];
|
|
8172
8242
|
if (replica["GlobalSecondaryIndexes"]) updateAction.GlobalSecondaryIndexes = replica["GlobalSecondaryIndexes"];
|
|
8173
8243
|
if (replica["TableClassOverride"]) updateAction.TableClassOverride = replica["TableClassOverride"];
|
|
8174
8244
|
if (!(updateAction.KMSMasterKeyId !== void 0 || updateAction.GlobalSecondaryIndexes !== void 0 || updateAction.TableClassOverride !== void 0)) {
|
|
8175
|
-
this.logger.debug(`Cross-region replica ${region} of ${physicalId}: only Tags-style changes detected;
|
|
8245
|
+
this.logger.debug(`Cross-region replica ${region} of ${physicalId}: only Tags-style changes detected; UpdateReplica skipped (AWS rejects empty Update actions). Tags propagation handled above via per-region client.`);
|
|
8176
8246
|
continue;
|
|
8177
8247
|
}
|
|
8178
8248
|
await this.dynamoDBClient.send(new UpdateTableCommand({
|
|
@@ -8259,10 +8329,22 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
8259
8329
|
}
|
|
8260
8330
|
/**
|
|
8261
8331
|
* Apply a diff between old and new CFn-shape Tags arrays via DynamoDB's
|
|
8262
|
-
* `TagResource` / `UntagResource` APIs
|
|
8263
|
-
* `ResourceArn`.
|
|
8332
|
+
* `TagResource` / `UntagResource` APIs against the local client. Both
|
|
8333
|
+
* take the table ARN as `ResourceArn`.
|
|
8334
|
+
*
|
|
8335
|
+
* Local-replica convenience wrapper around `applyTagDiffOnClient` so
|
|
8336
|
+
* existing call sites stay unchanged.
|
|
8264
8337
|
*/
|
|
8265
8338
|
async applyTagDiff(tableArn, oldTagsRaw, newTagsRaw) {
|
|
8339
|
+
await this.applyTagDiffOnClient(this.dynamoDBClient, tableArn, oldTagsRaw, newTagsRaw);
|
|
8340
|
+
}
|
|
8341
|
+
/**
|
|
8342
|
+
* Apply a Tags diff against the given `DynamoDBClient` (which may be
|
|
8343
|
+
* the local client or a per-region client returned by
|
|
8344
|
+
* `getRegionalClient`). Used by the local-replica path AND the
|
|
8345
|
+
* cross-region replica Tags propagation path (Issue #389).
|
|
8346
|
+
*/
|
|
8347
|
+
async applyTagDiffOnClient(client, tableArn, oldTagsRaw, newTagsRaw) {
|
|
8266
8348
|
const toMap = (tags) => {
|
|
8267
8349
|
const m = /* @__PURE__ */ new Map();
|
|
8268
8350
|
for (const t of tags ?? []) if (t.Key !== void 0 && t.Value !== void 0) m.set(t.Key, t.Value);
|
|
@@ -8278,14 +8360,14 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
8278
8360
|
const tagsToRemove = [];
|
|
8279
8361
|
for (const k of oldMap.keys()) if (!newMap.has(k)) tagsToRemove.push(k);
|
|
8280
8362
|
if (tagsToRemove.length > 0) {
|
|
8281
|
-
await
|
|
8363
|
+
await client.send(new UntagResourceCommand$2({
|
|
8282
8364
|
ResourceArn: tableArn,
|
|
8283
8365
|
TagKeys: tagsToRemove
|
|
8284
8366
|
}));
|
|
8285
8367
|
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from DynamoDB GlobalTable ${tableArn}`);
|
|
8286
8368
|
}
|
|
8287
8369
|
if (tagsToAdd.length > 0) {
|
|
8288
|
-
await
|
|
8370
|
+
await client.send(new TagResourceCommand$2({
|
|
8289
8371
|
ResourceArn: tableArn,
|
|
8290
8372
|
Tags: tagsToAdd
|
|
8291
8373
|
}));
|
|
@@ -8453,20 +8535,36 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
8453
8535
|
result["Replicas"] = await Promise.all((table.Replicas ?? []).map(async (r) => {
|
|
8454
8536
|
const entry = { Region: r.RegionName };
|
|
8455
8537
|
if (r.KMSMasterKeyId !== void 0) entry["KMSMasterKeyId"] = r.KMSMasterKeyId;
|
|
8456
|
-
if (r.RegionName
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8538
|
+
if (!r.RegionName) return entry;
|
|
8539
|
+
const isLocal = r.RegionName === currentRegion;
|
|
8540
|
+
const client = isLocal ? this.dynamoDBClient : this.getRegionalClient(r.RegionName);
|
|
8541
|
+
const regionLabel = r.RegionName;
|
|
8542
|
+
const replicaArn = isLocal ? table.TableArn : table.TableArn ? this.replicaArnForRegion(table.TableArn, r.RegionName) : void 0;
|
|
8543
|
+
const subs = await this.readReplicaSubSpecs(client, tableNameForSubs, regionLabel);
|
|
8544
|
+
Object.assign(entry, subs);
|
|
8545
|
+
if (replicaArn) try {
|
|
8546
|
+
entry["Tags"] = normalizeAwsTagsToCfn((await client.send(new ListTagsOfResourceCommand({ ResourceArn: replicaArn }))).Tags);
|
|
8547
|
+
} catch (tagErr) {
|
|
8548
|
+
if (tagErr instanceof ResourceNotFoundException$1) {
|
|
8549
|
+
if (isLocal) throw tagErr;
|
|
8550
|
+
this.logger.debug(`Cross-region replica ${regionLabel} returned RNF on ListTagsOfResource; omitting Tags`);
|
|
8551
|
+
entry["Tags"] = [];
|
|
8552
|
+
} else {
|
|
8553
|
+
this.logger.warn(`Could not fetch tags for DynamoDB GlobalTable ${tableNameForSubs} in ${regionLabel}: ${tagErr instanceof Error ? tagErr.message : String(tagErr)}`);
|
|
8464
8554
|
entry["Tags"] = [];
|
|
8465
8555
|
}
|
|
8466
|
-
else entry["Tags"] = [];
|
|
8467
8556
|
}
|
|
8557
|
+
else entry["Tags"] = [];
|
|
8468
8558
|
return entry;
|
|
8469
8559
|
}));
|
|
8560
|
+
if (table.OnDemandThroughput?.MaxWriteRequestUnits !== void 0) result["WriteOnDemandThroughputSettings"] = { MaxWriteRequestUnits: table.OnDemandThroughput.MaxWriteRequestUnits };
|
|
8561
|
+
else result["WriteOnDemandThroughputSettings"] = {};
|
|
8562
|
+
if (billingMode === "PROVISIONED") {
|
|
8563
|
+
const writeCapacity = table.ProvisionedThroughput?.WriteCapacityUnits;
|
|
8564
|
+
if (writeCapacity !== void 0) if (!await this.hasWriteAutoScalingPolicy(tableNameForSubs)) result["WriteProvisionedThroughputSettings"] = { WriteCapacityUnits: writeCapacity };
|
|
8565
|
+
else result["WriteProvisionedThroughputSettings"] = {};
|
|
8566
|
+
else result["WriteProvisionedThroughputSettings"] = {};
|
|
8567
|
+
} else result["WriteProvisionedThroughputSettings"] = {};
|
|
8470
8568
|
try {
|
|
8471
8569
|
const ttlDesc = (await this.dynamoDBClient.send(new DescribeTimeToLiveCommand({ TableName: tableNameForSubs }))).TimeToLiveDescription;
|
|
8472
8570
|
const ttlStatus = ttlDesc?.TimeToLiveStatus;
|
|
@@ -8485,7 +8583,9 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
8485
8583
|
}
|
|
8486
8584
|
}
|
|
8487
8585
|
/**
|
|
8488
|
-
* Read per-replica sub-specifications
|
|
8586
|
+
* Read per-replica sub-specifications against the given `DynamoDBClient`
|
|
8587
|
+
* (which may be the local client or a per-region client returned by
|
|
8588
|
+
* `getRegionalClient`):
|
|
8489
8589
|
* - `ContributorInsightsSpecification` via `DescribeContributorInsights`
|
|
8490
8590
|
* (table-level; GSI overrides are NOT surfaced in v1 — they would
|
|
8491
8591
|
* require one call per GSI and a different CFn nesting under the
|
|
@@ -8498,51 +8598,86 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
8498
8598
|
* Each call is best-effort: errors omit the offending key rather than
|
|
8499
8599
|
* fail the whole drift read.
|
|
8500
8600
|
*
|
|
8501
|
-
*
|
|
8502
|
-
*
|
|
8601
|
+
* Issue #389 lifted the LOCAL-only limitation by parameterizing the
|
|
8602
|
+
* client — the same reverse-mapping logic runs against any region's
|
|
8603
|
+
* client.
|
|
8503
8604
|
*/
|
|
8504
|
-
async
|
|
8605
|
+
async readReplicaSubSpecs(client, tableName, regionLabel) {
|
|
8505
8606
|
const out = {};
|
|
8506
8607
|
try {
|
|
8507
|
-
const ci = await
|
|
8608
|
+
const ci = await client.send(new DescribeContributorInsightsCommand({ TableName: tableName }));
|
|
8508
8609
|
if (ci.ContributorInsightsStatus) out["ContributorInsightsSpecification"] = { Enabled: ci.ContributorInsightsStatus === "ENABLED" };
|
|
8509
8610
|
} catch (err) {
|
|
8510
|
-
this.logger.debug(`Could not read ContributorInsights for ${tableName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8611
|
+
this.logger.debug(`Could not read ContributorInsights for ${tableName} in ${regionLabel}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8511
8612
|
}
|
|
8512
8613
|
try {
|
|
8513
|
-
const pitrStatus = (await
|
|
8614
|
+
const pitrStatus = (await client.send(new DescribeContinuousBackupsCommand({ TableName: tableName }))).ContinuousBackupsDescription?.PointInTimeRecoveryDescription?.PointInTimeRecoveryStatus;
|
|
8514
8615
|
if (pitrStatus) out["PointInTimeRecoverySpecification"] = { PointInTimeRecoveryEnabled: pitrStatus === "ENABLED" };
|
|
8515
8616
|
} catch (err) {
|
|
8516
|
-
this.logger.debug(`Could not read PointInTimeRecovery for ${tableName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8617
|
+
this.logger.debug(`Could not read PointInTimeRecovery for ${tableName} in ${regionLabel}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8517
8618
|
}
|
|
8518
8619
|
try {
|
|
8519
|
-
const active = ((await
|
|
8620
|
+
const active = ((await client.send(new DescribeKinesisStreamingDestinationCommand({ TableName: tableName }))).KinesisDataStreamDestinations ?? []).find((d) => d.DestinationStatus === "ACTIVE" || d.DestinationStatus === "ENABLING");
|
|
8520
8621
|
if (active?.StreamArn) {
|
|
8521
8622
|
const ksOut = { StreamArn: active.StreamArn };
|
|
8522
8623
|
if (active.ApproximateCreationDateTimePrecision !== void 0) ksOut["ApproximateCreationDateTimePrecision"] = active.ApproximateCreationDateTimePrecision;
|
|
8523
8624
|
out["KinesisStreamSpecification"] = ksOut;
|
|
8524
8625
|
}
|
|
8525
8626
|
} catch (err) {
|
|
8526
|
-
this.logger.debug(`Could not read KinesisStreamingDestination for ${tableName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8627
|
+
this.logger.debug(`Could not read KinesisStreamingDestination for ${tableName} in ${regionLabel}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8527
8628
|
}
|
|
8528
8629
|
return out;
|
|
8529
8630
|
}
|
|
8530
8631
|
/**
|
|
8632
|
+
* Detect whether application-autoscaling has a scaling policy on this
|
|
8633
|
+
* table's WriteCapacityUnits dimension. Used to decide whether the
|
|
8634
|
+
* `WriteProvisionedThroughputSettings.WriteCapacityUnits` flat-value
|
|
8635
|
+
* surface in `readCurrentState` is safe to emit (auto-scaling
|
|
8636
|
+
* dynamically mutates capacity, so a flat snapshot would fire false
|
|
8637
|
+
* drift on every scale event — when an autoscaling policy is in play
|
|
8638
|
+
* we omit the flat surface so a follow-up PR can reverse-map the
|
|
8639
|
+
* full `WriteCapacityAutoScalingSettings` shape).
|
|
8640
|
+
*
|
|
8641
|
+
* Best-effort: errors return `false` (no autoscaling detected) so a
|
|
8642
|
+
* permissions gap on `application-autoscaling:DescribeScalingPolicies`
|
|
8643
|
+
* does not abort drift reads. Logged at debug.
|
|
8644
|
+
*/
|
|
8645
|
+
async hasWriteAutoScalingPolicy(tableName) {
|
|
8646
|
+
try {
|
|
8647
|
+
return ((await new ApplicationAutoScalingClient({ region: await this.dynamoDBClient.config.region() ?? "" }).send(new DescribeScalingPoliciesCommand({
|
|
8648
|
+
ServiceNamespace: "dynamodb",
|
|
8649
|
+
ResourceId: `table/${tableName}`,
|
|
8650
|
+
ScalableDimension: "dynamodb:table:WriteCapacityUnits"
|
|
8651
|
+
}))).ScalingPolicies ?? []).length > 0;
|
|
8652
|
+
} catch (err) {
|
|
8653
|
+
this.logger.debug(`Could not query application-autoscaling for ${tableName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8654
|
+
return false;
|
|
8655
|
+
}
|
|
8656
|
+
}
|
|
8657
|
+
/**
|
|
8531
8658
|
* State property paths cdkd's GlobalTable readCurrentState cannot (yet)
|
|
8532
8659
|
* reverse-map. The drift comparator skips these so a templated value
|
|
8533
8660
|
* doesn't fire guaranteed false drift on every clean run.
|
|
8534
8661
|
*
|
|
8535
|
-
*
|
|
8536
|
-
*
|
|
8537
|
-
*
|
|
8538
|
-
*
|
|
8539
|
-
*
|
|
8540
|
-
*
|
|
8541
|
-
*
|
|
8542
|
-
*
|
|
8662
|
+
* Issue #389 emptied this list:
|
|
8663
|
+
* - `WriteProvisionedThroughputSettings` (flat-WriteCapacityUnits
|
|
8664
|
+
* subset) is now reverse-mapped from `Table.ProvisionedThroughput`
|
|
8665
|
+
* when BillingMode is PROVISIONED AND application-autoscaling has
|
|
8666
|
+
* no policy on the WriteCapacityUnits dimension. Auto-scaling
|
|
8667
|
+
* cases emit an empty `{}` placeholder so the comparator does NOT
|
|
8668
|
+
* fire false drift on the literal `WriteCapacityUnits` subtree.
|
|
8669
|
+
* - `WriteOnDemandThroughputSettings` is reverse-mapped from
|
|
8670
|
+
* `Table.OnDemandThroughput.MaxWriteRequestUnits`. Always-emit
|
|
8671
|
+
* `{}` placeholder when AWS reports no override.
|
|
8672
|
+
* - `TimeToLiveSpecification` is reverse-mapped via
|
|
8673
|
+
* `DescribeTimeToLive` in `readCurrentState`.
|
|
8674
|
+
*
|
|
8675
|
+
* Returning an empty list is the canonical "no known-unknown paths"
|
|
8676
|
+
* shape — keeping the method present (rather than removing it) for
|
|
8677
|
+
* future additions and for backward compat on test reflection.
|
|
8543
8678
|
*/
|
|
8544
8679
|
getDriftUnknownPaths(_resourceType) {
|
|
8545
|
-
return [
|
|
8680
|
+
return [];
|
|
8546
8681
|
}
|
|
8547
8682
|
/**
|
|
8548
8683
|
* Adopt an existing DynamoDB GlobalTable into cdkd state.
|
|
@@ -44028,7 +44163,7 @@ function reorderArgs(argv) {
|
|
|
44028
44163
|
*/
|
|
44029
44164
|
async function main() {
|
|
44030
44165
|
const program = new Command();
|
|
44031
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
44166
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.105.0");
|
|
44032
44167
|
program.addCommand(createBootstrapCommand());
|
|
44033
44168
|
program.addCommand(createSynthCommand());
|
|
44034
44169
|
program.addCommand(createListCommand());
|