@go-to-k/cdkd 0.278.32 → 0.278.34
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-DLlrKwbd.js → asg-provider-Cta08VYI.js} +2 -2
- package/dist/{asg-provider-DLlrKwbd.js.map → asg-provider-Cta08VYI.js.map} +1 -1
- package/dist/cli.js +201 -48
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-CEVFHtcP.js → deploy-engine-Dp2u4Ktr.js} +3 -3
- package/dist/{deploy-engine-CEVFHtcP.js.map → deploy-engine-Dp2u4Ktr.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as withRetry, $t as getAwsClients, A as red, At as synthesisStatusMessage, B as isTerminationProtectionPropagationError, Bt as stateBucketExistenceConfirmed, C as isStatefulRecreateTargetSync, Cn as normalizeAwsError, Ct as formatDockerLoginError, D as cyan, Dt as AssetManifestLoader, E as bold, Et as runDockerStreaming, F as ProviderRegistry, Ft as resolveCaptureObservedState, G as normalizeAwsTagsToCfn, Gt as findLargeInlineResources, H as cfnRefValueFromPhysicalId, Ht as CFN_TEMPLATE_BODY_LIMIT, I as findActionableSilentDrops, It as resolveSkipPrefix, J as readConfigString, Jt as AssemblyReader, K as resolveExplicitPhysicalId, Kt as uploadCfnTemplate, L as CloudControlProvider, Lt as resolveStateBucketWithDefault, M as IAMRoleProvider, Mt as getLegacyStateBucketName, N as collectInlinePolicyNamesManagedBySiblings, Nt as resolveApp, O as gray, Ot as getDockerImageBySourceHash, P as clearOnUpdateRemoval, Pt as resolveAutoAssetStorage, Q as describeTypeWithThrottleRetry, Qt as AwsClients, R as slowCcOperationTimeoutMs, Rt as resolveStateBucketWithDefaultAndSource, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as buildDockerImage, T as formatResourceLine, Tt as runDockerForeground, U as refStateLookupFromResource, Ut as CFN_TEMPLATE_URL_LIMIT, V as IntrinsicFunctionResolver, Vt as warnDeprecatedNoPrefixCliFlag, W as WAFv2WebACLProvider, Wt as MIGRATE_TMP_PREFIX, X as applyRoleArnIfSet, Y as requireConfigString, Yt as processStackMessages, Z as DiffCalculator, Zt as resolveBucketRegion, _ as createPreDeleteFinalSnapshot, _n as StackHasActiveImportsError, _t as ensureAssetStorage, a as DeploymentEventsStore, at as S3StateBackend, b as unsupportedFinalSnapshotError, bt as validateAssetBucketName, c as replayFailedOperations, cn as LocalMigrateError, ct as AssetPublisher, d as IMPLICIT_DELETE_DEPENDENCIES, dn as MissingCdkCliError, dt as buildAssetRedirectMap, en as resetAwsClients, et as isRetryableTransientError, f as computeImplicitDeleteEdges, fn as NestedStackChildDirectDestroyError, ft as createAssetRedirectResolver, g as ccRoutedFinalSnapshotError, gn as ResourceUpdateNotSupportedError, gt as BOOTSTRAP_MARKER_PREFIX, h as buildFinalSnapshotIdentifier, hn as ResourceTimeoutError, ht as AssetModeResolver, i as DeploymentEventsReader, it as LockManager, j as yellow, jt as getDefaultStateBucketName, k as green, kt as Synthesizer, l as replayRollback, ln as LocalStartServiceError, lt as stringifyValue, m as PRE_DELETE_SNAPSHOT_TYPES, mn as ProvisioningError, mt as rewriteTemplateAssetReferences, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as DagBuilder, o as planFailedOps, on as DeployCancelledError, ot as rebuildClientForBucketRegion, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as PartialFailureError, pt as loadPublishableAssetManifest, q as assertRegionMatch, qt as expectedOwnerParam, r as DeployEngine, rn as CdkdError, rt as TemplateParser, s as planRollback, sn as LocalInvokeBuildError$1, st as shouldRetainResource, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as setAwsClients, tt as isThrottlingError, u as withResourceDeadline, ut as WorkGraph, v as isFinalSnapshotError, vn as StackTerminationProtectionError, vt as getBootstrapMarkerKey, w as renderStatefulReason, wn as withErrorHandling, wt as getDockerCmd, x as extractDeploymentEventError, xt as validateContainerRepoName, y as refusesFinalSnapshot, yt as parseBootstrapMarker, z as disableInstanceApiTermination, zt as resolveUseCdkBootstrapAssets } from "./deploy-engine-
|
|
2
|
+
import { $ as withRetry, $t as getAwsClients, A as red, At as synthesisStatusMessage, B as isTerminationProtectionPropagationError, Bt as stateBucketExistenceConfirmed, C as isStatefulRecreateTargetSync, Cn as normalizeAwsError, Ct as formatDockerLoginError, D as cyan, Dt as AssetManifestLoader, E as bold, Et as runDockerStreaming, F as ProviderRegistry, Ft as resolveCaptureObservedState, G as normalizeAwsTagsToCfn, Gt as findLargeInlineResources, H as cfnRefValueFromPhysicalId, Ht as CFN_TEMPLATE_BODY_LIMIT, I as findActionableSilentDrops, It as resolveSkipPrefix, J as readConfigString, Jt as AssemblyReader, K as resolveExplicitPhysicalId, Kt as uploadCfnTemplate, L as CloudControlProvider, Lt as resolveStateBucketWithDefault, M as IAMRoleProvider, Mt as getLegacyStateBucketName, N as collectInlinePolicyNamesManagedBySiblings, Nt as resolveApp, O as gray, Ot as getDockerImageBySourceHash, P as clearOnUpdateRemoval, Pt as resolveAutoAssetStorage, Q as describeTypeWithThrottleRetry, Qt as AwsClients, R as slowCcOperationTimeoutMs, Rt as resolveStateBucketWithDefaultAndSource, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as buildDockerImage, T as formatResourceLine, Tt as runDockerForeground, U as refStateLookupFromResource, Ut as CFN_TEMPLATE_URL_LIMIT, V as IntrinsicFunctionResolver, Vt as warnDeprecatedNoPrefixCliFlag, W as WAFv2WebACLProvider, Wt as MIGRATE_TMP_PREFIX, X as applyRoleArnIfSet, Y as requireConfigString, Yt as processStackMessages, Z as DiffCalculator, Zt as resolveBucketRegion, _ as createPreDeleteFinalSnapshot, _n as StackHasActiveImportsError, _t as ensureAssetStorage, a as DeploymentEventsStore, at as S3StateBackend, b as unsupportedFinalSnapshotError, bt as validateAssetBucketName, c as replayFailedOperations, cn as LocalMigrateError, ct as AssetPublisher, d as IMPLICIT_DELETE_DEPENDENCIES, dn as MissingCdkCliError, dt as buildAssetRedirectMap, en as resetAwsClients, et as isRetryableTransientError, f as computeImplicitDeleteEdges, fn as NestedStackChildDirectDestroyError, ft as createAssetRedirectResolver, g as ccRoutedFinalSnapshotError, gn as ResourceUpdateNotSupportedError, gt as BOOTSTRAP_MARKER_PREFIX, h as buildFinalSnapshotIdentifier, hn as ResourceTimeoutError, ht as AssetModeResolver, i as DeploymentEventsReader, it as LockManager, j as yellow, jt as getDefaultStateBucketName, k as green, kt as Synthesizer, l as replayRollback, ln as LocalStartServiceError, lt as stringifyValue, m as PRE_DELETE_SNAPSHOT_TYPES, mn as ProvisioningError, mt as rewriteTemplateAssetReferences, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as DagBuilder, o as planFailedOps, on as DeployCancelledError, ot as rebuildClientForBucketRegion, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as PartialFailureError, pt as loadPublishableAssetManifest, q as assertRegionMatch, qt as expectedOwnerParam, r as DeployEngine, rn as CdkdError, rt as TemplateParser, s as planRollback, sn as LocalInvokeBuildError$1, st as shouldRetainResource, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as setAwsClients, tt as isThrottlingError, u as withResourceDeadline, ut as WorkGraph, v as isFinalSnapshotError, vn as StackTerminationProtectionError, vt as getBootstrapMarkerKey, w as renderStatefulReason, wn as withErrorHandling, wt as getDockerCmd, x as extractDeploymentEventError, xt as validateContainerRepoName, y as refusesFinalSnapshot, yt as parseBootstrapMarker, z as disableInstanceApiTermination, zt as resolveUseCdkBootstrapAssets } from "./deploy-engine-Dp2u4Ktr.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-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-Cta08VYI.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";
|
|
@@ -33886,6 +33886,8 @@ var GlueProvider = class {
|
|
|
33886
33886
|
result.StorageDescriptor = this.buildStorageDescriptor(sd);
|
|
33887
33887
|
}
|
|
33888
33888
|
if (tableInput["PartitionKeys"] !== void 0) result.PartitionKeys = tableInput["PartitionKeys"];
|
|
33889
|
+
if (tableInput["TargetTable"] !== void 0) result.TargetTable = tableInput["TargetTable"];
|
|
33890
|
+
if (tableInput["ViewDefinition"] !== void 0) result.ViewDefinition = tableInput["ViewDefinition"];
|
|
33889
33891
|
return result;
|
|
33890
33892
|
}
|
|
33891
33893
|
/**
|
|
@@ -33901,18 +33903,30 @@ var GlueProvider = class {
|
|
|
33901
33903
|
if (sd["NumberOfBuckets"] !== void 0) result.NumberOfBuckets = sd["NumberOfBuckets"];
|
|
33902
33904
|
if (sd["SerdeInfo"] !== void 0) {
|
|
33903
33905
|
const serde = sd["SerdeInfo"];
|
|
33904
|
-
if (serde["Parameters"]) {
|
|
33905
|
-
|
|
33906
|
-
|
|
33907
|
-
|
|
33908
|
-
|
|
33909
|
-
}
|
|
33910
|
-
result.SerdeInfo = serde;
|
|
33906
|
+
if (serde["Parameters"]) result.SerdeInfo = {
|
|
33907
|
+
...serde,
|
|
33908
|
+
Parameters: stringifyParameterValues(serde["Parameters"])
|
|
33909
|
+
};
|
|
33910
|
+
else result.SerdeInfo = serde;
|
|
33911
33911
|
}
|
|
33912
33912
|
if (sd["BucketColumns"] !== void 0) result.BucketColumns = sd["BucketColumns"];
|
|
33913
33913
|
if (sd["SortColumns"] !== void 0) result.SortColumns = sd["SortColumns"];
|
|
33914
33914
|
if (sd["Parameters"] !== void 0) result.Parameters = sd["Parameters"];
|
|
33915
33915
|
if (sd["StoredAsSubDirectories"] !== void 0) result.StoredAsSubDirectories = sd["StoredAsSubDirectories"];
|
|
33916
|
+
if (sd["SkewedInfo"] !== void 0) {
|
|
33917
|
+
const skewed = asRecord(sd["SkewedInfo"]) ?? {};
|
|
33918
|
+
result.SkewedInfo = skewed["SkewedColumnValueLocationMaps"] !== void 0 ? {
|
|
33919
|
+
...skewed,
|
|
33920
|
+
SkewedColumnValueLocationMaps: stringifyParameterValues(skewed["SkewedColumnValueLocationMaps"])
|
|
33921
|
+
} : skewed;
|
|
33922
|
+
}
|
|
33923
|
+
if (sd["SchemaReference"] !== void 0) {
|
|
33924
|
+
const schemaRef = asRecord(sd["SchemaReference"]) ?? {};
|
|
33925
|
+
result.SchemaReference = schemaRef["SchemaVersionNumber"] !== void 0 ? {
|
|
33926
|
+
...schemaRef,
|
|
33927
|
+
SchemaVersionNumber: coerceNumber(schemaRef["SchemaVersionNumber"])
|
|
33928
|
+
} : schemaRef;
|
|
33929
|
+
}
|
|
33916
33930
|
return result;
|
|
33917
33931
|
}
|
|
33918
33932
|
/**
|
|
@@ -34843,7 +34857,9 @@ function buildJobCommonFields(p) {
|
|
|
34843
34857
|
*/
|
|
34844
34858
|
function stringifyParameterValues(raw) {
|
|
34845
34859
|
const params = {};
|
|
34846
|
-
|
|
34860
|
+
const source = asRecord(raw);
|
|
34861
|
+
if (source === void 0) return params;
|
|
34862
|
+
for (const [k, v] of Object.entries(source)) params[k] = String(v);
|
|
34847
34863
|
return params;
|
|
34848
34864
|
}
|
|
34849
34865
|
/**
|
|
@@ -49243,48 +49259,128 @@ async function runAccept(reports, stateBackend, stateConfig, awsClients, options
|
|
|
49243
49259
|
}
|
|
49244
49260
|
}
|
|
49245
49261
|
/**
|
|
49246
|
-
*
|
|
49247
|
-
* `--revert`. Strategy:
|
|
49262
|
+
* A top-level property NAME that carries tags.
|
|
49248
49263
|
*
|
|
49249
|
-
*
|
|
49250
|
-
*
|
|
49251
|
-
*
|
|
49252
|
-
*
|
|
49253
|
-
*
|
|
49254
|
-
*
|
|
49264
|
+
* The shape test below is deliberately NOT sufficient on its own: a top-level
|
|
49265
|
+
* `[{ Key, Value }]` list is not tag-exclusive — `LoadBalancerAttributes`,
|
|
49266
|
+
* `TargetGroupAttributes` and SSM `Association.Targets` all match it. No such
|
|
49267
|
+
* property can carry an `aws:`-prefixed or `AmazonECSManaged` key today, so the
|
|
49268
|
+
* carve-out would degrade to the identity of the old wholesale overwrite there
|
|
49269
|
+
* — but borrowing `canonicalizeTagListsDeep`'s heuristic for a WRITE decision
|
|
49270
|
+
* is not justified by its use for a SORT: a sort false positive is harmless, an
|
|
49271
|
+
* append is not.
|
|
49272
|
+
*/
|
|
49273
|
+
function isTagListKey(key) {
|
|
49274
|
+
return key === "Tags" || key.endsWith("Tags");
|
|
49275
|
+
}
|
|
49276
|
+
/** A CFn-shaped tag list: a non-empty array whose every element has a string `Key`. */
|
|
49277
|
+
function isCfnTagList(value) {
|
|
49278
|
+
return Array.isArray(value) && value.length > 0 && value.every((t) => isPlainRecord(t) && typeof t.Key === "string");
|
|
49279
|
+
}
|
|
49280
|
+
/** The `Key` of every entry in a CFn tag list, in list order. */
|
|
49281
|
+
function tagKeys(tags) {
|
|
49282
|
+
return tags.map((t) => t["Key"]);
|
|
49283
|
+
}
|
|
49284
|
+
/**
|
|
49285
|
+
* AWS-SERVICE-authored tag keys a `--revert` must not strip (issue #1501).
|
|
49255
49286
|
*
|
|
49256
|
-
*
|
|
49257
|
-
*
|
|
49287
|
+
* `AmazonECSManaged` is attached by ECS when a capacity provider binds an Auto
|
|
49288
|
+
* Scaling group, and managed scaling stops working without it. That entry is
|
|
49289
|
+
* the load-bearing one.
|
|
49258
49290
|
*
|
|
49259
|
-
*
|
|
49260
|
-
*
|
|
49261
|
-
*
|
|
49262
|
-
*
|
|
49263
|
-
*
|
|
49264
|
-
*
|
|
49265
|
-
|
|
49266
|
-
|
|
49267
|
-
|
|
49268
|
-
|
|
49269
|
-
|
|
49291
|
+
* The `aws:` prefix is DEFENSIVE rather than load-bearing, and the distinction
|
|
49292
|
+
* is worth stating: AWS reserves the prefix and rejects a write of one, and the
|
|
49293
|
+
* 45 providers that route reads through `normalizeAwsTagsToCfn` strip such keys
|
|
49294
|
+
* on the way in — so an `aws:` key can only reach the AWS side of a comparison
|
|
49295
|
+
* via the Cloud Control `readCurrentState` path, which returns the raw model.
|
|
49296
|
+
* It costs nothing to honor and cdkd can never have authored one.
|
|
49297
|
+
*/
|
|
49298
|
+
const SERVICE_MANAGED_TAG_KEYS = /* @__PURE__ */ new Set(["AmazonECSManaged"]);
|
|
49299
|
+
/** Whether a tag key is AWS-service-authored, per {@link SERVICE_MANAGED_TAG_KEYS}. */
|
|
49300
|
+
function isServiceManagedTagKey(key) {
|
|
49301
|
+
return SERVICE_MANAGED_TAG_KEYS.has(key) || key.startsWith("aws:");
|
|
49302
|
+
}
|
|
49303
|
+
/**
|
|
49304
|
+
* Revert a TAG LIST, preserving AWS-SERVICE-authored entries (issue #1501).
|
|
49270
49305
|
*
|
|
49271
|
-
*
|
|
49272
|
-
*
|
|
49273
|
-
*
|
|
49274
|
-
*
|
|
49275
|
-
*
|
|
49276
|
-
*
|
|
49277
|
-
*
|
|
49278
|
-
*
|
|
49279
|
-
*
|
|
49280
|
-
*
|
|
49281
|
-
*
|
|
49306
|
+
* Everything in {@link buildRevertNewProperties} overwrites a drifted top-level
|
|
49307
|
+
* key wholesale, which for `Tags` means "AWS ends up with exactly the tags cdkd
|
|
49308
|
+
* state recorded" — so a service-authored tag added after deploy is stripped.
|
|
49309
|
+
* The concrete case: ECS attaches `AmazonECSManaged` to an ASG when a capacity
|
|
49310
|
+
* provider binds it, and that tag is REQUIRED for managed scaling. Because any
|
|
49311
|
+
* CDK ASG declares at least a `Name` tag, `Tags` is template-DECLARED, so the
|
|
49312
|
+
* #1498 carve-out (undeclared + captured-empty) correctly does not apply — and
|
|
49313
|
+
* the tag list is an ARRAY, which {@link findRevertDroppedAwsKeys}'s walk
|
|
49314
|
+
* compares wholesale and never descends into. Post-revert the ASG kept the
|
|
49315
|
+
* capacity provider with its managed scaling silently broken (verified live
|
|
49316
|
+
* 2026-08-10).
|
|
49282
49317
|
*
|
|
49283
|
-
* The
|
|
49284
|
-
*
|
|
49285
|
-
*
|
|
49286
|
-
*
|
|
49318
|
+
* The semantic: the baseline still WINS for every ordinary tag — one it has and
|
|
49319
|
+
* AWS lost is re-added, one whose value differs is reset, and a
|
|
49320
|
+
* user/console-added tag AWS alone has is still REMOVED. Only a
|
|
49321
|
+
* {@link isServiceManagedTagKey} entry survives.
|
|
49322
|
+
*
|
|
49323
|
+
* **This is the issue's option 2, not its option 1, and the choice was settled
|
|
49324
|
+
* by a live test rather than by taste.** Option 1 (revert the whole tag list as
|
|
49325
|
+
* a diff, so ANY out-of-band add survives) was implemented first and failed the
|
|
49326
|
+
* `drift-revert` integ at its final assertion: that fixture injects an
|
|
49327
|
+
* `IntegInjected` tag and requires `--revert` to strip it, i.e. "revert removes
|
|
49328
|
+
* a console-added tag" is an established contract with a test behind it.
|
|
49329
|
+
* Option 1 would redefine revert semantics for a whole property class — which
|
|
49330
|
+
* is exactly the design pass the issue said it needed — so the narrow safeguard
|
|
49331
|
+
* ships instead, fixing the reported breakage while leaving ordinary tag revert
|
|
49332
|
+
* untouched.
|
|
49333
|
+
*
|
|
49334
|
+
* Scope: TOP-LEVEL tag lists, which is where `buildRevertNewProperties`
|
|
49335
|
+
* operates. A tag list nested inside another property (an EC2 launch template's
|
|
49336
|
+
* `TagSpecifications`) still reverts wholesale.
|
|
49337
|
+
*
|
|
49338
|
+
* Order: baseline entries first in baseline order, then the preserved
|
|
49339
|
+
* service-managed entries. Providers apply tags as a set and the drift
|
|
49340
|
+
* comparator canonicalizes tag-list order on both sides
|
|
49341
|
+
* (`drift-normalize.ts`), so the order is for readability / determinism only.
|
|
49287
49342
|
*/
|
|
49343
|
+
function mergeTagListForRevert(baselineTags, awsTags) {
|
|
49344
|
+
const baselineKeys = new Set(tagKeys(baselineTags));
|
|
49345
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49346
|
+
const preserved = awsTags.filter((t) => {
|
|
49347
|
+
const key = t["Key"];
|
|
49348
|
+
if (baselineKeys.has(key) || !isServiceManagedTagKey(key) || seen.has(key)) return false;
|
|
49349
|
+
seen.add(key);
|
|
49350
|
+
return true;
|
|
49351
|
+
});
|
|
49352
|
+
return [...baselineTags, ...preserved];
|
|
49353
|
+
}
|
|
49354
|
+
/**
|
|
49355
|
+
* The AWS-service-authored tag keys a `--revert` will PRESERVE rather than
|
|
49356
|
+
* strip, i.e. those present on the AWS side of a drifted top-level tag list,
|
|
49357
|
+
* absent from the revert baseline, and {@link isServiceManagedTagKey} (issue
|
|
49358
|
+
* #1501).
|
|
49359
|
+
*
|
|
49360
|
+
* Reported in the plan so the carve-out of {@link mergeTagListForRevert} is
|
|
49361
|
+
* visible BEFORE the confirmation prompt: a user who did want the tag gone
|
|
49362
|
+
* learns here that the revert will not do it.
|
|
49363
|
+
*
|
|
49364
|
+
* @returns dotted `<Key>.<TagKey>` paths, sorted, e.g. `['Tags.AmazonECSManaged']`.
|
|
49365
|
+
*/
|
|
49366
|
+
function findRevertPreservedTagKeys(drifts, desiredProperties, awsProperties) {
|
|
49367
|
+
const preserved = /* @__PURE__ */ new Set();
|
|
49368
|
+
const driftedTopLevelKeys = /* @__PURE__ */ new Set();
|
|
49369
|
+
for (const d of drifts) {
|
|
49370
|
+
const topLevelKey = d.path.split(".", 1)[0];
|
|
49371
|
+
if (topLevelKey) driftedTopLevelKeys.add(topLevelKey);
|
|
49372
|
+
}
|
|
49373
|
+
for (const key of driftedTopLevelKeys) {
|
|
49374
|
+
if (!(key in desiredProperties)) continue;
|
|
49375
|
+
if (!isTagListKey(key)) continue;
|
|
49376
|
+
const desiredValue = desiredProperties[key];
|
|
49377
|
+
const awsValue = awsProperties[key];
|
|
49378
|
+
if (!(isCfnTagList(desiredValue) || Array.isArray(desiredValue) && desiredValue.length === 0) || !isCfnTagList(awsValue)) continue;
|
|
49379
|
+
const baselineKeys = new Set(tagKeys(desiredValue));
|
|
49380
|
+
for (const tagKey of tagKeys(awsValue)) if (!baselineKeys.has(tagKey) && isServiceManagedTagKey(tagKey)) preserved.add(`${key}.${tagKey}`);
|
|
49381
|
+
}
|
|
49382
|
+
return [...preserved].sort();
|
|
49383
|
+
}
|
|
49288
49384
|
/**
|
|
49289
49385
|
* The AWS-authored property paths a `--revert` is about to DROP, for a
|
|
49290
49386
|
* resource whose state predates observed-capture (issue #1478).
|
|
@@ -49361,12 +49457,60 @@ function collectMissingPaths(awsValue, desiredValue, path, out) {
|
|
|
49361
49457
|
function isPlainRecord(value) {
|
|
49362
49458
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49363
49459
|
}
|
|
49460
|
+
/**
|
|
49461
|
+
* Build the `newProperties` object passed to `provider.update` during
|
|
49462
|
+
* `--revert`. Strategy:
|
|
49463
|
+
*
|
|
49464
|
+
* 1. Start from `awsProperties` (the AWS-current snapshot returned
|
|
49465
|
+
* by `readCurrentState`, which `runRevert` already passes as the
|
|
49466
|
+
* `previousProperties` argument to `provider.update`).
|
|
49467
|
+
* 2. For every top-level key whose subtree contains a drifted path,
|
|
49468
|
+
* overwrite it with the corresponding sub-shape from
|
|
49469
|
+
* `desiredProperties` (the state-recorded `observedProperties`).
|
|
49470
|
+
*
|
|
49471
|
+
* Why "AWS-current base + drifted overlay" instead of "drifted-only
|
|
49472
|
+
* partial":
|
|
49473
|
+
*
|
|
49474
|
+
* Several providers' `update()` implementations diff
|
|
49475
|
+
* `newProperties[K]` against `previousProperties[K]` and treat
|
|
49476
|
+
* `newVal === undefined` as "remove K from AWS" (e.g.
|
|
49477
|
+
* `SNSTopicProvider` calls `SetTopicAttributes(K, '')`,
|
|
49478
|
+
* `IAMRoleProvider.updateManagedPolicies` detaches every previously
|
|
49479
|
+
* attached policy when the new arg is undefined). Passing a
|
|
49480
|
+
* drifted-only partial would silently clear non-drifted attributes
|
|
49481
|
+
* on those providers. Sending the AWS-current value back as the
|
|
49482
|
+
* "new" value for non-drifted keys keeps `JSON.stringify(newVal) ===
|
|
49483
|
+
* JSON.stringify(oldVal)` so the diff is a no-op — no provider
|
|
49484
|
+
* changes required.
|
|
49485
|
+
*
|
|
49486
|
+
* For non-diff providers (e.g. `SQSQueueProvider` blindly pushes
|
|
49487
|
+
* every defined key via `SetQueueAttributes`), the AWS-current
|
|
49488
|
+
* value still gets serialised back to the same string AWS already
|
|
49489
|
+
* has, so the round-trip is a no-op for the AWS resource state.
|
|
49490
|
+
* The one exception is `readCurrentState`'s always-emit
|
|
49491
|
+
* placeholder values — e.g. SQS `RedrivePolicy: {}` — which AWS
|
|
49492
|
+
* rejects as invalid input even though they're round-tripped. That
|
|
49493
|
+
* class of value (Class 2 / structurally-incomplete-when-empty) is
|
|
49494
|
+
* handled by per-provider sanitize at the wire-layer; see the SQS
|
|
49495
|
+
* provider's `serializeRedrivePolicy` helper for the canonical
|
|
49496
|
+
* pattern.
|
|
49497
|
+
*
|
|
49498
|
+
* The drift comparator never produces array-index segments
|
|
49499
|
+
* (`Tags[0].Value`) — array drifts surface as a single entry on the
|
|
49500
|
+
* parent path — so `path.split('.', 1)` is always safe to extract the
|
|
49501
|
+
* top-level key.
|
|
49502
|
+
*/
|
|
49364
49503
|
function buildRevertNewProperties(drifts, desiredProperties, awsProperties) {
|
|
49365
49504
|
const result = { ...awsProperties };
|
|
49366
49505
|
for (const d of drifts) {
|
|
49367
49506
|
const topLevelKey = d.path.split(".", 1)[0];
|
|
49368
49507
|
if (!topLevelKey) continue;
|
|
49369
|
-
if (topLevelKey in desiredProperties)
|
|
49508
|
+
if (topLevelKey in desiredProperties) {
|
|
49509
|
+
const desiredValue = desiredProperties[topLevelKey];
|
|
49510
|
+
const awsValue = awsProperties[topLevelKey];
|
|
49511
|
+
const baselineIsTagList = isCfnTagList(desiredValue) || Array.isArray(desiredValue) && desiredValue.length === 0;
|
|
49512
|
+
result[topLevelKey] = isTagListKey(topLevelKey) && baselineIsTagList && isCfnTagList(awsValue) ? mergeTagListForRevert(desiredValue, awsValue) : desiredValue;
|
|
49513
|
+
}
|
|
49370
49514
|
}
|
|
49371
49515
|
return result;
|
|
49372
49516
|
}
|
|
@@ -49489,6 +49633,15 @@ function printRevertPlan(reports) {
|
|
|
49489
49633
|
process.stdout.write(` → provider.update on ${o.logicalId} (${o.resourceType}): revert ${o.changes.length} ${word}\n`);
|
|
49490
49634
|
for (const change of o.changes) process.stdout.write(` ${change.path}: ${formatScalar(change.awsValue)} -> ${formatScalar(change.stateValue)}\n`);
|
|
49491
49635
|
const stateResource = report.state.resources[o.logicalId];
|
|
49636
|
+
if (stateResource) {
|
|
49637
|
+
const preserved = findRevertPreservedTagKeys(o.changes, stateResource.observedProperties ?? stateResource.properties ?? {}, o.awsProperties);
|
|
49638
|
+
if (preserved.length > 0) {
|
|
49639
|
+
const tagWord = preserved.length === 1 ? "tag" : "tags";
|
|
49640
|
+
process.stdout.write(` ! reverting this tag list KEEPS ${preserved.length} AWS-authored ${tagWord} the baseline does not carry:\n`);
|
|
49641
|
+
for (const path of preserved) process.stdout.write(` ${path}\n`);
|
|
49642
|
+
process.stdout.write(" Every other tag reverts normally. A service may require these (ECS needs AmazonECSManaged for managed scaling); 'aws:'-prefixed keys are AWS-reserved and cannot be removed by hand.\n");
|
|
49643
|
+
}
|
|
49644
|
+
}
|
|
49492
49645
|
if (stateResource && stateResource.observedProperties === void 0) {
|
|
49493
49646
|
const dropped = findRevertDroppedAwsKeys(o.changes, stateResource.properties ?? {}, o.awsProperties);
|
|
49494
49647
|
if (dropped.length > 0) {
|
|
@@ -66447,7 +66600,7 @@ function createMigrateCommand() {
|
|
|
66447
66600
|
*/
|
|
66448
66601
|
function buildProgram() {
|
|
66449
66602
|
const program = new Command();
|
|
66450
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.
|
|
66603
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.34");
|
|
66451
66604
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
66452
66605
|
const { profile } = actionCommand.optsWithGlobals();
|
|
66453
66606
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|