@go-to-k/cdkd 0.278.26 → 0.278.28
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-DLScqiT2.js → asg-provider-BJnh483x.js} +2 -2
- package/dist/{asg-provider-DLScqiT2.js.map → asg-provider-BJnh483x.js.map} +1 -1
- package/dist/cli.js +76 -46
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-BsHkBRtK.js → deploy-engine-Dcg1nH3d.js} +160 -7
- package/dist/deploy-engine-Dcg1nH3d.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BsHkBRtK.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 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-Dcg1nH3d.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-BJnh483x.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";
|
|
@@ -4936,7 +4936,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
4936
4936
|
* Apply versioning configuration if specified
|
|
4937
4937
|
*/
|
|
4938
4938
|
async applyVersioning(bucketName, versioningConfig) {
|
|
4939
|
-
const status = versioningConfig
|
|
4939
|
+
const status = readConfigString(versioningConfig, "Status", "Suspended", "AWS::S3::Bucket VersioningConfiguration");
|
|
4940
4940
|
await this.s3Client.send(new PutBucketVersioningCommand({
|
|
4941
4941
|
Bucket: bucketName,
|
|
4942
4942
|
VersioningConfiguration: { Status: status }
|
|
@@ -5045,7 +5045,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5045
5045
|
const rules = lifecycleConfig.Rules.map((rule) => {
|
|
5046
5046
|
const sdkRule = {
|
|
5047
5047
|
ID: rule["Id"],
|
|
5048
|
-
Status: rule
|
|
5048
|
+
Status: readConfigString(rule, "Status", "Enabled", "AWS::S3::Bucket LifecycleConfiguration.Rules[]"),
|
|
5049
5049
|
Prefix: useFilterForm ? void 0 : rule["Prefix"]
|
|
5050
5050
|
};
|
|
5051
5051
|
const expiration = rule["ExpirationInDays"] || rule["ExpirationDate"] || rule["Expiration"];
|
|
@@ -5168,7 +5168,8 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5168
5168
|
* SDK: PutBucketLogging with BucketLoggingStatus.LoggingEnabled
|
|
5169
5169
|
*/
|
|
5170
5170
|
async applyLoggingConfiguration(bucketName, loggingConfig) {
|
|
5171
|
-
|
|
5171
|
+
const destinationBucket = readConfigString(loggingConfig, "DestinationBucketName", "", "AWS::S3::Bucket LoggingConfiguration");
|
|
5172
|
+
if (!loggingConfig || destinationBucket === "") {
|
|
5172
5173
|
await this.s3Client.send(new PutBucketLoggingCommand({
|
|
5173
5174
|
Bucket: bucketName,
|
|
5174
5175
|
BucketLoggingStatus: {}
|
|
@@ -5179,8 +5180,8 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5179
5180
|
await this.s3Client.send(new PutBucketLoggingCommand({
|
|
5180
5181
|
Bucket: bucketName,
|
|
5181
5182
|
BucketLoggingStatus: { LoggingEnabled: {
|
|
5182
|
-
TargetBucket:
|
|
5183
|
-
TargetPrefix: loggingConfig
|
|
5183
|
+
TargetBucket: destinationBucket,
|
|
5184
|
+
TargetPrefix: readConfigString(loggingConfig, "LogFilePrefix", "", "AWS::S3::Bucket LoggingConfiguration")
|
|
5184
5185
|
} }
|
|
5185
5186
|
}));
|
|
5186
5187
|
this.logger.debug(`Applied logging configuration to bucket ${bucketName}`);
|
|
@@ -5358,11 +5359,11 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5358
5359
|
const dest = dataExport["Destination"];
|
|
5359
5360
|
const s3Dest = dest?.["BucketAccountId"] || dest?.["BucketArn"] || dest?.["Format"] ? dest : dest?.["S3BucketDestination"];
|
|
5360
5361
|
analyticsConfig.StorageClassAnalysis = { DataExport: {
|
|
5361
|
-
OutputSchemaVersion: dataExport
|
|
5362
|
+
OutputSchemaVersion: readConfigString(dataExport, "OutputSchemaVersion", "V_1", "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport"),
|
|
5362
5363
|
Destination: s3Dest ? { S3BucketDestination: {
|
|
5363
5364
|
Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
|
|
5364
5365
|
BucketAccountId: s3Dest["BucketAccountId"],
|
|
5365
|
-
Format: s3Dest
|
|
5366
|
+
Format: readConfigString(s3Dest, "Format", "CSV", "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport.Destination.S3BucketDestination"),
|
|
5366
5367
|
Prefix: s3Dest["Prefix"]
|
|
5367
5368
|
} } : void 0
|
|
5368
5369
|
} };
|
|
@@ -5387,7 +5388,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5387
5388
|
const tierings = config["Tierings"];
|
|
5388
5389
|
const itConfig = {
|
|
5389
5390
|
Id: id,
|
|
5390
|
-
Status: config
|
|
5391
|
+
Status: readConfigString(config, "Status", "Enabled", "AWS::S3::Bucket IntelligentTieringConfigurations[]"),
|
|
5391
5392
|
Tierings: (tierings || []).map((t) => ({
|
|
5392
5393
|
AccessTier: t["AccessTier"],
|
|
5393
5394
|
Days: t["Days"]
|
|
@@ -5425,12 +5426,12 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5425
5426
|
const inventoryConfig = {
|
|
5426
5427
|
Id: id,
|
|
5427
5428
|
IsEnabled: config["Enabled"] ?? true,
|
|
5428
|
-
IncludedObjectVersions: config
|
|
5429
|
-
Schedule: { Frequency: config["ScheduleFrequency"]
|
|
5429
|
+
IncludedObjectVersions: readConfigString(config, "IncludedObjectVersions", "All", "AWS::S3::Bucket InventoryConfigurations[]"),
|
|
5430
|
+
Schedule: { Frequency: config["ScheduleFrequency"] !== void 0 ? requireConfigString(config["ScheduleFrequency"], "Weekly", "AWS::S3::Bucket InventoryConfigurations[].ScheduleFrequency") : readConfigString(config["Schedule"], "Frequency", "Weekly", "AWS::S3::Bucket InventoryConfigurations[].Schedule") },
|
|
5430
5431
|
Destination: { S3BucketDestination: s3Dest ? {
|
|
5431
5432
|
Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
|
|
5432
5433
|
AccountId: s3Dest["BucketAccountId"],
|
|
5433
|
-
Format: s3Dest
|
|
5434
|
+
Format: readConfigString(s3Dest, "Format", "CSV", "AWS::S3::Bucket InventoryConfigurations[].Destination.S3BucketDestination"),
|
|
5434
5435
|
Prefix: s3Dest["Prefix"]
|
|
5435
5436
|
} : void 0 },
|
|
5436
5437
|
OptionalFields: config["OptionalFields"],
|
|
@@ -5462,7 +5463,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5462
5463
|
const dest = rule["Destination"];
|
|
5463
5464
|
const sdkRule = {
|
|
5464
5465
|
ID: rule["Id"],
|
|
5465
|
-
Status: rule
|
|
5466
|
+
Status: readConfigString(rule, "Status", "Enabled", "AWS::S3::Bucket ReplicationConfiguration.Rules[]"),
|
|
5466
5467
|
Priority: rule["Priority"],
|
|
5467
5468
|
Destination: {
|
|
5468
5469
|
Bucket: dest["Bucket"],
|
|
@@ -5539,7 +5540,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5539
5540
|
async applyConfiguration(bucketName, properties, options = {}) {
|
|
5540
5541
|
const { skipTags = false, skipDiffManaged = false } = options;
|
|
5541
5542
|
const versioningConfig = properties["VersioningConfiguration"];
|
|
5542
|
-
if (!skipDiffManaged && versioningConfig) await this.applyVersioning(bucketName, versioningConfig);
|
|
5543
|
+
if (!skipDiffManaged && versioningConfig != null) await this.applyVersioning(bucketName, versioningConfig);
|
|
5543
5544
|
const tags = properties["Tags"];
|
|
5544
5545
|
if (!skipTags && tags && Array.isArray(tags) && tags.length > 0) await this.applyTags(bucketName, tags);
|
|
5545
5546
|
const ownershipControls = properties["OwnershipControls"];
|
|
@@ -5594,10 +5595,10 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5594
5595
|
* declares the config.
|
|
5595
5596
|
*
|
|
5596
5597
|
* NOTE this helper does NOT cover `VersioningConfiguration` (it has no list
|
|
5597
|
-
* key)
|
|
5598
|
-
*
|
|
5599
|
-
*
|
|
5600
|
-
*
|
|
5598
|
+
* key). That property is malformed-shape-refused separately, by
|
|
5599
|
+
* `readConfigString` in `applyVersioning` + `applySubConfigDiffs`
|
|
5600
|
+
* (issue #1471) — same outcome, different mechanism, because a versioning
|
|
5601
|
+
* block has an inner FIELD to validate rather than a list to measure.
|
|
5601
5602
|
*/
|
|
5602
5603
|
static emptyListConfigToUndefined(config, listKey) {
|
|
5603
5604
|
if (config === void 0 || config === null) return void 0;
|
|
@@ -5672,7 +5673,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5672
5673
|
const previousVersioning = previousProperties["VersioningConfiguration"];
|
|
5673
5674
|
const nextVersioning = properties["VersioningConfiguration"];
|
|
5674
5675
|
const versioningChanged = JSON.stringify(previousVersioning ?? null) !== JSON.stringify(nextVersioning ?? null);
|
|
5675
|
-
const desiredVersioningStatus = nextVersioning
|
|
5676
|
+
const desiredVersioningStatus = readConfigString(nextVersioning, "Status", "Suspended", "AWS::S3::Bucket VersioningConfiguration");
|
|
5676
5677
|
if (versioningChanged && nextVersioning != null && desiredVersioningStatus !== "Suspended") await this.applyVersioning(bucketName, nextVersioning);
|
|
5677
5678
|
await this.diffSubConfig(bucketName, S3BucketProvider.emptyListConfigToUndefined(previousProperties["OwnershipControls"], "Rules"), S3BucketProvider.emptyListConfigToUndefined(properties["OwnershipControls"], "Rules"), async (cfg) => this.applyOwnershipControls(bucketName, cfg), async () => {
|
|
5678
5679
|
await this.s3Client.send(new DeleteBucketOwnershipControlsCommand({ Bucket: bucketName }));
|
|
@@ -5763,7 +5764,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5763
5764
|
const lifecycleConfig = properties["LifecycleConfiguration"];
|
|
5764
5765
|
if (lifecycleConfig?.Rules && Array.isArray(lifecycleConfig.Rules) && lifecycleConfig.Rules.length > 0) await this.applyLifecycleConfiguration(bucketName, lifecycleConfig);
|
|
5765
5766
|
const loggingConfig = properties["LoggingConfiguration"];
|
|
5766
|
-
if (loggingConfig
|
|
5767
|
+
if (readConfigString(loggingConfig, "DestinationBucketName", "", "AWS::S3::Bucket LoggingConfiguration") !== "") await this.applyLoggingConfiguration(bucketName, loggingConfig);
|
|
5767
5768
|
const websiteConfig = properties["WebsiteConfiguration"];
|
|
5768
5769
|
if (websiteConfig) await this.applyWebsiteConfiguration(bucketName, websiteConfig);
|
|
5769
5770
|
const accelerateConfig = properties["AccelerateConfiguration"];
|
|
@@ -15276,7 +15277,7 @@ var SecretsManagerSecretProvider = class {
|
|
|
15276
15277
|
const excludeLowercase = config["ExcludeLowercase"];
|
|
15277
15278
|
const excludeNumbers = config["ExcludeNumbers"];
|
|
15278
15279
|
const excludePunctuation = config["ExcludePunctuation"];
|
|
15279
|
-
const excludeCharacters = config
|
|
15280
|
+
const excludeCharacters = readConfigString(config, "ExcludeCharacters", "", "AWS::SecretsManager::Secret GenerateSecretString");
|
|
15280
15281
|
let chars = "";
|
|
15281
15282
|
if (!excludeUppercase) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
15282
15283
|
if (!excludeLowercase) chars += "abcdefghijklmnopqrstuvwxyz";
|
|
@@ -33105,10 +33106,10 @@ var GlueProvider = class {
|
|
|
33105
33106
|
if (!this.client) this.client = new GlueClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
33106
33107
|
return this.client;
|
|
33107
33108
|
}
|
|
33108
|
-
async create(logicalId, resourceType, properties) {
|
|
33109
|
+
async create(logicalId, resourceType, properties, context) {
|
|
33109
33110
|
switch (resourceType) {
|
|
33110
33111
|
case "AWS::Glue::Database": return this.createDatabase(logicalId, resourceType, properties);
|
|
33111
|
-
case "AWS::Glue::Table": return this.createTable(logicalId, resourceType, properties);
|
|
33112
|
+
case "AWS::Glue::Table": return this.createTable(logicalId, resourceType, properties, context);
|
|
33112
33113
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
33113
33114
|
}
|
|
33114
33115
|
}
|
|
@@ -33191,7 +33192,7 @@ var GlueProvider = class {
|
|
|
33191
33192
|
throw new ProvisioningError(`Failed to delete Glue Database ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
33192
33193
|
}
|
|
33193
33194
|
}
|
|
33194
|
-
async createTable(logicalId, resourceType, properties) {
|
|
33195
|
+
async createTable(logicalId, resourceType, properties, context) {
|
|
33195
33196
|
this.logger.debug(`Creating Glue Table ${logicalId}`);
|
|
33196
33197
|
const databaseName = properties["DatabaseName"];
|
|
33197
33198
|
if (!databaseName) throw new ProvisioningError(`DatabaseName is required for Glue Table ${logicalId}`, resourceType, logicalId);
|
|
@@ -33200,7 +33201,10 @@ var GlueProvider = class {
|
|
|
33200
33201
|
const tableName = tableInput["Name"] ?? properties["Name"];
|
|
33201
33202
|
if (!tableName) throw new ProvisioningError(`TableInput.Name or top-level Name is required for Glue Table ${logicalId}`, resourceType, logicalId);
|
|
33202
33203
|
const catalogId = properties["CatalogId"];
|
|
33203
|
-
|
|
33204
|
+
enforceIcebergTableInputAbsent(logicalId, resourceType, properties, {
|
|
33205
|
+
warn: (message) => this.logger.warn(message),
|
|
33206
|
+
replayingState: context?.replayingState === true
|
|
33207
|
+
});
|
|
33204
33208
|
const openTableFormatInput = properties["OpenTableFormatInput"];
|
|
33205
33209
|
try {
|
|
33206
33210
|
await this.getClient().send(new CreateTableCommand$1({
|
|
@@ -33990,15 +33994,35 @@ function findIcebergTableInputKey(properties) {
|
|
|
33990
33994
|
* produce a late, cryptic AWS error. Failing fast with the working shape spelled
|
|
33991
33995
|
* out is strictly more useful.
|
|
33992
33996
|
*
|
|
33993
|
-
* **
|
|
33994
|
-
*
|
|
33995
|
-
*
|
|
33996
|
-
*
|
|
33997
|
-
*
|
|
33998
|
-
*
|
|
33999
|
-
*
|
|
34000
|
-
*
|
|
34001
|
-
*
|
|
33997
|
+
* **TEMPLATE creates only — every STATE REPLAY warns instead.** The refusal is
|
|
33998
|
+
* conditioned on the ORIGIN of the properties, not on the operation name:
|
|
33999
|
+
*
|
|
34000
|
+
* - `update()` warns unconditionally. Rollback replays from cdkd STATE, and a
|
|
34001
|
+
* table created by a pre-#1390 build carries the key in its state record, so
|
|
34002
|
+
* refusing there would make such a table unrollbackable with no
|
|
34003
|
+
* template-side remedy. cdkd does not wire Glue's update-only
|
|
34004
|
+
* `UpdateOpenTableFormatInput` shape and `buildTableInput` is an explicit
|
|
34005
|
+
* allow-list, so warning forwards nothing and loses no protection.
|
|
34006
|
+
* - `create()` warns when {@link CreateContext.replayingState} is set — the
|
|
34007
|
+
* rollback executor's reverse-replacement arm, which revives the OLD
|
|
34008
|
+
* resource from `previousState.properties` (issue #1463). Same reasoning:
|
|
34009
|
+
* the user cannot edit a state record from the template. Unlike the update
|
|
34010
|
+
* path this one DOES forward the value, so the re-created table is degraded
|
|
34011
|
+
* in exactly the way the original was (the CFn spelling is dropped by the
|
|
34012
|
+
* SDK serializer per #1390; the SDK spelling is sent and Glue rejects it) —
|
|
34013
|
+
* the warning says so, and the fix-forward is a `cdkd deploy`.
|
|
34014
|
+
* - Every deploy-engine `create()` refuses: the CREATE branch, the
|
|
34015
|
+
* property-driven replacement, the `--recreate-via-*` destroy-then-create,
|
|
34016
|
+
* the `--replace` delete-first fallback, and the update-failure replacement.
|
|
34017
|
+
* All are driven by freshly resolved TEMPLATE properties, so the user CAN
|
|
34018
|
+
* fix the input and a fast, actionable refusal is strictly better.
|
|
34019
|
+
*
|
|
34020
|
+
* The asymmetry constrains where this provider may re-create. `GlueProvider`
|
|
34021
|
+
* must never call `this.create()` from inside its own `update()` the way ACM /
|
|
34022
|
+
* IAM / Lambda-permission / SNS-subscription do: those internal re-creates
|
|
34023
|
+
* forward `update()`'s `properties` — a STATE record during a rollback replay —
|
|
34024
|
+
* and `update()` has no context parameter to carry the flag, so this refusal
|
|
34025
|
+
* would fire on a replay with no way to detect it.
|
|
34002
34026
|
*
|
|
34003
34027
|
* **Known bypass: the sticky Cloud Control route.** This is a GlueProvider
|
|
34004
34028
|
* pre-flight, so it only runs on the SDK route. When a table's state record
|
|
@@ -34019,19 +34043,23 @@ function findIcebergTableInputKey(properties) {
|
|
|
34019
34043
|
* relaxed, the rename MUST be restored in the same change — otherwise the
|
|
34020
34044
|
* silent-drop bug of #1390 comes straight back.
|
|
34021
34045
|
*/
|
|
34022
|
-
function
|
|
34046
|
+
function enforceIcebergTableInputAbsent(logicalId, resourceType, properties, options) {
|
|
34023
34047
|
const key = findIcebergTableInputKey(properties);
|
|
34024
34048
|
if (key === void 0) return;
|
|
34025
|
-
|
|
34049
|
+
if (options.replayingState) {
|
|
34050
|
+
options.warn(icebergTableInputRefusalMessage(logicalId, key, "create-replay"));
|
|
34051
|
+
return;
|
|
34052
|
+
}
|
|
34053
|
+
throw new ProvisioningError(icebergTableInputRefusalMessage(logicalId, key, "create"), resourceType, logicalId);
|
|
34026
34054
|
}
|
|
34027
34055
|
/**
|
|
34028
|
-
* The shared #1454 message body, so the CREATE refusal
|
|
34029
|
-
* cannot drift apart. `mode` only changes
|
|
34030
|
-
*
|
|
34031
|
-
* next action is the same either way.
|
|
34056
|
+
* The shared #1454 message body, so the CREATE refusal, the UPDATE warning and
|
|
34057
|
+
* the rollback-replay CREATE warning cannot drift apart. `mode` only changes
|
|
34058
|
+
* the lead clause — everything after it (the probe evidence and the working
|
|
34059
|
+
* shape) is identical, because the user's next action is the same either way.
|
|
34032
34060
|
*/
|
|
34033
34061
|
function icebergTableInputRefusalMessage(logicalId, key, mode) {
|
|
34034
|
-
return `AWS::Glue::Table ${logicalId}: OpenTableFormatInput.IcebergInput.${key} ${mode === "create" ? `cannot be deployed by AWS in any shape, so cdkd refuses it before calling Glue (issue #1454).` : "cannot be deployed by AWS in any shape and is IGNORED on update — cdkd does not wire Glue's update-only UpdateOpenTableFormatInput shape, so it forwards nothing here and only warns (issue #1454). A CREATE of this table would be refused outright."}\n Live-probed 2026-08-09 in us-east-1 (issue #1408): glue:CreateTable — the API cdkd calls — rejects every Iceberg table spec ("Location information cannot be null while creating an iceberg table" without a TableInput.StorageDescriptor, "Table metadata information present at multiple parts of input request" with one), and CloudFormation rolls the same template back with "Table metadata is expected only via TableInput or via IcebergTableInputProperties inside OpenTableFormatInput" — a property name that exists in neither the CFn registry schema (IcebergInput.IcebergTableInput) nor @aws-sdk/client-glue (IcebergInput.CreateIcebergTableInput).\n Working shape — put the table metadata in TableInput and leave IcebergInput carrying only the create-time directive:\n TableInput: { Name, TableType: 'EXTERNAL_TABLE', StorageDescriptor: { Location: 's3://your-bucket/prefix/', Columns: [...] } }\n OpenTableFormatInput: { IcebergInput: { MetadataOperation: 'CREATE' } } // Version: '2' is also accepted\n Glue then writes the Iceberg metadata itself — the created table comes back with Parameters.table_type = ICEBERG and a populated Parameters.metadata_location.`;
|
|
34062
|
+
return `AWS::Glue::Table ${logicalId}: OpenTableFormatInput.IcebergInput.${key} ${mode === "create" ? `cannot be deployed by AWS in any shape, so cdkd refuses it before calling Glue (issue #1454).` : mode === "create-replay" ? "cannot be deployed by AWS in any shape, so cdkd normally refuses it before calling Glue (issue #1454) — but this create is REPLAYING a historical cdkd STATE record (a rollback reverse-replacement re-creating the OLD table), not your template, and refusing would leave that table unrestorable with no template-side remedy, only a hand-edit of state.json. cdkd therefore warns and proceeds (issue #1463). The re-created table is DEGRADED exactly as the original was: under the CFn spelling IcebergTableInput the AWS SDK serializer drops the unknown member (issue #1390), so the table comes back without its Iceberg metadata; under the SDK spelling CreateIcebergTableInput the value IS sent and Glue rejects the call, failing this one rollback operation. Either way, fix it forward with 'cdkd deploy' using the working shape below." : "cannot be deployed by AWS in any shape and is IGNORED on update — cdkd does not wire Glue's update-only UpdateOpenTableFormatInput shape, so it forwards nothing here and only warns (issue #1454). A CREATE of this table would be refused outright."}\n Live-probed 2026-08-09 in us-east-1 (issue #1408): glue:CreateTable — the API cdkd calls — rejects every Iceberg table spec ("Location information cannot be null while creating an iceberg table" without a TableInput.StorageDescriptor, "Table metadata information present at multiple parts of input request" with one), and CloudFormation rolls the same template back with "Table metadata is expected only via TableInput or via IcebergTableInputProperties inside OpenTableFormatInput" — a property name that exists in neither the CFn registry schema (IcebergInput.IcebergTableInput) nor @aws-sdk/client-glue (IcebergInput.CreateIcebergTableInput).\n Working shape — put the table metadata in TableInput and leave IcebergInput carrying only the create-time directive:\n TableInput: { Name, TableType: 'EXTERNAL_TABLE', StorageDescriptor: { Location: 's3://your-bucket/prefix/', Columns: [...] } }\n OpenTableFormatInput: { IcebergInput: { MetadataOperation: 'CREATE' } } // Version: '2' is also accepted\n Glue then writes the Iceberg metadata itself — the created table comes back with Parameters.table_type = ICEBERG and a populated Parameters.metadata_location.`;
|
|
34035
34063
|
}
|
|
34036
34064
|
/**
|
|
34037
34065
|
* Build the SDK `EncryptionConfiguration` from the CFn-shape input
|
|
@@ -36093,7 +36121,8 @@ var KinesisStreamProvider = class {
|
|
|
36093
36121
|
this.logger.debug(`Creating Kinesis stream ${logicalId}`);
|
|
36094
36122
|
const streamName = properties["Name"] || generateResourceName(logicalId, { maxLength: 128 });
|
|
36095
36123
|
try {
|
|
36096
|
-
const
|
|
36124
|
+
const streamModeDetails = properties["StreamModeDetails"];
|
|
36125
|
+
const streamMode = readConfigString(streamModeDetails, "StreamMode", "PROVISIONED", "AWS::Kinesis::Stream StreamModeDetails");
|
|
36097
36126
|
const shardCount = streamMode === "PROVISIONED" ? Number(properties["ShardCount"] ?? 1) : void 0;
|
|
36098
36127
|
await this.getClient().send(new CreateStreamCommand({
|
|
36099
36128
|
StreamName: streamName,
|
|
@@ -36157,7 +36186,8 @@ var KinesisStreamProvider = class {
|
|
|
36157
36186
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
36158
36187
|
this.logger.debug(`Updating Kinesis stream ${logicalId}: ${physicalId}`);
|
|
36159
36188
|
try {
|
|
36160
|
-
const
|
|
36189
|
+
const streamModeDetails = properties["StreamModeDetails"];
|
|
36190
|
+
const streamMode = readConfigString(streamModeDetails, "StreamMode", "PROVISIONED", "AWS::Kinesis::Stream StreamModeDetails");
|
|
36161
36191
|
const oldStreamMode = previousProperties["StreamModeDetails"]?.["StreamMode"] || "PROVISIONED";
|
|
36162
36192
|
const modeChanged = oldStreamMode !== streamMode;
|
|
36163
36193
|
if (modeChanged) {
|
|
@@ -43460,7 +43490,7 @@ var S3DirectoryBucketProvider = class {
|
|
|
43460
43490
|
*/
|
|
43461
43491
|
async create(logicalId, resourceType, properties) {
|
|
43462
43492
|
this.logger.debug(`Creating S3 Express Directory Bucket ${logicalId}`);
|
|
43463
|
-
const dataRedundancy = properties["DataRedundancy"]
|
|
43493
|
+
const dataRedundancy = requireConfigString(properties["DataRedundancy"], "SingleAvailabilityZone", "AWS::S3Express::DirectoryBucket DataRedundancy");
|
|
43464
43494
|
const azName = properties["LocationName"]?.replace(/--x-s3$/, "") || "us-east-1a";
|
|
43465
43495
|
const azId = await this.getAzId(azName);
|
|
43466
43496
|
let bucketName = properties["BucketName"];
|
|
@@ -65936,7 +65966,7 @@ function createMigrateCommand() {
|
|
|
65936
65966
|
*/
|
|
65937
65967
|
function buildProgram() {
|
|
65938
65968
|
const program = new Command();
|
|
65939
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.
|
|
65969
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.28");
|
|
65940
65970
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
65941
65971
|
const { profile } = actionCommand.optsWithGlobals();
|
|
65942
65972
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|