@go-to-k/cdkd 0.221.8 → 0.221.9
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 +14 -3
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-DCkhw7i7.js → deploy-engine-alFrHerE.js} +147 -3
- package/dist/deploy-engine-alFrHerE.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-DCkhw7i7.js.map +0 -1
|
@@ -7,7 +7,7 @@ import { AttachRolePolicyCommand, CreateRoleCommand, DeleteRoleCommand, DeleteRo
|
|
|
7
7
|
import { PublishCommand, SNSClient } from "@aws-sdk/client-sns";
|
|
8
8
|
import { GetFunctionCommand, GetFunctionUrlConfigCommand, InvokeCommand, LambdaClient, UpdateFunctionConfigurationCommand, waitUntilFunctionActiveV2, waitUntilFunctionUpdatedV2 } from "@aws-sdk/client-lambda";
|
|
9
9
|
import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
|
|
10
|
-
import { DescribeAvailabilityZonesCommand, DescribeImagesCommand, DescribeLaunchTemplatesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVpcsCommand, DescribeVpnGatewaysCommand, EC2Client } from "@aws-sdk/client-ec2";
|
|
10
|
+
import { DescribeAvailabilityZonesCommand, DescribeImagesCommand, DescribeInstancesCommand, DescribeLaunchTemplatesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVpcsCommand, DescribeVpnGatewaysCommand, EC2Client } from "@aws-sdk/client-ec2";
|
|
11
11
|
import { DescribeTableCommand } from "@aws-sdk/client-dynamodb";
|
|
12
12
|
import { CloudFormationClient, CreateChangeSetCommand, DeleteStackCommand, DescribeChangeSetCommand, DescribeTypeCommand, GetTemplateCommand, waitUntilChangeSetCreateComplete } from "@aws-sdk/client-cloudformation";
|
|
13
13
|
import { GetRestApiCommand } from "@aws-sdk/client-api-gateway";
|
|
@@ -5463,6 +5463,15 @@ const cachedAvailabilityZones = {};
|
|
|
5463
5463
|
*/
|
|
5464
5464
|
const cachedDynamicReferences = {};
|
|
5465
5465
|
/**
|
|
5466
|
+
* Cache for EC2 instance attributes that require a live DescribeInstances
|
|
5467
|
+
* lookup (PrivateIp / PublicIp / PrivateDnsName / PublicDnsName /
|
|
5468
|
+
* AvailabilityZone). Keyed by `${physicalId}#${attributeName}`. The IP /
|
|
5469
|
+
* DNS attributes are not derivable from the instance id, so they are read
|
|
5470
|
+
* back from AWS once per (instance, attribute) and memoized for the deploy
|
|
5471
|
+
* lifetime.
|
|
5472
|
+
*/
|
|
5473
|
+
const cachedEc2InstanceAttributes = {};
|
|
5474
|
+
/**
|
|
5466
5475
|
* Get AWS account information from STS
|
|
5467
5476
|
*/
|
|
5468
5477
|
async function getAccountInfo(overrideRegion) {
|
|
@@ -5859,6 +5868,10 @@ var IntrinsicFunctionResolver = class {
|
|
|
5859
5868
|
case "Arn": return `arn:${partition}:cloudwatch:${region}:${accountId}:alarm:${physicalId}`;
|
|
5860
5869
|
default: return physicalId;
|
|
5861
5870
|
}
|
|
5871
|
+
if (resourceType === "AWS::CloudWatch::CompositeAlarm") switch (attributeName) {
|
|
5872
|
+
case "Arn": return `arn:${partition}:cloudwatch:${region}:${accountId}:alarm:${physicalId}`;
|
|
5873
|
+
default: return physicalId;
|
|
5874
|
+
}
|
|
5862
5875
|
if (resourceType === "AWS::RDS::DBInstance" || resourceType === "AWS::DocDB::DBInstance" || resourceType === "AWS::Neptune::DBInstance") switch (attributeName) {
|
|
5863
5876
|
case "DBInstanceArn":
|
|
5864
5877
|
case "Arn": return `arn:${partition}:rds:${region}:${accountId}:db:${physicalId}`;
|
|
@@ -5929,6 +5942,47 @@ var IntrinsicFunctionResolver = class {
|
|
|
5929
5942
|
case "SubnetId": return physicalId;
|
|
5930
5943
|
default: return physicalId;
|
|
5931
5944
|
}
|
|
5945
|
+
if (resourceType === "AWS::EC2::Instance") switch (attributeName) {
|
|
5946
|
+
case "PrivateIp":
|
|
5947
|
+
case "PublicIp":
|
|
5948
|
+
case "PrivateDnsName":
|
|
5949
|
+
case "PublicDnsName":
|
|
5950
|
+
case "AvailabilityZone": {
|
|
5951
|
+
const cacheKey = `${physicalId}#${attributeName}`;
|
|
5952
|
+
const cached = cachedEc2InstanceAttributes[cacheKey];
|
|
5953
|
+
if (cached !== void 0) return cached;
|
|
5954
|
+
try {
|
|
5955
|
+
const instance = (await getAwsClients().ec2.send(new DescribeInstancesCommand({ InstanceIds: [physicalId] }))).Reservations?.[0]?.Instances?.[0];
|
|
5956
|
+
let value;
|
|
5957
|
+
switch (attributeName) {
|
|
5958
|
+
case "PrivateIp":
|
|
5959
|
+
value = instance?.PrivateIpAddress;
|
|
5960
|
+
break;
|
|
5961
|
+
case "PublicIp":
|
|
5962
|
+
value = instance?.PublicIpAddress;
|
|
5963
|
+
break;
|
|
5964
|
+
case "PrivateDnsName":
|
|
5965
|
+
value = instance?.PrivateDnsName;
|
|
5966
|
+
break;
|
|
5967
|
+
case "PublicDnsName":
|
|
5968
|
+
value = instance?.PublicDnsName;
|
|
5969
|
+
break;
|
|
5970
|
+
case "AvailabilityZone":
|
|
5971
|
+
value = instance?.Placement?.AvailabilityZone;
|
|
5972
|
+
break;
|
|
5973
|
+
}
|
|
5974
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
5975
|
+
cachedEc2InstanceAttributes[cacheKey] = value;
|
|
5976
|
+
return value;
|
|
5977
|
+
}
|
|
5978
|
+
this.logger.warn(`DescribeInstances(${physicalId}) returned no ${attributeName}; returning physical ID`);
|
|
5979
|
+
} catch (err) {
|
|
5980
|
+
this.logger.warn(`DescribeInstances(${physicalId}) failed for ${attributeName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
5981
|
+
}
|
|
5982
|
+
return physicalId;
|
|
5983
|
+
}
|
|
5984
|
+
default: return physicalId;
|
|
5985
|
+
}
|
|
5932
5986
|
if (resourceType === "AWS::EC2::LaunchTemplate") {
|
|
5933
5987
|
if (attributeName === "LatestVersionNumber" || attributeName === "DefaultVersionNumber") {
|
|
5934
5988
|
try {
|
|
@@ -11435,6 +11489,84 @@ const IMPLICIT_DELETE_DEPENDENCIES = {
|
|
|
11435
11489
|
"AWS::Lambda::Function"
|
|
11436
11490
|
]
|
|
11437
11491
|
};
|
|
11492
|
+
/**
|
|
11493
|
+
* Matches one alarm-state function token in a CompositeAlarm `AlarmRule`:
|
|
11494
|
+
* ALARM("name") | OK('name') | INSUFFICIENT_DATA(name)
|
|
11495
|
+
* The argument is captured raw (with any surrounding quotes) and trimmed /
|
|
11496
|
+
* unquoted by {@link extractReferencedAlarmNames}. CloudWatch also accepts the
|
|
11497
|
+
* boolean literals TRUE / FALSE which carry no argument, so they never match.
|
|
11498
|
+
*/
|
|
11499
|
+
const ALARM_RULE_FUNCTION_REGEX = /\b(?:ALARM|OK|INSUFFICIENT_DATA)\s*\(\s*([^)]*?)\s*\)/gi;
|
|
11500
|
+
/**
|
|
11501
|
+
* Extract every alarm NAME (or ARN) referenced by a CompositeAlarm `AlarmRule`
|
|
11502
|
+
* string. The rule references its child alarms by NAME (or ARN) as a plain
|
|
11503
|
+
* string — there is no `Ref` / `Fn::GetAtt`, so cdkd's DAG sees no dependency
|
|
11504
|
+
* edge from these references. We parse them out so a delete-ordering edge can be
|
|
11505
|
+
* synthesized (CloudWatch refuses to delete a metric alarm while a composite
|
|
11506
|
+
* alarm still references it).
|
|
11507
|
+
*
|
|
11508
|
+
* Handles the three alarm-state functions (`ALARM` / `OK` / `INSUFFICIENT_DATA`)
|
|
11509
|
+
* and both the bare-name and quoted-name forms. An ARN argument
|
|
11510
|
+
* (`arn:aws:cloudwatch:...:alarm:<name>`) is reduced to its trailing `<name>`
|
|
11511
|
+
* so it can be matched against a referenced alarm's `AlarmName` / physical id
|
|
11512
|
+
* the same way a bare name is.
|
|
11513
|
+
*/
|
|
11514
|
+
function extractReferencedAlarmNames(alarmRule) {
|
|
11515
|
+
const names = /* @__PURE__ */ new Set();
|
|
11516
|
+
for (const match of alarmRule.matchAll(ALARM_RULE_FUNCTION_REGEX)) {
|
|
11517
|
+
let arg = (match[1] ?? "").trim();
|
|
11518
|
+
if (arg.length === 0) continue;
|
|
11519
|
+
if (arg.startsWith("\"") && arg.endsWith("\"") || arg.startsWith("'") && arg.endsWith("'")) arg = arg.slice(1, -1);
|
|
11520
|
+
if (arg.length === 0) continue;
|
|
11521
|
+
const arnAlarmMatch = /:alarm:(.+)$/.exec(arg);
|
|
11522
|
+
if (arnAlarmMatch?.[1]) names.add(arnAlarmMatch[1]);
|
|
11523
|
+
else names.add(arg);
|
|
11524
|
+
}
|
|
11525
|
+
return [...names];
|
|
11526
|
+
}
|
|
11527
|
+
/**
|
|
11528
|
+
* Compute per-resource delete-ordering edges that cannot be inferred from
|
|
11529
|
+
* Ref / Fn::GetAtt edges or from the type-pair {@link IMPLICIT_DELETE_DEPENDENCIES}
|
|
11530
|
+
* table.
|
|
11531
|
+
*
|
|
11532
|
+
* Currently this synthesizes edges for `AWS::CloudWatch::CompositeAlarm`: a
|
|
11533
|
+
* composite alarm references its child alarms (metric `AWS::CloudWatch::Alarm`
|
|
11534
|
+
* or other composite alarms) by NAME inside its `AlarmRule` string. Because the
|
|
11535
|
+
* reference is a plain string (no `Ref` / `Fn::GetAtt`), cdkd's DAG sees no
|
|
11536
|
+
* dependency edge, so without this the metric alarm can be scheduled for
|
|
11537
|
+
* deletion while the composite still exists — and CloudWatch rejects that with
|
|
11538
|
+
* `Cannot delete <alarm> as there are composite alarm(s) depending on it.`
|
|
11539
|
+
* We therefore emit an edge making the composite alarm delete BEFORE every
|
|
11540
|
+
* alarm its `AlarmRule` references (handling composite-of-composite too).
|
|
11541
|
+
*
|
|
11542
|
+
* @param resources logical id -> resource (the subset of resources participating
|
|
11543
|
+
* in the delete). Only entries whose logical id is a key in this record are
|
|
11544
|
+
* considered as edge endpoints.
|
|
11545
|
+
*/
|
|
11546
|
+
function computeImplicitDeleteEdges(resources) {
|
|
11547
|
+
const edges = [];
|
|
11548
|
+
const alarmTypes = new Set(["AWS::CloudWatch::Alarm", "AWS::CloudWatch::CompositeAlarm"]);
|
|
11549
|
+
const nameToLogicalId = /* @__PURE__ */ new Map();
|
|
11550
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
11551
|
+
if (!alarmTypes.has(resource.resourceType)) continue;
|
|
11552
|
+
const alarmName = typeof resource.properties?.["AlarmName"] === "string" ? resource.properties["AlarmName"] : resource.physicalId;
|
|
11553
|
+
if (alarmName) nameToLogicalId.set(alarmName, logicalId);
|
|
11554
|
+
}
|
|
11555
|
+
for (const [logicalId, resource] of Object.entries(resources)) {
|
|
11556
|
+
if (resource.resourceType !== "AWS::CloudWatch::CompositeAlarm") continue;
|
|
11557
|
+
const alarmRule = resource.properties?.["AlarmRule"];
|
|
11558
|
+
if (typeof alarmRule !== "string") continue;
|
|
11559
|
+
for (const referencedName of extractReferencedAlarmNames(alarmRule)) {
|
|
11560
|
+
const referencedLogicalId = nameToLogicalId.get(referencedName);
|
|
11561
|
+
if (!referencedLogicalId || referencedLogicalId === logicalId) continue;
|
|
11562
|
+
edges.push({
|
|
11563
|
+
before: logicalId,
|
|
11564
|
+
after: referencedLogicalId
|
|
11565
|
+
});
|
|
11566
|
+
}
|
|
11567
|
+
}
|
|
11568
|
+
return edges;
|
|
11569
|
+
}
|
|
11438
11570
|
|
|
11439
11571
|
//#endregion
|
|
11440
11572
|
//#region src/deployment/retryable-errors.ts
|
|
@@ -12850,6 +12982,18 @@ var DeployEngine = class {
|
|
|
12850
12982
|
}
|
|
12851
12983
|
}
|
|
12852
12984
|
}
|
|
12985
|
+
const scoped = {};
|
|
12986
|
+
for (const id of deleteIds) {
|
|
12987
|
+
const resource = state.resources[id];
|
|
12988
|
+
if (resource) scoped[id] = resource;
|
|
12989
|
+
}
|
|
12990
|
+
for (const { before, after } of computeImplicitDeleteEdges(scoped)) {
|
|
12991
|
+
if (!dependedBy.has(after)) dependedBy.set(after, /* @__PURE__ */ new Set());
|
|
12992
|
+
if (!dependedBy.get(after).has(before)) {
|
|
12993
|
+
dependedBy.get(after).add(before);
|
|
12994
|
+
this.logger.debug(`Implicit delete dependency: ${before} (${scoped[before]?.resourceType}) must be deleted before ${after} (${scoped[after]?.resourceType})`);
|
|
12995
|
+
}
|
|
12996
|
+
}
|
|
12853
12997
|
}
|
|
12854
12998
|
/**
|
|
12855
12999
|
* Prepare a property map for a Cloud Control API call. When a Tier 1
|
|
@@ -12933,5 +13077,5 @@ var DeployEngine = class {
|
|
|
12933
13077
|
};
|
|
12934
13078
|
|
|
12935
13079
|
//#endregion
|
|
12936
|
-
export {
|
|
12937
|
-
//# sourceMappingURL=deploy-engine-
|
|
13080
|
+
export { AssemblyReader as $, shouldRetainResource as A, getDefaultStateBucketName as B, applyRoleArnIfSet as C, LockManager as D, TemplateParser as E, formatDockerLoginError as F, resolveStateBucketWithDefault as G, resolveApp as H, getDockerCmd as I, CFN_TEMPLATE_BODY_LIMIT as J, resolveStateBucketWithDefaultAndSource as K, runDockerForeground as L, stringifyValue as M, WorkGraph as N, S3StateBackend as O, buildDockerImage as P, uploadCfnTemplate as Q, runDockerStreaming as R, IntrinsicFunctionResolver as S, DagBuilder as T, resolveCaptureObservedState as U, getLegacyStateBucketName as V, resolveSkipPrefix as W, MIGRATE_TMP_PREFIX as X, CFN_TEMPLATE_URL_LIMIT as Y, findLargeInlineResources as Z, IAMRoleProvider as _, withRetry as a, findActionableSilentDrops as b, computeImplicitDeleteEdges as c, bold as d, clearBucketRegionCache as et, cyan as f, yellow as g, red as h, withResourceDeadline as i, AssetPublisher as j, rebuildClientForBucketRegion as k, extractDeploymentEventError as l, green as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, isRetryableTransientError as o, gray as p, warnDeprecatedNoPrefixCliFlag as q, DeployEngine as r, IMPLICIT_DELETE_DEPENDENCIES as s, DEFAULT_RESOURCE_TIMEOUT_MS as t, resolveBucketRegion as tt, formatResourceLine as u, collectInlinePolicyNamesManagedBySiblings as v, DiffCalculator as w, CloudControlProvider as x, ProviderRegistry as y, Synthesizer as z };
|
|
13081
|
+
//# sourceMappingURL=deploy-engine-alFrHerE.js.map
|