@go-to-k/cdkd 0.280.22 → 0.280.24
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-DVoWhe5E.js → asg-provider-Dpx4B6UA.js} +2 -2
- package/dist/{asg-provider-DVoWhe5E.js.map → asg-provider-Dpx4B6UA.js.map} +1 -1
- package/dist/cli.js +122 -26
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-DObU-2va.js → deploy-engine-60FIug-P.js} +74 -14
- package/dist/deploy-engine-60FIug-P.js.map +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-DObU-2va.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 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-60FIug-P.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-Dpx4B6UA.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";
|
|
@@ -4984,7 +4984,14 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
4984
4984
|
/**
|
|
4985
4985
|
* Apply versioning configuration if specified
|
|
4986
4986
|
*/
|
|
4987
|
-
async applyVersioning(bucketName, versioningConfig) {
|
|
4987
|
+
async applyVersioning(bucketName, versioningConfig, onUnusable) {
|
|
4988
|
+
if (onUnusable) {
|
|
4989
|
+
const refusal = configStringRefusal(versioningConfig, "Status", "Suspended", "AWS::S3::Bucket VersioningConfiguration");
|
|
4990
|
+
if (refusal !== void 0) {
|
|
4991
|
+
onUnusable(`${refusal}. No PutBucketVersioning is issued rather than applying the Suspended default, which would turn object versioning OFF on an existing bucket (on a replayed create it means the bucket is left unversioned); the same value is REFUSED on a template-path create`);
|
|
4992
|
+
return;
|
|
4993
|
+
}
|
|
4994
|
+
}
|
|
4988
4995
|
const status = readConfigString(versioningConfig, "Status", "Suspended", "AWS::S3::Bucket VersioningConfiguration");
|
|
4989
4996
|
await this.s3Client.send(new PutBucketVersioningCommand({
|
|
4990
4997
|
Bucket: bucketName,
|
|
@@ -5262,7 +5269,14 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5262
5269
|
* - LogFilePrefix -> SDK TargetPrefix
|
|
5263
5270
|
* SDK: PutBucketLogging with BucketLoggingStatus.LoggingEnabled
|
|
5264
5271
|
*/
|
|
5265
|
-
async applyLoggingConfiguration(bucketName, loggingConfig) {
|
|
5272
|
+
async applyLoggingConfiguration(bucketName, loggingConfig, onUnusable) {
|
|
5273
|
+
if (onUnusable) {
|
|
5274
|
+
const refusal = configStringRefusal(loggingConfig, "DestinationBucketName", "", "AWS::S3::Bucket LoggingConfiguration") ?? configStringRefusal(loggingConfig, "LogFilePrefix", "", "AWS::S3::Bucket LoggingConfiguration");
|
|
5275
|
+
if (refusal !== void 0) {
|
|
5276
|
+
onUnusable(`${refusal}. No PutBucketLogging is issued rather than clearing access logging, which would turn it OFF on an existing bucket (on a replayed create it means the bucket comes up with no access logging); the same value is REFUSED on a template-path create`);
|
|
5277
|
+
return;
|
|
5278
|
+
}
|
|
5279
|
+
}
|
|
5266
5280
|
const destinationBucket = readConfigString(loggingConfig, "DestinationBucketName", "", "AWS::S3::Bucket LoggingConfiguration");
|
|
5267
5281
|
if (!loggingConfig || destinationBucket === "") {
|
|
5268
5282
|
await this.s3Client.send(new PutBucketLoggingCommand({
|
|
@@ -5589,11 +5603,20 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5589
5603
|
const s3Dest = this.resolveS3BucketDestination(rawDest, inventoryDestPath, onUnusable);
|
|
5590
5604
|
if (s3Dest === void 0 && rawDest != null) continue;
|
|
5591
5605
|
const destPath = s3BucketDestinationPath(rawDest, inventoryDestPath);
|
|
5606
|
+
const scheduleFrequencyRefusal = onUnusable ? configStringRefusal(config, "ScheduleFrequency", "Weekly", "AWS::S3::Bucket InventoryConfigurations[]") : void 0;
|
|
5607
|
+
if (scheduleFrequencyRefusal !== void 0 && config["Schedule"] == null) {
|
|
5608
|
+
onUnusable?.(`${scheduleFrequencyRefusal}. Skipping this inventory configuration: there is no Schedule.Frequency to fall back to, and defaulting to Weekly would silently re-cadence a live inventory report; the same value is REFUSED on a template-path create`);
|
|
5609
|
+
continue;
|
|
5610
|
+
}
|
|
5611
|
+
if (scheduleFrequencyRefusal !== void 0) onUnusable?.(`${scheduleFrequencyRefusal}. Falling back to Schedule.Frequency; the same value is REFUSED on a template-path create`);
|
|
5612
|
+
const useScheduleFrequency = config["ScheduleFrequency"] !== void 0 && scheduleFrequencyRefusal === void 0;
|
|
5613
|
+
if (!useScheduleFrequency && this.skipOnUnusableConfigString(config["Schedule"], "Frequency", "Weekly", "AWS::S3::Bucket InventoryConfigurations[].Schedule", "Skipping this inventory configuration", onUnusable)) continue;
|
|
5614
|
+
const frequency = useScheduleFrequency ? requireConfigString(config["ScheduleFrequency"], "Weekly", "AWS::S3::Bucket InventoryConfigurations[].ScheduleFrequency") : readConfigString(config["Schedule"], "Frequency", "Weekly", "AWS::S3::Bucket InventoryConfigurations[].Schedule");
|
|
5592
5615
|
const inventoryConfig = {
|
|
5593
5616
|
Id: id,
|
|
5594
5617
|
IsEnabled: config["Enabled"] ?? true,
|
|
5595
5618
|
IncludedObjectVersions: readConfigString(config, "IncludedObjectVersions", "All", "AWS::S3::Bucket InventoryConfigurations[]"),
|
|
5596
|
-
Schedule: { Frequency:
|
|
5619
|
+
Schedule: { Frequency: frequency },
|
|
5597
5620
|
Destination: { S3BucketDestination: s3Dest ? {
|
|
5598
5621
|
Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
|
|
5599
5622
|
AccountId: s3Dest["BucketAccountId"],
|
|
@@ -5762,9 +5785,10 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5762
5785
|
* in both places would double-PUT.
|
|
5763
5786
|
*/
|
|
5764
5787
|
async applyConfiguration(bucketName, properties, options = {}) {
|
|
5765
|
-
const { skipTags = false, skipDiffManaged = false } = options;
|
|
5788
|
+
const { skipTags = false, skipDiffManaged = false, context } = options;
|
|
5789
|
+
const replayOnUnusable = replayWarn(this.logger, context).onUnusable;
|
|
5766
5790
|
const versioningConfig = properties["VersioningConfiguration"];
|
|
5767
|
-
if (!skipDiffManaged && versioningConfig != null) await this.applyVersioning(bucketName, versioningConfig);
|
|
5791
|
+
if (!skipDiffManaged && versioningConfig != null) await this.applyVersioning(bucketName, versioningConfig, replayOnUnusable);
|
|
5768
5792
|
const tags = properties["Tags"];
|
|
5769
5793
|
if (!skipTags && tags && Array.isArray(tags) && tags.length > 0) await this.applyTags(bucketName, tags);
|
|
5770
5794
|
const ownershipControls = properties["OwnershipControls"];
|
|
@@ -5897,8 +5921,10 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5897
5921
|
const previousVersioning = previousProperties["VersioningConfiguration"];
|
|
5898
5922
|
const nextVersioning = properties["VersioningConfiguration"];
|
|
5899
5923
|
const versioningChanged = JSON.stringify(previousVersioning ?? null) !== JSON.stringify(nextVersioning ?? null);
|
|
5900
|
-
const
|
|
5901
|
-
if (
|
|
5924
|
+
const versioningRefusal = configStringRefusal(nextVersioning, "Status", "Suspended", "AWS::S3::Bucket VersioningConfiguration");
|
|
5925
|
+
if (versioningRefusal !== void 0 && versioningChanged) this.logger.warn(`Bucket ${bucketName}: ${versioningRefusal}. Leaving the bucket's LIVE versioning state unchanged — neither enabling nor suspending it; the same value is REFUSED on a template-path create`);
|
|
5926
|
+
const desiredVersioningStatus = versioningRefusal === void 0 ? readConfigString(nextVersioning, "Status", "Suspended", "AWS::S3::Bucket VersioningConfiguration") : void 0;
|
|
5927
|
+
if (versioningRefusal === void 0 && versioningChanged && nextVersioning != null && desiredVersioningStatus !== "Suspended") await this.applyVersioning(bucketName, nextVersioning, (m) => this.logger.warn(m));
|
|
5902
5928
|
await this.diffSubConfig(bucketName, S3BucketProvider.emptyListConfigToUndefined(previousProperties["OwnershipControls"], "Rules"), S3BucketProvider.emptyListConfigToUndefined(properties["OwnershipControls"], "Rules"), async (cfg) => this.applyOwnershipControls(bucketName, cfg), async () => {
|
|
5903
5929
|
await this.s3Client.send(new DeleteBucketOwnershipControlsCommand({ Bucket: bucketName }));
|
|
5904
5930
|
this.logger.debug(`Deleted ownership controls on bucket ${bucketName}`);
|
|
@@ -5925,7 +5951,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5925
5951
|
await this.s3Client.send(new DeleteBucketWebsiteCommand({ Bucket: bucketName }));
|
|
5926
5952
|
this.logger.debug(`Deleted website configuration on bucket ${bucketName}`);
|
|
5927
5953
|
});
|
|
5928
|
-
await this.diffSubConfig(bucketName, previousProperties["LoggingConfiguration"], properties["LoggingConfiguration"], async (cfg) => this.applyLoggingConfiguration(bucketName, cfg), async () => this.applyLoggingConfiguration(bucketName, void 0));
|
|
5954
|
+
await this.diffSubConfig(bucketName, previousProperties["LoggingConfiguration"], properties["LoggingConfiguration"], async (cfg) => this.applyLoggingConfiguration(bucketName, cfg, (m) => this.logger.warn(m)), async () => this.applyLoggingConfiguration(bucketName, void 0));
|
|
5929
5955
|
await this.diffSubConfig(bucketName, previousProperties["NotificationConfiguration"], properties["NotificationConfiguration"], async (cfg) => this.applyNotificationConfiguration(bucketName, cfg), async () => this.applyNotificationConfiguration(bucketName, void 0));
|
|
5930
5956
|
await this.diffSubConfig(bucketName, previousProperties["ReplicationConfiguration"], properties["ReplicationConfiguration"], async (cfg) => this.applyReplicationConfiguration(bucketName, cfg, (m) => this.logger.warn(m)), async () => {
|
|
5931
5957
|
await this.s3Client.send(new DeleteBucketReplicationCommand({ Bucket: bucketName }));
|
|
@@ -5989,7 +6015,9 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5989
6015
|
const lifecycleConfig = properties["LifecycleConfiguration"];
|
|
5990
6016
|
if (lifecycleConfig?.Rules && Array.isArray(lifecycleConfig.Rules) && lifecycleConfig.Rules.length > 0) await this.applyLifecycleConfiguration(bucketName, lifecycleConfig, replayOnUnusable);
|
|
5991
6017
|
const loggingConfig = properties["LoggingConfiguration"];
|
|
5992
|
-
|
|
6018
|
+
const loggingRefusal = replayOnUnusable ? configStringRefusal(loggingConfig, "DestinationBucketName", "", "AWS::S3::Bucket LoggingConfiguration") : void 0;
|
|
6019
|
+
if (loggingRefusal !== void 0) replayOnUnusable?.(`${loggingRefusal}. Skipping the logging configuration; the same value is REFUSED on a template-path create`);
|
|
6020
|
+
else if (readConfigString(loggingConfig, "DestinationBucketName", "", "AWS::S3::Bucket LoggingConfiguration") !== "") await this.applyLoggingConfiguration(bucketName, loggingConfig, replayOnUnusable);
|
|
5993
6021
|
const websiteConfig = properties["WebsiteConfiguration"];
|
|
5994
6022
|
if (websiteConfig) await this.applyWebsiteConfiguration(bucketName, websiteConfig);
|
|
5995
6023
|
const accelerateConfig = properties["AccelerateConfiguration"];
|
|
@@ -6032,7 +6060,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
6032
6060
|
else throw createError;
|
|
6033
6061
|
}
|
|
6034
6062
|
try {
|
|
6035
|
-
await this.applyConfiguration(bucketName, properties);
|
|
6063
|
+
await this.applyConfiguration(bucketName, properties, { ...context ? { context } : {} });
|
|
6036
6064
|
await this.applyAllSubConfigsForCreate(bucketName, properties, context);
|
|
6037
6065
|
} catch (innerError) {
|
|
6038
6066
|
if (createdNewBucket) try {
|
|
@@ -17921,6 +17949,47 @@ var EventBridgeBusProvider = class {
|
|
|
17921
17949
|
//#endregion
|
|
17922
17950
|
//#region src/provisioning/providers/ec2-provider.ts
|
|
17923
17951
|
/**
|
|
17952
|
+
* The `AWS::EC2::Route` destination keys, in CloudFormation's own precedence
|
|
17953
|
+
* order — which is also the order `createRoute`'s
|
|
17954
|
+
* `DestinationCidrBlock || DestinationIpv6CidrBlock || DestinationPrefixListId`
|
|
17955
|
+
* chain resolves them.
|
|
17956
|
+
*/
|
|
17957
|
+
const ROUTE_DESTINATION_KEYS = [
|
|
17958
|
+
"DestinationCidrBlock",
|
|
17959
|
+
"DestinationIpv6CidrBlock",
|
|
17960
|
+
"DestinationPrefixListId"
|
|
17961
|
+
];
|
|
17962
|
+
/**
|
|
17963
|
+
* Split a Route property bag into the destination keys it DECLARES and the bag
|
|
17964
|
+
* carrying only the one that would actually be sent (issue #1591).
|
|
17965
|
+
*
|
|
17966
|
+
* ONE source for a decision two very different call sites have to agree on: the
|
|
17967
|
+
* provisioning path (`createRoute`, which narrows and warns) and the DIFF path
|
|
17968
|
+
* (the engine's canonicalizer, which must not report the losers as a change).
|
|
17969
|
+
* If those two disagreed the fix would be worse than the bug — state and
|
|
17970
|
+
* template would each be narrowed to a different key.
|
|
17971
|
+
*
|
|
17972
|
+
* The winner is simply `declared[0]`. That is not a shortcut: the list is built
|
|
17973
|
+
* in the same order and with the same truthiness predicate as the `||` chain,
|
|
17974
|
+
* so the first declared key IS what the chain resolves to. The predicate is
|
|
17975
|
+
* `Boolean`, not a hand-listed `undefined | null | ''` set, because the bag is
|
|
17976
|
+
* `unknown`-valued at runtime — an unquoted YAML `0` must be skipped by the
|
|
17977
|
+
* narrowing exactly as the chain skips it, or the two disagree on which key
|
|
17978
|
+
* was sent.
|
|
17979
|
+
*
|
|
17980
|
+
* `narrowed` is always a fresh object: the caller's bag is the engine's
|
|
17981
|
+
* `resolvedProps`, which it records for every resource that does NOT narrow.
|
|
17982
|
+
*/
|
|
17983
|
+
function narrowRouteDestinations(properties) {
|
|
17984
|
+
const declared = ROUTE_DESTINATION_KEYS.filter((key) => Boolean(properties[key]));
|
|
17985
|
+
const narrowed = { ...properties };
|
|
17986
|
+
for (const losingKey of declared.slice(1)) delete narrowed[losingKey];
|
|
17987
|
+
return {
|
|
17988
|
+
declared,
|
|
17989
|
+
narrowed
|
|
17990
|
+
};
|
|
17991
|
+
}
|
|
17992
|
+
/**
|
|
17924
17993
|
* AWS EC2 Networking Provider
|
|
17925
17994
|
*
|
|
17926
17995
|
* Implements resource provisioning for EC2 networking resources:
|
|
@@ -18768,15 +18837,15 @@ var EC2Provider = class {
|
|
|
18768
18837
|
const destinationPrefixListId = properties["DestinationPrefixListId"];
|
|
18769
18838
|
const destination = destinationCidrBlock || destinationIpv6CidrBlock || destinationPrefixListId;
|
|
18770
18839
|
if (!routeTableId || !destination) throw new ProvisioningError(`RouteTableId and one of DestinationCidrBlock/DestinationIpv6CidrBlock/DestinationPrefixListId are required for Route ${logicalId}`, resourceType, logicalId);
|
|
18771
|
-
const declaredDestinations =
|
|
18772
|
-
|
|
18773
|
-
["DestinationIpv6CidrBlock", destinationIpv6CidrBlock],
|
|
18774
|
-
["DestinationPrefixListId", destinationPrefixListId]
|
|
18775
|
-
].filter(([, value]) => Boolean(value)).map(([key]) => key);
|
|
18840
|
+
const { declared: declaredDestinations, narrowed: narrowedProperties } = narrowRouteDestinations(properties);
|
|
18841
|
+
let effectiveProperties;
|
|
18776
18842
|
if (declaredDestinations.length > 1) {
|
|
18777
18843
|
const message = `Route ${logicalId} declares more than one destination (${declaredDestinations.join(", ")}). CloudFormation and EC2 accept exactly one of DestinationCidrBlock/DestinationIpv6CidrBlock/DestinationPrefixListId; remove the extra keys from the template.`;
|
|
18778
|
-
if (onMultipleDestinations)
|
|
18779
|
-
|
|
18844
|
+
if (onMultipleDestinations) {
|
|
18845
|
+
const usedKey = declaredDestinations[0];
|
|
18846
|
+
effectiveProperties = narrowedProperties;
|
|
18847
|
+
onMultipleDestinations(`${message} Continuing with ${usedKey} and ignoring the rest.`);
|
|
18848
|
+
} else throw new ProvisioningError(message, resourceType, logicalId);
|
|
18780
18849
|
}
|
|
18781
18850
|
try {
|
|
18782
18851
|
await this.ec2Client.send(new CreateRouteCommand({
|
|
@@ -18798,7 +18867,8 @@ var EC2Provider = class {
|
|
|
18798
18867
|
this.logger.debug(`Successfully created Route ${logicalId}: ${physicalId}`);
|
|
18799
18868
|
return {
|
|
18800
18869
|
physicalId,
|
|
18801
|
-
attributes: {}
|
|
18870
|
+
attributes: {},
|
|
18871
|
+
...effectiveProperties && { effectiveProperties }
|
|
18802
18872
|
};
|
|
18803
18873
|
} catch (error) {
|
|
18804
18874
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -18817,7 +18887,8 @@ var EC2Provider = class {
|
|
|
18817
18887
|
return {
|
|
18818
18888
|
physicalId: createResult.physicalId,
|
|
18819
18889
|
wasReplaced: true,
|
|
18820
|
-
...createResult.attributes && { attributes: createResult.attributes }
|
|
18890
|
+
...createResult.attributes && { attributes: createResult.attributes },
|
|
18891
|
+
...createResult.effectiveProperties && { effectiveProperties: createResult.effectiveProperties }
|
|
18821
18892
|
};
|
|
18822
18893
|
} catch (error) {
|
|
18823
18894
|
if (error instanceof CdkdError) throw error;
|
|
@@ -20221,6 +20292,26 @@ var EC2Provider = class {
|
|
|
20221
20292
|
default: return [];
|
|
20222
20293
|
}
|
|
20223
20294
|
}
|
|
20295
|
+
/**
|
|
20296
|
+
* The diff-side half of the Route multi-destination narrowing (issue #1591).
|
|
20297
|
+
*
|
|
20298
|
+
* `createRoute` sends exactly one destination key and reports the narrowed
|
|
20299
|
+
* bag via `effectiveProperties`, so state carries one key. Without the same
|
|
20300
|
+
* narrowing here the template's extra keys read as an ADDED property on the
|
|
20301
|
+
* next deploy — and every destination key is create-only in the registry
|
|
20302
|
+
* schema, so the diff would classify a REPLACEMENT and the engine's
|
|
20303
|
+
* replacement create (which passes no context, and so gets no
|
|
20304
|
+
* `onMultipleDestinations` downgrade) would hit the #1566 refusal. A
|
|
20305
|
+
* previously-green no-op deploy would start failing.
|
|
20306
|
+
*
|
|
20307
|
+
* Shares `narrowRouteDestinations` with the provisioning path so the two
|
|
20308
|
+
* cannot disagree about which key survives.
|
|
20309
|
+
*/
|
|
20310
|
+
canonicalizeDesiredProperties(resourceType, properties) {
|
|
20311
|
+
if (resourceType !== "AWS::EC2::Route") return properties;
|
|
20312
|
+
const { declared, narrowed } = narrowRouteDestinations(properties);
|
|
20313
|
+
return declared.length > 1 ? narrowed : properties;
|
|
20314
|
+
}
|
|
20224
20315
|
async readVpcCurrentState(physicalId) {
|
|
20225
20316
|
const vpc = (await this.ec2Client.send(new DescribeVpcsCommand({ VpcIds: [physicalId] }))).Vpcs?.[0];
|
|
20226
20317
|
if (!vpc) return void 0;
|
|
@@ -51246,7 +51337,7 @@ async function loadStateOrEmpty(stackName, region, stateBackend) {
|
|
|
51246
51337
|
* Pure with respect to AWS state mutation — only reads state (the resolver
|
|
51247
51338
|
* may read producer state for `Fn::ImportValue` / `Fn::GetStackOutput`).
|
|
51248
51339
|
*/
|
|
51249
|
-
async function computeStackDiff(currentState, template, region, stackName, stateBackend, diffCalculator, parameters) {
|
|
51340
|
+
async function computeStackDiff(currentState, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties) {
|
|
51250
51341
|
const intrinsicResolver = new IntrinsicFunctionResolver(region);
|
|
51251
51342
|
let mergedParameters = parameters;
|
|
51252
51343
|
let parametersBound = false;
|
|
@@ -51286,7 +51377,7 @@ async function computeStackDiff(currentState, template, region, stackName, state
|
|
|
51286
51377
|
...mergedParameters && { parameters: mergedParameters },
|
|
51287
51378
|
...conditions && { conditions }
|
|
51288
51379
|
});
|
|
51289
|
-
return diffCalculator.calculateDiff(currentState, effectiveTemplate, resolveFn);
|
|
51380
|
+
return diffCalculator.calculateDiff(currentState, effectiveTemplate, resolveFn, canonicalizeProperties);
|
|
51290
51381
|
}
|
|
51291
51382
|
/**
|
|
51292
51383
|
* Resolve a nested-stack child's input `Parameters` (declared on the parent's
|
|
@@ -51347,13 +51438,13 @@ async function resolveChildStackParameters(parentStackRow, parentTemplate, paren
|
|
|
51347
51438
|
* fail at deploy time.
|
|
51348
51439
|
*/
|
|
51349
51440
|
async function buildDiffTree(args) {
|
|
51350
|
-
const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parameters, assetRedirect } = args;
|
|
51441
|
+
const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parameters, canonicalizeProperties, assetRedirect } = args;
|
|
51351
51442
|
const state = await loadStateOrEmpty(stackName, region, stateBackend);
|
|
51352
51443
|
const node = {
|
|
51353
51444
|
stackName,
|
|
51354
51445
|
displayName,
|
|
51355
51446
|
region,
|
|
51356
|
-
changes: await computeStackDiff(state, template, region, stackName, stateBackend, diffCalculator, parameters),
|
|
51447
|
+
changes: await computeStackDiff(state, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties),
|
|
51357
51448
|
ccApiRoutes: collectCcApiRoutes(template, state),
|
|
51358
51449
|
children: []
|
|
51359
51450
|
};
|
|
@@ -51379,6 +51470,7 @@ async function buildDiffTree(args) {
|
|
|
51379
51470
|
stateBackend,
|
|
51380
51471
|
diffCalculator,
|
|
51381
51472
|
parameters: childParameters,
|
|
51473
|
+
...canonicalizeProperties && { canonicalizeProperties },
|
|
51382
51474
|
...assetRedirect && { assetRedirect }
|
|
51383
51475
|
}));
|
|
51384
51476
|
}
|
|
@@ -51736,6 +51828,9 @@ async function diffCommand(stacks, options) {
|
|
|
51736
51828
|
...options.profile && { profile: options.profile }
|
|
51737
51829
|
});
|
|
51738
51830
|
const diffCalculator = new DiffCalculator();
|
|
51831
|
+
const diffProviderRegistry = new ProviderRegistry();
|
|
51832
|
+
registerAllProviders(diffProviderRegistry);
|
|
51833
|
+
const canonicalizeProperties = makeCanonicalizePropertiesFn(diffProviderRegistry);
|
|
51739
51834
|
const recursive = options.recursive ?? false;
|
|
51740
51835
|
const resolveAssetRedirect = createAssetRedirectResolver({
|
|
51741
51836
|
stateBackend,
|
|
@@ -51762,6 +51857,7 @@ async function diffCommand(stacks, options) {
|
|
|
51762
51857
|
recursive,
|
|
51763
51858
|
stateBackend,
|
|
51764
51859
|
diffCalculator,
|
|
51860
|
+
canonicalizeProperties,
|
|
51765
51861
|
...assetRedirect && { assetRedirect }
|
|
51766
51862
|
}));
|
|
51767
51863
|
}
|
|
@@ -70245,7 +70341,7 @@ function createMigrateCommand() {
|
|
|
70245
70341
|
*/
|
|
70246
70342
|
function buildProgram() {
|
|
70247
70343
|
const program = new Command();
|
|
70248
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.
|
|
70344
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.24");
|
|
70249
70345
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
70250
70346
|
const { profile } = actionCommand.optsWithGlobals();
|
|
70251
70347
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|