@go-to-k/cdkd 0.37.0 → 0.39.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/README.md +7 -1
- package/dist/cli.js +1361 -36
- package/dist/cli.js.map +3 -3
- package/dist/go-to-k-cdkd-0.39.0.tgz +0 -0
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.37.0.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -16532,6 +16532,52 @@ var SecretsManagerSecretProvider = class {
|
|
|
16532
16532
|
}
|
|
16533
16533
|
return password;
|
|
16534
16534
|
}
|
|
16535
|
+
/**
|
|
16536
|
+
* Read the AWS-current secret configuration in CFn-property shape.
|
|
16537
|
+
*
|
|
16538
|
+
* Issues `DescribeSecret` and surfaces `Name`, `Description`, `KmsKeyId`,
|
|
16539
|
+
* and `ReplicaRegions` (re-shaping `ReplicationStatus[]` to CFn's
|
|
16540
|
+
* `[{Region, KmsKeyId}]`).
|
|
16541
|
+
*
|
|
16542
|
+
* Intentionally omitted:
|
|
16543
|
+
* - `SecretString` / `GenerateSecretString`: `DescribeSecret` does not
|
|
16544
|
+
* return the secret value (that's `GetSecretValue`, which we never
|
|
16545
|
+
* call to avoid surfacing plaintext through drift). Cdkd state holds
|
|
16546
|
+
* the user-supplied string verbatim; comparing against AWS would
|
|
16547
|
+
* require pulling the value, so this is deliberately deferred.
|
|
16548
|
+
* - `Tags`: `DescribeSecret` returns Tags, but the auto-injected
|
|
16549
|
+
* `aws:cdk:path` tag-shape question is out of scope here.
|
|
16550
|
+
*
|
|
16551
|
+
* Returns `undefined` when the secret is gone (`ResourceNotFoundException`).
|
|
16552
|
+
*/
|
|
16553
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
16554
|
+
try {
|
|
16555
|
+
const resp = await this.smClient.send(new DescribeSecretCommand({ SecretId: physicalId }));
|
|
16556
|
+
const result = {};
|
|
16557
|
+
if (resp.Name !== void 0)
|
|
16558
|
+
result["Name"] = resp.Name;
|
|
16559
|
+
if (resp.Description !== void 0 && resp.Description !== "") {
|
|
16560
|
+
result["Description"] = resp.Description;
|
|
16561
|
+
}
|
|
16562
|
+
if (resp.KmsKeyId !== void 0)
|
|
16563
|
+
result["KmsKeyId"] = resp.KmsKeyId;
|
|
16564
|
+
if (resp.ReplicationStatus && resp.ReplicationStatus.length > 0) {
|
|
16565
|
+
result["ReplicaRegions"] = resp.ReplicationStatus.map((r) => {
|
|
16566
|
+
const out = {};
|
|
16567
|
+
if (r.Region)
|
|
16568
|
+
out["Region"] = r.Region;
|
|
16569
|
+
if (r.KmsKeyId)
|
|
16570
|
+
out["KmsKeyId"] = r.KmsKeyId;
|
|
16571
|
+
return out;
|
|
16572
|
+
});
|
|
16573
|
+
}
|
|
16574
|
+
return result;
|
|
16575
|
+
} catch (err) {
|
|
16576
|
+
if (err instanceof ResourceNotFoundException8)
|
|
16577
|
+
return void 0;
|
|
16578
|
+
throw err;
|
|
16579
|
+
}
|
|
16580
|
+
}
|
|
16535
16581
|
/**
|
|
16536
16582
|
* Adopt an existing Secrets Manager secret into cdkd state.
|
|
16537
16583
|
*
|
|
@@ -16802,6 +16848,74 @@ var SSMParameterProvider = class {
|
|
|
16802
16848
|
);
|
|
16803
16849
|
}
|
|
16804
16850
|
}
|
|
16851
|
+
/**
|
|
16852
|
+
* Read the AWS-current SSM parameter configuration in CFn-property shape.
|
|
16853
|
+
*
|
|
16854
|
+
* Issues `GetParameter` (with `WithDecryption: false` so SecureString
|
|
16855
|
+
* values stay encrypted on the wire) for `Type` / `Value` / `DataType`,
|
|
16856
|
+
* then `DescribeParameters` filtered on the parameter name to fetch
|
|
16857
|
+
* metadata (`Description`, `AllowedPattern`, `Tier`) that `GetParameter`
|
|
16858
|
+
* does not return.
|
|
16859
|
+
*
|
|
16860
|
+
* `Name` is set to the physical id. `Tags` and `Policies` are intentionally
|
|
16861
|
+
* out of scope (`Tags` requires a separate `ListTagsForResource` round-trip
|
|
16862
|
+
* and the auto-injected `aws:cdk:path` tag-shape question is unresolved;
|
|
16863
|
+
* `Policies` is returned by `DescribeParameters.Policies` as a structured
|
|
16864
|
+
* array but cdkd state holds the raw JSON string the user typed — comparing
|
|
16865
|
+
* the two accurately needs more work).
|
|
16866
|
+
*
|
|
16867
|
+
* **Note**: For `SecureString` parameters, AWS returns the encrypted
|
|
16868
|
+
* blob in `Value` (we pass `WithDecryption: false`). cdkd state usually
|
|
16869
|
+
* holds the plaintext value the user typed in their CDK app, so a
|
|
16870
|
+
* SecureString parameter will surface as `Value` drift on every run.
|
|
16871
|
+
* That's the correct conservative behavior — surfacing the discrepancy
|
|
16872
|
+
* is more useful than silently masking it.
|
|
16873
|
+
*
|
|
16874
|
+
* Returns `undefined` when the parameter is gone (`ParameterNotFound`).
|
|
16875
|
+
*/
|
|
16876
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
16877
|
+
let getResp;
|
|
16878
|
+
try {
|
|
16879
|
+
getResp = await this.ssmClient.send(
|
|
16880
|
+
new GetParameterCommand3({ Name: physicalId, WithDecryption: false })
|
|
16881
|
+
);
|
|
16882
|
+
} catch (err) {
|
|
16883
|
+
if (err instanceof ParameterNotFound)
|
|
16884
|
+
return void 0;
|
|
16885
|
+
throw err;
|
|
16886
|
+
}
|
|
16887
|
+
const param = getResp.Parameter;
|
|
16888
|
+
if (!param)
|
|
16889
|
+
return void 0;
|
|
16890
|
+
const result = { Name: physicalId };
|
|
16891
|
+
if (param.Type !== void 0)
|
|
16892
|
+
result["Type"] = param.Type;
|
|
16893
|
+
if (param.Value !== void 0)
|
|
16894
|
+
result["Value"] = param.Value;
|
|
16895
|
+
if (param.DataType !== void 0)
|
|
16896
|
+
result["DataType"] = param.DataType;
|
|
16897
|
+
try {
|
|
16898
|
+
const desc = await this.ssmClient.send(
|
|
16899
|
+
new DescribeParametersCommand({
|
|
16900
|
+
ParameterFilters: [{ Key: "Name", Values: [physicalId] }]
|
|
16901
|
+
})
|
|
16902
|
+
);
|
|
16903
|
+
const meta = desc.Parameters?.[0];
|
|
16904
|
+
if (meta) {
|
|
16905
|
+
if (meta.Description !== void 0 && meta.Description !== "") {
|
|
16906
|
+
result["Description"] = meta.Description;
|
|
16907
|
+
}
|
|
16908
|
+
if (meta.AllowedPattern !== void 0 && meta.AllowedPattern !== "") {
|
|
16909
|
+
result["AllowedPattern"] = meta.AllowedPattern;
|
|
16910
|
+
}
|
|
16911
|
+
if (meta.Tier !== void 0) {
|
|
16912
|
+
result["Tier"] = meta.Tier;
|
|
16913
|
+
}
|
|
16914
|
+
}
|
|
16915
|
+
} catch {
|
|
16916
|
+
}
|
|
16917
|
+
return result;
|
|
16918
|
+
}
|
|
16805
16919
|
/**
|
|
16806
16920
|
* Adopt an existing SSM parameter into cdkd state.
|
|
16807
16921
|
*
|
|
@@ -17132,6 +17246,78 @@ var EventBridgeRuleProvider = class {
|
|
|
17132
17246
|
}
|
|
17133
17247
|
throw new Error(`Unsupported attribute: ${attributeName} for AWS::Events::Rule`);
|
|
17134
17248
|
}
|
|
17249
|
+
/**
|
|
17250
|
+
* Read the AWS-current EventBridge rule configuration in CFn-property shape.
|
|
17251
|
+
*
|
|
17252
|
+
* Issues `DescribeRule` for the rule's main config, then a separate
|
|
17253
|
+
* `ListTargetsByRule` for `Targets`.
|
|
17254
|
+
*
|
|
17255
|
+
* Surfaced keys (when present): `Name`, `Description`, `EventBusName`,
|
|
17256
|
+
* `EventPattern` (parsed from JSON string back to object — cdkd state holds
|
|
17257
|
+
* it as the user typed it, typically an object), `ScheduleExpression`,
|
|
17258
|
+
* `State`, `RoleArn`, `Targets` (CFn shape `[{Id, Arn, ...}]`).
|
|
17259
|
+
*
|
|
17260
|
+
* `Tags` is omitted (separate `ListTagsForResource` round-trip; auto-injected
|
|
17261
|
+
* `aws:cdk:path` tag-shape question is out of scope here).
|
|
17262
|
+
*
|
|
17263
|
+
* Returns `undefined` when the rule is gone (`ResourceNotFoundException`).
|
|
17264
|
+
*/
|
|
17265
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
17266
|
+
const ruleName = this.extractRuleNameFromArn(physicalId);
|
|
17267
|
+
const eventBusName = this.extractBusNameFromArn(physicalId);
|
|
17268
|
+
let resp;
|
|
17269
|
+
try {
|
|
17270
|
+
resp = await this.eventBridgeClient.send(
|
|
17271
|
+
new DescribeRuleCommand({
|
|
17272
|
+
Name: ruleName,
|
|
17273
|
+
...eventBusName && eventBusName !== "default" ? { EventBusName: eventBusName } : {}
|
|
17274
|
+
})
|
|
17275
|
+
);
|
|
17276
|
+
} catch (err) {
|
|
17277
|
+
if (err instanceof ResourceNotFoundException9)
|
|
17278
|
+
return void 0;
|
|
17279
|
+
throw err;
|
|
17280
|
+
}
|
|
17281
|
+
const result = {};
|
|
17282
|
+
if (resp.Name !== void 0)
|
|
17283
|
+
result["Name"] = resp.Name;
|
|
17284
|
+
if (resp.Description !== void 0 && resp.Description !== "") {
|
|
17285
|
+
result["Description"] = resp.Description;
|
|
17286
|
+
}
|
|
17287
|
+
if (resp.EventBusName !== void 0 && resp.EventBusName !== "default") {
|
|
17288
|
+
result["EventBusName"] = resp.EventBusName;
|
|
17289
|
+
}
|
|
17290
|
+
if (resp.EventPattern !== void 0) {
|
|
17291
|
+
try {
|
|
17292
|
+
result["EventPattern"] = JSON.parse(resp.EventPattern);
|
|
17293
|
+
} catch {
|
|
17294
|
+
result["EventPattern"] = resp.EventPattern;
|
|
17295
|
+
}
|
|
17296
|
+
}
|
|
17297
|
+
if (resp.ScheduleExpression !== void 0) {
|
|
17298
|
+
result["ScheduleExpression"] = resp.ScheduleExpression;
|
|
17299
|
+
}
|
|
17300
|
+
if (resp.State !== void 0)
|
|
17301
|
+
result["State"] = resp.State;
|
|
17302
|
+
if (resp.RoleArn !== void 0)
|
|
17303
|
+
result["RoleArn"] = resp.RoleArn;
|
|
17304
|
+
try {
|
|
17305
|
+
const targetsResp = await this.eventBridgeClient.send(
|
|
17306
|
+
new ListTargetsByRuleCommand({
|
|
17307
|
+
Rule: ruleName,
|
|
17308
|
+
...eventBusName && eventBusName !== "default" ? { EventBusName: eventBusName } : {}
|
|
17309
|
+
})
|
|
17310
|
+
);
|
|
17311
|
+
if (targetsResp.Targets && targetsResp.Targets.length > 0) {
|
|
17312
|
+
result["Targets"] = targetsResp.Targets;
|
|
17313
|
+
}
|
|
17314
|
+
} catch (err) {
|
|
17315
|
+
if (!(err instanceof ResourceNotFoundException9)) {
|
|
17316
|
+
throw err;
|
|
17317
|
+
}
|
|
17318
|
+
}
|
|
17319
|
+
return result;
|
|
17320
|
+
}
|
|
17135
17321
|
/**
|
|
17136
17322
|
* Adopt an existing EventBridge rule into cdkd state.
|
|
17137
17323
|
*
|
|
@@ -17224,6 +17410,22 @@ var EventBridgeRuleProvider = class {
|
|
|
17224
17410
|
const parts = arn.split("/");
|
|
17225
17411
|
return parts[parts.length - 1] ?? arn;
|
|
17226
17412
|
}
|
|
17413
|
+
/**
|
|
17414
|
+
* Extract the event bus name from a rule ARN.
|
|
17415
|
+
*
|
|
17416
|
+
* ARN format: `arn:aws:events:region:account:rule/rule-name` (default bus, returns 'default')
|
|
17417
|
+
* or `arn:aws:events:region:account:rule/bus-name/rule-name` (custom bus).
|
|
17418
|
+
*
|
|
17419
|
+
* Returns `undefined` when the input is not an ARN (we can't tell which bus).
|
|
17420
|
+
*/
|
|
17421
|
+
extractBusNameFromArn(arn) {
|
|
17422
|
+
if (!arn.startsWith("arn:"))
|
|
17423
|
+
return void 0;
|
|
17424
|
+
const parts = arn.split("/");
|
|
17425
|
+
if (parts.length === 3)
|
|
17426
|
+
return parts[1];
|
|
17427
|
+
return "default";
|
|
17428
|
+
}
|
|
17227
17429
|
};
|
|
17228
17430
|
|
|
17229
17431
|
// src/provisioning/providers/eventbridge-bus-provider.ts
|
|
@@ -17475,6 +17677,53 @@ var EventBridgeBusProvider = class {
|
|
|
17475
17677
|
);
|
|
17476
17678
|
}
|
|
17477
17679
|
}
|
|
17680
|
+
/**
|
|
17681
|
+
* Read the AWS-current EventBus configuration in CFn-property shape.
|
|
17682
|
+
*
|
|
17683
|
+
* Issues `DescribeEventBus` and surfaces `Name`, `Description`,
|
|
17684
|
+
* `KmsKeyIdentifier`, `DeadLetterConfig`, and `Policy` (the latter is a
|
|
17685
|
+
* JSON string in `DescribeEventBus.Policy`; cdkd state holds it the way
|
|
17686
|
+
* the user typed it, which may be either an object or a string — the
|
|
17687
|
+
* comparator handles either side).
|
|
17688
|
+
*
|
|
17689
|
+
* `Tags` and `EventSourceName` are intentionally omitted: tags require a
|
|
17690
|
+
* separate `ListTagsForResource` round-trip and the auto-injected
|
|
17691
|
+
* `aws:cdk:path` tag-shape question is out of scope; `EventSourceName`
|
|
17692
|
+
* is set at create time only and not surfaced by `DescribeEventBus`.
|
|
17693
|
+
*
|
|
17694
|
+
* Returns `undefined` when the bus is gone (`ResourceNotFoundException`).
|
|
17695
|
+
*/
|
|
17696
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
17697
|
+
try {
|
|
17698
|
+
const resp = await this.eventBridgeClient.send(
|
|
17699
|
+
new DescribeEventBusCommand({ Name: physicalId })
|
|
17700
|
+
);
|
|
17701
|
+
const result = {};
|
|
17702
|
+
if (resp.Name !== void 0)
|
|
17703
|
+
result["Name"] = resp.Name;
|
|
17704
|
+
if (resp.Description !== void 0 && resp.Description !== "") {
|
|
17705
|
+
result["Description"] = resp.Description;
|
|
17706
|
+
}
|
|
17707
|
+
if (resp.KmsKeyIdentifier !== void 0) {
|
|
17708
|
+
result["KmsKeyIdentifier"] = resp.KmsKeyIdentifier;
|
|
17709
|
+
}
|
|
17710
|
+
if (resp.DeadLetterConfig?.Arn) {
|
|
17711
|
+
result["DeadLetterConfig"] = { Arn: resp.DeadLetterConfig.Arn };
|
|
17712
|
+
}
|
|
17713
|
+
if (resp.Policy) {
|
|
17714
|
+
try {
|
|
17715
|
+
result["Policy"] = JSON.parse(resp.Policy);
|
|
17716
|
+
} catch {
|
|
17717
|
+
result["Policy"] = resp.Policy;
|
|
17718
|
+
}
|
|
17719
|
+
}
|
|
17720
|
+
return result;
|
|
17721
|
+
} catch (err) {
|
|
17722
|
+
if (err instanceof ResourceNotFoundException10)
|
|
17723
|
+
return void 0;
|
|
17724
|
+
throw err;
|
|
17725
|
+
}
|
|
17726
|
+
}
|
|
17478
17727
|
/**
|
|
17479
17728
|
* Adopt an existing EventBridge event bus into cdkd state.
|
|
17480
17729
|
*
|
|
@@ -19728,6 +19977,7 @@ var EC2Provider = class {
|
|
|
19728
19977
|
// src/provisioning/providers/apigateway-provider.ts
|
|
19729
19978
|
import {
|
|
19730
19979
|
UpdateAccountCommand,
|
|
19980
|
+
GetAccountCommand,
|
|
19731
19981
|
CreateResourceCommand as CreateResourceCommand2,
|
|
19732
19982
|
DeleteResourceCommand as DeleteResourceCommand2,
|
|
19733
19983
|
CreateDeploymentCommand,
|
|
@@ -19737,6 +19987,7 @@ import {
|
|
|
19737
19987
|
DeleteStageCommand,
|
|
19738
19988
|
PutMethodCommand,
|
|
19739
19989
|
DeleteMethodCommand,
|
|
19990
|
+
GetMethodCommand,
|
|
19740
19991
|
PutIntegrationCommand,
|
|
19741
19992
|
PutMethodResponseCommand,
|
|
19742
19993
|
CreateAuthorizerCommand,
|
|
@@ -20727,6 +20978,81 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
20727
20978
|
}
|
|
20728
20979
|
return result;
|
|
20729
20980
|
}
|
|
20981
|
+
/**
|
|
20982
|
+
* Read the AWS-current API Gateway resource configuration in CFn-property
|
|
20983
|
+
* shape.
|
|
20984
|
+
*
|
|
20985
|
+
* **Coverage**:
|
|
20986
|
+
* - `AWS::ApiGateway::Account` → `GetAccount` for `CloudWatchRoleArn`.
|
|
20987
|
+
* - `AWS::ApiGateway::Method` → `GetMethod`. PhysicalId is the composite
|
|
20988
|
+
* `restApiId|resourceId|httpMethod`, so we have everything needed
|
|
20989
|
+
* without `Properties`.
|
|
20990
|
+
*
|
|
20991
|
+
* **Out of scope** (returns `undefined`, falls back to "drift unknown"):
|
|
20992
|
+
* - `AWS::ApiGateway::Authorizer` / `Resource` / `Deployment` / `Stage`:
|
|
20993
|
+
* each needs the parent `RestApiId` to issue a `Get*` call, but cdkd's
|
|
20994
|
+
* `readCurrentState` interface does not pass `Properties` (only the
|
|
20995
|
+
* physicalId, which for these types is just the sub-resource id).
|
|
20996
|
+
* CC API drift detection picks up `AWS::ApiGateway::RestApi` itself
|
|
20997
|
+
* once the user works through the SDK provider boundary; per-sub
|
|
20998
|
+
* drift detection here would need a contract change.
|
|
20999
|
+
*/
|
|
21000
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
21001
|
+
switch (resourceType) {
|
|
21002
|
+
case "AWS::ApiGateway::Account":
|
|
21003
|
+
return this.readCurrentStateAccount();
|
|
21004
|
+
case "AWS::ApiGateway::Method":
|
|
21005
|
+
return this.readCurrentStateMethod(physicalId);
|
|
21006
|
+
default:
|
|
21007
|
+
return void 0;
|
|
21008
|
+
}
|
|
21009
|
+
}
|
|
21010
|
+
async readCurrentStateAccount() {
|
|
21011
|
+
try {
|
|
21012
|
+
const resp = await this.apiGatewayClient.send(new GetAccountCommand({}));
|
|
21013
|
+
const result = {};
|
|
21014
|
+
if (resp.cloudwatchRoleArn !== void 0) {
|
|
21015
|
+
result["CloudWatchRoleArn"] = resp.cloudwatchRoleArn;
|
|
21016
|
+
}
|
|
21017
|
+
return result;
|
|
21018
|
+
} catch (err) {
|
|
21019
|
+
if (err instanceof NotFoundException3)
|
|
21020
|
+
return void 0;
|
|
21021
|
+
throw err;
|
|
21022
|
+
}
|
|
21023
|
+
}
|
|
21024
|
+
async readCurrentStateMethod(physicalId) {
|
|
21025
|
+
const parts = physicalId.split("|");
|
|
21026
|
+
if (parts.length !== 3)
|
|
21027
|
+
return void 0;
|
|
21028
|
+
const [restApiId, resourceId, httpMethod] = parts;
|
|
21029
|
+
try {
|
|
21030
|
+
const resp = await this.apiGatewayClient.send(
|
|
21031
|
+
new GetMethodCommand({ restApiId, resourceId, httpMethod })
|
|
21032
|
+
);
|
|
21033
|
+
const result = {};
|
|
21034
|
+
if (restApiId !== void 0)
|
|
21035
|
+
result["RestApiId"] = restApiId;
|
|
21036
|
+
if (resourceId !== void 0)
|
|
21037
|
+
result["ResourceId"] = resourceId;
|
|
21038
|
+
if (resp.httpMethod !== void 0)
|
|
21039
|
+
result["HttpMethod"] = resp.httpMethod;
|
|
21040
|
+
if (resp.authorizationType !== void 0) {
|
|
21041
|
+
result["AuthorizationType"] = resp.authorizationType;
|
|
21042
|
+
}
|
|
21043
|
+
if (resp.authorizerId !== void 0)
|
|
21044
|
+
result["AuthorizerId"] = resp.authorizerId;
|
|
21045
|
+
if (resp.methodIntegration)
|
|
21046
|
+
result["Integration"] = resp.methodIntegration;
|
|
21047
|
+
if (resp.methodResponses)
|
|
21048
|
+
result["MethodResponses"] = resp.methodResponses;
|
|
21049
|
+
return result;
|
|
21050
|
+
} catch (err) {
|
|
21051
|
+
if (err instanceof NotFoundException3)
|
|
21052
|
+
return void 0;
|
|
21053
|
+
throw err;
|
|
21054
|
+
}
|
|
21055
|
+
}
|
|
20730
21056
|
/**
|
|
20731
21057
|
* Adopt an existing API Gateway sub-resource into cdkd state.
|
|
20732
21058
|
*
|
|
@@ -21303,6 +21629,45 @@ var ApiGatewayV2Provider = class {
|
|
|
21303
21629
|
);
|
|
21304
21630
|
}
|
|
21305
21631
|
}
|
|
21632
|
+
// ─── Drift detection ──────────────────────────────────────────────
|
|
21633
|
+
/**
|
|
21634
|
+
* Read the AWS-current API Gateway V2 resource configuration in
|
|
21635
|
+
* CFn-property shape.
|
|
21636
|
+
*
|
|
21637
|
+
* **Coverage**:
|
|
21638
|
+
* - `AWS::ApiGatewayV2::Api` → `GetApi`. PhysicalId is the apiId,
|
|
21639
|
+
* self-sufficient.
|
|
21640
|
+
*
|
|
21641
|
+
* **Out of scope** (returns `undefined`, falls back to "drift unknown"):
|
|
21642
|
+
* - `AWS::ApiGatewayV2::Stage` / `Integration` / `Route` / `Authorizer`:
|
|
21643
|
+
* each needs the parent `ApiId` to issue a `Get*` call, but cdkd's
|
|
21644
|
+
* `readCurrentState` interface does not pass `Properties` (only the
|
|
21645
|
+
* physicalId, which for these types is just the sub-resource id).
|
|
21646
|
+
* Per-sub drift detection here would need a contract change.
|
|
21647
|
+
*/
|
|
21648
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
21649
|
+
if (resourceType !== "AWS::ApiGatewayV2::Api") {
|
|
21650
|
+
return void 0;
|
|
21651
|
+
}
|
|
21652
|
+
try {
|
|
21653
|
+
const resp = await this.getClient().send(new GetApiCommand({ ApiId: physicalId }));
|
|
21654
|
+
const result = {};
|
|
21655
|
+
if (resp.Name !== void 0)
|
|
21656
|
+
result["Name"] = resp.Name;
|
|
21657
|
+
if (resp.ProtocolType !== void 0)
|
|
21658
|
+
result["ProtocolType"] = resp.ProtocolType;
|
|
21659
|
+
if (resp.Description !== void 0 && resp.Description !== "") {
|
|
21660
|
+
result["Description"] = resp.Description;
|
|
21661
|
+
}
|
|
21662
|
+
if (resp.CorsConfiguration)
|
|
21663
|
+
result["CorsConfiguration"] = resp.CorsConfiguration;
|
|
21664
|
+
return result;
|
|
21665
|
+
} catch (err) {
|
|
21666
|
+
if (err instanceof NotFoundException4)
|
|
21667
|
+
return void 0;
|
|
21668
|
+
throw err;
|
|
21669
|
+
}
|
|
21670
|
+
}
|
|
21306
21671
|
// ─── Import ───────────────────────────────────────────────────────
|
|
21307
21672
|
/**
|
|
21308
21673
|
* Adopt an existing API Gateway V2 resource into cdkd state.
|
|
@@ -21516,6 +21881,36 @@ var CloudFrontOAIProvider = class {
|
|
|
21516
21881
|
`Unsupported attribute: ${attributeName} for AWS::CloudFront::CloudFrontOriginAccessIdentity`
|
|
21517
21882
|
);
|
|
21518
21883
|
}
|
|
21884
|
+
/**
|
|
21885
|
+
* Read the AWS-current OAI configuration in CFn-property shape.
|
|
21886
|
+
*
|
|
21887
|
+
* Issues a single `GetCloudFrontOriginAccessIdentity` and surfaces the
|
|
21888
|
+
* `CloudFrontOriginAccessIdentityConfig.Comment` key — the only
|
|
21889
|
+
* cdkd-managed property (CallerReference is set by cdkd itself and is
|
|
21890
|
+
* not part of the user-configurable surface).
|
|
21891
|
+
*
|
|
21892
|
+
* Returns `undefined` when the OAI is gone (`NoSuchCloudFrontOriginAccessIdentity`).
|
|
21893
|
+
*/
|
|
21894
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
21895
|
+
try {
|
|
21896
|
+
const resp = await this.cloudFrontClient.send(
|
|
21897
|
+
new GetCloudFrontOriginAccessIdentityCommand2({ Id: physicalId })
|
|
21898
|
+
);
|
|
21899
|
+
const config = resp.CloudFrontOriginAccessIdentity?.CloudFrontOriginAccessIdentityConfig;
|
|
21900
|
+
if (!config)
|
|
21901
|
+
return void 0;
|
|
21902
|
+
const inner = {};
|
|
21903
|
+
if (config.Comment !== void 0)
|
|
21904
|
+
inner["Comment"] = config.Comment;
|
|
21905
|
+
return {
|
|
21906
|
+
CloudFrontOriginAccessIdentityConfig: inner
|
|
21907
|
+
};
|
|
21908
|
+
} catch (err) {
|
|
21909
|
+
if (err instanceof NoSuchCloudFrontOriginAccessIdentity)
|
|
21910
|
+
return void 0;
|
|
21911
|
+
throw err;
|
|
21912
|
+
}
|
|
21913
|
+
}
|
|
21519
21914
|
/**
|
|
21520
21915
|
* Adopt an existing CloudFront Origin Access Identity into cdkd state.
|
|
21521
21916
|
*
|
|
@@ -22472,6 +22867,95 @@ var StepFunctionsProvider = class {
|
|
|
22472
22867
|
);
|
|
22473
22868
|
}
|
|
22474
22869
|
}
|
|
22870
|
+
/**
|
|
22871
|
+
* Read the AWS-current Step Functions state machine config in CFn-property
|
|
22872
|
+
* shape.
|
|
22873
|
+
*
|
|
22874
|
+
* Issues a single `DescribeStateMachine` and surfaces:
|
|
22875
|
+
* - `StateMachineName` (`name`)
|
|
22876
|
+
* - `RoleArn` (`roleArn`)
|
|
22877
|
+
* - `StateMachineType` (`type`)
|
|
22878
|
+
* - `LoggingConfiguration` / `TracingConfiguration` / `EncryptionConfiguration`
|
|
22879
|
+
* (re-mapped to CFn PascalCase)
|
|
22880
|
+
* - `Definition` (parsed from JSON; cdkd state may hold either the
|
|
22881
|
+
* stringified `DefinitionString` or the object `Definition`, so we
|
|
22882
|
+
* surface as the object form — the comparator handles either side).
|
|
22883
|
+
*
|
|
22884
|
+
* `DefinitionSubstitutions` is omitted because they are applied at create
|
|
22885
|
+
* time and not surfaced by `DescribeStateMachine` (the response carries
|
|
22886
|
+
* the already-substituted definition).
|
|
22887
|
+
*
|
|
22888
|
+
* `Tags` is omitted (separate `ListTagsForResource` round-trip; auto-injected
|
|
22889
|
+
* `aws:cdk:path` tag-shape question is out of scope here).
|
|
22890
|
+
*
|
|
22891
|
+
* Returns `undefined` when the state machine is gone (`StateMachineDoesNotExist`).
|
|
22892
|
+
*/
|
|
22893
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
22894
|
+
let resp;
|
|
22895
|
+
try {
|
|
22896
|
+
resp = await this.getClient().send(
|
|
22897
|
+
new DescribeStateMachineCommand({ stateMachineArn: physicalId })
|
|
22898
|
+
);
|
|
22899
|
+
} catch (err) {
|
|
22900
|
+
if (err instanceof StateMachineDoesNotExist)
|
|
22901
|
+
return void 0;
|
|
22902
|
+
throw err;
|
|
22903
|
+
}
|
|
22904
|
+
const result = {};
|
|
22905
|
+
if (resp.name !== void 0)
|
|
22906
|
+
result["StateMachineName"] = resp.name;
|
|
22907
|
+
if (resp.roleArn !== void 0)
|
|
22908
|
+
result["RoleArn"] = resp.roleArn;
|
|
22909
|
+
if (resp.type !== void 0)
|
|
22910
|
+
result["StateMachineType"] = resp.type;
|
|
22911
|
+
if (resp.definition !== void 0) {
|
|
22912
|
+
try {
|
|
22913
|
+
result["Definition"] = JSON.parse(resp.definition);
|
|
22914
|
+
} catch {
|
|
22915
|
+
result["Definition"] = resp.definition;
|
|
22916
|
+
}
|
|
22917
|
+
}
|
|
22918
|
+
if (resp.loggingConfiguration) {
|
|
22919
|
+
const lc = {};
|
|
22920
|
+
if (resp.loggingConfiguration.level !== void 0) {
|
|
22921
|
+
lc["Level"] = resp.loggingConfiguration.level;
|
|
22922
|
+
}
|
|
22923
|
+
if (resp.loggingConfiguration.includeExecutionData !== void 0) {
|
|
22924
|
+
lc["IncludeExecutionData"] = resp.loggingConfiguration.includeExecutionData;
|
|
22925
|
+
}
|
|
22926
|
+
if (resp.loggingConfiguration.destinations) {
|
|
22927
|
+
lc["Destinations"] = resp.loggingConfiguration.destinations.map((d) => {
|
|
22928
|
+
const inner = {};
|
|
22929
|
+
if (d.cloudWatchLogsLogGroup?.logGroupArn) {
|
|
22930
|
+
inner["CloudWatchLogsLogGroup"] = {
|
|
22931
|
+
LogGroupArn: d.cloudWatchLogsLogGroup.logGroupArn
|
|
22932
|
+
};
|
|
22933
|
+
}
|
|
22934
|
+
return inner;
|
|
22935
|
+
});
|
|
22936
|
+
}
|
|
22937
|
+
if (Object.keys(lc).length > 0)
|
|
22938
|
+
result["LoggingConfiguration"] = lc;
|
|
22939
|
+
}
|
|
22940
|
+
if (resp.tracingConfiguration?.enabled !== void 0) {
|
|
22941
|
+
result["TracingConfiguration"] = { Enabled: resp.tracingConfiguration.enabled };
|
|
22942
|
+
}
|
|
22943
|
+
if (resp.encryptionConfiguration) {
|
|
22944
|
+
const ec = {};
|
|
22945
|
+
if (resp.encryptionConfiguration.type !== void 0) {
|
|
22946
|
+
ec["Type"] = resp.encryptionConfiguration.type;
|
|
22947
|
+
}
|
|
22948
|
+
if (resp.encryptionConfiguration.kmsKeyId !== void 0) {
|
|
22949
|
+
ec["KmsKeyId"] = resp.encryptionConfiguration.kmsKeyId;
|
|
22950
|
+
}
|
|
22951
|
+
if (resp.encryptionConfiguration.kmsDataKeyReusePeriodSeconds !== void 0) {
|
|
22952
|
+
ec["KmsDataKeyReusePeriodSeconds"] = resp.encryptionConfiguration.kmsDataKeyReusePeriodSeconds;
|
|
22953
|
+
}
|
|
22954
|
+
if (Object.keys(ec).length > 0)
|
|
22955
|
+
result["EncryptionConfiguration"] = ec;
|
|
22956
|
+
}
|
|
22957
|
+
return result;
|
|
22958
|
+
}
|
|
22475
22959
|
/**
|
|
22476
22960
|
* Adopt an existing Step Functions state machine into cdkd state.
|
|
22477
22961
|
*
|
|
@@ -23301,6 +23785,173 @@ var ECSProvider = class {
|
|
|
23301
23785
|
}
|
|
23302
23786
|
return false;
|
|
23303
23787
|
}
|
|
23788
|
+
/**
|
|
23789
|
+
* Read the AWS-current ECS resource configuration in CFn-property shape.
|
|
23790
|
+
*
|
|
23791
|
+
* Dispatches by resource type:
|
|
23792
|
+
* - `AWS::ECS::Cluster` → `DescribeClusters`
|
|
23793
|
+
* - `AWS::ECS::Service` → `DescribeServices`. Service physicalIds use
|
|
23794
|
+
* the composite form `<clusterArn>|<serviceName>`; we split on `|`.
|
|
23795
|
+
* - `AWS::ECS::TaskDefinition` → `DescribeTaskDefinition`
|
|
23796
|
+
*
|
|
23797
|
+
* Each branch surfaces only the keys cdkd's `create()` accepts, mapping
|
|
23798
|
+
* the SDK's camelCase to CFn PascalCase. Tags are intentionally omitted
|
|
23799
|
+
* (separate `ListTagsForResource` round-trip).
|
|
23800
|
+
*/
|
|
23801
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
23802
|
+
switch (resourceType) {
|
|
23803
|
+
case "AWS::ECS::Cluster":
|
|
23804
|
+
return this.readCurrentStateCluster(physicalId);
|
|
23805
|
+
case "AWS::ECS::Service":
|
|
23806
|
+
return this.readCurrentStateService(physicalId);
|
|
23807
|
+
case "AWS::ECS::TaskDefinition":
|
|
23808
|
+
return this.readCurrentStateTaskDefinition(physicalId);
|
|
23809
|
+
default:
|
|
23810
|
+
return void 0;
|
|
23811
|
+
}
|
|
23812
|
+
}
|
|
23813
|
+
async readCurrentStateCluster(physicalId) {
|
|
23814
|
+
let resp;
|
|
23815
|
+
try {
|
|
23816
|
+
resp = await this.getClient().send(
|
|
23817
|
+
new DescribeClustersCommand({ clusters: [physicalId] })
|
|
23818
|
+
);
|
|
23819
|
+
} catch {
|
|
23820
|
+
return void 0;
|
|
23821
|
+
}
|
|
23822
|
+
const c = resp.clusters?.[0];
|
|
23823
|
+
if (!c || !c.clusterName)
|
|
23824
|
+
return void 0;
|
|
23825
|
+
const result = { ClusterName: c.clusterName };
|
|
23826
|
+
if (c.capacityProviders && c.capacityProviders.length > 0) {
|
|
23827
|
+
result["CapacityProviders"] = [...c.capacityProviders];
|
|
23828
|
+
}
|
|
23829
|
+
if (c.defaultCapacityProviderStrategy && c.defaultCapacityProviderStrategy.length > 0) {
|
|
23830
|
+
result["DefaultCapacityProviderStrategy"] = c.defaultCapacityProviderStrategy;
|
|
23831
|
+
}
|
|
23832
|
+
if (c.configuration)
|
|
23833
|
+
result["Configuration"] = c.configuration;
|
|
23834
|
+
if (c.settings && c.settings.length > 0) {
|
|
23835
|
+
result["ClusterSettings"] = c.settings.map((s) => ({
|
|
23836
|
+
Name: s.name,
|
|
23837
|
+
Value: s.value
|
|
23838
|
+
}));
|
|
23839
|
+
}
|
|
23840
|
+
return result;
|
|
23841
|
+
}
|
|
23842
|
+
async readCurrentStateService(physicalId) {
|
|
23843
|
+
const sep = physicalId.indexOf("|");
|
|
23844
|
+
if (sep < 0)
|
|
23845
|
+
return void 0;
|
|
23846
|
+
const clusterArn = physicalId.substring(0, sep);
|
|
23847
|
+
const serviceName = physicalId.substring(sep + 1);
|
|
23848
|
+
let resp;
|
|
23849
|
+
try {
|
|
23850
|
+
resp = await this.getClient().send(
|
|
23851
|
+
new DescribeServicesCommand({ cluster: clusterArn, services: [serviceName] })
|
|
23852
|
+
);
|
|
23853
|
+
} catch {
|
|
23854
|
+
return void 0;
|
|
23855
|
+
}
|
|
23856
|
+
const s = resp.services?.[0];
|
|
23857
|
+
if (!s || !s.serviceName)
|
|
23858
|
+
return void 0;
|
|
23859
|
+
const result = {};
|
|
23860
|
+
if (s.serviceName !== void 0)
|
|
23861
|
+
result["ServiceName"] = s.serviceName;
|
|
23862
|
+
if (s.clusterArn !== void 0)
|
|
23863
|
+
result["Cluster"] = s.clusterArn;
|
|
23864
|
+
if (s.taskDefinition !== void 0)
|
|
23865
|
+
result["TaskDefinition"] = s.taskDefinition;
|
|
23866
|
+
if (s.desiredCount !== void 0)
|
|
23867
|
+
result["DesiredCount"] = s.desiredCount;
|
|
23868
|
+
if (s.launchType !== void 0)
|
|
23869
|
+
result["LaunchType"] = s.launchType;
|
|
23870
|
+
if (s.platformVersion !== void 0)
|
|
23871
|
+
result["PlatformVersion"] = s.platformVersion;
|
|
23872
|
+
if (s.schedulingStrategy !== void 0)
|
|
23873
|
+
result["SchedulingStrategy"] = s.schedulingStrategy;
|
|
23874
|
+
if (s.propagateTags !== void 0)
|
|
23875
|
+
result["PropagateTags"] = s.propagateTags;
|
|
23876
|
+
if (s.enableECSManagedTags !== void 0) {
|
|
23877
|
+
result["EnableECSManagedTags"] = s.enableECSManagedTags;
|
|
23878
|
+
}
|
|
23879
|
+
if (s.enableExecuteCommand !== void 0) {
|
|
23880
|
+
result["EnableExecuteCommand"] = s.enableExecuteCommand;
|
|
23881
|
+
}
|
|
23882
|
+
if (s.healthCheckGracePeriodSeconds !== void 0) {
|
|
23883
|
+
result["HealthCheckGracePeriodSeconds"] = s.healthCheckGracePeriodSeconds;
|
|
23884
|
+
}
|
|
23885
|
+
if (s.networkConfiguration)
|
|
23886
|
+
result["NetworkConfiguration"] = s.networkConfiguration;
|
|
23887
|
+
if (s.loadBalancers && s.loadBalancers.length > 0) {
|
|
23888
|
+
result["LoadBalancers"] = s.loadBalancers;
|
|
23889
|
+
}
|
|
23890
|
+
if (s.capacityProviderStrategy && s.capacityProviderStrategy.length > 0) {
|
|
23891
|
+
result["CapacityProviderStrategy"] = s.capacityProviderStrategy;
|
|
23892
|
+
}
|
|
23893
|
+
if (s.deploymentConfiguration)
|
|
23894
|
+
result["DeploymentConfiguration"] = s.deploymentConfiguration;
|
|
23895
|
+
if (s.placementConstraints && s.placementConstraints.length > 0) {
|
|
23896
|
+
result["PlacementConstraints"] = s.placementConstraints;
|
|
23897
|
+
}
|
|
23898
|
+
if (s.placementStrategy && s.placementStrategy.length > 0) {
|
|
23899
|
+
result["PlacementStrategy"] = s.placementStrategy;
|
|
23900
|
+
}
|
|
23901
|
+
if (s.serviceRegistries && s.serviceRegistries.length > 0) {
|
|
23902
|
+
result["ServiceRegistries"] = s.serviceRegistries;
|
|
23903
|
+
}
|
|
23904
|
+
return result;
|
|
23905
|
+
}
|
|
23906
|
+
async readCurrentStateTaskDefinition(physicalId) {
|
|
23907
|
+
let resp;
|
|
23908
|
+
try {
|
|
23909
|
+
resp = await this.getClient().send(
|
|
23910
|
+
new DescribeTaskDefinitionCommand({ taskDefinition: physicalId })
|
|
23911
|
+
);
|
|
23912
|
+
} catch {
|
|
23913
|
+
return void 0;
|
|
23914
|
+
}
|
|
23915
|
+
const td = resp.taskDefinition;
|
|
23916
|
+
if (!td)
|
|
23917
|
+
return void 0;
|
|
23918
|
+
const result = {};
|
|
23919
|
+
if (td.family !== void 0)
|
|
23920
|
+
result["Family"] = td.family;
|
|
23921
|
+
if (td.cpu !== void 0)
|
|
23922
|
+
result["Cpu"] = td.cpu;
|
|
23923
|
+
if (td.memory !== void 0)
|
|
23924
|
+
result["Memory"] = td.memory;
|
|
23925
|
+
if (td.networkMode !== void 0)
|
|
23926
|
+
result["NetworkMode"] = td.networkMode;
|
|
23927
|
+
if (td.requiresCompatibilities && td.requiresCompatibilities.length > 0) {
|
|
23928
|
+
result["RequiresCompatibilities"] = [...td.requiresCompatibilities];
|
|
23929
|
+
}
|
|
23930
|
+
if (td.executionRoleArn !== void 0)
|
|
23931
|
+
result["ExecutionRoleArn"] = td.executionRoleArn;
|
|
23932
|
+
if (td.taskRoleArn !== void 0)
|
|
23933
|
+
result["TaskRoleArn"] = td.taskRoleArn;
|
|
23934
|
+
if (td.volumes && td.volumes.length > 0)
|
|
23935
|
+
result["Volumes"] = td.volumes;
|
|
23936
|
+
if (td.placementConstraints && td.placementConstraints.length > 0) {
|
|
23937
|
+
result["PlacementConstraints"] = td.placementConstraints;
|
|
23938
|
+
}
|
|
23939
|
+
if (td.runtimePlatform)
|
|
23940
|
+
result["RuntimePlatform"] = td.runtimePlatform;
|
|
23941
|
+
if (td.proxyConfiguration)
|
|
23942
|
+
result["ProxyConfiguration"] = td.proxyConfiguration;
|
|
23943
|
+
if (td.pidMode !== void 0)
|
|
23944
|
+
result["PidMode"] = td.pidMode;
|
|
23945
|
+
if (td.ipcMode !== void 0)
|
|
23946
|
+
result["IpcMode"] = td.ipcMode;
|
|
23947
|
+
if (td.ephemeralStorage?.sizeInGiB !== void 0) {
|
|
23948
|
+
result["EphemeralStorage"] = { SizeInGiB: td.ephemeralStorage.sizeInGiB };
|
|
23949
|
+
}
|
|
23950
|
+
if (td.containerDefinitions && td.containerDefinitions.length > 0) {
|
|
23951
|
+
result["ContainerDefinitions"] = td.containerDefinitions;
|
|
23952
|
+
}
|
|
23953
|
+
return result;
|
|
23954
|
+
}
|
|
23304
23955
|
/**
|
|
23305
23956
|
* Adopt an existing ECS resource into cdkd state.
|
|
23306
23957
|
*
|
|
@@ -24675,6 +25326,146 @@ var RDSProvider = class {
|
|
|
24675
25326
|
return null;
|
|
24676
25327
|
}
|
|
24677
25328
|
}
|
|
25329
|
+
/**
|
|
25330
|
+
* Read the AWS-current RDS resource configuration in CFn-property shape.
|
|
25331
|
+
*
|
|
25332
|
+
* Dispatches by resource type:
|
|
25333
|
+
* - `AWS::RDS::DBInstance` → `DescribeDBInstances`
|
|
25334
|
+
* - `AWS::RDS::DBCluster` → `DescribeDBClusters`
|
|
25335
|
+
* - `AWS::RDS::DBSubnetGroup` → `DescribeDBSubnetGroups`
|
|
25336
|
+
*
|
|
25337
|
+
* Each branch surfaces only the keys cdkd's `create()` accepts. Sensitive
|
|
25338
|
+
* fields like `MasterUserPassword` are NEVER surfaced (RDS does not return
|
|
25339
|
+
* them in the Describe responses). `Tags` are intentionally omitted
|
|
25340
|
+
* (separate `ListTagsForResource` round-trip).
|
|
25341
|
+
*
|
|
25342
|
+
* Returns `undefined` when the resource is gone (`*NotFoundFault`).
|
|
25343
|
+
*/
|
|
25344
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
25345
|
+
switch (resourceType) {
|
|
25346
|
+
case "AWS::RDS::DBInstance":
|
|
25347
|
+
return this.readCurrentStateDBInstance(physicalId);
|
|
25348
|
+
case "AWS::RDS::DBCluster":
|
|
25349
|
+
return this.readCurrentStateDBCluster(physicalId);
|
|
25350
|
+
case "AWS::RDS::DBSubnetGroup":
|
|
25351
|
+
return this.readCurrentStateDBSubnetGroup(physicalId);
|
|
25352
|
+
default:
|
|
25353
|
+
return void 0;
|
|
25354
|
+
}
|
|
25355
|
+
}
|
|
25356
|
+
async readCurrentStateDBInstance(physicalId) {
|
|
25357
|
+
let inst;
|
|
25358
|
+
try {
|
|
25359
|
+
inst = await this.describeDBInstance(physicalId);
|
|
25360
|
+
} catch (err) {
|
|
25361
|
+
if (this.isNotFoundError(err, "DBInstanceNotFoundFault"))
|
|
25362
|
+
return void 0;
|
|
25363
|
+
throw err;
|
|
25364
|
+
}
|
|
25365
|
+
if (!inst)
|
|
25366
|
+
return void 0;
|
|
25367
|
+
const result = {};
|
|
25368
|
+
if (inst.DBInstanceIdentifier !== void 0) {
|
|
25369
|
+
result["DBInstanceIdentifier"] = inst.DBInstanceIdentifier;
|
|
25370
|
+
}
|
|
25371
|
+
if (inst.DBInstanceClass !== void 0)
|
|
25372
|
+
result["DBInstanceClass"] = inst.DBInstanceClass;
|
|
25373
|
+
if (inst.Engine !== void 0)
|
|
25374
|
+
result["Engine"] = inst.Engine;
|
|
25375
|
+
if (inst.DBClusterIdentifier !== void 0) {
|
|
25376
|
+
result["DBClusterIdentifier"] = inst.DBClusterIdentifier;
|
|
25377
|
+
}
|
|
25378
|
+
if (inst.DBSubnetGroup?.DBSubnetGroupName !== void 0) {
|
|
25379
|
+
result["DBSubnetGroupName"] = inst.DBSubnetGroup.DBSubnetGroupName;
|
|
25380
|
+
}
|
|
25381
|
+
if (inst.PubliclyAccessible !== void 0) {
|
|
25382
|
+
result["PubliclyAccessible"] = inst.PubliclyAccessible;
|
|
25383
|
+
}
|
|
25384
|
+
return result;
|
|
25385
|
+
}
|
|
25386
|
+
async readCurrentStateDBCluster(physicalId) {
|
|
25387
|
+
let cluster;
|
|
25388
|
+
try {
|
|
25389
|
+
cluster = await this.describeDBCluster(physicalId);
|
|
25390
|
+
} catch (err) {
|
|
25391
|
+
if (this.isNotFoundError(err, "DBClusterNotFoundFault"))
|
|
25392
|
+
return void 0;
|
|
25393
|
+
throw err;
|
|
25394
|
+
}
|
|
25395
|
+
if (!cluster)
|
|
25396
|
+
return void 0;
|
|
25397
|
+
const result = {};
|
|
25398
|
+
if (cluster.DBClusterIdentifier !== void 0) {
|
|
25399
|
+
result["DBClusterIdentifier"] = cluster.DBClusterIdentifier;
|
|
25400
|
+
}
|
|
25401
|
+
if (cluster.Engine !== void 0)
|
|
25402
|
+
result["Engine"] = cluster.Engine;
|
|
25403
|
+
if (cluster.EngineVersion !== void 0)
|
|
25404
|
+
result["EngineVersion"] = cluster.EngineVersion;
|
|
25405
|
+
if (cluster.MasterUsername !== void 0)
|
|
25406
|
+
result["MasterUsername"] = cluster.MasterUsername;
|
|
25407
|
+
if (cluster.DatabaseName !== void 0)
|
|
25408
|
+
result["DatabaseName"] = cluster.DatabaseName;
|
|
25409
|
+
if (cluster.Port !== void 0)
|
|
25410
|
+
result["Port"] = cluster.Port;
|
|
25411
|
+
if (cluster.VpcSecurityGroups && cluster.VpcSecurityGroups.length > 0) {
|
|
25412
|
+
result["VpcSecurityGroupIds"] = cluster.VpcSecurityGroups.map(
|
|
25413
|
+
(sg) => sg.VpcSecurityGroupId
|
|
25414
|
+
).filter((id) => !!id);
|
|
25415
|
+
}
|
|
25416
|
+
if (cluster.DBSubnetGroup !== void 0)
|
|
25417
|
+
result["DBSubnetGroupName"] = cluster.DBSubnetGroup;
|
|
25418
|
+
if (cluster.StorageEncrypted !== void 0) {
|
|
25419
|
+
result["StorageEncrypted"] = cluster.StorageEncrypted;
|
|
25420
|
+
}
|
|
25421
|
+
if (cluster.KmsKeyId !== void 0)
|
|
25422
|
+
result["KmsKeyId"] = cluster.KmsKeyId;
|
|
25423
|
+
if (cluster.BackupRetentionPeriod !== void 0) {
|
|
25424
|
+
result["BackupRetentionPeriod"] = cluster.BackupRetentionPeriod;
|
|
25425
|
+
}
|
|
25426
|
+
if (cluster.DeletionProtection !== void 0) {
|
|
25427
|
+
result["DeletionProtection"] = cluster.DeletionProtection;
|
|
25428
|
+
}
|
|
25429
|
+
if (cluster.ServerlessV2ScalingConfiguration) {
|
|
25430
|
+
const sc = {};
|
|
25431
|
+
if (cluster.ServerlessV2ScalingConfiguration.MinCapacity !== void 0) {
|
|
25432
|
+
sc["MinCapacity"] = cluster.ServerlessV2ScalingConfiguration.MinCapacity;
|
|
25433
|
+
}
|
|
25434
|
+
if (cluster.ServerlessV2ScalingConfiguration.MaxCapacity !== void 0) {
|
|
25435
|
+
sc["MaxCapacity"] = cluster.ServerlessV2ScalingConfiguration.MaxCapacity;
|
|
25436
|
+
}
|
|
25437
|
+
if (Object.keys(sc).length > 0)
|
|
25438
|
+
result["ServerlessV2ScalingConfiguration"] = sc;
|
|
25439
|
+
}
|
|
25440
|
+
return result;
|
|
25441
|
+
}
|
|
25442
|
+
async readCurrentStateDBSubnetGroup(physicalId) {
|
|
25443
|
+
let resp;
|
|
25444
|
+
try {
|
|
25445
|
+
resp = await this.getClient().send(
|
|
25446
|
+
new DescribeDBSubnetGroupsCommand({ DBSubnetGroupName: physicalId })
|
|
25447
|
+
);
|
|
25448
|
+
} catch (err) {
|
|
25449
|
+
if (this.isNotFoundError(err, "DBSubnetGroupNotFoundFault"))
|
|
25450
|
+
return void 0;
|
|
25451
|
+
throw err;
|
|
25452
|
+
}
|
|
25453
|
+
const sg = resp.DBSubnetGroups?.[0];
|
|
25454
|
+
if (!sg)
|
|
25455
|
+
return void 0;
|
|
25456
|
+
const result = {};
|
|
25457
|
+
if (sg.DBSubnetGroupName !== void 0)
|
|
25458
|
+
result["DBSubnetGroupName"] = sg.DBSubnetGroupName;
|
|
25459
|
+
if (sg.DBSubnetGroupDescription !== void 0) {
|
|
25460
|
+
result["DBSubnetGroupDescription"] = sg.DBSubnetGroupDescription;
|
|
25461
|
+
}
|
|
25462
|
+
if (sg.Subnets && sg.Subnets.length > 0) {
|
|
25463
|
+
result["SubnetIds"] = sg.Subnets.map((s) => s.SubnetIdentifier).filter(
|
|
25464
|
+
(id) => !!id
|
|
25465
|
+
);
|
|
25466
|
+
}
|
|
25467
|
+
return result;
|
|
25468
|
+
}
|
|
24678
25469
|
async importDBInstance(input) {
|
|
24679
25470
|
const explicit = resolveExplicitPhysicalId(input, "DBInstanceIdentifier");
|
|
24680
25471
|
if (explicit) {
|
|
@@ -26127,6 +26918,98 @@ var CognitoUserPoolProvider = class {
|
|
|
26127
26918
|
);
|
|
26128
26919
|
}
|
|
26129
26920
|
}
|
|
26921
|
+
/**
|
|
26922
|
+
* Read the AWS-current Cognito User Pool configuration in CFn-property shape.
|
|
26923
|
+
*
|
|
26924
|
+
* Issues `DescribeUserPool` and surfaces the keys cdkd's `create()` accepts.
|
|
26925
|
+
* AWS-managed fields (Arn, Id, CreationDate, LastModifiedDate, EstimatedNumberOfUsers,
|
|
26926
|
+
* etc.) are filtered at the wire layer.
|
|
26927
|
+
*
|
|
26928
|
+
* **Note**: Cognito only supports `AWS::Cognito::UserPool` in this provider;
|
|
26929
|
+
* `UserPoolClient`, `UserPoolGroup`, and other Cognito sub-resources go
|
|
26930
|
+
* through the CC API fallback (which has its own `readCurrentState`).
|
|
26931
|
+
*
|
|
26932
|
+
* `UserPoolTags` is intentionally omitted (Cognito returns tags via a
|
|
26933
|
+
* separate `ListTagsForResource` round-trip; auto-injected `aws:cdk:path`
|
|
26934
|
+
* tag-shape question is out of scope here).
|
|
26935
|
+
*
|
|
26936
|
+
* Returns `undefined` when the pool is gone (`ResourceNotFoundException`).
|
|
26937
|
+
*/
|
|
26938
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
26939
|
+
if (resourceType !== "AWS::Cognito::UserPool")
|
|
26940
|
+
return void 0;
|
|
26941
|
+
let resp;
|
|
26942
|
+
try {
|
|
26943
|
+
resp = await this.getClient().send(new DescribeUserPoolCommand({ UserPoolId: physicalId }));
|
|
26944
|
+
} catch (err) {
|
|
26945
|
+
if (err instanceof ResourceNotFoundException12)
|
|
26946
|
+
return void 0;
|
|
26947
|
+
throw err;
|
|
26948
|
+
}
|
|
26949
|
+
const pool = resp.UserPool;
|
|
26950
|
+
if (!pool)
|
|
26951
|
+
return void 0;
|
|
26952
|
+
const result = {};
|
|
26953
|
+
if (pool.Name !== void 0)
|
|
26954
|
+
result["UserPoolName"] = pool.Name;
|
|
26955
|
+
if (pool.AutoVerifiedAttributes && pool.AutoVerifiedAttributes.length > 0) {
|
|
26956
|
+
result["AutoVerifiedAttributes"] = [...pool.AutoVerifiedAttributes];
|
|
26957
|
+
}
|
|
26958
|
+
if (pool.UsernameAttributes && pool.UsernameAttributes.length > 0) {
|
|
26959
|
+
result["UsernameAttributes"] = [...pool.UsernameAttributes];
|
|
26960
|
+
}
|
|
26961
|
+
if (pool.AliasAttributes && pool.AliasAttributes.length > 0) {
|
|
26962
|
+
result["AliasAttributes"] = [...pool.AliasAttributes];
|
|
26963
|
+
}
|
|
26964
|
+
if (pool.Policies)
|
|
26965
|
+
result["Policies"] = pool.Policies;
|
|
26966
|
+
if (pool.SchemaAttributes && pool.SchemaAttributes.length > 0) {
|
|
26967
|
+
result["Schema"] = pool.SchemaAttributes;
|
|
26968
|
+
}
|
|
26969
|
+
if (pool.LambdaConfig && Object.keys(pool.LambdaConfig).length > 0) {
|
|
26970
|
+
result["LambdaConfig"] = pool.LambdaConfig;
|
|
26971
|
+
}
|
|
26972
|
+
if (pool.MfaConfiguration !== void 0)
|
|
26973
|
+
result["MfaConfiguration"] = pool.MfaConfiguration;
|
|
26974
|
+
if (pool.AdminCreateUserConfig)
|
|
26975
|
+
result["AdminCreateUserConfig"] = pool.AdminCreateUserConfig;
|
|
26976
|
+
if (pool.AccountRecoverySetting) {
|
|
26977
|
+
result["AccountRecoverySetting"] = pool.AccountRecoverySetting;
|
|
26978
|
+
}
|
|
26979
|
+
if (pool.UserAttributeUpdateSettings) {
|
|
26980
|
+
result["UserAttributeUpdateSettings"] = pool.UserAttributeUpdateSettings;
|
|
26981
|
+
}
|
|
26982
|
+
if (pool.DeletionProtection !== void 0) {
|
|
26983
|
+
result["DeletionProtection"] = pool.DeletionProtection;
|
|
26984
|
+
}
|
|
26985
|
+
if (pool.EmailConfiguration)
|
|
26986
|
+
result["EmailConfiguration"] = pool.EmailConfiguration;
|
|
26987
|
+
if (pool.SmsConfiguration)
|
|
26988
|
+
result["SmsConfiguration"] = pool.SmsConfiguration;
|
|
26989
|
+
if (pool.VerificationMessageTemplate) {
|
|
26990
|
+
result["VerificationMessageTemplate"] = pool.VerificationMessageTemplate;
|
|
26991
|
+
}
|
|
26992
|
+
if (pool.UsernameConfiguration) {
|
|
26993
|
+
result["UsernameConfiguration"] = pool.UsernameConfiguration;
|
|
26994
|
+
}
|
|
26995
|
+
if (pool.DeviceConfiguration)
|
|
26996
|
+
result["DeviceConfiguration"] = pool.DeviceConfiguration;
|
|
26997
|
+
if (pool.UserPoolAddOns)
|
|
26998
|
+
result["UserPoolAddOns"] = pool.UserPoolAddOns;
|
|
26999
|
+
if (pool.EmailVerificationMessage !== void 0) {
|
|
27000
|
+
result["EmailVerificationMessage"] = pool.EmailVerificationMessage;
|
|
27001
|
+
}
|
|
27002
|
+
if (pool.EmailVerificationSubject !== void 0) {
|
|
27003
|
+
result["EmailVerificationSubject"] = pool.EmailVerificationSubject;
|
|
27004
|
+
}
|
|
27005
|
+
if (pool.SmsAuthenticationMessage !== void 0) {
|
|
27006
|
+
result["SmsAuthenticationMessage"] = pool.SmsAuthenticationMessage;
|
|
27007
|
+
}
|
|
27008
|
+
if (pool.SmsVerificationMessage !== void 0) {
|
|
27009
|
+
result["SmsVerificationMessage"] = pool.SmsVerificationMessage;
|
|
27010
|
+
}
|
|
27011
|
+
return result;
|
|
27012
|
+
}
|
|
26130
27013
|
/**
|
|
26131
27014
|
* Adopt an existing Cognito User Pool into cdkd state.
|
|
26132
27015
|
*
|
|
@@ -28700,6 +29583,88 @@ var KMSProvider = class {
|
|
|
28700
29583
|
);
|
|
28701
29584
|
}
|
|
28702
29585
|
}
|
|
29586
|
+
/**
|
|
29587
|
+
* Read the AWS-current KMS resource configuration in CFn-property shape.
|
|
29588
|
+
*
|
|
29589
|
+
* Dispatches by resource type:
|
|
29590
|
+
* - `AWS::KMS::Key` → `DescribeKey`. Surfaces `Description`, `KeySpec`,
|
|
29591
|
+
* `KeyUsage`, `Enabled`, `MultiRegion`, `Origin`. `KeyPolicy` is
|
|
29592
|
+
* intentionally NOT retrieved — `GetKeyPolicy` is a separate call
|
|
29593
|
+
* and the policy body needs JSON parsing for comparison; deferred
|
|
29594
|
+
* to a follow-up. `EnableKeyRotation` / `RotationPeriodInDays`
|
|
29595
|
+
* would require `GetKeyRotationStatus`; also deferred.
|
|
29596
|
+
* - `AWS::KMS::Alias` → `ListAliases` filtered to the alias name.
|
|
29597
|
+
* Surfaces `AliasName`, `TargetKeyId`. `ListAliases` is paginated
|
|
29598
|
+
* since there's no direct "describe one alias" API.
|
|
29599
|
+
*
|
|
29600
|
+
* `Tags` is intentionally omitted (separate `ListResourceTags` round-trip
|
|
29601
|
+
* for keys; auto-injected `aws:cdk:path` tag-shape question is out of
|
|
29602
|
+
* scope here). `BypassPolicyLockoutSafetyCheck` and `PendingWindowInDays`
|
|
29603
|
+
* are not part of the persisted AWS state visible via `DescribeKey`.
|
|
29604
|
+
*
|
|
29605
|
+
* Returns `undefined` when the resource is gone (`NotFoundException`).
|
|
29606
|
+
*/
|
|
29607
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
29608
|
+
switch (resourceType) {
|
|
29609
|
+
case "AWS::KMS::Key":
|
|
29610
|
+
return this.readCurrentStateKey(physicalId);
|
|
29611
|
+
case "AWS::KMS::Alias":
|
|
29612
|
+
return this.readCurrentStateAlias(physicalId);
|
|
29613
|
+
default:
|
|
29614
|
+
return void 0;
|
|
29615
|
+
}
|
|
29616
|
+
}
|
|
29617
|
+
async readCurrentStateKey(physicalId) {
|
|
29618
|
+
let resp;
|
|
29619
|
+
try {
|
|
29620
|
+
resp = await this.getClient().send(
|
|
29621
|
+
new DescribeKeyCommand({ KeyId: physicalId })
|
|
29622
|
+
);
|
|
29623
|
+
} catch (err) {
|
|
29624
|
+
if (err instanceof NotFoundException5)
|
|
29625
|
+
return void 0;
|
|
29626
|
+
throw err;
|
|
29627
|
+
}
|
|
29628
|
+
const md = resp.KeyMetadata;
|
|
29629
|
+
if (!md)
|
|
29630
|
+
return void 0;
|
|
29631
|
+
const result = {};
|
|
29632
|
+
if (md.Description !== void 0 && md.Description !== "") {
|
|
29633
|
+
result["Description"] = md.Description;
|
|
29634
|
+
}
|
|
29635
|
+
if (md.KeySpec !== void 0)
|
|
29636
|
+
result["KeySpec"] = md.KeySpec;
|
|
29637
|
+
if (md.KeyUsage !== void 0)
|
|
29638
|
+
result["KeyUsage"] = md.KeyUsage;
|
|
29639
|
+
if (md.Enabled !== void 0)
|
|
29640
|
+
result["Enabled"] = md.Enabled;
|
|
29641
|
+
if (md.MultiRegion !== void 0)
|
|
29642
|
+
result["MultiRegion"] = md.MultiRegion;
|
|
29643
|
+
if (md.Origin !== void 0)
|
|
29644
|
+
result["Origin"] = md.Origin;
|
|
29645
|
+
return result;
|
|
29646
|
+
}
|
|
29647
|
+
async readCurrentStateAlias(physicalId) {
|
|
29648
|
+
let marker;
|
|
29649
|
+
do {
|
|
29650
|
+
const list = await this.getClient().send(
|
|
29651
|
+
new ListAliasesCommand2({ ...marker && { Marker: marker } })
|
|
29652
|
+
);
|
|
29653
|
+
const found = list.Aliases?.find(
|
|
29654
|
+
(a) => a.AliasName === physicalId
|
|
29655
|
+
);
|
|
29656
|
+
if (found) {
|
|
29657
|
+
const result = {};
|
|
29658
|
+
if (found.AliasName)
|
|
29659
|
+
result["AliasName"] = found.AliasName;
|
|
29660
|
+
if (found.TargetKeyId)
|
|
29661
|
+
result["TargetKeyId"] = found.TargetKeyId;
|
|
29662
|
+
return result;
|
|
29663
|
+
}
|
|
29664
|
+
marker = list.NextMarker;
|
|
29665
|
+
} while (marker);
|
|
29666
|
+
return void 0;
|
|
29667
|
+
}
|
|
28703
29668
|
/**
|
|
28704
29669
|
* Adopt an existing KMS key or alias into cdkd state.
|
|
28705
29670
|
*
|
|
@@ -31712,12 +32677,14 @@ import {
|
|
|
31712
32677
|
CreateRepositoryCommand,
|
|
31713
32678
|
DeleteRepositoryCommand,
|
|
31714
32679
|
DescribeRepositoriesCommand,
|
|
32680
|
+
GetLifecyclePolicyCommand,
|
|
31715
32681
|
PutLifecyclePolicyCommand,
|
|
31716
32682
|
SetRepositoryPolicyCommand,
|
|
31717
32683
|
PutImageScanningConfigurationCommand,
|
|
31718
32684
|
PutImageTagMutabilityCommand,
|
|
31719
32685
|
TagResourceCommand as TagResourceCommand7,
|
|
31720
32686
|
ListTagsForResourceCommand as ListTagsForResourceCommand18,
|
|
32687
|
+
LifecyclePolicyNotFoundException,
|
|
31721
32688
|
RepositoryNotFoundException
|
|
31722
32689
|
} from "@aws-sdk/client-ecr";
|
|
31723
32690
|
var ECRProvider = class {
|
|
@@ -31951,6 +32918,82 @@ var ECRProvider = class {
|
|
|
31951
32918
|
);
|
|
31952
32919
|
}
|
|
31953
32920
|
}
|
|
32921
|
+
/**
|
|
32922
|
+
* Read the AWS-current ECR repository configuration in CFn-property shape.
|
|
32923
|
+
*
|
|
32924
|
+
* Issues `DescribeRepositories(filtered=[name])` for the repository's
|
|
32925
|
+
* configuration, then a separate `GetLifecyclePolicy` for `LifecyclePolicy`
|
|
32926
|
+
* (which `DescribeRepositories` doesn't return).
|
|
32927
|
+
*
|
|
32928
|
+
* Surfaced keys: `RepositoryName`, `ImageTagMutability`,
|
|
32929
|
+
* `ImageScanningConfiguration`, `EncryptionConfiguration`, `LifecyclePolicy`
|
|
32930
|
+
* (when configured — `LifecyclePolicyNotFoundException` is caught and the
|
|
32931
|
+
* key omitted, NOT propagated as repo-gone).
|
|
32932
|
+
*
|
|
32933
|
+
* Intentionally omitted:
|
|
32934
|
+
* - `RepositoryPolicyText`: requires a separate `GetRepositoryPolicy`
|
|
32935
|
+
* round-trip; cdkd state holds the policy as either a string or an
|
|
32936
|
+
* object (depending on user input), and the comparator round-trip
|
|
32937
|
+
* is not yet handled here.
|
|
32938
|
+
* - `Tags`: requires `ListTagsForResource`; auto-injected
|
|
32939
|
+
* `aws:cdk:path` tag-shape question is out of scope.
|
|
32940
|
+
* - `EmptyOnDelete` / `ImageTagMutabilityExclusionFilters`: not part
|
|
32941
|
+
* of the persisted AWS state visible via standard Describe.
|
|
32942
|
+
*
|
|
32943
|
+
* Returns `undefined` when the repository is gone (`RepositoryNotFoundException`).
|
|
32944
|
+
*/
|
|
32945
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
32946
|
+
let repo;
|
|
32947
|
+
try {
|
|
32948
|
+
repo = await this.getClient().send(
|
|
32949
|
+
new DescribeRepositoriesCommand({ repositoryNames: [physicalId] })
|
|
32950
|
+
);
|
|
32951
|
+
} catch (err) {
|
|
32952
|
+
if (err instanceof RepositoryNotFoundException)
|
|
32953
|
+
return void 0;
|
|
32954
|
+
throw err;
|
|
32955
|
+
}
|
|
32956
|
+
const r = repo.repositories?.[0];
|
|
32957
|
+
if (!r)
|
|
32958
|
+
return void 0;
|
|
32959
|
+
const result = {};
|
|
32960
|
+
if (r.repositoryName !== void 0)
|
|
32961
|
+
result["RepositoryName"] = r.repositoryName;
|
|
32962
|
+
if (r.imageTagMutability !== void 0)
|
|
32963
|
+
result["ImageTagMutability"] = r.imageTagMutability;
|
|
32964
|
+
if (r.imageScanningConfiguration) {
|
|
32965
|
+
const inner = {};
|
|
32966
|
+
if (r.imageScanningConfiguration.scanOnPush !== void 0) {
|
|
32967
|
+
inner["ScanOnPush"] = r.imageScanningConfiguration.scanOnPush;
|
|
32968
|
+
}
|
|
32969
|
+
if (Object.keys(inner).length > 0)
|
|
32970
|
+
result["ImageScanningConfiguration"] = inner;
|
|
32971
|
+
}
|
|
32972
|
+
if (r.encryptionConfiguration) {
|
|
32973
|
+
const inner = {};
|
|
32974
|
+
if (r.encryptionConfiguration.encryptionType !== void 0) {
|
|
32975
|
+
inner["EncryptionType"] = r.encryptionConfiguration.encryptionType;
|
|
32976
|
+
}
|
|
32977
|
+
if (r.encryptionConfiguration.kmsKey !== void 0) {
|
|
32978
|
+
inner["KmsKey"] = r.encryptionConfiguration.kmsKey;
|
|
32979
|
+
}
|
|
32980
|
+
if (Object.keys(inner).length > 0)
|
|
32981
|
+
result["EncryptionConfiguration"] = inner;
|
|
32982
|
+
}
|
|
32983
|
+
try {
|
|
32984
|
+
const lp = await this.getClient().send(
|
|
32985
|
+
new GetLifecyclePolicyCommand({ repositoryName: physicalId })
|
|
32986
|
+
);
|
|
32987
|
+
if (lp.lifecyclePolicyText) {
|
|
32988
|
+
result["LifecyclePolicy"] = { LifecyclePolicyText: lp.lifecyclePolicyText };
|
|
32989
|
+
}
|
|
32990
|
+
} catch (err) {
|
|
32991
|
+
if (!(err instanceof LifecyclePolicyNotFoundException)) {
|
|
32992
|
+
throw err;
|
|
32993
|
+
}
|
|
32994
|
+
}
|
|
32995
|
+
return result;
|
|
32996
|
+
}
|
|
31954
32997
|
/**
|
|
31955
32998
|
* Adopt an existing ECR repository into cdkd state.
|
|
31956
32999
|
*
|
|
@@ -34066,6 +35109,7 @@ function createDiffCommand() {
|
|
|
34066
35109
|
}
|
|
34067
35110
|
|
|
34068
35111
|
// src/cli/commands/drift.ts
|
|
35112
|
+
import * as readline from "node:readline/promises";
|
|
34069
35113
|
import { Command as Command6, Option as Option3 } from "commander";
|
|
34070
35114
|
init_aws_clients();
|
|
34071
35115
|
|
|
@@ -34141,6 +35185,11 @@ async function driftCommand(stacks, options) {
|
|
|
34141
35185
|
if (!options.all && stacks.length === 0) {
|
|
34142
35186
|
throw new Error("Stack name is required. Usage: cdkd drift <stack> [<stack>...] | --all");
|
|
34143
35187
|
}
|
|
35188
|
+
if (options.accept && options.revert) {
|
|
35189
|
+
throw new Error(
|
|
35190
|
+
"--accept and --revert are mutually exclusive. Use --accept to update cdkd state from AWS, or --revert to push cdkd state values back into AWS."
|
|
35191
|
+
);
|
|
35192
|
+
}
|
|
34144
35193
|
await applyRoleArnIfSet({ roleArn: options.roleArn, region: options.region });
|
|
34145
35194
|
const awsClients = new AwsClients({
|
|
34146
35195
|
...options.region && { region: options.region },
|
|
@@ -34151,14 +35200,11 @@ async function driftCommand(stacks, options) {
|
|
|
34151
35200
|
const region = options.region || process.env["AWS_REGION"] || "us-east-1";
|
|
34152
35201
|
const bucket = await resolveStateBucketWithDefault(options.stateBucket, region);
|
|
34153
35202
|
const prefix = options.statePrefix;
|
|
34154
|
-
const
|
|
34155
|
-
|
|
34156
|
-
|
|
34157
|
-
{
|
|
34158
|
-
|
|
34159
|
-
...options.profile && { profile: options.profile }
|
|
34160
|
-
}
|
|
34161
|
-
);
|
|
35203
|
+
const stateConfig = { bucket, prefix };
|
|
35204
|
+
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig, {
|
|
35205
|
+
region,
|
|
35206
|
+
...options.profile && { profile: options.profile }
|
|
35207
|
+
});
|
|
34162
35208
|
await stateBackend.verifyBucketExists();
|
|
34163
35209
|
const providerRegistry = new ProviderRegistry();
|
|
34164
35210
|
registerAllProviders(providerRegistry);
|
|
@@ -34186,8 +35232,22 @@ async function driftCommand(stacks, options) {
|
|
|
34186
35232
|
writeHumanReport(reports);
|
|
34187
35233
|
}
|
|
34188
35234
|
const drifted = reports.some((r) => r.outcomes.some((o) => o.kind === "drifted"));
|
|
34189
|
-
if (
|
|
34190
|
-
|
|
35235
|
+
if (!options.accept && !options.revert) {
|
|
35236
|
+
if (drifted) {
|
|
35237
|
+
throw new DriftDetectedError();
|
|
35238
|
+
}
|
|
35239
|
+
return;
|
|
35240
|
+
}
|
|
35241
|
+
if (!drifted) {
|
|
35242
|
+
logger.info(
|
|
35243
|
+
options.accept ? "No drift detected \u2014 nothing to accept." : "No drift detected \u2014 nothing to revert."
|
|
35244
|
+
);
|
|
35245
|
+
return;
|
|
35246
|
+
}
|
|
35247
|
+
if (options.accept) {
|
|
35248
|
+
await runAccept(reports, stateBackend, stateConfig, awsClients, options);
|
|
35249
|
+
} else {
|
|
35250
|
+
await runRevert(reports, providerRegistry, stateConfig, awsClients, options);
|
|
34191
35251
|
}
|
|
34192
35252
|
} finally {
|
|
34193
35253
|
awsClients.destroy();
|
|
@@ -34288,13 +35348,261 @@ async function runDriftForStack(stackName, region, stateBackend, providerRegistr
|
|
|
34288
35348
|
kind: "drifted",
|
|
34289
35349
|
logicalId,
|
|
34290
35350
|
resourceType: resource.resourceType,
|
|
34291
|
-
changes
|
|
35351
|
+
changes,
|
|
35352
|
+
awsProperties: aws
|
|
34292
35353
|
});
|
|
34293
35354
|
}
|
|
34294
35355
|
}
|
|
34295
|
-
return {
|
|
35356
|
+
return {
|
|
35357
|
+
stackName,
|
|
35358
|
+
region,
|
|
35359
|
+
outcomes,
|
|
35360
|
+
state,
|
|
35361
|
+
etag: result.etag,
|
|
35362
|
+
migrationPending: result.migrationPending ?? false
|
|
35363
|
+
};
|
|
34296
35364
|
});
|
|
34297
35365
|
}
|
|
35366
|
+
function setAtPath(target, path, value) {
|
|
35367
|
+
if (path.length === 0) {
|
|
35368
|
+
return;
|
|
35369
|
+
}
|
|
35370
|
+
const segments = path.split(".");
|
|
35371
|
+
let cursor = target;
|
|
35372
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
35373
|
+
const key = segments[i];
|
|
35374
|
+
const next = cursor[key];
|
|
35375
|
+
if (next === void 0 || next === null || typeof next !== "object" || Array.isArray(next)) {
|
|
35376
|
+
const fresh = {};
|
|
35377
|
+
cursor[key] = fresh;
|
|
35378
|
+
cursor = fresh;
|
|
35379
|
+
} else {
|
|
35380
|
+
cursor = next;
|
|
35381
|
+
}
|
|
35382
|
+
}
|
|
35383
|
+
cursor[segments[segments.length - 1]] = value;
|
|
35384
|
+
}
|
|
35385
|
+
async function runAccept(reports, stateBackend, stateConfig, awsClients, options) {
|
|
35386
|
+
const logger = getLogger();
|
|
35387
|
+
printAcceptPlan(reports);
|
|
35388
|
+
if (options.dryRun) {
|
|
35389
|
+
logger.info("--dry-run: state will NOT be written. Re-run without --dry-run to apply.");
|
|
35390
|
+
return;
|
|
35391
|
+
}
|
|
35392
|
+
if (!options.yes) {
|
|
35393
|
+
const ok = await confirmPrompt(`Update cdkd state with the AWS-current values shown above?`);
|
|
35394
|
+
if (!ok) {
|
|
35395
|
+
logger.info("Aborted.");
|
|
35396
|
+
return;
|
|
35397
|
+
}
|
|
35398
|
+
}
|
|
35399
|
+
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
35400
|
+
const owner = `${process.env["USER"] || "unknown"}@${process.env["HOSTNAME"] || "host"}:${process.pid}`;
|
|
35401
|
+
for (const report of reports) {
|
|
35402
|
+
const driftedOutcomes = report.outcomes.filter(
|
|
35403
|
+
(o) => o.kind === "drifted"
|
|
35404
|
+
);
|
|
35405
|
+
if (driftedOutcomes.length === 0) {
|
|
35406
|
+
continue;
|
|
35407
|
+
}
|
|
35408
|
+
await lockManager.acquireLock(report.stackName, report.region, owner, "drift-accept");
|
|
35409
|
+
try {
|
|
35410
|
+
const resources = { ...report.state.resources };
|
|
35411
|
+
for (const outcome of driftedOutcomes) {
|
|
35412
|
+
const existing = resources[outcome.logicalId];
|
|
35413
|
+
if (!existing)
|
|
35414
|
+
continue;
|
|
35415
|
+
const newProperties = JSON.parse(JSON.stringify(existing.properties ?? {}));
|
|
35416
|
+
for (const change of outcome.changes) {
|
|
35417
|
+
setAtPath(newProperties, change.path, change.awsValue);
|
|
35418
|
+
}
|
|
35419
|
+
resources[outcome.logicalId] = {
|
|
35420
|
+
...existing,
|
|
35421
|
+
properties: newProperties
|
|
35422
|
+
};
|
|
35423
|
+
}
|
|
35424
|
+
const newState = {
|
|
35425
|
+
...report.state,
|
|
35426
|
+
resources,
|
|
35427
|
+
lastModified: Date.now()
|
|
35428
|
+
};
|
|
35429
|
+
const saveOptions = {
|
|
35430
|
+
expectedEtag: report.etag
|
|
35431
|
+
};
|
|
35432
|
+
if (report.migrationPending) {
|
|
35433
|
+
saveOptions.migrateLegacy = true;
|
|
35434
|
+
}
|
|
35435
|
+
await stateBackend.saveState(report.stackName, report.region, newState, saveOptions);
|
|
35436
|
+
logger.info(
|
|
35437
|
+
`\u2713 State updated for ${report.stackName} (${report.region}): accepted drift on ${driftedOutcomes.length} resource(s).`
|
|
35438
|
+
);
|
|
35439
|
+
} finally {
|
|
35440
|
+
await lockManager.releaseLock(report.stackName, report.region).catch((err) => {
|
|
35441
|
+
logger.warn(
|
|
35442
|
+
`Failed to release lock for ${report.stackName} (${report.region}): ` + (err instanceof Error ? err.message : String(err))
|
|
35443
|
+
);
|
|
35444
|
+
});
|
|
35445
|
+
}
|
|
35446
|
+
}
|
|
35447
|
+
}
|
|
35448
|
+
async function runRevert(reports, providerRegistry, stateConfig, awsClients, options) {
|
|
35449
|
+
const logger = getLogger();
|
|
35450
|
+
printRevertPlan(reports);
|
|
35451
|
+
if (options.dryRun) {
|
|
35452
|
+
logger.info("--dry-run: AWS will NOT be modified. Re-run without --dry-run to apply.");
|
|
35453
|
+
return;
|
|
35454
|
+
}
|
|
35455
|
+
if (!options.yes) {
|
|
35456
|
+
const ok = await confirmPrompt(
|
|
35457
|
+
`Push cdkd state values back into AWS for the resources shown above?`
|
|
35458
|
+
);
|
|
35459
|
+
if (!ok) {
|
|
35460
|
+
logger.info("Aborted.");
|
|
35461
|
+
return;
|
|
35462
|
+
}
|
|
35463
|
+
}
|
|
35464
|
+
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
35465
|
+
const owner = `${process.env["USER"] || "unknown"}@${process.env["HOSTNAME"] || "host"}:${process.pid}`;
|
|
35466
|
+
const concurrency = Math.max(1, options.concurrency ?? 4);
|
|
35467
|
+
let totalFailed = 0;
|
|
35468
|
+
let totalSucceeded = 0;
|
|
35469
|
+
for (const report of reports) {
|
|
35470
|
+
const driftedOutcomes = report.outcomes.filter(
|
|
35471
|
+
(o) => o.kind === "drifted"
|
|
35472
|
+
);
|
|
35473
|
+
if (driftedOutcomes.length === 0) {
|
|
35474
|
+
continue;
|
|
35475
|
+
}
|
|
35476
|
+
await lockManager.acquireLock(report.stackName, report.region, owner, "drift-revert");
|
|
35477
|
+
try {
|
|
35478
|
+
const tasks = driftedOutcomes.map((outcome) => async () => {
|
|
35479
|
+
const stateResource = report.state.resources[outcome.logicalId];
|
|
35480
|
+
if (!stateResource) {
|
|
35481
|
+
totalFailed++;
|
|
35482
|
+
logger.error(
|
|
35483
|
+
` \u2717 ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): resource missing from state; skipped.`
|
|
35484
|
+
);
|
|
35485
|
+
return;
|
|
35486
|
+
}
|
|
35487
|
+
const provider = providerRegistry.getProvider(outcome.resourceType);
|
|
35488
|
+
try {
|
|
35489
|
+
await withRetry(
|
|
35490
|
+
() => provider.update(
|
|
35491
|
+
outcome.logicalId,
|
|
35492
|
+
stateResource.physicalId,
|
|
35493
|
+
outcome.resourceType,
|
|
35494
|
+
stateResource.properties ?? {},
|
|
35495
|
+
outcome.awsProperties
|
|
35496
|
+
),
|
|
35497
|
+
outcome.logicalId,
|
|
35498
|
+
{ logger: { debug: (msg) => logger.debug(msg) } }
|
|
35499
|
+
);
|
|
35500
|
+
totalSucceeded++;
|
|
35501
|
+
logger.info(
|
|
35502
|
+
` \u2713 ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): reverted.`
|
|
35503
|
+
);
|
|
35504
|
+
} catch (err) {
|
|
35505
|
+
totalFailed++;
|
|
35506
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
35507
|
+
logger.error(
|
|
35508
|
+
` \u2717 ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): ${msg}`
|
|
35509
|
+
);
|
|
35510
|
+
}
|
|
35511
|
+
});
|
|
35512
|
+
await runWithConcurrency(tasks, concurrency);
|
|
35513
|
+
} finally {
|
|
35514
|
+
await lockManager.releaseLock(report.stackName, report.region).catch((err) => {
|
|
35515
|
+
logger.warn(
|
|
35516
|
+
`Failed to release lock for ${report.stackName} (${report.region}): ` + (err instanceof Error ? err.message : String(err))
|
|
35517
|
+
);
|
|
35518
|
+
});
|
|
35519
|
+
}
|
|
35520
|
+
}
|
|
35521
|
+
logger.info(`
|
|
35522
|
+
Revert summary: ${totalSucceeded} reverted, ${totalFailed} failed.`);
|
|
35523
|
+
if (totalFailed > 0) {
|
|
35524
|
+
throw new PartialFailureError(
|
|
35525
|
+
`Revert completed with ${totalFailed} resource error(s). Re-run 'cdkd drift <stack>' to see the remaining drift, then 'cdkd drift <stack> --revert' to retry.`
|
|
35526
|
+
);
|
|
35527
|
+
}
|
|
35528
|
+
}
|
|
35529
|
+
function printAcceptPlan(reports) {
|
|
35530
|
+
for (const report of reports) {
|
|
35531
|
+
const drifted = report.outcomes.filter(
|
|
35532
|
+
(o) => o.kind === "drifted"
|
|
35533
|
+
);
|
|
35534
|
+
if (drifted.length === 0)
|
|
35535
|
+
continue;
|
|
35536
|
+
process.stdout.write(
|
|
35537
|
+
`
|
|
35538
|
+
Plan (--accept): update cdkd state for ${report.stackName} (${report.region}):
|
|
35539
|
+
`
|
|
35540
|
+
);
|
|
35541
|
+
for (const o of drifted) {
|
|
35542
|
+
process.stdout.write(` ~ ${o.logicalId} (${o.resourceType})
|
|
35543
|
+
`);
|
|
35544
|
+
for (const change of o.changes) {
|
|
35545
|
+
process.stdout.write(
|
|
35546
|
+
` ${change.path}: ${formatScalar(change.stateValue)} -> ${formatScalar(change.awsValue)}
|
|
35547
|
+
`
|
|
35548
|
+
);
|
|
35549
|
+
}
|
|
35550
|
+
}
|
|
35551
|
+
}
|
|
35552
|
+
}
|
|
35553
|
+
function printRevertPlan(reports) {
|
|
35554
|
+
for (const report of reports) {
|
|
35555
|
+
const drifted = report.outcomes.filter(
|
|
35556
|
+
(o) => o.kind === "drifted"
|
|
35557
|
+
);
|
|
35558
|
+
if (drifted.length === 0)
|
|
35559
|
+
continue;
|
|
35560
|
+
process.stdout.write(
|
|
35561
|
+
`
|
|
35562
|
+
Plan (--revert): push cdkd state values back into AWS for ${report.stackName} (${report.region}):
|
|
35563
|
+
`
|
|
35564
|
+
);
|
|
35565
|
+
for (const o of drifted) {
|
|
35566
|
+
const word = o.changes.length === 1 ? "property path" : "property paths";
|
|
35567
|
+
process.stdout.write(
|
|
35568
|
+
` \u2192 provider.update on ${o.logicalId} (${o.resourceType}): revert ${o.changes.length} ${word}
|
|
35569
|
+
`
|
|
35570
|
+
);
|
|
35571
|
+
for (const change of o.changes) {
|
|
35572
|
+
process.stdout.write(
|
|
35573
|
+
` ${change.path}: ${formatScalar(change.awsValue)} -> ${formatScalar(change.stateValue)}
|
|
35574
|
+
`
|
|
35575
|
+
);
|
|
35576
|
+
}
|
|
35577
|
+
}
|
|
35578
|
+
}
|
|
35579
|
+
}
|
|
35580
|
+
async function runWithConcurrency(tasks, concurrency) {
|
|
35581
|
+
const queue = [...tasks];
|
|
35582
|
+
const workers = [];
|
|
35583
|
+
for (let i = 0; i < Math.min(concurrency, queue.length); i++) {
|
|
35584
|
+
workers.push(
|
|
35585
|
+
(async () => {
|
|
35586
|
+
while (queue.length > 0) {
|
|
35587
|
+
const task = queue.shift();
|
|
35588
|
+
if (!task)
|
|
35589
|
+
break;
|
|
35590
|
+
await task();
|
|
35591
|
+
}
|
|
35592
|
+
})()
|
|
35593
|
+
);
|
|
35594
|
+
}
|
|
35595
|
+
await Promise.all(workers);
|
|
35596
|
+
}
|
|
35597
|
+
async function confirmPrompt(prompt) {
|
|
35598
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
35599
|
+
try {
|
|
35600
|
+
const ans = await rl.question(`${prompt} [y/N] `);
|
|
35601
|
+
return /^y(es)?$/i.test(ans.trim());
|
|
35602
|
+
} finally {
|
|
35603
|
+
rl.close();
|
|
35604
|
+
}
|
|
35605
|
+
}
|
|
34298
35606
|
function writeJsonReport(reports) {
|
|
34299
35607
|
const payload = reports.map((r) => {
|
|
34300
35608
|
const drifted = r.outcomes.filter((o) => o.kind === "drifted").map((o) => ({ logicalId: o.logicalId, type: o.resourceType, changes: o.changes }));
|
|
@@ -34371,8 +35679,25 @@ function stackRegionOption() {
|
|
|
34371
35679
|
}
|
|
34372
35680
|
function createDriftCommand() {
|
|
34373
35681
|
const cmd = new Command6("drift").description(
|
|
34374
|
-
"Detect drift between cdkd state and AWS reality. Exits 0 when no drift, 1 when drift is detected."
|
|
34375
|
-
).argument("[stacks...]", "Stack name(s) to check (physical CloudFormation names)").option("--all", "Check every stack in the state bucket", false).option("--json", "Output as JSON", false).
|
|
35682
|
+
"Detect drift between cdkd state and AWS reality. Exits 0 when no drift, 1 when drift is detected. Pass --accept to update cdkd state from AWS, or --revert to push cdkd state values back into AWS."
|
|
35683
|
+
).argument("[stacks...]", "Stack name(s) to check (physical CloudFormation names)").option("--all", "Check every stack in the state bucket", false).option("--json", "Output as JSON", false).option(
|
|
35684
|
+
"--accept",
|
|
35685
|
+
"Update cdkd state with the AWS-current values for every drifted property (state \u2190 AWS). Mutually exclusive with --revert.",
|
|
35686
|
+
false
|
|
35687
|
+
).option(
|
|
35688
|
+
"--revert",
|
|
35689
|
+
"Push cdkd state values back into AWS via provider.update for every drifted resource (AWS \u2190 state). Mutually exclusive with --accept.",
|
|
35690
|
+
false
|
|
35691
|
+
).option(
|
|
35692
|
+
"--dry-run",
|
|
35693
|
+
"Print the planned mutations without acquiring a lock or hitting AWS / S3. Honored by --accept and --revert.",
|
|
35694
|
+
false
|
|
35695
|
+
).option(
|
|
35696
|
+
"--concurrency <number>",
|
|
35697
|
+
"Maximum concurrent provider.update calls during --revert",
|
|
35698
|
+
(value) => parseInt(value, 10),
|
|
35699
|
+
4
|
|
35700
|
+
).addOption(stackRegionOption()).action(withErrorHandling(driftCommand));
|
|
34376
35701
|
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
34377
35702
|
cmd.addOption(deprecatedRegionOption);
|
|
34378
35703
|
return cmd;
|
|
@@ -34383,7 +35708,7 @@ import { Command as Command7 } from "commander";
|
|
|
34383
35708
|
init_aws_clients();
|
|
34384
35709
|
|
|
34385
35710
|
// src/cli/commands/destroy-runner.ts
|
|
34386
|
-
import * as
|
|
35711
|
+
import * as readline2 from "node:readline/promises";
|
|
34387
35712
|
init_aws_clients();
|
|
34388
35713
|
async function runDestroyForStack(stackName, state, ctx) {
|
|
34389
35714
|
const logger = getLogger();
|
|
@@ -34409,7 +35734,7 @@ Resources to be deleted (${resourceCount}):`);
|
|
|
34409
35734
|
logger.info(` - ${logicalId} (${resource.resourceType})`);
|
|
34410
35735
|
}
|
|
34411
35736
|
if (!ctx.skipConfirmation) {
|
|
34412
|
-
const rl =
|
|
35737
|
+
const rl = readline2.createInterface({
|
|
34413
35738
|
input: process.stdin,
|
|
34414
35739
|
output: process.stdout
|
|
34415
35740
|
});
|
|
@@ -34820,7 +36145,7 @@ function createDestroyCommand() {
|
|
|
34820
36145
|
}
|
|
34821
36146
|
|
|
34822
36147
|
// src/cli/commands/orphan.ts
|
|
34823
|
-
import * as
|
|
36148
|
+
import * as readline3 from "node:readline/promises";
|
|
34824
36149
|
import { Command as Command8 } from "commander";
|
|
34825
36150
|
init_aws_clients();
|
|
34826
36151
|
|
|
@@ -35353,7 +36678,7 @@ Re-run with --force to fall back to cached attribute values from state, or fix t
|
|
|
35353
36678
|
return;
|
|
35354
36679
|
}
|
|
35355
36680
|
if (!options.yes && !options.force) {
|
|
35356
|
-
const ok = await
|
|
36681
|
+
const ok = await confirmPrompt2(
|
|
35357
36682
|
`Orphan ${orphanLogicalIds.length} resource(s) from cdkd state for ${stackInfo.stackName} (${targetRegion})? AWS resources will NOT be deleted.`
|
|
35358
36683
|
);
|
|
35359
36684
|
if (!ok) {
|
|
@@ -35492,8 +36817,8 @@ function stringifyForAudit(value) {
|
|
|
35492
36817
|
return JSON.stringify(value);
|
|
35493
36818
|
return JSON.stringify(value);
|
|
35494
36819
|
}
|
|
35495
|
-
async function
|
|
35496
|
-
const rl =
|
|
36820
|
+
async function confirmPrompt2(prompt) {
|
|
36821
|
+
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
35497
36822
|
try {
|
|
35498
36823
|
const ans = await rl.question(`${prompt} [y/N] `);
|
|
35499
36824
|
return /^y(es)?$/i.test(ans.trim());
|
|
@@ -35768,7 +37093,7 @@ function createForceUnlockCommand() {
|
|
|
35768
37093
|
}
|
|
35769
37094
|
|
|
35770
37095
|
// src/cli/commands/state.ts
|
|
35771
|
-
import * as
|
|
37096
|
+
import * as readline5 from "node:readline/promises";
|
|
35772
37097
|
import { Command as Command12, Option as Option6 } from "commander";
|
|
35773
37098
|
import {
|
|
35774
37099
|
GetBucketLocationCommand as GetBucketLocationCommand2,
|
|
@@ -35778,7 +37103,7 @@ import {
|
|
|
35778
37103
|
init_aws_clients();
|
|
35779
37104
|
|
|
35780
37105
|
// src/cli/commands/state-migrate.ts
|
|
35781
|
-
import * as
|
|
37106
|
+
import * as readline4 from "node:readline/promises";
|
|
35782
37107
|
import { Command as Command11 } from "commander";
|
|
35783
37108
|
import {
|
|
35784
37109
|
CopyObjectCommand,
|
|
@@ -35848,7 +37173,7 @@ async function stateMigrateCommand(options) {
|
|
|
35848
37173
|
}
|
|
35849
37174
|
if (!options.yes) {
|
|
35850
37175
|
const action = options.removeLegacy ? "and DELETE the source bucket" : "(source bucket will be kept)";
|
|
35851
|
-
const ok = await
|
|
37176
|
+
const ok = await confirmPrompt3(
|
|
35852
37177
|
`Copy ${sourceObjects.length} object(s) from ${legacyBucket} -> ${newBucket} ${action}?`
|
|
35853
37178
|
);
|
|
35854
37179
|
if (!ok) {
|
|
@@ -36053,8 +37378,8 @@ async function emptyBucketAllVersions(s3, bucket) {
|
|
|
36053
37378
|
versionIdMarker = resp.NextVersionIdMarker;
|
|
36054
37379
|
} while (keyMarker || versionIdMarker);
|
|
36055
37380
|
}
|
|
36056
|
-
async function
|
|
36057
|
-
const rl =
|
|
37381
|
+
async function confirmPrompt3(prompt) {
|
|
37382
|
+
const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
|
|
36058
37383
|
try {
|
|
36059
37384
|
const ans = await rl.question(`${prompt} [y/N] `);
|
|
36060
37385
|
return /^y(es)?$/i.test(ans.trim());
|
|
@@ -36462,7 +37787,7 @@ Use 'cdkd destroy ${stackName}' if you want to delete the actual resources.
|
|
|
36462
37787
|
|
|
36463
37788
|
`
|
|
36464
37789
|
);
|
|
36465
|
-
const rl =
|
|
37790
|
+
const rl = readline5.createInterface({
|
|
36466
37791
|
input: process.stdin,
|
|
36467
37792
|
output: process.stdout
|
|
36468
37793
|
});
|
|
@@ -36553,7 +37878,7 @@ WARNING: This destroys ${stackNames.length} stack(s) and removes their state rec
|
|
|
36553
37878
|
`);
|
|
36554
37879
|
}
|
|
36555
37880
|
process.stdout.write("\n");
|
|
36556
|
-
const rl =
|
|
37881
|
+
const rl = readline5.createInterface({
|
|
36557
37882
|
input: process.stdin,
|
|
36558
37883
|
output: process.stdout
|
|
36559
37884
|
});
|
|
@@ -36795,12 +38120,12 @@ function createStateCommand() {
|
|
|
36795
38120
|
|
|
36796
38121
|
// src/cli/commands/import.ts
|
|
36797
38122
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
36798
|
-
import * as
|
|
38123
|
+
import * as readline7 from "node:readline/promises";
|
|
36799
38124
|
import { Command as Command13 } from "commander";
|
|
36800
38125
|
init_aws_clients();
|
|
36801
38126
|
|
|
36802
38127
|
// src/cli/commands/retire-cfn-stack.ts
|
|
36803
|
-
import * as
|
|
38128
|
+
import * as readline6 from "node:readline/promises";
|
|
36804
38129
|
import {
|
|
36805
38130
|
DescribeStacksCommand,
|
|
36806
38131
|
DescribeStackResourcesCommand,
|
|
@@ -36845,7 +38170,7 @@ async function retireCloudFormationStack(options) {
|
|
|
36845
38170
|
}
|
|
36846
38171
|
const { body: newBody, modified } = injectRetainPolicies(tpl.TemplateBody, cfnStackName);
|
|
36847
38172
|
if (!yes) {
|
|
36848
|
-
const ok = await
|
|
38173
|
+
const ok = await confirmPrompt4(
|
|
36849
38174
|
`Set DeletionPolicy=Retain and UpdateReplacePolicy=Retain on every resource in CloudFormation stack '${cfnStackName}', then delete the stack? AWS resources will NOT be deleted (cdkd state has been written).`
|
|
36850
38175
|
);
|
|
36851
38176
|
if (!ok) {
|
|
@@ -37005,8 +38330,8 @@ async function getCloudFormationResourceMapping(cfnStackName, cfnClient) {
|
|
|
37005
38330
|
}
|
|
37006
38331
|
return map;
|
|
37007
38332
|
}
|
|
37008
|
-
async function
|
|
37009
|
-
const rl =
|
|
38333
|
+
async function confirmPrompt4(prompt) {
|
|
38334
|
+
const rl = readline6.createInterface({ input: process.stdin, output: process.stdout });
|
|
37010
38335
|
try {
|
|
37011
38336
|
const ans = await rl.question(`${prompt} [y/N] `);
|
|
37012
38337
|
return /^y(es)?$/i.test(ans.trim());
|
|
@@ -37205,7 +38530,7 @@ async function importCommand(stackArg, options) {
|
|
|
37205
38530
|
const preservedCount = selectiveMode && existingState ? Object.keys(existingState.resources).filter((id) => !overrides.has(id)).length : 0;
|
|
37206
38531
|
const totalAfter = importedCount + preservedCount;
|
|
37207
38532
|
const breakdown = preservedCount > 0 ? ` (${importedCount} new/overwritten + ${preservedCount} preserved)` : "";
|
|
37208
|
-
const ok = await
|
|
38533
|
+
const ok = await confirmPrompt5(
|
|
37209
38534
|
`Write state for ${stackInfo.stackName} (${targetRegion}) with ${totalAfter} resource(s)${breakdown}?`
|
|
37210
38535
|
);
|
|
37211
38536
|
if (!ok) {
|
|
@@ -37466,8 +38791,8 @@ function formatOutcome(outcome) {
|
|
|
37466
38791
|
return "\u2717";
|
|
37467
38792
|
}
|
|
37468
38793
|
}
|
|
37469
|
-
async function
|
|
37470
|
-
const rl =
|
|
38794
|
+
async function confirmPrompt5(prompt) {
|
|
38795
|
+
const rl = readline7.createInterface({ input: process.stdin, output: process.stdout });
|
|
37471
38796
|
try {
|
|
37472
38797
|
const ans = await rl.question(`${prompt} [y/N] `);
|
|
37473
38798
|
return /^y(es)?$/i.test(ans.trim());
|
|
@@ -37544,7 +38869,7 @@ function reorderArgs(argv) {
|
|
|
37544
38869
|
}
|
|
37545
38870
|
async function main() {
|
|
37546
38871
|
const program = new Command14();
|
|
37547
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
38872
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.39.0");
|
|
37548
38873
|
program.addCommand(createBootstrapCommand());
|
|
37549
38874
|
program.addCommand(createSynthCommand());
|
|
37550
38875
|
program.addCommand(createListCommand());
|