@go-to-k/cdkd 0.163.0 → 0.164.1
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 +118 -20
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -37,6 +37,8 @@ import { AddTagsToResourceCommand as AddTagsToResourceCommand$1, CreateDBCluster
|
|
|
37
37
|
import { Command, Option } from "commander";
|
|
38
38
|
import { writeFileSync as writeFileSync$1 } from "fs";
|
|
39
39
|
import { join as join$1 } from "path";
|
|
40
|
+
import * as readline$1 from "node:readline/promises";
|
|
41
|
+
import readline from "node:readline/promises";
|
|
40
42
|
import * as zlib from "node:zlib";
|
|
41
43
|
import { ApplicationAutoScalingClient, DeleteScalingPolicyCommand, DeregisterScalableTargetCommand, DescribeScalableTargetsCommand, DescribeScalingPoliciesCommand, PutScalingPolicyCommand, RegisterScalableTargetCommand } from "@aws-sdk/client-application-auto-scaling";
|
|
42
44
|
import { ApiGatewayV2Client, CreateApiCommand, CreateAuthorizerCommand as CreateAuthorizerCommand$1, CreateIntegrationCommand, CreateRouteCommand as CreateRouteCommand$1, CreateStageCommand as CreateStageCommand$1, DeleteApiCommand, DeleteAuthorizerCommand as DeleteAuthorizerCommand$1, DeleteIntegrationCommand, DeleteRouteCommand as DeleteRouteCommand$1, DeleteStageCommand as DeleteStageCommand$1, GetApiCommand, GetApisCommand, GetAuthorizerCommand as GetAuthorizerCommand$1, GetIntegrationCommand, GetRouteCommand, GetStageCommand as GetStageCommand$1, NotFoundException as NotFoundException$3, UpdateApiCommand, UpdateAuthorizerCommand as UpdateAuthorizerCommand$1, UpdateIntegrationCommand, UpdateRouteCommand, UpdateStageCommand as UpdateStageCommand$1 } from "@aws-sdk/client-apigatewayv2";
|
|
@@ -59,7 +61,6 @@ import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteP
|
|
|
59
61
|
import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$18, ListVectorBucketsCommand, S3VectorsClient } from "@aws-sdk/client-s3vectors";
|
|
60
62
|
import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand as ListTablesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$19, NotFoundException as NotFoundException$5, S3TablesClient } from "@aws-sdk/client-s3tables";
|
|
61
63
|
import { AttachLoadBalancerTargetGroupsCommand, AttachLoadBalancersCommand, AttachTrafficSourcesCommand, AutoScalingClient, CreateAutoScalingGroupCommand, CreateOrUpdateTagsCommand, DeleteAutoScalingGroupCommand, DeleteLifecycleHookCommand, DeleteNotificationConfigurationCommand, DeleteTagsCommand as DeleteTagsCommand$1, DescribeAutoScalingGroupsCommand, DescribeLifecycleHooksCommand, DescribeNotificationConfigurationsCommand, DescribeTrafficSourcesCommand, DetachLoadBalancerTargetGroupsCommand, DetachLoadBalancersCommand, DetachTrafficSourcesCommand, DisableMetricsCollectionCommand, EnableMetricsCollectionCommand, PutLifecycleHookCommand, PutNotificationConfigurationCommand, UpdateAutoScalingGroupCommand } from "@aws-sdk/client-auto-scaling";
|
|
62
|
-
import * as readline from "node:readline/promises";
|
|
63
64
|
import { Document, Pair, Scalar, YAMLMap, YAMLSeq, parse as parse$1, stringify } from "yaml";
|
|
64
65
|
import { mkdir, mkdtemp } from "node:fs/promises";
|
|
65
66
|
import { Readable } from "node:stream";
|
|
@@ -1255,6 +1256,62 @@ async function probeAndRevalidateStateful(input) {
|
|
|
1255
1256
|
};
|
|
1256
1257
|
}
|
|
1257
1258
|
|
|
1259
|
+
//#endregion
|
|
1260
|
+
//#region src/cli/commands/recreate-confirm-prompt.ts
|
|
1261
|
+
/**
|
|
1262
|
+
* Interactive confirmation prompt for `cdkd deploy --recreate-via-cc-api`
|
|
1263
|
+
* (issue [#649]).
|
|
1264
|
+
*
|
|
1265
|
+
* Mirror of {@link ../prefix-migration-check.ts}'s `promptMigrationConfirm`
|
|
1266
|
+
* but for the recreate-via-cc-api destroy+recreate cycle:
|
|
1267
|
+
*
|
|
1268
|
+
* - `opts.yes` (CDK CLI parity `-y` / `--yes`) skips the prompt and
|
|
1269
|
+
* prints the per-target plan as a `WARN` block (the existing v1
|
|
1270
|
+
* surface). CI use case.
|
|
1271
|
+
* - When `opts.yes` is false, the prompt fires after the per-target
|
|
1272
|
+
* plan. Default is `N` because the side effect is destructive
|
|
1273
|
+
* (a per-resource destroy + recreate cycle).
|
|
1274
|
+
* - Non-TTY guard: if `opts.yes` is false AND stdin is not a TTY,
|
|
1275
|
+
* throws with an actionable message rather than hanging or
|
|
1276
|
+
* silently declining. CI runs without `--yes` would otherwise look
|
|
1277
|
+
* like a successful skipped-deploy.
|
|
1278
|
+
*
|
|
1279
|
+
* The per-target plan surfaces a **DATA LOSS** prefix for stateful
|
|
1280
|
+
* targets (those with a non-null `statefulReason` after the live
|
|
1281
|
+
* `s3:ListObjectsV2` probe — see issue [#648]); these reached pre-flight
|
|
1282
|
+
* only because the user opted in with `--force-stateful-recreation`,
|
|
1283
|
+
* so the prompt's **DATA LOSS** wording is the third "stop and think"
|
|
1284
|
+
* moment.
|
|
1285
|
+
*/
|
|
1286
|
+
async function promptRecreateConfirm(input) {
|
|
1287
|
+
if (input.targets.length === 0) return true;
|
|
1288
|
+
const logger = getLogger();
|
|
1289
|
+
logger.warn("");
|
|
1290
|
+
logger.warn(`--recreate-via-cc-api will destroy + recreate ${input.targets.length} resource(s) via Cloud Control API on stack ${input.stackName}:`);
|
|
1291
|
+
for (const t of input.targets) {
|
|
1292
|
+
const stateful = t.statefulReason !== null;
|
|
1293
|
+
const dataLossPrefix = stateful ? "**DATA LOSS** " : "";
|
|
1294
|
+
const stateNote = stateful ? ` — stateful (${t.statefulReason}); --force-stateful-recreation acknowledged` : "";
|
|
1295
|
+
logger.warn(` - ${dataLossPrefix}${t.logicalId} (${t.resourceType})${stateNote}`);
|
|
1296
|
+
if (stateful) logger.warn(` DATA: all data in ${t.logicalId} will be lost (no automatic data migration)`);
|
|
1297
|
+
}
|
|
1298
|
+
logger.warn(" The destroy + recreate cycle is per-resource; sibling resources are unaffected. Downstream consumers of any recreated resource's outputs (Fn::GetStackOutput / Fn::ImportValue) will need a re-deploy to see the new physical id.");
|
|
1299
|
+
if (input.yes) return true;
|
|
1300
|
+
if (process.stdin.isTTY !== true) throw new Error("--recreate-via-cc-api confirm prompt cannot run in a non-interactive environment. Pass --yes / -y to confirm the destroy + recreate cycle, or run the deploy from a real terminal.");
|
|
1301
|
+
const rl = readline.createInterface({
|
|
1302
|
+
input: process.stdin,
|
|
1303
|
+
output: process.stdout
|
|
1304
|
+
});
|
|
1305
|
+
try {
|
|
1306
|
+
const trimmed = (await rl.question("\nContinue? (y/N): ")).trim().toLowerCase();
|
|
1307
|
+
if (trimmed === "y" || trimmed === "yes") return true;
|
|
1308
|
+
logger.info("Deploy cancelled — no resources modified.");
|
|
1309
|
+
return false;
|
|
1310
|
+
} finally {
|
|
1311
|
+
rl.close();
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1258
1315
|
//#endregion
|
|
1259
1316
|
//#region src/state/export-index-store.ts
|
|
1260
1317
|
/**
|
|
@@ -32451,7 +32508,7 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
32451
32508
|
for (const [logicalId, resource] of Object.entries(state.resources)) logger.info(` - ${logicalId} (${resource.resourceType})`);
|
|
32452
32509
|
const protectedCount = ctx.removeProtection ? countProtectedResources(state) : 0;
|
|
32453
32510
|
if (!ctx.skipConfirmation) {
|
|
32454
|
-
const rl = readline.createInterface({
|
|
32511
|
+
const rl = readline$1.createInterface({
|
|
32455
32512
|
input: process.stdin,
|
|
32456
32513
|
output: process.stdout
|
|
32457
32514
|
});
|
|
@@ -33522,7 +33579,7 @@ async function promptMigrationConfirm(renames, opts) {
|
|
|
33522
33579
|
logger.warn("These resources will be REPLACED because the new naming convention drops the stack-name prefix.");
|
|
33523
33580
|
if (opts.yes) return true;
|
|
33524
33581
|
if (process.stdin.isTTY !== true) throw new Error("--no-prefix-user-supplied-names migration confirm prompt cannot run in a non-interactive environment. Pass --yes / -y to confirm the REPLACEMENT, or run the deploy from a real terminal.");
|
|
33525
|
-
const rl = readline.createInterface({
|
|
33582
|
+
const rl = readline$1.createInterface({
|
|
33526
33583
|
input: process.stdin,
|
|
33527
33584
|
output: process.stdout
|
|
33528
33585
|
});
|
|
@@ -33736,12 +33793,11 @@ async function deployCommand(stacks, options) {
|
|
|
33736
33793
|
if (errorBlock) throw new CdkdError(errorBlock, "RECREATE_VIA_CC_API_INVALID");
|
|
33737
33794
|
recreateViaCcApiTargets = new Set(validation.targets.map((t) => t.logicalId));
|
|
33738
33795
|
if (recreateViaCcApiTargets.size > 0) {
|
|
33739
|
-
|
|
33740
|
-
|
|
33741
|
-
|
|
33742
|
-
|
|
33743
|
-
}
|
|
33744
|
-
logger.warn(" The destroy + recreate cycle is per-resource; sibling resources are unaffected. Downstream consumers of any recreated resource's outputs (Fn::GetStackOutput / Fn::ImportValue) will need a re-deploy to see the new physical id.");
|
|
33796
|
+
if (!await promptRecreateConfirm({
|
|
33797
|
+
stackName: stackInfo.stackName,
|
|
33798
|
+
targets: validation.targets,
|
|
33799
|
+
yes: options.yes ?? false
|
|
33800
|
+
})) return;
|
|
33745
33801
|
}
|
|
33746
33802
|
}
|
|
33747
33803
|
const deployEngineOptions = {
|
|
@@ -34634,7 +34690,7 @@ async function walkCfnStackTree(stackName, physicalId, cfnClient) {
|
|
|
34634
34690
|
};
|
|
34635
34691
|
}
|
|
34636
34692
|
async function confirmPrompt$5(prompt) {
|
|
34637
|
-
const rl = readline.createInterface({
|
|
34693
|
+
const rl = readline$1.createInterface({
|
|
34638
34694
|
input: process.stdin,
|
|
34639
34695
|
output: process.stdout
|
|
34640
34696
|
});
|
|
@@ -35914,7 +35970,7 @@ async function runWithConcurrency(tasks, concurrency) {
|
|
|
35914
35970
|
await Promise.all(workers);
|
|
35915
35971
|
}
|
|
35916
35972
|
async function confirmPrompt$4(prompt) {
|
|
35917
|
-
const rl = readline.createInterface({
|
|
35973
|
+
const rl = readline$1.createInterface({
|
|
35918
35974
|
input: process.stdin,
|
|
35919
35975
|
output: process.stdout
|
|
35920
35976
|
});
|
|
@@ -36883,7 +36939,7 @@ function stringifyForAudit(value) {
|
|
|
36883
36939
|
return JSON.stringify(value);
|
|
36884
36940
|
}
|
|
36885
36941
|
async function confirmPrompt$3(prompt) {
|
|
36886
|
-
const rl = readline.createInterface({
|
|
36942
|
+
const rl = readline$1.createInterface({
|
|
36887
36943
|
input: process.stdin,
|
|
36888
36944
|
output: process.stdout
|
|
36889
36945
|
});
|
|
@@ -37372,7 +37428,7 @@ async function emptyBucketAllVersions(s3, bucket) {
|
|
|
37372
37428
|
} while (keyMarker || versionIdMarker);
|
|
37373
37429
|
}
|
|
37374
37430
|
async function confirmPrompt$2(prompt) {
|
|
37375
|
-
const rl = readline.createInterface({
|
|
37431
|
+
const rl = readline$1.createInterface({
|
|
37376
37432
|
input: process.stdin,
|
|
37377
37433
|
output: process.stdout
|
|
37378
37434
|
});
|
|
@@ -39789,7 +39845,7 @@ function printNextSteps(args) {
|
|
|
39789
39845
|
logger.info("");
|
|
39790
39846
|
}
|
|
39791
39847
|
async function confirmPrompt$1(prompt) {
|
|
39792
|
-
const rl = readline.createInterface({
|
|
39848
|
+
const rl = readline$1.createInterface({
|
|
39793
39849
|
input: process.stdin,
|
|
39794
39850
|
output: process.stdout
|
|
39795
39851
|
});
|
|
@@ -40368,7 +40424,7 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
40368
40424
|
if (!options.yes && !options.force) {
|
|
40369
40425
|
const targetList = targets.map((t) => formatStackRef(t)).join(", ");
|
|
40370
40426
|
process.stdout.write(`\nWARNING: This removes cdkd's state record for [${targetList}] only. AWS resources will NOT be deleted.\nUse 'cdkd destroy ${stackName}' if you want to delete the actual resources.\n\n`);
|
|
40371
|
-
const rl = readline.createInterface({
|
|
40427
|
+
const rl = readline$1.createInterface({
|
|
40372
40428
|
input: process.stdin,
|
|
40373
40429
|
output: process.stdout
|
|
40374
40430
|
});
|
|
@@ -40465,7 +40521,7 @@ async function stateDestroyCommand(stackArgs, options) {
|
|
|
40465
40521
|
process.stdout.write(`\nWARNING: This destroys ${stackNames.length} stack(s) and removes their state records:\n`);
|
|
40466
40522
|
for (const name of stackNames) process.stdout.write(` - ${name}\n`);
|
|
40467
40523
|
process.stdout.write("\n");
|
|
40468
|
-
const rl = readline.createInterface({
|
|
40524
|
+
const rl = readline$1.createInterface({
|
|
40469
40525
|
input: process.stdin,
|
|
40470
40526
|
output: process.stdout
|
|
40471
40527
|
});
|
|
@@ -40928,7 +40984,7 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
|
|
|
40928
40984
|
}
|
|
40929
40985
|
}
|
|
40930
40986
|
async function confirmRefresh(prompt) {
|
|
40931
|
-
const rl = readline.createInterface({
|
|
40987
|
+
const rl = readline$1.createInterface({
|
|
40932
40988
|
input: process.stdin,
|
|
40933
40989
|
output: process.stdout
|
|
40934
40990
|
});
|
|
@@ -41544,7 +41600,7 @@ function formatOutcome(outcome) {
|
|
|
41544
41600
|
}
|
|
41545
41601
|
}
|
|
41546
41602
|
async function confirmPrompt(prompt) {
|
|
41547
|
-
const rl = readline.createInterface({
|
|
41603
|
+
const rl = readline$1.createInterface({
|
|
41548
41604
|
input: process.stdin,
|
|
41549
41605
|
output: process.stdout
|
|
41550
41606
|
});
|
|
@@ -58696,6 +58752,7 @@ async function localInvokeCommand(target, options) {
|
|
|
58696
58752
|
region: options.region
|
|
58697
58753
|
});
|
|
58698
58754
|
await ensureDockerAvailable();
|
|
58755
|
+
const profileCredentials = options.profile ? await resolveProfileCredentials(options.profile) : void 0;
|
|
58699
58756
|
const appCmd = resolveApp(options.app);
|
|
58700
58757
|
if (!appCmd) throw new Error("No CDK app specified. Pass --app, set CDKD_APP, or add \"app\" to cdk.json.");
|
|
58701
58758
|
logger.info("Synthesizing CDK app...");
|
|
@@ -58793,7 +58850,10 @@ async function localInvokeCommand(target, options) {
|
|
|
58793
58850
|
logger.warn(`--assume-role: STS AssumeRole(${resolvedAssumeRoleArn}) failed: ${reason}. Falling back to the developer's shell credentials.`);
|
|
58794
58851
|
}
|
|
58795
58852
|
}
|
|
58796
|
-
if (!assumeSucceeded)
|
|
58853
|
+
if (!assumeSucceeded) {
|
|
58854
|
+
forwardAwsEnv(dockerEnv);
|
|
58855
|
+
applyProfileCredentialsOverlay(dockerEnv, profileCredentials, false);
|
|
58856
|
+
}
|
|
58797
58857
|
let debugPort;
|
|
58798
58858
|
if (options.debugPort) {
|
|
58799
58859
|
debugPort = Number(options.debugPort);
|
|
@@ -59230,6 +59290,44 @@ function forwardAwsEnv(env) {
|
|
|
59230
59290
|
}
|
|
59231
59291
|
}
|
|
59232
59292
|
/**
|
|
59293
|
+
* Issue #657: overlay `--profile <p>`-resolved credentials onto the
|
|
59294
|
+
* Lambda container's env block AFTER `forwardAwsEnv` has copied
|
|
59295
|
+
* `process.env.AWS_*`. The overlay covers SSO / IAM Identity Center /
|
|
59296
|
+
* fromIni / role-assumption profiles uniformly (resolved via the SDK's
|
|
59297
|
+
* default credential chain in `resolveProfileCredentials`). Without
|
|
59298
|
+
* this overlay, a dev who runs `cdkd local invoke --profile dev`
|
|
59299
|
+
* AND has no `AWS_ACCESS_KEY_ID` env var (the common SSO / Identity
|
|
59300
|
+
* Center case) sees the Lambda boot with no creds → handler's AWS SDK
|
|
59301
|
+
* call fails with `Could not load credentials from any providers`.
|
|
59302
|
+
*
|
|
59303
|
+
* Precedence (codifies existing semantics + this new layer):
|
|
59304
|
+
* 1. `--assume-role <arn>` (per-Lambda STS creds) — unchanged
|
|
59305
|
+
* 2. NEW: `--profile <p>` resolved + cached (this helper)
|
|
59306
|
+
* 3. `process.env.AWS_*` forwarded — when `--profile` not set
|
|
59307
|
+
*
|
|
59308
|
+
* Region from `forwardAwsEnv` is preserved — only the credential
|
|
59309
|
+
* triple is overlaid.
|
|
59310
|
+
*
|
|
59311
|
+
* When the resolved profile is long-lived (no `sessionToken`), any
|
|
59312
|
+
* inherited `AWS_SESSION_TOKEN` is stripped — a mismatched (long-
|
|
59313
|
+
* lived AKID + foreign session) would otherwise cause an SDK error
|
|
59314
|
+
* inside the container.
|
|
59315
|
+
*
|
|
59316
|
+
* No-op when `profileCreds` is `undefined` (profile not set) or when
|
|
59317
|
+
* `assumeRoleActive` is true (assume-role already won; its STS-issued
|
|
59318
|
+
* creds must not be clobbered by the profile overlay).
|
|
59319
|
+
*
|
|
59320
|
+
* Exported for unit-test isolation (see `local-invoke-profile-creds.test.ts`).
|
|
59321
|
+
*/
|
|
59322
|
+
function applyProfileCredentialsOverlay(env, profileCreds, assumeRoleActive) {
|
|
59323
|
+
if (!profileCreds) return;
|
|
59324
|
+
if (assumeRoleActive) return;
|
|
59325
|
+
env["AWS_ACCESS_KEY_ID"] = profileCreds.accessKeyId;
|
|
59326
|
+
env["AWS_SECRET_ACCESS_KEY"] = profileCreds.secretAccessKey;
|
|
59327
|
+
if (profileCreds.sessionToken) env["AWS_SESSION_TOKEN"] = profileCreds.sessionToken;
|
|
59328
|
+
else delete env["AWS_SESSION_TOKEN"];
|
|
59329
|
+
}
|
|
59330
|
+
/**
|
|
59233
59331
|
* Materialize an inline Lambda body (`Code.ZipFile`) to a tmpdir and
|
|
59234
59332
|
* return the directory the container should mount at /var/task. The
|
|
59235
59333
|
* filename is derived from the function's Handler property and the
|
|
@@ -60449,7 +60547,7 @@ function reorderArgs(argv) {
|
|
|
60449
60547
|
*/
|
|
60450
60548
|
async function main() {
|
|
60451
60549
|
const program = new Command();
|
|
60452
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
60550
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.164.1");
|
|
60453
60551
|
program.addCommand(createBootstrapCommand());
|
|
60454
60552
|
program.addCommand(createSynthCommand());
|
|
60455
60553
|
program.addCommand(createListCommand());
|