@go-to-k/cdkd 0.50.5 → 0.50.7
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 +1085 -120
- package/dist/cli.js.map +3 -3
- package/dist/go-to-k-cdkd-0.50.7.tgz +0 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.50.5.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -8705,10 +8705,10 @@ var IAMRoleProvider = class {
|
|
|
8705
8705
|
const updateParams = {
|
|
8706
8706
|
RoleName: physicalId
|
|
8707
8707
|
};
|
|
8708
|
-
if (properties["Description"]) {
|
|
8708
|
+
if (properties["Description"] !== void 0) {
|
|
8709
8709
|
updateParams.Description = properties["Description"];
|
|
8710
8710
|
}
|
|
8711
|
-
if (properties["MaxSessionDuration"]) {
|
|
8711
|
+
if (properties["MaxSessionDuration"] !== void 0) {
|
|
8712
8712
|
updateParams.MaxSessionDuration = properties["MaxSessionDuration"];
|
|
8713
8713
|
}
|
|
8714
8714
|
await this.iamClient.send(new UpdateRoleCommand(updateParams));
|
|
@@ -10038,6 +10038,7 @@ import {
|
|
|
10038
10038
|
ListUserTagsCommand,
|
|
10039
10039
|
NoSuchEntityException as NoSuchEntityException4,
|
|
10040
10040
|
TagUserCommand,
|
|
10041
|
+
UntagUserCommand,
|
|
10041
10042
|
PutUserPermissionsBoundaryCommand,
|
|
10042
10043
|
DeleteUserPermissionsBoundaryCommand
|
|
10043
10044
|
} from "@aws-sdk/client-iam";
|
|
@@ -10234,16 +10235,11 @@ var IAMUserGroupProvider = class {
|
|
|
10234
10235
|
async updateUser(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
10235
10236
|
this.logger.debug(`Updating IAM user ${logicalId}: ${physicalId}`);
|
|
10236
10237
|
try {
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
Tags: tags
|
|
10243
|
-
})
|
|
10244
|
-
);
|
|
10245
|
-
this.logger.debug(`Tagged user ${physicalId}`);
|
|
10246
|
-
}
|
|
10238
|
+
await this.applyUserTagDiff(
|
|
10239
|
+
physicalId,
|
|
10240
|
+
previousProperties["Tags"],
|
|
10241
|
+
properties["Tags"]
|
|
10242
|
+
);
|
|
10247
10243
|
const newPermBoundary = properties["PermissionsBoundary"];
|
|
10248
10244
|
const oldPermBoundary = previousProperties["PermissionsBoundary"];
|
|
10249
10245
|
if (newPermBoundary !== oldPermBoundary) {
|
|
@@ -10492,6 +10488,42 @@ var IAMUserGroupProvider = class {
|
|
|
10492
10488
|
throw error;
|
|
10493
10489
|
}
|
|
10494
10490
|
}
|
|
10491
|
+
/**
|
|
10492
|
+
* Apply a diff between old and new CFn-shape Tags arrays via IAM's
|
|
10493
|
+
* `TagUser` / `UntagUser` APIs.
|
|
10494
|
+
*/
|
|
10495
|
+
async applyUserTagDiff(userName, oldTagsRaw, newTagsRaw) {
|
|
10496
|
+
const toMap = (tags) => {
|
|
10497
|
+
const m = /* @__PURE__ */ new Map();
|
|
10498
|
+
for (const t of tags ?? []) {
|
|
10499
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
10500
|
+
m.set(t.Key, t.Value);
|
|
10501
|
+
}
|
|
10502
|
+
return m;
|
|
10503
|
+
};
|
|
10504
|
+
const oldMap = toMap(oldTagsRaw);
|
|
10505
|
+
const newMap = toMap(newTagsRaw);
|
|
10506
|
+
const tagsToAdd = [];
|
|
10507
|
+
for (const [k, v] of newMap) {
|
|
10508
|
+
if (oldMap.get(k) !== v)
|
|
10509
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
10510
|
+
}
|
|
10511
|
+
const tagsToRemove = [];
|
|
10512
|
+
for (const k of oldMap.keys()) {
|
|
10513
|
+
if (!newMap.has(k))
|
|
10514
|
+
tagsToRemove.push(k);
|
|
10515
|
+
}
|
|
10516
|
+
if (tagsToRemove.length > 0) {
|
|
10517
|
+
await this.iamClient.send(
|
|
10518
|
+
new UntagUserCommand({ UserName: userName, TagKeys: tagsToRemove })
|
|
10519
|
+
);
|
|
10520
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from IAM user ${userName}`);
|
|
10521
|
+
}
|
|
10522
|
+
if (tagsToAdd.length > 0) {
|
|
10523
|
+
await this.iamClient.send(new TagUserCommand({ UserName: userName, Tags: tagsToAdd }));
|
|
10524
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on IAM user ${userName}`);
|
|
10525
|
+
}
|
|
10526
|
+
}
|
|
10495
10527
|
async updateUserManagedPolicies(userName, newPolicies, oldPolicies) {
|
|
10496
10528
|
const newSet = new Set(newPolicies || []);
|
|
10497
10529
|
const oldSet = new Set(oldPolicies || []);
|
|
@@ -11224,6 +11256,7 @@ import {
|
|
|
11224
11256
|
ListBucketsCommand,
|
|
11225
11257
|
PutBucketVersioningCommand as PutBucketVersioningCommand2,
|
|
11226
11258
|
PutBucketTaggingCommand,
|
|
11259
|
+
DeleteBucketTaggingCommand,
|
|
11227
11260
|
PutBucketOwnershipControlsCommand,
|
|
11228
11261
|
PutBucketNotificationConfigurationCommand,
|
|
11229
11262
|
PutBucketCorsCommand,
|
|
@@ -11347,6 +11380,52 @@ var S3BucketProvider = class {
|
|
|
11347
11380
|
);
|
|
11348
11381
|
this.logger.debug(`Applied ${tags.length} tags to bucket ${bucketName}`);
|
|
11349
11382
|
}
|
|
11383
|
+
/**
|
|
11384
|
+
* Apply a diff between old and new CFn-shape Tags arrays via S3's
|
|
11385
|
+
* `PutBucketTagging` (full-replace) / `DeleteBucketTagging` APIs.
|
|
11386
|
+
*
|
|
11387
|
+
* S3's `PutBucketTagging` replaces the entire tag set in one call, so we
|
|
11388
|
+
* don't need separate add/remove API operations. When the new set is
|
|
11389
|
+
* empty, we issue `DeleteBucketTagging` to clear it. When old and new
|
|
11390
|
+
* are equal, we skip the call entirely.
|
|
11391
|
+
*/
|
|
11392
|
+
async applyTagDiff(bucketName, oldTagsRaw, newTagsRaw) {
|
|
11393
|
+
const normalize = (tags) => {
|
|
11394
|
+
const out = [];
|
|
11395
|
+
for (const t of tags ?? []) {
|
|
11396
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
11397
|
+
out.push({ Key: t.Key, Value: t.Value });
|
|
11398
|
+
}
|
|
11399
|
+
return out;
|
|
11400
|
+
};
|
|
11401
|
+
const oldNorm = normalize(oldTagsRaw);
|
|
11402
|
+
const newNorm = normalize(newTagsRaw);
|
|
11403
|
+
if (JSON.stringify(oldNorm) === JSON.stringify(newNorm))
|
|
11404
|
+
return;
|
|
11405
|
+
if (newNorm.length === 0) {
|
|
11406
|
+
try {
|
|
11407
|
+
await this.s3Client.send(
|
|
11408
|
+
new DeleteBucketTaggingCommand({
|
|
11409
|
+
Bucket: bucketName
|
|
11410
|
+
})
|
|
11411
|
+
);
|
|
11412
|
+
this.logger.debug(`Cleared tags from bucket ${bucketName}`);
|
|
11413
|
+
} catch (err) {
|
|
11414
|
+
const e = err;
|
|
11415
|
+
if (e.name === "NoSuchTagSet")
|
|
11416
|
+
return;
|
|
11417
|
+
throw err;
|
|
11418
|
+
}
|
|
11419
|
+
return;
|
|
11420
|
+
}
|
|
11421
|
+
await this.s3Client.send(
|
|
11422
|
+
new PutBucketTaggingCommand({
|
|
11423
|
+
Bucket: bucketName,
|
|
11424
|
+
Tagging: { TagSet: newNorm }
|
|
11425
|
+
})
|
|
11426
|
+
);
|
|
11427
|
+
this.logger.debug(`Replaced tag set on bucket ${bucketName} (${newNorm.length} tags)`);
|
|
11428
|
+
}
|
|
11350
11429
|
/**
|
|
11351
11430
|
* Apply CORS configuration
|
|
11352
11431
|
*
|
|
@@ -11890,13 +11969,13 @@ var S3BucketProvider = class {
|
|
|
11890
11969
|
/**
|
|
11891
11970
|
* Apply additional bucket configuration after creation
|
|
11892
11971
|
*/
|
|
11893
|
-
async applyConfiguration(bucketName, properties) {
|
|
11972
|
+
async applyConfiguration(bucketName, properties, skipTags = false) {
|
|
11894
11973
|
const versioningConfig = properties["VersioningConfiguration"];
|
|
11895
11974
|
if (versioningConfig) {
|
|
11896
11975
|
await this.applyVersioning(bucketName, versioningConfig);
|
|
11897
11976
|
}
|
|
11898
11977
|
const tags = properties["Tags"];
|
|
11899
|
-
if (tags && Array.isArray(tags) && tags.length > 0) {
|
|
11978
|
+
if (!skipTags && tags && Array.isArray(tags) && tags.length > 0) {
|
|
11900
11979
|
await this.applyTags(bucketName, tags);
|
|
11901
11980
|
}
|
|
11902
11981
|
const ownershipControls = properties["OwnershipControls"];
|
|
@@ -12035,7 +12114,7 @@ var S3BucketProvider = class {
|
|
|
12035
12114
|
/**
|
|
12036
12115
|
* Update an S3 bucket
|
|
12037
12116
|
*/
|
|
12038
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
12117
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
12039
12118
|
this.logger.debug(`Updating S3 bucket ${logicalId}: ${physicalId}`);
|
|
12040
12119
|
const newBucketName = properties["BucketName"];
|
|
12041
12120
|
if (newBucketName && newBucketName !== physicalId) {
|
|
@@ -12048,7 +12127,17 @@ var S3BucketProvider = class {
|
|
|
12048
12127
|
};
|
|
12049
12128
|
}
|
|
12050
12129
|
try {
|
|
12051
|
-
await this.applyConfiguration(
|
|
12130
|
+
await this.applyConfiguration(
|
|
12131
|
+
physicalId,
|
|
12132
|
+
properties,
|
|
12133
|
+
/* skipTags */
|
|
12134
|
+
true
|
|
12135
|
+
);
|
|
12136
|
+
await this.applyTagDiff(
|
|
12137
|
+
physicalId,
|
|
12138
|
+
previousProperties["Tags"],
|
|
12139
|
+
properties["Tags"]
|
|
12140
|
+
);
|
|
12052
12141
|
const attributes = await this.buildAttributes(physicalId);
|
|
12053
12142
|
this.logger.debug(`Successfully updated S3 bucket ${logicalId}`);
|
|
12054
12143
|
return {
|
|
@@ -12546,10 +12635,20 @@ import {
|
|
|
12546
12635
|
ListQueuesCommand,
|
|
12547
12636
|
ListQueueTagsCommand,
|
|
12548
12637
|
SetQueueAttributesCommand,
|
|
12638
|
+
TagQueueCommand,
|
|
12639
|
+
UntagQueueCommand,
|
|
12549
12640
|
QueueDoesNotExist
|
|
12550
12641
|
} from "@aws-sdk/client-sqs";
|
|
12551
12642
|
import { GetCallerIdentityCommand as GetCallerIdentityCommand4 } from "@aws-sdk/client-sts";
|
|
12552
12643
|
init_aws_clients();
|
|
12644
|
+
function serializeRedrivePolicy(value) {
|
|
12645
|
+
if (value === null || value === void 0)
|
|
12646
|
+
return "";
|
|
12647
|
+
if (typeof value === "object" && Object.keys(value).length === 0) {
|
|
12648
|
+
return "";
|
|
12649
|
+
}
|
|
12650
|
+
return JSON.stringify(value);
|
|
12651
|
+
}
|
|
12553
12652
|
var CDK_TO_SQS_ATTRIBUTES = {
|
|
12554
12653
|
VisibilityTimeout: "VisibilityTimeout",
|
|
12555
12654
|
MaximumMessageSize: "MaximumMessageSize",
|
|
@@ -12608,7 +12707,7 @@ var SQSQueueProvider = class {
|
|
|
12608
12707
|
if (properties[cdkKey] !== void 0) {
|
|
12609
12708
|
const value = properties[cdkKey];
|
|
12610
12709
|
if (cdkKey === "RedrivePolicy" && typeof value === "object") {
|
|
12611
|
-
attributes[sqsKey] =
|
|
12710
|
+
attributes[sqsKey] = serializeRedrivePolicy(value);
|
|
12612
12711
|
} else {
|
|
12613
12712
|
attributes[sqsKey] = String(value);
|
|
12614
12713
|
}
|
|
@@ -12656,7 +12755,7 @@ var SQSQueueProvider = class {
|
|
|
12656
12755
|
/**
|
|
12657
12756
|
* Update an SQS queue
|
|
12658
12757
|
*/
|
|
12659
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
12758
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
12660
12759
|
this.logger.debug(`Updating SQS queue ${logicalId}: ${physicalId}`);
|
|
12661
12760
|
try {
|
|
12662
12761
|
const attributes = {};
|
|
@@ -12666,7 +12765,7 @@ var SQSQueueProvider = class {
|
|
|
12666
12765
|
if (properties[cdkKey] !== void 0) {
|
|
12667
12766
|
const value = properties[cdkKey];
|
|
12668
12767
|
if (cdkKey === "RedrivePolicy" && typeof value === "object") {
|
|
12669
|
-
attributes[sqsKey] =
|
|
12768
|
+
attributes[sqsKey] = serializeRedrivePolicy(value);
|
|
12670
12769
|
} else {
|
|
12671
12770
|
attributes[sqsKey] = String(value);
|
|
12672
12771
|
}
|
|
@@ -12681,6 +12780,11 @@ var SQSQueueProvider = class {
|
|
|
12681
12780
|
);
|
|
12682
12781
|
this.logger.debug(`Updated attributes for SQS queue ${physicalId}`);
|
|
12683
12782
|
}
|
|
12783
|
+
await this.applyTagDiff(
|
|
12784
|
+
physicalId,
|
|
12785
|
+
previousProperties["Tags"],
|
|
12786
|
+
properties["Tags"]
|
|
12787
|
+
);
|
|
12684
12788
|
const getResponse = await this.sqsClient.send(
|
|
12685
12789
|
new GetQueueAttributesCommand({
|
|
12686
12790
|
QueueUrl: physicalId,
|
|
@@ -12739,6 +12843,46 @@ var SQSQueueProvider = class {
|
|
|
12739
12843
|
);
|
|
12740
12844
|
}
|
|
12741
12845
|
}
|
|
12846
|
+
/**
|
|
12847
|
+
* Apply a diff between old and new CFn-shape Tags arrays via SQS's
|
|
12848
|
+
* `TagQueue` / `UntagQueue` APIs. SQS's `TagQueue` takes a `Tags` map
|
|
12849
|
+
* (`{ key: value }`); `UntagQueue` takes a `TagKeys` array. cdkd state
|
|
12850
|
+
* holds Tags in CFn shape (`[{ Key, Value }]`).
|
|
12851
|
+
*/
|
|
12852
|
+
async applyTagDiff(queueUrl, oldTagsRaw, newTagsRaw) {
|
|
12853
|
+
const toMap = (tags) => {
|
|
12854
|
+
const m = /* @__PURE__ */ new Map();
|
|
12855
|
+
for (const t of tags ?? []) {
|
|
12856
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
12857
|
+
m.set(t.Key, t.Value);
|
|
12858
|
+
}
|
|
12859
|
+
return m;
|
|
12860
|
+
};
|
|
12861
|
+
const oldMap = toMap(oldTagsRaw);
|
|
12862
|
+
const newMap = toMap(newTagsRaw);
|
|
12863
|
+
const tagsToAdd = {};
|
|
12864
|
+
for (const [k, v] of newMap) {
|
|
12865
|
+
if (oldMap.get(k) !== v)
|
|
12866
|
+
tagsToAdd[k] = v;
|
|
12867
|
+
}
|
|
12868
|
+
const tagsToRemove = [];
|
|
12869
|
+
for (const k of oldMap.keys()) {
|
|
12870
|
+
if (!newMap.has(k))
|
|
12871
|
+
tagsToRemove.push(k);
|
|
12872
|
+
}
|
|
12873
|
+
if (tagsToRemove.length > 0) {
|
|
12874
|
+
await this.sqsClient.send(
|
|
12875
|
+
new UntagQueueCommand({ QueueUrl: queueUrl, TagKeys: tagsToRemove })
|
|
12876
|
+
);
|
|
12877
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from SQS queue ${queueUrl}`);
|
|
12878
|
+
}
|
|
12879
|
+
if (Object.keys(tagsToAdd).length > 0) {
|
|
12880
|
+
await this.sqsClient.send(new TagQueueCommand({ QueueUrl: queueUrl, Tags: tagsToAdd }));
|
|
12881
|
+
this.logger.debug(
|
|
12882
|
+
`Added/updated ${Object.keys(tagsToAdd).length} tag(s) on SQS queue ${queueUrl}`
|
|
12883
|
+
);
|
|
12884
|
+
}
|
|
12885
|
+
}
|
|
12742
12886
|
/**
|
|
12743
12887
|
* Construct SQS queue ARN from account/region/queue name
|
|
12744
12888
|
*/
|
|
@@ -14080,6 +14224,8 @@ import {
|
|
|
14080
14224
|
GetFunctionCommand,
|
|
14081
14225
|
ListFunctionsCommand,
|
|
14082
14226
|
ListTagsCommand,
|
|
14227
|
+
TagResourceCommand as TagResourceCommand2,
|
|
14228
|
+
UntagResourceCommand as UntagResourceCommand2,
|
|
14083
14229
|
ResourceNotFoundException,
|
|
14084
14230
|
waitUntilFunctionUpdatedV2 as waitUntilFunctionUpdatedV22
|
|
14085
14231
|
} from "@aws-sdk/client-lambda";
|
|
@@ -14297,11 +14443,17 @@ var LambdaFunctionProvider = class {
|
|
|
14297
14443
|
const getResponse = await this.lambdaClient.send(
|
|
14298
14444
|
new GetFunctionCommand({ FunctionName: physicalId })
|
|
14299
14445
|
);
|
|
14446
|
+
const functionArn = getResponse.Configuration?.FunctionArn;
|
|
14447
|
+
await this.applyTagDiff(
|
|
14448
|
+
functionArn,
|
|
14449
|
+
previousProperties["Tags"],
|
|
14450
|
+
properties["Tags"]
|
|
14451
|
+
);
|
|
14300
14452
|
return {
|
|
14301
14453
|
physicalId,
|
|
14302
14454
|
wasReplaced: false,
|
|
14303
14455
|
attributes: {
|
|
14304
|
-
Arn:
|
|
14456
|
+
Arn: functionArn,
|
|
14305
14457
|
FunctionName: getResponse.Configuration?.FunctionName
|
|
14306
14458
|
}
|
|
14307
14459
|
};
|
|
@@ -14493,6 +14645,53 @@ var LambdaFunctionProvider = class {
|
|
|
14493
14645
|
* one resource type that actually needs it preserves the bug fix
|
|
14494
14646
|
* without paying the whole-stack tax.
|
|
14495
14647
|
*/
|
|
14648
|
+
/**
|
|
14649
|
+
* Apply a diff between old and new CFn-shape Tags arrays via Lambda's
|
|
14650
|
+
* `TagResource` / `UntagResource` APIs. Without this, `cdkd deploy`
|
|
14651
|
+
* and `cdkd drift --revert` silently no-op tag changes — the
|
|
14652
|
+
* `UpdateFunctionConfiguration` command does NOT accept a Tags
|
|
14653
|
+
* parameter (Lambda treats tags as a separate API surface).
|
|
14654
|
+
*/
|
|
14655
|
+
async applyTagDiff(functionArn, oldTagsRaw, newTagsRaw) {
|
|
14656
|
+
if (!functionArn)
|
|
14657
|
+
return;
|
|
14658
|
+
const toMap = (tags) => {
|
|
14659
|
+
const m = /* @__PURE__ */ new Map();
|
|
14660
|
+
for (const t of tags ?? []) {
|
|
14661
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
14662
|
+
m.set(t.Key, t.Value);
|
|
14663
|
+
}
|
|
14664
|
+
return m;
|
|
14665
|
+
};
|
|
14666
|
+
const oldMap = toMap(oldTagsRaw);
|
|
14667
|
+
const newMap = toMap(newTagsRaw);
|
|
14668
|
+
const tagsToAdd = {};
|
|
14669
|
+
for (const [k, v] of newMap) {
|
|
14670
|
+
if (oldMap.get(k) !== v)
|
|
14671
|
+
tagsToAdd[k] = v;
|
|
14672
|
+
}
|
|
14673
|
+
const tagsToRemove = [];
|
|
14674
|
+
for (const k of oldMap.keys()) {
|
|
14675
|
+
if (!newMap.has(k))
|
|
14676
|
+
tagsToRemove.push(k);
|
|
14677
|
+
}
|
|
14678
|
+
if (tagsToRemove.length > 0) {
|
|
14679
|
+
await this.lambdaClient.send(
|
|
14680
|
+
new UntagResourceCommand2({ Resource: functionArn, TagKeys: tagsToRemove })
|
|
14681
|
+
);
|
|
14682
|
+
this.logger.debug(
|
|
14683
|
+
`Removed ${tagsToRemove.length} tag(s) from Lambda function ${functionArn}`
|
|
14684
|
+
);
|
|
14685
|
+
}
|
|
14686
|
+
if (Object.keys(tagsToAdd).length > 0) {
|
|
14687
|
+
await this.lambdaClient.send(
|
|
14688
|
+
new TagResourceCommand2({ Resource: functionArn, Tags: tagsToAdd })
|
|
14689
|
+
);
|
|
14690
|
+
this.logger.debug(
|
|
14691
|
+
`Added/updated ${Object.keys(tagsToAdd).length} tag(s) on Lambda function ${functionArn}`
|
|
14692
|
+
);
|
|
14693
|
+
}
|
|
14694
|
+
}
|
|
14496
14695
|
async waitForFunctionUpdated(logicalId, resourceType, functionName) {
|
|
14497
14696
|
try {
|
|
14498
14697
|
await waitUntilFunctionUpdatedV22(
|
|
@@ -14827,14 +15026,11 @@ var LambdaFunctionProvider = class {
|
|
|
14827
15026
|
if (cfg.EphemeralStorage?.Size !== void 0) {
|
|
14828
15027
|
result["EphemeralStorage"] = { Size: cfg.EphemeralStorage.Size };
|
|
14829
15028
|
}
|
|
14830
|
-
|
|
15029
|
+
result["VpcConfig"] = {
|
|
14831
15030
|
SubnetIds: cfg.VpcConfig?.SubnetIds ? [...cfg.VpcConfig.SubnetIds] : [],
|
|
14832
|
-
SecurityGroupIds: cfg.VpcConfig?.SecurityGroupIds ? [...cfg.VpcConfig.SecurityGroupIds] : []
|
|
15031
|
+
SecurityGroupIds: cfg.VpcConfig?.SecurityGroupIds ? [...cfg.VpcConfig.SecurityGroupIds] : [],
|
|
15032
|
+
Ipv6AllowedForDualStack: cfg.VpcConfig?.Ipv6AllowedForDualStack ?? false
|
|
14833
15033
|
};
|
|
14834
|
-
if (cfg.VpcConfig?.Ipv6AllowedForDualStack !== void 0) {
|
|
14835
|
-
vpc["Ipv6AllowedForDualStack"] = cfg.VpcConfig.Ipv6AllowedForDualStack;
|
|
14836
|
-
}
|
|
14837
|
-
result["VpcConfig"] = vpc;
|
|
14838
15034
|
const tags = normalizeAwsTagsToCfn(resp.Tags);
|
|
14839
15035
|
result["Tags"] = tags;
|
|
14840
15036
|
return result;
|
|
@@ -15468,6 +15664,8 @@ import {
|
|
|
15468
15664
|
DeleteEventSourceMappingCommand,
|
|
15469
15665
|
UpdateEventSourceMappingCommand,
|
|
15470
15666
|
GetEventSourceMappingCommand,
|
|
15667
|
+
TagResourceCommand as TagResourceCommand3,
|
|
15668
|
+
UntagResourceCommand as UntagResourceCommand3,
|
|
15471
15669
|
ResourceNotFoundException as ResourceNotFoundException4
|
|
15472
15670
|
} from "@aws-sdk/client-lambda";
|
|
15473
15671
|
init_aws_clients();
|
|
@@ -15591,7 +15789,7 @@ var LambdaEventSourceMappingProvider = class {
|
|
|
15591
15789
|
/**
|
|
15592
15790
|
* Update a Lambda Event Source Mapping
|
|
15593
15791
|
*/
|
|
15594
|
-
async update(logicalId, physicalId, _resourceType, properties,
|
|
15792
|
+
async update(logicalId, physicalId, _resourceType, properties, previousProperties) {
|
|
15595
15793
|
this.logger.debug(`Updating event source mapping ${logicalId}: ${physicalId}`);
|
|
15596
15794
|
const updateParams = {
|
|
15597
15795
|
UUID: physicalId,
|
|
@@ -15625,7 +15823,17 @@ var LambdaEventSourceMappingProvider = class {
|
|
|
15625
15823
|
updateParams.ScalingConfig = properties["ScalingConfig"];
|
|
15626
15824
|
if (properties["DocumentDBEventSourceConfig"])
|
|
15627
15825
|
updateParams.DocumentDBEventSourceConfig = properties["DocumentDBEventSourceConfig"];
|
|
15628
|
-
await this.lambdaClient.send(
|
|
15826
|
+
const updateResp = await this.lambdaClient.send(
|
|
15827
|
+
new UpdateEventSourceMappingCommand(updateParams)
|
|
15828
|
+
);
|
|
15829
|
+
const eventSourceMappingArn = updateResp.EventSourceMappingArn;
|
|
15830
|
+
if (eventSourceMappingArn) {
|
|
15831
|
+
await this.applyTagDiff(
|
|
15832
|
+
eventSourceMappingArn,
|
|
15833
|
+
previousProperties["Tags"],
|
|
15834
|
+
properties["Tags"]
|
|
15835
|
+
);
|
|
15836
|
+
}
|
|
15629
15837
|
this.logger.debug(`Successfully updated event source mapping ${logicalId}`);
|
|
15630
15838
|
return {
|
|
15631
15839
|
physicalId,
|
|
@@ -15635,6 +15843,46 @@ var LambdaEventSourceMappingProvider = class {
|
|
|
15635
15843
|
}
|
|
15636
15844
|
};
|
|
15637
15845
|
}
|
|
15846
|
+
/**
|
|
15847
|
+
* Apply a diff between old and new CFn-shape Tags arrays via Lambda's
|
|
15848
|
+
* `TagResource` / `UntagResource` APIs against the EventSourceMapping
|
|
15849
|
+
* ARN. Lambda's `TagResource` takes `{ Resource, Tags: { key: value } }`;
|
|
15850
|
+
* `UntagResource` takes `{ Resource, TagKeys: [...] }`.
|
|
15851
|
+
*/
|
|
15852
|
+
async applyTagDiff(arn, oldTagsRaw, newTagsRaw) {
|
|
15853
|
+
const toMap = (tags) => {
|
|
15854
|
+
const m = /* @__PURE__ */ new Map();
|
|
15855
|
+
for (const t of tags ?? []) {
|
|
15856
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
15857
|
+
m.set(t.Key, t.Value);
|
|
15858
|
+
}
|
|
15859
|
+
return m;
|
|
15860
|
+
};
|
|
15861
|
+
const oldMap = toMap(oldTagsRaw);
|
|
15862
|
+
const newMap = toMap(newTagsRaw);
|
|
15863
|
+
const tagsToAdd = {};
|
|
15864
|
+
for (const [k, v] of newMap) {
|
|
15865
|
+
if (oldMap.get(k) !== v)
|
|
15866
|
+
tagsToAdd[k] = v;
|
|
15867
|
+
}
|
|
15868
|
+
const tagsToRemove = [];
|
|
15869
|
+
for (const k of oldMap.keys()) {
|
|
15870
|
+
if (!newMap.has(k))
|
|
15871
|
+
tagsToRemove.push(k);
|
|
15872
|
+
}
|
|
15873
|
+
if (tagsToRemove.length > 0) {
|
|
15874
|
+
await this.lambdaClient.send(
|
|
15875
|
+
new UntagResourceCommand3({ Resource: arn, TagKeys: tagsToRemove })
|
|
15876
|
+
);
|
|
15877
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from EventSourceMapping ${arn}`);
|
|
15878
|
+
}
|
|
15879
|
+
if (Object.keys(tagsToAdd).length > 0) {
|
|
15880
|
+
await this.lambdaClient.send(new TagResourceCommand3({ Resource: arn, Tags: tagsToAdd }));
|
|
15881
|
+
this.logger.debug(
|
|
15882
|
+
`Added/updated ${Object.keys(tagsToAdd).length} tag(s) on EventSourceMapping ${arn}`
|
|
15883
|
+
);
|
|
15884
|
+
}
|
|
15885
|
+
}
|
|
15638
15886
|
/**
|
|
15639
15887
|
* Delete a Lambda Event Source Mapping
|
|
15640
15888
|
*/
|
|
@@ -16068,6 +16316,8 @@ import {
|
|
|
16068
16316
|
DescribeTableCommand as DescribeTableCommand2,
|
|
16069
16317
|
ListTablesCommand,
|
|
16070
16318
|
ListTagsOfResourceCommand,
|
|
16319
|
+
TagResourceCommand as TagResourceCommand4,
|
|
16320
|
+
UntagResourceCommand as UntagResourceCommand4,
|
|
16071
16321
|
ResourceNotFoundException as ResourceNotFoundException6
|
|
16072
16322
|
} from "@aws-sdk/client-dynamodb";
|
|
16073
16323
|
init_aws_clients();
|
|
@@ -16193,13 +16443,20 @@ var DynamoDBTableProvider = class {
|
|
|
16193
16443
|
* For immutable property changes (KeySchema, etc.), the deployment layer
|
|
16194
16444
|
* handles replacement via DELETE + CREATE.
|
|
16195
16445
|
*/
|
|
16196
|
-
async update(logicalId, physicalId, resourceType,
|
|
16446
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
16197
16447
|
this.logger.debug(`Updating DynamoDB table ${logicalId}: ${physicalId}`);
|
|
16198
16448
|
try {
|
|
16199
16449
|
const response = await this.dynamoDBClient.send(
|
|
16200
16450
|
new DescribeTableCommand2({ TableName: physicalId })
|
|
16201
16451
|
);
|
|
16202
16452
|
const table = response.Table;
|
|
16453
|
+
if (table?.TableArn) {
|
|
16454
|
+
await this.applyTagDiff(
|
|
16455
|
+
table.TableArn,
|
|
16456
|
+
previousProperties["Tags"],
|
|
16457
|
+
properties["Tags"]
|
|
16458
|
+
);
|
|
16459
|
+
}
|
|
16203
16460
|
return {
|
|
16204
16461
|
physicalId,
|
|
16205
16462
|
wasReplaced: false,
|
|
@@ -16252,6 +16509,45 @@ var DynamoDBTableProvider = class {
|
|
|
16252
16509
|
);
|
|
16253
16510
|
}
|
|
16254
16511
|
}
|
|
16512
|
+
/**
|
|
16513
|
+
* Apply a diff between old and new CFn-shape Tags arrays via DynamoDB's
|
|
16514
|
+
* `TagResource` / `UntagResource` APIs. Both take the table ARN as
|
|
16515
|
+
* `ResourceArn`.
|
|
16516
|
+
*/
|
|
16517
|
+
async applyTagDiff(tableArn, oldTagsRaw, newTagsRaw) {
|
|
16518
|
+
const toMap = (tags) => {
|
|
16519
|
+
const m = /* @__PURE__ */ new Map();
|
|
16520
|
+
for (const t of tags ?? []) {
|
|
16521
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
16522
|
+
m.set(t.Key, t.Value);
|
|
16523
|
+
}
|
|
16524
|
+
return m;
|
|
16525
|
+
};
|
|
16526
|
+
const oldMap = toMap(oldTagsRaw);
|
|
16527
|
+
const newMap = toMap(newTagsRaw);
|
|
16528
|
+
const tagsToAdd = [];
|
|
16529
|
+
for (const [k, v] of newMap) {
|
|
16530
|
+
if (oldMap.get(k) !== v)
|
|
16531
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
16532
|
+
}
|
|
16533
|
+
const tagsToRemove = [];
|
|
16534
|
+
for (const k of oldMap.keys()) {
|
|
16535
|
+
if (!newMap.has(k))
|
|
16536
|
+
tagsToRemove.push(k);
|
|
16537
|
+
}
|
|
16538
|
+
if (tagsToRemove.length > 0) {
|
|
16539
|
+
await this.dynamoDBClient.send(
|
|
16540
|
+
new UntagResourceCommand4({ ResourceArn: tableArn, TagKeys: tagsToRemove })
|
|
16541
|
+
);
|
|
16542
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from DynamoDB table ${tableArn}`);
|
|
16543
|
+
}
|
|
16544
|
+
if (tagsToAdd.length > 0) {
|
|
16545
|
+
await this.dynamoDBClient.send(
|
|
16546
|
+
new TagResourceCommand4({ ResourceArn: tableArn, Tags: tagsToAdd })
|
|
16547
|
+
);
|
|
16548
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on DynamoDB table ${tableArn}`);
|
|
16549
|
+
}
|
|
16550
|
+
}
|
|
16255
16551
|
/**
|
|
16256
16552
|
* Poll DescribeTable until the table reaches ACTIVE status
|
|
16257
16553
|
*
|
|
@@ -16471,8 +16767,8 @@ import {
|
|
|
16471
16767
|
ListTagsForResourceCommand as ListTagsForResourceCommand2,
|
|
16472
16768
|
PutRetentionPolicyCommand,
|
|
16473
16769
|
DeleteRetentionPolicyCommand,
|
|
16474
|
-
TagResourceCommand as
|
|
16475
|
-
UntagResourceCommand as
|
|
16770
|
+
TagResourceCommand as TagResourceCommand5,
|
|
16771
|
+
UntagResourceCommand as UntagResourceCommand5,
|
|
16476
16772
|
PutDataProtectionPolicyCommand,
|
|
16477
16773
|
DeleteDataProtectionPolicyCommand,
|
|
16478
16774
|
ResourceNotFoundException as ResourceNotFoundException7,
|
|
@@ -16622,7 +16918,7 @@ var LogsLogGroupProvider = class {
|
|
|
16622
16918
|
if (oldTags && oldTags.length > 0) {
|
|
16623
16919
|
const oldTagKeys = oldTags.map((t) => t.Key);
|
|
16624
16920
|
await this.logsClient.send(
|
|
16625
|
-
new
|
|
16921
|
+
new UntagResourceCommand5({
|
|
16626
16922
|
resourceArn: arn2,
|
|
16627
16923
|
tagKeys: oldTagKeys
|
|
16628
16924
|
})
|
|
@@ -16631,7 +16927,7 @@ var LogsLogGroupProvider = class {
|
|
|
16631
16927
|
if (newTags && newTags.length > 0) {
|
|
16632
16928
|
const tagsMap = Object.fromEntries(newTags.map((t) => [t.Key, t.Value]));
|
|
16633
16929
|
await this.logsClient.send(
|
|
16634
|
-
new
|
|
16930
|
+
new TagResourceCommand5({
|
|
16635
16931
|
resourceArn: arn2,
|
|
16636
16932
|
tags: tagsMap
|
|
16637
16933
|
})
|
|
@@ -16831,7 +17127,9 @@ import {
|
|
|
16831
17127
|
PutMetricAlarmCommand,
|
|
16832
17128
|
DeleteAlarmsCommand,
|
|
16833
17129
|
DescribeAlarmsCommand,
|
|
16834
|
-
ListTagsForResourceCommand as ListTagsForResourceCommand3
|
|
17130
|
+
ListTagsForResourceCommand as ListTagsForResourceCommand3,
|
|
17131
|
+
TagResourceCommand as TagResourceCommand6,
|
|
17132
|
+
UntagResourceCommand as UntagResourceCommand6
|
|
16835
17133
|
} from "@aws-sdk/client-cloudwatch";
|
|
16836
17134
|
init_aws_clients();
|
|
16837
17135
|
var CloudWatchAlarmProvider = class {
|
|
@@ -16900,7 +17198,7 @@ var CloudWatchAlarmProvider = class {
|
|
|
16900
17198
|
*
|
|
16901
17199
|
* PutMetricAlarm is idempotent - calling it with the same alarm name updates the alarm.
|
|
16902
17200
|
*/
|
|
16903
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
17201
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
16904
17202
|
this.logger.debug(`Updating CloudWatch alarm ${logicalId}: ${physicalId}`);
|
|
16905
17203
|
try {
|
|
16906
17204
|
await this.cloudWatchClient.send(
|
|
@@ -16908,6 +17206,11 @@ var CloudWatchAlarmProvider = class {
|
|
|
16908
17206
|
);
|
|
16909
17207
|
this.logger.debug(`Successfully updated CloudWatch alarm ${logicalId}`);
|
|
16910
17208
|
const alarmArn = await this.getAlarmArn(physicalId);
|
|
17209
|
+
await this.applyTagDiff(
|
|
17210
|
+
alarmArn,
|
|
17211
|
+
previousProperties["Tags"],
|
|
17212
|
+
properties["Tags"]
|
|
17213
|
+
);
|
|
16911
17214
|
return {
|
|
16912
17215
|
physicalId,
|
|
16913
17216
|
wasReplaced: false,
|
|
@@ -16992,6 +17295,44 @@ var CloudWatchAlarmProvider = class {
|
|
|
16992
17295
|
return `arn:aws:cloudwatch:*:*:alarm:${alarmName}`;
|
|
16993
17296
|
}
|
|
16994
17297
|
}
|
|
17298
|
+
/**
|
|
17299
|
+
* Apply a diff between old and new CFn-shape Tags arrays via CloudWatch's
|
|
17300
|
+
* `TagResource` / `UntagResource` APIs (keyed by `ResourceARN`).
|
|
17301
|
+
*/
|
|
17302
|
+
async applyTagDiff(resourceArn, oldTagsRaw, newTagsRaw) {
|
|
17303
|
+
const toMap = (tags) => {
|
|
17304
|
+
const m = /* @__PURE__ */ new Map();
|
|
17305
|
+
for (const t of tags ?? []) {
|
|
17306
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
17307
|
+
m.set(t.Key, t.Value);
|
|
17308
|
+
}
|
|
17309
|
+
return m;
|
|
17310
|
+
};
|
|
17311
|
+
const oldMap = toMap(oldTagsRaw);
|
|
17312
|
+
const newMap = toMap(newTagsRaw);
|
|
17313
|
+
const tagsToAdd = [];
|
|
17314
|
+
for (const [k, v] of newMap) {
|
|
17315
|
+
if (oldMap.get(k) !== v)
|
|
17316
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
17317
|
+
}
|
|
17318
|
+
const tagsToRemove = [];
|
|
17319
|
+
for (const k of oldMap.keys()) {
|
|
17320
|
+
if (!newMap.has(k))
|
|
17321
|
+
tagsToRemove.push(k);
|
|
17322
|
+
}
|
|
17323
|
+
if (tagsToRemove.length > 0) {
|
|
17324
|
+
await this.cloudWatchClient.send(
|
|
17325
|
+
new UntagResourceCommand6({ ResourceARN: resourceArn, TagKeys: tagsToRemove })
|
|
17326
|
+
);
|
|
17327
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from alarm ${resourceArn}`);
|
|
17328
|
+
}
|
|
17329
|
+
if (tagsToAdd.length > 0) {
|
|
17330
|
+
await this.cloudWatchClient.send(
|
|
17331
|
+
new TagResourceCommand6({ ResourceARN: resourceArn, Tags: tagsToAdd })
|
|
17332
|
+
);
|
|
17333
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on alarm ${resourceArn}`);
|
|
17334
|
+
}
|
|
17335
|
+
}
|
|
16995
17336
|
/**
|
|
16996
17337
|
* Build PutMetricAlarm parameters from CDK properties
|
|
16997
17338
|
*/
|
|
@@ -17184,8 +17525,8 @@ import {
|
|
|
17184
17525
|
DescribeSecretCommand,
|
|
17185
17526
|
ListSecretsCommand,
|
|
17186
17527
|
UpdateSecretCommand,
|
|
17187
|
-
TagResourceCommand as
|
|
17188
|
-
UntagResourceCommand as
|
|
17528
|
+
TagResourceCommand as TagResourceCommand7,
|
|
17529
|
+
UntagResourceCommand as UntagResourceCommand7,
|
|
17189
17530
|
ReplicateSecretToRegionsCommand,
|
|
17190
17531
|
RemoveRegionsFromReplicationCommand,
|
|
17191
17532
|
ResourceNotFoundException as ResourceNotFoundException8
|
|
@@ -17298,7 +17639,7 @@ var SecretsManagerSecretProvider = class {
|
|
|
17298
17639
|
const oldTagKeys = oldTags.map((t) => t.Key).filter((k) => !!k);
|
|
17299
17640
|
if (oldTagKeys.length > 0) {
|
|
17300
17641
|
await this.smClient.send(
|
|
17301
|
-
new
|
|
17642
|
+
new UntagResourceCommand7({
|
|
17302
17643
|
SecretId: physicalId,
|
|
17303
17644
|
TagKeys: oldTagKeys
|
|
17304
17645
|
})
|
|
@@ -17307,7 +17648,7 @@ var SecretsManagerSecretProvider = class {
|
|
|
17307
17648
|
}
|
|
17308
17649
|
if (newTags && newTags.length > 0) {
|
|
17309
17650
|
await this.smClient.send(
|
|
17310
|
-
new
|
|
17651
|
+
new TagResourceCommand7({
|
|
17311
17652
|
SecretId: physicalId,
|
|
17312
17653
|
Tags: newTags
|
|
17313
17654
|
})
|
|
@@ -17911,8 +18252,8 @@ import {
|
|
|
17911
18252
|
ListRulesCommand,
|
|
17912
18253
|
ListTargetsByRuleCommand,
|
|
17913
18254
|
ListTagsForResourceCommand as ListTagsForResourceCommand5,
|
|
17914
|
-
TagResourceCommand as
|
|
17915
|
-
UntagResourceCommand as
|
|
18255
|
+
TagResourceCommand as TagResourceCommand8,
|
|
18256
|
+
UntagResourceCommand as UntagResourceCommand8,
|
|
17916
18257
|
ResourceNotFoundException as ResourceNotFoundException9
|
|
17917
18258
|
} from "@aws-sdk/client-eventbridge";
|
|
17918
18259
|
init_aws_clients();
|
|
@@ -18065,7 +18406,7 @@ var EventBridgeRuleProvider = class {
|
|
|
18065
18406
|
const oldTagKeys = oldTags.map((t) => t.Key).filter((k) => !!k);
|
|
18066
18407
|
if (oldTagKeys.length > 0) {
|
|
18067
18408
|
await this.eventBridgeClient.send(
|
|
18068
|
-
new
|
|
18409
|
+
new UntagResourceCommand8({
|
|
18069
18410
|
ResourceARN: ruleArn,
|
|
18070
18411
|
TagKeys: oldTagKeys
|
|
18071
18412
|
})
|
|
@@ -18074,7 +18415,7 @@ var EventBridgeRuleProvider = class {
|
|
|
18074
18415
|
}
|
|
18075
18416
|
if (newTags && newTags.length > 0) {
|
|
18076
18417
|
await this.eventBridgeClient.send(
|
|
18077
|
-
new
|
|
18418
|
+
new TagResourceCommand8({
|
|
18078
18419
|
ResourceARN: ruleArn,
|
|
18079
18420
|
Tags: newTags
|
|
18080
18421
|
})
|
|
@@ -18381,8 +18722,8 @@ import {
|
|
|
18381
18722
|
RemoveTargetsCommand as RemoveTargetsCommand2,
|
|
18382
18723
|
DeleteRuleCommand as DeleteRuleCommand2,
|
|
18383
18724
|
ListTargetsByRuleCommand as ListTargetsByRuleCommand2,
|
|
18384
|
-
TagResourceCommand as
|
|
18385
|
-
UntagResourceCommand as
|
|
18725
|
+
TagResourceCommand as TagResourceCommand9,
|
|
18726
|
+
UntagResourceCommand as UntagResourceCommand9,
|
|
18386
18727
|
ResourceNotFoundException as ResourceNotFoundException10
|
|
18387
18728
|
} from "@aws-sdk/client-eventbridge";
|
|
18388
18729
|
init_aws_clients();
|
|
@@ -18495,7 +18836,7 @@ var EventBridgeBusProvider = class {
|
|
|
18495
18836
|
const oldTagKeys = oldTags.map((t) => t.Key).filter((k) => !!k);
|
|
18496
18837
|
if (oldTagKeys.length > 0) {
|
|
18497
18838
|
await this.eventBridgeClient.send(
|
|
18498
|
-
new
|
|
18839
|
+
new UntagResourceCommand9({
|
|
18499
18840
|
ResourceARN: busArn,
|
|
18500
18841
|
TagKeys: oldTagKeys
|
|
18501
18842
|
})
|
|
@@ -18504,7 +18845,7 @@ var EventBridgeBusProvider = class {
|
|
|
18504
18845
|
}
|
|
18505
18846
|
if (newTags && newTags.length > 0) {
|
|
18506
18847
|
await this.eventBridgeClient.send(
|
|
18507
|
-
new
|
|
18848
|
+
new TagResourceCommand9({
|
|
18508
18849
|
ResourceARN: busArn,
|
|
18509
18850
|
Tags: newTags
|
|
18510
18851
|
})
|
|
@@ -18756,6 +19097,7 @@ import {
|
|
|
18756
19097
|
AuthorizeSecurityGroupEgressCommand,
|
|
18757
19098
|
RevokeSecurityGroupEgressCommand,
|
|
18758
19099
|
CreateTagsCommand,
|
|
19100
|
+
DeleteTagsCommand,
|
|
18759
19101
|
DescribeSubnetsCommand as DescribeSubnetsCommand2,
|
|
18760
19102
|
DescribeSecurityGroupsCommand as DescribeSecurityGroupsCommand2,
|
|
18761
19103
|
RunInstancesCommand,
|
|
@@ -18920,7 +19262,7 @@ var EC2Provider = class {
|
|
|
18920
19262
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
18921
19263
|
switch (resourceType) {
|
|
18922
19264
|
case "AWS::EC2::VPC":
|
|
18923
|
-
return this.updateVpc(logicalId, physicalId, resourceType, properties);
|
|
19265
|
+
return this.updateVpc(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
18924
19266
|
case "AWS::EC2::Subnet":
|
|
18925
19267
|
return this.updateSubnet(logicalId, physicalId);
|
|
18926
19268
|
case "AWS::EC2::InternetGateway":
|
|
@@ -18958,7 +19300,13 @@ var EC2Provider = class {
|
|
|
18958
19300
|
previousProperties
|
|
18959
19301
|
);
|
|
18960
19302
|
case "AWS::EC2::Instance":
|
|
18961
|
-
return this.updateInstance(
|
|
19303
|
+
return this.updateInstance(
|
|
19304
|
+
logicalId,
|
|
19305
|
+
physicalId,
|
|
19306
|
+
resourceType,
|
|
19307
|
+
properties,
|
|
19308
|
+
previousProperties
|
|
19309
|
+
);
|
|
18962
19310
|
case "AWS::EC2::NetworkAcl":
|
|
18963
19311
|
case "AWS::EC2::NetworkAclEntry":
|
|
18964
19312
|
case "AWS::EC2::SubnetNetworkAclAssociation":
|
|
@@ -19104,7 +19452,7 @@ var EC2Provider = class {
|
|
|
19104
19452
|
);
|
|
19105
19453
|
}
|
|
19106
19454
|
}
|
|
19107
|
-
async updateVpc(logicalId, physicalId, resourceType, properties) {
|
|
19455
|
+
async updateVpc(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
19108
19456
|
this.logger.debug(`Updating VPC ${logicalId}: ${physicalId}`);
|
|
19109
19457
|
try {
|
|
19110
19458
|
if (properties["EnableDnsHostnames"] !== void 0) {
|
|
@@ -19125,7 +19473,11 @@ var EC2Provider = class {
|
|
|
19125
19473
|
})
|
|
19126
19474
|
);
|
|
19127
19475
|
}
|
|
19128
|
-
await this.
|
|
19476
|
+
await this.applyTagDiff(
|
|
19477
|
+
physicalId,
|
|
19478
|
+
previousProperties["Tags"],
|
|
19479
|
+
properties["Tags"]
|
|
19480
|
+
);
|
|
19129
19481
|
this.logger.debug(`Successfully updated VPC ${logicalId}`);
|
|
19130
19482
|
return {
|
|
19131
19483
|
physicalId,
|
|
@@ -19995,7 +20347,11 @@ var EC2Provider = class {
|
|
|
19995
20347
|
async updateSecurityGroup(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
19996
20348
|
this.logger.debug(`Updating SecurityGroup ${logicalId}: ${physicalId}`);
|
|
19997
20349
|
try {
|
|
19998
|
-
await this.
|
|
20350
|
+
await this.applyTagDiff(
|
|
20351
|
+
physicalId,
|
|
20352
|
+
previousProperties["Tags"],
|
|
20353
|
+
properties["Tags"]
|
|
20354
|
+
);
|
|
19999
20355
|
await this.applySecurityGroupRuleDiff(
|
|
20000
20356
|
physicalId,
|
|
20001
20357
|
previousProperties["SecurityGroupIngress"] ?? [],
|
|
@@ -20323,10 +20679,14 @@ var EC2Provider = class {
|
|
|
20323
20679
|
);
|
|
20324
20680
|
}
|
|
20325
20681
|
}
|
|
20326
|
-
async updateInstance(logicalId, physicalId, resourceType,
|
|
20682
|
+
async updateInstance(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
20327
20683
|
this.logger.debug(`Updating EC2 Instance ${logicalId}: ${physicalId}`);
|
|
20328
20684
|
try {
|
|
20329
|
-
await this.
|
|
20685
|
+
await this.applyTagDiff(
|
|
20686
|
+
physicalId,
|
|
20687
|
+
previousProperties["Tags"],
|
|
20688
|
+
properties["Tags"]
|
|
20689
|
+
);
|
|
20330
20690
|
const describeResponse = await this.ec2Client.send(
|
|
20331
20691
|
new DescribeInstancesCommand({ InstanceIds: [physicalId] })
|
|
20332
20692
|
);
|
|
@@ -20801,7 +21161,10 @@ var EC2Provider = class {
|
|
|
20801
21161
|
}
|
|
20802
21162
|
}
|
|
20803
21163
|
/**
|
|
20804
|
-
* Apply tags to an EC2 resource
|
|
21164
|
+
* Apply tags to an EC2 resource (create-time, no removal).
|
|
21165
|
+
*
|
|
21166
|
+
* Used by `create*` paths. Update paths should use `applyTagDiff` instead
|
|
21167
|
+
* to handle tag removal too.
|
|
20805
21168
|
*/
|
|
20806
21169
|
async applyTags(resourceId, properties, logicalId) {
|
|
20807
21170
|
const tags = properties["Tags"];
|
|
@@ -20821,6 +21184,64 @@ var EC2Provider = class {
|
|
|
20821
21184
|
}
|
|
20822
21185
|
}
|
|
20823
21186
|
}
|
|
21187
|
+
/**
|
|
21188
|
+
* Apply a diff between old and new CFn-shape Tags arrays via EC2's
|
|
21189
|
+
* `CreateTags` / `DeleteTags` APIs. Used by `update*` paths so that
|
|
21190
|
+
* tag removals reach AWS too. EC2 keys both APIs by a list of resource
|
|
21191
|
+
* ids.
|
|
21192
|
+
*/
|
|
21193
|
+
async applyTagDiff(resourceId, oldTagsRaw, newTagsRaw) {
|
|
21194
|
+
const toMap = (tags) => {
|
|
21195
|
+
const m = /* @__PURE__ */ new Map();
|
|
21196
|
+
for (const t of tags ?? []) {
|
|
21197
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
21198
|
+
m.set(t.Key, t.Value);
|
|
21199
|
+
}
|
|
21200
|
+
return m;
|
|
21201
|
+
};
|
|
21202
|
+
const oldMap = toMap(oldTagsRaw);
|
|
21203
|
+
const newMap = toMap(newTagsRaw);
|
|
21204
|
+
const tagsToAdd = [];
|
|
21205
|
+
for (const [k, v] of newMap) {
|
|
21206
|
+
if (oldMap.get(k) !== v)
|
|
21207
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
21208
|
+
}
|
|
21209
|
+
const tagsToRemove = [];
|
|
21210
|
+
for (const k of oldMap.keys()) {
|
|
21211
|
+
if (!newMap.has(k))
|
|
21212
|
+
tagsToRemove.push({ Key: k });
|
|
21213
|
+
}
|
|
21214
|
+
if (tagsToRemove.length > 0) {
|
|
21215
|
+
try {
|
|
21216
|
+
await this.ec2Client.send(
|
|
21217
|
+
new DeleteTagsCommand({
|
|
21218
|
+
Resources: [resourceId],
|
|
21219
|
+
Tags: tagsToRemove
|
|
21220
|
+
})
|
|
21221
|
+
);
|
|
21222
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from ${resourceId}`);
|
|
21223
|
+
} catch (error) {
|
|
21224
|
+
this.logger.warn(
|
|
21225
|
+
`Failed to remove tags from ${resourceId}: ${error instanceof Error ? error.message : String(error)}`
|
|
21226
|
+
);
|
|
21227
|
+
}
|
|
21228
|
+
}
|
|
21229
|
+
if (tagsToAdd.length > 0) {
|
|
21230
|
+
try {
|
|
21231
|
+
await this.ec2Client.send(
|
|
21232
|
+
new CreateTagsCommand({
|
|
21233
|
+
Resources: [resourceId],
|
|
21234
|
+
Tags: tagsToAdd
|
|
21235
|
+
})
|
|
21236
|
+
);
|
|
21237
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on ${resourceId}`);
|
|
21238
|
+
} catch (error) {
|
|
21239
|
+
this.logger.warn(
|
|
21240
|
+
`Failed to add tags on ${resourceId}: ${error instanceof Error ? error.message : String(error)}`
|
|
21241
|
+
);
|
|
21242
|
+
}
|
|
21243
|
+
}
|
|
21244
|
+
}
|
|
20824
21245
|
/**
|
|
20825
21246
|
* Check if an error indicates the resource was not found
|
|
20826
21247
|
*/
|
|
@@ -21167,6 +21588,8 @@ import {
|
|
|
21167
21588
|
CreateAuthorizerCommand,
|
|
21168
21589
|
DeleteAuthorizerCommand,
|
|
21169
21590
|
GetAuthorizerCommand,
|
|
21591
|
+
TagResourceCommand as TagResourceCommand10,
|
|
21592
|
+
UntagResourceCommand as UntagResourceCommand10,
|
|
21170
21593
|
NotFoundException as NotFoundException3
|
|
21171
21594
|
} from "@aws-sdk/client-api-gateway";
|
|
21172
21595
|
init_aws_clients();
|
|
@@ -21890,24 +22313,24 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
21890
22313
|
value: description ?? ""
|
|
21891
22314
|
});
|
|
21892
22315
|
}
|
|
21893
|
-
if (patchOperations.length === 0) {
|
|
21894
|
-
this.logger.debug(`No changes detected for API Gateway Stage ${logicalId}`);
|
|
21895
|
-
return {
|
|
21896
|
-
physicalId,
|
|
21897
|
-
wasReplaced: false,
|
|
21898
|
-
attributes: {
|
|
21899
|
-
StageName: physicalId
|
|
21900
|
-
}
|
|
21901
|
-
};
|
|
21902
|
-
}
|
|
21903
22316
|
try {
|
|
21904
|
-
|
|
21905
|
-
|
|
21906
|
-
|
|
21907
|
-
|
|
21908
|
-
|
|
21909
|
-
|
|
21910
|
-
|
|
22317
|
+
if (patchOperations.length > 0) {
|
|
22318
|
+
await this.apiGatewayClient.send(
|
|
22319
|
+
new UpdateStageCommand({
|
|
22320
|
+
restApiId,
|
|
22321
|
+
stageName: physicalId,
|
|
22322
|
+
patchOperations
|
|
22323
|
+
})
|
|
22324
|
+
);
|
|
22325
|
+
}
|
|
22326
|
+
const stageArn = await this.buildStageArn(restApiId, physicalId);
|
|
22327
|
+
if (stageArn) {
|
|
22328
|
+
await this.applyTagDiff(
|
|
22329
|
+
stageArn,
|
|
22330
|
+
previousProperties["Tags"],
|
|
22331
|
+
properties["Tags"]
|
|
22332
|
+
);
|
|
22333
|
+
}
|
|
21911
22334
|
this.logger.debug(`Successfully updated API Gateway Stage ${logicalId}`);
|
|
21912
22335
|
return {
|
|
21913
22336
|
physicalId,
|
|
@@ -22142,6 +22565,63 @@ var ApiGatewayProvider = class _ApiGatewayProvider {
|
|
|
22142
22565
|
}
|
|
22143
22566
|
return Promise.resolve(void 0);
|
|
22144
22567
|
}
|
|
22568
|
+
/**
|
|
22569
|
+
* Build the ARN for an API Gateway Stage, used for tag mutations.
|
|
22570
|
+
*
|
|
22571
|
+
* Format: `arn:aws:apigateway:{region}::/restapis/{restApiId}/stages/{stageName}`.
|
|
22572
|
+
* The double colon (`::`) is intentional: API Gateway tagging uses an
|
|
22573
|
+
* account-id-less ARN.
|
|
22574
|
+
*/
|
|
22575
|
+
async buildStageArn(restApiId, stageName) {
|
|
22576
|
+
try {
|
|
22577
|
+
const region = await this.apiGatewayClient.config.region();
|
|
22578
|
+
return `arn:aws:apigateway:${region}::/restapis/${restApiId}/stages/${stageName}`;
|
|
22579
|
+
} catch {
|
|
22580
|
+
return void 0;
|
|
22581
|
+
}
|
|
22582
|
+
}
|
|
22583
|
+
/**
|
|
22584
|
+
* Apply a diff between old and new CFn-shape Tags arrays via API Gateway's
|
|
22585
|
+
* `TagResource` / `UntagResource` APIs. API Gateway's `TagResource` takes
|
|
22586
|
+
* lowercase camelCase fields plus a tag-map (`{ resourceArn, tags: {key: value} }`);
|
|
22587
|
+
* `UntagResource` takes `{ resourceArn, tagKeys: [...] }`.
|
|
22588
|
+
*/
|
|
22589
|
+
async applyTagDiff(resourceArn, oldTagsRaw, newTagsRaw) {
|
|
22590
|
+
const toMap = (tags) => {
|
|
22591
|
+
const m = /* @__PURE__ */ new Map();
|
|
22592
|
+
for (const t of tags ?? []) {
|
|
22593
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
22594
|
+
m.set(t.Key, t.Value);
|
|
22595
|
+
}
|
|
22596
|
+
return m;
|
|
22597
|
+
};
|
|
22598
|
+
const oldMap = toMap(oldTagsRaw);
|
|
22599
|
+
const newMap = toMap(newTagsRaw);
|
|
22600
|
+
const tagsToAdd = {};
|
|
22601
|
+
for (const [k, v] of newMap) {
|
|
22602
|
+
if (oldMap.get(k) !== v)
|
|
22603
|
+
tagsToAdd[k] = v;
|
|
22604
|
+
}
|
|
22605
|
+
const tagsToRemove = [];
|
|
22606
|
+
for (const k of oldMap.keys()) {
|
|
22607
|
+
if (!newMap.has(k))
|
|
22608
|
+
tagsToRemove.push(k);
|
|
22609
|
+
}
|
|
22610
|
+
if (tagsToRemove.length > 0) {
|
|
22611
|
+
await this.apiGatewayClient.send(
|
|
22612
|
+
new UntagResourceCommand10({ resourceArn, tagKeys: tagsToRemove })
|
|
22613
|
+
);
|
|
22614
|
+
this.logger.debug(
|
|
22615
|
+
`Removed ${tagsToRemove.length} tag(s) from API Gateway resource ${resourceArn}`
|
|
22616
|
+
);
|
|
22617
|
+
}
|
|
22618
|
+
if (Object.keys(tagsToAdd).length > 0) {
|
|
22619
|
+
await this.apiGatewayClient.send(new TagResourceCommand10({ resourceArn, tags: tagsToAdd }));
|
|
22620
|
+
this.logger.debug(
|
|
22621
|
+
`Added/updated ${Object.keys(tagsToAdd).length} tag(s) on API Gateway resource ${resourceArn}`
|
|
22622
|
+
);
|
|
22623
|
+
}
|
|
22624
|
+
}
|
|
22145
22625
|
/**
|
|
22146
22626
|
* Sleep for specified milliseconds
|
|
22147
22627
|
*/
|
|
@@ -24175,6 +24655,8 @@ import {
|
|
|
24175
24655
|
DescribeStateMachineCommand,
|
|
24176
24656
|
ListStateMachinesCommand,
|
|
24177
24657
|
ListTagsForResourceCommand as ListTagsForResourceCommand8,
|
|
24658
|
+
TagResourceCommand as TagResourceCommand11,
|
|
24659
|
+
UntagResourceCommand as UntagResourceCommand11,
|
|
24178
24660
|
StateMachineDoesNotExist
|
|
24179
24661
|
} from "@aws-sdk/client-sfn";
|
|
24180
24662
|
var StepFunctionsProvider = class {
|
|
@@ -24277,7 +24759,7 @@ var StepFunctionsProvider = class {
|
|
|
24277
24759
|
/**
|
|
24278
24760
|
* Update a Step Functions state machine
|
|
24279
24761
|
*/
|
|
24280
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
24762
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
24281
24763
|
this.logger.debug(`Updating Step Functions state machine ${logicalId}: ${physicalId}`);
|
|
24282
24764
|
try {
|
|
24283
24765
|
const definitionString = this.buildDefinitionString(properties);
|
|
@@ -24301,6 +24783,11 @@ var StepFunctionsProvider = class {
|
|
|
24301
24783
|
})
|
|
24302
24784
|
);
|
|
24303
24785
|
this.logger.debug(`Updated Step Functions state machine ${physicalId}`);
|
|
24786
|
+
await this.applyTagDiff(
|
|
24787
|
+
physicalId,
|
|
24788
|
+
previousProperties["Tags"],
|
|
24789
|
+
properties["Tags"]
|
|
24790
|
+
);
|
|
24304
24791
|
const describeResponse = await this.getClient().send(
|
|
24305
24792
|
new DescribeStateMachineCommand({ stateMachineArn: physicalId })
|
|
24306
24793
|
);
|
|
@@ -24502,6 +24989,49 @@ var StepFunctionsProvider = class {
|
|
|
24502
24989
|
} while (nextToken);
|
|
24503
24990
|
return null;
|
|
24504
24991
|
}
|
|
24992
|
+
/**
|
|
24993
|
+
* Apply a diff between old and new CFn-shape Tags arrays via SFN's
|
|
24994
|
+
* `TagResource` / `UntagResource` APIs. SFN uses lowercase camelCase
|
|
24995
|
+
* (`{ key, value }`) for tags.
|
|
24996
|
+
*/
|
|
24997
|
+
async applyTagDiff(stateMachineArn, oldTagsRaw, newTagsRaw) {
|
|
24998
|
+
const toMap = (tags) => {
|
|
24999
|
+
const m = /* @__PURE__ */ new Map();
|
|
25000
|
+
for (const t of tags ?? []) {
|
|
25001
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
25002
|
+
m.set(t.Key, t.Value);
|
|
25003
|
+
}
|
|
25004
|
+
return m;
|
|
25005
|
+
};
|
|
25006
|
+
const oldMap = toMap(oldTagsRaw);
|
|
25007
|
+
const newMap = toMap(newTagsRaw);
|
|
25008
|
+
const tagsToAdd = [];
|
|
25009
|
+
for (const [k, v] of newMap) {
|
|
25010
|
+
if (oldMap.get(k) !== v)
|
|
25011
|
+
tagsToAdd.push({ key: k, value: v });
|
|
25012
|
+
}
|
|
25013
|
+
const tagsToRemove = [];
|
|
25014
|
+
for (const k of oldMap.keys()) {
|
|
25015
|
+
if (!newMap.has(k))
|
|
25016
|
+
tagsToRemove.push(k);
|
|
25017
|
+
}
|
|
25018
|
+
if (tagsToRemove.length > 0) {
|
|
25019
|
+
await this.getClient().send(
|
|
25020
|
+
new UntagResourceCommand11({ resourceArn: stateMachineArn, tagKeys: tagsToRemove })
|
|
25021
|
+
);
|
|
25022
|
+
this.logger.debug(
|
|
25023
|
+
`Removed ${tagsToRemove.length} tag(s) from SFN state machine ${stateMachineArn}`
|
|
25024
|
+
);
|
|
25025
|
+
}
|
|
25026
|
+
if (tagsToAdd.length > 0) {
|
|
25027
|
+
await this.getClient().send(
|
|
25028
|
+
new TagResourceCommand11({ resourceArn: stateMachineArn, tags: tagsToAdd })
|
|
25029
|
+
);
|
|
25030
|
+
this.logger.debug(
|
|
25031
|
+
`Added/updated ${tagsToAdd.length} tag(s) on SFN state machine ${stateMachineArn}`
|
|
25032
|
+
);
|
|
25033
|
+
}
|
|
25034
|
+
}
|
|
24505
25035
|
/**
|
|
24506
25036
|
* Match SFN's lowercase `key`/`value` tag shape against the CDK path.
|
|
24507
25037
|
*/
|
|
@@ -24553,7 +25083,9 @@ import {
|
|
|
24553
25083
|
DescribeServicesCommand,
|
|
24554
25084
|
ListClustersCommand,
|
|
24555
25085
|
ListServicesCommand,
|
|
24556
|
-
ListTagsForResourceCommand as ListTagsForResourceCommand9
|
|
25086
|
+
ListTagsForResourceCommand as ListTagsForResourceCommand9,
|
|
25087
|
+
TagResourceCommand as TagResourceCommand12,
|
|
25088
|
+
UntagResourceCommand as UntagResourceCommand12
|
|
24557
25089
|
} from "@aws-sdk/client-ecs";
|
|
24558
25090
|
function convertTags(tags) {
|
|
24559
25091
|
if (!tags || tags.length === 0)
|
|
@@ -24648,7 +25180,13 @@ var ECSProvider = class {
|
|
|
24648
25180
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
24649
25181
|
switch (resourceType) {
|
|
24650
25182
|
case "AWS::ECS::Cluster":
|
|
24651
|
-
return this.updateCluster(
|
|
25183
|
+
return this.updateCluster(
|
|
25184
|
+
logicalId,
|
|
25185
|
+
physicalId,
|
|
25186
|
+
resourceType,
|
|
25187
|
+
properties,
|
|
25188
|
+
previousProperties
|
|
25189
|
+
);
|
|
24652
25190
|
case "AWS::ECS::TaskDefinition":
|
|
24653
25191
|
return this.updateTaskDefinition(logicalId, physicalId, resourceType, properties);
|
|
24654
25192
|
case "AWS::ECS::Service":
|
|
@@ -24740,7 +25278,7 @@ var ECSProvider = class {
|
|
|
24740
25278
|
);
|
|
24741
25279
|
}
|
|
24742
25280
|
}
|
|
24743
|
-
async updateCluster(logicalId, physicalId, resourceType, properties) {
|
|
25281
|
+
async updateCluster(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
24744
25282
|
this.logger.debug(`Updating ECS cluster ${logicalId}: ${physicalId}`);
|
|
24745
25283
|
const client = this.getClient();
|
|
24746
25284
|
try {
|
|
@@ -24758,6 +25296,13 @@ var ECSProvider = class {
|
|
|
24758
25296
|
new DescribeClustersCommand({ clusters: [physicalId] })
|
|
24759
25297
|
);
|
|
24760
25298
|
const cluster = describeResponse.clusters?.[0];
|
|
25299
|
+
if (cluster?.clusterArn) {
|
|
25300
|
+
await this.applyTagDiff(
|
|
25301
|
+
cluster.clusterArn,
|
|
25302
|
+
previousProperties["Tags"],
|
|
25303
|
+
properties["Tags"]
|
|
25304
|
+
);
|
|
25305
|
+
}
|
|
24761
25306
|
return {
|
|
24762
25307
|
physicalId,
|
|
24763
25308
|
wasReplaced: false,
|
|
@@ -25026,6 +25571,13 @@ var ECSProvider = class {
|
|
|
25026
25571
|
})
|
|
25027
25572
|
);
|
|
25028
25573
|
const service = response.service;
|
|
25574
|
+
if (service?.serviceArn) {
|
|
25575
|
+
await this.applyTagDiff(
|
|
25576
|
+
service.serviceArn,
|
|
25577
|
+
previousProperties["Tags"],
|
|
25578
|
+
properties["Tags"]
|
|
25579
|
+
);
|
|
25580
|
+
}
|
|
25029
25581
|
return {
|
|
25030
25582
|
physicalId,
|
|
25031
25583
|
wasReplaced: false,
|
|
@@ -25127,6 +25679,42 @@ var ECSProvider = class {
|
|
|
25127
25679
|
}
|
|
25128
25680
|
}
|
|
25129
25681
|
// ─── Helpers ────────────────────────────────────────────────────
|
|
25682
|
+
/**
|
|
25683
|
+
* Apply a diff between old and new CFn-shape Tags arrays via ECS's
|
|
25684
|
+
* `TagResource` / `UntagResource` APIs. ECS uses lowercase camelCase
|
|
25685
|
+
* (`{ key, value }`) for tags. Resource ARN identifies the cluster /
|
|
25686
|
+
* service / task definition.
|
|
25687
|
+
*/
|
|
25688
|
+
async applyTagDiff(resourceArn, oldTagsRaw, newTagsRaw) {
|
|
25689
|
+
const toMap = (tags) => {
|
|
25690
|
+
const m = /* @__PURE__ */ new Map();
|
|
25691
|
+
for (const t of tags ?? []) {
|
|
25692
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
25693
|
+
m.set(t.Key, t.Value);
|
|
25694
|
+
}
|
|
25695
|
+
return m;
|
|
25696
|
+
};
|
|
25697
|
+
const oldMap = toMap(oldTagsRaw);
|
|
25698
|
+
const newMap = toMap(newTagsRaw);
|
|
25699
|
+
const tagsToAdd = [];
|
|
25700
|
+
for (const [k, v] of newMap) {
|
|
25701
|
+
if (oldMap.get(k) !== v)
|
|
25702
|
+
tagsToAdd.push({ key: k, value: v });
|
|
25703
|
+
}
|
|
25704
|
+
const tagsToRemove = [];
|
|
25705
|
+
for (const k of oldMap.keys()) {
|
|
25706
|
+
if (!newMap.has(k))
|
|
25707
|
+
tagsToRemove.push(k);
|
|
25708
|
+
}
|
|
25709
|
+
if (tagsToRemove.length > 0) {
|
|
25710
|
+
await this.getClient().send(new UntagResourceCommand12({ resourceArn, tagKeys: tagsToRemove }));
|
|
25711
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from ECS resource ${resourceArn}`);
|
|
25712
|
+
}
|
|
25713
|
+
if (tagsToAdd.length > 0) {
|
|
25714
|
+
await this.getClient().send(new TagResourceCommand12({ resourceArn, tags: tagsToAdd }));
|
|
25715
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on ECS resource ${resourceArn}`);
|
|
25716
|
+
}
|
|
25717
|
+
}
|
|
25130
25718
|
/**
|
|
25131
25719
|
* Convert CFn ContainerDefinitions to ECS SDK format.
|
|
25132
25720
|
* CFn uses PascalCase, ECS SDK uses camelCase.
|
|
@@ -25574,6 +26162,8 @@ import {
|
|
|
25574
26162
|
ModifyTargetGroupCommand,
|
|
25575
26163
|
DescribeTargetGroupsCommand,
|
|
25576
26164
|
DescribeTagsCommand,
|
|
26165
|
+
AddTagsCommand,
|
|
26166
|
+
RemoveTagsCommand,
|
|
25577
26167
|
CreateListenerCommand,
|
|
25578
26168
|
DeleteListenerCommand,
|
|
25579
26169
|
ModifyListenerCommand,
|
|
@@ -25656,14 +26246,26 @@ var ELBv2Provider = class {
|
|
|
25656
26246
|
);
|
|
25657
26247
|
}
|
|
25658
26248
|
}
|
|
25659
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
26249
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
25660
26250
|
switch (resourceType) {
|
|
25661
26251
|
case "AWS::ElasticLoadBalancingV2::LoadBalancer":
|
|
25662
26252
|
return this.updateLoadBalancer(logicalId, physicalId, resourceType, properties);
|
|
25663
26253
|
case "AWS::ElasticLoadBalancingV2::TargetGroup":
|
|
25664
|
-
return this.updateTargetGroup(
|
|
26254
|
+
return this.updateTargetGroup(
|
|
26255
|
+
logicalId,
|
|
26256
|
+
physicalId,
|
|
26257
|
+
resourceType,
|
|
26258
|
+
properties,
|
|
26259
|
+
previousProperties
|
|
26260
|
+
);
|
|
25665
26261
|
case "AWS::ElasticLoadBalancingV2::Listener":
|
|
25666
|
-
return this.updateListener(
|
|
26262
|
+
return this.updateListener(
|
|
26263
|
+
logicalId,
|
|
26264
|
+
physicalId,
|
|
26265
|
+
resourceType,
|
|
26266
|
+
properties,
|
|
26267
|
+
previousProperties
|
|
26268
|
+
);
|
|
25667
26269
|
default:
|
|
25668
26270
|
throw new ProvisioningError(
|
|
25669
26271
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -25842,7 +26444,7 @@ var ELBv2Provider = class {
|
|
|
25842
26444
|
);
|
|
25843
26445
|
}
|
|
25844
26446
|
}
|
|
25845
|
-
async updateTargetGroup(logicalId, physicalId, resourceType, properties) {
|
|
26447
|
+
async updateTargetGroup(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
25846
26448
|
this.logger.debug(`Updating TargetGroup ${logicalId}: ${physicalId}`);
|
|
25847
26449
|
try {
|
|
25848
26450
|
const matcher = properties["Matcher"];
|
|
@@ -25864,6 +26466,11 @@ var ELBv2Provider = class {
|
|
|
25864
26466
|
new DescribeTargetGroupsCommand({ TargetGroupArns: [physicalId] })
|
|
25865
26467
|
);
|
|
25866
26468
|
const tg = describeResponse.TargetGroups?.[0];
|
|
26469
|
+
await this.applyTagDiff(
|
|
26470
|
+
physicalId,
|
|
26471
|
+
previousProperties["Tags"],
|
|
26472
|
+
properties["Tags"]
|
|
26473
|
+
);
|
|
25867
26474
|
this.logger.debug(`Successfully updated TargetGroup ${logicalId}`);
|
|
25868
26475
|
return {
|
|
25869
26476
|
physicalId,
|
|
@@ -25957,7 +26564,7 @@ var ELBv2Provider = class {
|
|
|
25957
26564
|
);
|
|
25958
26565
|
}
|
|
25959
26566
|
}
|
|
25960
|
-
async updateListener(logicalId, physicalId, resourceType, properties) {
|
|
26567
|
+
async updateListener(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
25961
26568
|
this.logger.debug(`Updating Listener ${logicalId}: ${physicalId}`);
|
|
25962
26569
|
try {
|
|
25963
26570
|
const defaultActions = this.convertActions(
|
|
@@ -25976,6 +26583,11 @@ var ELBv2Provider = class {
|
|
|
25976
26583
|
...certificates && { Certificates: certificates }
|
|
25977
26584
|
})
|
|
25978
26585
|
);
|
|
26586
|
+
await this.applyTagDiff(
|
|
26587
|
+
physicalId,
|
|
26588
|
+
previousProperties["Tags"],
|
|
26589
|
+
properties["Tags"]
|
|
26590
|
+
);
|
|
25979
26591
|
this.logger.debug(`Successfully updated Listener ${logicalId}`);
|
|
25980
26592
|
return {
|
|
25981
26593
|
physicalId,
|
|
@@ -26033,6 +26645,44 @@ var ELBv2Provider = class {
|
|
|
26033
26645
|
return [];
|
|
26034
26646
|
return properties["Tags"];
|
|
26035
26647
|
}
|
|
26648
|
+
/**
|
|
26649
|
+
* Apply a diff between old and new CFn-shape Tags arrays via ELBv2's
|
|
26650
|
+
* `AddTags` / `RemoveTags` APIs. Both accept `ResourceArns: [arn]`
|
|
26651
|
+
* (single ARN), `Tags: [{Key, Value}]` for AddTags, and
|
|
26652
|
+
* `TagKeys: [...]` for RemoveTags.
|
|
26653
|
+
*/
|
|
26654
|
+
async applyTagDiff(arn, oldTagsRaw, newTagsRaw) {
|
|
26655
|
+
const toMap = (tags) => {
|
|
26656
|
+
const m = /* @__PURE__ */ new Map();
|
|
26657
|
+
for (const t of tags ?? []) {
|
|
26658
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
26659
|
+
m.set(t.Key, t.Value);
|
|
26660
|
+
}
|
|
26661
|
+
return m;
|
|
26662
|
+
};
|
|
26663
|
+
const oldMap = toMap(oldTagsRaw);
|
|
26664
|
+
const newMap = toMap(newTagsRaw);
|
|
26665
|
+
const tagsToAdd = [];
|
|
26666
|
+
for (const [k, v] of newMap) {
|
|
26667
|
+
if (oldMap.get(k) !== v)
|
|
26668
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
26669
|
+
}
|
|
26670
|
+
const tagsToRemove = [];
|
|
26671
|
+
for (const k of oldMap.keys()) {
|
|
26672
|
+
if (!newMap.has(k))
|
|
26673
|
+
tagsToRemove.push(k);
|
|
26674
|
+
}
|
|
26675
|
+
if (tagsToRemove.length > 0) {
|
|
26676
|
+
await this.getClient().send(
|
|
26677
|
+
new RemoveTagsCommand({ ResourceArns: [arn], TagKeys: tagsToRemove })
|
|
26678
|
+
);
|
|
26679
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from ELBv2 resource ${arn}`);
|
|
26680
|
+
}
|
|
26681
|
+
if (tagsToAdd.length > 0) {
|
|
26682
|
+
await this.getClient().send(new AddTagsCommand({ ResourceArns: [arn], Tags: tagsToAdd }));
|
|
26683
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on ELBv2 resource ${arn}`);
|
|
26684
|
+
}
|
|
26685
|
+
}
|
|
26036
26686
|
/**
|
|
26037
26687
|
* Convert CDK DefaultActions to ELBv2 API Action format
|
|
26038
26688
|
* CDK uses PascalCase property names matching the ELBv2 API, so pass through.
|
|
@@ -26347,7 +26997,9 @@ import {
|
|
|
26347
26997
|
DeleteDBSubnetGroupCommand,
|
|
26348
26998
|
DescribeDBSubnetGroupsCommand,
|
|
26349
26999
|
ModifyDBSubnetGroupCommand,
|
|
26350
|
-
ListTagsForResourceCommand as ListTagsForResourceCommand10
|
|
27000
|
+
ListTagsForResourceCommand as ListTagsForResourceCommand10,
|
|
27001
|
+
AddTagsToResourceCommand as AddTagsToResourceCommand2,
|
|
27002
|
+
RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand2
|
|
26351
27003
|
} from "@aws-sdk/client-rds";
|
|
26352
27004
|
var RDSProvider = class {
|
|
26353
27005
|
rdsClient;
|
|
@@ -26414,14 +27066,32 @@ var RDSProvider = class {
|
|
|
26414
27066
|
);
|
|
26415
27067
|
}
|
|
26416
27068
|
}
|
|
26417
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
27069
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
26418
27070
|
switch (resourceType) {
|
|
26419
27071
|
case "AWS::RDS::DBSubnetGroup":
|
|
26420
|
-
return this.updateDBSubnetGroup(
|
|
27072
|
+
return this.updateDBSubnetGroup(
|
|
27073
|
+
logicalId,
|
|
27074
|
+
physicalId,
|
|
27075
|
+
resourceType,
|
|
27076
|
+
properties,
|
|
27077
|
+
previousProperties
|
|
27078
|
+
);
|
|
26421
27079
|
case "AWS::RDS::DBCluster":
|
|
26422
|
-
return this.updateDBCluster(
|
|
27080
|
+
return this.updateDBCluster(
|
|
27081
|
+
logicalId,
|
|
27082
|
+
physicalId,
|
|
27083
|
+
resourceType,
|
|
27084
|
+
properties,
|
|
27085
|
+
previousProperties
|
|
27086
|
+
);
|
|
26423
27087
|
case "AWS::RDS::DBInstance":
|
|
26424
|
-
return this.updateDBInstance(
|
|
27088
|
+
return this.updateDBInstance(
|
|
27089
|
+
logicalId,
|
|
27090
|
+
physicalId,
|
|
27091
|
+
resourceType,
|
|
27092
|
+
properties,
|
|
27093
|
+
previousProperties
|
|
27094
|
+
);
|
|
26425
27095
|
default:
|
|
26426
27096
|
throw new ProvisioningError(
|
|
26427
27097
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -26480,7 +27150,7 @@ var RDSProvider = class {
|
|
|
26480
27150
|
);
|
|
26481
27151
|
}
|
|
26482
27152
|
}
|
|
26483
|
-
async updateDBSubnetGroup(logicalId, physicalId, resourceType, properties) {
|
|
27153
|
+
async updateDBSubnetGroup(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
26484
27154
|
this.logger.debug(`Updating DBSubnetGroup ${logicalId}: ${physicalId}`);
|
|
26485
27155
|
try {
|
|
26486
27156
|
await this.getClient().send(
|
|
@@ -26490,6 +27160,17 @@ var RDSProvider = class {
|
|
|
26490
27160
|
SubnetIds: properties["SubnetIds"]
|
|
26491
27161
|
})
|
|
26492
27162
|
);
|
|
27163
|
+
const desc = await this.getClient().send(
|
|
27164
|
+
new DescribeDBSubnetGroupsCommand({ DBSubnetGroupName: physicalId })
|
|
27165
|
+
);
|
|
27166
|
+
const arn = desc.DBSubnetGroups?.[0]?.DBSubnetGroupArn;
|
|
27167
|
+
if (arn) {
|
|
27168
|
+
await this.applyTagDiff(
|
|
27169
|
+
arn,
|
|
27170
|
+
previousProperties["Tags"],
|
|
27171
|
+
properties["Tags"]
|
|
27172
|
+
);
|
|
27173
|
+
}
|
|
26493
27174
|
this.logger.debug(`Successfully updated DBSubnetGroup ${logicalId}`);
|
|
26494
27175
|
return {
|
|
26495
27176
|
physicalId,
|
|
@@ -26604,7 +27285,7 @@ var RDSProvider = class {
|
|
|
26604
27285
|
);
|
|
26605
27286
|
}
|
|
26606
27287
|
}
|
|
26607
|
-
async updateDBCluster(logicalId, physicalId, resourceType, properties) {
|
|
27288
|
+
async updateDBCluster(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
26608
27289
|
this.logger.debug(`Updating DBCluster ${logicalId}: ${physicalId}`);
|
|
26609
27290
|
try {
|
|
26610
27291
|
const serverlessV2Config = properties["ServerlessV2ScalingConfiguration"];
|
|
@@ -26628,6 +27309,13 @@ var RDSProvider = class {
|
|
|
26628
27309
|
);
|
|
26629
27310
|
this.logger.debug(`Successfully updated DBCluster ${logicalId}`);
|
|
26630
27311
|
const described = await this.describeDBCluster(physicalId);
|
|
27312
|
+
if (described?.DBClusterArn) {
|
|
27313
|
+
await this.applyTagDiff(
|
|
27314
|
+
described.DBClusterArn,
|
|
27315
|
+
previousProperties["Tags"],
|
|
27316
|
+
properties["Tags"]
|
|
27317
|
+
);
|
|
27318
|
+
}
|
|
26631
27319
|
return {
|
|
26632
27320
|
physicalId,
|
|
26633
27321
|
wasReplaced: false,
|
|
@@ -26745,7 +27433,7 @@ var RDSProvider = class {
|
|
|
26745
27433
|
);
|
|
26746
27434
|
}
|
|
26747
27435
|
}
|
|
26748
|
-
async updateDBInstance(logicalId, physicalId, resourceType, properties) {
|
|
27436
|
+
async updateDBInstance(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
26749
27437
|
this.logger.debug(`Updating DBInstance ${logicalId}: ${physicalId}`);
|
|
26750
27438
|
try {
|
|
26751
27439
|
await this.getClient().send(
|
|
@@ -26758,6 +27446,13 @@ var RDSProvider = class {
|
|
|
26758
27446
|
);
|
|
26759
27447
|
this.logger.debug(`Successfully updated DBInstance ${logicalId}`);
|
|
26760
27448
|
const described = await this.describeDBInstance(physicalId);
|
|
27449
|
+
if (described?.DBInstanceArn) {
|
|
27450
|
+
await this.applyTagDiff(
|
|
27451
|
+
described.DBInstanceArn,
|
|
27452
|
+
previousProperties["Tags"],
|
|
27453
|
+
properties["Tags"]
|
|
27454
|
+
);
|
|
27455
|
+
}
|
|
26761
27456
|
return {
|
|
26762
27457
|
physicalId,
|
|
26763
27458
|
wasReplaced: false,
|
|
@@ -26828,6 +27523,45 @@ var RDSProvider = class {
|
|
|
26828
27523
|
}
|
|
26829
27524
|
}
|
|
26830
27525
|
// ─── Helpers ──────────────────────────────────────────────────────
|
|
27526
|
+
/**
|
|
27527
|
+
* Apply a diff between old and new CFn-shape Tags arrays via RDS's
|
|
27528
|
+
* `AddTagsToResource` / `RemoveTagsFromResource` APIs (keyed by
|
|
27529
|
+
* `ResourceName=arn`).
|
|
27530
|
+
*/
|
|
27531
|
+
async applyTagDiff(arn, oldTagsRaw, newTagsRaw) {
|
|
27532
|
+
const toMap = (tags) => {
|
|
27533
|
+
const m = /* @__PURE__ */ new Map();
|
|
27534
|
+
for (const t of tags ?? []) {
|
|
27535
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
27536
|
+
m.set(t.Key, t.Value);
|
|
27537
|
+
}
|
|
27538
|
+
return m;
|
|
27539
|
+
};
|
|
27540
|
+
const oldMap = toMap(oldTagsRaw);
|
|
27541
|
+
const newMap = toMap(newTagsRaw);
|
|
27542
|
+
const tagsToAdd = [];
|
|
27543
|
+
for (const [k, v] of newMap) {
|
|
27544
|
+
if (oldMap.get(k) !== v)
|
|
27545
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
27546
|
+
}
|
|
27547
|
+
const tagsToRemove = [];
|
|
27548
|
+
for (const k of oldMap.keys()) {
|
|
27549
|
+
if (!newMap.has(k))
|
|
27550
|
+
tagsToRemove.push(k);
|
|
27551
|
+
}
|
|
27552
|
+
if (tagsToRemove.length > 0) {
|
|
27553
|
+
await this.getClient().send(
|
|
27554
|
+
new RemoveTagsFromResourceCommand2({ ResourceName: arn, TagKeys: tagsToRemove })
|
|
27555
|
+
);
|
|
27556
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from RDS resource ${arn}`);
|
|
27557
|
+
}
|
|
27558
|
+
if (tagsToAdd.length > 0) {
|
|
27559
|
+
await this.getClient().send(
|
|
27560
|
+
new AddTagsToResourceCommand2({ ResourceName: arn, Tags: tagsToAdd })
|
|
27561
|
+
);
|
|
27562
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on RDS resource ${arn}`);
|
|
27563
|
+
}
|
|
27564
|
+
}
|
|
26831
27565
|
buildTags(properties) {
|
|
26832
27566
|
if (!properties["Tags"])
|
|
26833
27567
|
return [];
|
|
@@ -28115,6 +28849,8 @@ import {
|
|
|
28115
28849
|
GetWebACLCommand,
|
|
28116
28850
|
ListWebACLsCommand,
|
|
28117
28851
|
ListTagsForResourceCommand as ListTagsForResourceCommand12,
|
|
28852
|
+
TagResourceCommand as TagResourceCommand13,
|
|
28853
|
+
UntagResourceCommand as UntagResourceCommand13,
|
|
28118
28854
|
WAFNonexistentItemException
|
|
28119
28855
|
} from "@aws-sdk/client-wafv2";
|
|
28120
28856
|
function parseWebACLArn(arn) {
|
|
@@ -28221,7 +28957,7 @@ var WAFv2WebACLProvider = class {
|
|
|
28221
28957
|
* Name and Scope are immutable - changes to those require replacement.
|
|
28222
28958
|
* UpdateWebACL requires LockToken obtained from GetWebACL.
|
|
28223
28959
|
*/
|
|
28224
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
28960
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
28225
28961
|
this.logger.debug(`Updating WAFv2 WebACL ${logicalId}: ${physicalId}`);
|
|
28226
28962
|
try {
|
|
28227
28963
|
const { id, name, scope } = parseWebACLArn(physicalId);
|
|
@@ -28253,6 +28989,11 @@ var WAFv2WebACLProvider = class {
|
|
|
28253
28989
|
AssociationConfig: properties["AssociationConfig"]
|
|
28254
28990
|
})
|
|
28255
28991
|
);
|
|
28992
|
+
await this.applyTagDiff(
|
|
28993
|
+
physicalId,
|
|
28994
|
+
previousProperties["Tags"],
|
|
28995
|
+
properties["Tags"]
|
|
28996
|
+
);
|
|
28256
28997
|
this.logger.debug(`Successfully updated WAFv2 WebACL ${logicalId}`);
|
|
28257
28998
|
return {
|
|
28258
28999
|
physicalId,
|
|
@@ -28329,6 +29070,42 @@ var WAFv2WebACLProvider = class {
|
|
|
28329
29070
|
);
|
|
28330
29071
|
}
|
|
28331
29072
|
}
|
|
29073
|
+
/**
|
|
29074
|
+
* Apply a diff between old and new CFn-shape Tags arrays via WAFv2's
|
|
29075
|
+
* `TagResource` / `UntagResource` APIs (keyed by `ResourceARN`).
|
|
29076
|
+
*/
|
|
29077
|
+
async applyTagDiff(arn, oldTagsRaw, newTagsRaw) {
|
|
29078
|
+
const toMap = (tags) => {
|
|
29079
|
+
const m = /* @__PURE__ */ new Map();
|
|
29080
|
+
for (const t of tags ?? []) {
|
|
29081
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
29082
|
+
m.set(t.Key, t.Value);
|
|
29083
|
+
}
|
|
29084
|
+
return m;
|
|
29085
|
+
};
|
|
29086
|
+
const oldMap = toMap(oldTagsRaw);
|
|
29087
|
+
const newMap = toMap(newTagsRaw);
|
|
29088
|
+
const tagsToAdd = [];
|
|
29089
|
+
for (const [k, v] of newMap) {
|
|
29090
|
+
if (oldMap.get(k) !== v)
|
|
29091
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
29092
|
+
}
|
|
29093
|
+
const tagsToRemove = [];
|
|
29094
|
+
for (const k of oldMap.keys()) {
|
|
29095
|
+
if (!newMap.has(k))
|
|
29096
|
+
tagsToRemove.push(k);
|
|
29097
|
+
}
|
|
29098
|
+
if (tagsToRemove.length > 0) {
|
|
29099
|
+
await this.getClient().send(
|
|
29100
|
+
new UntagResourceCommand13({ ResourceARN: arn, TagKeys: tagsToRemove })
|
|
29101
|
+
);
|
|
29102
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from WAFv2 WebACL ${arn}`);
|
|
29103
|
+
}
|
|
29104
|
+
if (tagsToAdd.length > 0) {
|
|
29105
|
+
await this.getClient().send(new TagResourceCommand13({ ResourceARN: arn, Tags: tagsToAdd }));
|
|
29106
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on WAFv2 WebACL ${arn}`);
|
|
29107
|
+
}
|
|
29108
|
+
}
|
|
28332
29109
|
/**
|
|
28333
29110
|
* Read the AWS-current WAFv2 WebACL configuration in CFn-property shape.
|
|
28334
29111
|
*
|
|
@@ -28943,7 +29720,9 @@ import {
|
|
|
28943
29720
|
DeleteCacheSubnetGroupCommand,
|
|
28944
29721
|
ModifyCacheSubnetGroupCommand,
|
|
28945
29722
|
ModifyCacheClusterCommand,
|
|
28946
|
-
ListTagsForResourceCommand as ListTagsForResourceCommand14
|
|
29723
|
+
ListTagsForResourceCommand as ListTagsForResourceCommand14,
|
|
29724
|
+
AddTagsToResourceCommand as AddTagsToResourceCommand3,
|
|
29725
|
+
RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand3
|
|
28947
29726
|
} from "@aws-sdk/client-elasticache";
|
|
28948
29727
|
import { STSClient as STSClient6, GetCallerIdentityCommand as GetCallerIdentityCommand6 } from "@aws-sdk/client-sts";
|
|
28949
29728
|
var ElastiCacheProvider = class {
|
|
@@ -29009,12 +29788,18 @@ var ElastiCacheProvider = class {
|
|
|
29009
29788
|
);
|
|
29010
29789
|
}
|
|
29011
29790
|
}
|
|
29012
|
-
async update(logicalId, physicalId, resourceType, properties,
|
|
29791
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
29013
29792
|
switch (resourceType) {
|
|
29014
29793
|
case "AWS::ElastiCache::SubnetGroup":
|
|
29015
29794
|
return this.updateSubnetGroup(logicalId, physicalId, resourceType, properties);
|
|
29016
29795
|
case "AWS::ElastiCache::CacheCluster":
|
|
29017
|
-
return this.updateCacheCluster(
|
|
29796
|
+
return this.updateCacheCluster(
|
|
29797
|
+
logicalId,
|
|
29798
|
+
physicalId,
|
|
29799
|
+
resourceType,
|
|
29800
|
+
properties,
|
|
29801
|
+
previousProperties
|
|
29802
|
+
);
|
|
29018
29803
|
default:
|
|
29019
29804
|
throw new ProvisioningError(
|
|
29020
29805
|
`Unsupported resource type: ${resourceType}`,
|
|
@@ -29199,7 +29984,7 @@ var ElastiCacheProvider = class {
|
|
|
29199
29984
|
);
|
|
29200
29985
|
}
|
|
29201
29986
|
}
|
|
29202
|
-
async updateCacheCluster(logicalId, physicalId, resourceType, properties) {
|
|
29987
|
+
async updateCacheCluster(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
29203
29988
|
this.logger.debug(`Updating CacheCluster ${logicalId}: ${physicalId}`);
|
|
29204
29989
|
try {
|
|
29205
29990
|
await this.getClient().send(
|
|
@@ -29222,6 +30007,13 @@ var ElastiCacheProvider = class {
|
|
|
29222
30007
|
this.logger.debug(`Successfully updated CacheCluster ${logicalId}`);
|
|
29223
30008
|
await this.waitForClusterAvailable(physicalId);
|
|
29224
30009
|
const described = await this.describeCacheCluster(physicalId);
|
|
30010
|
+
if (described?.ARN) {
|
|
30011
|
+
await this.applyTagDiff(
|
|
30012
|
+
described.ARN,
|
|
30013
|
+
previousProperties["Tags"],
|
|
30014
|
+
properties["Tags"]
|
|
30015
|
+
);
|
|
30016
|
+
}
|
|
29225
30017
|
const attributes = {};
|
|
29226
30018
|
if (described?.CacheNodes?.[0]?.Endpoint) {
|
|
29227
30019
|
const endpoint = described.CacheNodes[0].Endpoint;
|
|
@@ -29286,6 +30078,45 @@ var ElastiCacheProvider = class {
|
|
|
29286
30078
|
}
|
|
29287
30079
|
}
|
|
29288
30080
|
// ─── Helpers ──────────────────────────────────────────────────────
|
|
30081
|
+
/**
|
|
30082
|
+
* Apply a diff between old and new CFn-shape Tags arrays via ElastiCache's
|
|
30083
|
+
* `AddTagsToResource` / `RemoveTagsFromResource` APIs (keyed by
|
|
30084
|
+
* `ResourceName=arn`).
|
|
30085
|
+
*/
|
|
30086
|
+
async applyTagDiff(arn, oldTagsRaw, newTagsRaw) {
|
|
30087
|
+
const toMap = (tags) => {
|
|
30088
|
+
const m = /* @__PURE__ */ new Map();
|
|
30089
|
+
for (const t of tags ?? []) {
|
|
30090
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
30091
|
+
m.set(t.Key, t.Value);
|
|
30092
|
+
}
|
|
30093
|
+
return m;
|
|
30094
|
+
};
|
|
30095
|
+
const oldMap = toMap(oldTagsRaw);
|
|
30096
|
+
const newMap = toMap(newTagsRaw);
|
|
30097
|
+
const tagsToAdd = [];
|
|
30098
|
+
for (const [k, v] of newMap) {
|
|
30099
|
+
if (oldMap.get(k) !== v)
|
|
30100
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
30101
|
+
}
|
|
30102
|
+
const tagsToRemove = [];
|
|
30103
|
+
for (const k of oldMap.keys()) {
|
|
30104
|
+
if (!newMap.has(k))
|
|
30105
|
+
tagsToRemove.push(k);
|
|
30106
|
+
}
|
|
30107
|
+
if (tagsToRemove.length > 0) {
|
|
30108
|
+
await this.getClient().send(
|
|
30109
|
+
new RemoveTagsFromResourceCommand3({ ResourceName: arn, TagKeys: tagsToRemove })
|
|
30110
|
+
);
|
|
30111
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from ElastiCache resource ${arn}`);
|
|
30112
|
+
}
|
|
30113
|
+
if (tagsToAdd.length > 0) {
|
|
30114
|
+
await this.getClient().send(
|
|
30115
|
+
new AddTagsToResourceCommand3({ ResourceName: arn, Tags: tagsToAdd })
|
|
30116
|
+
);
|
|
30117
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on ElastiCache resource ${arn}`);
|
|
30118
|
+
}
|
|
30119
|
+
}
|
|
29289
30120
|
buildTags(properties) {
|
|
29290
30121
|
if (!properties["Tags"])
|
|
29291
30122
|
return [];
|
|
@@ -31613,8 +32444,8 @@ import {
|
|
|
31613
32444
|
PutKeyPolicyCommand,
|
|
31614
32445
|
EnableKeyCommand,
|
|
31615
32446
|
DisableKeyCommand,
|
|
31616
|
-
TagResourceCommand as
|
|
31617
|
-
UntagResourceCommand as
|
|
32447
|
+
TagResourceCommand as TagResourceCommand14,
|
|
32448
|
+
UntagResourceCommand as UntagResourceCommand14,
|
|
31618
32449
|
NotFoundException as NotFoundException5
|
|
31619
32450
|
} from "@aws-sdk/client-kms";
|
|
31620
32451
|
var KMSProvider = class {
|
|
@@ -31799,26 +32630,11 @@ var KMSProvider = class {
|
|
|
31799
32630
|
await this.getClient().send(new EnableKeyCommand({ KeyId: physicalId }));
|
|
31800
32631
|
}
|
|
31801
32632
|
}
|
|
31802
|
-
|
|
31803
|
-
|
|
31804
|
-
|
|
31805
|
-
|
|
31806
|
-
|
|
31807
|
-
new UntagResourceCommand6({
|
|
31808
|
-
KeyId: physicalId,
|
|
31809
|
-
TagKeys: oldTags.map((t) => t.Key)
|
|
31810
|
-
})
|
|
31811
|
-
);
|
|
31812
|
-
}
|
|
31813
|
-
if (newTags && newTags.length > 0) {
|
|
31814
|
-
await this.getClient().send(
|
|
31815
|
-
new TagResourceCommand6({
|
|
31816
|
-
KeyId: physicalId,
|
|
31817
|
-
Tags: newTags.map((t) => ({ TagKey: t.Key, TagValue: t.Value }))
|
|
31818
|
-
})
|
|
31819
|
-
);
|
|
31820
|
-
}
|
|
31821
|
-
}
|
|
32633
|
+
await this.applyTagDiff(
|
|
32634
|
+
physicalId,
|
|
32635
|
+
previousProperties["Tags"],
|
|
32636
|
+
properties["Tags"]
|
|
32637
|
+
);
|
|
31822
32638
|
const newKeyPolicy = properties["KeyPolicy"];
|
|
31823
32639
|
const oldKeyPolicy = previousProperties["KeyPolicy"];
|
|
31824
32640
|
const newPolicyStr = newKeyPolicy ? typeof newKeyPolicy === "string" ? newKeyPolicy : JSON.stringify(newKeyPolicy) : void 0;
|
|
@@ -31880,6 +32696,43 @@ var KMSProvider = class {
|
|
|
31880
32696
|
);
|
|
31881
32697
|
}
|
|
31882
32698
|
}
|
|
32699
|
+
/**
|
|
32700
|
+
* Apply a diff between old and new CFn-shape Tags arrays via KMS's
|
|
32701
|
+
* `TagResource` / `UntagResource` APIs. KMS uses `{TagKey, TagValue}`
|
|
32702
|
+
* (NOT the standard `{Key, Value}` shape) keyed by `KeyId`.
|
|
32703
|
+
*/
|
|
32704
|
+
async applyTagDiff(keyId, oldTagsRaw, newTagsRaw) {
|
|
32705
|
+
const toMap = (tags) => {
|
|
32706
|
+
const m = /* @__PURE__ */ new Map();
|
|
32707
|
+
for (const t of tags ?? []) {
|
|
32708
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
32709
|
+
m.set(t.Key, t.Value);
|
|
32710
|
+
}
|
|
32711
|
+
return m;
|
|
32712
|
+
};
|
|
32713
|
+
const oldMap = toMap(oldTagsRaw);
|
|
32714
|
+
const newMap = toMap(newTagsRaw);
|
|
32715
|
+
const tagsToAdd = [];
|
|
32716
|
+
for (const [k, v] of newMap) {
|
|
32717
|
+
if (oldMap.get(k) !== v)
|
|
32718
|
+
tagsToAdd.push({ TagKey: k, TagValue: v });
|
|
32719
|
+
}
|
|
32720
|
+
const tagsToRemove = [];
|
|
32721
|
+
for (const k of oldMap.keys()) {
|
|
32722
|
+
if (!newMap.has(k))
|
|
32723
|
+
tagsToRemove.push(k);
|
|
32724
|
+
}
|
|
32725
|
+
if (tagsToRemove.length > 0) {
|
|
32726
|
+
await this.getClient().send(
|
|
32727
|
+
new UntagResourceCommand14({ KeyId: keyId, TagKeys: tagsToRemove })
|
|
32728
|
+
);
|
|
32729
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from KMS Key ${keyId}`);
|
|
32730
|
+
}
|
|
32731
|
+
if (tagsToAdd.length > 0) {
|
|
32732
|
+
await this.getClient().send(new TagResourceCommand14({ KeyId: keyId, Tags: tagsToAdd }));
|
|
32733
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on KMS Key ${keyId}`);
|
|
32734
|
+
}
|
|
32735
|
+
}
|
|
31883
32736
|
// ─── AWS::KMS::Alias ───────────────────────────────────────────────
|
|
31884
32737
|
async createAlias(logicalId, resourceType, properties) {
|
|
31885
32738
|
this.logger.debug(`Creating KMS Alias ${logicalId}`);
|
|
@@ -32164,6 +33017,7 @@ import {
|
|
|
32164
33017
|
DescribeStreamCommand,
|
|
32165
33018
|
UpdateShardCountCommand,
|
|
32166
33019
|
AddTagsToStreamCommand,
|
|
33020
|
+
RemoveTagsFromStreamCommand,
|
|
32167
33021
|
IncreaseStreamRetentionPeriodCommand,
|
|
32168
33022
|
DecreaseStreamRetentionPeriodCommand,
|
|
32169
33023
|
StartStreamEncryptionCommand,
|
|
@@ -32341,6 +33195,11 @@ var KinesisStreamProvider = class {
|
|
|
32341
33195
|
}
|
|
32342
33196
|
await this.waitForStreamActive(physicalId);
|
|
32343
33197
|
}
|
|
33198
|
+
await this.applyTagDiff(
|
|
33199
|
+
physicalId,
|
|
33200
|
+
previousProperties["Tags"],
|
|
33201
|
+
properties["Tags"]
|
|
33202
|
+
);
|
|
32344
33203
|
const newEncryption = properties["StreamEncryption"];
|
|
32345
33204
|
const oldEncryption = previousProperties["StreamEncryption"];
|
|
32346
33205
|
if (JSON.stringify(newEncryption) !== JSON.stringify(oldEncryption)) {
|
|
@@ -32422,6 +33281,47 @@ var KinesisStreamProvider = class {
|
|
|
32422
33281
|
);
|
|
32423
33282
|
}
|
|
32424
33283
|
}
|
|
33284
|
+
/**
|
|
33285
|
+
* Apply a diff between old and new CFn-shape Tags arrays via Kinesis's
|
|
33286
|
+
* `AddTagsToStream` (map shape) / `RemoveTagsFromStream` (TagKeys list)
|
|
33287
|
+
* APIs.
|
|
33288
|
+
*/
|
|
33289
|
+
async applyTagDiff(streamName, oldTagsRaw, newTagsRaw) {
|
|
33290
|
+
const toMap = (tags) => {
|
|
33291
|
+
const m = /* @__PURE__ */ new Map();
|
|
33292
|
+
for (const t of tags ?? []) {
|
|
33293
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
33294
|
+
m.set(t.Key, t.Value);
|
|
33295
|
+
}
|
|
33296
|
+
return m;
|
|
33297
|
+
};
|
|
33298
|
+
const oldMap = toMap(oldTagsRaw);
|
|
33299
|
+
const newMap = toMap(newTagsRaw);
|
|
33300
|
+
const tagsToAdd = {};
|
|
33301
|
+
for (const [k, v] of newMap) {
|
|
33302
|
+
if (oldMap.get(k) !== v)
|
|
33303
|
+
tagsToAdd[k] = v;
|
|
33304
|
+
}
|
|
33305
|
+
const tagsToRemove = [];
|
|
33306
|
+
for (const k of oldMap.keys()) {
|
|
33307
|
+
if (!newMap.has(k))
|
|
33308
|
+
tagsToRemove.push(k);
|
|
33309
|
+
}
|
|
33310
|
+
if (tagsToRemove.length > 0) {
|
|
33311
|
+
await this.getClient().send(
|
|
33312
|
+
new RemoveTagsFromStreamCommand({ StreamName: streamName, TagKeys: tagsToRemove })
|
|
33313
|
+
);
|
|
33314
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from Kinesis stream ${streamName}`);
|
|
33315
|
+
}
|
|
33316
|
+
if (Object.keys(tagsToAdd).length > 0) {
|
|
33317
|
+
await this.getClient().send(
|
|
33318
|
+
new AddTagsToStreamCommand({ StreamName: streamName, Tags: tagsToAdd })
|
|
33319
|
+
);
|
|
33320
|
+
this.logger.debug(
|
|
33321
|
+
`Added/updated ${Object.keys(tagsToAdd).length} tag(s) on Kinesis stream ${streamName}`
|
|
33322
|
+
);
|
|
33323
|
+
}
|
|
33324
|
+
}
|
|
32425
33325
|
/**
|
|
32426
33326
|
* Adopt an existing Kinesis stream into cdkd state.
|
|
32427
33327
|
*
|
|
@@ -33782,6 +34682,8 @@ import {
|
|
|
33782
34682
|
GetEventSelectorsCommand,
|
|
33783
34683
|
ListTrailsCommand,
|
|
33784
34684
|
ListTagsCommand as ListTagsCommand3,
|
|
34685
|
+
AddTagsCommand as AddTagsCommand2,
|
|
34686
|
+
RemoveTagsCommand as RemoveTagsCommand2,
|
|
33785
34687
|
TrailNotFoundException
|
|
33786
34688
|
} from "@aws-sdk/client-cloudtrail";
|
|
33787
34689
|
var CloudTrailProvider = class {
|
|
@@ -33965,6 +34867,11 @@ var CloudTrailProvider = class {
|
|
|
33965
34867
|
await this.getClient().send(new StartLoggingCommand({ Name: physicalId }));
|
|
33966
34868
|
}
|
|
33967
34869
|
}
|
|
34870
|
+
await this.applyTagDiff(
|
|
34871
|
+
physicalId,
|
|
34872
|
+
previousProperties["Tags"],
|
|
34873
|
+
properties["Tags"]
|
|
34874
|
+
);
|
|
33968
34875
|
this.logger.debug(`Successfully updated CloudTrail Trail ${logicalId}`);
|
|
33969
34876
|
return { physicalId, wasReplaced: false };
|
|
33970
34877
|
} catch (error) {
|
|
@@ -34013,6 +34920,46 @@ var CloudTrailProvider = class {
|
|
|
34013
34920
|
getAttribute(_physicalId, _resourceType, attributeName) {
|
|
34014
34921
|
return Promise.resolve(attributeName);
|
|
34015
34922
|
}
|
|
34923
|
+
/**
|
|
34924
|
+
* Apply a diff between old and new CFn-shape Tags arrays via CloudTrail's
|
|
34925
|
+
* `AddTags` / `RemoveTags` APIs. Note: CloudTrail's `RemoveTags` takes
|
|
34926
|
+
* full `{Key, Value}` objects in `TagsList` (NOT just keys), unlike most
|
|
34927
|
+
* other AWS services.
|
|
34928
|
+
*/
|
|
34929
|
+
async applyTagDiff(trailArn, oldTagsRaw, newTagsRaw) {
|
|
34930
|
+
const toMap = (tags) => {
|
|
34931
|
+
const m = /* @__PURE__ */ new Map();
|
|
34932
|
+
for (const t of tags ?? []) {
|
|
34933
|
+
if (t.Key !== void 0 && t.Value !== void 0)
|
|
34934
|
+
m.set(t.Key, t.Value);
|
|
34935
|
+
}
|
|
34936
|
+
return m;
|
|
34937
|
+
};
|
|
34938
|
+
const oldMap = toMap(oldTagsRaw);
|
|
34939
|
+
const newMap = toMap(newTagsRaw);
|
|
34940
|
+
const tagsToAdd = [];
|
|
34941
|
+
for (const [k, v] of newMap) {
|
|
34942
|
+
if (oldMap.get(k) !== v)
|
|
34943
|
+
tagsToAdd.push({ Key: k, Value: v });
|
|
34944
|
+
}
|
|
34945
|
+
const tagsToRemove = [];
|
|
34946
|
+
for (const [k, v] of oldMap) {
|
|
34947
|
+
if (!newMap.has(k))
|
|
34948
|
+
tagsToRemove.push({ Key: k, Value: v });
|
|
34949
|
+
}
|
|
34950
|
+
if (tagsToRemove.length > 0) {
|
|
34951
|
+
await this.getClient().send(
|
|
34952
|
+
new RemoveTagsCommand2({ ResourceId: trailArn, TagsList: tagsToRemove })
|
|
34953
|
+
);
|
|
34954
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from CloudTrail Trail ${trailArn}`);
|
|
34955
|
+
}
|
|
34956
|
+
if (tagsToAdd.length > 0) {
|
|
34957
|
+
await this.getClient().send(
|
|
34958
|
+
new AddTagsCommand2({ ResourceId: trailArn, TagsList: tagsToAdd })
|
|
34959
|
+
);
|
|
34960
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on CloudTrail Trail ${trailArn}`);
|
|
34961
|
+
}
|
|
34962
|
+
}
|
|
34016
34963
|
/**
|
|
34017
34964
|
* Adopt an existing CloudTrail trail into cdkd state.
|
|
34018
34965
|
*
|
|
@@ -35836,7 +36783,7 @@ import {
|
|
|
35836
36783
|
SetRepositoryPolicyCommand,
|
|
35837
36784
|
PutImageScanningConfigurationCommand,
|
|
35838
36785
|
PutImageTagMutabilityCommand,
|
|
35839
|
-
TagResourceCommand as
|
|
36786
|
+
TagResourceCommand as TagResourceCommand15,
|
|
35840
36787
|
ListTagsForResourceCommand as ListTagsForResourceCommand18,
|
|
35841
36788
|
LifecyclePolicyNotFoundException,
|
|
35842
36789
|
RepositoryNotFoundException
|
|
@@ -36002,7 +36949,7 @@ var ECRProvider = class {
|
|
|
36002
36949
|
const repoArn = describeResponse.repositories?.[0]?.repositoryArn;
|
|
36003
36950
|
if (repoArn && newTags) {
|
|
36004
36951
|
await this.getClient().send(
|
|
36005
|
-
new
|
|
36952
|
+
new TagResourceCommand15({
|
|
36006
36953
|
resourceArn: repoArn,
|
|
36007
36954
|
tags: newTags
|
|
36008
36955
|
})
|
|
@@ -38885,6 +39832,19 @@ async function runAccept(reports, stateBackend, stateConfig, awsClients, options
|
|
|
38885
39832
|
}
|
|
38886
39833
|
}
|
|
38887
39834
|
}
|
|
39835
|
+
function buildRevertNewProperties(drifts, desiredProperties, awsProperties) {
|
|
39836
|
+
const result = { ...awsProperties };
|
|
39837
|
+
for (const d of drifts) {
|
|
39838
|
+
const topLevelKey = d.path.split(".", 1)[0];
|
|
39839
|
+
if (!topLevelKey)
|
|
39840
|
+
continue;
|
|
39841
|
+
if (topLevelKey in desiredProperties) {
|
|
39842
|
+
result[topLevelKey] = desiredProperties[topLevelKey];
|
|
39843
|
+
} else {
|
|
39844
|
+
}
|
|
39845
|
+
}
|
|
39846
|
+
return result;
|
|
39847
|
+
}
|
|
38888
39848
|
async function runRevert(reports, providerRegistry, stateConfig, awsClients, options) {
|
|
38889
39849
|
const logger = getLogger();
|
|
38890
39850
|
printRevertPlan(reports);
|
|
@@ -38927,13 +39887,18 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
|
|
|
38927
39887
|
}
|
|
38928
39888
|
const provider = providerRegistry.getProvider(outcome.resourceType);
|
|
38929
39889
|
const desiredProperties = stateResource.observedProperties ?? stateResource.properties ?? {};
|
|
39890
|
+
const newProperties = buildRevertNewProperties(
|
|
39891
|
+
outcome.changes,
|
|
39892
|
+
desiredProperties,
|
|
39893
|
+
outcome.awsProperties
|
|
39894
|
+
);
|
|
38930
39895
|
try {
|
|
38931
39896
|
await withRetry(
|
|
38932
39897
|
() => provider.update(
|
|
38933
39898
|
outcome.logicalId,
|
|
38934
39899
|
stateResource.physicalId,
|
|
38935
39900
|
outcome.resourceType,
|
|
38936
|
-
|
|
39901
|
+
newProperties,
|
|
38937
39902
|
outcome.awsProperties
|
|
38938
39903
|
),
|
|
38939
39904
|
outcome.logicalId,
|
|
@@ -42566,7 +43531,7 @@ function reorderArgs(argv) {
|
|
|
42566
43531
|
}
|
|
42567
43532
|
async function main() {
|
|
42568
43533
|
const program = new Command14();
|
|
42569
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.50.
|
|
43534
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.50.7");
|
|
42570
43535
|
program.addCommand(createBootstrapCommand());
|
|
42571
43536
|
program.addCommand(createSynthCommand());
|
|
42572
43537
|
program.addCommand(createListCommand());
|