@go-to-k/cdkd 0.201.0 → 0.201.1
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 +60 -39
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -17236,7 +17236,7 @@ var CloudFrontDistributionProvider = class {
|
|
|
17236
17236
|
const getResponse = await this.cloudFrontClient.send(new GetDistributionCommand({ Id: physicalId }));
|
|
17237
17237
|
const domainName = getResponse.Distribution?.DomainName ?? "";
|
|
17238
17238
|
const arn = getResponse.Distribution?.ARN;
|
|
17239
|
-
await this.
|
|
17239
|
+
await this.applyTagDiff(arn, previousProperties["Tags"], properties["Tags"], physicalId, logicalId, resourceType);
|
|
17240
17240
|
this.logger.debug(`Updated CloudFront Distribution ${physicalId}`);
|
|
17241
17241
|
return {
|
|
17242
17242
|
physicalId,
|
|
@@ -17489,32 +17489,44 @@ var CloudFrontDistributionProvider = class {
|
|
|
17489
17489
|
};
|
|
17490
17490
|
}
|
|
17491
17491
|
/**
|
|
17492
|
-
* Apply a tag diff to a distribution
|
|
17492
|
+
* Apply a tag diff to a distribution.
|
|
17493
17493
|
*
|
|
17494
17494
|
* CloudFront has no atomic overlay API for tags — `TagResource` adds /
|
|
17495
17495
|
* overwrites and `UntagResource` removes. Run the removal first, then
|
|
17496
17496
|
* the upsert, so a same-key value rewrite (which lands in `upserts`)
|
|
17497
17497
|
* is not accidentally cleared by a stale Untag.
|
|
17498
17498
|
*
|
|
17499
|
-
* Errors are
|
|
17500
|
-
*
|
|
17501
|
-
*
|
|
17502
|
-
*
|
|
17503
|
-
*
|
|
17499
|
+
* Errors are RETHROWN as `ProvisioningError` (issue #740 fix) so the
|
|
17500
|
+
* deploy engine sees a failed update() and (a) does NOT write the new
|
|
17501
|
+
* properties.Tags into state — the next deploy retries the tag-diff
|
|
17502
|
+
* against the still-old state, (b) surfaces the failure to the user
|
|
17503
|
+
* via the standard error path. The deploy engine's `withRetry` MAY
|
|
17504
|
+
* pick up some transient AWS errors via the cause-message-pattern
|
|
17505
|
+
* match (`retryable-errors.ts`'s `RETRYABLE_ERROR_MESSAGE_PATTERNS`),
|
|
17506
|
+
* but bare HTTP 429 throttles wrapped by update()'s outer catch reach
|
|
17507
|
+
* the classifier two levels deep and slip past its single-level
|
|
17508
|
+
* `.cause` walk — so the **load-bearing retry guarantee is the
|
|
17509
|
+
* next-deploy retry**, not in-deploy retry. This is acceptable: the
|
|
17510
|
+
* user sees the failure, can react, and the next `cdkd deploy`
|
|
17511
|
+
* re-fires the tag-diff against the still-old state cleanly.
|
|
17512
|
+
*
|
|
17513
|
+
* Trade-off: a tag-side failure flips an otherwise-successful
|
|
17514
|
+
* `UpdateDistribution` into a deploy failure, and the retry will
|
|
17515
|
+
* re-issue UpdateDistribution against the (now-current) config —
|
|
17516
|
+
* AWS accepts the no-op idempotently. The cost of that secondary
|
|
17517
|
+
* noise is much lower than the cost of silent tag drift the pre-#740
|
|
17518
|
+
* swallow caused.
|
|
17504
17519
|
*
|
|
17505
17520
|
* The ARN is unexpectedly absent only on a hypothetical SDK regression
|
|
17506
17521
|
* (`GetDistribution` returns ARN as a required string in every SDK
|
|
17507
17522
|
* shape verified so far). When that happens AND a tag delta exists,
|
|
17508
|
-
*
|
|
17509
|
-
*
|
|
17523
|
+
* THROW so the silent-drop does not silently resurface; when no delta
|
|
17524
|
+
* exists, return without needing ARN.
|
|
17510
17525
|
*/
|
|
17511
|
-
async
|
|
17526
|
+
async applyTagDiff(arn, previousTags, newTags, physicalId, logicalId, resourceType) {
|
|
17512
17527
|
const { removed, upserts } = this.computeTagDiff(previousTags, newTags);
|
|
17513
17528
|
if (removed.length === 0 && upserts.length === 0) return;
|
|
17514
|
-
if (!arn) {
|
|
17515
|
-
this.logger.warn(`CloudFront Distribution ${physicalId}: GetDistribution returned no ARN; skipping tag diff (removed=${removed.length}, upserts=${upserts.length}). Tags on AWS may drift from the template.`);
|
|
17516
|
-
return;
|
|
17517
|
-
}
|
|
17529
|
+
if (!arn) throw new ProvisioningError(`CloudFront Distribution ${physicalId}: GetDistribution returned no ARN; cannot apply tag diff (removed=${removed.length}, upserts=${upserts.length}). Refusing to silently drop the tag update — retry on next deploy or check SDK version.`, resourceType, logicalId, physicalId);
|
|
17518
17530
|
try {
|
|
17519
17531
|
if (removed.length > 0) {
|
|
17520
17532
|
this.logger.debug(`Untagging CloudFront Distribution ${arn}: ${removed.join(", ")}`);
|
|
@@ -17531,7 +17543,8 @@ var CloudFrontDistributionProvider = class {
|
|
|
17531
17543
|
}));
|
|
17532
17544
|
}
|
|
17533
17545
|
} catch (err) {
|
|
17534
|
-
|
|
17546
|
+
const cause = err instanceof Error ? err : void 0;
|
|
17547
|
+
throw new ProvisioningError(`CloudFront Distribution ${physicalId}: tag diff failed (removed=${removed.length}, upserts=${upserts.length}): ${err instanceof Error ? err.message : String(err)}. UpdateDistribution succeeded but TagResource/UntagResource did not — state has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
|
|
17535
17548
|
}
|
|
17536
17549
|
}
|
|
17537
17550
|
/**
|
|
@@ -32023,7 +32036,7 @@ var S3TablesProvider = class {
|
|
|
32023
32036
|
}
|
|
32024
32037
|
}
|
|
32025
32038
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
32026
|
-
if (resourceType === "AWS::S3Tables::Table") await this.applyTableTagsDiff(physicalId, previousProperties["Tags"], properties["Tags"]);
|
|
32039
|
+
if (resourceType === "AWS::S3Tables::Table") await this.applyTableTagsDiff(logicalId, physicalId, resourceType, previousProperties["Tags"], properties["Tags"]);
|
|
32027
32040
|
else this.logger.debug(`Update is no-op for ${resourceType} ${logicalId}`);
|
|
32028
32041
|
return {
|
|
32029
32042
|
physicalId,
|
|
@@ -32502,40 +32515,47 @@ var S3TablesProvider = class {
|
|
|
32502
32515
|
* value-only rewrite on key K isn't accidentally cleared by a stale
|
|
32503
32516
|
* UntagResource pass (matches the CloudFront / S3Vectors pattern).
|
|
32504
32517
|
*
|
|
32505
|
-
* Tag
|
|
32506
|
-
*
|
|
32507
|
-
*
|
|
32508
|
-
*
|
|
32509
|
-
|
|
32510
|
-
|
|
32511
|
-
|
|
32512
|
-
|
|
32513
|
-
|
|
32514
|
-
|
|
32515
|
-
|
|
32516
|
-
|
|
32517
|
-
|
|
32518
|
-
|
|
32519
|
-
|
|
32520
|
-
|
|
32518
|
+
* Tag-side failures THROW `ProvisioningError` (issue #740 fix): a
|
|
32519
|
+
* silent swallow would let the deploy engine write the new properties.Tags
|
|
32520
|
+
* to state as if applied, and the next deploy's diff (template Tags
|
|
32521
|
+
* vs new state Tags) sees no change → tag-diff never re-fires → AWS
|
|
32522
|
+
* tags stay stale forever. Throwing means: (a) state is NOT written,
|
|
32523
|
+
* (b) the next deploy retries the tag-diff against the still-old
|
|
32524
|
+
* state. The deploy engine's `withRetry` MAY pick up transient AWS
|
|
32525
|
+
* errors via the cause-message-pattern match in `retryable-errors.ts`,
|
|
32526
|
+
* but bare HTTP 429 throttles can slip past the classifier's
|
|
32527
|
+
* single-level `.cause` walk depending on wrapping — so the
|
|
32528
|
+
* **load-bearing retry guarantee is the next-deploy retry**, not
|
|
32529
|
+
* in-deploy retry. For the S3Tables Table case `update()` is
|
|
32530
|
+
* otherwise a no-op (the Table itself is immutable), so a tag-side
|
|
32531
|
+
* throw cleanly turns the whole update into a retry without
|
|
32532
|
+
* side-effects.
|
|
32533
|
+
*
|
|
32534
|
+
* The malformed-physicalId / GetTable-NotFound branches throw too
|
|
32535
|
+
* — both indicate a state-vs-AWS divergence the user needs to see,
|
|
32536
|
+
* not silently skip past.
|
|
32537
|
+
*/
|
|
32538
|
+
async applyTableTagsDiff(logicalId, physicalId, resourceType, previousTags, newTags) {
|
|
32521
32539
|
const prev = this.cfnTagsToSdkMap(previousTags) ?? {};
|
|
32522
32540
|
const next = this.cfnTagsToSdkMap(newTags) ?? {};
|
|
32523
32541
|
const removedKeys = Object.keys(prev).filter((k) => !(k in next));
|
|
32524
32542
|
const upserts = {};
|
|
32525
32543
|
for (const [k, v] of Object.entries(next)) if (prev[k] !== v) upserts[k] = v;
|
|
32526
32544
|
if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
|
|
32545
|
+
const parts = physicalId.split("|");
|
|
32546
|
+
if (parts.length < 3) throw new ProvisioningError(`applyTableTagsDiff: cannot derive table ARN from physicalId '${physicalId}' (expected '<bucketArn>|<namespace>|<name>') — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
|
|
32547
|
+
const [tableBucketARN, namespace, name] = parts;
|
|
32548
|
+
if (!tableBucketARN || !namespace || !name) throw new ProvisioningError(`applyTableTagsDiff: cannot derive table ARN from malformed physicalId '${physicalId}' (empty part after split) — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
|
|
32527
32549
|
const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
|
|
32528
|
-
if (!resourceArn) {
|
|
32529
|
-
this.logger.warn(`applyTableTagsDiff: GetTable returned no tableARN for ${physicalId} — skipping tag-diff (table gone? state out-of-sync?)`);
|
|
32530
|
-
return;
|
|
32531
|
-
}
|
|
32550
|
+
if (!resourceArn) throw new ProvisioningError(`applyTableTagsDiff: GetTable returned no tableARN for ${physicalId} — table is gone or state is out-of-sync. Refusing to silently drop the tag update (run 'cdkd state orphan ${logicalId}' to clean up if the table was deleted out-of-band).`, resourceType, logicalId, physicalId);
|
|
32532
32551
|
if (removedKeys.length > 0) try {
|
|
32533
32552
|
await this.getClient().send(new UntagResourceCommand$15({
|
|
32534
32553
|
resourceArn,
|
|
32535
32554
|
tagKeys: removedKeys
|
|
32536
32555
|
}));
|
|
32537
32556
|
} catch (err) {
|
|
32538
|
-
|
|
32557
|
+
const cause = err instanceof Error ? err : void 0;
|
|
32558
|
+
throw new ProvisioningError(`applyTableTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
|
|
32539
32559
|
}
|
|
32540
32560
|
if (Object.keys(upserts).length > 0) try {
|
|
32541
32561
|
await this.getClient().send(new TagResourceCommand$16({
|
|
@@ -32543,7 +32563,8 @@ var S3TablesProvider = class {
|
|
|
32543
32563
|
tags: upserts
|
|
32544
32564
|
}));
|
|
32545
32565
|
} catch (err) {
|
|
32546
|
-
|
|
32566
|
+
const cause = err instanceof Error ? err : void 0;
|
|
32567
|
+
throw new ProvisioningError(`applyTableTagsDiff: TagResource failed for ${resourceArn} (keys: ${Object.keys(upserts).join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
|
|
32547
32568
|
}
|
|
32548
32569
|
}
|
|
32549
32570
|
};
|
|
@@ -51856,7 +51877,7 @@ function reorderArgs(argv) {
|
|
|
51856
51877
|
*/
|
|
51857
51878
|
async function main() {
|
|
51858
51879
|
const program = new Command();
|
|
51859
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.201.
|
|
51880
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.201.1");
|
|
51860
51881
|
program.addCommand(createBootstrapCommand());
|
|
51861
51882
|
program.addCommand(createSynthCommand());
|
|
51862
51883
|
program.addCommand(createListCommand());
|