@go-to-k/cdkd 0.115.0 → 0.115.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/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-CuHRHcyW.js";
|
|
3
|
-
import { A as
|
|
3
|
+
import { $ as StackTerminationProtectionError, A as getDefaultStateBucketName, B as resolveBucketRegion, C as AssetPublisher, D as getDockerCmd, E as buildDockerImage, F as resolveStateBucketWithDefault, G as LocalInvokeBuildError, H as CdkdError, I as resolveStateBucketWithDefaultAndSource, J as ProvisioningError, L as warnDeprecatedNoPrefixCliFlag, M as resolveApp, N as resolveCaptureObservedState, O as runDockerStreaming, P as resolveSkipPrefix, Q as StackHasActiveImportsError, R as AssemblyReader, S as shouldRetainResource, T as WorkGraph, X as ResourceUpdateNotSupportedError, Y as ResourceTimeoutError, Z as RouteDiscoveryError, _ as DiffCalculator, a as withRetry, at as withErrorHandling, b as LockManager, c as collectInlinePolicyNamesManagedBySiblings, d as normalizeAwsTagsToCfn, dt as PATTERN_B_NAME_PROPERTIES, f as resolveExplicitPhysicalId, ft as PATTERN_B_RESOURCE_TYPES, g as IntrinsicFunctionResolver, gt as withStackName, h as assertRegionMatch, ht as withSkipPrefix, i as withResourceDeadline, it as normalizeAwsError, j as getLegacyStateBucketName, k as Synthesizer, l as CDK_PATH_TAG, lt as runStackBuffered, m as CloudControlProvider, mt as generateResourceNameWithFallback, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as IMPLICIT_DELETE_DEPENDENCIES, p as ProviderRegistry, pt as generateResourceName, q as PartialFailureError, r as DeployEngine, s as IAMRoleProvider, st as getLogger, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as matchesCdkPath, ut as getLiveRenderer, v as DagBuilder, w as stringifyValue, x as S3StateBackend, y as TemplateParser } from "./deploy-engine-AoZgViZN.js";
|
|
4
4
|
import { createHash, createPublicKey, createVerify, randomBytes, randomUUID } from "node:crypto";
|
|
5
5
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
6
6
|
import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachUserPolicyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachUserPolicyCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListInstanceProfilesCommand, ListUserPoliciesCommand, ListUserTagsCommand, ListUsersCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagUserCommand, UntagUserCommand, UpdateLoginProfileCommand } from "@aws-sdk/client-iam";
|
|
@@ -27,7 +27,6 @@ import { tmpdir } from "node:os";
|
|
|
27
27
|
import { AssociateVPCWithHostedZoneCommand, ChangeResourceRecordSetsCommand, ChangeTagsForResourceCommand, CreateHostedZoneCommand, CreateQueryLoggingConfigCommand, DeleteHostedZoneCommand, DeleteQueryLoggingConfigCommand, DisassociateVPCFromHostedZoneCommand, GetHostedZoneCommand, ListHostedZonesByNameCommand, ListHostedZonesCommand, ListQueryLoggingConfigsCommand, ListResourceRecordSetsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$6, Route53Client, UpdateHostedZoneCommentCommand } from "@aws-sdk/client-route-53";
|
|
28
28
|
import { AddTagsCommand, CreateListenerCommand, CreateLoadBalancerCommand, CreateTargetGroupCommand, DeleteListenerCommand, DeleteLoadBalancerCommand, DeleteTargetGroupCommand, DescribeListenersCommand, DescribeLoadBalancerAttributesCommand, DescribeLoadBalancersCommand, DescribeTagsCommand, DescribeTargetGroupsCommand, ElasticLoadBalancingV2Client, ModifyListenerCommand, ModifyLoadBalancerAttributesCommand, ModifyTargetGroupCommand, RemoveTagsCommand, SetIpAddressTypeCommand, SetSecurityGroupsCommand, SetSubnetsCommand } from "@aws-sdk/client-elastic-load-balancing-v2";
|
|
29
29
|
import { CreateAliasCommand, CreateKeyCommand, DeleteAliasCommand, DescribeKeyCommand, DisableKeyCommand, DisableKeyRotationCommand, EnableKeyCommand, EnableKeyRotationCommand, GetKeyPolicyCommand, GetKeyRotationStatusCommand, KMSClient, ListAliasesCommand, ListKeysCommand, ListResourceTagsCommand, NotFoundException as NotFoundException$2, PutKeyPolicyCommand, ScheduleKeyDeletionCommand, TagResourceCommand as TagResourceCommand$8, UntagResourceCommand as UntagResourceCommand$8, UpdateAliasCommand, UpdateKeyDescriptionCommand } from "@aws-sdk/client-kms";
|
|
30
|
-
import { promisify } from "node:util";
|
|
31
30
|
import { CreateRepositoryCommand, DeleteLifecyclePolicyCommand, DeleteRepositoryCommand, DeleteRepositoryPolicyCommand, DescribeRepositoriesCommand, ECRClient, GetAuthorizationTokenCommand, GetLifecyclePolicyCommand, LifecyclePolicyNotFoundException, ListTagsForResourceCommand as ListTagsForResourceCommand$7, PutImageScanningConfigurationCommand, PutImageTagMutabilityCommand, PutLifecyclePolicyCommand, RepositoryNotFoundException, SetRepositoryPolicyCommand, TagResourceCommand as TagResourceCommand$9 } from "@aws-sdk/client-ecr";
|
|
32
31
|
import graphlib from "graphlib";
|
|
33
32
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$1, CreateDBClusterCommand, CreateDBInstanceCommand, CreateDBProxyCommand, CreateDBProxyEndpointCommand, CreateDBSubnetGroupCommand, DBProxyEndpointNotFoundFault, DBProxyNotFoundFault, DBProxyTargetGroupNotFoundFault, DBProxyTargetNotFoundFault, DeleteDBClusterCommand, DeleteDBInstanceCommand, DeleteDBProxyCommand, DeleteDBProxyEndpointCommand, DeleteDBSubnetGroupCommand, DeregisterDBProxyTargetsCommand, DescribeDBClustersCommand, DescribeDBInstancesCommand, DescribeDBProxiesCommand, DescribeDBProxyEndpointsCommand, DescribeDBProxyTargetGroupsCommand, DescribeDBProxyTargetsCommand, DescribeDBSubnetGroupsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$8, ModifyDBClusterCommand, ModifyDBInstanceCommand, ModifyDBProxyCommand, ModifyDBProxyEndpointCommand, ModifyDBProxyTargetGroupCommand, ModifyDBSubnetGroupCommand, RDSClient, RegisterDBProxyTargetsCommand, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$1 } from "@aws-sdk/client-rds";
|
|
@@ -58,6 +57,7 @@ import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as
|
|
|
58
57
|
import { AttachTrafficSourcesCommand, AutoScalingClient, CreateAutoScalingGroupCommand, DeleteAutoScalingGroupCommand, DeleteLifecycleHookCommand, DeleteNotificationConfigurationCommand, DescribeAutoScalingGroupsCommand, DescribeLifecycleHooksCommand, DescribeNotificationConfigurationsCommand, DescribeTrafficSourcesCommand, DetachTrafficSourcesCommand, DisableMetricsCollectionCommand, EnableMetricsCollectionCommand, PutLifecycleHookCommand, PutNotificationConfigurationCommand, UpdateAutoScalingGroupCommand } from "@aws-sdk/client-auto-scaling";
|
|
59
58
|
import * as readline from "node:readline/promises";
|
|
60
59
|
import { createServer } from "node:net";
|
|
60
|
+
import { promisify } from "node:util";
|
|
61
61
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
62
62
|
import { readFile } from "fs/promises";
|
|
63
63
|
import { createServer as createServer$1 } from "node:http";
|
|
@@ -37331,7 +37331,7 @@ function resolveRuntimeCodeMountPath(runtime) {
|
|
|
37331
37331
|
|
|
37332
37332
|
//#endregion
|
|
37333
37333
|
//#region src/local/docker-runner.ts
|
|
37334
|
-
const execFileAsync$
|
|
37334
|
+
const execFileAsync$2 = promisify(execFile);
|
|
37335
37335
|
/**
|
|
37336
37336
|
* Wraps `docker pull` / `docker run` / `docker rm` for `cdkd local invoke`.
|
|
37337
37337
|
*
|
|
@@ -37366,11 +37366,11 @@ async function pullImage(image, skipPull) {
|
|
|
37366
37366
|
}
|
|
37367
37367
|
if (getLogger().getLevel() === "debug") {
|
|
37368
37368
|
logger.info(`Pulling ${image}...`);
|
|
37369
|
-
await runForeground$1(
|
|
37369
|
+
await runForeground$1(getDockerCmd(), ["pull", image]);
|
|
37370
37370
|
return;
|
|
37371
37371
|
}
|
|
37372
37372
|
logger.debug(`Pulling ${image} (silent — pass --verbose to stream progress)`);
|
|
37373
|
-
await runCaptured(
|
|
37373
|
+
await runCaptured(getDockerCmd(), ["pull", image], image);
|
|
37374
37374
|
}
|
|
37375
37375
|
/**
|
|
37376
37376
|
* Run a child process with stdout / stderr captured (not inherited).
|
|
@@ -37441,9 +37441,9 @@ async function runDetached(opts) {
|
|
|
37441
37441
|
entryPointTail = opts.entryPoint.slice(1);
|
|
37442
37442
|
}
|
|
37443
37443
|
args.push(opts.image, ...entryPointTail, ...opts.cmd);
|
|
37444
|
-
getLogger().child("docker").debug(
|
|
37444
|
+
getLogger().child("docker").debug(`${getDockerCmd()} ${redactAwsCredentialsInArgs(args).join(" ")}`);
|
|
37445
37445
|
try {
|
|
37446
|
-
const { stdout } = await execFileAsync$
|
|
37446
|
+
const { stdout } = await execFileAsync$2(getDockerCmd(), args, { maxBuffer: 10 * 1024 * 1024 });
|
|
37447
37447
|
return stdout.trim();
|
|
37448
37448
|
} catch (error) {
|
|
37449
37449
|
const err = error;
|
|
@@ -37455,7 +37455,7 @@ async function runDetached(opts) {
|
|
|
37455
37455
|
* stops the stream (used by the caller in a `finally` block).
|
|
37456
37456
|
*/
|
|
37457
37457
|
function streamLogs(containerId) {
|
|
37458
|
-
const proc = spawn(
|
|
37458
|
+
const proc = spawn(getDockerCmd(), [
|
|
37459
37459
|
"logs",
|
|
37460
37460
|
"-f",
|
|
37461
37461
|
containerId
|
|
@@ -37480,7 +37480,7 @@ async function removeContainer(containerId) {
|
|
|
37480
37480
|
if (!containerId) return;
|
|
37481
37481
|
const logger = getLogger().child("docker");
|
|
37482
37482
|
try {
|
|
37483
|
-
await execFileAsync$
|
|
37483
|
+
await execFileAsync$2(getDockerCmd(), [
|
|
37484
37484
|
"rm",
|
|
37485
37485
|
"-f",
|
|
37486
37486
|
containerId
|
|
@@ -37497,16 +37497,17 @@ async function removeContainer(containerId) {
|
|
|
37497
37497
|
* otherwise see at the first run call. Called once up front.
|
|
37498
37498
|
*/
|
|
37499
37499
|
async function ensureDockerAvailable() {
|
|
37500
|
+
const cmd = getDockerCmd();
|
|
37500
37501
|
try {
|
|
37501
|
-
await execFileAsync$
|
|
37502
|
+
await execFileAsync$2(cmd, [
|
|
37502
37503
|
"version",
|
|
37503
37504
|
"--format",
|
|
37504
37505
|
"{{.Server.Version}}"
|
|
37505
37506
|
]);
|
|
37506
37507
|
} catch (error) {
|
|
37507
37508
|
const err = error;
|
|
37508
|
-
if (err.code === "ENOENT") throw new DockerRunnerError(
|
|
37509
|
-
throw new DockerRunnerError(
|
|
37509
|
+
if (err.code === "ENOENT") throw new DockerRunnerError(`${cmd} is not installed or not on PATH. cdkd local invoke needs Docker (or a compatible CLI specified via CDK_DOCKER) — install it and retry.`);
|
|
37510
|
+
throw new DockerRunnerError(`${cmd} daemon is not reachable: ${err.stderr?.trim() || err.message || String(error)}. Start Docker Desktop / the docker daemon and retry.`);
|
|
37510
37511
|
}
|
|
37511
37512
|
}
|
|
37512
37513
|
/**
|
|
@@ -37593,7 +37594,6 @@ function runForeground$1(cmd, args) {
|
|
|
37593
37594
|
|
|
37594
37595
|
//#endregion
|
|
37595
37596
|
//#region src/local/ecr-puller.ts
|
|
37596
|
-
const execFileAsync$2 = promisify(execFile);
|
|
37597
37597
|
/**
|
|
37598
37598
|
* ECR pull fallback for `cdkd local invoke` against deployed container
|
|
37599
37599
|
* Lambdas (PR 5, D5.2). When `Code.ImageUri` resolves to an ECR URI but
|
|
@@ -37665,7 +37665,7 @@ async function pullEcrImage(imageUri, options) {
|
|
|
37665
37665
|
ecr.destroy();
|
|
37666
37666
|
}
|
|
37667
37667
|
logger.info(`Pulling ${imageUri}...`);
|
|
37668
|
-
await runForeground(
|
|
37668
|
+
await runForeground(getDockerCmd(), ["pull", imageUri]);
|
|
37669
37669
|
return imageUri;
|
|
37670
37670
|
}
|
|
37671
37671
|
/**
|
|
@@ -37679,33 +37679,20 @@ async function ecrLogin(client, accountId, region) {
|
|
|
37679
37679
|
const authData = (await client.send(new GetAuthorizationTokenCommand({}))).authorizationData?.[0];
|
|
37680
37680
|
if (!authData?.authorizationToken) throw new LocalInvokeBuildError("Failed to get ECR authorization token");
|
|
37681
37681
|
const [username, password] = Buffer.from(authData.authorizationToken, "base64").toString().split(":");
|
|
37682
|
+
if (!username || password === void 0) throw new LocalInvokeBuildError("ECR authorization token has unexpected shape (missing username/password)");
|
|
37682
37683
|
const endpoint = authData.proxyEndpoint || `https://${accountId}.dkr.ecr.${region}.amazonaws.com`;
|
|
37683
|
-
|
|
37684
|
-
|
|
37684
|
+
try {
|
|
37685
|
+
await runDockerStreaming([
|
|
37685
37686
|
"login",
|
|
37686
37687
|
"--username",
|
|
37687
37688
|
username,
|
|
37688
37689
|
"--password-stdin",
|
|
37689
37690
|
endpoint
|
|
37690
|
-
], {
|
|
37691
|
-
|
|
37692
|
-
|
|
37693
|
-
|
|
37694
|
-
|
|
37695
|
-
let stderr = "";
|
|
37696
|
-
proc.stderr?.on("data", (data) => {
|
|
37697
|
-
stderr += data.toString();
|
|
37698
|
-
});
|
|
37699
|
-
proc.on("close", (code) => {
|
|
37700
|
-
if (code === 0) resolve();
|
|
37701
|
-
else reject(new LocalInvokeBuildError(`ECR login failed: ${stderr.trim()}`));
|
|
37702
|
-
});
|
|
37703
|
-
proc.on("error", (err) => {
|
|
37704
|
-
reject(new LocalInvokeBuildError(`ECR login failed: ${err.message}`));
|
|
37705
|
-
});
|
|
37706
|
-
proc.stdin?.write(password);
|
|
37707
|
-
proc.stdin?.end();
|
|
37708
|
-
});
|
|
37691
|
+
], { input: password });
|
|
37692
|
+
} catch (err) {
|
|
37693
|
+
const e = err;
|
|
37694
|
+
throw new LocalInvokeBuildError(`ECR login failed: ${e.stderr?.trim() || e.message || String(err)}`);
|
|
37695
|
+
}
|
|
37709
37696
|
}
|
|
37710
37697
|
/**
|
|
37711
37698
|
* `docker image inspect <uri>` returns non-zero when the image is not in
|
|
@@ -37714,7 +37701,7 @@ async function ecrLogin(client, accountId, region) {
|
|
|
37714
37701
|
*/
|
|
37715
37702
|
async function verifyImageInLocalCache(imageUri) {
|
|
37716
37703
|
try {
|
|
37717
|
-
await
|
|
37704
|
+
await runDockerStreaming([
|
|
37718
37705
|
"image",
|
|
37719
37706
|
"inspect",
|
|
37720
37707
|
imageUri
|
|
@@ -37732,7 +37719,7 @@ async function verifyImageInLocalCache(imageUri) {
|
|
|
37732
37719
|
*/
|
|
37733
37720
|
async function isImageInLocalCache(imageRef) {
|
|
37734
37721
|
try {
|
|
37735
|
-
await
|
|
37722
|
+
await runDockerStreaming([
|
|
37736
37723
|
"image",
|
|
37737
37724
|
"inspect",
|
|
37738
37725
|
imageRef
|
|
@@ -37782,10 +37769,24 @@ async function buildContainerImage(asset, cdkOutDir, options) {
|
|
|
37782
37769
|
}
|
|
37783
37770
|
logger.info(`Building container image (platform=${platform})...`);
|
|
37784
37771
|
logger.debug(`Local tag: ${tag}`);
|
|
37785
|
-
await buildDockerImage(asset, cdkOutDir,
|
|
37772
|
+
const actualTag = await buildDockerImage(asset, cdkOutDir, {
|
|
37773
|
+
tag,
|
|
37786
37774
|
platform,
|
|
37787
|
-
wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for container Lambda asset (${asset.source.directory}): ${stderr}`)
|
|
37775
|
+
wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for container Lambda asset (${asset.source.directory ?? asset.source.executable?.join(" ")}): ${stderr}`)
|
|
37788
37776
|
});
|
|
37777
|
+
if (actualTag !== tag) {
|
|
37778
|
+
logger.debug(`Re-tagging executable-built image '${actualTag}' → '${tag}'`);
|
|
37779
|
+
try {
|
|
37780
|
+
await runDockerStreaming([
|
|
37781
|
+
"tag",
|
|
37782
|
+
actualTag,
|
|
37783
|
+
tag
|
|
37784
|
+
]);
|
|
37785
|
+
} catch (err) {
|
|
37786
|
+
const e = err;
|
|
37787
|
+
throw new LocalInvokeBuildError(`docker tag failed re-tagging '${actualTag}' → '${tag}': ${e.stderr?.trim() || e.message || String(err)}`);
|
|
37788
|
+
}
|
|
37789
|
+
}
|
|
37789
37790
|
return tag;
|
|
37790
37791
|
}
|
|
37791
37792
|
/**
|
|
@@ -37800,27 +37801,49 @@ function architectureToPlatform(architecture) {
|
|
|
37800
37801
|
return architecture === "arm64" ? "linux/arm64" : "linux/amd64";
|
|
37801
37802
|
}
|
|
37802
37803
|
/**
|
|
37803
|
-
* Build a stable local tag derived from the asset's build context.
|
|
37804
|
-
*
|
|
37805
|
-
*
|
|
37806
|
-
*
|
|
37807
|
-
* tag stays around in
|
|
37804
|
+
* Build a stable local tag derived from the asset's build context.
|
|
37805
|
+
*
|
|
37806
|
+
* Fingerprints every field that affects the produced image so an iteration
|
|
37807
|
+
* that doesn't change those fields hits Docker's layer cache; an iteration
|
|
37808
|
+
* that DOES change them gets a fresh tag (the old tag stays around in
|
|
37809
|
+
* `docker images` but harmlessly). The fingerprint covers the full CDK
|
|
37810
|
+
* `DockerImageSource` schema so `dockerBuildSecrets` / `dockerBuildContexts`
|
|
37811
|
+
* / `cacheFrom` / etc. changes also bust the local cache as expected.
|
|
37808
37812
|
*/
|
|
37809
37813
|
function computeLocalTag(source) {
|
|
37810
37814
|
const hash = createHash("sha256");
|
|
37811
|
-
hash
|
|
37812
|
-
hash.
|
|
37813
|
-
hash
|
|
37814
|
-
hash.
|
|
37815
|
-
hash
|
|
37815
|
+
pushField(hash, "directory", source.directory ?? "");
|
|
37816
|
+
pushField(hash, "executable", (source.executable ?? []).join(" "));
|
|
37817
|
+
pushField(hash, "dockerFile", source.dockerFile ?? "");
|
|
37818
|
+
pushField(hash, "dockerBuildTarget", source.dockerBuildTarget ?? "");
|
|
37819
|
+
pushField(hash, "networkMode", source.networkMode ?? "");
|
|
37820
|
+
pushField(hash, "platform", source.platform ?? "");
|
|
37821
|
+
pushField(hash, "dockerBuildSsh", source.dockerBuildSsh ?? "");
|
|
37822
|
+
pushField(hash, "cacheDisabled", source.cacheDisabled ? "1" : "0");
|
|
37823
|
+
pushMap(hash, "dockerBuildArgs", source.dockerBuildArgs);
|
|
37824
|
+
pushMap(hash, "dockerBuildContexts", source.dockerBuildContexts);
|
|
37825
|
+
pushMap(hash, "dockerBuildSecrets", source.dockerBuildSecrets);
|
|
37826
|
+
pushField(hash, "dockerOutputs", (source.dockerOutputs ?? []).join(""));
|
|
37827
|
+
pushField(hash, "cacheFrom", (source.cacheFrom ?? []).map((o) => JSON.stringify(o)).join(""));
|
|
37828
|
+
pushField(hash, "cacheTo", source.cacheTo ? JSON.stringify(source.cacheTo) : "");
|
|
37829
|
+
return `cdkd-local-invoke-${hash.digest("hex").slice(0, 16)}`;
|
|
37830
|
+
}
|
|
37831
|
+
function pushField(hash, name, value) {
|
|
37832
|
+
hash.update(name);
|
|
37833
|
+
hash.update("=");
|
|
37834
|
+
hash.update(value);
|
|
37816
37835
|
hash.update("\0");
|
|
37817
|
-
|
|
37836
|
+
}
|
|
37837
|
+
function pushMap(hash, name, value) {
|
|
37838
|
+
hash.update(name);
|
|
37839
|
+
hash.update("={");
|
|
37840
|
+
if (value) for (const [k, v] of Object.entries(value)) {
|
|
37818
37841
|
hash.update(k);
|
|
37819
37842
|
hash.update("=");
|
|
37820
37843
|
hash.update(v);
|
|
37821
|
-
hash.update("
|
|
37844
|
+
hash.update(";");
|
|
37822
37845
|
}
|
|
37823
|
-
|
|
37846
|
+
hash.update("}\0");
|
|
37824
37847
|
}
|
|
37825
37848
|
|
|
37826
37849
|
//#endregion
|
|
@@ -39987,19 +40010,52 @@ function resolveHttpApiAuthorizer(authorizerLogicalId, routeAuthorizationScopes,
|
|
|
39987
40010
|
throw new RouteDiscoveryError(`${stackName}/${authorizerLogicalId}: AWS::ApiGatewayV2::Authorizer.AuthorizerType '${String(authType)}' is not supported by cdkd local start-api (only REQUEST / JWT).`);
|
|
39988
40011
|
}
|
|
39989
40012
|
/**
|
|
40013
|
+
* Thrown by {@link resolveLambdaArn} when the authorizer's
|
|
40014
|
+
* `AuthorizerUri` intrinsic does not resolve to a same-template Lambda
|
|
40015
|
+
* (cross-stack reference, imported Lambda, hand-rolled `Fn::Sub` outside
|
|
40016
|
+
* the invoke-ARN wrapper).
|
|
40017
|
+
*
|
|
40018
|
+
* Caught by {@link attachAuthorizers} and converted into a per-route
|
|
40019
|
+
* `unsupported` flag — symmetric with how `route-discovery.ts` handles
|
|
40020
|
+
* an unresolvable `IntegrationUri`. The route appears in the route
|
|
40021
|
+
* table as `[501 Not Implemented]` and returns HTTP 501 + the
|
|
40022
|
+
* `reason` at request time. The alternative ("attach no authorizer,
|
|
40023
|
+
* leave route normal") would be **unsafe** — it would let a request
|
|
40024
|
+
* hit a user-protected route without any auth check just because the
|
|
40025
|
+
* authorizer Lambda lives in another stack.
|
|
40026
|
+
*
|
|
40027
|
+
* Private to this module: `attachAuthorizers` is the only legitimate
|
|
40028
|
+
* consumer.
|
|
40029
|
+
*/
|
|
40030
|
+
var AuthorizerLambdaUnresolvableError = class AuthorizerLambdaUnresolvableError extends RouteDiscoveryError {
|
|
40031
|
+
reason;
|
|
40032
|
+
constructor(reason) {
|
|
40033
|
+
super(reason);
|
|
40034
|
+
this.reason = reason;
|
|
40035
|
+
this.name = "AuthorizerLambdaUnresolvableError";
|
|
40036
|
+
Object.setPrototypeOf(this, AuthorizerLambdaUnresolvableError.prototype);
|
|
40037
|
+
}
|
|
40038
|
+
};
|
|
40039
|
+
/**
|
|
39990
40040
|
* Resolve a Lambda ARN intrinsic to its logical ID. Delegates to the
|
|
39991
40041
|
* shared `resolveLambdaArnIntrinsic` in `intrinsic-lambda-arn.ts`
|
|
39992
40042
|
* (extracted in issue #286 Gaps 3 / 4); accepts `Ref` /
|
|
39993
40043
|
* `Fn::GetAtt: [..., 'Arn']` / the REST v1 invoke-ARN `Fn::Join` wrapper
|
|
39994
40044
|
* (now also used by CDK 2.x's `HttpLambdaAuthorizer` for HTTP API v2 —
|
|
39995
40045
|
* verified via real `cdk synth` 2026-05-12) / the `Fn::Sub` invoke-ARN
|
|
39996
|
-
* wrapper (both 1-arg and 2-arg forms).
|
|
39997
|
-
*
|
|
40046
|
+
* wrapper (both 1-arg and 2-arg forms).
|
|
40047
|
+
*
|
|
40048
|
+
* On an unresolvable intrinsic throws {@link AuthorizerLambdaUnresolvableError}
|
|
40049
|
+
* (caught by `attachAuthorizers` and converted into a per-route
|
|
40050
|
+
* deferred-501) instead of the generic `RouteDiscoveryError`, so
|
|
40051
|
+
* `cdkd local start-api` can boot against an app with a cross-stack
|
|
40052
|
+
* authorizer Lambda — symmetric with the route-level `IntegrationUri`
|
|
40053
|
+
* unresolvable case (issue #431).
|
|
39998
40054
|
*/
|
|
39999
40055
|
function resolveLambdaArn(value, location) {
|
|
40000
40056
|
const outcome = resolveLambdaArnIntrinsic(value);
|
|
40001
40057
|
if (outcome.kind === "resolved") return outcome.logicalId;
|
|
40002
|
-
throw new
|
|
40058
|
+
throw new AuthorizerLambdaUnresolvableError(`${location}: ${outcome.detail} (got ${shortJson(value)}). Only { Ref }, { Fn::GetAtt: [..., 'Arn'] }, the REST v1 invoke-ARN Fn::Join wrapper, and the Fn::Sub invoke-ARN wrapper are supported.`);
|
|
40003
40059
|
}
|
|
40004
40060
|
/**
|
|
40005
40061
|
* REST v1 IdentitySource for TOKEN authorizers must be exactly one
|
|
@@ -40187,6 +40243,13 @@ function attachAuthorizers(stacks, routes) {
|
|
|
40187
40243
|
...authorizer && { authorizer }
|
|
40188
40244
|
});
|
|
40189
40245
|
} catch (err) {
|
|
40246
|
+
if (err instanceof AuthorizerLambdaUnresolvableError) {
|
|
40247
|
+
out.push({ route: {
|
|
40248
|
+
...route,
|
|
40249
|
+
unsupported: { reason: `${route.declaredAt}: authorizer Lambda Arn unresolvable — ${err.reason}` }
|
|
40250
|
+
} });
|
|
40251
|
+
continue;
|
|
40252
|
+
}
|
|
40190
40253
|
errors.push(err instanceof Error ? err.message : String(err));
|
|
40191
40254
|
}
|
|
40192
40255
|
}
|
|
@@ -42727,7 +42790,7 @@ async function createTaskNetwork(options = {}) {
|
|
|
42727
42790
|
await pullImage(METADATA_ENDPOINT_IMAGE, options.skipPull ?? false);
|
|
42728
42791
|
logger.info(`Creating docker network ${networkName} (subnet ${METADATA_ENDPOINT_SUBNET})...`);
|
|
42729
42792
|
try {
|
|
42730
|
-
await execFileAsync$1(
|
|
42793
|
+
await execFileAsync$1(getDockerCmd(), [
|
|
42731
42794
|
"network",
|
|
42732
42795
|
"create",
|
|
42733
42796
|
"--driver",
|
|
@@ -42763,7 +42826,7 @@ async function createTaskNetwork(options = {}) {
|
|
|
42763
42826
|
logger.info("Starting ECS local-container-endpoints sidecar at 169.254.170.2...");
|
|
42764
42827
|
let sidecarContainerId;
|
|
42765
42828
|
try {
|
|
42766
|
-
const { stdout } = await execFileAsync$1(
|
|
42829
|
+
const { stdout } = await execFileAsync$1(getDockerCmd(), sidecarArgs, { maxBuffer: 10 * 1024 * 1024 });
|
|
42767
42830
|
sidecarContainerId = stdout.trim();
|
|
42768
42831
|
} catch (err) {
|
|
42769
42832
|
await destroyNetworkOnly(networkName);
|
|
@@ -42809,7 +42872,7 @@ async function destroyNetworkOnly(networkName) {
|
|
|
42809
42872
|
if (!networkName) return;
|
|
42810
42873
|
const logger = getLogger().child("ecs-network");
|
|
42811
42874
|
try {
|
|
42812
|
-
await execFileAsync$1(
|
|
42875
|
+
await execFileAsync$1(getDockerCmd(), [
|
|
42813
42876
|
"network",
|
|
42814
42877
|
"rm",
|
|
42815
42878
|
networkName
|
|
@@ -43002,7 +43065,7 @@ async function cleanupEcsRun(state, options) {
|
|
|
43002
43065
|
await destroyTaskNetwork(state.network);
|
|
43003
43066
|
state.network = void 0;
|
|
43004
43067
|
for (const v of state.dockerVolumeNames) try {
|
|
43005
|
-
await execFileAsync(
|
|
43068
|
+
await execFileAsync(getDockerCmd(), [
|
|
43006
43069
|
"volume",
|
|
43007
43070
|
"rm",
|
|
43008
43071
|
v
|
|
@@ -43066,7 +43129,7 @@ async function runEcsTask(task, options, state) {
|
|
|
43066
43129
|
logger.info(`Starting container '${container.name}' (image=${imagePlan.get(container.name)})`);
|
|
43067
43130
|
let id;
|
|
43068
43131
|
try {
|
|
43069
|
-
const { stdout } = await execFileAsync(
|
|
43132
|
+
const { stdout } = await execFileAsync(getDockerCmd(), args, { maxBuffer: 10 * 1024 * 1024 });
|
|
43070
43133
|
id = stdout.trim();
|
|
43071
43134
|
} catch (err) {
|
|
43072
43135
|
const e = err;
|
|
@@ -43175,7 +43238,7 @@ async function waitForContainerHealthy(containerId, displayName) {
|
|
|
43175
43238
|
let lastStatus = "";
|
|
43176
43239
|
while (Date.now() < deadline) {
|
|
43177
43240
|
try {
|
|
43178
|
-
const { stdout } = await execFileAsync(
|
|
43241
|
+
const { stdout } = await execFileAsync(getDockerCmd(), [
|
|
43179
43242
|
"inspect",
|
|
43180
43243
|
"--format",
|
|
43181
43244
|
"{{.State.Health.Status}}",
|
|
@@ -43198,7 +43261,7 @@ async function waitForContainerHealthy(containerId, displayName) {
|
|
|
43198
43261
|
}
|
|
43199
43262
|
async function waitForContainerExit(containerId) {
|
|
43200
43263
|
try {
|
|
43201
|
-
const { stdout } = await execFileAsync(
|
|
43264
|
+
const { stdout } = await execFileAsync(getDockerCmd(), ["wait", containerId], { maxBuffer: 1024 * 1024 });
|
|
43202
43265
|
const code = Number.parseInt(stdout.trim(), 10);
|
|
43203
43266
|
return Number.isFinite(code) ? code : 1;
|
|
43204
43267
|
} catch (err) {
|
|
@@ -43208,7 +43271,7 @@ async function waitForContainerExit(containerId) {
|
|
|
43208
43271
|
}
|
|
43209
43272
|
async function stopContainer(containerId, graceSeconds) {
|
|
43210
43273
|
try {
|
|
43211
|
-
await execFileAsync(
|
|
43274
|
+
await execFileAsync(getDockerCmd(), [
|
|
43212
43275
|
"stop",
|
|
43213
43276
|
"-t",
|
|
43214
43277
|
String(graceSeconds),
|
|
@@ -43224,7 +43287,7 @@ function sleep(ms) {
|
|
|
43224
43287
|
* every line. Returns a stop function for the caller's `finally`.
|
|
43225
43288
|
*/
|
|
43226
43289
|
function streamContainerLogs(containerName, containerId) {
|
|
43227
|
-
const proc = spawn(
|
|
43290
|
+
const proc = spawn(getDockerCmd(), [
|
|
43228
43291
|
"logs",
|
|
43229
43292
|
"-f",
|
|
43230
43293
|
containerId
|
|
@@ -43291,10 +43354,21 @@ async function prepareOneImage(task, container, options) {
|
|
|
43291
43354
|
else if (entries.length === 1) asset = entries[0][1];
|
|
43292
43355
|
if (!asset) throw new EcsTaskRunnerError(`Container '${container.name}' references a CDK asset image but no matching entry was found in cdk.out. Re-synthesize the CDK app and retry.`);
|
|
43293
43356
|
const tag = `cdkd-local-run-task-${(image.assetHash ?? "single").slice(0, 16)}`;
|
|
43294
|
-
await buildDockerImage(asset, cdkOutDir,
|
|
43357
|
+
const actualTag = await buildDockerImage(asset, cdkOutDir, {
|
|
43358
|
+
tag,
|
|
43295
43359
|
...options.platformOverride !== void 0 && { platform: options.platformOverride },
|
|
43296
|
-
wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for ECS container '${container.name}' (${asset.source.directory}): ${stderr}`)
|
|
43360
|
+
wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for ECS container '${container.name}' (${asset.source.directory ?? asset.source.executable?.join(" ")}): ${stderr}`)
|
|
43297
43361
|
});
|
|
43362
|
+
if (actualTag !== tag) try {
|
|
43363
|
+
await runDockerStreaming([
|
|
43364
|
+
"tag",
|
|
43365
|
+
actualTag,
|
|
43366
|
+
tag
|
|
43367
|
+
]);
|
|
43368
|
+
} catch (err) {
|
|
43369
|
+
const e = err;
|
|
43370
|
+
throw new LocalInvokeBuildError(`docker tag failed re-tagging '${actualTag}' → '${tag}' for ECS container '${container.name}': ${e.stderr?.trim() || e.message || String(err)}`);
|
|
43371
|
+
}
|
|
43298
43372
|
return tag;
|
|
43299
43373
|
}
|
|
43300
43374
|
}
|
|
@@ -43321,7 +43395,7 @@ async function realizeDockerVolumes(volumes, state) {
|
|
|
43321
43395
|
const dockerVolumeName = `cdkd-local-${v.name}-${randHex(4)}`;
|
|
43322
43396
|
args.push(dockerVolumeName);
|
|
43323
43397
|
try {
|
|
43324
|
-
await execFileAsync(
|
|
43398
|
+
await execFileAsync(getDockerCmd(), args);
|
|
43325
43399
|
state.dockerVolumeNames.push(dockerVolumeName);
|
|
43326
43400
|
logger.debug(`Created docker volume ${dockerVolumeName} for task volume '${v.name}'`);
|
|
43327
43401
|
} catch (err) {
|
|
@@ -45520,7 +45594,7 @@ function reorderArgs(argv) {
|
|
|
45520
45594
|
*/
|
|
45521
45595
|
async function main() {
|
|
45522
45596
|
const program = new Command();
|
|
45523
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.115.
|
|
45597
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.115.2");
|
|
45524
45598
|
program.addCommand(createBootstrapCommand());
|
|
45525
45599
|
program.addCommand(createSynthCommand());
|
|
45526
45600
|
program.addCommand(createListCommand());
|