@go-to-k/cdkd 0.43.0 → 0.45.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 +377 -134
- package/dist/cli.js.map +3 -3
- package/dist/go-to-k-cdkd-0.45.0.tgz +0 -0
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.43.0.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -1187,6 +1187,22 @@ var PartialFailureError = class _PartialFailureError extends CdkdError {
|
|
|
1187
1187
|
Object.setPrototypeOf(this, _PartialFailureError.prototype);
|
|
1188
1188
|
}
|
|
1189
1189
|
};
|
|
1190
|
+
var ResourceUpdateNotSupportedError = class _ResourceUpdateNotSupportedError extends CdkdError {
|
|
1191
|
+
constructor(resourceType, logicalId, suggestion, cause) {
|
|
1192
|
+
const tail = suggestion ? suggestion : "use cdkd deploy with --replace, or change the resource definition to create a new version";
|
|
1193
|
+
super(
|
|
1194
|
+
`${resourceType} (${logicalId}) cannot be updated in place: ${tail}.`,
|
|
1195
|
+
"RESOURCE_UPDATE_NOT_SUPPORTED",
|
|
1196
|
+
cause
|
|
1197
|
+
);
|
|
1198
|
+
this.resourceType = resourceType;
|
|
1199
|
+
this.logicalId = logicalId;
|
|
1200
|
+
this.suggestion = suggestion;
|
|
1201
|
+
this.name = "ResourceUpdateNotSupportedError";
|
|
1202
|
+
Object.setPrototypeOf(this, _ResourceUpdateNotSupportedError.prototype);
|
|
1203
|
+
}
|
|
1204
|
+
exitCode = 2;
|
|
1205
|
+
};
|
|
1190
1206
|
function isCdkdError(error) {
|
|
1191
1207
|
return error instanceof CdkdError;
|
|
1192
1208
|
}
|
|
@@ -21335,20 +21351,22 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
21335
21351
|
}
|
|
21336
21352
|
}
|
|
21337
21353
|
/**
|
|
21338
|
-
* Update an API Gateway Authorizer
|
|
21354
|
+
* Update an API Gateway Authorizer.
|
|
21339
21355
|
*
|
|
21340
|
-
*
|
|
21341
|
-
*
|
|
21356
|
+
* AWS exposes `UpdateAuthorizer` (PATCH) but cdkd does not yet plumb the
|
|
21357
|
+
* patch-operations builder through. Authorizers are recreated by the
|
|
21358
|
+
* deploy engine's immutable-property replacement path. `cdkd drift
|
|
21359
|
+
* --revert` surfaces a clear "use --replace or re-deploy" message
|
|
21360
|
+
* instead of silently no-op'ing the revert.
|
|
21342
21361
|
*/
|
|
21343
|
-
updateAuthorizer(logicalId,
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21349
|
-
|
|
21350
|
-
|
|
21351
|
-
});
|
|
21362
|
+
updateAuthorizer(logicalId, _physicalId, _resourceType) {
|
|
21363
|
+
return Promise.reject(
|
|
21364
|
+
new ResourceUpdateNotSupportedError(
|
|
21365
|
+
"AWS::ApiGateway::Authorizer",
|
|
21366
|
+
logicalId,
|
|
21367
|
+
"API Gateway Authorizer updates are not yet implemented in cdkd; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
21368
|
+
)
|
|
21369
|
+
);
|
|
21352
21370
|
}
|
|
21353
21371
|
/**
|
|
21354
21372
|
* Delete an API Gateway Authorizer
|
|
@@ -21580,20 +21598,20 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
21580
21598
|
}
|
|
21581
21599
|
}
|
|
21582
21600
|
/**
|
|
21583
|
-
* Update an API Gateway Deployment
|
|
21601
|
+
* Update an API Gateway Deployment.
|
|
21584
21602
|
*
|
|
21585
|
-
* Deployments are immutable
|
|
21586
|
-
*
|
|
21603
|
+
* Deployments are immutable — every property change requires a fresh
|
|
21604
|
+
* Deployment. `cdkd drift --revert` therefore throws
|
|
21605
|
+
* `ResourceUpdateNotSupportedError` instead of silently no-op'ing.
|
|
21587
21606
|
*/
|
|
21588
|
-
updateDeployment(logicalId,
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
21592
|
-
|
|
21593
|
-
|
|
21594
|
-
|
|
21595
|
-
|
|
21596
|
-
});
|
|
21607
|
+
updateDeployment(logicalId, _physicalId, _resourceType) {
|
|
21608
|
+
return Promise.reject(
|
|
21609
|
+
new ResourceUpdateNotSupportedError(
|
|
21610
|
+
"AWS::ApiGateway::Deployment",
|
|
21611
|
+
logicalId,
|
|
21612
|
+
"API Gateway Deployment is immutable; re-deploy with cdkd deploy --replace, or change the resource definition to create a new Deployment"
|
|
21613
|
+
)
|
|
21614
|
+
);
|
|
21597
21615
|
}
|
|
21598
21616
|
/**
|
|
21599
21617
|
* Delete an API Gateway Deployment
|
|
@@ -21894,17 +21912,22 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
21894
21912
|
}
|
|
21895
21913
|
}
|
|
21896
21914
|
/**
|
|
21897
|
-
* Update an API Gateway Method
|
|
21915
|
+
* Update an API Gateway Method.
|
|
21898
21916
|
*
|
|
21899
|
-
*
|
|
21917
|
+
* AWS exposes `UpdateMethod` (PATCH) but cdkd does not yet plumb the
|
|
21918
|
+
* patch-operations builder through. Methods are recreated by the deploy
|
|
21919
|
+
* engine's immutable-property replacement path. `cdkd drift --revert`
|
|
21920
|
+
* surfaces a clear "use --replace or re-deploy" message instead of
|
|
21921
|
+
* silently no-op'ing the revert.
|
|
21900
21922
|
*/
|
|
21901
|
-
updateMethod(logicalId,
|
|
21902
|
-
|
|
21903
|
-
|
|
21904
|
-
|
|
21905
|
-
|
|
21906
|
-
|
|
21907
|
-
|
|
21923
|
+
updateMethod(logicalId, _physicalId) {
|
|
21924
|
+
return Promise.reject(
|
|
21925
|
+
new ResourceUpdateNotSupportedError(
|
|
21926
|
+
"AWS::ApiGateway::Method",
|
|
21927
|
+
logicalId,
|
|
21928
|
+
"API Gateway Method updates are not yet implemented in cdkd; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
21929
|
+
)
|
|
21930
|
+
);
|
|
21908
21931
|
}
|
|
21909
21932
|
/**
|
|
21910
21933
|
* Delete an API Gateway Method
|
|
@@ -22282,13 +22305,23 @@ var ApiGatewayV2Provider = class {
|
|
|
22282
22305
|
);
|
|
22283
22306
|
}
|
|
22284
22307
|
}
|
|
22285
|
-
|
|
22286
|
-
|
|
22287
|
-
|
|
22288
|
-
|
|
22289
|
-
|
|
22290
|
-
|
|
22291
|
-
|
|
22308
|
+
/**
|
|
22309
|
+
* HTTP API resources are treated as immutable by cdkd: the deploy engine
|
|
22310
|
+
* recreates them on property changes via the immutable-property
|
|
22311
|
+
* replacement path. AWS does expose `UpdateApi` / `UpdateRoute` /
|
|
22312
|
+
* `UpdateIntegration` / `UpdateStage` / `UpdateAuthorizer`, but cdkd
|
|
22313
|
+
* does not yet plumb them through. `cdkd drift --revert` surfaces a
|
|
22314
|
+
* clear "use --replace or re-deploy" message instead of silently
|
|
22315
|
+
* no-op'ing the revert.
|
|
22316
|
+
*/
|
|
22317
|
+
update(logicalId, _physicalId, resourceType, _properties, _previousProperties) {
|
|
22318
|
+
return Promise.reject(
|
|
22319
|
+
new ResourceUpdateNotSupportedError(
|
|
22320
|
+
resourceType,
|
|
22321
|
+
logicalId,
|
|
22322
|
+
"API Gateway V2 (HTTP API) resources are recreated on property changes; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
22323
|
+
)
|
|
22324
|
+
);
|
|
22292
22325
|
}
|
|
22293
22326
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
22294
22327
|
switch (resourceType) {
|
|
@@ -22964,6 +22997,7 @@ import {
|
|
|
22964
22997
|
CreateCloudFrontOriginAccessIdentityCommand,
|
|
22965
22998
|
DeleteCloudFrontOriginAccessIdentityCommand,
|
|
22966
22999
|
GetCloudFrontOriginAccessIdentityCommand as GetCloudFrontOriginAccessIdentityCommand2,
|
|
23000
|
+
UpdateCloudFrontOriginAccessIdentityCommand,
|
|
22967
23001
|
NoSuchCloudFrontOriginAccessIdentity
|
|
22968
23002
|
} from "@aws-sdk/client-cloudfront";
|
|
22969
23003
|
init_aws_clients();
|
|
@@ -23019,17 +23053,61 @@ var CloudFrontOAIProvider = class {
|
|
|
23019
23053
|
}
|
|
23020
23054
|
}
|
|
23021
23055
|
/**
|
|
23022
|
-
* Update a CloudFront Origin Access Identity
|
|
23056
|
+
* Update a CloudFront Origin Access Identity.
|
|
23057
|
+
*
|
|
23058
|
+
* Only the `Comment` field is mutable on an OAI; `CallerReference` is set
|
|
23059
|
+
* by cdkd at create time and cannot be changed. AWS exposes a single
|
|
23060
|
+
* `UpdateCloudFrontOriginAccessIdentity` call that requires the current
|
|
23061
|
+
* `ETag` (fetched via `GetCloudFrontOriginAccessIdentity`) and overwrites
|
|
23062
|
+
* the entire `CloudFrontOriginAccessIdentityConfig`.
|
|
23023
23063
|
*
|
|
23024
|
-
*
|
|
23025
|
-
*
|
|
23064
|
+
* Used by `cdkd drift --revert` to push the cdkd-state Comment back into
|
|
23065
|
+
* AWS; on the normal deploy path this is also exercised when a user
|
|
23066
|
+
* tweaks the Comment in their CDK code.
|
|
23026
23067
|
*/
|
|
23027
|
-
update(logicalId, physicalId,
|
|
23028
|
-
this.logger.debug(`
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23032
|
-
|
|
23068
|
+
async update(logicalId, physicalId, resourceType, properties, _previousProperties) {
|
|
23069
|
+
this.logger.debug(`Updating CloudFront OAI ${logicalId}: ${physicalId}`);
|
|
23070
|
+
const config = properties["CloudFrontOriginAccessIdentityConfig"];
|
|
23071
|
+
const comment = config?.["Comment"] ?? "";
|
|
23072
|
+
try {
|
|
23073
|
+
const getResponse = await this.cloudFrontClient.send(
|
|
23074
|
+
new GetCloudFrontOriginAccessIdentityCommand2({ Id: physicalId })
|
|
23075
|
+
);
|
|
23076
|
+
const etag = getResponse.ETag;
|
|
23077
|
+
if (!etag) {
|
|
23078
|
+
throw new Error("GetCloudFrontOriginAccessIdentity did not return ETag");
|
|
23079
|
+
}
|
|
23080
|
+
await this.cloudFrontClient.send(
|
|
23081
|
+
new UpdateCloudFrontOriginAccessIdentityCommand({
|
|
23082
|
+
Id: physicalId,
|
|
23083
|
+
IfMatch: etag,
|
|
23084
|
+
CloudFrontOriginAccessIdentityConfig: {
|
|
23085
|
+
// CallerReference is immutable; preserve whatever the OAI was
|
|
23086
|
+
// created with so AWS does not reject the update.
|
|
23087
|
+
CallerReference: getResponse.CloudFrontOriginAccessIdentity?.CloudFrontOriginAccessIdentityConfig?.CallerReference ?? logicalId,
|
|
23088
|
+
Comment: comment
|
|
23089
|
+
}
|
|
23090
|
+
})
|
|
23091
|
+
);
|
|
23092
|
+
this.logger.debug(`Successfully updated CloudFront OAI ${logicalId}`);
|
|
23093
|
+
return {
|
|
23094
|
+
physicalId,
|
|
23095
|
+
wasReplaced: false,
|
|
23096
|
+
attributes: {
|
|
23097
|
+
Id: physicalId,
|
|
23098
|
+
S3CanonicalUserId: getResponse.CloudFrontOriginAccessIdentity?.S3CanonicalUserId
|
|
23099
|
+
}
|
|
23100
|
+
};
|
|
23101
|
+
} catch (error) {
|
|
23102
|
+
const cause = error instanceof Error ? error : void 0;
|
|
23103
|
+
throw new ProvisioningError(
|
|
23104
|
+
`Failed to update CloudFront OAI ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
23105
|
+
resourceType,
|
|
23106
|
+
logicalId,
|
|
23107
|
+
physicalId,
|
|
23108
|
+
cause
|
|
23109
|
+
);
|
|
23110
|
+
}
|
|
23033
23111
|
}
|
|
23034
23112
|
/**
|
|
23035
23113
|
* Delete a CloudFront Origin Access Identity
|
|
@@ -25570,34 +25648,14 @@ var ELBv2Provider = class {
|
|
|
25570
25648
|
);
|
|
25571
25649
|
}
|
|
25572
25650
|
}
|
|
25573
|
-
|
|
25574
|
-
|
|
25575
|
-
|
|
25576
|
-
|
|
25577
|
-
new DescribeLoadBalancersCommand2({ LoadBalancerArns: [physicalId] })
|
|
25578
|
-
);
|
|
25579
|
-
const lb = describeResponse.LoadBalancers?.[0];
|
|
25580
|
-
return {
|
|
25581
|
-
physicalId,
|
|
25582
|
-
wasReplaced: false,
|
|
25583
|
-
attributes: {
|
|
25584
|
-
DNSName: lb?.DNSName,
|
|
25585
|
-
CanonicalHostedZoneID: lb?.CanonicalHostedZoneId,
|
|
25586
|
-
LoadBalancerArn: physicalId,
|
|
25587
|
-
LoadBalancerFullName: physicalId.split("/").slice(1).join("/"),
|
|
25588
|
-
LoadBalancerName: lb?.LoadBalancerName
|
|
25589
|
-
}
|
|
25590
|
-
};
|
|
25591
|
-
} catch (error) {
|
|
25592
|
-
const cause = error instanceof Error ? error : void 0;
|
|
25593
|
-
throw new ProvisioningError(
|
|
25594
|
-
`Failed to update LoadBalancer ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
25595
|
-
resourceType,
|
|
25651
|
+
updateLoadBalancer(logicalId, _physicalId, _resourceType, _properties) {
|
|
25652
|
+
return Promise.reject(
|
|
25653
|
+
new ResourceUpdateNotSupportedError(
|
|
25654
|
+
"AWS::ElasticLoadBalancingV2::LoadBalancer",
|
|
25596
25655
|
logicalId,
|
|
25597
|
-
|
|
25598
|
-
|
|
25599
|
-
|
|
25600
|
-
}
|
|
25656
|
+
"ELBv2 LoadBalancer in-place updates are not yet implemented in cdkd; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
25657
|
+
)
|
|
25658
|
+
);
|
|
25601
25659
|
}
|
|
25602
25660
|
async deleteLoadBalancer(logicalId, physicalId, resourceType, context) {
|
|
25603
25661
|
this.logger.debug(`Deleting LoadBalancer ${logicalId}: ${physicalId}`);
|
|
@@ -29590,15 +29648,14 @@ var ServiceDiscoveryProvider = class {
|
|
|
29590
29648
|
);
|
|
29591
29649
|
}
|
|
29592
29650
|
}
|
|
29593
|
-
updateNamespace(logicalId,
|
|
29594
|
-
|
|
29595
|
-
|
|
29596
|
-
|
|
29597
|
-
|
|
29598
|
-
|
|
29599
|
-
|
|
29600
|
-
|
|
29601
|
-
});
|
|
29651
|
+
updateNamespace(logicalId, _physicalId) {
|
|
29652
|
+
return Promise.reject(
|
|
29653
|
+
new ResourceUpdateNotSupportedError(
|
|
29654
|
+
"AWS::ServiceDiscovery::PrivateDnsNamespace",
|
|
29655
|
+
logicalId,
|
|
29656
|
+
"PrivateDnsNamespace updates are not yet implemented in cdkd; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
29657
|
+
)
|
|
29658
|
+
);
|
|
29602
29659
|
}
|
|
29603
29660
|
async deleteNamespace(logicalId, physicalId, resourceType, context) {
|
|
29604
29661
|
this.logger.debug(`Deleting private DNS namespace ${logicalId}: ${physicalId}`);
|
|
@@ -29693,15 +29750,14 @@ var ServiceDiscoveryProvider = class {
|
|
|
29693
29750
|
);
|
|
29694
29751
|
}
|
|
29695
29752
|
}
|
|
29696
|
-
updateService(logicalId,
|
|
29697
|
-
|
|
29698
|
-
|
|
29699
|
-
|
|
29700
|
-
|
|
29701
|
-
|
|
29702
|
-
|
|
29703
|
-
|
|
29704
|
-
});
|
|
29753
|
+
updateService(logicalId, _physicalId) {
|
|
29754
|
+
return Promise.reject(
|
|
29755
|
+
new ResourceUpdateNotSupportedError(
|
|
29756
|
+
"AWS::ServiceDiscovery::Service",
|
|
29757
|
+
logicalId,
|
|
29758
|
+
"ServiceDiscovery Service updates are not yet implemented in cdkd; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
29759
|
+
)
|
|
29760
|
+
);
|
|
29705
29761
|
}
|
|
29706
29762
|
async deleteService(logicalId, physicalId, resourceType, context) {
|
|
29707
29763
|
this.logger.debug(`Deleting service discovery service ${logicalId}: ${physicalId}`);
|
|
@@ -30049,9 +30105,22 @@ var AppSyncProvider = class {
|
|
|
30049
30105
|
);
|
|
30050
30106
|
}
|
|
30051
30107
|
}
|
|
30052
|
-
|
|
30053
|
-
|
|
30054
|
-
|
|
30108
|
+
/**
|
|
30109
|
+
* AppSync resources are treated as immutable by cdkd: every supported
|
|
30110
|
+
* type (`GraphQLApi`, `GraphQLSchema`, `DataSource`, `Resolver`,
|
|
30111
|
+
* `ApiKey`) is recreated on property changes via the deploy engine's
|
|
30112
|
+
* immutable-property replacement path. There is no in-place update,
|
|
30113
|
+
* so `cdkd drift --revert` surfaces a clear "use --replace or
|
|
30114
|
+
* re-deploy" message instead of silently no-op'ing the revert.
|
|
30115
|
+
*/
|
|
30116
|
+
update(logicalId, _physicalId, resourceType, _properties, _previousProperties) {
|
|
30117
|
+
return Promise.reject(
|
|
30118
|
+
new ResourceUpdateNotSupportedError(
|
|
30119
|
+
resourceType,
|
|
30120
|
+
logicalId,
|
|
30121
|
+
"AppSync resources are recreated on property changes; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
30122
|
+
)
|
|
30123
|
+
);
|
|
30055
30124
|
}
|
|
30056
30125
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
30057
30126
|
switch (resourceType) {
|
|
@@ -30788,10 +30857,11 @@ var GlueProvider = class {
|
|
|
30788
30857
|
async update(logicalId, physicalId, resourceType, properties, _previousProperties) {
|
|
30789
30858
|
switch (resourceType) {
|
|
30790
30859
|
case "AWS::Glue::Database":
|
|
30791
|
-
|
|
30792
|
-
|
|
30860
|
+
throw new ResourceUpdateNotSupportedError(
|
|
30861
|
+
resourceType,
|
|
30862
|
+
logicalId,
|
|
30863
|
+
"Glue Database updates are not yet implemented in cdkd; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
30793
30864
|
);
|
|
30794
|
-
return { physicalId, wasReplaced: false };
|
|
30795
30865
|
case "AWS::Glue::Table":
|
|
30796
30866
|
return this.updateTable(logicalId, physicalId, resourceType, properties);
|
|
30797
30867
|
default:
|
|
@@ -32414,8 +32484,15 @@ var EFSProvider = class {
|
|
|
32414
32484
|
);
|
|
32415
32485
|
}
|
|
32416
32486
|
}
|
|
32487
|
+
/**
|
|
32488
|
+
* EFS resources are treated as immutable by cdkd's `update()`. The deploy
|
|
32489
|
+
* engine recreates them on property changes via immutable-property
|
|
32490
|
+
* detection. (AWS does expose `UpdateFileSystem` for ThroughputMode and
|
|
32491
|
+
* `ModifyMountTargetSecurityGroups` for mount-target SGs — those are
|
|
32492
|
+
* deferred to a follow-up PR.) `cdkd drift --revert` surfaces a clear
|
|
32493
|
+
* "use --replace or re-deploy" message instead of silently no-op'ing.
|
|
32494
|
+
*/
|
|
32417
32495
|
update(logicalId, physicalId, resourceType, _properties, _previousProperties) {
|
|
32418
|
-
this.logger.debug(`Update for ${resourceType} ${logicalId} (${physicalId}) - no-op, immutable`);
|
|
32419
32496
|
if (resourceType !== "AWS::EFS::FileSystem" && resourceType !== "AWS::EFS::MountTarget" && resourceType !== "AWS::EFS::AccessPoint") {
|
|
32420
32497
|
throw new ProvisioningError(
|
|
32421
32498
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -32424,7 +32501,13 @@ var EFSProvider = class {
|
|
|
32424
32501
|
physicalId
|
|
32425
32502
|
);
|
|
32426
32503
|
}
|
|
32427
|
-
return Promise.
|
|
32504
|
+
return Promise.reject(
|
|
32505
|
+
new ResourceUpdateNotSupportedError(
|
|
32506
|
+
resourceType,
|
|
32507
|
+
logicalId,
|
|
32508
|
+
"EFS resources are recreated on property changes; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
32509
|
+
)
|
|
32510
|
+
);
|
|
32428
32511
|
}
|
|
32429
32512
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
32430
32513
|
switch (resourceType) {
|
|
@@ -33241,15 +33324,21 @@ var FirehoseProvider = class {
|
|
|
33241
33324
|
}
|
|
33242
33325
|
}
|
|
33243
33326
|
/**
|
|
33244
|
-
*
|
|
33245
|
-
*
|
|
33246
|
-
*
|
|
33327
|
+
* Firehose delivery streams are treated as immutable by cdkd. Most
|
|
33328
|
+
* destination-config changes require replacement, and AWS's
|
|
33329
|
+
* `UpdateDestination` API surface is deep enough that the deploy engine's
|
|
33330
|
+
* immutable-property replacement path covers the common cases more
|
|
33331
|
+
* reliably. `cdkd drift --revert` therefore surfaces a clear "use
|
|
33332
|
+
* --replace or re-deploy" message instead of silently no-op'ing.
|
|
33247
33333
|
*/
|
|
33248
|
-
update(logicalId,
|
|
33249
|
-
|
|
33250
|
-
|
|
33334
|
+
update(logicalId, _physicalId, resourceType, _properties, _previousProperties) {
|
|
33335
|
+
return Promise.reject(
|
|
33336
|
+
new ResourceUpdateNotSupportedError(
|
|
33337
|
+
resourceType,
|
|
33338
|
+
logicalId,
|
|
33339
|
+
"Firehose delivery streams are recreated on property changes; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
|
|
33340
|
+
)
|
|
33251
33341
|
);
|
|
33252
|
-
return Promise.resolve({ physicalId, wasReplaced: false });
|
|
33253
33342
|
}
|
|
33254
33343
|
/**
|
|
33255
33344
|
* Delete a Firehose delivery stream
|
|
@@ -38050,6 +38139,128 @@ function isPlainObject(value) {
|
|
|
38050
38139
|
return typeof value === "object" && value !== null;
|
|
38051
38140
|
}
|
|
38052
38141
|
|
|
38142
|
+
// src/analyzer/drift-cc-api-deny-list.ts
|
|
38143
|
+
var CC_API_FALLBACK_DENY_LIST = {
|
|
38144
|
+
// AWS::IAM::ManagedPolicy: PolicyDocument round-trips through CC API
|
|
38145
|
+
// URL-encoded; cdkd state stores it as a parsed JSON object. Without
|
|
38146
|
+
// a per-type decoder, every comparison sees a string-vs-object
|
|
38147
|
+
// mismatch and fires drift on every run. The IAM Role provider's
|
|
38148
|
+
// first-class readCurrentState handles its inline AssumeRolePolicy
|
|
38149
|
+
// the same way (URL-decode + JSON-parse); the same fix pattern is
|
|
38150
|
+
// needed for ManagedPolicy when an SDK provider is added.
|
|
38151
|
+
"AWS::IAM::ManagedPolicy": "PolicyDocument is URL-encoded JSON in CC API responses, but cdkd state stores it as a parsed object \u2014 needs per-type decode",
|
|
38152
|
+
// AWS::ApiGateway::RestApi: the `Body` property (OpenAPI spec object
|
|
38153
|
+
// when supplied via `Body` rather than `BodyS3Location`) is write-only
|
|
38154
|
+
// — `GetRestApi` does NOT return it, but cdkd state preserves the
|
|
38155
|
+
// object the user passed in. CC API GetResource inherits this — the
|
|
38156
|
+
// returned shape omits `Body`, so every drift run flags it as
|
|
38157
|
+
// missing-on-AWS. Comparison silently dropping it would also be
|
|
38158
|
+
// wrong; the right move is a dedicated SDK provider that knows to
|
|
38159
|
+
// skip `Body` entirely.
|
|
38160
|
+
"AWS::ApiGateway::RestApi": "Body / BodyS3Location are write-only inputs not returned by CC API GetResource; cdkd state preserves them",
|
|
38161
|
+
// AWS::CloudFormation::Stack: nested stacks aren't supported by cdkd's
|
|
38162
|
+
// provider registry at all; the deploy / destroy paths reject them.
|
|
38163
|
+
// Listing here is defense-in-depth — if a user manually crafts state
|
|
38164
|
+
// with one, drift via CC API would compare CFn-template-input
|
|
38165
|
+
// properties against CC API's stack-output shape (CC API's
|
|
38166
|
+
// `AWS::CloudFormation::Stack` reports outputs / status, not the
|
|
38167
|
+
// template parameters cdkd would have stored).
|
|
38168
|
+
"AWS::CloudFormation::Stack": "CC API returns runtime stack state (outputs/status), not the template parameters cdkd state stores",
|
|
38169
|
+
// AWS::EC2::LaunchTemplate: `LaunchTemplateData` ships with deeply
|
|
38170
|
+
// structured sub-objects that CC API normalizes into a versioned shape
|
|
38171
|
+
// — every UpdateLaunchTemplate (and even GetLaunchTemplate) bumps the
|
|
38172
|
+
// returned default version, and CC API attaches a synthetic
|
|
38173
|
+
// `LatestVersionNumber` / `DefaultVersionNumber` next to the template
|
|
38174
|
+
// data that drift would surface as drift on the parent. Until an SDK
|
|
38175
|
+
// provider strips those, deny.
|
|
38176
|
+
"AWS::EC2::LaunchTemplate": "CC API returns version-bumped LaunchTemplateData with synthetic LatestVersionNumber that diverges from the CFn input shape"
|
|
38177
|
+
};
|
|
38178
|
+
|
|
38179
|
+
// src/analyzer/cc-api-strip.ts
|
|
38180
|
+
var ALWAYS_STRIPPED_FIELDS = /* @__PURE__ */ new Set([
|
|
38181
|
+
// Timestamps — AWS-managed, change on every modification. Names are
|
|
38182
|
+
// unambiguous: no CFn template ever exposes a "CreationDate" /
|
|
38183
|
+
// "LastModifiedTime" as a settable input.
|
|
38184
|
+
"CreationDate",
|
|
38185
|
+
"CreationTime",
|
|
38186
|
+
"CreatedTime",
|
|
38187
|
+
"CreatedDate",
|
|
38188
|
+
"CreatedAt",
|
|
38189
|
+
"LastModifiedDate",
|
|
38190
|
+
"LastModifiedTime",
|
|
38191
|
+
"LastModified",
|
|
38192
|
+
"LastUpdatedTime",
|
|
38193
|
+
"LastUpdatedDate",
|
|
38194
|
+
"UpdatedAt",
|
|
38195
|
+
// Owner / account / principal info — derived from the calling
|
|
38196
|
+
// principal, never user-set in a CFn template. `CreatedBy` /
|
|
38197
|
+
// `OwnerArn` are unique enough that no settable CFn property
|
|
38198
|
+
// collides with them.
|
|
38199
|
+
"OwnerId",
|
|
38200
|
+
"OwnerAccountId",
|
|
38201
|
+
"CreatedBy",
|
|
38202
|
+
"OwnerArn",
|
|
38203
|
+
// Lambda-specific generated identifiers. `RevisionId` rotates on
|
|
38204
|
+
// every operation; `LastUpdateStatus*` mirror runtime state. None
|
|
38205
|
+
// are settable in a CFn template.
|
|
38206
|
+
"RevisionId",
|
|
38207
|
+
"LastUpdateStatus",
|
|
38208
|
+
"LastUpdateStatusReason",
|
|
38209
|
+
"LastUpdateStatusReasonCode",
|
|
38210
|
+
// CloudFormation/Cloud Control passthrough metadata — never
|
|
38211
|
+
// appears as a settable input in a CFn template body.
|
|
38212
|
+
"StackId",
|
|
38213
|
+
"PhysicalResourceId",
|
|
38214
|
+
"LogicalResourceId"
|
|
38215
|
+
// Notes on intentional EXCLUSIONS:
|
|
38216
|
+
//
|
|
38217
|
+
// `State` / `Status` / `StateReason` / `StatusReason` — these
|
|
38218
|
+
// names ARE used by some CFn types as settable nested properties
|
|
38219
|
+
// (e.g. `AWS::ECS::CapacityProvider.AutoScalingGroupProvider.ManagedScaling.Status`,
|
|
38220
|
+
// `AWS::S3::Bucket.VersioningConfiguration.Status`). Stripping them
|
|
38221
|
+
// globally would cause false-positive drift on a clean stack.
|
|
38222
|
+
// The comparator already ignores AWS-only top-level `Status` values
|
|
38223
|
+
// because state doesn't carry them; only the nested-name-collision
|
|
38224
|
+
// cases would have leaked through, and excluding them here protects
|
|
38225
|
+
// those.
|
|
38226
|
+
//
|
|
38227
|
+
// `Arn` — many CFn types accept `Arn` as a settable property and
|
|
38228
|
+
// cdkd state may record it at create time. Drift on `Arn` is
|
|
38229
|
+
// genuine drift the user wants to see.
|
|
38230
|
+
//
|
|
38231
|
+
// `VersionId` / `GenerationId` / `ETag` — narrow utility (only S3
|
|
38232
|
+
// / KMS / ImageBuilder use these in their Get* responses), and at
|
|
38233
|
+
// least `VersionId` IS a settable input on `AWS::S3::Bucket`'s
|
|
38234
|
+
// versioning config. Per-provider readCurrentState handles them.
|
|
38235
|
+
//
|
|
38236
|
+
// `AccountId` / `StackName` — also collide with settable inputs
|
|
38237
|
+
// on a few CFn types (`AWS::CloudWatch::CrossAccountSharingRule.AccountId`,
|
|
38238
|
+
// `AWS::CloudFormation::HookDefaultVersion.StackName`).
|
|
38239
|
+
//
|
|
38240
|
+
// `StartTime` / `EndTime` — used as settable inputs in scheduling
|
|
38241
|
+
// shapes (e.g. `AWS::AutoScaling::ScheduledAction.StartTime`).
|
|
38242
|
+
]);
|
|
38243
|
+
function stripCcApiAwsManagedFields(resourceType, awsProps) {
|
|
38244
|
+
return stripWalk(awsProps);
|
|
38245
|
+
}
|
|
38246
|
+
function stripWalk(value) {
|
|
38247
|
+
if (value === null || value === void 0)
|
|
38248
|
+
return value;
|
|
38249
|
+
if (Array.isArray(value)) {
|
|
38250
|
+
return value.map(stripWalk);
|
|
38251
|
+
}
|
|
38252
|
+
if (typeof value === "object") {
|
|
38253
|
+
const out = {};
|
|
38254
|
+
for (const [key, child] of Object.entries(value)) {
|
|
38255
|
+
if (ALWAYS_STRIPPED_FIELDS.has(key))
|
|
38256
|
+
continue;
|
|
38257
|
+
out[key] = stripWalk(child);
|
|
38258
|
+
}
|
|
38259
|
+
return out;
|
|
38260
|
+
}
|
|
38261
|
+
return value;
|
|
38262
|
+
}
|
|
38263
|
+
|
|
38053
38264
|
// src/cli/commands/drift.ts
|
|
38054
38265
|
var DriftDetectedError = class _DriftDetectedError extends CdkdError {
|
|
38055
38266
|
silent = true;
|
|
@@ -38092,6 +38303,7 @@ async function driftCommand(stacks, options) {
|
|
|
38092
38303
|
const providerRegistry = new ProviderRegistry();
|
|
38093
38304
|
registerAllProviders(providerRegistry);
|
|
38094
38305
|
providerRegistry.setCustomResourceResponseBucket(bucket);
|
|
38306
|
+
const ccApiFallback = new CloudControlProvider();
|
|
38095
38307
|
const stateRefs = await stateBackend.listStacks();
|
|
38096
38308
|
const targetRefs = resolveTargetRefs(stacks, stateRefs, options);
|
|
38097
38309
|
const reports = [];
|
|
@@ -38105,7 +38317,8 @@ async function driftCommand(stacks, options) {
|
|
|
38105
38317
|
ref.stackName,
|
|
38106
38318
|
ref.region,
|
|
38107
38319
|
stateBackend,
|
|
38108
|
-
providerRegistry
|
|
38320
|
+
providerRegistry,
|
|
38321
|
+
ccApiFallback
|
|
38109
38322
|
);
|
|
38110
38323
|
reports.push(report);
|
|
38111
38324
|
}
|
|
@@ -38176,7 +38389,7 @@ function resolveTargetRefs(stacks, stateRefs, options) {
|
|
|
38176
38389
|
}
|
|
38177
38390
|
return out;
|
|
38178
38391
|
}
|
|
38179
|
-
async function runDriftForStack(stackName, region, stateBackend, providerRegistry) {
|
|
38392
|
+
async function runDriftForStack(stackName, region, stateBackend, providerRegistry, ccApiFallback) {
|
|
38180
38393
|
const result = await stateBackend.getState(stackName, region);
|
|
38181
38394
|
if (!result) {
|
|
38182
38395
|
throw new Error(
|
|
@@ -38202,27 +38415,39 @@ async function runDriftForStack(stackName, region, stateBackend, providerRegistr
|
|
|
38202
38415
|
});
|
|
38203
38416
|
continue;
|
|
38204
38417
|
}
|
|
38205
|
-
let
|
|
38206
|
-
if (
|
|
38207
|
-
|
|
38208
|
-
|
|
38209
|
-
|
|
38418
|
+
let aws;
|
|
38419
|
+
if (provider.readCurrentState) {
|
|
38420
|
+
aws = await provider.readCurrentState(
|
|
38421
|
+
resource.physicalId,
|
|
38422
|
+
logicalId,
|
|
38423
|
+
resource.resourceType,
|
|
38424
|
+
resource.properties ?? {}
|
|
38425
|
+
);
|
|
38426
|
+
} else {
|
|
38427
|
+
if (CC_API_FALLBACK_DENY_LIST[resource.resourceType]) {
|
|
38428
|
+
outcomes.push({
|
|
38429
|
+
kind: "unsupported",
|
|
38430
|
+
logicalId,
|
|
38431
|
+
resourceType: resource.resourceType
|
|
38432
|
+
});
|
|
38433
|
+
continue;
|
|
38210
38434
|
}
|
|
38211
|
-
|
|
38212
|
-
|
|
38213
|
-
outcomes.push({
|
|
38214
|
-
kind: "unsupported",
|
|
38435
|
+
const ccApiAws = await ccApiFallback.readCurrentState(
|
|
38436
|
+
resource.physicalId,
|
|
38215
38437
|
logicalId,
|
|
38216
|
-
|
|
38217
|
-
|
|
38218
|
-
|
|
38438
|
+
resource.resourceType,
|
|
38439
|
+
resource.properties ?? {}
|
|
38440
|
+
);
|
|
38441
|
+
if (ccApiAws === void 0) {
|
|
38442
|
+
outcomes.push({
|
|
38443
|
+
kind: "unsupported",
|
|
38444
|
+
logicalId,
|
|
38445
|
+
resourceType: resource.resourceType
|
|
38446
|
+
});
|
|
38447
|
+
continue;
|
|
38448
|
+
}
|
|
38449
|
+
aws = stripCcApiAwsManagedFields(resource.resourceType, ccApiAws);
|
|
38219
38450
|
}
|
|
38220
|
-
const aws = await readCurrentState(
|
|
38221
|
-
resource.physicalId,
|
|
38222
|
-
logicalId,
|
|
38223
|
-
resource.resourceType,
|
|
38224
|
-
resource.properties ?? {}
|
|
38225
|
-
);
|
|
38226
38451
|
if (aws === void 0) {
|
|
38227
38452
|
outcomes.push({
|
|
38228
38453
|
kind: "unsupported",
|
|
@@ -38356,6 +38581,7 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
|
|
|
38356
38581
|
const owner = `${process.env["USER"] || "unknown"}@${process.env["HOSTNAME"] || "host"}:${process.pid}`;
|
|
38357
38582
|
const concurrency = Math.max(1, options.concurrency ?? 4);
|
|
38358
38583
|
let totalFailed = 0;
|
|
38584
|
+
let totalUnsupported = 0;
|
|
38359
38585
|
let totalSucceeded = 0;
|
|
38360
38586
|
for (const report of reports) {
|
|
38361
38587
|
const driftedOutcomes = report.outcomes.filter(
|
|
@@ -38393,10 +38619,17 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
|
|
|
38393
38619
|
` \u2713 ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): reverted.`
|
|
38394
38620
|
);
|
|
38395
38621
|
} catch (err) {
|
|
38622
|
+
if (err instanceof ResourceUpdateNotSupportedError) {
|
|
38623
|
+
totalUnsupported++;
|
|
38624
|
+
logger.warn(
|
|
38625
|
+
` \u2298 ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): could not revert \u2014 ${err.message}`
|
|
38626
|
+
);
|
|
38627
|
+
return;
|
|
38628
|
+
}
|
|
38396
38629
|
totalFailed++;
|
|
38397
38630
|
const msg = err instanceof Error ? err.message : String(err);
|
|
38398
38631
|
logger.error(
|
|
38399
|
-
` \u2717 ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): ${msg}`
|
|
38632
|
+
` \u2717 ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): AWS update failed \u2014 ${msg}`
|
|
38400
38633
|
);
|
|
38401
38634
|
}
|
|
38402
38635
|
});
|
|
@@ -38409,11 +38642,21 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
|
|
|
38409
38642
|
});
|
|
38410
38643
|
}
|
|
38411
38644
|
}
|
|
38645
|
+
const summaryParts = [`${totalSucceeded} reverted`];
|
|
38646
|
+
if (totalUnsupported > 0)
|
|
38647
|
+
summaryParts.push(`${totalUnsupported} update-not-supported`);
|
|
38648
|
+
if (totalFailed > 0)
|
|
38649
|
+
summaryParts.push(`${totalFailed} failed`);
|
|
38412
38650
|
logger.info(`
|
|
38413
|
-
Revert summary: ${
|
|
38414
|
-
if (
|
|
38651
|
+
Revert summary: ${summaryParts.join(", ")}.`);
|
|
38652
|
+
if (totalUnsupported > 0) {
|
|
38653
|
+
logger.warn(
|
|
38654
|
+
`${totalUnsupported} resource(s) cannot be reverted in place \u2014 re-deploy the stack with cdkd deploy --replace, or destroy + redeploy to push the cdkd-state values back into AWS.`
|
|
38655
|
+
);
|
|
38656
|
+
}
|
|
38657
|
+
if (totalFailed > 0 || totalUnsupported > 0) {
|
|
38415
38658
|
throw new PartialFailureError(
|
|
38416
|
-
`Revert completed with ${totalFailed} resource error(s). Re-run 'cdkd drift <stack>' to see the remaining drift, then 'cdkd drift <stack> --revert' to retry.`
|
|
38659
|
+
`Revert completed with ${totalFailed + totalUnsupported} resource error(s) (${totalFailed} AWS update failure(s), ${totalUnsupported} update-not-supported). Re-run 'cdkd drift <stack>' to see the remaining drift, then 'cdkd drift <stack> --revert' to retry.`
|
|
38417
38660
|
);
|
|
38418
38661
|
}
|
|
38419
38662
|
}
|
|
@@ -41760,7 +42003,7 @@ function reorderArgs(argv) {
|
|
|
41760
42003
|
}
|
|
41761
42004
|
async function main() {
|
|
41762
42005
|
const program = new Command14();
|
|
41763
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
42006
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.45.0");
|
|
41764
42007
|
program.addCommand(createBootstrapCommand());
|
|
41765
42008
|
program.addCommand(createSynthCommand());
|
|
41766
42009
|
program.addCommand(createListCommand());
|