@go-to-k/cdkd 0.39.0 → 0.41.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 +2517 -30
- package/dist/cli.js.map +3 -3
- package/dist/go-to-k-cdkd-0.41.0.tgz +0 -0
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.39.0.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -9747,6 +9747,42 @@ var IAMInstanceProfileProvider = class {
|
|
|
9747
9747
|
);
|
|
9748
9748
|
}
|
|
9749
9749
|
}
|
|
9750
|
+
/**
|
|
9751
|
+
* Read the AWS-current IAM instance profile configuration in CFn-property
|
|
9752
|
+
* shape.
|
|
9753
|
+
*
|
|
9754
|
+
* Issues a single `GetInstanceProfile` and surfaces the keys `create()`
|
|
9755
|
+
* accepts (`InstanceProfileName`, `Path`, `Roles`). The Roles list maps
|
|
9756
|
+
* the inline `Role[]` (each carrying `{RoleName, Arn, ...}`) back to the
|
|
9757
|
+
* `string[]` of role names that CFn / cdkd state holds.
|
|
9758
|
+
*
|
|
9759
|
+
* Returns `undefined` when the profile is gone (`NoSuchEntityException`).
|
|
9760
|
+
*/
|
|
9761
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
9762
|
+
let profile;
|
|
9763
|
+
try {
|
|
9764
|
+
const resp = await this.iamClient.send(
|
|
9765
|
+
new GetInstanceProfileCommand({ InstanceProfileName: physicalId })
|
|
9766
|
+
);
|
|
9767
|
+
profile = resp.InstanceProfile;
|
|
9768
|
+
} catch (err) {
|
|
9769
|
+
if (err instanceof NoSuchEntityException3)
|
|
9770
|
+
return void 0;
|
|
9771
|
+
throw err;
|
|
9772
|
+
}
|
|
9773
|
+
if (!profile)
|
|
9774
|
+
return void 0;
|
|
9775
|
+
const result = {};
|
|
9776
|
+
if (profile.InstanceProfileName !== void 0) {
|
|
9777
|
+
result["InstanceProfileName"] = profile.InstanceProfileName;
|
|
9778
|
+
}
|
|
9779
|
+
if (profile.Path !== void 0)
|
|
9780
|
+
result["Path"] = profile.Path;
|
|
9781
|
+
const roleNames = (profile.Roles ?? []).map((r) => r.RoleName).filter((n) => !!n);
|
|
9782
|
+
if (roleNames.length > 0)
|
|
9783
|
+
result["Roles"] = roleNames;
|
|
9784
|
+
return result;
|
|
9785
|
+
}
|
|
9750
9786
|
/**
|
|
9751
9787
|
* Adopt an existing IAM instance profile into cdkd state.
|
|
9752
9788
|
*
|
|
@@ -10799,6 +10835,123 @@ var IAMUserGroupProvider = class {
|
|
|
10799
10835
|
);
|
|
10800
10836
|
}
|
|
10801
10837
|
}
|
|
10838
|
+
// ─── readCurrentState dispatch ───────────────────────────────────
|
|
10839
|
+
/**
|
|
10840
|
+
* Read the AWS-current configuration for an IAM user / group /
|
|
10841
|
+
* UserToGroupAddition in CFn-property shape.
|
|
10842
|
+
*
|
|
10843
|
+
* - **AWS::IAM::User**: `GetUser` for `UserName`, `Path`,
|
|
10844
|
+
* `PermissionsBoundary` (re-shaped from `PermissionsBoundary.Arn`);
|
|
10845
|
+
* `ListAttachedUserPolicies` for `ManagedPolicyArns`;
|
|
10846
|
+
* `ListGroupsForUser` for `Groups`. `Tags`, `LoginProfile`, and
|
|
10847
|
+
* `Policies` (inline policy bodies) are intentionally omitted —
|
|
10848
|
+
* same shape decisions as `iam-role-provider` (LoginProfile contains a
|
|
10849
|
+
* one-time password and inline policy bodies cost N extra round-trips
|
|
10850
|
+
* that are out of scope for v1).
|
|
10851
|
+
* - **AWS::IAM::Group**: `GetGroup` for `GroupName`, `Path`;
|
|
10852
|
+
* `ListAttachedGroupPolicies` for `ManagedPolicyArns`. `Policies`
|
|
10853
|
+
* (inline policy bodies) is omitted for the same reason as User /
|
|
10854
|
+
* Role.
|
|
10855
|
+
* - **AWS::IAM::UserToGroupAddition**: SKIPPED — returns `undefined`
|
|
10856
|
+
* because the resource is metadata-only (group-membership attachments
|
|
10857
|
+
* written via `AddUserToGroup`). A meaningful drift check would
|
|
10858
|
+
* require both the `GroupName` and the source-of-truth `Users` list
|
|
10859
|
+
* from state, neither of which `readCurrentState` receives. The
|
|
10860
|
+
* drift comparator falls back to "drift unknown" and the user can
|
|
10861
|
+
* inspect the membership manually.
|
|
10862
|
+
*
|
|
10863
|
+
* Returns `undefined` when the user / group is gone
|
|
10864
|
+
* (`NoSuchEntityException`).
|
|
10865
|
+
*/
|
|
10866
|
+
async readCurrentState(physicalId, logicalId, resourceType) {
|
|
10867
|
+
switch (resourceType) {
|
|
10868
|
+
case "AWS::IAM::User":
|
|
10869
|
+
return this.readUserCurrentState(physicalId);
|
|
10870
|
+
case "AWS::IAM::Group":
|
|
10871
|
+
return this.readGroupCurrentState(physicalId);
|
|
10872
|
+
case "AWS::IAM::UserToGroupAddition":
|
|
10873
|
+
return void 0;
|
|
10874
|
+
default:
|
|
10875
|
+
this.logger.debug(
|
|
10876
|
+
`readCurrentState: unsupported resource type ${resourceType} for ${logicalId}`
|
|
10877
|
+
);
|
|
10878
|
+
return void 0;
|
|
10879
|
+
}
|
|
10880
|
+
}
|
|
10881
|
+
async readUserCurrentState(physicalId) {
|
|
10882
|
+
let user;
|
|
10883
|
+
try {
|
|
10884
|
+
const resp = await this.iamClient.send(new GetUserCommand({ UserName: physicalId }));
|
|
10885
|
+
user = resp.User;
|
|
10886
|
+
} catch (err) {
|
|
10887
|
+
if (err instanceof NoSuchEntityException4)
|
|
10888
|
+
return void 0;
|
|
10889
|
+
throw err;
|
|
10890
|
+
}
|
|
10891
|
+
if (!user)
|
|
10892
|
+
return void 0;
|
|
10893
|
+
const result = {};
|
|
10894
|
+
if (user.UserName !== void 0)
|
|
10895
|
+
result["UserName"] = user.UserName;
|
|
10896
|
+
if (user.Path !== void 0)
|
|
10897
|
+
result["Path"] = user.Path;
|
|
10898
|
+
if (user.PermissionsBoundary?.PermissionsBoundaryArn !== void 0) {
|
|
10899
|
+
result["PermissionsBoundary"] = user.PermissionsBoundary.PermissionsBoundaryArn;
|
|
10900
|
+
}
|
|
10901
|
+
try {
|
|
10902
|
+
const attached = await this.iamClient.send(
|
|
10903
|
+
new ListAttachedUserPoliciesCommand({ UserName: physicalId })
|
|
10904
|
+
);
|
|
10905
|
+
const arns = (attached.AttachedPolicies ?? []).map((p) => p.PolicyArn).filter((arn) => !!arn);
|
|
10906
|
+
if (arns.length > 0)
|
|
10907
|
+
result["ManagedPolicyArns"] = arns;
|
|
10908
|
+
} catch (err) {
|
|
10909
|
+
if (!(err instanceof NoSuchEntityException4))
|
|
10910
|
+
throw err;
|
|
10911
|
+
}
|
|
10912
|
+
try {
|
|
10913
|
+
const groups = await this.iamClient.send(
|
|
10914
|
+
new ListGroupsForUserCommand({ UserName: physicalId })
|
|
10915
|
+
);
|
|
10916
|
+
const names = (groups.Groups ?? []).map((g) => g.GroupName).filter((n) => !!n);
|
|
10917
|
+
if (names.length > 0)
|
|
10918
|
+
result["Groups"] = names;
|
|
10919
|
+
} catch (err) {
|
|
10920
|
+
if (!(err instanceof NoSuchEntityException4))
|
|
10921
|
+
throw err;
|
|
10922
|
+
}
|
|
10923
|
+
return result;
|
|
10924
|
+
}
|
|
10925
|
+
async readGroupCurrentState(physicalId) {
|
|
10926
|
+
let group;
|
|
10927
|
+
try {
|
|
10928
|
+
const resp = await this.iamClient.send(new GetGroupCommand({ GroupName: physicalId }));
|
|
10929
|
+
group = resp.Group;
|
|
10930
|
+
} catch (err) {
|
|
10931
|
+
if (err instanceof NoSuchEntityException4)
|
|
10932
|
+
return void 0;
|
|
10933
|
+
throw err;
|
|
10934
|
+
}
|
|
10935
|
+
if (!group)
|
|
10936
|
+
return void 0;
|
|
10937
|
+
const result = {};
|
|
10938
|
+
if (group.GroupName !== void 0)
|
|
10939
|
+
result["GroupName"] = group.GroupName;
|
|
10940
|
+
if (group.Path !== void 0)
|
|
10941
|
+
result["Path"] = group.Path;
|
|
10942
|
+
try {
|
|
10943
|
+
const attached = await this.iamClient.send(
|
|
10944
|
+
new ListAttachedGroupPoliciesCommand({ GroupName: physicalId })
|
|
10945
|
+
);
|
|
10946
|
+
const arns = (attached.AttachedPolicies ?? []).map((p) => p.PolicyArn).filter((arn) => !!arn);
|
|
10947
|
+
if (arns.length > 0)
|
|
10948
|
+
result["ManagedPolicyArns"] = arns;
|
|
10949
|
+
} catch (err) {
|
|
10950
|
+
if (!(err instanceof NoSuchEntityException4))
|
|
10951
|
+
throw err;
|
|
10952
|
+
}
|
|
10953
|
+
return result;
|
|
10954
|
+
}
|
|
10802
10955
|
// ─── Import dispatch ──────────────────────────────────────────────
|
|
10803
10956
|
/**
|
|
10804
10957
|
* Adopt an existing IAM user / group / user-to-group addition into cdkd state.
|
|
@@ -12002,6 +12155,7 @@ var S3BucketProvider = class {
|
|
|
12002
12155
|
import {
|
|
12003
12156
|
PutBucketPolicyCommand as PutBucketPolicyCommand2,
|
|
12004
12157
|
DeleteBucketPolicyCommand,
|
|
12158
|
+
GetBucketPolicyCommand,
|
|
12005
12159
|
NoSuchBucket as NoSuchBucket2
|
|
12006
12160
|
} from "@aws-sdk/client-s3";
|
|
12007
12161
|
init_aws_clients();
|
|
@@ -12159,6 +12313,43 @@ var S3BucketPolicyProvider = class {
|
|
|
12159
12313
|
);
|
|
12160
12314
|
}
|
|
12161
12315
|
}
|
|
12316
|
+
/**
|
|
12317
|
+
* Read the AWS-current S3 bucket policy in CFn-property shape.
|
|
12318
|
+
*
|
|
12319
|
+
* Issues `GetBucketPolicy` against the bucket (physicalId === bucket
|
|
12320
|
+
* name) and surfaces:
|
|
12321
|
+
* - `Bucket` — derived directly from `physicalId`.
|
|
12322
|
+
* - `PolicyDocument` — JSON-parsed back to the object form cdkd state
|
|
12323
|
+
* typically holds.
|
|
12324
|
+
*
|
|
12325
|
+
* Returns `undefined` when the bucket is gone (`NoSuchBucket`) or when
|
|
12326
|
+
* no policy is currently attached (`NoSuchBucketPolicy`).
|
|
12327
|
+
*/
|
|
12328
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
12329
|
+
let policyJson;
|
|
12330
|
+
try {
|
|
12331
|
+
const resp = await this.s3Client.send(new GetBucketPolicyCommand({ Bucket: physicalId }));
|
|
12332
|
+
policyJson = resp.Policy;
|
|
12333
|
+
} catch (err) {
|
|
12334
|
+
if (err instanceof NoSuchBucket2)
|
|
12335
|
+
return void 0;
|
|
12336
|
+
const e = err;
|
|
12337
|
+
if (e.name === "NoSuchBucketPolicy")
|
|
12338
|
+
return void 0;
|
|
12339
|
+
throw err;
|
|
12340
|
+
}
|
|
12341
|
+
if (!policyJson)
|
|
12342
|
+
return void 0;
|
|
12343
|
+
const result = {
|
|
12344
|
+
Bucket: physicalId
|
|
12345
|
+
};
|
|
12346
|
+
try {
|
|
12347
|
+
result["PolicyDocument"] = JSON.parse(policyJson);
|
|
12348
|
+
} catch {
|
|
12349
|
+
result["PolicyDocument"] = policyJson;
|
|
12350
|
+
}
|
|
12351
|
+
return result;
|
|
12352
|
+
}
|
|
12162
12353
|
/**
|
|
12163
12354
|
* Adopt an existing S3 bucket policy into cdkd state.
|
|
12164
12355
|
*
|
|
@@ -12582,7 +12773,10 @@ var SQSQueueProvider = class {
|
|
|
12582
12773
|
};
|
|
12583
12774
|
|
|
12584
12775
|
// src/provisioning/providers/sqs-queue-policy-provider.ts
|
|
12585
|
-
import {
|
|
12776
|
+
import {
|
|
12777
|
+
SetQueueAttributesCommand as SetQueueAttributesCommand2,
|
|
12778
|
+
GetQueueAttributesCommand as GetQueueAttributesCommand2
|
|
12779
|
+
} from "@aws-sdk/client-sqs";
|
|
12586
12780
|
init_aws_clients();
|
|
12587
12781
|
var SQSQueuePolicyProvider = class {
|
|
12588
12782
|
sqsClient;
|
|
@@ -12735,6 +12929,52 @@ var SQSQueuePolicyProvider = class {
|
|
|
12735
12929
|
);
|
|
12736
12930
|
}
|
|
12737
12931
|
}
|
|
12932
|
+
/**
|
|
12933
|
+
* Read the AWS-current SQS queue policy in CFn-property shape.
|
|
12934
|
+
*
|
|
12935
|
+
* The provider's `create()` records `physicalId` as the first queue URL
|
|
12936
|
+
* in the `Queues` array. Drift here surfaces:
|
|
12937
|
+
* - `Queues` — single-element array containing `physicalId`. The full
|
|
12938
|
+
* state list of queues isn't recoverable from AWS (no reverse index)
|
|
12939
|
+
* and the comparator only descends into keys present in state, so a
|
|
12940
|
+
* state with multiple queues will still surface drift on
|
|
12941
|
+
* `PolicyDocument` for the first queue (the most common drift case).
|
|
12942
|
+
* - `PolicyDocument` — fetched via `GetQueueAttributes` for
|
|
12943
|
+
* `Policy`, JSON-parsed back to the object form cdkd state holds.
|
|
12944
|
+
*
|
|
12945
|
+
* Returns `undefined` when the queue is gone (`QueueDoesNotExist`) or
|
|
12946
|
+
* when no policy is currently attached (the `Policy` attribute is
|
|
12947
|
+
* absent / empty).
|
|
12948
|
+
*/
|
|
12949
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
12950
|
+
let policyAttr;
|
|
12951
|
+
try {
|
|
12952
|
+
const resp = await this.sqsClient.send(
|
|
12953
|
+
new GetQueueAttributesCommand2({
|
|
12954
|
+
QueueUrl: physicalId,
|
|
12955
|
+
AttributeNames: ["Policy"]
|
|
12956
|
+
})
|
|
12957
|
+
);
|
|
12958
|
+
policyAttr = resp.Attributes?.["Policy"];
|
|
12959
|
+
} catch (err) {
|
|
12960
|
+
const e = err;
|
|
12961
|
+
if (e.name === "QueueDoesNotExist" || typeof e.message === "string" && e.message.includes("does not exist")) {
|
|
12962
|
+
return void 0;
|
|
12963
|
+
}
|
|
12964
|
+
throw err;
|
|
12965
|
+
}
|
|
12966
|
+
if (!policyAttr)
|
|
12967
|
+
return void 0;
|
|
12968
|
+
const result = {
|
|
12969
|
+
Queues: [physicalId]
|
|
12970
|
+
};
|
|
12971
|
+
try {
|
|
12972
|
+
result["PolicyDocument"] = JSON.parse(policyAttr);
|
|
12973
|
+
} catch {
|
|
12974
|
+
result["PolicyDocument"] = policyAttr;
|
|
12975
|
+
}
|
|
12976
|
+
return result;
|
|
12977
|
+
}
|
|
12738
12978
|
/**
|
|
12739
12979
|
* Adopt an existing SQS queue policy into cdkd state.
|
|
12740
12980
|
*
|
|
@@ -13207,6 +13447,7 @@ var SNSTopicProvider = class {
|
|
|
13207
13447
|
import {
|
|
13208
13448
|
SubscribeCommand,
|
|
13209
13449
|
UnsubscribeCommand,
|
|
13450
|
+
GetSubscriptionAttributesCommand,
|
|
13210
13451
|
NotFoundException as NotFoundException2
|
|
13211
13452
|
} from "@aws-sdk/client-sns";
|
|
13212
13453
|
init_aws_clients();
|
|
@@ -13338,6 +13579,52 @@ var SNSSubscriptionProvider = class {
|
|
|
13338
13579
|
);
|
|
13339
13580
|
}
|
|
13340
13581
|
}
|
|
13582
|
+
/**
|
|
13583
|
+
* Read the AWS-current SNS Subscription configuration in CFn-property shape.
|
|
13584
|
+
*
|
|
13585
|
+
* Issues `GetSubscriptionAttributes`. AWS returns ALL attribute values
|
|
13586
|
+
* as strings; we type-coerce `RawMessageDelivery` to a boolean and
|
|
13587
|
+
* JSON-parse `FilterPolicy` so the comparator matches cdkd state's
|
|
13588
|
+
* already-typed values. `TopicArn`, `Protocol`, `Endpoint` pass through
|
|
13589
|
+
* as strings.
|
|
13590
|
+
*
|
|
13591
|
+
* Returns `undefined` when the subscription is gone (`NotFoundException`),
|
|
13592
|
+
* including the special "PendingConfirmation" case where the
|
|
13593
|
+
* `SubscriptionArn` has not yet been confirmed and `Attributes` is null.
|
|
13594
|
+
*/
|
|
13595
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
13596
|
+
let attributes;
|
|
13597
|
+
try {
|
|
13598
|
+
const resp = await this.snsClient.send(
|
|
13599
|
+
new GetSubscriptionAttributesCommand({ SubscriptionArn: physicalId })
|
|
13600
|
+
);
|
|
13601
|
+
attributes = resp.Attributes;
|
|
13602
|
+
} catch (err) {
|
|
13603
|
+
if (err instanceof NotFoundException2)
|
|
13604
|
+
return void 0;
|
|
13605
|
+
throw err;
|
|
13606
|
+
}
|
|
13607
|
+
if (!attributes)
|
|
13608
|
+
return void 0;
|
|
13609
|
+
const result = {};
|
|
13610
|
+
if (attributes["TopicArn"] !== void 0)
|
|
13611
|
+
result["TopicArn"] = attributes["TopicArn"];
|
|
13612
|
+
if (attributes["Protocol"] !== void 0)
|
|
13613
|
+
result["Protocol"] = attributes["Protocol"];
|
|
13614
|
+
if (attributes["Endpoint"] !== void 0)
|
|
13615
|
+
result["Endpoint"] = attributes["Endpoint"];
|
|
13616
|
+
if (attributes["RawMessageDelivery"] !== void 0) {
|
|
13617
|
+
result["RawMessageDelivery"] = attributes["RawMessageDelivery"] === "true";
|
|
13618
|
+
}
|
|
13619
|
+
if (attributes["FilterPolicy"]) {
|
|
13620
|
+
try {
|
|
13621
|
+
result["FilterPolicy"] = JSON.parse(attributes["FilterPolicy"]);
|
|
13622
|
+
} catch {
|
|
13623
|
+
result["FilterPolicy"] = attributes["FilterPolicy"];
|
|
13624
|
+
}
|
|
13625
|
+
}
|
|
13626
|
+
return result;
|
|
13627
|
+
}
|
|
13341
13628
|
/**
|
|
13342
13629
|
* Adopt an existing SNS subscription into cdkd state.
|
|
13343
13630
|
*
|
|
@@ -13360,7 +13647,7 @@ var SNSSubscriptionProvider = class {
|
|
|
13360
13647
|
};
|
|
13361
13648
|
|
|
13362
13649
|
// src/provisioning/providers/sns-topic-policy-provider.ts
|
|
13363
|
-
import { SetTopicAttributesCommand as SetTopicAttributesCommand2 } from "@aws-sdk/client-sns";
|
|
13650
|
+
import { SetTopicAttributesCommand as SetTopicAttributesCommand2, GetTopicAttributesCommand as GetTopicAttributesCommand2 } from "@aws-sdk/client-sns";
|
|
13364
13651
|
init_aws_clients();
|
|
13365
13652
|
var SNSTopicPolicyProvider = class {
|
|
13366
13653
|
logger = getLogger().child("SNSTopicPolicyProvider");
|
|
@@ -13496,6 +13783,57 @@ var SNSTopicPolicyProvider = class {
|
|
|
13496
13783
|
}
|
|
13497
13784
|
this.logger.debug(`Successfully deleted SNS topic policy ${logicalId}`);
|
|
13498
13785
|
}
|
|
13786
|
+
/**
|
|
13787
|
+
* Read the AWS-current SNS topic policy in CFn-property shape.
|
|
13788
|
+
*
|
|
13789
|
+
* The provider's `create()` builds `physicalId` as a comma-joined list
|
|
13790
|
+
* of topic ARNs. We:
|
|
13791
|
+
* 1. Split the physical id back into the list of topic ARNs and surface
|
|
13792
|
+
* them as `Topics` (matching `create()` shape).
|
|
13793
|
+
* 2. Fetch `GetTopicAttributes` on the FIRST topic to retrieve the
|
|
13794
|
+
* `Policy` attribute and surface it as `PolicyDocument` (JSON-parsed
|
|
13795
|
+
* to match the object form cdkd state holds).
|
|
13796
|
+
*
|
|
13797
|
+
* Single-topic fetch is intentional: cdkd applies the same policy to
|
|
13798
|
+
* every topic in `Topics`, so the body is the same on each. A future
|
|
13799
|
+
* enhancement could verify per-topic that the policy actually matches
|
|
13800
|
+
* (catches manual divergence between multiple targets), but the bulk of
|
|
13801
|
+
* drift cases involve a single topic and the body content is what users
|
|
13802
|
+
* actually care about.
|
|
13803
|
+
*
|
|
13804
|
+
* Returns `undefined` when no topics are listed in the physical id, or
|
|
13805
|
+
* when the first listed topic is gone (`NotFoundException`).
|
|
13806
|
+
*/
|
|
13807
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
13808
|
+
const topics = physicalId.split(",").filter((t) => t.length > 0);
|
|
13809
|
+
if (topics.length === 0)
|
|
13810
|
+
return void 0;
|
|
13811
|
+
const firstTopic = topics[0];
|
|
13812
|
+
let policyAttr;
|
|
13813
|
+
try {
|
|
13814
|
+
const resp = await getAwsClients().sns.send(
|
|
13815
|
+
new GetTopicAttributesCommand2({ TopicArn: firstTopic })
|
|
13816
|
+
);
|
|
13817
|
+
policyAttr = resp.Attributes?.["Policy"];
|
|
13818
|
+
} catch (err) {
|
|
13819
|
+
const e = err;
|
|
13820
|
+
if (e.name === "NotFoundException" || e.name === "NotFound" || typeof e.message === "string" && e.message.includes("does not exist")) {
|
|
13821
|
+
return void 0;
|
|
13822
|
+
}
|
|
13823
|
+
throw err;
|
|
13824
|
+
}
|
|
13825
|
+
const result = {
|
|
13826
|
+
Topics: topics
|
|
13827
|
+
};
|
|
13828
|
+
if (policyAttr) {
|
|
13829
|
+
try {
|
|
13830
|
+
result["PolicyDocument"] = JSON.parse(policyAttr);
|
|
13831
|
+
} catch {
|
|
13832
|
+
result["PolicyDocument"] = policyAttr;
|
|
13833
|
+
}
|
|
13834
|
+
}
|
|
13835
|
+
return result;
|
|
13836
|
+
}
|
|
13499
13837
|
/**
|
|
13500
13838
|
* Adopt an existing SNS topic policy into cdkd state.
|
|
13501
13839
|
*
|
|
@@ -14746,6 +15084,66 @@ var LambdaUrlProvider = class {
|
|
|
14746
15084
|
throw err;
|
|
14747
15085
|
}
|
|
14748
15086
|
}
|
|
15087
|
+
/**
|
|
15088
|
+
* Read the AWS-current Lambda Function URL configuration in CFn-property
|
|
15089
|
+
* shape.
|
|
15090
|
+
*
|
|
15091
|
+
* Issues `GetFunctionUrlConfig` with the parent function's ARN/name (the
|
|
15092
|
+
* physical id) and surfaces `AuthType`, `InvokeMode`, and `Cors`.
|
|
15093
|
+
* AWS-managed fields (`FunctionUrl`, `FunctionArn`, `CreationTime`,
|
|
15094
|
+
* `LastModifiedTime`) are filtered at the wire layer.
|
|
15095
|
+
*
|
|
15096
|
+
* `TargetFunctionArn` is surfaced from `physicalId` (the create() flow
|
|
15097
|
+
* stores the parent function's ARN/name there). `Qualifier` is NOT
|
|
15098
|
+
* available from `GetFunctionUrlConfig` (it's only an input on Create);
|
|
15099
|
+
* cdkd state stores it but AWS does not surface it back, so we omit it
|
|
15100
|
+
* from the snapshot — the comparator's "key absent in state never
|
|
15101
|
+
* drifts" rule handles the omission cleanly when state lacks Qualifier
|
|
15102
|
+
* too, and cases where state HAS Qualifier surface as drift only when
|
|
15103
|
+
* the qualifier was changed via Update (which the SDK supports through
|
|
15104
|
+
* `physicalId` rather than the qualifier itself).
|
|
15105
|
+
*
|
|
15106
|
+
* Returns `undefined` when the URL config is gone
|
|
15107
|
+
* (`ResourceNotFoundException`).
|
|
15108
|
+
*/
|
|
15109
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
15110
|
+
let resp;
|
|
15111
|
+
try {
|
|
15112
|
+
resp = await this.lambdaClient.send(
|
|
15113
|
+
new GetFunctionUrlConfigCommand2({ FunctionName: physicalId })
|
|
15114
|
+
);
|
|
15115
|
+
} catch (err) {
|
|
15116
|
+
if (err instanceof ResourceNotFoundException3)
|
|
15117
|
+
return void 0;
|
|
15118
|
+
throw err;
|
|
15119
|
+
}
|
|
15120
|
+
const result = {
|
|
15121
|
+
TargetFunctionArn: physicalId
|
|
15122
|
+
};
|
|
15123
|
+
if (resp.AuthType !== void 0)
|
|
15124
|
+
result["AuthType"] = resp.AuthType;
|
|
15125
|
+
if (resp.InvokeMode !== void 0)
|
|
15126
|
+
result["InvokeMode"] = resp.InvokeMode;
|
|
15127
|
+
if (resp.Cors !== void 0) {
|
|
15128
|
+
const cors = {};
|
|
15129
|
+
if (resp.Cors.AllowOrigins)
|
|
15130
|
+
cors["AllowOrigins"] = [...resp.Cors.AllowOrigins];
|
|
15131
|
+
if (resp.Cors.AllowMethods)
|
|
15132
|
+
cors["AllowMethods"] = [...resp.Cors.AllowMethods];
|
|
15133
|
+
if (resp.Cors.AllowHeaders)
|
|
15134
|
+
cors["AllowHeaders"] = [...resp.Cors.AllowHeaders];
|
|
15135
|
+
if (resp.Cors.ExposeHeaders)
|
|
15136
|
+
cors["ExposeHeaders"] = [...resp.Cors.ExposeHeaders];
|
|
15137
|
+
if (resp.Cors.MaxAge !== void 0)
|
|
15138
|
+
cors["MaxAge"] = resp.Cors.MaxAge;
|
|
15139
|
+
if (resp.Cors.AllowCredentials !== void 0) {
|
|
15140
|
+
cors["AllowCredentials"] = resp.Cors.AllowCredentials;
|
|
15141
|
+
}
|
|
15142
|
+
if (Object.keys(cors).length > 0)
|
|
15143
|
+
result["Cors"] = cors;
|
|
15144
|
+
}
|
|
15145
|
+
return result;
|
|
15146
|
+
}
|
|
14749
15147
|
/**
|
|
14750
15148
|
* Adopt an existing Lambda Function URL into cdkd state.
|
|
14751
15149
|
*
|
|
@@ -15008,6 +15406,96 @@ var LambdaEventSourceMappingProvider = class {
|
|
|
15008
15406
|
);
|
|
15009
15407
|
}
|
|
15010
15408
|
}
|
|
15409
|
+
/**
|
|
15410
|
+
* Read the AWS-current Lambda event source mapping configuration in
|
|
15411
|
+
* CFn-property shape.
|
|
15412
|
+
*
|
|
15413
|
+
* Issues `GetEventSourceMapping` for the UUID and surfaces the keys
|
|
15414
|
+
* `create()` accepts. AWS-managed fields (`UUID`, `LastModified`,
|
|
15415
|
+
* `LastProcessingResult`, `State`, `StateTransitionReason`,
|
|
15416
|
+
* `EventSourceMappingArn`) are filtered at the wire layer.
|
|
15417
|
+
*
|
|
15418
|
+
* `FunctionName` is surfaced as the AWS `FunctionArn` (which is what
|
|
15419
|
+
* `GetEventSourceMapping` returns) — cdkd state typically holds this
|
|
15420
|
+
* resolved ARN form already after intrinsic resolution. The drift
|
|
15421
|
+
* comparator can match against both forms when state holds a name vs an
|
|
15422
|
+
* ARN; mismatched-shape false positives are out of scope for v1.
|
|
15423
|
+
*
|
|
15424
|
+
* `Tags` is omitted: cdkd `create()` reshapes CFn tag arrays into a
|
|
15425
|
+
* tags map at create time, but `GetEventSourceMapping` does not return
|
|
15426
|
+
* tags (`ListTags(Resource: arn)` does). Same shape-decision rationale
|
|
15427
|
+
* as Lambda function tags drift — out of scope for v1.
|
|
15428
|
+
*
|
|
15429
|
+
* Returns `undefined` when the mapping is gone
|
|
15430
|
+
* (`ResourceNotFoundException`).
|
|
15431
|
+
*/
|
|
15432
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
15433
|
+
let resp;
|
|
15434
|
+
try {
|
|
15435
|
+
resp = await this.lambdaClient.send(new GetEventSourceMappingCommand({ UUID: physicalId }));
|
|
15436
|
+
} catch (err) {
|
|
15437
|
+
if (err instanceof ResourceNotFoundException4)
|
|
15438
|
+
return void 0;
|
|
15439
|
+
throw err;
|
|
15440
|
+
}
|
|
15441
|
+
const result = {};
|
|
15442
|
+
if (resp.FunctionArn !== void 0)
|
|
15443
|
+
result["FunctionName"] = resp.FunctionArn;
|
|
15444
|
+
if (resp.EventSourceArn !== void 0)
|
|
15445
|
+
result["EventSourceArn"] = resp.EventSourceArn;
|
|
15446
|
+
if (resp.BatchSize !== void 0)
|
|
15447
|
+
result["BatchSize"] = resp.BatchSize;
|
|
15448
|
+
if (resp.StartingPosition !== void 0)
|
|
15449
|
+
result["StartingPosition"] = resp.StartingPosition;
|
|
15450
|
+
if (resp.MaximumBatchingWindowInSeconds !== void 0) {
|
|
15451
|
+
result["MaximumBatchingWindowInSeconds"] = resp.MaximumBatchingWindowInSeconds;
|
|
15452
|
+
}
|
|
15453
|
+
if (resp.MaximumRetryAttempts !== void 0) {
|
|
15454
|
+
result["MaximumRetryAttempts"] = resp.MaximumRetryAttempts;
|
|
15455
|
+
}
|
|
15456
|
+
if (resp.BisectBatchOnFunctionError !== void 0) {
|
|
15457
|
+
result["BisectBatchOnFunctionError"] = resp.BisectBatchOnFunctionError;
|
|
15458
|
+
}
|
|
15459
|
+
if (resp.MaximumRecordAgeInSeconds !== void 0) {
|
|
15460
|
+
result["MaximumRecordAgeInSeconds"] = resp.MaximumRecordAgeInSeconds;
|
|
15461
|
+
}
|
|
15462
|
+
if (resp.ParallelizationFactor !== void 0) {
|
|
15463
|
+
result["ParallelizationFactor"] = resp.ParallelizationFactor;
|
|
15464
|
+
}
|
|
15465
|
+
if (resp.FilterCriteria !== void 0)
|
|
15466
|
+
result["FilterCriteria"] = resp.FilterCriteria;
|
|
15467
|
+
if (resp.DestinationConfig !== void 0) {
|
|
15468
|
+
result["DestinationConfig"] = resp.DestinationConfig;
|
|
15469
|
+
}
|
|
15470
|
+
if (resp.TumblingWindowInSeconds !== void 0) {
|
|
15471
|
+
result["TumblingWindowInSeconds"] = resp.TumblingWindowInSeconds;
|
|
15472
|
+
}
|
|
15473
|
+
if (resp.FunctionResponseTypes !== void 0 && resp.FunctionResponseTypes.length > 0) {
|
|
15474
|
+
result["FunctionResponseTypes"] = [...resp.FunctionResponseTypes];
|
|
15475
|
+
}
|
|
15476
|
+
if (resp.SourceAccessConfigurations !== void 0 && resp.SourceAccessConfigurations.length > 0) {
|
|
15477
|
+
result["SourceAccessConfigurations"] = resp.SourceAccessConfigurations;
|
|
15478
|
+
}
|
|
15479
|
+
if (resp.SelfManagedEventSource !== void 0) {
|
|
15480
|
+
result["SelfManagedEventSource"] = resp.SelfManagedEventSource;
|
|
15481
|
+
}
|
|
15482
|
+
if (resp.SelfManagedKafkaEventSourceConfig !== void 0) {
|
|
15483
|
+
result["SelfManagedKafkaEventSourceConfig"] = resp.SelfManagedKafkaEventSourceConfig;
|
|
15484
|
+
}
|
|
15485
|
+
if (resp.AmazonManagedKafkaEventSourceConfig !== void 0) {
|
|
15486
|
+
result["AmazonManagedKafkaEventSourceConfig"] = resp.AmazonManagedKafkaEventSourceConfig;
|
|
15487
|
+
}
|
|
15488
|
+
if (resp.DocumentDBEventSourceConfig !== void 0) {
|
|
15489
|
+
result["DocumentDBEventSourceConfig"] = resp.DocumentDBEventSourceConfig;
|
|
15490
|
+
}
|
|
15491
|
+
if (resp.ScalingConfig !== void 0)
|
|
15492
|
+
result["ScalingConfig"] = resp.ScalingConfig;
|
|
15493
|
+
if (resp.State !== void 0) {
|
|
15494
|
+
const enabled = resp.State === "Enabled" || resp.State === "Enabling" || resp.State === "Updating";
|
|
15495
|
+
result["Enabled"] = enabled;
|
|
15496
|
+
}
|
|
15497
|
+
return result;
|
|
15498
|
+
}
|
|
15011
15499
|
/**
|
|
15012
15500
|
* Adopt an existing Lambda event source mapping into cdkd state.
|
|
15013
15501
|
*
|
|
@@ -15176,6 +15664,57 @@ var LambdaLayerVersionProvider = class {
|
|
|
15176
15664
|
);
|
|
15177
15665
|
}
|
|
15178
15666
|
}
|
|
15667
|
+
/**
|
|
15668
|
+
* Read the AWS-current Lambda layer version configuration in CFn-property
|
|
15669
|
+
* shape.
|
|
15670
|
+
*
|
|
15671
|
+
* Issues `GetLayerVersionByArn` (the physical id is the version ARN) and
|
|
15672
|
+
* surfaces `LayerName`, `Description`, `CompatibleRuntimes`,
|
|
15673
|
+
* `CompatibleArchitectures`, and `LicenseInfo`. AWS-managed fields
|
|
15674
|
+
* (`Version`, `CreatedDate`, `LayerVersionArn`, `LayerArn`,
|
|
15675
|
+
* `Content.CodeSize`, `Content.CodeSha256`) are filtered at the wire
|
|
15676
|
+
* layer.
|
|
15677
|
+
*
|
|
15678
|
+
* `Content` is intentionally omitted: like Lambda function `Code`, the
|
|
15679
|
+
* `GetLayerVersionByArn` response contains a pre-signed S3 URL for the
|
|
15680
|
+
* deployed content, not the asset hash cdkd state stored. The two could
|
|
15681
|
+
* never match, so excluding it avoids a guaranteed false-positive.
|
|
15682
|
+
*
|
|
15683
|
+
* `LayerName` is derived from the ARN tail when not surfaced directly:
|
|
15684
|
+
* the version ARN format is
|
|
15685
|
+
* `arn:aws:lambda:<region>:<account>:layer:<name>:<version>`.
|
|
15686
|
+
*
|
|
15687
|
+
* Returns `undefined` when the layer version is gone
|
|
15688
|
+
* (`ResourceNotFoundException`).
|
|
15689
|
+
*/
|
|
15690
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
15691
|
+
let resp;
|
|
15692
|
+
try {
|
|
15693
|
+
resp = await this.lambdaClient.send(new GetLayerVersionByArnCommand({ Arn: physicalId }));
|
|
15694
|
+
} catch (err) {
|
|
15695
|
+
if (err instanceof ResourceNotFoundException5)
|
|
15696
|
+
return void 0;
|
|
15697
|
+
throw err;
|
|
15698
|
+
}
|
|
15699
|
+
const result = {};
|
|
15700
|
+
const arnParts = physicalId.split(":");
|
|
15701
|
+
if (arnParts.length >= 7 && arnParts[6]) {
|
|
15702
|
+
result["LayerName"] = arnParts[6];
|
|
15703
|
+
}
|
|
15704
|
+
if (resp.Description !== void 0 && resp.Description !== "") {
|
|
15705
|
+
result["Description"] = resp.Description;
|
|
15706
|
+
}
|
|
15707
|
+
if (resp.CompatibleRuntimes !== void 0 && resp.CompatibleRuntimes.length > 0) {
|
|
15708
|
+
result["CompatibleRuntimes"] = [...resp.CompatibleRuntimes];
|
|
15709
|
+
}
|
|
15710
|
+
if (resp.CompatibleArchitectures !== void 0 && resp.CompatibleArchitectures.length > 0) {
|
|
15711
|
+
result["CompatibleArchitectures"] = [...resp.CompatibleArchitectures];
|
|
15712
|
+
}
|
|
15713
|
+
if (resp.LicenseInfo !== void 0 && resp.LicenseInfo !== "") {
|
|
15714
|
+
result["LicenseInfo"] = resp.LicenseInfo;
|
|
15715
|
+
}
|
|
15716
|
+
return result;
|
|
15717
|
+
}
|
|
15179
15718
|
/**
|
|
15180
15719
|
* Adopt an existing Lambda layer version into cdkd state.
|
|
15181
15720
|
*
|
|
@@ -16209,6 +16748,82 @@ var CloudWatchAlarmProvider = class {
|
|
|
16209
16748
|
* 2. `DescribeAlarms` paginated, then `ListTagsForResource(AlarmArn)` per
|
|
16210
16749
|
* alarm to match `aws:cdk:path`.
|
|
16211
16750
|
*/
|
|
16751
|
+
/**
|
|
16752
|
+
* Read the AWS-current CloudWatch Alarm configuration in CFn-property shape.
|
|
16753
|
+
*
|
|
16754
|
+
* Issues `DescribeAlarms` filtered by `AlarmNames=[physicalId]` and
|
|
16755
|
+
* surfaces the keys cdkd's `create()` accepts (`AlarmName`,
|
|
16756
|
+
* `AlarmDescription`, `MetricName`, `Namespace`, `Statistic`,
|
|
16757
|
+
* `ComparisonOperator`, `Threshold`, `EvaluationPeriods`, `Period`,
|
|
16758
|
+
* `DatapointsToAlarm`, `ActionsEnabled`, `AlarmActions`,
|
|
16759
|
+
* `OKActions`, `InsufficientDataActions`, `TreatMissingData`, `Unit`,
|
|
16760
|
+
* `Dimensions`, `Metrics`).
|
|
16761
|
+
*
|
|
16762
|
+
* `DescribeAlarms` returns the result via either `MetricAlarms` (single-
|
|
16763
|
+
* metric form) or `CompositeAlarms` (composite form). cdkd's provider
|
|
16764
|
+
* only handles the single-metric form, so we look at `MetricAlarms` only.
|
|
16765
|
+
*
|
|
16766
|
+
* Returns `undefined` when the alarm is gone (no matching `MetricAlarms`).
|
|
16767
|
+
*/
|
|
16768
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
16769
|
+
const resp = await this.cloudWatchClient.send(
|
|
16770
|
+
new DescribeAlarmsCommand({ AlarmNames: [physicalId], AlarmTypes: ["MetricAlarm"] })
|
|
16771
|
+
);
|
|
16772
|
+
const alarm = resp.MetricAlarms?.[0];
|
|
16773
|
+
if (!alarm)
|
|
16774
|
+
return void 0;
|
|
16775
|
+
const result = {};
|
|
16776
|
+
if (alarm.AlarmName !== void 0)
|
|
16777
|
+
result["AlarmName"] = alarm.AlarmName;
|
|
16778
|
+
if (alarm.AlarmDescription !== void 0 && alarm.AlarmDescription !== "") {
|
|
16779
|
+
result["AlarmDescription"] = alarm.AlarmDescription;
|
|
16780
|
+
}
|
|
16781
|
+
if (alarm.MetricName !== void 0)
|
|
16782
|
+
result["MetricName"] = alarm.MetricName;
|
|
16783
|
+
if (alarm.Namespace !== void 0)
|
|
16784
|
+
result["Namespace"] = alarm.Namespace;
|
|
16785
|
+
if (alarm.Statistic !== void 0)
|
|
16786
|
+
result["Statistic"] = alarm.Statistic;
|
|
16787
|
+
if (alarm.ComparisonOperator !== void 0) {
|
|
16788
|
+
result["ComparisonOperator"] = alarm.ComparisonOperator;
|
|
16789
|
+
}
|
|
16790
|
+
if (alarm.Threshold !== void 0)
|
|
16791
|
+
result["Threshold"] = alarm.Threshold;
|
|
16792
|
+
if (alarm.EvaluationPeriods !== void 0) {
|
|
16793
|
+
result["EvaluationPeriods"] = alarm.EvaluationPeriods;
|
|
16794
|
+
}
|
|
16795
|
+
if (alarm.Period !== void 0)
|
|
16796
|
+
result["Period"] = alarm.Period;
|
|
16797
|
+
if (alarm.DatapointsToAlarm !== void 0) {
|
|
16798
|
+
result["DatapointsToAlarm"] = alarm.DatapointsToAlarm;
|
|
16799
|
+
}
|
|
16800
|
+
if (alarm.ActionsEnabled !== void 0)
|
|
16801
|
+
result["ActionsEnabled"] = alarm.ActionsEnabled;
|
|
16802
|
+
if (alarm.AlarmActions && alarm.AlarmActions.length > 0) {
|
|
16803
|
+
result["AlarmActions"] = [...alarm.AlarmActions];
|
|
16804
|
+
}
|
|
16805
|
+
if (alarm.OKActions && alarm.OKActions.length > 0) {
|
|
16806
|
+
result["OKActions"] = [...alarm.OKActions];
|
|
16807
|
+
}
|
|
16808
|
+
if (alarm.InsufficientDataActions && alarm.InsufficientDataActions.length > 0) {
|
|
16809
|
+
result["InsufficientDataActions"] = [...alarm.InsufficientDataActions];
|
|
16810
|
+
}
|
|
16811
|
+
if (alarm.TreatMissingData !== void 0) {
|
|
16812
|
+
result["TreatMissingData"] = alarm.TreatMissingData;
|
|
16813
|
+
}
|
|
16814
|
+
if (alarm.Unit !== void 0)
|
|
16815
|
+
result["Unit"] = alarm.Unit;
|
|
16816
|
+
if (alarm.Dimensions && alarm.Dimensions.length > 0) {
|
|
16817
|
+
result["Dimensions"] = alarm.Dimensions.map((d) => ({
|
|
16818
|
+
...d.Name !== void 0 ? { Name: d.Name } : {},
|
|
16819
|
+
...d.Value !== void 0 ? { Value: d.Value } : {}
|
|
16820
|
+
}));
|
|
16821
|
+
}
|
|
16822
|
+
if (alarm.Metrics && alarm.Metrics.length > 0) {
|
|
16823
|
+
result["Metrics"] = alarm.Metrics.map((m) => m);
|
|
16824
|
+
}
|
|
16825
|
+
return result;
|
|
16826
|
+
}
|
|
16212
16827
|
async import(input) {
|
|
16213
16828
|
const explicit = resolveExplicitPhysicalId(input, "AlarmName");
|
|
16214
16829
|
if (explicit) {
|
|
@@ -17777,7 +18392,10 @@ import {
|
|
|
17777
18392
|
CreateVpcCommand,
|
|
17778
18393
|
DeleteVpcCommand,
|
|
17779
18394
|
ModifyVpcAttributeCommand,
|
|
18395
|
+
DescribeVpcAttributeCommand,
|
|
17780
18396
|
DescribeVpcsCommand as DescribeVpcsCommand2,
|
|
18397
|
+
DescribeInternetGatewaysCommand,
|
|
18398
|
+
DescribeRouteTablesCommand as DescribeRouteTablesCommand2,
|
|
17781
18399
|
CreateSubnetCommand,
|
|
17782
18400
|
DeleteSubnetCommand,
|
|
17783
18401
|
CreateInternetGatewayCommand,
|
|
@@ -19937,9 +20555,226 @@ var EC2Provider = class {
|
|
|
19937
20555
|
throw error;
|
|
19938
20556
|
}
|
|
19939
20557
|
}
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
20558
|
+
/**
|
|
20559
|
+
* Read the AWS-current EC2 networking resource configuration in
|
|
20560
|
+
* CFn-property shape.
|
|
20561
|
+
*
|
|
20562
|
+
* Supported types (highest-value drift coverage):
|
|
20563
|
+
* - **AWS::EC2::VPC**: `DescribeVpcs` for `CidrBlock` + `InstanceTenancy`;
|
|
20564
|
+
* `DescribeVpcAttribute(enableDnsHostnames|enableDnsSupport)` for the
|
|
20565
|
+
* DNS booleans (CFn defaults: hostnames=false, support=true — we only
|
|
20566
|
+
* surface them if AWS reports them, so the comparator's "key-absent
|
|
20567
|
+
* never drifts" rule applies cleanly to state without these keys).
|
|
20568
|
+
* - **AWS::EC2::Subnet**: `DescribeSubnets` for `VpcId`, `CidrBlock`,
|
|
20569
|
+
* `AvailabilityZone`, `MapPublicIpOnLaunch`.
|
|
20570
|
+
* - **AWS::EC2::InternetGateway**: `DescribeInternetGateways` for
|
|
20571
|
+
* existence verification. The provider only handles `Tags`, which is
|
|
20572
|
+
* out of scope for v1 drift.
|
|
20573
|
+
* - **AWS::EC2::NatGateway**: `DescribeNatGateways` for `SubnetId`,
|
|
20574
|
+
* `AllocationId`, `ConnectivityType`, `PrivateIpAddress`.
|
|
20575
|
+
* - **AWS::EC2::RouteTable**: `DescribeRouteTables` for `VpcId`.
|
|
20576
|
+
* - **AWS::EC2::SecurityGroup**: `DescribeSecurityGroups` for
|
|
20577
|
+
* `GroupName`, `GroupDescription`, `VpcId`. Ingress / egress rules
|
|
20578
|
+
* are NOT surfaced — the CFn shape is rule-list-style, while AWS
|
|
20579
|
+
* returns IpPermissions in a different normalized form, and a
|
|
20580
|
+
* faithful reverse-mapping is out of scope for v1.
|
|
20581
|
+
* - **AWS::EC2::Instance**: `DescribeInstances` for `ImageId`,
|
|
20582
|
+
* `InstanceType`, `KeyName`, `SubnetId`. SecurityGroupIds /
|
|
20583
|
+
* BlockDeviceMappings shape-match is out of scope for v1.
|
|
20584
|
+
* - **AWS::EC2::NetworkAcl**: `DescribeNetworkAcls` for `VpcId`.
|
|
20585
|
+
*
|
|
20586
|
+
* Skipped (return `undefined`, falls through to the comparator's
|
|
20587
|
+
* "unsupported" outcome):
|
|
20588
|
+
* - **AWS::EC2::VPCGatewayAttachment**: physical id is
|
|
20589
|
+
* `IGW|VpcId`. The two ids are immutable inputs to the SDK call;
|
|
20590
|
+
* drift detection on this resource has no useful signal beyond
|
|
20591
|
+
* existence verification (which the user can do via the parent IGW
|
|
20592
|
+
* / VPC drift report).
|
|
20593
|
+
* - **AWS::EC2::Route**, **AWS::EC2::SubnetRouteTableAssociation**,
|
|
20594
|
+
* **AWS::EC2::SecurityGroupIngress**, **AWS::EC2::NetworkAclEntry**,
|
|
20595
|
+
* **AWS::EC2::SubnetNetworkAclAssociation**: rule / association
|
|
20596
|
+
* sub-resources whose AWS API surfaces them inside the parent's
|
|
20597
|
+
* list, not as standalone Get* responses. v1 drift coverage focuses
|
|
20598
|
+
* on top-level resources where the property shape comparison is
|
|
20599
|
+
* cheap and unambiguous; these sub-resources need a more elaborate
|
|
20600
|
+
* extraction layer that's out of scope for this PR.
|
|
20601
|
+
*
|
|
20602
|
+
* Returns `undefined` when the resource is gone (any `*NotFound` /
|
|
20603
|
+
* `Invalid*` error from the EC2 SDK matches `isNotFoundError`).
|
|
20604
|
+
*/
|
|
20605
|
+
async readCurrentState(physicalId, logicalId, resourceType) {
|
|
20606
|
+
try {
|
|
20607
|
+
switch (resourceType) {
|
|
20608
|
+
case "AWS::EC2::VPC":
|
|
20609
|
+
return await this.readVpcCurrentState(physicalId);
|
|
20610
|
+
case "AWS::EC2::Subnet":
|
|
20611
|
+
return await this.readSubnetCurrentState(physicalId);
|
|
20612
|
+
case "AWS::EC2::InternetGateway":
|
|
20613
|
+
return await this.readInternetGatewayCurrentState(physicalId);
|
|
20614
|
+
case "AWS::EC2::NatGateway":
|
|
20615
|
+
return await this.readNatGatewayCurrentState(physicalId);
|
|
20616
|
+
case "AWS::EC2::RouteTable":
|
|
20617
|
+
return await this.readRouteTableCurrentState(physicalId);
|
|
20618
|
+
case "AWS::EC2::SecurityGroup":
|
|
20619
|
+
return await this.readSecurityGroupCurrentState(physicalId);
|
|
20620
|
+
case "AWS::EC2::Instance":
|
|
20621
|
+
return await this.readInstanceCurrentState(physicalId);
|
|
20622
|
+
case "AWS::EC2::NetworkAcl":
|
|
20623
|
+
return await this.readNetworkAclCurrentState(physicalId);
|
|
20624
|
+
default:
|
|
20625
|
+
this.logger.debug(
|
|
20626
|
+
`readCurrentState: unsupported resource type ${resourceType} for ${logicalId}`
|
|
20627
|
+
);
|
|
20628
|
+
return void 0;
|
|
20629
|
+
}
|
|
20630
|
+
} catch (err) {
|
|
20631
|
+
if (this.isNotFoundError(err))
|
|
20632
|
+
return void 0;
|
|
20633
|
+
throw err;
|
|
20634
|
+
}
|
|
20635
|
+
}
|
|
20636
|
+
async readVpcCurrentState(physicalId) {
|
|
20637
|
+
const resp = await this.ec2Client.send(new DescribeVpcsCommand2({ VpcIds: [physicalId] }));
|
|
20638
|
+
const vpc = resp.Vpcs?.[0];
|
|
20639
|
+
if (!vpc)
|
|
20640
|
+
return void 0;
|
|
20641
|
+
const result = {};
|
|
20642
|
+
if (vpc.CidrBlock !== void 0)
|
|
20643
|
+
result["CidrBlock"] = vpc.CidrBlock;
|
|
20644
|
+
if (vpc.InstanceTenancy !== void 0)
|
|
20645
|
+
result["InstanceTenancy"] = vpc.InstanceTenancy;
|
|
20646
|
+
try {
|
|
20647
|
+
const dnsHost = await this.ec2Client.send(
|
|
20648
|
+
new DescribeVpcAttributeCommand({ VpcId: physicalId, Attribute: "enableDnsHostnames" })
|
|
20649
|
+
);
|
|
20650
|
+
if (dnsHost.EnableDnsHostnames?.Value !== void 0) {
|
|
20651
|
+
result["EnableDnsHostnames"] = dnsHost.EnableDnsHostnames.Value;
|
|
20652
|
+
}
|
|
20653
|
+
} catch (err) {
|
|
20654
|
+
if (!this.isNotFoundError(err))
|
|
20655
|
+
throw err;
|
|
20656
|
+
}
|
|
20657
|
+
try {
|
|
20658
|
+
const dnsSupp = await this.ec2Client.send(
|
|
20659
|
+
new DescribeVpcAttributeCommand({ VpcId: physicalId, Attribute: "enableDnsSupport" })
|
|
20660
|
+
);
|
|
20661
|
+
if (dnsSupp.EnableDnsSupport?.Value !== void 0) {
|
|
20662
|
+
result["EnableDnsSupport"] = dnsSupp.EnableDnsSupport.Value;
|
|
20663
|
+
}
|
|
20664
|
+
} catch (err) {
|
|
20665
|
+
if (!this.isNotFoundError(err))
|
|
20666
|
+
throw err;
|
|
20667
|
+
}
|
|
20668
|
+
return result;
|
|
20669
|
+
}
|
|
20670
|
+
async readSubnetCurrentState(physicalId) {
|
|
20671
|
+
const resp = await this.ec2Client.send(new DescribeSubnetsCommand2({ SubnetIds: [physicalId] }));
|
|
20672
|
+
const subnet = resp.Subnets?.[0];
|
|
20673
|
+
if (!subnet)
|
|
20674
|
+
return void 0;
|
|
20675
|
+
const result = {};
|
|
20676
|
+
if (subnet.VpcId !== void 0)
|
|
20677
|
+
result["VpcId"] = subnet.VpcId;
|
|
20678
|
+
if (subnet.CidrBlock !== void 0)
|
|
20679
|
+
result["CidrBlock"] = subnet.CidrBlock;
|
|
20680
|
+
if (subnet.AvailabilityZone !== void 0) {
|
|
20681
|
+
result["AvailabilityZone"] = subnet.AvailabilityZone;
|
|
20682
|
+
}
|
|
20683
|
+
if (subnet.MapPublicIpOnLaunch !== void 0) {
|
|
20684
|
+
result["MapPublicIpOnLaunch"] = subnet.MapPublicIpOnLaunch;
|
|
20685
|
+
}
|
|
20686
|
+
return result;
|
|
20687
|
+
}
|
|
20688
|
+
async readInternetGatewayCurrentState(physicalId) {
|
|
20689
|
+
const resp = await this.ec2Client.send(
|
|
20690
|
+
new DescribeInternetGatewaysCommand({ InternetGatewayIds: [physicalId] })
|
|
20691
|
+
);
|
|
20692
|
+
const igw = resp.InternetGateways?.[0];
|
|
20693
|
+
if (!igw)
|
|
20694
|
+
return void 0;
|
|
20695
|
+
return {};
|
|
20696
|
+
}
|
|
20697
|
+
async readNatGatewayCurrentState(physicalId) {
|
|
20698
|
+
const resp = await this.ec2Client.send(
|
|
20699
|
+
new DescribeNatGatewaysCommand({ NatGatewayIds: [physicalId] })
|
|
20700
|
+
);
|
|
20701
|
+
const gw = resp.NatGateways?.find((g) => g.State !== "deleted" && g.State !== "deleting");
|
|
20702
|
+
if (!gw)
|
|
20703
|
+
return void 0;
|
|
20704
|
+
const result = {};
|
|
20705
|
+
if (gw.SubnetId !== void 0)
|
|
20706
|
+
result["SubnetId"] = gw.SubnetId;
|
|
20707
|
+
if (gw.ConnectivityType !== void 0)
|
|
20708
|
+
result["ConnectivityType"] = gw.ConnectivityType;
|
|
20709
|
+
const primary = gw.NatGatewayAddresses?.[0];
|
|
20710
|
+
if (primary?.AllocationId !== void 0)
|
|
20711
|
+
result["AllocationId"] = primary.AllocationId;
|
|
20712
|
+
if (primary?.PrivateIp !== void 0)
|
|
20713
|
+
result["PrivateIpAddress"] = primary.PrivateIp;
|
|
20714
|
+
return result;
|
|
20715
|
+
}
|
|
20716
|
+
async readRouteTableCurrentState(physicalId) {
|
|
20717
|
+
const resp = await this.ec2Client.send(
|
|
20718
|
+
new DescribeRouteTablesCommand2({ RouteTableIds: [physicalId] })
|
|
20719
|
+
);
|
|
20720
|
+
const rt = resp.RouteTables?.[0];
|
|
20721
|
+
if (!rt)
|
|
20722
|
+
return void 0;
|
|
20723
|
+
const result = {};
|
|
20724
|
+
if (rt.VpcId !== void 0)
|
|
20725
|
+
result["VpcId"] = rt.VpcId;
|
|
20726
|
+
return result;
|
|
20727
|
+
}
|
|
20728
|
+
async readSecurityGroupCurrentState(physicalId) {
|
|
20729
|
+
const resp = await this.ec2Client.send(
|
|
20730
|
+
new DescribeSecurityGroupsCommand2({ GroupIds: [physicalId] })
|
|
20731
|
+
);
|
|
20732
|
+
const sg = resp.SecurityGroups?.[0];
|
|
20733
|
+
if (!sg)
|
|
20734
|
+
return void 0;
|
|
20735
|
+
const result = {};
|
|
20736
|
+
if (sg.GroupName !== void 0)
|
|
20737
|
+
result["GroupName"] = sg.GroupName;
|
|
20738
|
+
if (sg.Description !== void 0)
|
|
20739
|
+
result["GroupDescription"] = sg.Description;
|
|
20740
|
+
if (sg.VpcId !== void 0)
|
|
20741
|
+
result["VpcId"] = sg.VpcId;
|
|
20742
|
+
return result;
|
|
20743
|
+
}
|
|
20744
|
+
async readInstanceCurrentState(physicalId) {
|
|
20745
|
+
const resp = await this.ec2Client.send(
|
|
20746
|
+
new DescribeInstancesCommand({ InstanceIds: [physicalId] })
|
|
20747
|
+
);
|
|
20748
|
+
const instance = resp.Reservations?.[0]?.Instances?.[0];
|
|
20749
|
+
if (!instance || instance.State?.Name === "terminated" || instance.State?.Name === "shutting-down") {
|
|
20750
|
+
return void 0;
|
|
20751
|
+
}
|
|
20752
|
+
const result = {};
|
|
20753
|
+
if (instance.ImageId !== void 0)
|
|
20754
|
+
result["ImageId"] = instance.ImageId;
|
|
20755
|
+
if (instance.InstanceType !== void 0)
|
|
20756
|
+
result["InstanceType"] = instance.InstanceType;
|
|
20757
|
+
if (instance.KeyName !== void 0)
|
|
20758
|
+
result["KeyName"] = instance.KeyName;
|
|
20759
|
+
if (instance.SubnetId !== void 0)
|
|
20760
|
+
result["SubnetId"] = instance.SubnetId;
|
|
20761
|
+
return result;
|
|
20762
|
+
}
|
|
20763
|
+
async readNetworkAclCurrentState(physicalId) {
|
|
20764
|
+
const resp = await this.ec2Client.send(
|
|
20765
|
+
new DescribeNetworkAclsCommand({ NetworkAclIds: [physicalId] })
|
|
20766
|
+
);
|
|
20767
|
+
const acl = resp.NetworkAcls?.[0];
|
|
20768
|
+
if (!acl)
|
|
20769
|
+
return void 0;
|
|
20770
|
+
const result = {};
|
|
20771
|
+
if (acl.VpcId !== void 0)
|
|
20772
|
+
result["VpcId"] = acl.VpcId;
|
|
20773
|
+
return result;
|
|
20774
|
+
}
|
|
20775
|
+
async verifyExplicit(resourceType, physicalId) {
|
|
20776
|
+
try {
|
|
20777
|
+
switch (resourceType) {
|
|
19943
20778
|
case "AWS::EC2::VPC": {
|
|
19944
20779
|
const resp = await this.ec2Client.send(new DescribeVpcsCommand2({ VpcIds: [physicalId] }));
|
|
19945
20780
|
return resp.Vpcs?.[0] ? { physicalId, attributes: {} } : null;
|
|
@@ -22419,6 +23254,23 @@ function pascalToCamelCaseKeys(value) {
|
|
|
22419
23254
|
}
|
|
22420
23255
|
return value;
|
|
22421
23256
|
}
|
|
23257
|
+
function camelToPascalCaseKeys(value) {
|
|
23258
|
+
if (value === null || value === void 0) {
|
|
23259
|
+
return value;
|
|
23260
|
+
}
|
|
23261
|
+
if (Array.isArray(value)) {
|
|
23262
|
+
return value.map(camelToPascalCaseKeys);
|
|
23263
|
+
}
|
|
23264
|
+
if (typeof value === "object") {
|
|
23265
|
+
const result = {};
|
|
23266
|
+
for (const [key, val] of Object.entries(value)) {
|
|
23267
|
+
const pascalKey = key.charAt(0).toUpperCase() + key.slice(1);
|
|
23268
|
+
result[pascalKey] = camelToPascalCaseKeys(val);
|
|
23269
|
+
}
|
|
23270
|
+
return result;
|
|
23271
|
+
}
|
|
23272
|
+
return value;
|
|
23273
|
+
}
|
|
22422
23274
|
var AgentCoreRuntimeProvider = class {
|
|
22423
23275
|
client;
|
|
22424
23276
|
logger = getLogger().child("AgentCoreRuntimeProvider");
|
|
@@ -22653,6 +23505,68 @@ var AgentCoreRuntimeProvider = class {
|
|
|
22653
23505
|
}
|
|
22654
23506
|
throw new Error(`Unsupported attribute: ${attributeName} for AWS::BedrockAgentCore::Runtime`);
|
|
22655
23507
|
}
|
|
23508
|
+
/**
|
|
23509
|
+
* Read the AWS-current BedrockAgentCore Runtime configuration in
|
|
23510
|
+
* CFn-property shape.
|
|
23511
|
+
*
|
|
23512
|
+
* Issues `GetAgentRuntime` (the physical id is the runtime id) and
|
|
23513
|
+
* surfaces the keys `create()` accepts. The SDK returns camelCase keys
|
|
23514
|
+
* (`agentRuntimeName`, `roleArn`, `agentRuntimeArtifact`, etc.); we
|
|
23515
|
+
* re-shape back to PascalCase via `camelToPascalCaseKeys` so the
|
|
23516
|
+
* comparator matches cdkd state.
|
|
23517
|
+
*
|
|
23518
|
+
* `ProtocolConfiguration` parity: `create()` accepts a CFn-style string
|
|
23519
|
+
* (`"HTTP"`) and converts it to `{serverProtocol: "HTTP"}` for the SDK.
|
|
23520
|
+
* The SDK returns the object form. We surface the object form here; if
|
|
23521
|
+
* cdkd state holds the original string the comparator will report drift
|
|
23522
|
+
* — users can inspect and dismiss this case manually. (A more elaborate
|
|
23523
|
+
* shape negotiation belongs in a follow-up that knows about both forms.)
|
|
23524
|
+
*
|
|
23525
|
+
* `ClientToken` is omitted: AWS does not surface it back via
|
|
23526
|
+
* `GetAgentRuntime` (it's an idempotency token only meaningful at create
|
|
23527
|
+
* time).
|
|
23528
|
+
*
|
|
23529
|
+
* Returns `undefined` when the runtime is gone
|
|
23530
|
+
* (`ResourceNotFoundException`).
|
|
23531
|
+
*/
|
|
23532
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
23533
|
+
let resp;
|
|
23534
|
+
try {
|
|
23535
|
+
resp = await this.client.send(new GetAgentRuntimeCommand({ agentRuntimeId: physicalId }));
|
|
23536
|
+
} catch (err) {
|
|
23537
|
+
if (err instanceof ResourceNotFoundException11)
|
|
23538
|
+
return void 0;
|
|
23539
|
+
throw err;
|
|
23540
|
+
}
|
|
23541
|
+
const result = {};
|
|
23542
|
+
if (resp.agentRuntimeName !== void 0) {
|
|
23543
|
+
result["AgentRuntimeName"] = resp.agentRuntimeName;
|
|
23544
|
+
}
|
|
23545
|
+
if (resp.roleArn !== void 0)
|
|
23546
|
+
result["RoleArn"] = resp.roleArn;
|
|
23547
|
+
if (resp.agentRuntimeArtifact !== void 0) {
|
|
23548
|
+
result["AgentRuntimeArtifact"] = camelToPascalCaseKeys(resp.agentRuntimeArtifact);
|
|
23549
|
+
}
|
|
23550
|
+
if (resp.networkConfiguration !== void 0) {
|
|
23551
|
+
result["NetworkConfiguration"] = camelToPascalCaseKeys(resp.networkConfiguration);
|
|
23552
|
+
}
|
|
23553
|
+
if (resp.description !== void 0 && resp.description !== "") {
|
|
23554
|
+
result["Description"] = resp.description;
|
|
23555
|
+
}
|
|
23556
|
+
if (resp.authorizerConfiguration !== void 0) {
|
|
23557
|
+
result["AuthorizerConfiguration"] = camelToPascalCaseKeys(resp.authorizerConfiguration);
|
|
23558
|
+
}
|
|
23559
|
+
if (resp.protocolConfiguration !== void 0) {
|
|
23560
|
+
result["ProtocolConfiguration"] = camelToPascalCaseKeys(resp.protocolConfiguration);
|
|
23561
|
+
}
|
|
23562
|
+
if (resp.lifecycleConfiguration !== void 0) {
|
|
23563
|
+
result["LifecycleConfiguration"] = camelToPascalCaseKeys(resp.lifecycleConfiguration);
|
|
23564
|
+
}
|
|
23565
|
+
if (resp.environmentVariables !== void 0) {
|
|
23566
|
+
result["EnvironmentVariables"] = resp.environmentVariables;
|
|
23567
|
+
}
|
|
23568
|
+
return result;
|
|
23569
|
+
}
|
|
22656
23570
|
/**
|
|
22657
23571
|
* Adopt an existing BedrockAgentCore Runtime into cdkd state.
|
|
22658
23572
|
*
|
|
@@ -24089,7 +25003,8 @@ import {
|
|
|
24089
25003
|
DescribeTagsCommand,
|
|
24090
25004
|
CreateListenerCommand,
|
|
24091
25005
|
DeleteListenerCommand,
|
|
24092
|
-
ModifyListenerCommand
|
|
25006
|
+
ModifyListenerCommand,
|
|
25007
|
+
DescribeListenersCommand as DescribeListenersCommand2
|
|
24093
25008
|
} from "@aws-sdk/client-elastic-load-balancing-v2";
|
|
24094
25009
|
var ELBv2Provider = class {
|
|
24095
25010
|
elbv2Client;
|
|
@@ -24582,6 +25497,170 @@ var ELBv2Provider = class {
|
|
|
24582
25497
|
return void 0;
|
|
24583
25498
|
return certificates;
|
|
24584
25499
|
}
|
|
25500
|
+
/**
|
|
25501
|
+
* Read the AWS-current ELBv2 resource configuration in CFn-property shape.
|
|
25502
|
+
*
|
|
25503
|
+
* Dispatch per resource type:
|
|
25504
|
+
* - `LoadBalancer` → `DescribeLoadBalancers` (Name, Subnets via
|
|
25505
|
+
* `AvailabilityZones[].SubnetId`, SecurityGroups, Scheme, Type,
|
|
25506
|
+
* IpAddressType). LoadBalancerAttributes is omitted for v1 — it
|
|
25507
|
+
* requires a separate `DescribeLoadBalancerAttributes` call and the
|
|
25508
|
+
* drift comparator only descends into keys present in state, so an
|
|
25509
|
+
* absent key cannot fire false drift.
|
|
25510
|
+
* - `TargetGroup` → `DescribeTargetGroups` (Protocol, Port, VpcId,
|
|
25511
|
+
* TargetType, ProtocolVersion, HealthCheck*, Matcher, Name).
|
|
25512
|
+
* - `Listener` → `DescribeListeners` (LoadBalancerArn, Certificates,
|
|
25513
|
+
* DefaultActions, Port, Protocol, SslPolicy).
|
|
25514
|
+
*
|
|
25515
|
+
* Tags are skipped (CDK auto-tag handling deferred). Returns `undefined`
|
|
25516
|
+
* when the resource is gone (`*NotFoundException`).
|
|
25517
|
+
*/
|
|
25518
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
25519
|
+
switch (resourceType) {
|
|
25520
|
+
case "AWS::ElasticLoadBalancingV2::LoadBalancer":
|
|
25521
|
+
return this.readLoadBalancer(physicalId);
|
|
25522
|
+
case "AWS::ElasticLoadBalancingV2::TargetGroup":
|
|
25523
|
+
return this.readTargetGroup(physicalId);
|
|
25524
|
+
case "AWS::ElasticLoadBalancingV2::Listener":
|
|
25525
|
+
return this.readListener(physicalId);
|
|
25526
|
+
default:
|
|
25527
|
+
return void 0;
|
|
25528
|
+
}
|
|
25529
|
+
}
|
|
25530
|
+
async readLoadBalancer(physicalId) {
|
|
25531
|
+
let lb;
|
|
25532
|
+
try {
|
|
25533
|
+
const resp = await this.getClient().send(
|
|
25534
|
+
new DescribeLoadBalancersCommand2({ LoadBalancerArns: [physicalId] })
|
|
25535
|
+
);
|
|
25536
|
+
lb = resp.LoadBalancers?.[0];
|
|
25537
|
+
} catch (err) {
|
|
25538
|
+
if (this.isNotFoundError(err))
|
|
25539
|
+
return void 0;
|
|
25540
|
+
throw err;
|
|
25541
|
+
}
|
|
25542
|
+
if (!lb)
|
|
25543
|
+
return void 0;
|
|
25544
|
+
const result = {};
|
|
25545
|
+
if (lb.LoadBalancerName !== void 0)
|
|
25546
|
+
result["Name"] = lb.LoadBalancerName;
|
|
25547
|
+
if (lb.AvailabilityZones && lb.AvailabilityZones.length > 0) {
|
|
25548
|
+
const subnets = lb.AvailabilityZones.map((az) => az.SubnetId).filter(
|
|
25549
|
+
(id) => !!id
|
|
25550
|
+
);
|
|
25551
|
+
if (subnets.length > 0)
|
|
25552
|
+
result["Subnets"] = subnets;
|
|
25553
|
+
}
|
|
25554
|
+
if (lb.SecurityGroups && lb.SecurityGroups.length > 0) {
|
|
25555
|
+
result["SecurityGroups"] = [...lb.SecurityGroups];
|
|
25556
|
+
}
|
|
25557
|
+
if (lb.Scheme !== void 0)
|
|
25558
|
+
result["Scheme"] = lb.Scheme;
|
|
25559
|
+
if (lb.Type !== void 0)
|
|
25560
|
+
result["Type"] = lb.Type;
|
|
25561
|
+
if (lb.IpAddressType !== void 0)
|
|
25562
|
+
result["IpAddressType"] = lb.IpAddressType;
|
|
25563
|
+
return result;
|
|
25564
|
+
}
|
|
25565
|
+
async readTargetGroup(physicalId) {
|
|
25566
|
+
let tg;
|
|
25567
|
+
try {
|
|
25568
|
+
const resp = await this.getClient().send(
|
|
25569
|
+
new DescribeTargetGroupsCommand({ TargetGroupArns: [physicalId] })
|
|
25570
|
+
);
|
|
25571
|
+
tg = resp.TargetGroups?.[0];
|
|
25572
|
+
} catch (err) {
|
|
25573
|
+
if (this.isNotFoundError(err))
|
|
25574
|
+
return void 0;
|
|
25575
|
+
throw err;
|
|
25576
|
+
}
|
|
25577
|
+
if (!tg)
|
|
25578
|
+
return void 0;
|
|
25579
|
+
const result = {};
|
|
25580
|
+
if (tg.TargetGroupName !== void 0)
|
|
25581
|
+
result["Name"] = tg.TargetGroupName;
|
|
25582
|
+
if (tg.Protocol !== void 0)
|
|
25583
|
+
result["Protocol"] = tg.Protocol;
|
|
25584
|
+
if (tg.Port !== void 0)
|
|
25585
|
+
result["Port"] = tg.Port;
|
|
25586
|
+
if (tg.VpcId !== void 0)
|
|
25587
|
+
result["VpcId"] = tg.VpcId;
|
|
25588
|
+
if (tg.TargetType !== void 0)
|
|
25589
|
+
result["TargetType"] = tg.TargetType;
|
|
25590
|
+
if (tg.ProtocolVersion !== void 0)
|
|
25591
|
+
result["ProtocolVersion"] = tg.ProtocolVersion;
|
|
25592
|
+
if (tg.HealthCheckProtocol !== void 0)
|
|
25593
|
+
result["HealthCheckProtocol"] = tg.HealthCheckProtocol;
|
|
25594
|
+
if (tg.HealthCheckPort !== void 0)
|
|
25595
|
+
result["HealthCheckPort"] = tg.HealthCheckPort;
|
|
25596
|
+
if (tg.HealthCheckPath !== void 0)
|
|
25597
|
+
result["HealthCheckPath"] = tg.HealthCheckPath;
|
|
25598
|
+
if (tg.HealthCheckEnabled !== void 0)
|
|
25599
|
+
result["HealthCheckEnabled"] = tg.HealthCheckEnabled;
|
|
25600
|
+
if (tg.HealthCheckIntervalSeconds !== void 0) {
|
|
25601
|
+
result["HealthCheckIntervalSeconds"] = tg.HealthCheckIntervalSeconds;
|
|
25602
|
+
}
|
|
25603
|
+
if (tg.HealthCheckTimeoutSeconds !== void 0) {
|
|
25604
|
+
result["HealthCheckTimeoutSeconds"] = tg.HealthCheckTimeoutSeconds;
|
|
25605
|
+
}
|
|
25606
|
+
if (tg.HealthyThresholdCount !== void 0) {
|
|
25607
|
+
result["HealthyThresholdCount"] = tg.HealthyThresholdCount;
|
|
25608
|
+
}
|
|
25609
|
+
if (tg.UnhealthyThresholdCount !== void 0) {
|
|
25610
|
+
result["UnhealthyThresholdCount"] = tg.UnhealthyThresholdCount;
|
|
25611
|
+
}
|
|
25612
|
+
if (tg.Matcher) {
|
|
25613
|
+
const matcher = {};
|
|
25614
|
+
if (tg.Matcher.HttpCode !== void 0)
|
|
25615
|
+
matcher["HttpCode"] = tg.Matcher.HttpCode;
|
|
25616
|
+
if (tg.Matcher.GrpcCode !== void 0)
|
|
25617
|
+
matcher["GrpcCode"] = tg.Matcher.GrpcCode;
|
|
25618
|
+
if (Object.keys(matcher).length > 0)
|
|
25619
|
+
result["Matcher"] = matcher;
|
|
25620
|
+
}
|
|
25621
|
+
return result;
|
|
25622
|
+
}
|
|
25623
|
+
async readListener(physicalId) {
|
|
25624
|
+
let listener;
|
|
25625
|
+
try {
|
|
25626
|
+
const resp = await this.getClient().send(
|
|
25627
|
+
new DescribeListenersCommand2({ ListenerArns: [physicalId] })
|
|
25628
|
+
);
|
|
25629
|
+
listener = resp.Listeners?.[0];
|
|
25630
|
+
} catch (err) {
|
|
25631
|
+
if (this.isNotFoundError(err))
|
|
25632
|
+
return void 0;
|
|
25633
|
+
throw err;
|
|
25634
|
+
}
|
|
25635
|
+
if (!listener)
|
|
25636
|
+
return void 0;
|
|
25637
|
+
const result = {};
|
|
25638
|
+
if (listener.LoadBalancerArn !== void 0) {
|
|
25639
|
+
result["LoadBalancerArn"] = listener.LoadBalancerArn;
|
|
25640
|
+
}
|
|
25641
|
+
if (listener.Port !== void 0)
|
|
25642
|
+
result["Port"] = listener.Port;
|
|
25643
|
+
if (listener.Protocol !== void 0)
|
|
25644
|
+
result["Protocol"] = listener.Protocol;
|
|
25645
|
+
if (listener.SslPolicy !== void 0)
|
|
25646
|
+
result["SslPolicy"] = listener.SslPolicy;
|
|
25647
|
+
if (listener.Certificates && listener.Certificates.length > 0) {
|
|
25648
|
+
result["Certificates"] = listener.Certificates.map((c) => {
|
|
25649
|
+
const out = {};
|
|
25650
|
+
if (c.CertificateArn !== void 0)
|
|
25651
|
+
out["CertificateArn"] = c.CertificateArn;
|
|
25652
|
+
if (c.IsDefault !== void 0)
|
|
25653
|
+
out["IsDefault"] = c.IsDefault;
|
|
25654
|
+
return out;
|
|
25655
|
+
});
|
|
25656
|
+
}
|
|
25657
|
+
if (listener.DefaultActions && listener.DefaultActions.length > 0) {
|
|
25658
|
+
result["DefaultActions"] = listener.DefaultActions.map(
|
|
25659
|
+
(a) => a
|
|
25660
|
+
);
|
|
25661
|
+
}
|
|
25662
|
+
return result;
|
|
25663
|
+
}
|
|
24585
25664
|
/**
|
|
24586
25665
|
* Adopt an existing ELBv2 LoadBalancer or TargetGroup into cdkd state.
|
|
24587
25666
|
*
|
|
@@ -25589,6 +26668,7 @@ import {
|
|
|
25589
26668
|
ListQueryLoggingConfigsCommand,
|
|
25590
26669
|
ListHostedZonesByNameCommand as ListHostedZonesByNameCommand2,
|
|
25591
26670
|
ListHostedZonesCommand,
|
|
26671
|
+
ListResourceRecordSetsCommand,
|
|
25592
26672
|
ListTagsForResourceCommand as ListTagsForResourceCommand11
|
|
25593
26673
|
} from "@aws-sdk/client-route-53";
|
|
25594
26674
|
var Route53Provider = class {
|
|
@@ -26236,6 +27316,150 @@ var Route53Provider = class {
|
|
|
26236
27316
|
physicalId
|
|
26237
27317
|
);
|
|
26238
27318
|
}
|
|
27319
|
+
/**
|
|
27320
|
+
* Read the AWS-current Route 53 resource configuration in CFn-property shape.
|
|
27321
|
+
*
|
|
27322
|
+
* Dispatch per resource type:
|
|
27323
|
+
* - `HostedZone` → `GetHostedZone` (Name, HostedZoneConfig{Comment,
|
|
27324
|
+
* PrivateZone}, VPCs from `VPCs[]`). Tags are skipped (CDK auto-tag
|
|
27325
|
+
* handling deferred); QueryLoggingConfig is skipped because it's a
|
|
27326
|
+
* separate `ListQueryLoggingConfigs` call and the v1 surface does
|
|
27327
|
+
* not surface it.
|
|
27328
|
+
* - `RecordSet` → `ListResourceRecordSets` filtered to the exact
|
|
27329
|
+
* `(name, type)` pair from the composite physicalId
|
|
27330
|
+
* (`{zoneId}|{name}|{type}`). Surfaces TTL, ResourceRecords (with
|
|
27331
|
+
* `[{Value}]` -> string[] re-shape to match cdkd state), AliasTarget,
|
|
27332
|
+
* Weight, Region, Failover, MultiValueAnswer, HealthCheckId,
|
|
27333
|
+
* GeoLocation, SetIdentifier.
|
|
27334
|
+
*
|
|
27335
|
+
* Returns `undefined` when the parent zone is gone (`NoSuchHostedZone`).
|
|
27336
|
+
*/
|
|
27337
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
27338
|
+
switch (resourceType) {
|
|
27339
|
+
case "AWS::Route53::HostedZone":
|
|
27340
|
+
return this.readHostedZone(physicalId);
|
|
27341
|
+
case "AWS::Route53::RecordSet":
|
|
27342
|
+
return this.readRecordSet(physicalId);
|
|
27343
|
+
default:
|
|
27344
|
+
return void 0;
|
|
27345
|
+
}
|
|
27346
|
+
}
|
|
27347
|
+
async readHostedZone(physicalId) {
|
|
27348
|
+
let resp;
|
|
27349
|
+
try {
|
|
27350
|
+
resp = await this.getClient().send(new GetHostedZoneCommand2({ Id: physicalId }));
|
|
27351
|
+
} catch (err) {
|
|
27352
|
+
if (err instanceof Error && err.name === "NoSuchHostedZone")
|
|
27353
|
+
return void 0;
|
|
27354
|
+
throw err;
|
|
27355
|
+
}
|
|
27356
|
+
if (!resp.HostedZone)
|
|
27357
|
+
return void 0;
|
|
27358
|
+
const result = {};
|
|
27359
|
+
if (resp.HostedZone.Name !== void 0)
|
|
27360
|
+
result["Name"] = resp.HostedZone.Name;
|
|
27361
|
+
if (resp.HostedZone.Config) {
|
|
27362
|
+
const cfg = {};
|
|
27363
|
+
if (resp.HostedZone.Config.Comment !== void 0) {
|
|
27364
|
+
cfg["Comment"] = resp.HostedZone.Config.Comment;
|
|
27365
|
+
}
|
|
27366
|
+
if (resp.HostedZone.Config.PrivateZone !== void 0) {
|
|
27367
|
+
cfg["PrivateZone"] = resp.HostedZone.Config.PrivateZone;
|
|
27368
|
+
}
|
|
27369
|
+
if (Object.keys(cfg).length > 0)
|
|
27370
|
+
result["HostedZoneConfig"] = cfg;
|
|
27371
|
+
}
|
|
27372
|
+
if (resp.VPCs && resp.VPCs.length > 0) {
|
|
27373
|
+
result["VPCs"] = resp.VPCs.map((v) => {
|
|
27374
|
+
const out = {};
|
|
27375
|
+
if (v.VPCId !== void 0)
|
|
27376
|
+
out["VPCId"] = v.VPCId;
|
|
27377
|
+
if (v.VPCRegion !== void 0)
|
|
27378
|
+
out["VPCRegion"] = v.VPCRegion;
|
|
27379
|
+
return out;
|
|
27380
|
+
});
|
|
27381
|
+
}
|
|
27382
|
+
return result;
|
|
27383
|
+
}
|
|
27384
|
+
async readRecordSet(physicalId) {
|
|
27385
|
+
const parts = physicalId.split("|");
|
|
27386
|
+
if (parts.length < 3)
|
|
27387
|
+
return void 0;
|
|
27388
|
+
const [hostedZoneId, name, type] = parts;
|
|
27389
|
+
if (!hostedZoneId || !name || !type)
|
|
27390
|
+
return void 0;
|
|
27391
|
+
let resp;
|
|
27392
|
+
try {
|
|
27393
|
+
resp = await this.getClient().send(
|
|
27394
|
+
new ListResourceRecordSetsCommand({
|
|
27395
|
+
HostedZoneId: hostedZoneId,
|
|
27396
|
+
StartRecordName: name,
|
|
27397
|
+
StartRecordType: type,
|
|
27398
|
+
MaxItems: 1
|
|
27399
|
+
})
|
|
27400
|
+
);
|
|
27401
|
+
} catch (err) {
|
|
27402
|
+
if (err instanceof Error && err.name === "NoSuchHostedZone")
|
|
27403
|
+
return void 0;
|
|
27404
|
+
throw err;
|
|
27405
|
+
}
|
|
27406
|
+
const recordSet = resp.ResourceRecordSets?.find((r) => r.Name === name && r.Type === type);
|
|
27407
|
+
if (!recordSet)
|
|
27408
|
+
return void 0;
|
|
27409
|
+
const result = {
|
|
27410
|
+
HostedZoneId: hostedZoneId,
|
|
27411
|
+
Name: name,
|
|
27412
|
+
Type: type
|
|
27413
|
+
};
|
|
27414
|
+
if (recordSet.TTL !== void 0)
|
|
27415
|
+
result["TTL"] = recordSet.TTL;
|
|
27416
|
+
if (recordSet.ResourceRecords && recordSet.ResourceRecords.length > 0) {
|
|
27417
|
+
result["ResourceRecords"] = recordSet.ResourceRecords.map((r) => r.Value).filter(
|
|
27418
|
+
(v) => typeof v === "string"
|
|
27419
|
+
);
|
|
27420
|
+
}
|
|
27421
|
+
if (recordSet.AliasTarget) {
|
|
27422
|
+
const at = {};
|
|
27423
|
+
if (recordSet.AliasTarget.HostedZoneId !== void 0) {
|
|
27424
|
+
at["HostedZoneId"] = recordSet.AliasTarget.HostedZoneId;
|
|
27425
|
+
}
|
|
27426
|
+
if (recordSet.AliasTarget.DNSName !== void 0) {
|
|
27427
|
+
at["DNSName"] = recordSet.AliasTarget.DNSName;
|
|
27428
|
+
}
|
|
27429
|
+
if (recordSet.AliasTarget.EvaluateTargetHealth !== void 0) {
|
|
27430
|
+
at["EvaluateTargetHealth"] = recordSet.AliasTarget.EvaluateTargetHealth;
|
|
27431
|
+
}
|
|
27432
|
+
result["AliasTarget"] = at;
|
|
27433
|
+
}
|
|
27434
|
+
if (recordSet.SetIdentifier !== void 0)
|
|
27435
|
+
result["SetIdentifier"] = recordSet.SetIdentifier;
|
|
27436
|
+
if (recordSet.Weight !== void 0)
|
|
27437
|
+
result["Weight"] = recordSet.Weight;
|
|
27438
|
+
if (recordSet.Region !== void 0)
|
|
27439
|
+
result["Region"] = recordSet.Region;
|
|
27440
|
+
if (recordSet.Failover !== void 0)
|
|
27441
|
+
result["Failover"] = recordSet.Failover;
|
|
27442
|
+
if (recordSet.MultiValueAnswer !== void 0) {
|
|
27443
|
+
result["MultiValueAnswer"] = recordSet.MultiValueAnswer;
|
|
27444
|
+
}
|
|
27445
|
+
if (recordSet.HealthCheckId !== void 0)
|
|
27446
|
+
result["HealthCheckId"] = recordSet.HealthCheckId;
|
|
27447
|
+
if (recordSet.GeoLocation) {
|
|
27448
|
+
const geo = {};
|
|
27449
|
+
if (recordSet.GeoLocation.ContinentCode !== void 0) {
|
|
27450
|
+
geo["ContinentCode"] = recordSet.GeoLocation.ContinentCode;
|
|
27451
|
+
}
|
|
27452
|
+
if (recordSet.GeoLocation.CountryCode !== void 0) {
|
|
27453
|
+
geo["CountryCode"] = recordSet.GeoLocation.CountryCode;
|
|
27454
|
+
}
|
|
27455
|
+
if (recordSet.GeoLocation.SubdivisionCode !== void 0) {
|
|
27456
|
+
geo["SubdivisionCode"] = recordSet.GeoLocation.SubdivisionCode;
|
|
27457
|
+
}
|
|
27458
|
+
if (Object.keys(geo).length > 0)
|
|
27459
|
+
result["GeoLocation"] = geo;
|
|
27460
|
+
}
|
|
27461
|
+
return result;
|
|
27462
|
+
}
|
|
26239
27463
|
/**
|
|
26240
27464
|
* Adopt an existing Route 53 resource into cdkd state.
|
|
26241
27465
|
*
|
|
@@ -26525,33 +27749,102 @@ var WAFv2WebACLProvider = class {
|
|
|
26525
27749
|
}
|
|
26526
27750
|
}
|
|
26527
27751
|
/**
|
|
26528
|
-
*
|
|
27752
|
+
* Read the AWS-current WAFv2 WebACL configuration in CFn-property shape.
|
|
26529
27753
|
*
|
|
26530
|
-
*
|
|
26531
|
-
*
|
|
26532
|
-
*
|
|
26533
|
-
*
|
|
26534
|
-
*
|
|
26535
|
-
*
|
|
27754
|
+
* The cdkd physicalId is the WebACL ARN; we parse it back to
|
|
27755
|
+
* `(id, name, scope)` and call `GetWebACL`. The response holds Name,
|
|
27756
|
+
* Description, DefaultAction, Rules, VisibilityConfig,
|
|
27757
|
+
* CustomResponseBodies, CaptchaConfig, ChallengeConfig, TokenDomains,
|
|
27758
|
+
* and AssociationConfig — every key cdkd state declares as
|
|
27759
|
+
* `handledProperties`. `Scope` is recovered from the ARN parse.
|
|
26536
27760
|
*
|
|
26537
|
-
*
|
|
26538
|
-
*
|
|
27761
|
+
* Tags are skipped (CDK auto-tag handling deferred). Returns `undefined`
|
|
27762
|
+
* when the ARN can't be parsed or the WebACL is gone
|
|
27763
|
+
* (`WAFNonexistentItemException`).
|
|
26539
27764
|
*/
|
|
26540
|
-
async
|
|
26541
|
-
|
|
26542
|
-
|
|
26543
|
-
|
|
26544
|
-
|
|
26545
|
-
|
|
26546
|
-
|
|
26547
|
-
|
|
26548
|
-
return null;
|
|
26549
|
-
throw err;
|
|
26550
|
-
}
|
|
27765
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
27766
|
+
let id;
|
|
27767
|
+
let name;
|
|
27768
|
+
let scope;
|
|
27769
|
+
try {
|
|
27770
|
+
({ id, name, scope } = parseWebACLArn(physicalId));
|
|
27771
|
+
} catch {
|
|
27772
|
+
return void 0;
|
|
26551
27773
|
}
|
|
26552
|
-
|
|
26553
|
-
|
|
26554
|
-
|
|
27774
|
+
let webACL;
|
|
27775
|
+
try {
|
|
27776
|
+
const resp = await this.getClient().send(
|
|
27777
|
+
new GetWebACLCommand({ Id: id, Name: name, Scope: scope })
|
|
27778
|
+
);
|
|
27779
|
+
webACL = resp.WebACL;
|
|
27780
|
+
} catch (err) {
|
|
27781
|
+
if (err instanceof WAFNonexistentItemException)
|
|
27782
|
+
return void 0;
|
|
27783
|
+
throw err;
|
|
27784
|
+
}
|
|
27785
|
+
if (!webACL)
|
|
27786
|
+
return void 0;
|
|
27787
|
+
const result = {};
|
|
27788
|
+
if (webACL.Name !== void 0)
|
|
27789
|
+
result["Name"] = webACL.Name;
|
|
27790
|
+
result["Scope"] = scope;
|
|
27791
|
+
if (webACL.Description !== void 0 && webACL.Description !== "") {
|
|
27792
|
+
result["Description"] = webACL.Description;
|
|
27793
|
+
}
|
|
27794
|
+
if (webACL.DefaultAction) {
|
|
27795
|
+
result["DefaultAction"] = webACL.DefaultAction;
|
|
27796
|
+
}
|
|
27797
|
+
if (webACL.Rules && webACL.Rules.length > 0) {
|
|
27798
|
+
result["Rules"] = webACL.Rules.map((r) => r);
|
|
27799
|
+
}
|
|
27800
|
+
if (webACL.VisibilityConfig) {
|
|
27801
|
+
result["VisibilityConfig"] = webACL.VisibilityConfig;
|
|
27802
|
+
}
|
|
27803
|
+
if (webACL.CustomResponseBodies && Object.keys(webACL.CustomResponseBodies).length > 0) {
|
|
27804
|
+
result["CustomResponseBodies"] = webACL.CustomResponseBodies;
|
|
27805
|
+
}
|
|
27806
|
+
if (webACL.CaptchaConfig) {
|
|
27807
|
+
result["CaptchaConfig"] = webACL.CaptchaConfig;
|
|
27808
|
+
}
|
|
27809
|
+
if (webACL.ChallengeConfig) {
|
|
27810
|
+
result["ChallengeConfig"] = webACL.ChallengeConfig;
|
|
27811
|
+
}
|
|
27812
|
+
if (webACL.TokenDomains && webACL.TokenDomains.length > 0) {
|
|
27813
|
+
result["TokenDomains"] = [...webACL.TokenDomains];
|
|
27814
|
+
}
|
|
27815
|
+
if (webACL.AssociationConfig) {
|
|
27816
|
+
result["AssociationConfig"] = webACL.AssociationConfig;
|
|
27817
|
+
}
|
|
27818
|
+
return result;
|
|
27819
|
+
}
|
|
27820
|
+
/**
|
|
27821
|
+
* Adopt an existing WAFv2 WebACL into cdkd state.
|
|
27822
|
+
*
|
|
27823
|
+
* Lookup order:
|
|
27824
|
+
* 1. `--resource <id>=<arn>` override → verify with `GetWebACL` (parses
|
|
27825
|
+
* Name/Id/Scope back out of the ARN).
|
|
27826
|
+
* 2. Walk `ListWebACLs(Scope)` → match `aws:cdk:path` via
|
|
27827
|
+
* `ListTagsForResource(ResourceARN)` (returns
|
|
27828
|
+
* `TagInfoForResource.TagList`, standard `Key`/`Value` shape).
|
|
27829
|
+
*
|
|
27830
|
+
* `Scope` is required by `ListWebACLs` — read from
|
|
27831
|
+
* `Properties.Scope` (`REGIONAL` is the default).
|
|
27832
|
+
*/
|
|
27833
|
+
async import(input) {
|
|
27834
|
+
if (input.knownPhysicalId) {
|
|
27835
|
+
try {
|
|
27836
|
+
const { id, name, scope: scope2 } = parseWebACLArn(input.knownPhysicalId);
|
|
27837
|
+
await this.getClient().send(new GetWebACLCommand({ Id: id, Name: name, Scope: scope2 }));
|
|
27838
|
+
return { physicalId: input.knownPhysicalId, attributes: {} };
|
|
27839
|
+
} catch (err) {
|
|
27840
|
+
if (err instanceof WAFNonexistentItemException)
|
|
27841
|
+
return null;
|
|
27842
|
+
throw err;
|
|
27843
|
+
}
|
|
27844
|
+
}
|
|
27845
|
+
if (!input.cdkPath)
|
|
27846
|
+
return null;
|
|
27847
|
+
const scope = input.properties["Scope"] || "REGIONAL";
|
|
26555
27848
|
let nextMarker;
|
|
26556
27849
|
do {
|
|
26557
27850
|
const list = await this.getClient().send(
|
|
@@ -27496,6 +28789,133 @@ var ElastiCacheProvider = class {
|
|
|
27496
28789
|
sleep(ms) {
|
|
27497
28790
|
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
27498
28791
|
}
|
|
28792
|
+
/**
|
|
28793
|
+
* Read the AWS-current ElastiCache resource configuration in CFn-property shape.
|
|
28794
|
+
*
|
|
28795
|
+
* Dispatch per resource type:
|
|
28796
|
+
* - `CacheCluster` → `DescribeCacheClusters` filtered by `CacheClusterId`,
|
|
28797
|
+
* surfacing `Engine`, `CacheNodeType`, `NumCacheNodes`,
|
|
28798
|
+
* `CacheSubnetGroupName`, `Port`, `EngineVersion`,
|
|
28799
|
+
* `CacheParameterGroupName`, `PreferredMaintenanceWindow`,
|
|
28800
|
+
* `PreferredAvailabilityZone`, `SnapshotRetentionLimit`,
|
|
28801
|
+
* `SnapshotWindow`, `AutoMinorVersionUpgrade`, `NotificationTopicArn`,
|
|
28802
|
+
* `IpDiscovery`, `NetworkType`, `TransitEncryptionEnabled`, plus
|
|
28803
|
+
* `VpcSecurityGroupIds` derived from the cluster's `SecurityGroups[]`.
|
|
28804
|
+
* - `SubnetGroup` → `DescribeCacheSubnetGroups` filtered by name,
|
|
28805
|
+
* surfacing `CacheSubnetGroupName`, `CacheSubnetGroupDescription`,
|
|
28806
|
+
* and `SubnetIds` derived from `Subnets[].SubnetIdentifier`.
|
|
28807
|
+
*
|
|
28808
|
+
* Tags are skipped (CDK auto-tag handling deferred). Returns `undefined`
|
|
28809
|
+
* when the resource is gone (`*NotFoundFault`).
|
|
28810
|
+
*/
|
|
28811
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
28812
|
+
switch (resourceType) {
|
|
28813
|
+
case "AWS::ElastiCache::CacheCluster":
|
|
28814
|
+
return this.readCacheCluster(physicalId);
|
|
28815
|
+
case "AWS::ElastiCache::SubnetGroup":
|
|
28816
|
+
return this.readSubnetGroup(physicalId);
|
|
28817
|
+
default:
|
|
28818
|
+
return void 0;
|
|
28819
|
+
}
|
|
28820
|
+
}
|
|
28821
|
+
async readCacheCluster(physicalId) {
|
|
28822
|
+
let cluster;
|
|
28823
|
+
try {
|
|
28824
|
+
const resp = await this.getClient().send(
|
|
28825
|
+
new DescribeCacheClustersCommand({
|
|
28826
|
+
CacheClusterId: physicalId,
|
|
28827
|
+
ShowCacheNodeInfo: true
|
|
28828
|
+
})
|
|
28829
|
+
);
|
|
28830
|
+
cluster = resp.CacheClusters?.[0];
|
|
28831
|
+
} catch (err) {
|
|
28832
|
+
if (this.isNotFoundError(err, "CacheClusterNotFoundFault"))
|
|
28833
|
+
return void 0;
|
|
28834
|
+
throw err;
|
|
28835
|
+
}
|
|
28836
|
+
if (!cluster)
|
|
28837
|
+
return void 0;
|
|
28838
|
+
const result = {};
|
|
28839
|
+
if (cluster.CacheClusterId !== void 0)
|
|
28840
|
+
result["ClusterName"] = cluster.CacheClusterId;
|
|
28841
|
+
if (cluster.Engine !== void 0)
|
|
28842
|
+
result["Engine"] = cluster.Engine;
|
|
28843
|
+
if (cluster.CacheNodeType !== void 0)
|
|
28844
|
+
result["CacheNodeType"] = cluster.CacheNodeType;
|
|
28845
|
+
if (cluster.NumCacheNodes !== void 0)
|
|
28846
|
+
result["NumCacheNodes"] = cluster.NumCacheNodes;
|
|
28847
|
+
if (cluster.CacheSubnetGroupName !== void 0) {
|
|
28848
|
+
result["CacheSubnetGroupName"] = cluster.CacheSubnetGroupName;
|
|
28849
|
+
}
|
|
28850
|
+
if (cluster.EngineVersion !== void 0)
|
|
28851
|
+
result["EngineVersion"] = cluster.EngineVersion;
|
|
28852
|
+
if (cluster.CacheParameterGroup?.CacheParameterGroupName !== void 0) {
|
|
28853
|
+
result["CacheParameterGroupName"] = cluster.CacheParameterGroup.CacheParameterGroupName;
|
|
28854
|
+
}
|
|
28855
|
+
if (cluster.PreferredMaintenanceWindow !== void 0) {
|
|
28856
|
+
result["PreferredMaintenanceWindow"] = cluster.PreferredMaintenanceWindow;
|
|
28857
|
+
}
|
|
28858
|
+
if (cluster.PreferredAvailabilityZone !== void 0) {
|
|
28859
|
+
result["PreferredAvailabilityZone"] = cluster.PreferredAvailabilityZone;
|
|
28860
|
+
}
|
|
28861
|
+
if (cluster.SnapshotRetentionLimit !== void 0) {
|
|
28862
|
+
result["SnapshotRetentionLimit"] = cluster.SnapshotRetentionLimit;
|
|
28863
|
+
}
|
|
28864
|
+
if (cluster.SnapshotWindow !== void 0)
|
|
28865
|
+
result["SnapshotWindow"] = cluster.SnapshotWindow;
|
|
28866
|
+
if (cluster.AutoMinorVersionUpgrade !== void 0) {
|
|
28867
|
+
result["AutoMinorVersionUpgrade"] = cluster.AutoMinorVersionUpgrade;
|
|
28868
|
+
}
|
|
28869
|
+
if (cluster.NotificationConfiguration?.TopicArn !== void 0) {
|
|
28870
|
+
result["NotificationTopicArn"] = cluster.NotificationConfiguration.TopicArn;
|
|
28871
|
+
}
|
|
28872
|
+
if (cluster.IpDiscovery !== void 0)
|
|
28873
|
+
result["IpDiscovery"] = cluster.IpDiscovery;
|
|
28874
|
+
if (cluster.NetworkType !== void 0)
|
|
28875
|
+
result["NetworkType"] = cluster.NetworkType;
|
|
28876
|
+
if (cluster.TransitEncryptionEnabled !== void 0) {
|
|
28877
|
+
result["TransitEncryptionEnabled"] = cluster.TransitEncryptionEnabled;
|
|
28878
|
+
}
|
|
28879
|
+
if (cluster.CacheNodes?.[0]?.Endpoint?.Port !== void 0) {
|
|
28880
|
+
result["Port"] = cluster.CacheNodes[0].Endpoint.Port;
|
|
28881
|
+
}
|
|
28882
|
+
if (cluster.SecurityGroups && cluster.SecurityGroups.length > 0) {
|
|
28883
|
+
const ids = cluster.SecurityGroups.map((sg) => sg.SecurityGroupId).filter(
|
|
28884
|
+
(id) => !!id
|
|
28885
|
+
);
|
|
28886
|
+
if (ids.length > 0)
|
|
28887
|
+
result["VpcSecurityGroupIds"] = ids;
|
|
28888
|
+
}
|
|
28889
|
+
return result;
|
|
28890
|
+
}
|
|
28891
|
+
async readSubnetGroup(physicalId) {
|
|
28892
|
+
let group;
|
|
28893
|
+
try {
|
|
28894
|
+
const resp = await this.getClient().send(
|
|
28895
|
+
new DescribeCacheSubnetGroupsCommand({ CacheSubnetGroupName: physicalId })
|
|
28896
|
+
);
|
|
28897
|
+
group = resp.CacheSubnetGroups?.[0];
|
|
28898
|
+
} catch (err) {
|
|
28899
|
+
if (this.isNotFoundError(err, "CacheSubnetGroupNotFoundFault"))
|
|
28900
|
+
return void 0;
|
|
28901
|
+
throw err;
|
|
28902
|
+
}
|
|
28903
|
+
if (!group)
|
|
28904
|
+
return void 0;
|
|
28905
|
+
const result = {};
|
|
28906
|
+
if (group.CacheSubnetGroupName !== void 0) {
|
|
28907
|
+
result["CacheSubnetGroupName"] = group.CacheSubnetGroupName;
|
|
28908
|
+
}
|
|
28909
|
+
if (group.CacheSubnetGroupDescription !== void 0) {
|
|
28910
|
+
result["CacheSubnetGroupDescription"] = group.CacheSubnetGroupDescription;
|
|
28911
|
+
}
|
|
28912
|
+
if (group.Subnets && group.Subnets.length > 0) {
|
|
28913
|
+
const ids = group.Subnets.map((s) => s.SubnetIdentifier).filter((id) => !!id);
|
|
28914
|
+
if (ids.length > 0)
|
|
28915
|
+
result["SubnetIds"] = ids;
|
|
28916
|
+
}
|
|
28917
|
+
return result;
|
|
28918
|
+
}
|
|
27499
28919
|
/**
|
|
27500
28920
|
* Adopt an existing ElastiCache resource into cdkd state.
|
|
27501
28921
|
*
|
|
@@ -27968,6 +29388,87 @@ var ServiceDiscoveryProvider = class {
|
|
|
27968
29388
|
* - **AWS::ServiceDiscovery::Service**: same shape — `ListServices` +
|
|
27969
29389
|
* `ListTagsForResource`. Both use `Tag[]` arrays.
|
|
27970
29390
|
*/
|
|
29391
|
+
/**
|
|
29392
|
+
* Read the AWS-current ServiceDiscovery resource configuration in CFn-property shape.
|
|
29393
|
+
*
|
|
29394
|
+
* Dispatch per resource type:
|
|
29395
|
+
* - `PrivateDnsNamespace` → `GetNamespace` (Name, Description). `Vpc`
|
|
29396
|
+
* is NOT returned by `GetNamespace` — Cloud Map exposes the VPC only
|
|
29397
|
+
* at create time and via `ListNamespaces`-side `Properties.DnsProperties.HostedZoneId`,
|
|
29398
|
+
* not as a directly comparable VPC ID. We skip it; the comparator
|
|
29399
|
+
* only descends into keys present in cdkd state, so an absent key
|
|
29400
|
+
* cannot fire false drift, but a `Vpc` change will not be detected
|
|
29401
|
+
* via this provider's drift surface (use the CFn-side `aws cloudmap`
|
|
29402
|
+
* CLI for that edge case).
|
|
29403
|
+
* - `Service` → `GetService` (Name, NamespaceId, Description, Type,
|
|
29404
|
+
* DnsConfig, HealthCheckConfig, HealthCheckCustomConfig).
|
|
29405
|
+
*
|
|
29406
|
+
* Tags are skipped (CDK auto-tag handling deferred). Returns `undefined`
|
|
29407
|
+
* when the resource is gone (`NamespaceNotFound` / `ServiceNotFound`).
|
|
29408
|
+
*/
|
|
29409
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
29410
|
+
switch (resourceType) {
|
|
29411
|
+
case "AWS::ServiceDiscovery::PrivateDnsNamespace":
|
|
29412
|
+
return this.readNamespace(physicalId);
|
|
29413
|
+
case "AWS::ServiceDiscovery::Service":
|
|
29414
|
+
return this.readService(physicalId);
|
|
29415
|
+
default:
|
|
29416
|
+
return void 0;
|
|
29417
|
+
}
|
|
29418
|
+
}
|
|
29419
|
+
async readNamespace(physicalId) {
|
|
29420
|
+
let ns;
|
|
29421
|
+
try {
|
|
29422
|
+
const resp = await this.getClient().send(new GetNamespaceCommand({ Id: physicalId }));
|
|
29423
|
+
ns = resp.Namespace;
|
|
29424
|
+
} catch (err) {
|
|
29425
|
+
if (err instanceof NamespaceNotFound)
|
|
29426
|
+
return void 0;
|
|
29427
|
+
throw err;
|
|
29428
|
+
}
|
|
29429
|
+
if (!ns)
|
|
29430
|
+
return void 0;
|
|
29431
|
+
const result = {};
|
|
29432
|
+
if (ns.Name !== void 0)
|
|
29433
|
+
result["Name"] = ns.Name;
|
|
29434
|
+
if (ns.Description !== void 0 && ns.Description !== "") {
|
|
29435
|
+
result["Description"] = ns.Description;
|
|
29436
|
+
}
|
|
29437
|
+
return result;
|
|
29438
|
+
}
|
|
29439
|
+
async readService(physicalId) {
|
|
29440
|
+
let svc;
|
|
29441
|
+
try {
|
|
29442
|
+
const resp = await this.getClient().send(new GetServiceCommand({ Id: physicalId }));
|
|
29443
|
+
svc = resp.Service;
|
|
29444
|
+
} catch (err) {
|
|
29445
|
+
if (err instanceof ServiceNotFound)
|
|
29446
|
+
return void 0;
|
|
29447
|
+
throw err;
|
|
29448
|
+
}
|
|
29449
|
+
if (!svc)
|
|
29450
|
+
return void 0;
|
|
29451
|
+
const result = {};
|
|
29452
|
+
if (svc.Name !== void 0)
|
|
29453
|
+
result["Name"] = svc.Name;
|
|
29454
|
+
if (svc.NamespaceId !== void 0)
|
|
29455
|
+
result["NamespaceId"] = svc.NamespaceId;
|
|
29456
|
+
if (svc.Description !== void 0 && svc.Description !== "") {
|
|
29457
|
+
result["Description"] = svc.Description;
|
|
29458
|
+
}
|
|
29459
|
+
if (svc.Type !== void 0)
|
|
29460
|
+
result["Type"] = svc.Type;
|
|
29461
|
+
if (svc.DnsConfig) {
|
|
29462
|
+
result["DnsConfig"] = svc.DnsConfig;
|
|
29463
|
+
}
|
|
29464
|
+
if (svc.HealthCheckConfig) {
|
|
29465
|
+
result["HealthCheckConfig"] = svc.HealthCheckConfig;
|
|
29466
|
+
}
|
|
29467
|
+
if (svc.HealthCheckCustomConfig) {
|
|
29468
|
+
result["HealthCheckCustomConfig"] = svc.HealthCheckCustomConfig;
|
|
29469
|
+
}
|
|
29470
|
+
return result;
|
|
29471
|
+
}
|
|
27971
29472
|
async import(input) {
|
|
27972
29473
|
switch (input.resourceType) {
|
|
27973
29474
|
case "AWS::ServiceDiscovery::PrivateDnsNamespace":
|
|
@@ -28084,6 +29585,9 @@ import {
|
|
|
28084
29585
|
DeleteApiKeyCommand,
|
|
28085
29586
|
StartSchemaCreationCommand,
|
|
28086
29587
|
GetGraphqlApiCommand,
|
|
29588
|
+
GetDataSourceCommand,
|
|
29589
|
+
GetResolverCommand,
|
|
29590
|
+
ListApiKeysCommand,
|
|
28087
29591
|
ListGraphqlApisCommand,
|
|
28088
29592
|
NotFoundException as AppSyncNotFoundException
|
|
28089
29593
|
} from "@aws-sdk/client-appsync";
|
|
@@ -28593,6 +30097,209 @@ var AppSyncProvider = class {
|
|
|
28593
30097
|
const name = error.name ?? "";
|
|
28594
30098
|
return message.includes("not found") || message.includes("does not exist") || name === "NotFoundException";
|
|
28595
30099
|
}
|
|
30100
|
+
/**
|
|
30101
|
+
* Read the AWS-current AppSync resource configuration in CFn-property shape.
|
|
30102
|
+
*
|
|
30103
|
+
* Dispatches per resource type:
|
|
30104
|
+
* - `GraphQLApi` → `GetGraphqlApi` (Name, AuthenticationType, XrayEnabled,
|
|
30105
|
+
* LogConfig). Tags are skipped (CDK auto-tag handling deferred).
|
|
30106
|
+
* - `DataSource` → `GetDataSource` (Name, Type, Description,
|
|
30107
|
+
* ServiceRoleArn, DynamoDBConfig, LambdaConfig, HttpConfig). The
|
|
30108
|
+
* `ApiId` cdkd holds is recovered from the `apiId|name` physicalId.
|
|
30109
|
+
* - `Resolver` → `GetResolver` (TypeName, FieldName, DataSourceName,
|
|
30110
|
+
* request/response templates, Kind, PipelineConfig, Runtime, Code).
|
|
30111
|
+
* - `ApiKey` → `ListApiKeys` filtered by id (no `GetApiKey` SDK call;
|
|
30112
|
+
* AppSync only exposes list-based access). Surfaces Description and
|
|
30113
|
+
* Expires.
|
|
30114
|
+
* - `GraphQLSchema` → `GetSchemaCreationStatus` is the closest live
|
|
30115
|
+
* state, but it returns a status string only (not the full schema
|
|
30116
|
+
* body). Schema bodies live in cdkd state's `Definition` and would
|
|
30117
|
+
* need `GetIntrospectionSchema` + reverse-mapping to compare; that's
|
|
30118
|
+
* a separate task. Returns `undefined` so the comparator marks it
|
|
30119
|
+
* as "drift unknown" rather than firing a false positive.
|
|
30120
|
+
*
|
|
30121
|
+
* Returns `undefined` when the parent resource is gone (`NotFoundException`).
|
|
30122
|
+
*/
|
|
30123
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
30124
|
+
switch (resourceType) {
|
|
30125
|
+
case "AWS::AppSync::GraphQLApi":
|
|
30126
|
+
return this.readGraphQLApi(physicalId);
|
|
30127
|
+
case "AWS::AppSync::DataSource":
|
|
30128
|
+
return this.readDataSource(physicalId);
|
|
30129
|
+
case "AWS::AppSync::Resolver":
|
|
30130
|
+
return this.readResolver(physicalId);
|
|
30131
|
+
case "AWS::AppSync::ApiKey":
|
|
30132
|
+
return this.readApiKey(physicalId);
|
|
30133
|
+
case "AWS::AppSync::GraphQLSchema":
|
|
30134
|
+
return void 0;
|
|
30135
|
+
default:
|
|
30136
|
+
return void 0;
|
|
30137
|
+
}
|
|
30138
|
+
}
|
|
30139
|
+
async readGraphQLApi(physicalId) {
|
|
30140
|
+
let api;
|
|
30141
|
+
try {
|
|
30142
|
+
const resp = await this.getClient().send(new GetGraphqlApiCommand({ apiId: physicalId }));
|
|
30143
|
+
api = resp.graphqlApi;
|
|
30144
|
+
} catch (err) {
|
|
30145
|
+
if (err instanceof AppSyncNotFoundException)
|
|
30146
|
+
return void 0;
|
|
30147
|
+
throw err;
|
|
30148
|
+
}
|
|
30149
|
+
if (!api)
|
|
30150
|
+
return void 0;
|
|
30151
|
+
const result = {};
|
|
30152
|
+
if (api.name !== void 0)
|
|
30153
|
+
result["Name"] = api.name;
|
|
30154
|
+
if (api.authenticationType !== void 0) {
|
|
30155
|
+
result["AuthenticationType"] = api.authenticationType;
|
|
30156
|
+
}
|
|
30157
|
+
if (api.xrayEnabled !== void 0)
|
|
30158
|
+
result["XrayEnabled"] = api.xrayEnabled;
|
|
30159
|
+
if (api.logConfig) {
|
|
30160
|
+
const log = {};
|
|
30161
|
+
if (api.logConfig.cloudWatchLogsRoleArn !== void 0) {
|
|
30162
|
+
log["CloudWatchLogsRoleArn"] = api.logConfig.cloudWatchLogsRoleArn;
|
|
30163
|
+
}
|
|
30164
|
+
if (api.logConfig.fieldLogLevel !== void 0) {
|
|
30165
|
+
log["FieldLogLevel"] = api.logConfig.fieldLogLevel;
|
|
30166
|
+
}
|
|
30167
|
+
if (api.logConfig.excludeVerboseContent !== void 0) {
|
|
30168
|
+
log["ExcludeVerboseContent"] = api.logConfig.excludeVerboseContent;
|
|
30169
|
+
}
|
|
30170
|
+
if (Object.keys(log).length > 0)
|
|
30171
|
+
result["LogConfig"] = log;
|
|
30172
|
+
}
|
|
30173
|
+
return result;
|
|
30174
|
+
}
|
|
30175
|
+
async readDataSource(physicalId) {
|
|
30176
|
+
const [apiId, name] = physicalId.split("|");
|
|
30177
|
+
if (!apiId || !name)
|
|
30178
|
+
return void 0;
|
|
30179
|
+
let ds;
|
|
30180
|
+
try {
|
|
30181
|
+
const resp = await this.getClient().send(new GetDataSourceCommand({ apiId, name }));
|
|
30182
|
+
ds = resp.dataSource;
|
|
30183
|
+
} catch (err) {
|
|
30184
|
+
if (err instanceof AppSyncNotFoundException)
|
|
30185
|
+
return void 0;
|
|
30186
|
+
throw err;
|
|
30187
|
+
}
|
|
30188
|
+
if (!ds)
|
|
30189
|
+
return void 0;
|
|
30190
|
+
const result = { ApiId: apiId };
|
|
30191
|
+
if (ds.name !== void 0)
|
|
30192
|
+
result["Name"] = ds.name;
|
|
30193
|
+
if (ds.type !== void 0)
|
|
30194
|
+
result["Type"] = ds.type;
|
|
30195
|
+
if (ds.description !== void 0 && ds.description !== "") {
|
|
30196
|
+
result["Description"] = ds.description;
|
|
30197
|
+
}
|
|
30198
|
+
if (ds.serviceRoleArn !== void 0)
|
|
30199
|
+
result["ServiceRoleArn"] = ds.serviceRoleArn;
|
|
30200
|
+
if (ds.dynamodbConfig) {
|
|
30201
|
+
const dynamo = {};
|
|
30202
|
+
if (ds.dynamodbConfig.tableName !== void 0)
|
|
30203
|
+
dynamo["TableName"] = ds.dynamodbConfig.tableName;
|
|
30204
|
+
if (ds.dynamodbConfig.awsRegion !== void 0)
|
|
30205
|
+
dynamo["AwsRegion"] = ds.dynamodbConfig.awsRegion;
|
|
30206
|
+
if (ds.dynamodbConfig.useCallerCredentials !== void 0) {
|
|
30207
|
+
dynamo["UseCallerCredentials"] = ds.dynamodbConfig.useCallerCredentials;
|
|
30208
|
+
}
|
|
30209
|
+
if (Object.keys(dynamo).length > 0)
|
|
30210
|
+
result["DynamoDBConfig"] = dynamo;
|
|
30211
|
+
}
|
|
30212
|
+
if (ds.lambdaConfig?.lambdaFunctionArn !== void 0) {
|
|
30213
|
+
result["LambdaConfig"] = { LambdaFunctionArn: ds.lambdaConfig.lambdaFunctionArn };
|
|
30214
|
+
}
|
|
30215
|
+
if (ds.httpConfig?.endpoint !== void 0) {
|
|
30216
|
+
result["HttpConfig"] = { Endpoint: ds.httpConfig.endpoint };
|
|
30217
|
+
}
|
|
30218
|
+
return result;
|
|
30219
|
+
}
|
|
30220
|
+
async readResolver(physicalId) {
|
|
30221
|
+
const parts = physicalId.split("|");
|
|
30222
|
+
if (parts.length < 3)
|
|
30223
|
+
return void 0;
|
|
30224
|
+
const [apiId, typeName, fieldName] = parts;
|
|
30225
|
+
if (!apiId || !typeName || !fieldName)
|
|
30226
|
+
return void 0;
|
|
30227
|
+
let resolver;
|
|
30228
|
+
try {
|
|
30229
|
+
const resp = await this.getClient().send(
|
|
30230
|
+
new GetResolverCommand({ apiId, typeName, fieldName })
|
|
30231
|
+
);
|
|
30232
|
+
resolver = resp.resolver;
|
|
30233
|
+
} catch (err) {
|
|
30234
|
+
if (err instanceof AppSyncNotFoundException)
|
|
30235
|
+
return void 0;
|
|
30236
|
+
throw err;
|
|
30237
|
+
}
|
|
30238
|
+
if (!resolver)
|
|
30239
|
+
return void 0;
|
|
30240
|
+
const result = { ApiId: apiId };
|
|
30241
|
+
if (resolver.typeName !== void 0)
|
|
30242
|
+
result["TypeName"] = resolver.typeName;
|
|
30243
|
+
if (resolver.fieldName !== void 0)
|
|
30244
|
+
result["FieldName"] = resolver.fieldName;
|
|
30245
|
+
if (resolver.dataSourceName !== void 0)
|
|
30246
|
+
result["DataSourceName"] = resolver.dataSourceName;
|
|
30247
|
+
if (resolver.requestMappingTemplate !== void 0) {
|
|
30248
|
+
result["RequestMappingTemplate"] = resolver.requestMappingTemplate;
|
|
30249
|
+
}
|
|
30250
|
+
if (resolver.responseMappingTemplate !== void 0) {
|
|
30251
|
+
result["ResponseMappingTemplate"] = resolver.responseMappingTemplate;
|
|
30252
|
+
}
|
|
30253
|
+
if (resolver.kind !== void 0)
|
|
30254
|
+
result["Kind"] = resolver.kind;
|
|
30255
|
+
if (resolver.pipelineConfig?.functions && resolver.pipelineConfig.functions.length > 0) {
|
|
30256
|
+
result["PipelineConfig"] = { Functions: [...resolver.pipelineConfig.functions] };
|
|
30257
|
+
}
|
|
30258
|
+
if (resolver.runtime) {
|
|
30259
|
+
const runtime = {};
|
|
30260
|
+
if (resolver.runtime.name !== void 0)
|
|
30261
|
+
runtime["Name"] = resolver.runtime.name;
|
|
30262
|
+
if (resolver.runtime.runtimeVersion !== void 0) {
|
|
30263
|
+
runtime["RuntimeVersion"] = resolver.runtime.runtimeVersion;
|
|
30264
|
+
}
|
|
30265
|
+
if (Object.keys(runtime).length > 0)
|
|
30266
|
+
result["Runtime"] = runtime;
|
|
30267
|
+
}
|
|
30268
|
+
if (resolver.code !== void 0)
|
|
30269
|
+
result["Code"] = resolver.code;
|
|
30270
|
+
return result;
|
|
30271
|
+
}
|
|
30272
|
+
async readApiKey(physicalId) {
|
|
30273
|
+
const [apiId, apiKeyId] = physicalId.split("|");
|
|
30274
|
+
if (!apiId || !apiKeyId)
|
|
30275
|
+
return void 0;
|
|
30276
|
+
let nextToken;
|
|
30277
|
+
do {
|
|
30278
|
+
let resp;
|
|
30279
|
+
try {
|
|
30280
|
+
resp = await this.getClient().send(
|
|
30281
|
+
new ListApiKeysCommand({ apiId, ...nextToken && { nextToken } })
|
|
30282
|
+
);
|
|
30283
|
+
} catch (err) {
|
|
30284
|
+
if (err instanceof AppSyncNotFoundException)
|
|
30285
|
+
return void 0;
|
|
30286
|
+
throw err;
|
|
30287
|
+
}
|
|
30288
|
+
for (const key of resp.apiKeys ?? []) {
|
|
30289
|
+
if (key.id === apiKeyId) {
|
|
30290
|
+
const result = { ApiId: apiId };
|
|
30291
|
+
if (key.description !== void 0 && key.description !== "") {
|
|
30292
|
+
result["Description"] = key.description;
|
|
30293
|
+
}
|
|
30294
|
+
if (key.expires !== void 0)
|
|
30295
|
+
result["Expires"] = key.expires;
|
|
30296
|
+
return result;
|
|
30297
|
+
}
|
|
30298
|
+
}
|
|
30299
|
+
nextToken = resp.nextToken;
|
|
30300
|
+
} while (nextToken);
|
|
30301
|
+
return void 0;
|
|
30302
|
+
}
|
|
28596
30303
|
/**
|
|
28597
30304
|
* Adopt an existing AppSync resource into cdkd state.
|
|
28598
30305
|
*
|
|
@@ -29044,6 +30751,116 @@ var GlueProvider = class {
|
|
|
29044
30751
|
* Glue list APIs return only names — ARNs are constructed locally
|
|
29045
30752
|
* for the per-item GetTags call.
|
|
29046
30753
|
*/
|
|
30754
|
+
/**
|
|
30755
|
+
* Read the AWS-current Glue resource configuration in CFn-property shape.
|
|
30756
|
+
*
|
|
30757
|
+
* Dispatch per resource type:
|
|
30758
|
+
* - `Database` → `GetDatabase` returning DatabaseInput-shape
|
|
30759
|
+
* (`Name`, `Description`, `LocationUri`, `Parameters`).
|
|
30760
|
+
* - `Table` → `GetTable` returning the same-named TableInput-shape
|
|
30761
|
+
* fields (`Name`, `Description`, `Owner`, `Retention`, `TableType`,
|
|
30762
|
+
* `PartitionKeys`, `Parameters`, `StorageDescriptor`, `ViewOriginalText`,
|
|
30763
|
+
* `ViewExpandedText`, `TargetTable`). The table physicalId is
|
|
30764
|
+
* `databaseName|tableName`; we recover both from the split.
|
|
30765
|
+
*
|
|
30766
|
+
* `CatalogId` is intentionally not surfaced — `GetDatabase` /
|
|
30767
|
+
* `GetTable` do not echo it back, and cdkd state's `CatalogId` is
|
|
30768
|
+
* usually the AWS account id (defaulted by the API). Comparator only
|
|
30769
|
+
* descends into keys present in state, so an absent surface key cannot
|
|
30770
|
+
* fire false drift here.
|
|
30771
|
+
*
|
|
30772
|
+
* Returns `undefined` when the resource is gone (`EntityNotFoundException`).
|
|
30773
|
+
* Other Glue resource types (`Job`, `Crawler`, `Connection`, `Trigger`,
|
|
30774
|
+
* `Workflow`, `SecurityConfiguration`, etc.) are out of scope for v1 —
|
|
30775
|
+
* the provider's `create()` only handles Database/Table; CC API picks
|
|
30776
|
+
* up drift detection for the rest.
|
|
30777
|
+
*/
|
|
30778
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
30779
|
+
switch (resourceType) {
|
|
30780
|
+
case "AWS::Glue::Database":
|
|
30781
|
+
return this.readDatabase(physicalId);
|
|
30782
|
+
case "AWS::Glue::Table":
|
|
30783
|
+
return this.readTable(physicalId);
|
|
30784
|
+
default:
|
|
30785
|
+
return void 0;
|
|
30786
|
+
}
|
|
30787
|
+
}
|
|
30788
|
+
async readDatabase(physicalId) {
|
|
30789
|
+
let db;
|
|
30790
|
+
try {
|
|
30791
|
+
const resp = await this.getClient().send(new GetDatabaseCommand({ Name: physicalId }));
|
|
30792
|
+
db = resp.Database;
|
|
30793
|
+
} catch (err) {
|
|
30794
|
+
if (err instanceof EntityNotFoundException)
|
|
30795
|
+
return void 0;
|
|
30796
|
+
throw err;
|
|
30797
|
+
}
|
|
30798
|
+
if (!db)
|
|
30799
|
+
return void 0;
|
|
30800
|
+
const dbInput = {};
|
|
30801
|
+
if (db.Name !== void 0)
|
|
30802
|
+
dbInput["Name"] = db.Name;
|
|
30803
|
+
if (db.Description !== void 0 && db.Description !== "") {
|
|
30804
|
+
dbInput["Description"] = db.Description;
|
|
30805
|
+
}
|
|
30806
|
+
if (db.LocationUri !== void 0)
|
|
30807
|
+
dbInput["LocationUri"] = db.LocationUri;
|
|
30808
|
+
if (db.Parameters && Object.keys(db.Parameters).length > 0) {
|
|
30809
|
+
dbInput["Parameters"] = db.Parameters;
|
|
30810
|
+
}
|
|
30811
|
+
return { DatabaseInput: dbInput };
|
|
30812
|
+
}
|
|
30813
|
+
async readTable(physicalId) {
|
|
30814
|
+
const [databaseName, tableName] = physicalId.split("|");
|
|
30815
|
+
if (!databaseName || !tableName)
|
|
30816
|
+
return void 0;
|
|
30817
|
+
let table;
|
|
30818
|
+
try {
|
|
30819
|
+
const resp = await this.getClient().send(
|
|
30820
|
+
new GetTableCommand({ DatabaseName: databaseName, Name: tableName })
|
|
30821
|
+
);
|
|
30822
|
+
table = resp.Table;
|
|
30823
|
+
} catch (err) {
|
|
30824
|
+
if (err instanceof EntityNotFoundException)
|
|
30825
|
+
return void 0;
|
|
30826
|
+
throw err;
|
|
30827
|
+
}
|
|
30828
|
+
if (!table)
|
|
30829
|
+
return void 0;
|
|
30830
|
+
const tableInput = {};
|
|
30831
|
+
if (table.Name !== void 0)
|
|
30832
|
+
tableInput["Name"] = table.Name;
|
|
30833
|
+
if (table.Description !== void 0 && table.Description !== "") {
|
|
30834
|
+
tableInput["Description"] = table.Description;
|
|
30835
|
+
}
|
|
30836
|
+
if (table.Owner !== void 0)
|
|
30837
|
+
tableInput["Owner"] = table.Owner;
|
|
30838
|
+
if (table.Retention !== void 0)
|
|
30839
|
+
tableInput["Retention"] = table.Retention;
|
|
30840
|
+
if (table.TableType !== void 0)
|
|
30841
|
+
tableInput["TableType"] = table.TableType;
|
|
30842
|
+
if (table.PartitionKeys && table.PartitionKeys.length > 0) {
|
|
30843
|
+
tableInput["PartitionKeys"] = table.PartitionKeys.map(
|
|
30844
|
+
(k) => k
|
|
30845
|
+
);
|
|
30846
|
+
}
|
|
30847
|
+
if (table.Parameters && Object.keys(table.Parameters).length > 0) {
|
|
30848
|
+
tableInput["Parameters"] = table.Parameters;
|
|
30849
|
+
}
|
|
30850
|
+
if (table.StorageDescriptor) {
|
|
30851
|
+
tableInput["StorageDescriptor"] = table.StorageDescriptor;
|
|
30852
|
+
}
|
|
30853
|
+
if (table.ViewOriginalText !== void 0) {
|
|
30854
|
+
tableInput["ViewOriginalText"] = table.ViewOriginalText;
|
|
30855
|
+
}
|
|
30856
|
+
if (table.ViewExpandedText !== void 0) {
|
|
30857
|
+
tableInput["ViewExpandedText"] = table.ViewExpandedText;
|
|
30858
|
+
}
|
|
30859
|
+
if (table.TargetTable) {
|
|
30860
|
+
tableInput["TargetTable"] = table.TargetTable;
|
|
30861
|
+
}
|
|
30862
|
+
return { DatabaseName: databaseName, TableInput: tableInput };
|
|
30863
|
+
}
|
|
29047
30864
|
async import(input) {
|
|
29048
30865
|
switch (input.resourceType) {
|
|
29049
30866
|
case "AWS::Glue::Database":
|
|
@@ -30020,6 +31837,57 @@ var KinesisStreamProvider = class {
|
|
|
30020
31837
|
* Kinesis tags use the standard `Tag[]` array shape (`Key`/`Value`),
|
|
30021
31838
|
* so `matchesCdkPath` from import-helpers applies directly.
|
|
30022
31839
|
*/
|
|
31840
|
+
/**
|
|
31841
|
+
* Read the AWS-current Kinesis stream configuration in CFn-property shape.
|
|
31842
|
+
*
|
|
31843
|
+
* Issues `DescribeStream` and surfaces the keys cdkd's `create()`
|
|
31844
|
+
* accepts: `Name`, `StreamModeDetails`, `ShardCount`, `RetentionPeriodHours`,
|
|
31845
|
+
* and `StreamEncryption`. Tags are skipped (CDK auto-tag handling deferred).
|
|
31846
|
+
*
|
|
31847
|
+
* `ShardCount` is reported as the count of `Shards[]` in the stream
|
|
31848
|
+
* description (only present for PROVISIONED-mode streams; ON_DEMAND
|
|
31849
|
+
* mode reports an empty list).
|
|
31850
|
+
*
|
|
31851
|
+
* Returns `undefined` when the stream is gone (`ResourceNotFoundException`).
|
|
31852
|
+
* Only `AWS::Kinesis::Stream` is supported (the provider does not handle
|
|
31853
|
+
* `AWS::Kinesis::StreamConsumer`).
|
|
31854
|
+
*/
|
|
31855
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
31856
|
+
if (resourceType !== "AWS::Kinesis::Stream")
|
|
31857
|
+
return void 0;
|
|
31858
|
+
let stream;
|
|
31859
|
+
try {
|
|
31860
|
+
const resp = await this.getClient().send(
|
|
31861
|
+
new DescribeStreamCommand({ StreamName: physicalId })
|
|
31862
|
+
);
|
|
31863
|
+
stream = resp.StreamDescription;
|
|
31864
|
+
} catch (err) {
|
|
31865
|
+
if (err instanceof ResourceNotFoundException13)
|
|
31866
|
+
return void 0;
|
|
31867
|
+
throw err;
|
|
31868
|
+
}
|
|
31869
|
+
if (!stream)
|
|
31870
|
+
return void 0;
|
|
31871
|
+
const result = {};
|
|
31872
|
+
if (stream.StreamName !== void 0)
|
|
31873
|
+
result["Name"] = stream.StreamName;
|
|
31874
|
+
if (stream.StreamModeDetails?.StreamMode !== void 0) {
|
|
31875
|
+
result["StreamModeDetails"] = { StreamMode: stream.StreamModeDetails.StreamMode };
|
|
31876
|
+
}
|
|
31877
|
+
if (stream.Shards && stream.Shards.length > 0) {
|
|
31878
|
+
result["ShardCount"] = stream.Shards.length;
|
|
31879
|
+
}
|
|
31880
|
+
if (stream.RetentionPeriodHours !== void 0) {
|
|
31881
|
+
result["RetentionPeriodHours"] = stream.RetentionPeriodHours;
|
|
31882
|
+
}
|
|
31883
|
+
if (stream.EncryptionType !== void 0 && stream.EncryptionType !== "NONE") {
|
|
31884
|
+
const encryption = { EncryptionType: stream.EncryptionType };
|
|
31885
|
+
if (stream.KeyId !== void 0)
|
|
31886
|
+
encryption["KeyId"] = stream.KeyId;
|
|
31887
|
+
result["StreamEncryption"] = encryption;
|
|
31888
|
+
}
|
|
31889
|
+
return result;
|
|
31890
|
+
}
|
|
30023
31891
|
async import(input) {
|
|
30024
31892
|
const explicit = resolveExplicitPhysicalId(input, "Name");
|
|
30025
31893
|
if (explicit) {
|
|
@@ -30099,6 +31967,8 @@ import {
|
|
|
30099
31967
|
DeleteAccessPointCommand,
|
|
30100
31968
|
DescribeFileSystemsCommand,
|
|
30101
31969
|
DescribeAccessPointsCommand,
|
|
31970
|
+
DescribeLifecycleConfigurationCommand,
|
|
31971
|
+
DescribeBackupPolicyCommand,
|
|
30102
31972
|
FileSystemNotFound,
|
|
30103
31973
|
MountTargetNotFound,
|
|
30104
31974
|
AccessPointNotFound
|
|
@@ -30500,6 +32370,173 @@ var EFSProvider = class {
|
|
|
30500
32370
|
);
|
|
30501
32371
|
}
|
|
30502
32372
|
}
|
|
32373
|
+
/**
|
|
32374
|
+
* Read the AWS-current EFS resource configuration in CFn-property shape.
|
|
32375
|
+
*
|
|
32376
|
+
* Dispatch per resource type:
|
|
32377
|
+
* - `FileSystem` → `DescribeFileSystems` filtered by id (PerformanceMode,
|
|
32378
|
+
* ThroughputMode, Encrypted, KmsKeyId, ProvisionedThroughputInMibps),
|
|
32379
|
+
* plus optional `DescribeLifecycleConfiguration` and
|
|
32380
|
+
* `DescribeBackupPolicy` enrichment. Each enrichment call is wrapped
|
|
32381
|
+
* in its own try/catch so a "not configured" error on either omits
|
|
32382
|
+
* the corresponding key without failing the whole snapshot.
|
|
32383
|
+
* - `AccessPoint` → `DescribeAccessPoints` filtered by id (PosixUser,
|
|
32384
|
+
* RootDirectory).
|
|
32385
|
+
* - `MountTarget` → `DescribeMountTargets` (FileSystemId, SubnetId).
|
|
32386
|
+
* SecurityGroups requires a separate call and is omitted for v1.
|
|
32387
|
+
*
|
|
32388
|
+
* Tags are skipped across all three (CDK auto-tag handling deferred).
|
|
32389
|
+
* Returns `undefined` when the resource is gone (`*NotFound`).
|
|
32390
|
+
*/
|
|
32391
|
+
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
32392
|
+
switch (resourceType) {
|
|
32393
|
+
case "AWS::EFS::FileSystem":
|
|
32394
|
+
return this.readFileSystem(physicalId);
|
|
32395
|
+
case "AWS::EFS::AccessPoint":
|
|
32396
|
+
return this.readAccessPoint(physicalId);
|
|
32397
|
+
case "AWS::EFS::MountTarget":
|
|
32398
|
+
return this.readMountTarget(physicalId);
|
|
32399
|
+
default:
|
|
32400
|
+
return void 0;
|
|
32401
|
+
}
|
|
32402
|
+
}
|
|
32403
|
+
async readFileSystem(physicalId) {
|
|
32404
|
+
let fs;
|
|
32405
|
+
try {
|
|
32406
|
+
const resp = await this.getClient().send(
|
|
32407
|
+
new DescribeFileSystemsCommand({ FileSystemId: physicalId })
|
|
32408
|
+
);
|
|
32409
|
+
fs = resp.FileSystems?.[0];
|
|
32410
|
+
} catch (err) {
|
|
32411
|
+
if (err instanceof FileSystemNotFound)
|
|
32412
|
+
return void 0;
|
|
32413
|
+
throw err;
|
|
32414
|
+
}
|
|
32415
|
+
if (!fs)
|
|
32416
|
+
return void 0;
|
|
32417
|
+
const result = {};
|
|
32418
|
+
if (fs.PerformanceMode !== void 0)
|
|
32419
|
+
result["PerformanceMode"] = fs.PerformanceMode;
|
|
32420
|
+
if (fs.ThroughputMode !== void 0)
|
|
32421
|
+
result["ThroughputMode"] = fs.ThroughputMode;
|
|
32422
|
+
if (fs.Encrypted !== void 0)
|
|
32423
|
+
result["Encrypted"] = fs.Encrypted;
|
|
32424
|
+
if (fs.KmsKeyId !== void 0)
|
|
32425
|
+
result["KmsKeyId"] = fs.KmsKeyId;
|
|
32426
|
+
if (fs.ProvisionedThroughputInMibps !== void 0) {
|
|
32427
|
+
result["ProvisionedThroughputInMibps"] = fs.ProvisionedThroughputInMibps;
|
|
32428
|
+
}
|
|
32429
|
+
try {
|
|
32430
|
+
const resp = await this.getClient().send(
|
|
32431
|
+
new DescribeLifecycleConfigurationCommand({ FileSystemId: physicalId })
|
|
32432
|
+
);
|
|
32433
|
+
const policies = resp.LifecyclePolicies;
|
|
32434
|
+
if (policies && policies.length > 0) {
|
|
32435
|
+
result["LifecyclePolicies"] = policies.map((p) => {
|
|
32436
|
+
const out = {};
|
|
32437
|
+
if (p.TransitionToIA !== void 0)
|
|
32438
|
+
out["TransitionToIA"] = p.TransitionToIA;
|
|
32439
|
+
if (p.TransitionToPrimaryStorageClass !== void 0) {
|
|
32440
|
+
out["TransitionToPrimaryStorageClass"] = p.TransitionToPrimaryStorageClass;
|
|
32441
|
+
}
|
|
32442
|
+
if (p.TransitionToArchive !== void 0)
|
|
32443
|
+
out["TransitionToArchive"] = p.TransitionToArchive;
|
|
32444
|
+
return out;
|
|
32445
|
+
});
|
|
32446
|
+
}
|
|
32447
|
+
} catch (err) {
|
|
32448
|
+
if (err instanceof FileSystemNotFound)
|
|
32449
|
+
return void 0;
|
|
32450
|
+
const e = err;
|
|
32451
|
+
if (e.name !== "PolicyNotFound") {
|
|
32452
|
+
}
|
|
32453
|
+
}
|
|
32454
|
+
try {
|
|
32455
|
+
const resp = await this.getClient().send(
|
|
32456
|
+
new DescribeBackupPolicyCommand({ FileSystemId: physicalId })
|
|
32457
|
+
);
|
|
32458
|
+
if (resp.BackupPolicy?.Status !== void 0) {
|
|
32459
|
+
result["BackupPolicy"] = { Status: resp.BackupPolicy.Status };
|
|
32460
|
+
}
|
|
32461
|
+
} catch (err) {
|
|
32462
|
+
if (err instanceof FileSystemNotFound)
|
|
32463
|
+
return void 0;
|
|
32464
|
+
}
|
|
32465
|
+
return result;
|
|
32466
|
+
}
|
|
32467
|
+
async readAccessPoint(physicalId) {
|
|
32468
|
+
let ap;
|
|
32469
|
+
try {
|
|
32470
|
+
const resp = await this.getClient().send(
|
|
32471
|
+
new DescribeAccessPointsCommand({ AccessPointId: physicalId })
|
|
32472
|
+
);
|
|
32473
|
+
ap = resp.AccessPoints?.[0];
|
|
32474
|
+
} catch (err) {
|
|
32475
|
+
if (err instanceof AccessPointNotFound)
|
|
32476
|
+
return void 0;
|
|
32477
|
+
throw err;
|
|
32478
|
+
}
|
|
32479
|
+
if (!ap)
|
|
32480
|
+
return void 0;
|
|
32481
|
+
const result = {};
|
|
32482
|
+
if (ap.FileSystemId !== void 0)
|
|
32483
|
+
result["FileSystemId"] = ap.FileSystemId;
|
|
32484
|
+
if (ap.PosixUser) {
|
|
32485
|
+
const posix = {};
|
|
32486
|
+
if (ap.PosixUser.Uid !== void 0)
|
|
32487
|
+
posix["Uid"] = ap.PosixUser.Uid;
|
|
32488
|
+
if (ap.PosixUser.Gid !== void 0)
|
|
32489
|
+
posix["Gid"] = ap.PosixUser.Gid;
|
|
32490
|
+
if (ap.PosixUser.SecondaryGids && ap.PosixUser.SecondaryGids.length > 0) {
|
|
32491
|
+
posix["SecondaryGids"] = [...ap.PosixUser.SecondaryGids];
|
|
32492
|
+
}
|
|
32493
|
+
if (Object.keys(posix).length > 0)
|
|
32494
|
+
result["PosixUser"] = posix;
|
|
32495
|
+
}
|
|
32496
|
+
if (ap.RootDirectory) {
|
|
32497
|
+
const root = {};
|
|
32498
|
+
if (ap.RootDirectory.Path !== void 0)
|
|
32499
|
+
root["Path"] = ap.RootDirectory.Path;
|
|
32500
|
+
if (ap.RootDirectory.CreationInfo) {
|
|
32501
|
+
const ci = {};
|
|
32502
|
+
if (ap.RootDirectory.CreationInfo.OwnerUid !== void 0) {
|
|
32503
|
+
ci["OwnerUid"] = ap.RootDirectory.CreationInfo.OwnerUid;
|
|
32504
|
+
}
|
|
32505
|
+
if (ap.RootDirectory.CreationInfo.OwnerGid !== void 0) {
|
|
32506
|
+
ci["OwnerGid"] = ap.RootDirectory.CreationInfo.OwnerGid;
|
|
32507
|
+
}
|
|
32508
|
+
if (ap.RootDirectory.CreationInfo.Permissions !== void 0) {
|
|
32509
|
+
ci["Permissions"] = ap.RootDirectory.CreationInfo.Permissions;
|
|
32510
|
+
}
|
|
32511
|
+
if (Object.keys(ci).length > 0)
|
|
32512
|
+
root["CreationInfo"] = ci;
|
|
32513
|
+
}
|
|
32514
|
+
if (Object.keys(root).length > 0)
|
|
32515
|
+
result["RootDirectory"] = root;
|
|
32516
|
+
}
|
|
32517
|
+
return result;
|
|
32518
|
+
}
|
|
32519
|
+
async readMountTarget(physicalId) {
|
|
32520
|
+
let mt;
|
|
32521
|
+
try {
|
|
32522
|
+
const resp = await this.getClient().send(
|
|
32523
|
+
new DescribeMountTargetsCommand({ MountTargetId: physicalId })
|
|
32524
|
+
);
|
|
32525
|
+
mt = resp.MountTargets?.[0];
|
|
32526
|
+
} catch (err) {
|
|
32527
|
+
if (err instanceof MountTargetNotFound)
|
|
32528
|
+
return void 0;
|
|
32529
|
+
throw err;
|
|
32530
|
+
}
|
|
32531
|
+
if (!mt)
|
|
32532
|
+
return void 0;
|
|
32533
|
+
const result = {};
|
|
32534
|
+
if (mt.FileSystemId !== void 0)
|
|
32535
|
+
result["FileSystemId"] = mt.FileSystemId;
|
|
32536
|
+
if (mt.SubnetId !== void 0)
|
|
32537
|
+
result["SubnetId"] = mt.SubnetId;
|
|
32538
|
+
return result;
|
|
32539
|
+
}
|
|
30503
32540
|
/**
|
|
30504
32541
|
* Adopt an existing EFS resource into cdkd state.
|
|
30505
32542
|
*
|
|
@@ -30952,6 +32989,63 @@ var FirehoseProvider = class {
|
|
|
30952
32989
|
*
|
|
30953
32990
|
* Firehose tags use the standard `Tag[]` array shape (`Key`/`Value`).
|
|
30954
32991
|
*/
|
|
32992
|
+
/**
|
|
32993
|
+
* Read the AWS-current Firehose delivery stream configuration in CFn-property shape.
|
|
32994
|
+
*
|
|
32995
|
+
* Surfaces top-level configuration that has a clean 1:1 mapping back to
|
|
32996
|
+
* cdkd state — `DeliveryStreamName`, `DeliveryStreamType`, and the
|
|
32997
|
+
* `KinesisStreamSourceConfiguration` parent fields when present (the
|
|
32998
|
+
* `DescribeDeliveryStream` response splits source under `Source.KinesisStreamSourceDescription`).
|
|
32999
|
+
*
|
|
33000
|
+
* Destination configurations (`*DestinationConfiguration` in CFn vs.
|
|
33001
|
+
* `*DestinationDescription` in `DescribeDeliveryStream`) are intentionally
|
|
33002
|
+
* not re-shaped here. Their nested fields are large and the description
|
|
33003
|
+
* vs. configuration shape divergence (extra metadata, write-only fields
|
|
33004
|
+
* like `Password` redacted) makes a clean comparator surface impossible
|
|
33005
|
+
* for v1. We do surface the destination *kind* under a stable key so
|
|
33006
|
+
* users at least see destination drift across types, but not the inner
|
|
33007
|
+
* fields. Drift on destination contents is best chased manually via
|
|
33008
|
+
* `aws firehose describe-delivery-stream` for now.
|
|
33009
|
+
*
|
|
33010
|
+
* Tags + DeliveryStreamEncryptionConfigurationInput are skipped (they
|
|
33011
|
+
* each need separate calls / shape decisions).
|
|
33012
|
+
*
|
|
33013
|
+
* Returns `undefined` when the stream is gone (`ResourceNotFoundException`).
|
|
33014
|
+
*/
|
|
33015
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
33016
|
+
let desc;
|
|
33017
|
+
try {
|
|
33018
|
+
const resp = await this.getClient().send(
|
|
33019
|
+
new DescribeDeliveryStreamCommand({ DeliveryStreamName: physicalId })
|
|
33020
|
+
);
|
|
33021
|
+
desc = resp.DeliveryStreamDescription;
|
|
33022
|
+
} catch (err) {
|
|
33023
|
+
if (err instanceof ResourceNotFoundException14)
|
|
33024
|
+
return void 0;
|
|
33025
|
+
throw err;
|
|
33026
|
+
}
|
|
33027
|
+
if (!desc)
|
|
33028
|
+
return void 0;
|
|
33029
|
+
const result = {};
|
|
33030
|
+
if (desc.DeliveryStreamName !== void 0) {
|
|
33031
|
+
result["DeliveryStreamName"] = desc.DeliveryStreamName;
|
|
33032
|
+
}
|
|
33033
|
+
if (desc.DeliveryStreamType !== void 0) {
|
|
33034
|
+
result["DeliveryStreamType"] = desc.DeliveryStreamType;
|
|
33035
|
+
}
|
|
33036
|
+
if (desc.Source?.KinesisStreamSourceDescription) {
|
|
33037
|
+
const src = desc.Source.KinesisStreamSourceDescription;
|
|
33038
|
+
const srcOut = {};
|
|
33039
|
+
if (src.KinesisStreamARN !== void 0)
|
|
33040
|
+
srcOut["KinesisStreamARN"] = src.KinesisStreamARN;
|
|
33041
|
+
if (src.RoleARN !== void 0)
|
|
33042
|
+
srcOut["RoleARN"] = src.RoleARN;
|
|
33043
|
+
if (Object.keys(srcOut).length > 0) {
|
|
33044
|
+
result["KinesisStreamSourceConfiguration"] = srcOut;
|
|
33045
|
+
}
|
|
33046
|
+
}
|
|
33047
|
+
return result;
|
|
33048
|
+
}
|
|
30955
33049
|
async import(input) {
|
|
30956
33050
|
const explicit = resolveExplicitPhysicalId(input, "DeliveryStreamName");
|
|
30957
33051
|
if (explicit) {
|
|
@@ -31027,6 +33121,8 @@ import {
|
|
|
31027
33121
|
PutEventSelectorsCommand,
|
|
31028
33122
|
PutInsightSelectorsCommand,
|
|
31029
33123
|
GetTrailCommand,
|
|
33124
|
+
GetTrailStatusCommand,
|
|
33125
|
+
GetEventSelectorsCommand,
|
|
31030
33126
|
ListTrailsCommand,
|
|
31031
33127
|
ListTagsCommand as ListTagsCommand3,
|
|
31032
33128
|
TrailNotFoundException
|
|
@@ -31268,6 +33364,86 @@ var CloudTrailProvider = class {
|
|
|
31268
33364
|
* 2. `ListTrails` + `ListTags` (CloudTrail uses `Tag[]` arrays per ARN),
|
|
31269
33365
|
* match `aws:cdk:path` tag.
|
|
31270
33366
|
*/
|
|
33367
|
+
/**
|
|
33368
|
+
* Read the AWS-current CloudTrail Trail configuration in CFn-property shape.
|
|
33369
|
+
*
|
|
33370
|
+
* Issues `GetTrail`, plus best-effort `GetTrailStatus` (for `IsLogging`)
|
|
33371
|
+
* and `GetEventSelectors` (for `EventSelectors`). Each enrichment call is
|
|
33372
|
+
* wrapped in its own try/catch so an "AccessDenied" or other transient
|
|
33373
|
+
* error on the secondary calls omits that key without failing the
|
|
33374
|
+
* whole snapshot — the comparator only descends into keys present in
|
|
33375
|
+
* state.
|
|
33376
|
+
*
|
|
33377
|
+
* Mapping: AWS `GetTrail` returns `KmsKeyId` (lowercase `s`) while CFn
|
|
33378
|
+
* uses `KMSKeyId`; we re-shape the key. SnsTopicARN is the Trail's
|
|
33379
|
+
* derived field; the cdkd state property is `SnsTopicName` so we
|
|
33380
|
+
* surface `SnsTopicName` directly from `GetTrail.SnsTopicName`.
|
|
33381
|
+
*
|
|
33382
|
+
* Tags + InsightSelectors are skipped for v1 (each needs its own
|
|
33383
|
+
* separate call + shape mapping).
|
|
33384
|
+
*
|
|
33385
|
+
* Returns `undefined` when the trail is gone (`TrailNotFoundException`).
|
|
33386
|
+
*/
|
|
33387
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
33388
|
+
let trail;
|
|
33389
|
+
try {
|
|
33390
|
+
const resp = await this.getClient().send(new GetTrailCommand({ Name: physicalId }));
|
|
33391
|
+
trail = resp.Trail;
|
|
33392
|
+
} catch (err) {
|
|
33393
|
+
if (err instanceof TrailNotFoundException)
|
|
33394
|
+
return void 0;
|
|
33395
|
+
throw err;
|
|
33396
|
+
}
|
|
33397
|
+
if (!trail)
|
|
33398
|
+
return void 0;
|
|
33399
|
+
const result = {};
|
|
33400
|
+
if (trail.Name !== void 0)
|
|
33401
|
+
result["TrailName"] = trail.Name;
|
|
33402
|
+
if (trail.S3BucketName !== void 0)
|
|
33403
|
+
result["S3BucketName"] = trail.S3BucketName;
|
|
33404
|
+
if (trail.S3KeyPrefix !== void 0)
|
|
33405
|
+
result["S3KeyPrefix"] = trail.S3KeyPrefix;
|
|
33406
|
+
if (trail.IsMultiRegionTrail !== void 0) {
|
|
33407
|
+
result["IsMultiRegionTrail"] = trail.IsMultiRegionTrail;
|
|
33408
|
+
}
|
|
33409
|
+
if (trail.IncludeGlobalServiceEvents !== void 0) {
|
|
33410
|
+
result["IncludeGlobalServiceEvents"] = trail.IncludeGlobalServiceEvents;
|
|
33411
|
+
}
|
|
33412
|
+
if (trail.LogFileValidationEnabled !== void 0) {
|
|
33413
|
+
result["EnableLogFileValidation"] = trail.LogFileValidationEnabled;
|
|
33414
|
+
}
|
|
33415
|
+
if (trail.CloudWatchLogsLogGroupArn !== void 0) {
|
|
33416
|
+
result["CloudWatchLogsLogGroupArn"] = trail.CloudWatchLogsLogGroupArn;
|
|
33417
|
+
}
|
|
33418
|
+
if (trail.CloudWatchLogsRoleArn !== void 0) {
|
|
33419
|
+
result["CloudWatchLogsRoleArn"] = trail.CloudWatchLogsRoleArn;
|
|
33420
|
+
}
|
|
33421
|
+
if (trail.KmsKeyId !== void 0)
|
|
33422
|
+
result["KMSKeyId"] = trail.KmsKeyId;
|
|
33423
|
+
if (trail.SnsTopicName !== void 0)
|
|
33424
|
+
result["SnsTopicName"] = trail.SnsTopicName;
|
|
33425
|
+
if (trail.IsOrganizationTrail !== void 0) {
|
|
33426
|
+
result["IsOrganizationTrail"] = trail.IsOrganizationTrail;
|
|
33427
|
+
}
|
|
33428
|
+
try {
|
|
33429
|
+
const status = await this.getClient().send(new GetTrailStatusCommand({ Name: physicalId }));
|
|
33430
|
+
if (status.IsLogging !== void 0)
|
|
33431
|
+
result["IsLogging"] = status.IsLogging;
|
|
33432
|
+
} catch {
|
|
33433
|
+
}
|
|
33434
|
+
try {
|
|
33435
|
+
const sel = await this.getClient().send(
|
|
33436
|
+
new GetEventSelectorsCommand({ TrailName: physicalId })
|
|
33437
|
+
);
|
|
33438
|
+
if (sel.EventSelectors && sel.EventSelectors.length > 0) {
|
|
33439
|
+
result["EventSelectors"] = sel.EventSelectors.map(
|
|
33440
|
+
(es) => es
|
|
33441
|
+
);
|
|
33442
|
+
}
|
|
33443
|
+
} catch {
|
|
33444
|
+
}
|
|
33445
|
+
return result;
|
|
33446
|
+
}
|
|
31271
33447
|
async import(input) {
|
|
31272
33448
|
const explicit = resolveExplicitPhysicalId(input, "TrailName");
|
|
31273
33449
|
if (explicit) {
|
|
@@ -31585,6 +33761,141 @@ var CodeBuildProvider = class {
|
|
|
31585
33761
|
* `key`/`value` tags, not the standard `Key`/`Value`), match
|
|
31586
33762
|
* `aws:cdk:path` tag.
|
|
31587
33763
|
*/
|
|
33764
|
+
/**
|
|
33765
|
+
* Read the AWS-current CodeBuild Project configuration in CFn-property shape.
|
|
33766
|
+
*
|
|
33767
|
+
* Issues `BatchGetProjects` and re-shapes the SDK's camelCase response back
|
|
33768
|
+
* to CFn's PascalCase shape (the `mapProperties` helper above goes the
|
|
33769
|
+
* other way at create time). The drift comparator only descends into
|
|
33770
|
+
* keys present in cdkd state, so we focus on the high-value top-level
|
|
33771
|
+
* fields and the most commonly-set `Source` / `Artifacts` /
|
|
33772
|
+
* `Environment` sub-fields. Less common nested config (full
|
|
33773
|
+
* `LogsConfig`, `VpcConfig` rebuild, secondary sources/artifacts, etc.)
|
|
33774
|
+
* is left to a follow-up — surfacing them with a partial shape would
|
|
33775
|
+
* fire false drift on every project that uses them.
|
|
33776
|
+
*
|
|
33777
|
+
* Tags are skipped (CDK auto-tag handling deferred). Returns `undefined`
|
|
33778
|
+
* when the project is gone (`projects` array empty / `projectsNotFound` set).
|
|
33779
|
+
*/
|
|
33780
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
33781
|
+
let project;
|
|
33782
|
+
try {
|
|
33783
|
+
const resp = await this.getClient().send(
|
|
33784
|
+
new BatchGetProjectsCommand({ names: [physicalId] })
|
|
33785
|
+
);
|
|
33786
|
+
project = resp.projects?.[0];
|
|
33787
|
+
} catch (err) {
|
|
33788
|
+
if (err instanceof ResourceNotFoundException15)
|
|
33789
|
+
return void 0;
|
|
33790
|
+
throw err;
|
|
33791
|
+
}
|
|
33792
|
+
if (!project)
|
|
33793
|
+
return void 0;
|
|
33794
|
+
const result = {};
|
|
33795
|
+
if (project.name !== void 0)
|
|
33796
|
+
result["Name"] = project.name;
|
|
33797
|
+
if (project.description !== void 0 && project.description !== "") {
|
|
33798
|
+
result["Description"] = project.description;
|
|
33799
|
+
}
|
|
33800
|
+
if (project.serviceRole !== void 0)
|
|
33801
|
+
result["ServiceRole"] = project.serviceRole;
|
|
33802
|
+
if (project.timeoutInMinutes !== void 0) {
|
|
33803
|
+
result["TimeoutInMinutes"] = project.timeoutInMinutes;
|
|
33804
|
+
}
|
|
33805
|
+
if (project.queuedTimeoutInMinutes !== void 0) {
|
|
33806
|
+
result["QueuedTimeoutInMinutes"] = project.queuedTimeoutInMinutes;
|
|
33807
|
+
}
|
|
33808
|
+
if (project.encryptionKey !== void 0)
|
|
33809
|
+
result["EncryptionKey"] = project.encryptionKey;
|
|
33810
|
+
if (project.concurrentBuildLimit !== void 0) {
|
|
33811
|
+
result["ConcurrentBuildLimit"] = project.concurrentBuildLimit;
|
|
33812
|
+
}
|
|
33813
|
+
if (project.badge?.badgeEnabled !== void 0) {
|
|
33814
|
+
result["BadgeEnabled"] = project.badge.badgeEnabled;
|
|
33815
|
+
}
|
|
33816
|
+
if (project.sourceVersion !== void 0)
|
|
33817
|
+
result["SourceVersion"] = project.sourceVersion;
|
|
33818
|
+
if (project.source) {
|
|
33819
|
+
const src = {};
|
|
33820
|
+
if (project.source.type !== void 0)
|
|
33821
|
+
src["Type"] = project.source.type;
|
|
33822
|
+
if (project.source.location !== void 0)
|
|
33823
|
+
src["Location"] = project.source.location;
|
|
33824
|
+
if (project.source.buildspec !== void 0)
|
|
33825
|
+
src["BuildSpec"] = project.source.buildspec;
|
|
33826
|
+
if (project.source.gitCloneDepth !== void 0) {
|
|
33827
|
+
src["GitCloneDepth"] = project.source.gitCloneDepth;
|
|
33828
|
+
}
|
|
33829
|
+
if (project.source.insecureSsl !== void 0)
|
|
33830
|
+
src["InsecureSsl"] = project.source.insecureSsl;
|
|
33831
|
+
if (project.source.reportBuildStatus !== void 0) {
|
|
33832
|
+
src["ReportBuildStatus"] = project.source.reportBuildStatus;
|
|
33833
|
+
}
|
|
33834
|
+
if (Object.keys(src).length > 0)
|
|
33835
|
+
result["Source"] = src;
|
|
33836
|
+
}
|
|
33837
|
+
if (project.artifacts) {
|
|
33838
|
+
const art = {};
|
|
33839
|
+
if (project.artifacts.type !== void 0)
|
|
33840
|
+
art["Type"] = project.artifacts.type;
|
|
33841
|
+
if (project.artifacts.location !== void 0)
|
|
33842
|
+
art["Location"] = project.artifacts.location;
|
|
33843
|
+
if (project.artifacts.path !== void 0)
|
|
33844
|
+
art["Path"] = project.artifacts.path;
|
|
33845
|
+
if (project.artifacts.name !== void 0)
|
|
33846
|
+
art["Name"] = project.artifacts.name;
|
|
33847
|
+
if (project.artifacts.namespaceType !== void 0) {
|
|
33848
|
+
art["NamespaceType"] = project.artifacts.namespaceType;
|
|
33849
|
+
}
|
|
33850
|
+
if (project.artifacts.packaging !== void 0)
|
|
33851
|
+
art["Packaging"] = project.artifacts.packaging;
|
|
33852
|
+
if (project.artifacts.encryptionDisabled !== void 0) {
|
|
33853
|
+
art["EncryptionDisabled"] = project.artifacts.encryptionDisabled;
|
|
33854
|
+
}
|
|
33855
|
+
if (project.artifacts.overrideArtifactName !== void 0) {
|
|
33856
|
+
art["OverrideArtifactName"] = project.artifacts.overrideArtifactName;
|
|
33857
|
+
}
|
|
33858
|
+
if (project.artifacts.artifactIdentifier !== void 0) {
|
|
33859
|
+
art["ArtifactIdentifier"] = project.artifacts.artifactIdentifier;
|
|
33860
|
+
}
|
|
33861
|
+
if (Object.keys(art).length > 0)
|
|
33862
|
+
result["Artifacts"] = art;
|
|
33863
|
+
}
|
|
33864
|
+
if (project.environment) {
|
|
33865
|
+
const env = {};
|
|
33866
|
+
if (project.environment.type !== void 0)
|
|
33867
|
+
env["Type"] = project.environment.type;
|
|
33868
|
+
if (project.environment.image !== void 0)
|
|
33869
|
+
env["Image"] = project.environment.image;
|
|
33870
|
+
if (project.environment.computeType !== void 0) {
|
|
33871
|
+
env["ComputeType"] = project.environment.computeType;
|
|
33872
|
+
}
|
|
33873
|
+
if (project.environment.privilegedMode !== void 0) {
|
|
33874
|
+
env["PrivilegedMode"] = project.environment.privilegedMode;
|
|
33875
|
+
}
|
|
33876
|
+
if (project.environment.imagePullCredentialsType !== void 0) {
|
|
33877
|
+
env["ImagePullCredentialsType"] = project.environment.imagePullCredentialsType;
|
|
33878
|
+
}
|
|
33879
|
+
if (project.environment.certificate !== void 0) {
|
|
33880
|
+
env["Certificate"] = project.environment.certificate;
|
|
33881
|
+
}
|
|
33882
|
+
if (project.environment.environmentVariables && project.environment.environmentVariables.length > 0) {
|
|
33883
|
+
env["EnvironmentVariables"] = project.environment.environmentVariables.map((ev) => {
|
|
33884
|
+
const out = {};
|
|
33885
|
+
if (ev.name !== void 0)
|
|
33886
|
+
out["Name"] = ev.name;
|
|
33887
|
+
if (ev.value !== void 0)
|
|
33888
|
+
out["Value"] = ev.value;
|
|
33889
|
+
if (ev.type !== void 0)
|
|
33890
|
+
out["Type"] = ev.type;
|
|
33891
|
+
return out;
|
|
33892
|
+
});
|
|
33893
|
+
}
|
|
33894
|
+
if (Object.keys(env).length > 0)
|
|
33895
|
+
result["Environment"] = env;
|
|
33896
|
+
}
|
|
33897
|
+
return result;
|
|
33898
|
+
}
|
|
31588
33899
|
async import(input) {
|
|
31589
33900
|
const explicit = resolveExplicitPhysicalId(input, "Name");
|
|
31590
33901
|
if (explicit) {
|
|
@@ -31791,6 +34102,49 @@ var S3VectorsProvider = class {
|
|
|
31791
34102
|
nextToken = listResult.nextToken;
|
|
31792
34103
|
} while (nextToken);
|
|
31793
34104
|
}
|
|
34105
|
+
/**
|
|
34106
|
+
* Read the AWS-current S3 Vector Bucket configuration in CFn-property
|
|
34107
|
+
* shape.
|
|
34108
|
+
*
|
|
34109
|
+
* Issues `GetVectorBucket` for the bucket name (the physical id) and
|
|
34110
|
+
* surfaces `VectorBucketName` and `EncryptionConfiguration` (re-shaping
|
|
34111
|
+
* the camelCase SDK response back to PascalCase CFn property names —
|
|
34112
|
+
* `sseType` → `SSEType`, `kmsKeyArn` → `KMSKeyArn`).
|
|
34113
|
+
*
|
|
34114
|
+
* Returns `undefined` when the bucket is gone (`NotFoundException` /
|
|
34115
|
+
* `NoSuchVectorBucket`).
|
|
34116
|
+
*/
|
|
34117
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
34118
|
+
let resp;
|
|
34119
|
+
try {
|
|
34120
|
+
resp = await this.getClient().send(
|
|
34121
|
+
new GetVectorBucketCommand({ vectorBucketName: physicalId })
|
|
34122
|
+
);
|
|
34123
|
+
} catch (err) {
|
|
34124
|
+
if (this.isNotFoundError(err))
|
|
34125
|
+
return void 0;
|
|
34126
|
+
throw err;
|
|
34127
|
+
}
|
|
34128
|
+
const result = {};
|
|
34129
|
+
const bucket = resp.vectorBucket;
|
|
34130
|
+
if (bucket?.vectorBucketName !== void 0) {
|
|
34131
|
+
result["VectorBucketName"] = bucket.vectorBucketName;
|
|
34132
|
+
} else {
|
|
34133
|
+
result["VectorBucketName"] = physicalId;
|
|
34134
|
+
}
|
|
34135
|
+
if (bucket?.encryptionConfiguration) {
|
|
34136
|
+
const enc = {};
|
|
34137
|
+
if (bucket.encryptionConfiguration.sseType !== void 0) {
|
|
34138
|
+
enc["SSEType"] = bucket.encryptionConfiguration.sseType;
|
|
34139
|
+
}
|
|
34140
|
+
if (bucket.encryptionConfiguration.kmsKeyArn !== void 0) {
|
|
34141
|
+
enc["KMSKeyArn"] = bucket.encryptionConfiguration.kmsKeyArn;
|
|
34142
|
+
}
|
|
34143
|
+
if (Object.keys(enc).length > 0)
|
|
34144
|
+
result["EncryptionConfiguration"] = enc;
|
|
34145
|
+
}
|
|
34146
|
+
return result;
|
|
34147
|
+
}
|
|
31794
34148
|
/**
|
|
31795
34149
|
* Adopt an existing S3 Vector Bucket into cdkd state.
|
|
31796
34150
|
*
|
|
@@ -32060,6 +34414,48 @@ var S3DirectoryBucketProvider = class {
|
|
|
32060
34414
|
continuationToken = listResponse.IsTruncated ? listResponse.NextContinuationToken : void 0;
|
|
32061
34415
|
} while (continuationToken);
|
|
32062
34416
|
}
|
|
34417
|
+
/**
|
|
34418
|
+
* Read the AWS-current S3 Express Directory Bucket configuration in
|
|
34419
|
+
* CFn-property shape.
|
|
34420
|
+
*
|
|
34421
|
+
* Issues `HeadBucket` to verify existence and surfaces `BucketName`
|
|
34422
|
+
* (the physicalId). `DataRedundancy` and `LocationName` are not exposed
|
|
34423
|
+
* by any cheap S3 Express API — the only way to inspect them is by
|
|
34424
|
+
* parsing the bucket name's `--<az-id>--x-s3` suffix, which is best
|
|
34425
|
+
* effort. We surface them when they are recoverable from the bucket
|
|
34426
|
+
* name to give the comparator a chance to detect mismatches.
|
|
34427
|
+
*
|
|
34428
|
+
* `--<az-id>--x-s3` suffix parsing: directory bucket names follow the
|
|
34429
|
+
* format `<base>--<az-id>--x-s3`, e.g.
|
|
34430
|
+
* `my-bucket--use1-az1--x-s3`. We don't reverse the AZ-ID -> AZ-name
|
|
34431
|
+
* mapping here (that would require a per-call EC2 `DescribeAvailabilityZones`
|
|
34432
|
+
* round-trip); state's `LocationName` is `us-east-1a--x-s3`-style,
|
|
34433
|
+
* while the bucket name carries the AZ-ID `use1-az1`. Cross-region
|
|
34434
|
+
* mapping is too expensive for v1 — we omit `LocationName` from the
|
|
34435
|
+
* snapshot and rely on the comparator's "key absent in state never
|
|
34436
|
+
* drifts" rule to no-op against state.
|
|
34437
|
+
*
|
|
34438
|
+
* Returns `undefined` when the bucket is gone (`HeadBucket` returns
|
|
34439
|
+
* `NotFound` / `NoSuchBucket`).
|
|
34440
|
+
*/
|
|
34441
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
34442
|
+
try {
|
|
34443
|
+
await this.s3Client.send(new HeadBucketCommand4({ Bucket: physicalId }));
|
|
34444
|
+
} catch (err) {
|
|
34445
|
+
const e = err;
|
|
34446
|
+
if (e.name === "NotFound" || e.name === "NoSuchBucket" || e.name === "BucketNotFound") {
|
|
34447
|
+
return void 0;
|
|
34448
|
+
}
|
|
34449
|
+
throw err;
|
|
34450
|
+
}
|
|
34451
|
+
const result = {
|
|
34452
|
+
BucketName: physicalId
|
|
34453
|
+
};
|
|
34454
|
+
if (physicalId.endsWith("--x-s3")) {
|
|
34455
|
+
result["DataRedundancy"] = "SingleAvailabilityZone";
|
|
34456
|
+
}
|
|
34457
|
+
return result;
|
|
34458
|
+
}
|
|
32063
34459
|
/**
|
|
32064
34460
|
* Adopt an existing S3 Express Directory Bucket into cdkd state.
|
|
32065
34461
|
*
|
|
@@ -32464,6 +34860,97 @@ var S3TablesProvider = class {
|
|
|
32464
34860
|
);
|
|
32465
34861
|
}
|
|
32466
34862
|
}
|
|
34863
|
+
// ─── readCurrentState dispatch ───────────────────────────────────
|
|
34864
|
+
/**
|
|
34865
|
+
* Read the AWS-current S3 Tables resource configuration in CFn-property
|
|
34866
|
+
* shape.
|
|
34867
|
+
*
|
|
34868
|
+
* - **AWS::S3Tables::TableBucket**: `GetTableBucket` for the ARN; we
|
|
34869
|
+
* surface `TableBucketName` (the only mutable cdkd-managed property).
|
|
34870
|
+
* - **AWS::S3Tables::Namespace**: parses `tableBucketARN|namespace`
|
|
34871
|
+
* from physical id and surfaces `TableBucketARN` and `Namespace`
|
|
34872
|
+
* (as a `string[]` with one entry, matching `create()`'s shape).
|
|
34873
|
+
* No GetNamespace call — the physical id IS the source of truth and
|
|
34874
|
+
* AWS surfaces no additional managed fields cdkd cares about.
|
|
34875
|
+
* - **AWS::S3Tables::Table**: parses `tableBucketARN|namespace|name`
|
|
34876
|
+
* from physical id, calls `GetTable` to verify existence and recover
|
|
34877
|
+
* `format`, surfaces `TableBucketARN`, `Namespace` (string), `Name`,
|
|
34878
|
+
* `Format`.
|
|
34879
|
+
*
|
|
34880
|
+
* Returns `undefined` when the resource is gone (`NotFoundException`).
|
|
34881
|
+
*/
|
|
34882
|
+
async readCurrentState(physicalId, logicalId, resourceType) {
|
|
34883
|
+
switch (resourceType) {
|
|
34884
|
+
case "AWS::S3Tables::TableBucket":
|
|
34885
|
+
return this.readTableBucketCurrentState(physicalId);
|
|
34886
|
+
case "AWS::S3Tables::Namespace":
|
|
34887
|
+
return this.readNamespaceCurrentState(physicalId);
|
|
34888
|
+
case "AWS::S3Tables::Table":
|
|
34889
|
+
return this.readTableCurrentState(physicalId);
|
|
34890
|
+
default:
|
|
34891
|
+
this.logger.debug(
|
|
34892
|
+
`readCurrentState: unsupported resource type ${resourceType} for ${logicalId}`
|
|
34893
|
+
);
|
|
34894
|
+
return void 0;
|
|
34895
|
+
}
|
|
34896
|
+
}
|
|
34897
|
+
async readTableBucketCurrentState(physicalId) {
|
|
34898
|
+
let bucket;
|
|
34899
|
+
try {
|
|
34900
|
+
const resp = await this.getClient().send(
|
|
34901
|
+
new GetTableBucketCommand({ tableBucketARN: physicalId })
|
|
34902
|
+
);
|
|
34903
|
+
bucket = resp;
|
|
34904
|
+
} catch (err) {
|
|
34905
|
+
if (err instanceof NotFoundException6)
|
|
34906
|
+
return void 0;
|
|
34907
|
+
throw err;
|
|
34908
|
+
}
|
|
34909
|
+
const result = {};
|
|
34910
|
+
if (bucket.name !== void 0)
|
|
34911
|
+
result["TableBucketName"] = bucket.name;
|
|
34912
|
+
return result;
|
|
34913
|
+
}
|
|
34914
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- structural; physical id is the source of truth
|
|
34915
|
+
async readNamespaceCurrentState(physicalId) {
|
|
34916
|
+
const [tableBucketARN, namespaceName] = physicalId.split("|");
|
|
34917
|
+
if (!tableBucketARN || !namespaceName)
|
|
34918
|
+
return void 0;
|
|
34919
|
+
return {
|
|
34920
|
+
TableBucketARN: tableBucketARN,
|
|
34921
|
+
Namespace: [namespaceName]
|
|
34922
|
+
};
|
|
34923
|
+
}
|
|
34924
|
+
async readTableCurrentState(physicalId) {
|
|
34925
|
+
const parts = physicalId.split("|");
|
|
34926
|
+
if (parts.length < 3)
|
|
34927
|
+
return void 0;
|
|
34928
|
+
const [tableBucketARN, namespace, name] = parts;
|
|
34929
|
+
if (!tableBucketARN || !namespace || !name)
|
|
34930
|
+
return void 0;
|
|
34931
|
+
let resp;
|
|
34932
|
+
try {
|
|
34933
|
+
resp = await this.getClient().send(
|
|
34934
|
+
new GetTableCommand2({
|
|
34935
|
+
tableBucketARN,
|
|
34936
|
+
namespace,
|
|
34937
|
+
name
|
|
34938
|
+
})
|
|
34939
|
+
);
|
|
34940
|
+
} catch (err) {
|
|
34941
|
+
if (err instanceof NotFoundException6)
|
|
34942
|
+
return void 0;
|
|
34943
|
+
throw err;
|
|
34944
|
+
}
|
|
34945
|
+
const result = {
|
|
34946
|
+
TableBucketARN: tableBucketARN,
|
|
34947
|
+
Namespace: namespace,
|
|
34948
|
+
Name: resp.name ?? name
|
|
34949
|
+
};
|
|
34950
|
+
if (resp.format !== void 0)
|
|
34951
|
+
result["Format"] = resp.format;
|
|
34952
|
+
return result;
|
|
34953
|
+
}
|
|
32467
34954
|
// ─── Import dispatch ──────────────────────────────────────────────
|
|
32468
34955
|
/**
|
|
32469
34956
|
* Adopt an existing S3 Tables resource into cdkd state.
|
|
@@ -38869,7 +41356,7 @@ function reorderArgs(argv) {
|
|
|
38869
41356
|
}
|
|
38870
41357
|
async function main() {
|
|
38871
41358
|
const program = new Command14();
|
|
38872
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
41359
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.41.0");
|
|
38873
41360
|
program.addCommand(createBootstrapCommand());
|
|
38874
41361
|
program.addCommand(createSynthCommand());
|
|
38875
41362
|
program.addCommand(createListCommand());
|