@go-to-k/cdkd 0.231.0 → 0.231.2
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/{asg-provider-Dgj3loIG.js → asg-provider-Dd9Xze-T.js} +2 -2
- package/dist/{asg-provider-Dgj3loIG.js.map → asg-provider-Dd9Xze-T.js.map} +1 -1
- package/dist/cli.js +88 -370
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-IqXCHYxE.js → deploy-engine-B9NOJeGf.js} +360 -8
- package/dist/deploy-engine-B9NOJeGf.js.map +1 -0
- package/dist/{import-helpers-DayvBD4T.js → ec2-termination-protection-uvVnteGl.js} +32 -32
- package/dist/ec2-termination-protection-uvVnteGl.js.map +1 -0
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/deploy-engine-IqXCHYxE.js.map +0 -1
- package/dist/import-helpers-DayvBD4T.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as SynthesisError, F as getLiveRenderer, M as getLogger, S as ResourceUpdateNotSupportedError, T as StateError, U as withStackName, V as generateResourceNameWithFallback, a as
|
|
1
|
+
import { B as generateResourceName, E as SynthesisError, F as getLiveRenderer, M as getLogger, S as ResourceUpdateNotSupportedError, T as StateError, U as withStackName, V as generateResourceNameWithFallback, a as normalizeAwsTagsToCfn, b as ProvisioningError, c as AssetError, d as DependencyError, g as MacroExpansionError, h as LockError, i as matchesCdkPath, k as normalizeAwsError, l as CdkdError, n as isTerminationProtectionPropagationError, o as resolveExplicitPhysicalId, s as assertRegionMatch, t as disableInstanceApiTermination, x as ResourceTimeoutError, z as applyDefaultNameForFallback } from "./ec2-termination-protection-uvVnteGl.js";
|
|
2
2
|
import { r as getAwsClients } from "./aws-clients-pjPwZz1r.js";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, NoSuchKey, PutObjectCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -31,6 +31,7 @@ import { DescribeDBClustersCommand, DescribeDBInstancesCommand, RDSClient } from
|
|
|
31
31
|
import { DescribeReplicationGroupsCommand, ElastiCacheClient } from "@aws-sdk/client-elasticache";
|
|
32
32
|
import { DescribeClustersCommand, RedshiftClient } from "@aws-sdk/client-redshift";
|
|
33
33
|
import { DescribeDomainCommand, OpenSearchClient } from "@aws-sdk/client-opensearch";
|
|
34
|
+
import { CreateWebACLCommand, DeleteWebACLCommand, GetWebACLCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$8, ListWebACLsCommand, TagResourceCommand as TagResourceCommand$9, UntagResourceCommand as UntagResourceCommand$8, UpdateWebACLCommand, WAFNonexistentItemException, WAFV2Client } from "@aws-sdk/client-wafv2";
|
|
34
35
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
35
36
|
|
|
36
37
|
//#region src/utils/aws-region-resolver.ts
|
|
@@ -6061,6 +6062,342 @@ async function applyRoleArnIfSet(opts) {
|
|
|
6061
6062
|
}
|
|
6062
6063
|
}
|
|
6063
6064
|
|
|
6065
|
+
//#endregion
|
|
6066
|
+
//#region src/provisioning/providers/wafv2-provider.ts
|
|
6067
|
+
/**
|
|
6068
|
+
* Translate the empty-string placeholder `readCurrentState` emits for an
|
|
6069
|
+
* absent `Description` to `undefined` before shipping it to AWS.
|
|
6070
|
+
*
|
|
6071
|
+
* `readCurrentState` always-emits `Description: ''` on a WebACL with no
|
|
6072
|
+
* description (the comparator's top-level walk is state-keys-only, so
|
|
6073
|
+
* the placeholder is required to detect a console-side description add).
|
|
6074
|
+
* AWS WAFv2 `CreateWebACL` / `UpdateWebACL` reject `Description: ''`
|
|
6075
|
+
* with `Member must have length greater than or equal to 1` (min 1 / max
|
|
6076
|
+
* 256). On `cdkd drift --revert` the placeholder would round-trip
|
|
6077
|
+
* through `update()` and surface as a hard AWS rejection, so we sanitize
|
|
6078
|
+
* the wire-layer payload while keeping the read-side placeholder
|
|
6079
|
+
* intact. This is the Class 2 pattern from
|
|
6080
|
+
* `docs/provider-development.md § 3b`.
|
|
6081
|
+
*/
|
|
6082
|
+
function sanitizeDescription(value) {
|
|
6083
|
+
if (value === void 0 || value === null) return void 0;
|
|
6084
|
+
if (typeof value === "string" && value.length === 0) return void 0;
|
|
6085
|
+
return value;
|
|
6086
|
+
}
|
|
6087
|
+
/**
|
|
6088
|
+
* Parse WAFv2 WebACL ARN to extract Id, Name, and Scope.
|
|
6089
|
+
*
|
|
6090
|
+
* ARN format:
|
|
6091
|
+
* arn:aws:wafv2:{region}:{account}:regional/webacl/{name}/{id}
|
|
6092
|
+
* arn:aws:wafv2:{region}:{account}:global/webacl/{name}/{id}
|
|
6093
|
+
*
|
|
6094
|
+
* A short / malformed ARN yields `undefined` for `name` / `id` (the path
|
|
6095
|
+
* segments simply are not there) — callers must guard. `scope` is always
|
|
6096
|
+
* defined (anything not `global` maps to `REGIONAL`).
|
|
6097
|
+
*/
|
|
6098
|
+
function parseWebACLArn(arn) {
|
|
6099
|
+
const segments = arn.split(":").slice(5).join(":").split("/");
|
|
6100
|
+
const scopeRaw = segments[0];
|
|
6101
|
+
const name = segments[2];
|
|
6102
|
+
return {
|
|
6103
|
+
id: segments[3],
|
|
6104
|
+
name,
|
|
6105
|
+
scope: scopeRaw === "global" ? "CLOUDFRONT" : "REGIONAL"
|
|
6106
|
+
};
|
|
6107
|
+
}
|
|
6108
|
+
/**
|
|
6109
|
+
* AWS WAFv2 WebACL Provider
|
|
6110
|
+
*
|
|
6111
|
+
* Implements resource provisioning for AWS::WAFv2::WebACL using the WAFv2 SDK.
|
|
6112
|
+
* WHY: WAFv2 CreateWebACL is synchronous - the CC API adds unnecessary polling
|
|
6113
|
+
* overhead for an operation that completes immediately.
|
|
6114
|
+
* This SDK provider eliminates that polling and returns instantly.
|
|
6115
|
+
*/
|
|
6116
|
+
var WAFv2WebACLProvider = class {
|
|
6117
|
+
wafv2Client;
|
|
6118
|
+
providerRegion = process.env["AWS_REGION"];
|
|
6119
|
+
logger = getLogger().child("WAFv2WebACLProvider");
|
|
6120
|
+
handledProperties = new Map([["AWS::WAFv2::WebACL", new Set([
|
|
6121
|
+
"Name",
|
|
6122
|
+
"Scope",
|
|
6123
|
+
"Tags",
|
|
6124
|
+
"DefaultAction",
|
|
6125
|
+
"Description",
|
|
6126
|
+
"Rules",
|
|
6127
|
+
"VisibilityConfig",
|
|
6128
|
+
"CustomResponseBodies",
|
|
6129
|
+
"CaptchaConfig",
|
|
6130
|
+
"ChallengeConfig",
|
|
6131
|
+
"TokenDomains",
|
|
6132
|
+
"AssociationConfig"
|
|
6133
|
+
])]]);
|
|
6134
|
+
getClient() {
|
|
6135
|
+
if (!this.wafv2Client) this.wafv2Client = new WAFV2Client(this.providerRegion ? { region: this.providerRegion } : {});
|
|
6136
|
+
return this.wafv2Client;
|
|
6137
|
+
}
|
|
6138
|
+
/**
|
|
6139
|
+
* Create a WAFv2 WebACL
|
|
6140
|
+
*/
|
|
6141
|
+
async create(logicalId, resourceType, properties) {
|
|
6142
|
+
this.logger.debug(`Creating WAFv2 WebACL ${logicalId}`);
|
|
6143
|
+
const name = properties["Name"] || generateResourceName(logicalId, { maxLength: 128 });
|
|
6144
|
+
const scope = properties["Scope"] || "REGIONAL";
|
|
6145
|
+
try {
|
|
6146
|
+
const tags = [];
|
|
6147
|
+
if (properties["Tags"]) {
|
|
6148
|
+
const tagList = properties["Tags"];
|
|
6149
|
+
for (const tag of tagList) tags.push({
|
|
6150
|
+
Key: tag.Key,
|
|
6151
|
+
Value: tag.Value
|
|
6152
|
+
});
|
|
6153
|
+
}
|
|
6154
|
+
const summary = (await this.getClient().send(new CreateWebACLCommand({
|
|
6155
|
+
Name: name,
|
|
6156
|
+
Scope: scope,
|
|
6157
|
+
DefaultAction: properties["DefaultAction"],
|
|
6158
|
+
Description: sanitizeDescription(properties["Description"]),
|
|
6159
|
+
Rules: properties["Rules"] || [],
|
|
6160
|
+
VisibilityConfig: properties["VisibilityConfig"],
|
|
6161
|
+
...tags.length > 0 && { Tags: tags },
|
|
6162
|
+
CustomResponseBodies: properties["CustomResponseBodies"],
|
|
6163
|
+
CaptchaConfig: properties["CaptchaConfig"],
|
|
6164
|
+
ChallengeConfig: properties["ChallengeConfig"],
|
|
6165
|
+
TokenDomains: properties["TokenDomains"],
|
|
6166
|
+
AssociationConfig: properties["AssociationConfig"]
|
|
6167
|
+
}))).Summary;
|
|
6168
|
+
if (!summary?.ARN || !summary?.Id) throw new Error("CreateWebACL did not return Summary with ARN and Id");
|
|
6169
|
+
this.logger.debug(`Successfully created WAFv2 WebACL ${logicalId}: ${summary.ARN}`);
|
|
6170
|
+
return {
|
|
6171
|
+
physicalId: summary.ARN,
|
|
6172
|
+
attributes: {
|
|
6173
|
+
Arn: summary.ARN,
|
|
6174
|
+
Id: summary.Id,
|
|
6175
|
+
LabelNamespace: summary["LabelNamespace"]
|
|
6176
|
+
}
|
|
6177
|
+
};
|
|
6178
|
+
} catch (error) {
|
|
6179
|
+
if (error instanceof ProvisioningError) throw error;
|
|
6180
|
+
const cause = error instanceof Error ? error : void 0;
|
|
6181
|
+
throw new ProvisioningError(`Failed to create WAFv2 WebACL ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
6182
|
+
}
|
|
6183
|
+
}
|
|
6184
|
+
/**
|
|
6185
|
+
* Update a WAFv2 WebACL
|
|
6186
|
+
*
|
|
6187
|
+
* Name and Scope are immutable - changes to those require replacement.
|
|
6188
|
+
* UpdateWebACL requires LockToken obtained from GetWebACL.
|
|
6189
|
+
*/
|
|
6190
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
6191
|
+
this.logger.debug(`Updating WAFv2 WebACL ${logicalId}: ${physicalId}`);
|
|
6192
|
+
try {
|
|
6193
|
+
const { id, name, scope } = parseWebACLArn(physicalId);
|
|
6194
|
+
const getResponse = await this.getClient().send(new GetWebACLCommand({
|
|
6195
|
+
Name: name,
|
|
6196
|
+
Scope: scope,
|
|
6197
|
+
Id: id
|
|
6198
|
+
}));
|
|
6199
|
+
const lockToken = getResponse.LockToken;
|
|
6200
|
+
if (!lockToken) throw new Error("GetWebACL did not return LockToken");
|
|
6201
|
+
await this.getClient().send(new UpdateWebACLCommand({
|
|
6202
|
+
Name: name,
|
|
6203
|
+
Scope: scope,
|
|
6204
|
+
Id: id,
|
|
6205
|
+
LockToken: lockToken,
|
|
6206
|
+
DefaultAction: properties["DefaultAction"],
|
|
6207
|
+
Description: sanitizeDescription(properties["Description"]),
|
|
6208
|
+
Rules: properties["Rules"] || [],
|
|
6209
|
+
VisibilityConfig: properties["VisibilityConfig"],
|
|
6210
|
+
CustomResponseBodies: properties["CustomResponseBodies"],
|
|
6211
|
+
CaptchaConfig: properties["CaptchaConfig"],
|
|
6212
|
+
ChallengeConfig: properties["ChallengeConfig"],
|
|
6213
|
+
TokenDomains: properties["TokenDomains"],
|
|
6214
|
+
AssociationConfig: properties["AssociationConfig"]
|
|
6215
|
+
}));
|
|
6216
|
+
await this.applyTagDiff(physicalId, previousProperties["Tags"], properties["Tags"]);
|
|
6217
|
+
this.logger.debug(`Successfully updated WAFv2 WebACL ${logicalId}`);
|
|
6218
|
+
return {
|
|
6219
|
+
physicalId,
|
|
6220
|
+
wasReplaced: false,
|
|
6221
|
+
attributes: {
|
|
6222
|
+
Arn: physicalId,
|
|
6223
|
+
Id: id,
|
|
6224
|
+
LabelNamespace: getResponse.WebACL?.LabelNamespace
|
|
6225
|
+
}
|
|
6226
|
+
};
|
|
6227
|
+
} catch (error) {
|
|
6228
|
+
if (error instanceof ProvisioningError) throw error;
|
|
6229
|
+
const cause = error instanceof Error ? error : void 0;
|
|
6230
|
+
throw new ProvisioningError(`Failed to update WAFv2 WebACL ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
6231
|
+
}
|
|
6232
|
+
}
|
|
6233
|
+
/**
|
|
6234
|
+
* Delete a WAFv2 WebACL
|
|
6235
|
+
*
|
|
6236
|
+
* DeleteWebACL requires LockToken obtained from GetWebACL.
|
|
6237
|
+
* WAFNonexistentItemException is treated as success (idempotent delete).
|
|
6238
|
+
*/
|
|
6239
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
6240
|
+
this.logger.debug(`Deleting WAFv2 WebACL ${logicalId}: ${physicalId}`);
|
|
6241
|
+
try {
|
|
6242
|
+
const { id, name, scope } = parseWebACLArn(physicalId);
|
|
6243
|
+
const lockToken = (await this.getClient().send(new GetWebACLCommand({
|
|
6244
|
+
Name: name,
|
|
6245
|
+
Scope: scope,
|
|
6246
|
+
Id: id
|
|
6247
|
+
}))).LockToken;
|
|
6248
|
+
if (!lockToken) throw new Error("GetWebACL did not return LockToken");
|
|
6249
|
+
await this.getClient().send(new DeleteWebACLCommand({
|
|
6250
|
+
Name: name,
|
|
6251
|
+
Scope: scope,
|
|
6252
|
+
Id: id,
|
|
6253
|
+
LockToken: lockToken
|
|
6254
|
+
}));
|
|
6255
|
+
this.logger.debug(`Successfully deleted WAFv2 WebACL ${logicalId}`);
|
|
6256
|
+
} catch (error) {
|
|
6257
|
+
if (error instanceof WAFNonexistentItemException) {
|
|
6258
|
+
assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
6259
|
+
this.logger.debug(`WAFv2 WebACL ${physicalId} does not exist, skipping deletion`);
|
|
6260
|
+
return;
|
|
6261
|
+
}
|
|
6262
|
+
const cause = error instanceof Error ? error : void 0;
|
|
6263
|
+
throw new ProvisioningError(`Failed to delete WAFv2 WebACL ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
6264
|
+
}
|
|
6265
|
+
}
|
|
6266
|
+
/**
|
|
6267
|
+
* Apply a diff between old and new CFn-shape Tags arrays via WAFv2's
|
|
6268
|
+
* `TagResource` / `UntagResource` APIs (keyed by `ResourceARN`).
|
|
6269
|
+
*/
|
|
6270
|
+
async applyTagDiff(arn, oldTagsRaw, newTagsRaw) {
|
|
6271
|
+
const toMap = (tags) => {
|
|
6272
|
+
const m = /* @__PURE__ */ new Map();
|
|
6273
|
+
for (const t of tags ?? []) if (t.Key !== void 0 && t.Value !== void 0) m.set(t.Key, t.Value);
|
|
6274
|
+
return m;
|
|
6275
|
+
};
|
|
6276
|
+
const oldMap = toMap(oldTagsRaw);
|
|
6277
|
+
const newMap = toMap(newTagsRaw);
|
|
6278
|
+
const tagsToAdd = [];
|
|
6279
|
+
for (const [k, v] of newMap) if (oldMap.get(k) !== v) tagsToAdd.push({
|
|
6280
|
+
Key: k,
|
|
6281
|
+
Value: v
|
|
6282
|
+
});
|
|
6283
|
+
const tagsToRemove = [];
|
|
6284
|
+
for (const k of oldMap.keys()) if (!newMap.has(k)) tagsToRemove.push(k);
|
|
6285
|
+
if (tagsToRemove.length > 0) {
|
|
6286
|
+
await this.getClient().send(new UntagResourceCommand$8({
|
|
6287
|
+
ResourceARN: arn,
|
|
6288
|
+
TagKeys: tagsToRemove
|
|
6289
|
+
}));
|
|
6290
|
+
this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from WAFv2 WebACL ${arn}`);
|
|
6291
|
+
}
|
|
6292
|
+
if (tagsToAdd.length > 0) {
|
|
6293
|
+
await this.getClient().send(new TagResourceCommand$9({
|
|
6294
|
+
ResourceARN: arn,
|
|
6295
|
+
Tags: tagsToAdd
|
|
6296
|
+
}));
|
|
6297
|
+
this.logger.debug(`Added/updated ${tagsToAdd.length} tag(s) on WAFv2 WebACL ${arn}`);
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6300
|
+
/**
|
|
6301
|
+
* Read the AWS-current WAFv2 WebACL configuration in CFn-property shape.
|
|
6302
|
+
*
|
|
6303
|
+
* The cdkd physicalId is the WebACL ARN; we parse it back to
|
|
6304
|
+
* `(id, name, scope)` and call `GetWebACL`. The response holds Name,
|
|
6305
|
+
* Description, DefaultAction, Rules, VisibilityConfig,
|
|
6306
|
+
* CustomResponseBodies, CaptchaConfig, ChallengeConfig, TokenDomains,
|
|
6307
|
+
* and AssociationConfig — every key cdkd state declares as
|
|
6308
|
+
* `handledProperties`. `Scope` is recovered from the ARN parse.
|
|
6309
|
+
*
|
|
6310
|
+
* Tags are surfaced via a follow-up `ListTagsForResource(ResourceARN)`
|
|
6311
|
+
* call. CDK's `aws:*` auto-tags are filtered out and the result key is
|
|
6312
|
+
* omitted when AWS reports no user tags. Returns `undefined`
|
|
6313
|
+
* when the ARN can't be parsed or the WebACL is gone
|
|
6314
|
+
* (`WAFNonexistentItemException`).
|
|
6315
|
+
*/
|
|
6316
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
6317
|
+
const { id, name, scope } = parseWebACLArn(physicalId);
|
|
6318
|
+
if (!id || !name) return void 0;
|
|
6319
|
+
let webACL;
|
|
6320
|
+
try {
|
|
6321
|
+
webACL = (await this.getClient().send(new GetWebACLCommand({
|
|
6322
|
+
Id: id,
|
|
6323
|
+
Name: name,
|
|
6324
|
+
Scope: scope
|
|
6325
|
+
}))).WebACL;
|
|
6326
|
+
} catch (err) {
|
|
6327
|
+
if (err instanceof WAFNonexistentItemException) return void 0;
|
|
6328
|
+
throw err;
|
|
6329
|
+
}
|
|
6330
|
+
if (!webACL) return void 0;
|
|
6331
|
+
const result = {};
|
|
6332
|
+
if (webACL.Name !== void 0) result["Name"] = webACL.Name;
|
|
6333
|
+
result["Scope"] = scope;
|
|
6334
|
+
result["Description"] = webACL.Description ?? "";
|
|
6335
|
+
if (webACL.DefaultAction) result["DefaultAction"] = webACL.DefaultAction;
|
|
6336
|
+
result["Rules"] = (webACL.Rules ?? []).map((r) => r);
|
|
6337
|
+
if (webACL.VisibilityConfig) result["VisibilityConfig"] = webACL.VisibilityConfig;
|
|
6338
|
+
result["CustomResponseBodies"] = webACL.CustomResponseBodies ?? {};
|
|
6339
|
+
if (webACL.CaptchaConfig) result["CaptchaConfig"] = webACL.CaptchaConfig;
|
|
6340
|
+
if (webACL.ChallengeConfig) result["ChallengeConfig"] = webACL.ChallengeConfig;
|
|
6341
|
+
result["TokenDomains"] = webACL.TokenDomains ? [...webACL.TokenDomains] : [];
|
|
6342
|
+
if (webACL.AssociationConfig) result["AssociationConfig"] = webACL.AssociationConfig;
|
|
6343
|
+
try {
|
|
6344
|
+
result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$8({ ResourceARN: physicalId }))).TagInfoForResource?.TagList);
|
|
6345
|
+
} catch (err) {
|
|
6346
|
+
this.logger.debug(`WAFv2 ListTagsForResource(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6347
|
+
}
|
|
6348
|
+
return result;
|
|
6349
|
+
}
|
|
6350
|
+
/**
|
|
6351
|
+
* Adopt an existing WAFv2 WebACL into cdkd state.
|
|
6352
|
+
*
|
|
6353
|
+
* Lookup order:
|
|
6354
|
+
* 1. `--resource <id>=<arn>` override → verify with `GetWebACL` (parses
|
|
6355
|
+
* Name/Id/Scope back out of the ARN).
|
|
6356
|
+
* 2. Walk `ListWebACLs(Scope)` → match `aws:cdk:path` via
|
|
6357
|
+
* `ListTagsForResource(ResourceARN)` (returns
|
|
6358
|
+
* `TagInfoForResource.TagList`, standard `Key`/`Value` shape).
|
|
6359
|
+
*
|
|
6360
|
+
* `Scope` is required by `ListWebACLs` — read from
|
|
6361
|
+
* `Properties.Scope` (`REGIONAL` is the default).
|
|
6362
|
+
*/
|
|
6363
|
+
async import(input) {
|
|
6364
|
+
if (input.knownPhysicalId) try {
|
|
6365
|
+
const { id, name, scope } = parseWebACLArn(input.knownPhysicalId);
|
|
6366
|
+
await this.getClient().send(new GetWebACLCommand({
|
|
6367
|
+
Id: id,
|
|
6368
|
+
Name: name,
|
|
6369
|
+
Scope: scope
|
|
6370
|
+
}));
|
|
6371
|
+
return {
|
|
6372
|
+
physicalId: input.knownPhysicalId,
|
|
6373
|
+
attributes: {}
|
|
6374
|
+
};
|
|
6375
|
+
} catch (err) {
|
|
6376
|
+
if (err instanceof WAFNonexistentItemException) return null;
|
|
6377
|
+
throw err;
|
|
6378
|
+
}
|
|
6379
|
+
if (!input.cdkPath) return null;
|
|
6380
|
+
const scope = input.properties["Scope"] || "REGIONAL";
|
|
6381
|
+
let nextMarker;
|
|
6382
|
+
do {
|
|
6383
|
+
const list = await this.getClient().send(new ListWebACLsCommand({
|
|
6384
|
+
Scope: scope,
|
|
6385
|
+
...nextMarker && { NextMarker: nextMarker }
|
|
6386
|
+
}));
|
|
6387
|
+
for (const item of list.WebACLs ?? []) {
|
|
6388
|
+
if (!item.ARN) continue;
|
|
6389
|
+
const tagList = (await this.getClient().send(new ListTagsForResourceCommand$8({ ResourceARN: item.ARN }))).TagInfoForResource?.TagList;
|
|
6390
|
+
if (matchesCdkPath(tagList, input.cdkPath)) return {
|
|
6391
|
+
physicalId: item.ARN,
|
|
6392
|
+
attributes: {}
|
|
6393
|
+
};
|
|
6394
|
+
}
|
|
6395
|
+
nextMarker = list.NextMarker;
|
|
6396
|
+
} while (nextMarker);
|
|
6397
|
+
return null;
|
|
6398
|
+
}
|
|
6399
|
+
};
|
|
6400
|
+
|
|
6064
6401
|
//#endregion
|
|
6065
6402
|
//#region src/deployment/intrinsic-function-resolver.ts
|
|
6066
6403
|
/**
|
|
@@ -6127,8 +6464,15 @@ const AWS_NO_VALUE = Symbol("AWS::NoValue");
|
|
|
6127
6464
|
* CFn-generated synthetic id like `mysta-metho-01234b567890example`, not
|
|
6128
6465
|
* reconstructible from the `<apiId>|<resourceId>|<verb>` physical id).
|
|
6129
6466
|
* Also EXCLUDE types whose AWS-docs page documents NO `Ref` return value
|
|
6130
|
-
* at all (ApiGateway::DocumentationVersion) — with no
|
|
6131
|
-
* the raw physical id is the least-surprising value.
|
|
6467
|
+
* at all (ApiGateway::DocumentationVersion, Lambda::Permission) — with no
|
|
6468
|
+
* contract to honor, the raw physical id is the least-surprising value.
|
|
6469
|
+
* The 2026-07-03 cross-family audit of every SDK-registered compound-id
|
|
6470
|
+
* type also excluded EC2::Route ("the ID of the route") /
|
|
6471
|
+
* EC2::VPCGatewayAttachment ("the ID of the VPC gateway attachment") /
|
|
6472
|
+
* Lambda::EventInvokeConfig ("a unique identifier") — all synthetic CFn
|
|
6473
|
+
* ids with no bare-segment contract and no consuming API — and
|
|
6474
|
+
* confirmed WAFv2::WebACL's `Ref` IS the pipe-joined compound (see the
|
|
6475
|
+
* special case in {@link cfnRefValueFromPhysicalId}).
|
|
6132
6476
|
* 4. Types whose primaryIdentifier puts the `Ref` component FIRST
|
|
6133
6477
|
* (`[<refId>, <parentId>]` — e.g. ApiGateway::Deployment /
|
|
6134
6478
|
* ::DocumentationPart) belong in
|
|
@@ -6158,7 +6502,9 @@ const REF_RETURNS_SEGMENT_AFTER_PIPE = new Set([
|
|
|
6158
6502
|
"AWS::AppConfig::Environment",
|
|
6159
6503
|
"AWS::AppConfig::ConfigurationProfile",
|
|
6160
6504
|
"AWS::AppConfig::HostedConfigurationVersion",
|
|
6161
|
-
"AWS::AppConfig::Deployment"
|
|
6505
|
+
"AWS::AppConfig::Deployment",
|
|
6506
|
+
"AWS::S3Tables::Namespace",
|
|
6507
|
+
"AWS::S3Tables::Table"
|
|
6162
6508
|
]);
|
|
6163
6509
|
/**
|
|
6164
6510
|
* Sibling of {@link REF_RETURNS_SEGMENT_AFTER_PIPE} for compound-id types
|
|
@@ -6191,7 +6537,8 @@ const REF_RETURNS_SEGMENT_BEFORE_FIRST_PIPE = new Set([
|
|
|
6191
6537
|
"AWS::ApiGateway::Deployment",
|
|
6192
6538
|
"AWS::ApiGateway::DocumentationPart",
|
|
6193
6539
|
"AWS::ApiGatewayV2::Authorizer",
|
|
6194
|
-
"AWS::ApiGatewayV2::ApiMapping"
|
|
6540
|
+
"AWS::ApiGatewayV2::ApiMapping",
|
|
6541
|
+
"AWS::ECS::Service"
|
|
6195
6542
|
]);
|
|
6196
6543
|
/**
|
|
6197
6544
|
* SDK-provisioned types whose provider stores the resource ARN as the physical
|
|
@@ -6214,6 +6561,11 @@ const REF_RETURNS_NAME_FROM_ARN = new Map([["AWS::Events::Rule", ":rule/"], ["AW
|
|
|
6214
6561
|
* extraction and name-from-ARN extraction included).
|
|
6215
6562
|
*/
|
|
6216
6563
|
function cfnRefValueFromPhysicalId(resourceType, physicalId) {
|
|
6564
|
+
if (resourceType === "AWS::WAFv2::WebACL" && physicalId.startsWith("arn:")) {
|
|
6565
|
+
const { id, name, scope } = parseWebACLArn(physicalId);
|
|
6566
|
+
if (name && id) return `${name}|${id}|${scope}`;
|
|
6567
|
+
return physicalId;
|
|
6568
|
+
}
|
|
6217
6569
|
const nameMarker = REF_RETURNS_NAME_FROM_ARN.get(resourceType);
|
|
6218
6570
|
if (nameMarker && physicalId.startsWith("arn:")) {
|
|
6219
6571
|
const markerIdx = physicalId.indexOf(nameMarker);
|
|
@@ -8269,7 +8621,7 @@ var CloudControlProvider = class {
|
|
|
8269
8621
|
this.logger.debug(`Deleting resource ${logicalId} (${resourceType}), physical ID: ${physicalId}`);
|
|
8270
8622
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
8271
8623
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
8272
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
8624
|
+
const { ASGProvider } = await import("./asg-provider-Dd9Xze-T.js").then((n) => n.n);
|
|
8273
8625
|
await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
8274
8626
|
return;
|
|
8275
8627
|
}
|
|
@@ -14507,5 +14859,5 @@ var DeployEngine = class {
|
|
|
14507
14859
|
};
|
|
14508
14860
|
|
|
14509
14861
|
//#endregion
|
|
14510
|
-
export {
|
|
14511
|
-
//# sourceMappingURL=deploy-engine-
|
|
14862
|
+
export { resolveStateBucketWithDefault as $, DagBuilder as A, formatDockerLoginError as B, findActionableSilentDrops as C, WAFv2WebACLProvider as D, cfnRefValueFromPhysicalId as E, shouldRetainResource as F, getDockerImageBySourceHash as G, runDockerForeground as H, AssetPublisher as I, getDefaultStateBucketName as J, Synthesizer as K, stringifyValue as L, LockManager as M, S3StateBackend as N, applyRoleArnIfSet as O, rebuildClientForBucketRegion as P, resolveSkipPrefix as Q, WorkGraph as R, ProviderRegistry as S, IntrinsicFunctionResolver as T, runDockerStreaming as U, getDockerCmd as V, AssetManifestLoader as W, resolveApp as X, getLegacyStateBucketName as Y, resolveCaptureObservedState as Z, green as _, withRetry as a, findLargeInlineResources as at, IAMRoleProvider as b, computeImplicitDeleteEdges as c, clearBucketRegionCache as ct, isStatefulRecreateTargetSync as d, resolveStateBucketWithDefaultAndSource as et, renderStatefulReason as f, gray as g, cyan as h, withResourceDeadline as i, MIGRATE_TMP_PREFIX as it, TemplateParser as j, DiffCalculator as k, extractDeploymentEventError as l, resolveBucketRegion as lt, bold as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, CFN_TEMPLATE_BODY_LIMIT as nt, isRetryableTransientError as o, uploadCfnTemplate as ot, formatResourceLine as p, synthesisStatusMessage as q, DeployEngine as r, CFN_TEMPLATE_URL_LIMIT as rt, IMPLICIT_DELETE_DEPENDENCIES as s, AssemblyReader as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, warnDeprecatedNoPrefixCliFlag as tt, MULTI_REGION_RECREATE_BLOCKED_TYPES as u, red as v, CloudControlProvider as w, collectInlinePolicyNamesManagedBySiblings as x, yellow as y, buildDockerImage as z };
|
|
14863
|
+
//# sourceMappingURL=deploy-engine-B9NOJeGf.js.map
|