@go-to-k/cdkd 0.5.1 → 0.7.0
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/README.md +19 -0
- package/dist/cli.js +357 -7
- package/dist/cli.js.map +4 -4
- package/dist/go-to-k-cdkd-0.7.0.tgz +0 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.5.1.tgz +0 -0
package/README.md
CHANGED
|
@@ -428,6 +428,25 @@ cdkd destroy --all --force
|
|
|
428
428
|
|
|
429
429
|
# Force-unlock a stale lock from interrupted deploy
|
|
430
430
|
cdkd force-unlock MyStack
|
|
431
|
+
|
|
432
|
+
# List stacks registered in the cdkd state bucket
|
|
433
|
+
cdkd state list
|
|
434
|
+
cdkd state ls --long # include resource count, last-modified, lock status
|
|
435
|
+
cdkd state list --json # JSON output (alone, or combined with --long)
|
|
436
|
+
|
|
437
|
+
# List resources of a single stack from state
|
|
438
|
+
cdkd state resources MyStack # aligned columns: LogicalID, Type, PhysicalID
|
|
439
|
+
cdkd state resources MyStack --long # per-resource block with dependencies and attributes
|
|
440
|
+
cdkd state resources MyStack --json # full JSON array
|
|
441
|
+
|
|
442
|
+
# Show full state record for a stack (metadata, outputs, all resources incl. properties)
|
|
443
|
+
cdkd state show MyStack
|
|
444
|
+
cdkd state show MyStack --json # raw {state, lock} JSON
|
|
445
|
+
|
|
446
|
+
# Remove cdkd's state record for a stack (does NOT delete AWS resources)
|
|
447
|
+
cdkd state rm MyStack # confirmation prompt (y/N)
|
|
448
|
+
cdkd state rm MyStack --yes # skip confirmation
|
|
449
|
+
cdkd state rm StackA StackB --force # also bypass the locked-stack refusal
|
|
431
450
|
```
|
|
432
451
|
|
|
433
452
|
### Concurrency Options
|
package/dist/cli.js
CHANGED
|
@@ -447,7 +447,7 @@ var init_aws_clients = __esm({
|
|
|
447
447
|
});
|
|
448
448
|
|
|
449
449
|
// src/cli/index.ts
|
|
450
|
-
import { Command as
|
|
450
|
+
import { Command as Command10 } from "commander";
|
|
451
451
|
|
|
452
452
|
// src/cli/commands/bootstrap.ts
|
|
453
453
|
import { Command } from "commander";
|
|
@@ -2401,7 +2401,9 @@ function toYaml(obj, indent = 0) {
|
|
|
2401
2401
|
let result = "\n";
|
|
2402
2402
|
for (const [key, value] of entries) {
|
|
2403
2403
|
const safeKey = key.includes(" ") ? `"${key}"` : key;
|
|
2404
|
-
|
|
2404
|
+
const isContainer = typeof value === "object" && value !== null;
|
|
2405
|
+
const isEmptyContainer = isContainer && (Array.isArray(value) ? value.length === 0 : Object.keys(value).length === 0);
|
|
2406
|
+
if (isContainer && !isEmptyContainer) {
|
|
2405
2407
|
result += `${prefix}${safeKey}:${toYaml(value, indent + 1)}`;
|
|
2406
2408
|
} else {
|
|
2407
2409
|
result += `${prefix}${safeKey}: ${toYaml(value, indent + 1).trimStart()}`;
|
|
@@ -2584,17 +2586,20 @@ async function listCommand(patterns, options) {
|
|
|
2584
2586
|
}
|
|
2585
2587
|
if (options.showDependencies) {
|
|
2586
2588
|
const records = sorted.map((s) => ({
|
|
2587
|
-
id: s
|
|
2589
|
+
id: formatDisplayId(s),
|
|
2588
2590
|
dependencies: [...s.dependencyNames]
|
|
2589
2591
|
}));
|
|
2590
2592
|
emitStructured(records, options.json);
|
|
2591
2593
|
return;
|
|
2592
2594
|
}
|
|
2593
2595
|
for (const stack of sorted) {
|
|
2594
|
-
process.stdout.write(`${stack
|
|
2596
|
+
process.stdout.write(`${formatDisplayId(stack)}
|
|
2595
2597
|
`);
|
|
2596
2598
|
}
|
|
2597
2599
|
}
|
|
2600
|
+
function formatDisplayId(stack) {
|
|
2601
|
+
return stack.displayName === stack.stackName ? stack.displayName : `${stack.displayName} (${stack.stackName})`;
|
|
2602
|
+
}
|
|
2598
2603
|
function emitStructured(payload, asJson) {
|
|
2599
2604
|
if (asJson) {
|
|
2600
2605
|
process.stdout.write(`${JSON.stringify(payload, null, 2)}
|
|
@@ -3563,6 +3568,18 @@ var LockManager = class {
|
|
|
3563
3568
|
);
|
|
3564
3569
|
}
|
|
3565
3570
|
}
|
|
3571
|
+
/**
|
|
3572
|
+
* Check whether a lock currently exists for a stack
|
|
3573
|
+
*
|
|
3574
|
+
* Returns true if a lock file is present in S3 (regardless of expiry).
|
|
3575
|
+
* This is intended for read-only inspection (e.g. `cdkd state list --long`),
|
|
3576
|
+
* not for acquisition decisions — use `acquireLock` for that, which has its
|
|
3577
|
+
* own expired-lock cleanup logic.
|
|
3578
|
+
*/
|
|
3579
|
+
async isLocked(stackName) {
|
|
3580
|
+
const lockInfo = await this.getLockInfo(stackName);
|
|
3581
|
+
return lockInfo !== null;
|
|
3582
|
+
}
|
|
3566
3583
|
/**
|
|
3567
3584
|
* Release a lock for a stack
|
|
3568
3585
|
*/
|
|
@@ -28089,6 +28106,337 @@ function createForceUnlockCommand() {
|
|
|
28089
28106
|
return cmd;
|
|
28090
28107
|
}
|
|
28091
28108
|
|
|
28109
|
+
// src/cli/commands/state.ts
|
|
28110
|
+
import * as readline2 from "node:readline/promises";
|
|
28111
|
+
import { Command as Command9 } from "commander";
|
|
28112
|
+
init_aws_clients();
|
|
28113
|
+
async function setupStateBackend(options) {
|
|
28114
|
+
const awsClients = new AwsClients({
|
|
28115
|
+
...options.region && { region: options.region },
|
|
28116
|
+
...options.profile && { profile: options.profile }
|
|
28117
|
+
});
|
|
28118
|
+
setAwsClients(awsClients);
|
|
28119
|
+
const region = options.region || process.env["AWS_REGION"] || "us-east-1";
|
|
28120
|
+
const bucket = await resolveStateBucketWithDefault(options.stateBucket, region);
|
|
28121
|
+
const prefix = options.statePrefix;
|
|
28122
|
+
const stateConfig = { bucket, prefix };
|
|
28123
|
+
const stateBackend = new S3StateBackend(awsClients.s3, stateConfig);
|
|
28124
|
+
const lockManager = new LockManager(awsClients.s3, stateConfig);
|
|
28125
|
+
await stateBackend.verifyBucketExists();
|
|
28126
|
+
return {
|
|
28127
|
+
stateBackend,
|
|
28128
|
+
lockManager,
|
|
28129
|
+
bucket,
|
|
28130
|
+
prefix,
|
|
28131
|
+
dispose: () => awsClients.destroy()
|
|
28132
|
+
};
|
|
28133
|
+
}
|
|
28134
|
+
async function stateListCommand(options) {
|
|
28135
|
+
const logger = getLogger();
|
|
28136
|
+
if (options.verbose)
|
|
28137
|
+
logger.setLevel("debug");
|
|
28138
|
+
const setup = await setupStateBackend(options);
|
|
28139
|
+
try {
|
|
28140
|
+
const stackNames = (await setup.stateBackend.listStacks()).slice().sort();
|
|
28141
|
+
if (!options.long && !options.json) {
|
|
28142
|
+
for (const name of stackNames) {
|
|
28143
|
+
process.stdout.write(`${name}
|
|
28144
|
+
`);
|
|
28145
|
+
}
|
|
28146
|
+
return;
|
|
28147
|
+
}
|
|
28148
|
+
if (options.json && !options.long) {
|
|
28149
|
+
process.stdout.write(`${JSON.stringify(stackNames, null, 2)}
|
|
28150
|
+
`);
|
|
28151
|
+
return;
|
|
28152
|
+
}
|
|
28153
|
+
const details = await Promise.all(
|
|
28154
|
+
stackNames.map(async (stackName) => {
|
|
28155
|
+
const [stateResult, locked] = await Promise.all([
|
|
28156
|
+
setup.stateBackend.getState(stackName),
|
|
28157
|
+
setup.lockManager.isLocked(stackName)
|
|
28158
|
+
]);
|
|
28159
|
+
const state = stateResult?.state;
|
|
28160
|
+
return {
|
|
28161
|
+
stackName,
|
|
28162
|
+
resourceCount: state ? Object.keys(state.resources).length : 0,
|
|
28163
|
+
lastModified: state && typeof state.lastModified === "number" ? new Date(state.lastModified).toISOString() : null,
|
|
28164
|
+
locked
|
|
28165
|
+
};
|
|
28166
|
+
})
|
|
28167
|
+
);
|
|
28168
|
+
if (options.json) {
|
|
28169
|
+
process.stdout.write(`${JSON.stringify(details, null, 2)}
|
|
28170
|
+
`);
|
|
28171
|
+
return;
|
|
28172
|
+
}
|
|
28173
|
+
const lines = [];
|
|
28174
|
+
for (const detail of details) {
|
|
28175
|
+
lines.push(detail.stackName);
|
|
28176
|
+
lines.push(` Resources: ${detail.resourceCount}`);
|
|
28177
|
+
lines.push(` Last Modified: ${detail.lastModified ?? "unknown"}`);
|
|
28178
|
+
lines.push(` Lock: ${detail.locked ? "locked" : "unlocked"}`);
|
|
28179
|
+
lines.push("");
|
|
28180
|
+
}
|
|
28181
|
+
if (lines.length > 0) {
|
|
28182
|
+
if (lines[lines.length - 1] === "") {
|
|
28183
|
+
lines.pop();
|
|
28184
|
+
}
|
|
28185
|
+
process.stdout.write(`${lines.join("\n")}
|
|
28186
|
+
`);
|
|
28187
|
+
}
|
|
28188
|
+
} finally {
|
|
28189
|
+
setup.dispose();
|
|
28190
|
+
}
|
|
28191
|
+
}
|
|
28192
|
+
function createStateListCommand() {
|
|
28193
|
+
const cmd = new Command9("list").alias("ls").description("List stacks registered in the cdkd state bucket").option("-l, --long", "Show resource count, last-modified time, and lock status", false).option("--json", "Output as JSON", false).action(withErrorHandling(stateListCommand));
|
|
28194
|
+
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
28195
|
+
return cmd;
|
|
28196
|
+
}
|
|
28197
|
+
async function stateResourcesCommand(stackName, options) {
|
|
28198
|
+
const logger = getLogger();
|
|
28199
|
+
if (options.verbose)
|
|
28200
|
+
logger.setLevel("debug");
|
|
28201
|
+
const setup = await setupStateBackend(options);
|
|
28202
|
+
try {
|
|
28203
|
+
const stateResult = await setup.stateBackend.getState(stackName);
|
|
28204
|
+
if (!stateResult) {
|
|
28205
|
+
throw new Error(
|
|
28206
|
+
`No state found for stack '${stackName}' in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`
|
|
28207
|
+
);
|
|
28208
|
+
}
|
|
28209
|
+
const resources = stateResult.state.resources ?? {};
|
|
28210
|
+
const details = Object.entries(resources).map(([logicalId, resource]) => ({
|
|
28211
|
+
logicalId,
|
|
28212
|
+
resourceType: resource.resourceType,
|
|
28213
|
+
physicalId: resource.physicalId,
|
|
28214
|
+
dependencies: resource.dependencies ?? [],
|
|
28215
|
+
attributes: resource.attributes ?? {}
|
|
28216
|
+
})).sort((a, b) => a.logicalId.localeCompare(b.logicalId));
|
|
28217
|
+
if (options.json) {
|
|
28218
|
+
process.stdout.write(`${JSON.stringify(details, null, 2)}
|
|
28219
|
+
`);
|
|
28220
|
+
return;
|
|
28221
|
+
}
|
|
28222
|
+
if (details.length === 0) {
|
|
28223
|
+
return;
|
|
28224
|
+
}
|
|
28225
|
+
if (options.long) {
|
|
28226
|
+
const lines = [];
|
|
28227
|
+
for (const detail of details) {
|
|
28228
|
+
lines.push(detail.logicalId);
|
|
28229
|
+
lines.push(` Type: ${detail.resourceType}`);
|
|
28230
|
+
lines.push(` PhysicalID: ${detail.physicalId}`);
|
|
28231
|
+
lines.push(
|
|
28232
|
+
` Dependencies: ${detail.dependencies.length > 0 ? detail.dependencies.join(", ") : "(none)"}`
|
|
28233
|
+
);
|
|
28234
|
+
const attrEntries = Object.entries(detail.attributes);
|
|
28235
|
+
if (attrEntries.length === 0) {
|
|
28236
|
+
lines.push(" Attributes: (none)");
|
|
28237
|
+
} else {
|
|
28238
|
+
lines.push(" Attributes:");
|
|
28239
|
+
for (const [k, v] of attrEntries) {
|
|
28240
|
+
lines.push(` ${k}: ${formatAttributeValue(v)}`);
|
|
28241
|
+
}
|
|
28242
|
+
}
|
|
28243
|
+
lines.push("");
|
|
28244
|
+
}
|
|
28245
|
+
if (lines[lines.length - 1] === "") {
|
|
28246
|
+
lines.pop();
|
|
28247
|
+
}
|
|
28248
|
+
process.stdout.write(`${lines.join("\n")}
|
|
28249
|
+
`);
|
|
28250
|
+
return;
|
|
28251
|
+
}
|
|
28252
|
+
const idWidth = Math.max(...details.map((d) => d.logicalId.length));
|
|
28253
|
+
const typeWidth = Math.max(...details.map((d) => d.resourceType.length));
|
|
28254
|
+
for (const detail of details) {
|
|
28255
|
+
process.stdout.write(
|
|
28256
|
+
`${detail.logicalId.padEnd(idWidth)} ${detail.resourceType.padEnd(typeWidth)} ${detail.physicalId}
|
|
28257
|
+
`
|
|
28258
|
+
);
|
|
28259
|
+
}
|
|
28260
|
+
} finally {
|
|
28261
|
+
setup.dispose();
|
|
28262
|
+
}
|
|
28263
|
+
}
|
|
28264
|
+
function formatAttributeValue(value) {
|
|
28265
|
+
if (value === null)
|
|
28266
|
+
return "null";
|
|
28267
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
28268
|
+
return String(value);
|
|
28269
|
+
}
|
|
28270
|
+
return JSON.stringify(value);
|
|
28271
|
+
}
|
|
28272
|
+
function formatDuration(ms) {
|
|
28273
|
+
const seconds = Math.floor(ms / 1e3);
|
|
28274
|
+
if (seconds < 60)
|
|
28275
|
+
return `${seconds}s`;
|
|
28276
|
+
const minutes = Math.floor(seconds / 60);
|
|
28277
|
+
const remainingSeconds = seconds % 60;
|
|
28278
|
+
return `${minutes}m${remainingSeconds}s`;
|
|
28279
|
+
}
|
|
28280
|
+
function formatLockSummary(lockInfo) {
|
|
28281
|
+
if (!lockInfo)
|
|
28282
|
+
return "unlocked";
|
|
28283
|
+
const opStr = lockInfo.operation ? ` (operation: ${lockInfo.operation})` : "";
|
|
28284
|
+
const expiresInMs = lockInfo.expiresAt - Date.now();
|
|
28285
|
+
const expiresStr = expiresInMs > 0 ? `expires in ${formatDuration(expiresInMs)}` : `expired ${formatDuration(-expiresInMs)} ago`;
|
|
28286
|
+
return `locked by ${lockInfo.owner}${opStr}, ${expiresStr}`;
|
|
28287
|
+
}
|
|
28288
|
+
function createStateResourcesCommand() {
|
|
28289
|
+
const cmd = new Command9("resources").description("List resources recorded in a stack's state").argument("<stack>", "Stack name (physical CloudFormation name)").option("-l, --long", "Include dependencies and attributes per resource", false).option("--json", "Output as JSON", false).action(withErrorHandling(stateResourcesCommand));
|
|
28290
|
+
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
28291
|
+
return cmd;
|
|
28292
|
+
}
|
|
28293
|
+
async function stateShowCommand(stackName, options) {
|
|
28294
|
+
const logger = getLogger();
|
|
28295
|
+
if (options.verbose)
|
|
28296
|
+
logger.setLevel("debug");
|
|
28297
|
+
const setup = await setupStateBackend(options);
|
|
28298
|
+
try {
|
|
28299
|
+
const [stateResult, lockInfo] = await Promise.all([
|
|
28300
|
+
setup.stateBackend.getState(stackName),
|
|
28301
|
+
setup.lockManager.getLockInfo(stackName)
|
|
28302
|
+
]);
|
|
28303
|
+
if (!stateResult) {
|
|
28304
|
+
throw new Error(
|
|
28305
|
+
`No state found for stack '${stackName}' in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`
|
|
28306
|
+
);
|
|
28307
|
+
}
|
|
28308
|
+
if (options.json) {
|
|
28309
|
+
process.stdout.write(
|
|
28310
|
+
`${JSON.stringify({ state: stateResult.state, lock: lockInfo }, null, 2)}
|
|
28311
|
+
`
|
|
28312
|
+
);
|
|
28313
|
+
return;
|
|
28314
|
+
}
|
|
28315
|
+
const state = stateResult.state;
|
|
28316
|
+
const lines = [];
|
|
28317
|
+
lines.push(`Stack: ${state.stackName}`);
|
|
28318
|
+
if (state.region)
|
|
28319
|
+
lines.push(` Region: ${state.region}`);
|
|
28320
|
+
lines.push(` Version: ${state.version}`);
|
|
28321
|
+
lines.push(` Last Modified: ${new Date(state.lastModified).toISOString()}`);
|
|
28322
|
+
lines.push(` Lock: ${formatLockSummary(lockInfo)}`);
|
|
28323
|
+
const outputEntries = Object.entries(state.outputs ?? {});
|
|
28324
|
+
if (outputEntries.length > 0) {
|
|
28325
|
+
lines.push("");
|
|
28326
|
+
lines.push("Outputs:");
|
|
28327
|
+
for (const [k, v] of outputEntries) {
|
|
28328
|
+
lines.push(` ${k}: ${formatAttributeValue(v)}`);
|
|
28329
|
+
}
|
|
28330
|
+
}
|
|
28331
|
+
const resourceEntries = Object.entries(state.resources ?? {}).sort(
|
|
28332
|
+
([a], [b]) => a.localeCompare(b)
|
|
28333
|
+
);
|
|
28334
|
+
lines.push("");
|
|
28335
|
+
lines.push(`Resources (${resourceEntries.length}):`);
|
|
28336
|
+
for (const [logicalId, resource] of resourceEntries) {
|
|
28337
|
+
lines.push("");
|
|
28338
|
+
lines.push(logicalId);
|
|
28339
|
+
lines.push(` Type: ${resource.resourceType}`);
|
|
28340
|
+
lines.push(` PhysicalID: ${resource.physicalId}`);
|
|
28341
|
+
const deps = resource.dependencies ?? [];
|
|
28342
|
+
lines.push(` Dependencies: ${deps.length > 0 ? deps.join(", ") : "(none)"}`);
|
|
28343
|
+
const attrEntries = Object.entries(resource.attributes ?? {});
|
|
28344
|
+
if (attrEntries.length === 0) {
|
|
28345
|
+
lines.push(" Attributes: (none)");
|
|
28346
|
+
} else {
|
|
28347
|
+
lines.push(" Attributes:");
|
|
28348
|
+
for (const [k, v] of attrEntries) {
|
|
28349
|
+
lines.push(` ${k}: ${formatAttributeValue(v)}`);
|
|
28350
|
+
}
|
|
28351
|
+
}
|
|
28352
|
+
const propEntries = Object.entries(resource.properties ?? {});
|
|
28353
|
+
if (propEntries.length === 0) {
|
|
28354
|
+
lines.push(" Properties: (none)");
|
|
28355
|
+
} else {
|
|
28356
|
+
lines.push(" Properties:");
|
|
28357
|
+
for (const [k, v] of propEntries) {
|
|
28358
|
+
lines.push(` ${k}: ${formatAttributeValue(v)}`);
|
|
28359
|
+
}
|
|
28360
|
+
}
|
|
28361
|
+
}
|
|
28362
|
+
process.stdout.write(`${lines.join("\n")}
|
|
28363
|
+
`);
|
|
28364
|
+
} finally {
|
|
28365
|
+
setup.dispose();
|
|
28366
|
+
}
|
|
28367
|
+
}
|
|
28368
|
+
function createStateShowCommand() {
|
|
28369
|
+
const cmd = new Command9("show").description("Show the full cdkd state record for a stack (metadata, outputs, resources)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--json", "Output the raw state and lock as JSON", false).action(withErrorHandling(stateShowCommand));
|
|
28370
|
+
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
28371
|
+
return cmd;
|
|
28372
|
+
}
|
|
28373
|
+
async function stateRmCommand(stackArgs, options) {
|
|
28374
|
+
const logger = getLogger();
|
|
28375
|
+
if (options.verbose)
|
|
28376
|
+
logger.setLevel("debug");
|
|
28377
|
+
if (stackArgs.length === 0) {
|
|
28378
|
+
throw new Error("Stack name is required. Usage: cdkd state rm <stack> [<stack>...]");
|
|
28379
|
+
}
|
|
28380
|
+
const setup = await setupStateBackend(options);
|
|
28381
|
+
try {
|
|
28382
|
+
for (const stackName of stackArgs) {
|
|
28383
|
+
const exists = await setup.stateBackend.stateExists(stackName);
|
|
28384
|
+
if (!exists) {
|
|
28385
|
+
logger.info(`No state found for stack: ${stackName}, skipping`);
|
|
28386
|
+
continue;
|
|
28387
|
+
}
|
|
28388
|
+
if (!options.force) {
|
|
28389
|
+
const locked = await setup.lockManager.isLocked(stackName);
|
|
28390
|
+
if (locked) {
|
|
28391
|
+
throw new Error(
|
|
28392
|
+
`Stack '${stackName}' is locked. Run 'cdkd force-unlock ${stackName}' first, or pass --force to remove anyway.`
|
|
28393
|
+
);
|
|
28394
|
+
}
|
|
28395
|
+
}
|
|
28396
|
+
if (!options.yes && !options.force) {
|
|
28397
|
+
process.stdout.write(
|
|
28398
|
+
`
|
|
28399
|
+
WARNING: This removes cdkd's state record for '${stackName}' only. AWS resources will NOT be deleted.
|
|
28400
|
+
Use 'cdkd destroy ${stackName}' if you want to delete the actual resources.
|
|
28401
|
+
|
|
28402
|
+
`
|
|
28403
|
+
);
|
|
28404
|
+
const rl = readline2.createInterface({
|
|
28405
|
+
input: process.stdin,
|
|
28406
|
+
output: process.stdout
|
|
28407
|
+
});
|
|
28408
|
+
const answer = await rl.question(
|
|
28409
|
+
`Remove state for stack '${stackName}' from s3://${setup.bucket}/${setup.prefix}/? (y/N): `
|
|
28410
|
+
);
|
|
28411
|
+
rl.close();
|
|
28412
|
+
const trimmed = answer.trim().toLowerCase();
|
|
28413
|
+
if (trimmed !== "y" && trimmed !== "yes") {
|
|
28414
|
+
logger.info(`Cancelled removal of state for stack: ${stackName}`);
|
|
28415
|
+
continue;
|
|
28416
|
+
}
|
|
28417
|
+
}
|
|
28418
|
+
await setup.stateBackend.deleteState(stackName);
|
|
28419
|
+
await setup.lockManager.forceReleaseLock(stackName);
|
|
28420
|
+
logger.info(`\u2713 Removed state for stack: ${stackName}`);
|
|
28421
|
+
}
|
|
28422
|
+
} finally {
|
|
28423
|
+
setup.dispose();
|
|
28424
|
+
}
|
|
28425
|
+
}
|
|
28426
|
+
function createStateRmCommand() {
|
|
28427
|
+
const cmd = new Command9("rm").description("Remove cdkd state for one or more stacks (does NOT delete AWS resources)").argument("<stacks...>", "Stack name(s) to remove from state").option("-f, --force", "Skip confirmation and remove even if the stack is locked", false).action(withErrorHandling(stateRmCommand));
|
|
28428
|
+
[...commonOptions, ...stateOptions].forEach((opt) => cmd.addOption(opt));
|
|
28429
|
+
return cmd;
|
|
28430
|
+
}
|
|
28431
|
+
function createStateCommand() {
|
|
28432
|
+
const cmd = new Command9("state").description("Manage cdkd state stored in S3");
|
|
28433
|
+
cmd.addCommand(createStateListCommand());
|
|
28434
|
+
cmd.addCommand(createStateResourcesCommand());
|
|
28435
|
+
cmd.addCommand(createStateShowCommand());
|
|
28436
|
+
cmd.addCommand(createStateRmCommand());
|
|
28437
|
+
return cmd;
|
|
28438
|
+
}
|
|
28439
|
+
|
|
28092
28440
|
// src/cli/index.ts
|
|
28093
28441
|
var SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
28094
28442
|
"bootstrap",
|
|
@@ -28099,7 +28447,8 @@ var SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
28099
28447
|
"diff",
|
|
28100
28448
|
"destroy",
|
|
28101
28449
|
"publish-assets",
|
|
28102
|
-
"force-unlock"
|
|
28450
|
+
"force-unlock",
|
|
28451
|
+
"state"
|
|
28103
28452
|
]);
|
|
28104
28453
|
function reorderArgs(argv) {
|
|
28105
28454
|
const prefix = argv.slice(0, 2);
|
|
@@ -28112,8 +28461,8 @@ function reorderArgs(argv) {
|
|
|
28112
28461
|
return [...prefix, ...cmdAndAfter, ...beforeCmd];
|
|
28113
28462
|
}
|
|
28114
28463
|
async function main() {
|
|
28115
|
-
const program = new
|
|
28116
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
28464
|
+
const program = new Command10();
|
|
28465
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.7.0");
|
|
28117
28466
|
program.addCommand(createBootstrapCommand());
|
|
28118
28467
|
program.addCommand(createSynthCommand());
|
|
28119
28468
|
program.addCommand(createListCommand());
|
|
@@ -28122,6 +28471,7 @@ async function main() {
|
|
|
28122
28471
|
program.addCommand(createDestroyCommand());
|
|
28123
28472
|
program.addCommand(createPublishAssetsCommand());
|
|
28124
28473
|
program.addCommand(createForceUnlockCommand());
|
|
28474
|
+
program.addCommand(createStateCommand());
|
|
28125
28475
|
const args = reorderArgs(process.argv);
|
|
28126
28476
|
await program.parseAsync(args);
|
|
28127
28477
|
}
|