@go-to-k/cdkd 0.40.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 +970 -3
- 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.40.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
|
*
|
|
@@ -13407,7 +13647,7 @@ var SNSSubscriptionProvider = class {
|
|
|
13407
13647
|
};
|
|
13408
13648
|
|
|
13409
13649
|
// src/provisioning/providers/sns-topic-policy-provider.ts
|
|
13410
|
-
import { SetTopicAttributesCommand as SetTopicAttributesCommand2 } from "@aws-sdk/client-sns";
|
|
13650
|
+
import { SetTopicAttributesCommand as SetTopicAttributesCommand2, GetTopicAttributesCommand as GetTopicAttributesCommand2 } from "@aws-sdk/client-sns";
|
|
13411
13651
|
init_aws_clients();
|
|
13412
13652
|
var SNSTopicPolicyProvider = class {
|
|
13413
13653
|
logger = getLogger().child("SNSTopicPolicyProvider");
|
|
@@ -13543,6 +13783,57 @@ var SNSTopicPolicyProvider = class {
|
|
|
13543
13783
|
}
|
|
13544
13784
|
this.logger.debug(`Successfully deleted SNS topic policy ${logicalId}`);
|
|
13545
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
|
+
}
|
|
13546
13837
|
/**
|
|
13547
13838
|
* Adopt an existing SNS topic policy into cdkd state.
|
|
13548
13839
|
*
|
|
@@ -14793,6 +15084,66 @@ var LambdaUrlProvider = class {
|
|
|
14793
15084
|
throw err;
|
|
14794
15085
|
}
|
|
14795
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
|
+
}
|
|
14796
15147
|
/**
|
|
14797
15148
|
* Adopt an existing Lambda Function URL into cdkd state.
|
|
14798
15149
|
*
|
|
@@ -15055,6 +15406,96 @@ var LambdaEventSourceMappingProvider = class {
|
|
|
15055
15406
|
);
|
|
15056
15407
|
}
|
|
15057
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
|
+
}
|
|
15058
15499
|
/**
|
|
15059
15500
|
* Adopt an existing Lambda event source mapping into cdkd state.
|
|
15060
15501
|
*
|
|
@@ -15223,6 +15664,57 @@ var LambdaLayerVersionProvider = class {
|
|
|
15223
15664
|
);
|
|
15224
15665
|
}
|
|
15225
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
|
+
}
|
|
15226
15718
|
/**
|
|
15227
15719
|
* Adopt an existing Lambda layer version into cdkd state.
|
|
15228
15720
|
*
|
|
@@ -17900,7 +18392,10 @@ import {
|
|
|
17900
18392
|
CreateVpcCommand,
|
|
17901
18393
|
DeleteVpcCommand,
|
|
17902
18394
|
ModifyVpcAttributeCommand,
|
|
18395
|
+
DescribeVpcAttributeCommand,
|
|
17903
18396
|
DescribeVpcsCommand as DescribeVpcsCommand2,
|
|
18397
|
+
DescribeInternetGatewaysCommand,
|
|
18398
|
+
DescribeRouteTablesCommand as DescribeRouteTablesCommand2,
|
|
17904
18399
|
CreateSubnetCommand,
|
|
17905
18400
|
DeleteSubnetCommand,
|
|
17906
18401
|
CreateInternetGatewayCommand,
|
|
@@ -20060,6 +20555,223 @@ var EC2Provider = class {
|
|
|
20060
20555
|
throw error;
|
|
20061
20556
|
}
|
|
20062
20557
|
}
|
|
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
|
+
}
|
|
20063
20775
|
async verifyExplicit(resourceType, physicalId) {
|
|
20064
20776
|
try {
|
|
20065
20777
|
switch (resourceType) {
|
|
@@ -22542,6 +23254,23 @@ function pascalToCamelCaseKeys(value) {
|
|
|
22542
23254
|
}
|
|
22543
23255
|
return value;
|
|
22544
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
|
+
}
|
|
22545
23274
|
var AgentCoreRuntimeProvider = class {
|
|
22546
23275
|
client;
|
|
22547
23276
|
logger = getLogger().child("AgentCoreRuntimeProvider");
|
|
@@ -22776,6 +23505,68 @@ var AgentCoreRuntimeProvider = class {
|
|
|
22776
23505
|
}
|
|
22777
23506
|
throw new Error(`Unsupported attribute: ${attributeName} for AWS::BedrockAgentCore::Runtime`);
|
|
22778
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
|
+
}
|
|
22779
23570
|
/**
|
|
22780
23571
|
* Adopt an existing BedrockAgentCore Runtime into cdkd state.
|
|
22781
23572
|
*
|
|
@@ -33311,6 +34102,49 @@ var S3VectorsProvider = class {
|
|
|
33311
34102
|
nextToken = listResult.nextToken;
|
|
33312
34103
|
} while (nextToken);
|
|
33313
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
|
+
}
|
|
33314
34148
|
/**
|
|
33315
34149
|
* Adopt an existing S3 Vector Bucket into cdkd state.
|
|
33316
34150
|
*
|
|
@@ -33580,6 +34414,48 @@ var S3DirectoryBucketProvider = class {
|
|
|
33580
34414
|
continuationToken = listResponse.IsTruncated ? listResponse.NextContinuationToken : void 0;
|
|
33581
34415
|
} while (continuationToken);
|
|
33582
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
|
+
}
|
|
33583
34459
|
/**
|
|
33584
34460
|
* Adopt an existing S3 Express Directory Bucket into cdkd state.
|
|
33585
34461
|
*
|
|
@@ -33984,6 +34860,97 @@ var S3TablesProvider = class {
|
|
|
33984
34860
|
);
|
|
33985
34861
|
}
|
|
33986
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
|
+
}
|
|
33987
34954
|
// ─── Import dispatch ──────────────────────────────────────────────
|
|
33988
34955
|
/**
|
|
33989
34956
|
* Adopt an existing S3 Tables resource into cdkd state.
|
|
@@ -40389,7 +41356,7 @@ function reorderArgs(argv) {
|
|
|
40389
41356
|
}
|
|
40390
41357
|
async function main() {
|
|
40391
41358
|
const program = new Command14();
|
|
40392
|
-
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");
|
|
40393
41360
|
program.addCommand(createBootstrapCommand());
|
|
40394
41361
|
program.addCommand(createSynthCommand());
|
|
40395
41362
|
program.addCommand(createListCommand());
|