@go-to-k/cdkd 0.51.10 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +419 -57
- package/dist/cli.js.map +3 -3
- package/dist/go-to-k-cdkd-0.53.0.tgz +0 -0
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.51.10.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -17059,11 +17059,15 @@ var DynamoDBTableProvider = class {
|
|
|
17059
17059
|
// src/provisioning/providers/logs-loggroup-provider.ts
|
|
17060
17060
|
import {
|
|
17061
17061
|
CreateLogGroupCommand,
|
|
17062
|
+
DeleteIndexPolicyCommand,
|
|
17062
17063
|
DeleteLogGroupCommand,
|
|
17063
17064
|
DescribeIndexPoliciesCommand,
|
|
17064
17065
|
DescribeLogGroupsCommand,
|
|
17065
17066
|
GetDataProtectionPolicyCommand,
|
|
17066
17067
|
ListTagsForResourceCommand as ListTagsForResourceCommand2,
|
|
17068
|
+
PutBearerTokenAuthenticationCommand,
|
|
17069
|
+
PutIndexPolicyCommand,
|
|
17070
|
+
PutLogGroupDeletionProtectionCommand,
|
|
17067
17071
|
PutRetentionPolicyCommand,
|
|
17068
17072
|
DeleteRetentionPolicyCommand,
|
|
17069
17073
|
TagResourceCommand as TagResourceCommand5,
|
|
@@ -17116,6 +17120,9 @@ var LogsLogGroupProvider = class {
|
|
|
17116
17120
|
if (properties["LogGroupClass"]) {
|
|
17117
17121
|
createParams.logGroupClass = properties["LogGroupClass"];
|
|
17118
17122
|
}
|
|
17123
|
+
if (properties["DeletionProtectionEnabled"] !== void 0) {
|
|
17124
|
+
createParams.deletionProtectionEnabled = properties["DeletionProtectionEnabled"];
|
|
17125
|
+
}
|
|
17119
17126
|
if (properties["Tags"]) {
|
|
17120
17127
|
const cfnTags = properties["Tags"];
|
|
17121
17128
|
createParams.tags = Object.fromEntries(cfnTags.map((t) => [t.Key, t.Value]));
|
|
@@ -17139,6 +17146,30 @@ var LogsLogGroupProvider = class {
|
|
|
17139
17146
|
})
|
|
17140
17147
|
);
|
|
17141
17148
|
}
|
|
17149
|
+
const fieldIndexPolicies = properties["FieldIndexPolicies"];
|
|
17150
|
+
if (fieldIndexPolicies && fieldIndexPolicies.length > 0) {
|
|
17151
|
+
if (fieldIndexPolicies.length > 1) {
|
|
17152
|
+
this.logger.debug(
|
|
17153
|
+
`Log group ${logicalId} declares ${fieldIndexPolicies.length} FieldIndexPolicies; AWS only supports one log-group-level field index policy. Applying the first.`
|
|
17154
|
+
);
|
|
17155
|
+
}
|
|
17156
|
+
const first = fieldIndexPolicies[0];
|
|
17157
|
+
const policyDocument = typeof first === "string" ? first : JSON.stringify(first);
|
|
17158
|
+
await this.logsClient.send(
|
|
17159
|
+
new PutIndexPolicyCommand({
|
|
17160
|
+
logGroupIdentifier: logGroupName,
|
|
17161
|
+
policyDocument
|
|
17162
|
+
})
|
|
17163
|
+
);
|
|
17164
|
+
}
|
|
17165
|
+
if (properties["BearerTokenAuthenticationEnabled"] !== void 0) {
|
|
17166
|
+
await this.logsClient.send(
|
|
17167
|
+
new PutBearerTokenAuthenticationCommand({
|
|
17168
|
+
logGroupIdentifier: logGroupName,
|
|
17169
|
+
bearerTokenAuthenticationEnabled: properties["BearerTokenAuthenticationEnabled"]
|
|
17170
|
+
})
|
|
17171
|
+
);
|
|
17172
|
+
}
|
|
17142
17173
|
this.logger.debug(`Successfully created log group ${logicalId}: ${logGroupName}`);
|
|
17143
17174
|
const arn = await this.buildArn(logGroupName);
|
|
17144
17175
|
return {
|
|
@@ -17171,7 +17202,10 @@ var LogsLogGroupProvider = class {
|
|
|
17171
17202
|
/**
|
|
17172
17203
|
* Update a CloudWatch Logs log group
|
|
17173
17204
|
*
|
|
17174
|
-
*
|
|
17205
|
+
* Mutable: `RetentionInDays`, `DataProtectionPolicy`, `Tags`,
|
|
17206
|
+
* `DeletionProtectionEnabled`, `BearerTokenAuthenticationEnabled`,
|
|
17207
|
+
* `FieldIndexPolicies`. `LogGroupName` / `KmsKeyId` / `LogGroupClass`
|
|
17208
|
+
* are immutable on AWS-side and require replacement.
|
|
17175
17209
|
*/
|
|
17176
17210
|
async update(logicalId, physicalId, _resourceType, properties, previousProperties) {
|
|
17177
17211
|
this.logger.debug(`Updating log group ${logicalId}: ${physicalId}`);
|
|
@@ -17210,6 +17244,70 @@ var LogsLogGroupProvider = class {
|
|
|
17210
17244
|
);
|
|
17211
17245
|
}
|
|
17212
17246
|
}
|
|
17247
|
+
if (properties["DeletionProtectionEnabled"] !== previousProperties["DeletionProtectionEnabled"]) {
|
|
17248
|
+
const next = properties["DeletionProtectionEnabled"];
|
|
17249
|
+
if (next !== void 0) {
|
|
17250
|
+
await this.logsClient.send(
|
|
17251
|
+
new PutLogGroupDeletionProtectionCommand({
|
|
17252
|
+
logGroupIdentifier: physicalId,
|
|
17253
|
+
deletionProtectionEnabled: next
|
|
17254
|
+
})
|
|
17255
|
+
);
|
|
17256
|
+
} else {
|
|
17257
|
+
await this.logsClient.send(
|
|
17258
|
+
new PutLogGroupDeletionProtectionCommand({
|
|
17259
|
+
logGroupIdentifier: physicalId,
|
|
17260
|
+
deletionProtectionEnabled: false
|
|
17261
|
+
})
|
|
17262
|
+
);
|
|
17263
|
+
}
|
|
17264
|
+
}
|
|
17265
|
+
if (properties["BearerTokenAuthenticationEnabled"] !== previousProperties["BearerTokenAuthenticationEnabled"]) {
|
|
17266
|
+
const next = properties["BearerTokenAuthenticationEnabled"];
|
|
17267
|
+
if (next !== void 0) {
|
|
17268
|
+
await this.logsClient.send(
|
|
17269
|
+
new PutBearerTokenAuthenticationCommand({
|
|
17270
|
+
logGroupIdentifier: physicalId,
|
|
17271
|
+
bearerTokenAuthenticationEnabled: next
|
|
17272
|
+
})
|
|
17273
|
+
);
|
|
17274
|
+
} else {
|
|
17275
|
+
await this.logsClient.send(
|
|
17276
|
+
new PutBearerTokenAuthenticationCommand({
|
|
17277
|
+
logGroupIdentifier: physicalId,
|
|
17278
|
+
bearerTokenAuthenticationEnabled: false
|
|
17279
|
+
})
|
|
17280
|
+
);
|
|
17281
|
+
}
|
|
17282
|
+
}
|
|
17283
|
+
const newFieldIndex = properties["FieldIndexPolicies"];
|
|
17284
|
+
const oldFieldIndex = previousProperties["FieldIndexPolicies"];
|
|
17285
|
+
if (JSON.stringify(newFieldIndex) !== JSON.stringify(oldFieldIndex)) {
|
|
17286
|
+
if (newFieldIndex && newFieldIndex.length > 0) {
|
|
17287
|
+
if (newFieldIndex.length > 1) {
|
|
17288
|
+
this.logger.debug(
|
|
17289
|
+
`Log group ${physicalId} declares ${newFieldIndex.length} FieldIndexPolicies; AWS only supports one log-group-level field index policy. Applying the first.`
|
|
17290
|
+
);
|
|
17291
|
+
}
|
|
17292
|
+
const first = newFieldIndex[0];
|
|
17293
|
+
const policyDocument = typeof first === "string" ? first : JSON.stringify(first);
|
|
17294
|
+
await this.logsClient.send(
|
|
17295
|
+
new PutIndexPolicyCommand({
|
|
17296
|
+
logGroupIdentifier: physicalId,
|
|
17297
|
+
policyDocument
|
|
17298
|
+
})
|
|
17299
|
+
);
|
|
17300
|
+
} else {
|
|
17301
|
+
try {
|
|
17302
|
+
await this.logsClient.send(
|
|
17303
|
+
new DeleteIndexPolicyCommand({ logGroupIdentifier: physicalId })
|
|
17304
|
+
);
|
|
17305
|
+
} catch (err) {
|
|
17306
|
+
if (!(err instanceof ResourceNotFoundException7))
|
|
17307
|
+
throw err;
|
|
17308
|
+
}
|
|
17309
|
+
}
|
|
17310
|
+
}
|
|
17213
17311
|
const newTags = properties["Tags"];
|
|
17214
17312
|
const oldTags = previousProperties["Tags"];
|
|
17215
17313
|
if (JSON.stringify(newTags) !== JSON.stringify(oldTags)) {
|
|
@@ -17326,14 +17424,15 @@ var LogsLogGroupProvider = class {
|
|
|
17326
17424
|
* `AWS::Logs::ResourcePolicy` resource type — account-wide, not
|
|
17327
17425
|
* per-log-group).
|
|
17328
17426
|
*
|
|
17329
|
-
*
|
|
17330
|
-
*
|
|
17331
|
-
*
|
|
17332
|
-
*
|
|
17333
|
-
* `
|
|
17334
|
-
*
|
|
17335
|
-
*
|
|
17336
|
-
*
|
|
17427
|
+
* Write-side coverage: `FieldIndexPolicies` is applied via
|
|
17428
|
+
* `PutIndexPolicy` (CloudWatch Logs allows at most one log-group-level
|
|
17429
|
+
* field index policy at a time, so the CFn array is effectively 0-or-1
|
|
17430
|
+
* — the first entry is applied and a debug log notes any additional
|
|
17431
|
+
* entries are ignored). `DeletionProtectionEnabled` is forwarded as
|
|
17432
|
+
* part of `CreateLogGroup` and updated via
|
|
17433
|
+
* `PutLogGroupDeletionProtection`. `BearerTokenAuthenticationEnabled`
|
|
17434
|
+
* is applied via `PutBearerTokenAuthentication` after the log group
|
|
17435
|
+
* exists (it is not part of `CreateLogGroupRequest`).
|
|
17337
17436
|
*
|
|
17338
17437
|
* Tags are read via `ListTagsForResource` (using the log-group ARN from
|
|
17339
17438
|
* the same `DescribeLogGroups` response). CDK's `aws:*` auto-tags are
|
|
@@ -31574,8 +31673,10 @@ var ElastiCacheProvider = class {
|
|
|
31574
31673
|
import {
|
|
31575
31674
|
ServiceDiscoveryClient,
|
|
31576
31675
|
CreatePrivateDnsNamespaceCommand,
|
|
31676
|
+
UpdatePrivateDnsNamespaceCommand,
|
|
31577
31677
|
DeleteNamespaceCommand,
|
|
31578
31678
|
CreateServiceCommand as CreateServiceCommand2,
|
|
31679
|
+
UpdateServiceCommand as UpdateServiceCommand2,
|
|
31579
31680
|
DeleteServiceCommand as DeleteServiceCommand2,
|
|
31580
31681
|
GetNamespaceCommand,
|
|
31581
31682
|
GetOperationCommand,
|
|
@@ -31637,12 +31738,18 @@ var ServiceDiscoveryProvider = class {
|
|
|
31637
31738
|
);
|
|
31638
31739
|
}
|
|
31639
31740
|
}
|
|
31640
|
-
update(logicalId, physicalId, resourceType,
|
|
31741
|
+
update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
31641
31742
|
switch (resourceType) {
|
|
31642
31743
|
case "AWS::ServiceDiscovery::PrivateDnsNamespace":
|
|
31643
|
-
return this.updateNamespace(logicalId, physicalId);
|
|
31744
|
+
return this.updateNamespace(logicalId, physicalId, resourceType, properties);
|
|
31644
31745
|
case "AWS::ServiceDiscovery::Service":
|
|
31645
|
-
return this.updateService(
|
|
31746
|
+
return this.updateService(
|
|
31747
|
+
logicalId,
|
|
31748
|
+
physicalId,
|
|
31749
|
+
resourceType,
|
|
31750
|
+
properties,
|
|
31751
|
+
previousProperties
|
|
31752
|
+
);
|
|
31646
31753
|
default:
|
|
31647
31754
|
throw new ProvisioningError(
|
|
31648
31755
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -31725,14 +31832,66 @@ var ServiceDiscoveryProvider = class {
|
|
|
31725
31832
|
);
|
|
31726
31833
|
}
|
|
31727
31834
|
}
|
|
31728
|
-
|
|
31729
|
-
|
|
31730
|
-
|
|
31731
|
-
|
|
31835
|
+
/**
|
|
31836
|
+
* Update a private DNS namespace.
|
|
31837
|
+
*
|
|
31838
|
+
* AWS exposes `UpdatePrivateDnsNamespace` for two mutable surfaces:
|
|
31839
|
+
* - `Description`
|
|
31840
|
+
* - `Properties.DnsProperties.SOA.TTL`
|
|
31841
|
+
*
|
|
31842
|
+
* `Name` and `Vpc` are immutable; the deploy engine's
|
|
31843
|
+
* replacement-detection layer routes those through DELETE+CREATE
|
|
31844
|
+
* before this method is ever called, so we do not validate them here.
|
|
31845
|
+
*
|
|
31846
|
+
* Empty-string Description is intentionally allowed through (`!== undefined`
|
|
31847
|
+
* gate, not truthy) so `cdkd drift --revert` can clear a console-side ADD.
|
|
31848
|
+
*/
|
|
31849
|
+
async updateNamespace(logicalId, physicalId, resourceType, properties) {
|
|
31850
|
+
this.logger.debug(`Updating private DNS namespace ${logicalId}: ${physicalId}`);
|
|
31851
|
+
const client = this.getClient();
|
|
31852
|
+
const namespaceChange = {};
|
|
31853
|
+
if (properties["Description"] !== void 0) {
|
|
31854
|
+
namespaceChange.Description = properties["Description"];
|
|
31855
|
+
}
|
|
31856
|
+
const propsBag = properties["Properties"];
|
|
31857
|
+
const dnsProps = propsBag?.["DnsProperties"];
|
|
31858
|
+
const soa = dnsProps?.["SOA"];
|
|
31859
|
+
if (soa?.TTL !== void 0) {
|
|
31860
|
+
namespaceChange.Properties = {
|
|
31861
|
+
DnsProperties: {
|
|
31862
|
+
SOA: { TTL: Number(soa.TTL) }
|
|
31863
|
+
}
|
|
31864
|
+
};
|
|
31865
|
+
}
|
|
31866
|
+
if (Object.keys(namespaceChange).length === 0) {
|
|
31867
|
+
this.logger.debug(`No mutable diff for PrivateDnsNamespace ${logicalId}, skipping update`);
|
|
31868
|
+
return { physicalId, wasReplaced: false };
|
|
31869
|
+
}
|
|
31870
|
+
try {
|
|
31871
|
+
const response = await client.send(
|
|
31872
|
+
new UpdatePrivateDnsNamespaceCommand({
|
|
31873
|
+
Id: physicalId,
|
|
31874
|
+
Namespace: namespaceChange
|
|
31875
|
+
})
|
|
31876
|
+
);
|
|
31877
|
+
const operationId = response.OperationId;
|
|
31878
|
+
if (operationId) {
|
|
31879
|
+
await this.pollOperation(operationId, logicalId, resourceType);
|
|
31880
|
+
}
|
|
31881
|
+
this.logger.debug(`Successfully updated private DNS namespace ${logicalId}`);
|
|
31882
|
+
return { physicalId, wasReplaced: false };
|
|
31883
|
+
} catch (error) {
|
|
31884
|
+
if (error instanceof ProvisioningError)
|
|
31885
|
+
throw error;
|
|
31886
|
+
const cause = error instanceof Error ? error : void 0;
|
|
31887
|
+
throw new ProvisioningError(
|
|
31888
|
+
`Failed to update private DNS namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
31889
|
+
resourceType,
|
|
31732
31890
|
logicalId,
|
|
31733
|
-
|
|
31734
|
-
|
|
31735
|
-
|
|
31891
|
+
physicalId,
|
|
31892
|
+
cause
|
|
31893
|
+
);
|
|
31894
|
+
}
|
|
31736
31895
|
}
|
|
31737
31896
|
async deleteNamespace(logicalId, physicalId, resourceType, context) {
|
|
31738
31897
|
this.logger.debug(`Deleting private DNS namespace ${logicalId}: ${physicalId}`);
|
|
@@ -31827,14 +31986,69 @@ var ServiceDiscoveryProvider = class {
|
|
|
31827
31986
|
);
|
|
31828
31987
|
}
|
|
31829
31988
|
}
|
|
31830
|
-
|
|
31831
|
-
|
|
31832
|
-
|
|
31833
|
-
|
|
31989
|
+
/**
|
|
31990
|
+
* Update a service discovery service.
|
|
31991
|
+
*
|
|
31992
|
+
* Per AWS docs, `UpdateService` accepts a `ServiceChange` body with
|
|
31993
|
+
* `Description`, `DnsConfig.DnsRecords` (TTLs etc. — `NamespaceId` /
|
|
31994
|
+
* `RoutingPolicy` are not part of the change shape and are immutable
|
|
31995
|
+
* here), and `HealthCheckConfig`. `Name` / `NamespaceId` /
|
|
31996
|
+
* `HealthCheckCustomConfig` are immutable on UpdateService — the
|
|
31997
|
+
* replacement-detection layer routes those through DELETE+CREATE.
|
|
31998
|
+
*
|
|
31999
|
+
* Per AWS docs, omitting `DnsRecords` / `HealthCheckConfig` from the
|
|
32000
|
+
* request DELETES that configuration. To preserve fields cdkd is not
|
|
32001
|
+
* actively reverting, we always echo the AWS-current value when the
|
|
32002
|
+
* caller did not supply a change. `cdkd drift --revert` passes the
|
|
32003
|
+
* full AWS-current snapshot as `properties`, so the round-trip is
|
|
32004
|
+
* value-preserving.
|
|
32005
|
+
*/
|
|
32006
|
+
async updateService(logicalId, physicalId, resourceType, properties, _previousProperties) {
|
|
32007
|
+
this.logger.debug(`Updating service discovery service ${logicalId}: ${physicalId}`);
|
|
32008
|
+
const client = this.getClient();
|
|
32009
|
+
const serviceChange = {};
|
|
32010
|
+
if (properties["Description"] !== void 0) {
|
|
32011
|
+
serviceChange.Description = properties["Description"];
|
|
32012
|
+
}
|
|
32013
|
+
const dnsConfig = properties["DnsConfig"];
|
|
32014
|
+
if (dnsConfig?.DnsRecords !== void 0) {
|
|
32015
|
+
const change = { DnsRecords: dnsConfig.DnsRecords };
|
|
32016
|
+
serviceChange.DnsConfig = change;
|
|
32017
|
+
}
|
|
32018
|
+
if (properties["HealthCheckConfig"] !== void 0) {
|
|
32019
|
+
serviceChange.HealthCheckConfig = properties["HealthCheckConfig"];
|
|
32020
|
+
}
|
|
32021
|
+
if (Object.keys(serviceChange).length === 0) {
|
|
32022
|
+
this.logger.debug(
|
|
32023
|
+
`No mutable diff for ServiceDiscovery Service ${logicalId}, skipping update`
|
|
32024
|
+
);
|
|
32025
|
+
return { physicalId, wasReplaced: false };
|
|
32026
|
+
}
|
|
32027
|
+
try {
|
|
32028
|
+
const response = await client.send(
|
|
32029
|
+
new UpdateServiceCommand2({
|
|
32030
|
+
Id: physicalId,
|
|
32031
|
+
Service: serviceChange
|
|
32032
|
+
})
|
|
32033
|
+
);
|
|
32034
|
+
const operationId = response.OperationId;
|
|
32035
|
+
if (operationId) {
|
|
32036
|
+
await this.pollOperation(operationId, logicalId, resourceType);
|
|
32037
|
+
}
|
|
32038
|
+
this.logger.debug(`Successfully updated service discovery service ${logicalId}`);
|
|
32039
|
+
return { physicalId, wasReplaced: false };
|
|
32040
|
+
} catch (error) {
|
|
32041
|
+
if (error instanceof ProvisioningError)
|
|
32042
|
+
throw error;
|
|
32043
|
+
const cause = error instanceof Error ? error : void 0;
|
|
32044
|
+
throw new ProvisioningError(
|
|
32045
|
+
`Failed to update service discovery service ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
32046
|
+
resourceType,
|
|
31834
32047
|
logicalId,
|
|
31835
|
-
|
|
31836
|
-
|
|
31837
|
-
|
|
32048
|
+
physicalId,
|
|
32049
|
+
cause
|
|
32050
|
+
);
|
|
32051
|
+
}
|
|
31838
32052
|
}
|
|
31839
32053
|
async deleteService(logicalId, physicalId, resourceType, context) {
|
|
31840
32054
|
this.logger.debug(`Deleting service discovery service ${logicalId}: ${physicalId}`);
|
|
@@ -32921,6 +33135,7 @@ var AppSyncProvider = class {
|
|
|
32921
33135
|
import {
|
|
32922
33136
|
GlueClient,
|
|
32923
33137
|
CreateDatabaseCommand,
|
|
33138
|
+
UpdateDatabaseCommand,
|
|
32924
33139
|
DeleteDatabaseCommand,
|
|
32925
33140
|
CreateTableCommand as CreateTableCommand2,
|
|
32926
33141
|
UpdateTableCommand,
|
|
@@ -32967,11 +33182,7 @@ var GlueProvider = class {
|
|
|
32967
33182
|
async update(logicalId, physicalId, resourceType, properties, _previousProperties) {
|
|
32968
33183
|
switch (resourceType) {
|
|
32969
33184
|
case "AWS::Glue::Database":
|
|
32970
|
-
|
|
32971
|
-
resourceType,
|
|
32972
|
-
logicalId,
|
|
32973
|
-
"Glue Database updates are not yet implemented in cdkd; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
32974
|
-
);
|
|
33185
|
+
return this.updateDatabase(logicalId, physicalId, resourceType, properties);
|
|
32975
33186
|
case "AWS::Glue::Table":
|
|
32976
33187
|
return this.updateTable(logicalId, physicalId, resourceType, properties);
|
|
32977
33188
|
default:
|
|
@@ -33022,12 +33233,7 @@ var GlueProvider = class {
|
|
|
33022
33233
|
await this.getClient().send(
|
|
33023
33234
|
new CreateDatabaseCommand({
|
|
33024
33235
|
CatalogId: catalogId,
|
|
33025
|
-
DatabaseInput:
|
|
33026
|
-
Name: databaseName,
|
|
33027
|
-
Description: databaseInput["Description"],
|
|
33028
|
-
LocationUri: databaseInput["LocationUri"],
|
|
33029
|
-
Parameters: databaseInput["Parameters"]
|
|
33030
|
-
}
|
|
33236
|
+
DatabaseInput: this.buildDatabaseInput(databaseInput, databaseName)
|
|
33031
33237
|
})
|
|
33032
33238
|
);
|
|
33033
33239
|
this.logger.debug(`Successfully created Glue Database ${logicalId}: ${databaseName}`);
|
|
@@ -33046,6 +33252,42 @@ var GlueProvider = class {
|
|
|
33046
33252
|
);
|
|
33047
33253
|
}
|
|
33048
33254
|
}
|
|
33255
|
+
async updateDatabase(logicalId, physicalId, resourceType, properties) {
|
|
33256
|
+
this.logger.debug(`Updating Glue Database ${logicalId}: ${physicalId}`);
|
|
33257
|
+
const databaseInput = properties["DatabaseInput"];
|
|
33258
|
+
if (!databaseInput) {
|
|
33259
|
+
throw new ProvisioningError(
|
|
33260
|
+
`DatabaseInput is required for Glue Database update ${logicalId}`,
|
|
33261
|
+
resourceType,
|
|
33262
|
+
logicalId,
|
|
33263
|
+
physicalId
|
|
33264
|
+
);
|
|
33265
|
+
}
|
|
33266
|
+
const catalogId = properties["CatalogId"];
|
|
33267
|
+
try {
|
|
33268
|
+
await this.getClient().send(
|
|
33269
|
+
new UpdateDatabaseCommand({
|
|
33270
|
+
...catalogId !== void 0 && { CatalogId: catalogId },
|
|
33271
|
+
Name: physicalId,
|
|
33272
|
+
DatabaseInput: this.buildDatabaseInput(databaseInput, physicalId)
|
|
33273
|
+
})
|
|
33274
|
+
);
|
|
33275
|
+
this.logger.debug(`Successfully updated Glue Database ${logicalId}`);
|
|
33276
|
+
return {
|
|
33277
|
+
physicalId,
|
|
33278
|
+
wasReplaced: false
|
|
33279
|
+
};
|
|
33280
|
+
} catch (error) {
|
|
33281
|
+
const cause = error instanceof Error ? error : void 0;
|
|
33282
|
+
throw new ProvisioningError(
|
|
33283
|
+
`Failed to update Glue Database ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
33284
|
+
resourceType,
|
|
33285
|
+
logicalId,
|
|
33286
|
+
physicalId,
|
|
33287
|
+
cause
|
|
33288
|
+
);
|
|
33289
|
+
}
|
|
33290
|
+
}
|
|
33049
33291
|
async deleteDatabase(logicalId, physicalId, resourceType, properties, context) {
|
|
33050
33292
|
this.logger.debug(`Deleting Glue Database ${logicalId}: ${physicalId}`);
|
|
33051
33293
|
try {
|
|
@@ -33217,6 +33459,31 @@ var GlueProvider = class {
|
|
|
33217
33459
|
}
|
|
33218
33460
|
}
|
|
33219
33461
|
// ─── Helpers ───────────────────────────────────────────────────────
|
|
33462
|
+
/**
|
|
33463
|
+
* Build DatabaseInput for Glue API from CFn template properties.
|
|
33464
|
+
*
|
|
33465
|
+
* Used by both `createDatabase` and `updateDatabase` so the same
|
|
33466
|
+
* field-by-field shape is sent on both paths. Optional fields use
|
|
33467
|
+
* `!== undefined` gates (per `feedback_update_optional_field_undefined_check.md`)
|
|
33468
|
+
* so empty-string Description, empty Parameters map, etc. reach AWS
|
|
33469
|
+
* intact — `cdkd drift --revert` relies on this to clear console-side
|
|
33470
|
+
* additions.
|
|
33471
|
+
*/
|
|
33472
|
+
buildDatabaseInput(databaseInput, fallbackName) {
|
|
33473
|
+
const result = {
|
|
33474
|
+
Name: databaseInput["Name"] ?? fallbackName
|
|
33475
|
+
};
|
|
33476
|
+
if (databaseInput["Description"] !== void 0) {
|
|
33477
|
+
result.Description = databaseInput["Description"];
|
|
33478
|
+
}
|
|
33479
|
+
if (databaseInput["LocationUri"] !== void 0) {
|
|
33480
|
+
result.LocationUri = databaseInput["LocationUri"];
|
|
33481
|
+
}
|
|
33482
|
+
if (databaseInput["Parameters"] !== void 0) {
|
|
33483
|
+
result.Parameters = databaseInput["Parameters"];
|
|
33484
|
+
}
|
|
33485
|
+
return result;
|
|
33486
|
+
}
|
|
33220
33487
|
/**
|
|
33221
33488
|
* Build TableInput for Glue API from CFn template properties
|
|
33222
33489
|
*/
|
|
@@ -33991,10 +34258,10 @@ var KMSProvider = class {
|
|
|
33991
34258
|
* Dispatches by resource type:
|
|
33992
34259
|
* - `AWS::KMS::Key` → `DescribeKey`. Surfaces `Description`, `KeySpec`,
|
|
33993
34260
|
* `KeyUsage`, `Enabled`, `MultiRegion`, `Origin`. `KeyPolicy` is
|
|
33994
|
-
*
|
|
33995
|
-
* and
|
|
33996
|
-
*
|
|
33997
|
-
*
|
|
34261
|
+
* additionally retrieved via `GetKeyPolicy` (URL-decoded JSON-parsed)
|
|
34262
|
+
* and `EnableKeyRotation` / `RotationPeriodInDays` via
|
|
34263
|
+
* `GetKeyRotationStatus` (Class 1 discriminator-gated on `KeySpec`
|
|
34264
|
+
* since asymmetric keys reject the call).
|
|
33998
34265
|
* - `AWS::KMS::Alias` → `ListAliases` filtered to the alias name.
|
|
33999
34266
|
* Surfaces `AliasName`, `TargetKeyId`. `ListAliases` is paginated
|
|
34000
34267
|
* since there's no direct "describe one alias" API.
|
|
@@ -34682,10 +34949,12 @@ var KinesisStreamProvider = class {
|
|
|
34682
34949
|
import {
|
|
34683
34950
|
EFSClient,
|
|
34684
34951
|
CreateFileSystemCommand,
|
|
34952
|
+
UpdateFileSystemCommand,
|
|
34685
34953
|
DeleteFileSystemCommand,
|
|
34686
34954
|
CreateMountTargetCommand,
|
|
34687
34955
|
DeleteMountTargetCommand,
|
|
34688
34956
|
DescribeMountTargetsCommand,
|
|
34957
|
+
ModifyMountTargetSecurityGroupsCommand,
|
|
34689
34958
|
CreateAccessPointCommand,
|
|
34690
34959
|
DeleteAccessPointCommand,
|
|
34691
34960
|
DescribeFileSystemsCommand,
|
|
@@ -34743,29 +35012,122 @@ var EFSProvider = class {
|
|
|
34743
35012
|
}
|
|
34744
35013
|
}
|
|
34745
35014
|
/**
|
|
34746
|
-
*
|
|
34747
|
-
*
|
|
34748
|
-
*
|
|
34749
|
-
*
|
|
34750
|
-
*
|
|
34751
|
-
*
|
|
35015
|
+
* Mutable surfaces by resource type:
|
|
35016
|
+
* - `AWS::EFS::FileSystem` → `UpdateFileSystem` (ThroughputMode,
|
|
35017
|
+
* ProvisionedThroughputInMibps). Other property changes
|
|
35018
|
+
* (Encrypted / KmsKeyId / PerformanceMode / etc.) are routed
|
|
35019
|
+
* through DELETE+CREATE by the replacement-detection layer; if a
|
|
35020
|
+
* diff somehow includes them, defensively reject.
|
|
35021
|
+
* - `AWS::EFS::MountTarget` → `ModifyMountTargetSecurityGroups`
|
|
35022
|
+
* (SecurityGroups only). IpAddress / SubnetId / FileSystemId are
|
|
35023
|
+
* immutable.
|
|
35024
|
+
* - `AWS::EFS::AccessPoint` → no mutable surface; AWS recreates on
|
|
35025
|
+
* every change. Reject so `cdkd drift --revert` surfaces a clear
|
|
35026
|
+
* "use --replace" hint.
|
|
34752
35027
|
*/
|
|
34753
|
-
update(logicalId, physicalId, resourceType,
|
|
34754
|
-
|
|
35028
|
+
update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
35029
|
+
switch (resourceType) {
|
|
35030
|
+
case "AWS::EFS::FileSystem":
|
|
35031
|
+
return this.updateFileSystem(
|
|
35032
|
+
logicalId,
|
|
35033
|
+
physicalId,
|
|
35034
|
+
resourceType,
|
|
35035
|
+
properties,
|
|
35036
|
+
previousProperties
|
|
35037
|
+
);
|
|
35038
|
+
case "AWS::EFS::MountTarget":
|
|
35039
|
+
return this.updateMountTarget(logicalId, physicalId, resourceType, properties);
|
|
35040
|
+
case "AWS::EFS::AccessPoint":
|
|
35041
|
+
return Promise.reject(
|
|
35042
|
+
new ResourceUpdateNotSupportedError(
|
|
35043
|
+
resourceType,
|
|
35044
|
+
logicalId,
|
|
35045
|
+
"EFS AccessPoint is recreated on property changes; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
35046
|
+
)
|
|
35047
|
+
);
|
|
35048
|
+
default:
|
|
35049
|
+
throw new ProvisioningError(
|
|
35050
|
+
`Unsupported resource type: ${resourceType}`,
|
|
35051
|
+
resourceType,
|
|
35052
|
+
logicalId,
|
|
35053
|
+
physicalId
|
|
35054
|
+
);
|
|
35055
|
+
}
|
|
35056
|
+
}
|
|
35057
|
+
async updateFileSystem(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
35058
|
+
const immutableKeys = ["Encrypted", "KmsKeyId", "PerformanceMode"];
|
|
35059
|
+
for (const key of immutableKeys) {
|
|
35060
|
+
const next = properties[key];
|
|
35061
|
+
const prev = previousProperties[key];
|
|
35062
|
+
if (next !== void 0 && prev !== void 0 && JSON.stringify(next) !== JSON.stringify(prev)) {
|
|
35063
|
+
throw new ResourceUpdateNotSupportedError(
|
|
35064
|
+
resourceType,
|
|
35065
|
+
logicalId,
|
|
35066
|
+
`EFS FileSystem ${key} is immutable; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack`
|
|
35067
|
+
);
|
|
35068
|
+
}
|
|
35069
|
+
}
|
|
35070
|
+
const newThroughputMode = properties["ThroughputMode"];
|
|
35071
|
+
const newProvisioned = properties["ProvisionedThroughputInMibps"];
|
|
35072
|
+
const oldThroughputMode = previousProperties["ThroughputMode"];
|
|
35073
|
+
const oldProvisioned = previousProperties["ProvisionedThroughputInMibps"];
|
|
35074
|
+
const throughputModeChanged = newThroughputMode !== void 0 && newThroughputMode !== oldThroughputMode;
|
|
35075
|
+
const provisionedChanged = newProvisioned !== void 0 && newProvisioned !== oldProvisioned;
|
|
35076
|
+
if (!throughputModeChanged && !provisionedChanged) {
|
|
35077
|
+
this.logger.debug(`No mutable diff for EFS FileSystem ${logicalId}, skipping update`);
|
|
35078
|
+
return { physicalId, wasReplaced: false };
|
|
35079
|
+
}
|
|
35080
|
+
this.logger.debug(`Updating EFS FileSystem ${logicalId}: ${physicalId}`);
|
|
35081
|
+
try {
|
|
35082
|
+
await this.getClient().send(
|
|
35083
|
+
new UpdateFileSystemCommand({
|
|
35084
|
+
FileSystemId: physicalId,
|
|
35085
|
+
...throughputModeChanged && { ThroughputMode: newThroughputMode },
|
|
35086
|
+
...provisionedChanged && { ProvisionedThroughputInMibps: newProvisioned }
|
|
35087
|
+
})
|
|
35088
|
+
);
|
|
35089
|
+
await this.waitForFileSystemAvailable(physicalId, logicalId, resourceType);
|
|
35090
|
+
this.logger.debug(`Successfully updated EFS FileSystem ${logicalId}`);
|
|
35091
|
+
return { physicalId, wasReplaced: false };
|
|
35092
|
+
} catch (error) {
|
|
35093
|
+
if (error instanceof ProvisioningError)
|
|
35094
|
+
throw error;
|
|
35095
|
+
const cause = error instanceof Error ? error : void 0;
|
|
34755
35096
|
throw new ProvisioningError(
|
|
34756
|
-
`
|
|
35097
|
+
`Failed to update EFS FileSystem ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
34757
35098
|
resourceType,
|
|
34758
35099
|
logicalId,
|
|
34759
|
-
physicalId
|
|
35100
|
+
physicalId,
|
|
35101
|
+
cause
|
|
34760
35102
|
);
|
|
34761
35103
|
}
|
|
34762
|
-
|
|
34763
|
-
|
|
35104
|
+
}
|
|
35105
|
+
async updateMountTarget(logicalId, physicalId, resourceType, properties) {
|
|
35106
|
+
this.logger.debug(`Updating EFS MountTarget ${logicalId}: ${physicalId}`);
|
|
35107
|
+
const securityGroups = properties["SecurityGroups"];
|
|
35108
|
+
if (securityGroups === void 0) {
|
|
35109
|
+
this.logger.debug(`No mutable diff for EFS MountTarget ${logicalId}, skipping update`);
|
|
35110
|
+
return { physicalId, wasReplaced: false };
|
|
35111
|
+
}
|
|
35112
|
+
try {
|
|
35113
|
+
await this.getClient().send(
|
|
35114
|
+
new ModifyMountTargetSecurityGroupsCommand({
|
|
35115
|
+
MountTargetId: physicalId,
|
|
35116
|
+
SecurityGroups: securityGroups
|
|
35117
|
+
})
|
|
35118
|
+
);
|
|
35119
|
+
this.logger.debug(`Successfully updated EFS MountTarget ${logicalId}`);
|
|
35120
|
+
return { physicalId, wasReplaced: false };
|
|
35121
|
+
} catch (error) {
|
|
35122
|
+
const cause = error instanceof Error ? error : void 0;
|
|
35123
|
+
throw new ProvisioningError(
|
|
35124
|
+
`Failed to update EFS MountTarget ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
34764
35125
|
resourceType,
|
|
34765
35126
|
logicalId,
|
|
34766
|
-
|
|
34767
|
-
|
|
34768
|
-
|
|
35127
|
+
physicalId,
|
|
35128
|
+
cause
|
|
35129
|
+
);
|
|
35130
|
+
}
|
|
34769
35131
|
}
|
|
34770
35132
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
34771
35133
|
switch (resourceType) {
|
|
@@ -45240,7 +45602,7 @@ function reorderArgs(argv) {
|
|
|
45240
45602
|
}
|
|
45241
45603
|
async function main() {
|
|
45242
45604
|
const program = new Command14();
|
|
45243
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
45605
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.53.0");
|
|
45244
45606
|
program.addCommand(createBootstrapCommand());
|
|
45245
45607
|
program.addCommand(createSynthCommand());
|
|
45246
45608
|
program.addCommand(createListCommand());
|