@bifos/nhncloud-cli 0.18.0 → 0.19.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 +111 -190
- package/dist/index.js +1435 -89
- package/package.json +25 -4
- package/skills/nhncloud-cli/SKILL.md +3 -2
- package/skills/nhncloud-cli/references/apigateway.md +2 -6
- package/skills/nhncloud-cli/references/common.md +6 -16
- package/skills/nhncloud-cli/references/deploy.md +0 -1
- package/skills/nhncloud-cli/references/loadbalancer.md +2 -3
- package/skills/nhncloud-cli/references/logncrash.md +6 -9
- package/skills/nhncloud-cli/references/ncs.md +3 -3
- package/skills/nhncloud-cli/references/nks.md +1 -1
- package/skills/nhncloud-cli/references/skm.md +118 -0
- package/skills/nhncloud-cli/references/troubleshooting.md +14 -30
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
|
-
var
|
|
27
|
+
var import_commander72 = require("commander");
|
|
28
28
|
var import_chalk18 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// src/utils/spinner.ts
|
|
@@ -413,6 +413,17 @@ function configureCommanderExitCodes(root) {
|
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
+
// src/commands/help.ts
|
|
417
|
+
function configureGlobalOptionsHelp(root) {
|
|
418
|
+
root.configureHelp({ showGlobalOptions: true });
|
|
419
|
+
for (const child of root.commands) {
|
|
420
|
+
configureGlobalOptionsHelp(child);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/version.ts
|
|
425
|
+
var CLI_VERSION = true ? "0.19.0" : "0.0.0-dev";
|
|
426
|
+
|
|
416
427
|
// src/commands/configure.ts
|
|
417
428
|
var import_commander2 = require("commander");
|
|
418
429
|
var import_chalk2 = __toESM(require("chalk"));
|
|
@@ -517,6 +528,13 @@ async function writeToken(profile, accessToken, expiresAt, credentialHash) {
|
|
|
517
528
|
|
|
518
529
|
// src/api/httpError.ts
|
|
519
530
|
var import_ky = require("ky");
|
|
531
|
+
async function readHttpErrorBody(err) {
|
|
532
|
+
try {
|
|
533
|
+
return await err.response.clone().json();
|
|
534
|
+
} catch {
|
|
535
|
+
return void 0;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
520
538
|
function toNhnCloudCliError(err) {
|
|
521
539
|
if (err instanceof NhnCloudCliError) {
|
|
522
540
|
return err;
|
|
@@ -592,10 +610,12 @@ var import_ky3 = __toESM(require("ky"));
|
|
|
592
610
|
var ENDPOINTS = {
|
|
593
611
|
logncrash: "https://api-lncs-search.nhncloudservice.com",
|
|
594
612
|
"logncrash-collector": "https://api-logncrash.nhncloudservice.com",
|
|
595
|
-
deploy: "https://api-deploy.nhncloudservice.com"
|
|
613
|
+
deploy: "https://api-deploy.nhncloudservice.com",
|
|
614
|
+
skm: "https://api-keymanager.nhncloudservice.com"
|
|
596
615
|
};
|
|
597
616
|
var GOV_ENDPOINTS = {
|
|
598
|
-
deploy: "https://api-tcd.gov-nhncloudservice.com"
|
|
617
|
+
deploy: "https://api-tcd.gov-nhncloudservice.com",
|
|
618
|
+
skm: "https://api-keymanager.gov-nhncloudservice.com"
|
|
599
619
|
};
|
|
600
620
|
function endpointFor(service, environment = "real") {
|
|
601
621
|
const endpoints = environment === "gov" ? GOV_ENDPOINTS : ENDPOINTS;
|
|
@@ -875,12 +895,9 @@ async function toLogncrashError(err) {
|
|
|
875
895
|
return toNhnCloudCliError(err);
|
|
876
896
|
}
|
|
877
897
|
let requestId = null;
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
requestId = body.requestId;
|
|
882
|
-
}
|
|
883
|
-
} catch {
|
|
898
|
+
const body = await readHttpErrorBody(err);
|
|
899
|
+
if (typeof body === "object" && body !== null && "requestId" in body && typeof body.requestId === "string") {
|
|
900
|
+
requestId = body.requestId;
|
|
884
901
|
}
|
|
885
902
|
return new LogncrashServerError(
|
|
886
903
|
`API \uD638\uCD9C \uC2E4\uD328 (500): ${err.message}`,
|
|
@@ -2009,7 +2026,7 @@ async function verifyLogncrash(uak, appkey) {
|
|
|
2009
2026
|
}
|
|
2010
2027
|
|
|
2011
2028
|
// src/commands/configure.ts
|
|
2012
|
-
async function saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, apigateway, deploy, doVerify, logncrashUak = uak) {
|
|
2029
|
+
async function saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, apigateway, skm, deploy, doVerify, logncrashUak = uak) {
|
|
2013
2030
|
if (doVerify) {
|
|
2014
2031
|
if (await getProfileEnvironment(profileName, true) === "gov") {
|
|
2015
2032
|
throw new NhnCloudCliError(
|
|
@@ -2115,6 +2132,9 @@ async function saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, apigat
|
|
|
2115
2132
|
if (apigateway) {
|
|
2116
2133
|
await setServiceCredential(profileName, "apigateway", apigateway);
|
|
2117
2134
|
}
|
|
2135
|
+
if (skm) {
|
|
2136
|
+
await setServiceCredential(profileName, "skm", skm);
|
|
2137
|
+
}
|
|
2118
2138
|
if (deploy) {
|
|
2119
2139
|
await setServiceCredential(profileName, "deploy", deploy);
|
|
2120
2140
|
}
|
|
@@ -2244,7 +2264,7 @@ async function runInteractive(opts) {
|
|
|
2244
2264
|
}
|
|
2245
2265
|
if (opts.verify) {
|
|
2246
2266
|
try {
|
|
2247
|
-
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, deploy, true, uak);
|
|
2267
|
+
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, void 0, deploy, true, uak);
|
|
2248
2268
|
} catch (err) {
|
|
2249
2269
|
if (err instanceof NhnCloudCliError && err.exitCode === EXIT_AUTH_ERROR) {
|
|
2250
2270
|
process.stderr.write(import_chalk2.default.red(` \u2717 ${sanitizeMultilineForTerminal(err.message)}
|
|
@@ -2257,13 +2277,13 @@ async function runInteractive(opts) {
|
|
|
2257
2277
|
process.stderr.write(import_chalk2.default.yellow("\uC800\uC7A5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
|
|
2258
2278
|
return;
|
|
2259
2279
|
}
|
|
2260
|
-
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, deploy, false, uak);
|
|
2280
|
+
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, void 0, deploy, false, uak);
|
|
2261
2281
|
} else {
|
|
2262
2282
|
throw err;
|
|
2263
2283
|
}
|
|
2264
2284
|
}
|
|
2265
2285
|
} else {
|
|
2266
|
-
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, deploy, false, uak);
|
|
2286
|
+
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, ncs, void 0, void 0, deploy, false, uak);
|
|
2267
2287
|
}
|
|
2268
2288
|
}
|
|
2269
2289
|
async function runNonInteractive(opts) {
|
|
@@ -2287,6 +2307,9 @@ async function runNonInteractive(opts) {
|
|
|
2287
2307
|
if (opts.apigatewayAppkey !== void 0 && opts.apigatewayAppkey.trim().length === 0) {
|
|
2288
2308
|
throw new NhnCloudCliError("--apigateway-appkey \uAC12\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2289
2309
|
}
|
|
2310
|
+
if (opts.skmAppkey !== void 0 && opts.skmAppkey.trim().length === 0) {
|
|
2311
|
+
throw new NhnCloudCliError("--skm-appkey \uAC12\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2312
|
+
}
|
|
2290
2313
|
if (opts.deployAppkey !== void 0 && opts.deployAppkey.trim().length === 0) {
|
|
2291
2314
|
throw new NhnCloudCliError("--deploy-appkey \uAC12\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
2292
2315
|
}
|
|
@@ -2309,10 +2332,11 @@ async function runNonInteractive(opts) {
|
|
|
2309
2332
|
const ncr = opts.ncrAppkey?.trim() ? { appkey: opts.ncrAppkey.trim() } : void 0;
|
|
2310
2333
|
const ncs = opts.ncsAppkey?.trim() ? { appkey: opts.ncsAppkey.trim() } : void 0;
|
|
2311
2334
|
const apigateway = opts.apigatewayAppkey?.trim() ? { appkey: opts.apigatewayAppkey.trim() } : void 0;
|
|
2335
|
+
const skm = opts.skmAppkey?.trim() ? { appkey: opts.skmAppkey.trim() } : void 0;
|
|
2312
2336
|
const deploy = opts.deployAppkey?.trim() ? { appkey: opts.deployAppkey.trim() } : void 0;
|
|
2313
|
-
if (!uak && !logncrash && !iaas && !ncr && !ncs && !apigateway && !deploy) {
|
|
2337
|
+
if (!uak && !logncrash && !iaas && !ncr && !ncs && !apigateway && !skm && !deploy) {
|
|
2314
2338
|
throw new NhnCloudCliError(
|
|
2315
|
-
"\uBE44\uB300\uD654\uD615 \uBAA8\uB4DC: --uak-id + UAK secret, --logncrash-appkey,\n--iaas-tenant-id + --iaas-username + iaas password,\n--ncr-appkey, --ncs-appkey, --apigateway-appkey, \uB610\uB294 --deploy-appkey\n\uC911 \uD558\uB098\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\nsecret/password \uB294 \uB178\uCD9C \uBC29\uC9C0\uB97C \uC704\uD574 \uD658\uACBD\uBCC0\uC218 \uAD8C\uC7A5:\nNHNCLOUD_UAK_SECRET / NHNCLOUD_IAAS_PASSWORD.",
|
|
2339
|
+
"\uBE44\uB300\uD654\uD615 \uBAA8\uB4DC: --uak-id + UAK secret, --logncrash-appkey,\n--iaas-tenant-id + --iaas-username + iaas password,\n--ncr-appkey, --ncs-appkey, --apigateway-appkey, --skm-appkey, \uB610\uB294 --deploy-appkey\n\uC911 \uD558\uB098\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\nsecret/password \uB294 \uB178\uCD9C \uBC29\uC9C0\uB97C \uC704\uD574 \uD658\uACBD\uBCC0\uC218 \uAD8C\uC7A5:\nNHNCLOUD_UAK_SECRET / NHNCLOUD_IAAS_PASSWORD.",
|
|
2316
2340
|
EXIT_PARAM_ERROR
|
|
2317
2341
|
);
|
|
2318
2342
|
}
|
|
@@ -2331,6 +2355,7 @@ async function runNonInteractive(opts) {
|
|
|
2331
2355
|
ncr,
|
|
2332
2356
|
ncs,
|
|
2333
2357
|
apigateway,
|
|
2358
|
+
skm,
|
|
2334
2359
|
deploy,
|
|
2335
2360
|
opts.verify,
|
|
2336
2361
|
logncrashUak
|
|
@@ -2339,8 +2364,8 @@ async function runNonInteractive(opts) {
|
|
|
2339
2364
|
var configureCommand = new import_commander2.Command("configure").description("\uC790\uACA9\uC99D\uBA85 \uC124\uC815 \uB9C8\uBC95\uC0AC (\uB300\uD654\uD615 + flag)").option("--profile <name>", "\uB300\uC0C1 profile \uC774\uB984 (\uAE30\uBCF8: default)").option("--uak-id <id>", "\uAC1C\uC778 UAK ID (\uBE44\uB300\uD654\uD615)").option("--uak-secret <secret>", "\uAC1C\uC778 UAK Secret (\uBE44\uB300\uD654\uD615, \uB178\uCD9C \uBC29\uC9C0\uB85C env NHNCLOUD_UAK_SECRET \uAD8C\uC7A5)").option("--logncrash-appkey <key>", "logncrash appkey (\uBE44\uB300\uD654\uD615)").option("--logncrash-secret <secret>", "\uD3D0\uAE30 \uC608\uC815: Search v3\uC5D0\uC11C\uB294 \uC0AC\uC6A9\xB7\uC800\uC7A5\uD558\uC9C0 \uC54A\uC74C").option("--iaas-tenant-id <id>", "iaas tenantId / \uD504\uB85C\uC81D\uD2B8 ID (\uBE44\uB300\uD654\uD615)").option("--iaas-username <user>", "iaas IAM username (\uBE44\uB300\uD654\uD615)").option(
|
|
2340
2365
|
"--iaas-password <pass>",
|
|
2341
2366
|
"iaas API \uBE44\uBC00\uBC88\uD638 (\uBE44\uB300\uD654\uD615, \uB178\uCD9C \uBC29\uC9C0\uB85C env NHNCLOUD_IAAS_PASSWORD \uAD8C\uC7A5)"
|
|
2342
|
-
).option("--iaas-region <region>", "iaas region (\uAE30\uBCF8: kr1)", "kr1").option("--ncr-appkey <key>", "ncr appkey (\uBE44\uB300\uD654\uD615)").option("--ncs-appkey <key>", "ncs appkey (\uBE44\uB300\uD654\uD615)").option("--apigateway-appkey <key>", "API Gateway appkey (\uBE44\uB300\uD654\uD615)").option("--deploy-appkey <key>", "deploy appkey (\uBE44\uB300\uD654\uD615)").option("--no-verify", "\uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC0DD\uB7B5").action(async (opts) => {
|
|
2343
|
-
const hasFlag = opts.uakId !== void 0 || opts.uakSecret !== void 0 || opts.logncrashAppkey !== void 0 || opts.logncrashSecret !== void 0 || opts.iaasTenantId !== void 0 || opts.iaasUsername !== void 0 || opts.iaasPassword !== void 0 || opts.ncrAppkey !== void 0 || opts.ncsAppkey !== void 0 || opts.apigatewayAppkey !== void 0 || opts.deployAppkey !== void 0;
|
|
2367
|
+
).option("--iaas-region <region>", "iaas region (\uAE30\uBCF8: kr1)", "kr1").option("--ncr-appkey <key>", "ncr appkey (\uBE44\uB300\uD654\uD615)").option("--ncs-appkey <key>", "ncs appkey (\uBE44\uB300\uD654\uD615)").option("--apigateway-appkey <key>", "API Gateway appkey (\uBE44\uB300\uD654\uD615)").option("--skm-appkey <key>", "Secure Key Manager appkey (\uBE44\uB300\uD654\uD615)").option("--deploy-appkey <key>", "deploy appkey (\uBE44\uB300\uD654\uD615)").option("--no-verify", "\uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC0DD\uB7B5").action(async (opts) => {
|
|
2368
|
+
const hasFlag = opts.uakId !== void 0 || opts.uakSecret !== void 0 || opts.logncrashAppkey !== void 0 || opts.logncrashSecret !== void 0 || opts.iaasTenantId !== void 0 || opts.iaasUsername !== void 0 || opts.iaasPassword !== void 0 || opts.ncrAppkey !== void 0 || opts.ncsAppkey !== void 0 || opts.apigatewayAppkey !== void 0 || opts.skmAppkey !== void 0 || opts.deployAppkey !== void 0;
|
|
2344
2369
|
try {
|
|
2345
2370
|
if (hasFlag) {
|
|
2346
2371
|
await runNonInteractive(opts);
|
|
@@ -5405,13 +5430,10 @@ async function toNetworkWriteError(err) {
|
|
|
5405
5430
|
return base;
|
|
5406
5431
|
}
|
|
5407
5432
|
let reason = null;
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
if (typeof message === "string") reason = message;
|
|
5413
|
-
} catch {
|
|
5414
|
-
}
|
|
5433
|
+
const body = await readHttpErrorBody(err);
|
|
5434
|
+
const neutron = typeof body === "object" && body !== null ? body["NeutronError"] : void 0;
|
|
5435
|
+
const message = typeof neutron === "object" && neutron !== null ? neutron["message"] : void 0;
|
|
5436
|
+
if (typeof message === "string") reason = message;
|
|
5415
5437
|
if (reason === null) return base;
|
|
5416
5438
|
return new NhnCloudCliError(
|
|
5417
5439
|
`${base.message}
|
|
@@ -11200,19 +11222,1343 @@ var importResourcesCommand = addApiGatewayOptions3(
|
|
|
11200
11222
|
});
|
|
11201
11223
|
var stageCommand = new import_commander58.Command("stage").description("API Gateway stage \uC870\uD68C \uBC0F \uBCC0\uACBD \uBA85\uB839").addCommand(listCommand15).addCommand(swaggerCommand).addCommand(resourcesCommand).addCommand(updateCommand3).addCommand(importResourcesCommand).addCommand(deployCommand);
|
|
11202
11224
|
|
|
11203
|
-
// src/commands/
|
|
11225
|
+
// src/commands/skm/confirm.ts
|
|
11204
11226
|
var import_commander59 = require("commander");
|
|
11205
11227
|
|
|
11206
|
-
// src/commands/
|
|
11228
|
+
// src/commands/skm/helpers.ts
|
|
11207
11229
|
var import_node_net2 = require("net");
|
|
11208
11230
|
|
|
11209
|
-
// src/services/
|
|
11231
|
+
// src/services/skm/client.ts
|
|
11210
11232
|
var import_ky16 = __toESM(require("ky"));
|
|
11211
11233
|
|
|
11212
|
-
// src/services/
|
|
11234
|
+
// src/services/skm/types.ts
|
|
11213
11235
|
function isRecord3(value) {
|
|
11214
11236
|
return typeof value === "object" && value !== null;
|
|
11215
11237
|
}
|
|
11238
|
+
function hasStrings(obj, keys) {
|
|
11239
|
+
return keys.every((key) => typeof obj[key] === "string");
|
|
11240
|
+
}
|
|
11241
|
+
function hasNumbers(obj, keys) {
|
|
11242
|
+
return keys.every((key) => typeof obj[key] === "number");
|
|
11243
|
+
}
|
|
11244
|
+
function hasOptional(obj, keys, type) {
|
|
11245
|
+
return keys.every((key) => obj[key] === void 0 || obj[key] === null || typeof obj[key] === type);
|
|
11246
|
+
}
|
|
11247
|
+
var AUDIT_FIELDS = ["creationUser", "creationDatetime", "lastChangeUser", "lastChangeDatetime"];
|
|
11248
|
+
function isSkmClientInfo(value) {
|
|
11249
|
+
if (!isRecord3(value)) return false;
|
|
11250
|
+
return typeof value["clientIp"] === "string" && typeof value["clientSentCertificate"] === "boolean" && hasOptional(value, ["clientMacHeader"], "string");
|
|
11251
|
+
}
|
|
11252
|
+
function isSkmKeyStore(value) {
|
|
11253
|
+
if (!isRecord3(value)) return false;
|
|
11254
|
+
return typeof value["keyStoreId"] === "number" && hasStrings(value, ["name", "ip4AuthUse", "macAuthUse", "certificateAuthUse"]) && hasOptional(value, ["description", ...AUDIT_FIELDS], "string");
|
|
11255
|
+
}
|
|
11256
|
+
function isSkmKey(value) {
|
|
11257
|
+
if (!isRecord3(value)) return false;
|
|
11258
|
+
return hasStrings(value, ["keyId", "name", "keyType"]) && typeof value["currentKeyValueVersion"] === "number" && hasOptional(value, ["autoRotationPeriod"], "number") && hasOptional(
|
|
11259
|
+
value,
|
|
11260
|
+
["description", "nextAutoRotationDate", "lastAccessDatetime", "deletionDatetime", ...AUDIT_FIELDS],
|
|
11261
|
+
"string"
|
|
11262
|
+
);
|
|
11263
|
+
}
|
|
11264
|
+
function isSkmAuthDetail(value) {
|
|
11265
|
+
if (!isRecord3(value)) return false;
|
|
11266
|
+
return (typeof value["value"] === "string" || typeof value["name"] === "string") && hasOptional(
|
|
11267
|
+
value,
|
|
11268
|
+
[
|
|
11269
|
+
"value",
|
|
11270
|
+
"name",
|
|
11271
|
+
"password",
|
|
11272
|
+
"description",
|
|
11273
|
+
"expirationDate",
|
|
11274
|
+
"lastAccessDatetime",
|
|
11275
|
+
"deletionDatetime",
|
|
11276
|
+
...AUDIT_FIELDS
|
|
11277
|
+
],
|
|
11278
|
+
"string"
|
|
11279
|
+
);
|
|
11280
|
+
}
|
|
11281
|
+
function isSkmEncryptResult(value) {
|
|
11282
|
+
return isRecord3(value) && hasStrings(value, ["ciphertext"]) && hasNumbers(value, ["keyVersion"]);
|
|
11283
|
+
}
|
|
11284
|
+
function isSkmDecryptResult(value) {
|
|
11285
|
+
return isRecord3(value) && hasStrings(value, ["plaintext"]) && hasNumbers(value, ["keyVersion"]);
|
|
11286
|
+
}
|
|
11287
|
+
function isSkmLocalKey(value) {
|
|
11288
|
+
return isRecord3(value) && hasStrings(value, ["localKeyPlaintext", "localKeyCiphertext"]) && hasNumbers(value, ["keyVersion"]);
|
|
11289
|
+
}
|
|
11290
|
+
function isSkmSymmetricKey(value) {
|
|
11291
|
+
return isRecord3(value) && hasStrings(value, ["symmetricKey"]) && hasNumbers(value, ["keyVersion"]);
|
|
11292
|
+
}
|
|
11293
|
+
function isSkmSignResult(value) {
|
|
11294
|
+
return isRecord3(value) && hasStrings(value, ["signature"]) && hasNumbers(value, ["keyVersion"]);
|
|
11295
|
+
}
|
|
11296
|
+
function isSkmStandardSignResult(value) {
|
|
11297
|
+
return isRecord3(value) && hasStrings(value, ["signature", "algorithm", "hashAlgorithm", "mgfAlgorithm"]) && hasNumbers(value, ["keyVersion", "saltLength"]);
|
|
11298
|
+
}
|
|
11299
|
+
function isSkmVerifyResult(value) {
|
|
11300
|
+
return isRecord3(value) && typeof value["result"] === "boolean" && hasNumbers(value, ["keyVersion"]);
|
|
11301
|
+
}
|
|
11302
|
+
function isSkmAsymmetricKeyMaterial(value) {
|
|
11303
|
+
return isRecord3(value) && hasStrings(value, ["keyType", "key", "encodedKey"]) && hasOptional(value, ["standardEncodedKey"], "string") && hasNumbers(value, ["keyVersion"]);
|
|
11304
|
+
}
|
|
11305
|
+
function isSkmCreatedKey(value) {
|
|
11306
|
+
return isRecord3(value) && hasStrings(value, ["keyId", "keyStatus"]);
|
|
11307
|
+
}
|
|
11308
|
+
function isSkmCreatedKeyStore(value) {
|
|
11309
|
+
if (!isRecord3(value)) return false;
|
|
11310
|
+
return typeof value["keyStoreId"] === "number" && hasStrings(value, ["name", "ip4AuthUse", "macAuthUse", "certificateAuthUse"]) && hasOptional(value, ["description", "authMode"], "string");
|
|
11311
|
+
}
|
|
11312
|
+
function isSkmUpdatedSecret(value) {
|
|
11313
|
+
if (!isRecord3(value)) return false;
|
|
11314
|
+
return hasStrings(value, ["keyId", "name"]) && hasOptional(value, ["description", "secretValue", ...AUDIT_FIELDS], "string");
|
|
11315
|
+
}
|
|
11316
|
+
function isSkmDeletion(value) {
|
|
11317
|
+
return isRecord3(value) && hasStrings(value, ["keyId", "deletionDateTime"]);
|
|
11318
|
+
}
|
|
11319
|
+
function hasAuthIdentifier(obj) {
|
|
11320
|
+
return (typeof obj["value"] === "string" || typeof obj["name"] === "string") && hasOptional(obj, ["value", "name"], "string");
|
|
11321
|
+
}
|
|
11322
|
+
function isSkmAuthAdded(value) {
|
|
11323
|
+
return isRecord3(value) && hasAuthIdentifier(value) && hasOptional(value, ["description"], "string");
|
|
11324
|
+
}
|
|
11325
|
+
function isSkmAuthDeletion(value) {
|
|
11326
|
+
return isRecord3(value) && hasAuthIdentifier(value) && hasStrings(value, ["deletionDateTime"]);
|
|
11327
|
+
}
|
|
11328
|
+
|
|
11329
|
+
// src/services/skm/client.ts
|
|
11330
|
+
var KEY_PAGE_SIZE = 100;
|
|
11331
|
+
var STANDARD_SIGN_ALGORITHM = "RSASSA-PSS";
|
|
11332
|
+
var AUTH_PATHS = {
|
|
11333
|
+
ipv4: { path: "ips", field: "ipv4List" },
|
|
11334
|
+
mac: { path: "macs", field: "macList" },
|
|
11335
|
+
certificate: { path: "certificates", field: "certificateList" }
|
|
11336
|
+
};
|
|
11337
|
+
var AUTH_WRITE_PATH = {
|
|
11338
|
+
ipv4: "ipv4s",
|
|
11339
|
+
mac: "macs",
|
|
11340
|
+
certificate: "certificates"
|
|
11341
|
+
};
|
|
11342
|
+
function isRecord4(value) {
|
|
11343
|
+
return typeof value === "object" && value !== null;
|
|
11344
|
+
}
|
|
11345
|
+
function isEnvelope(value) {
|
|
11346
|
+
if (!isRecord4(value)) return false;
|
|
11347
|
+
const header = value["header"];
|
|
11348
|
+
return isRecord4(header) && typeof header["isSuccessful"] === "boolean";
|
|
11349
|
+
}
|
|
11350
|
+
function arrayOf(guard) {
|
|
11351
|
+
return (value) => Array.isArray(value) && value.every(guard);
|
|
11352
|
+
}
|
|
11353
|
+
function isString(value) {
|
|
11354
|
+
return typeof value === "string";
|
|
11355
|
+
}
|
|
11356
|
+
function withDescription(body, description) {
|
|
11357
|
+
return description === void 0 ? body : { ...body, description };
|
|
11358
|
+
}
|
|
11359
|
+
function authDeletionBody(type, keyStoreName, value) {
|
|
11360
|
+
return type === "certificate" ? { keyStoreName, name: value } : { keyStoreName, value };
|
|
11361
|
+
}
|
|
11362
|
+
function keyStoreBody(input) {
|
|
11363
|
+
const { name, description, ip4AuthUse, macAuthUse, certificateAuthUse, authMode } = input;
|
|
11364
|
+
return withDescription({ name, ip4AuthUse, macAuthUse, certificateAuthUse, authMode }, description);
|
|
11365
|
+
}
|
|
11366
|
+
function keyVersionParams(keyVersion) {
|
|
11367
|
+
return keyVersion === void 0 ? {} : { searchParams: { keyVersion } };
|
|
11368
|
+
}
|
|
11369
|
+
async function toSkmError(err) {
|
|
11370
|
+
if (!(err instanceof import_ky16.HTTPError)) return toNhnCloudCliError(err);
|
|
11371
|
+
let resultMessage = null;
|
|
11372
|
+
const body = await readHttpErrorBody(err);
|
|
11373
|
+
const header = isRecord4(body) ? body["header"] : void 0;
|
|
11374
|
+
const message = isRecord4(header) ? header["resultMessage"] : void 0;
|
|
11375
|
+
if (typeof message === "string") resultMessage = message;
|
|
11376
|
+
if (resultMessage === null) return toNhnCloudCliError(err);
|
|
11377
|
+
const status = err.response.status;
|
|
11378
|
+
return new NhnCloudCliError(
|
|
11379
|
+
`API \uD638\uCD9C \uC2E4\uD328 (${status}): ${sanitizeForTerminal(resultMessage)}`,
|
|
11380
|
+
status === 401 || status === 403 ? EXIT_AUTH_ERROR : EXIT_API_ERROR
|
|
11381
|
+
);
|
|
11382
|
+
}
|
|
11383
|
+
var SkmClient = class {
|
|
11384
|
+
baseUrl;
|
|
11385
|
+
headers;
|
|
11386
|
+
constructor(accessToken, environment, appKey, macAddress) {
|
|
11387
|
+
this.baseUrl = `${endpointFor("skm", environment)}/keymanager/v1.3/appkey/${encodeURIComponent(appKey)}`;
|
|
11388
|
+
this.headers = { "X-NHN-Authorization": `Bearer ${accessToken}` };
|
|
11389
|
+
if (macAddress !== void 0) {
|
|
11390
|
+
this.headers["X-TOAST-CLIENT-MAC-ADDR"] = macAddress;
|
|
11391
|
+
}
|
|
11392
|
+
}
|
|
11393
|
+
/**
|
|
11394
|
+
* 요청을 보내고 봉투 형태인지만 확인해 반환한다. 성공 판정은 호출부가 한다.
|
|
11395
|
+
* 쓰기 요청도 중복 실행을 막으려고 재시도하지 않는다.
|
|
11396
|
+
*/
|
|
11397
|
+
async send(method, path5, options) {
|
|
11398
|
+
let response;
|
|
11399
|
+
try {
|
|
11400
|
+
response = await import_ky16.default[method](`${this.baseUrl}${path5}`, {
|
|
11401
|
+
headers: this.headers,
|
|
11402
|
+
...options,
|
|
11403
|
+
retry: 0,
|
|
11404
|
+
timeout: DEFAULT_TIMEOUT_MS
|
|
11405
|
+
}).json();
|
|
11406
|
+
} catch (err) {
|
|
11407
|
+
throw await toSkmError(err);
|
|
11408
|
+
}
|
|
11409
|
+
if (!isEnvelope(response)) {
|
|
11410
|
+
throw new NhnCloudCliError("Secure Key Manager \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: header", EXIT_API_ERROR);
|
|
11411
|
+
}
|
|
11412
|
+
return response;
|
|
11413
|
+
}
|
|
11414
|
+
/**
|
|
11415
|
+
* 요청을 보내고 봉투를 벗긴 뒤 body 또는 body[field] 를 가드로 검사해 반환한다.
|
|
11416
|
+
* field 가 null 이면 body 전체를 검사한다.
|
|
11417
|
+
*/
|
|
11418
|
+
async request(method, path5, field, guard, options = {}) {
|
|
11419
|
+
const body = unwrap(await this.send(method, path5, options));
|
|
11420
|
+
const value = field === null ? body : isRecord4(body) ? body[field] : void 0;
|
|
11421
|
+
if (!guard(value)) {
|
|
11422
|
+
throw new NhnCloudCliError(`Secure Key Manager \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: ${field ?? "body"}`, EXIT_API_ERROR);
|
|
11423
|
+
}
|
|
11424
|
+
return value;
|
|
11425
|
+
}
|
|
11426
|
+
/**
|
|
11427
|
+
* body 가 null 이거나 없는 응답(키 저장소 수정·삭제)은 검사할 필드가 없어 헤더만 본다 (ADR-040).
|
|
11428
|
+
* isSuccessful 이 false 면 unwrapHeader 가 NhnEnvelopeError 를 던진다.
|
|
11429
|
+
*/
|
|
11430
|
+
async requestHeaderOnly(method, path5, options = {}) {
|
|
11431
|
+
unwrapHeader(await this.send(method, path5, options));
|
|
11432
|
+
}
|
|
11433
|
+
keyPath(prefix, keyId, action) {
|
|
11434
|
+
return `/${prefix}/${encodeURIComponent(keyId)}/${action}`;
|
|
11435
|
+
}
|
|
11436
|
+
/** 호출 클라이언트의 IP·MAC·인증서 전송 여부를 확인한다. */
|
|
11437
|
+
confirm() {
|
|
11438
|
+
return this.request("get", "/confirm", null, isSkmClientInfo);
|
|
11439
|
+
}
|
|
11440
|
+
listKeyStores() {
|
|
11441
|
+
return this.request("get", "/keystores", "keyStoreList", arrayOf(isSkmKeyStore), {
|
|
11442
|
+
searchParams: { detail: "true" }
|
|
11443
|
+
});
|
|
11444
|
+
}
|
|
11445
|
+
getKeyStore(keyStoreId) {
|
|
11446
|
+
return this.request("get", `/keystores/${keyStoreId}`, null, isSkmKeyStore);
|
|
11447
|
+
}
|
|
11448
|
+
/**
|
|
11449
|
+
* 모든 페이지의 키를 모은다.
|
|
11450
|
+
* 서버가 pageNumber 를 무시하면 같은 페이지가 반복되므로, 첫 keyId 가 직전 페이지와 같으면 중단한다.
|
|
11451
|
+
*/
|
|
11452
|
+
async listKeys(keyStoreId, filter = {}) {
|
|
11453
|
+
const keys = [];
|
|
11454
|
+
let previousFirstKeyId;
|
|
11455
|
+
for (let pageNumber = 1; ; pageNumber++) {
|
|
11456
|
+
const searchParams = { detail: "true", pageNumber, pageSize: KEY_PAGE_SIZE };
|
|
11457
|
+
if (filter.type) searchParams["type"] = filter.type;
|
|
11458
|
+
if (filter.name) searchParams["name"] = filter.name;
|
|
11459
|
+
if (filter.status) searchParams["status"] = filter.status;
|
|
11460
|
+
const page = await this.request("get", `/keystores/${keyStoreId}/keys`, "keyList", arrayOf(isSkmKey), {
|
|
11461
|
+
searchParams
|
|
11462
|
+
});
|
|
11463
|
+
const firstKeyId = page[0]?.keyId;
|
|
11464
|
+
if (firstKeyId !== void 0 && firstKeyId === previousFirstKeyId) {
|
|
11465
|
+
throw new NhnCloudCliError(
|
|
11466
|
+
`Secure Key Manager \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: ${pageNumber} \uD398\uC774\uC9C0\uAC00 \uC9C1\uC804 \uD398\uC774\uC9C0\uC640 \uAC19\uC740 \uD0A4\uB85C \uC2DC\uC791\uD569\uB2C8\uB2E4.`,
|
|
11467
|
+
EXIT_API_ERROR
|
|
11468
|
+
);
|
|
11469
|
+
}
|
|
11470
|
+
keys.push(...page);
|
|
11471
|
+
if (page.length < KEY_PAGE_SIZE) return keys;
|
|
11472
|
+
previousFirstKeyId = firstKeyId;
|
|
11473
|
+
}
|
|
11474
|
+
}
|
|
11475
|
+
getKey(keyStoreId, keyId) {
|
|
11476
|
+
return this.request("get", `/keystores/${keyStoreId}/keys/${encodeURIComponent(keyId)}`, null, isSkmKey);
|
|
11477
|
+
}
|
|
11478
|
+
listAuths(keyStoreId, type) {
|
|
11479
|
+
const { path: path5, field } = AUTH_PATHS[type];
|
|
11480
|
+
return this.request("get", `/keystores/${keyStoreId}/${path5}`, field, arrayOf(isString));
|
|
11481
|
+
}
|
|
11482
|
+
getAuth(keyStoreId, type, value) {
|
|
11483
|
+
const { path: path5, field } = AUTH_PATHS[type];
|
|
11484
|
+
return this.request("get", `/keystores/${keyStoreId}/${path5}`, field, arrayOf(isSkmAuthDetail), {
|
|
11485
|
+
searchParams: { value }
|
|
11486
|
+
});
|
|
11487
|
+
}
|
|
11488
|
+
getSecret(keyId) {
|
|
11489
|
+
return this.request("get", `/secrets/${encodeURIComponent(keyId)}`, "secret", isString);
|
|
11490
|
+
}
|
|
11491
|
+
encrypt(keyId, plaintext) {
|
|
11492
|
+
return this.request("post", this.keyPath("symmetric-keys", keyId, "encrypt"), null, isSkmEncryptResult, {
|
|
11493
|
+
json: { plaintext }
|
|
11494
|
+
});
|
|
11495
|
+
}
|
|
11496
|
+
decrypt(keyId, ciphertext) {
|
|
11497
|
+
return this.request("post", this.keyPath("symmetric-keys", keyId, "decrypt"), null, isSkmDecryptResult, {
|
|
11498
|
+
json: { ciphertext }
|
|
11499
|
+
});
|
|
11500
|
+
}
|
|
11501
|
+
createLocalKey(keyId) {
|
|
11502
|
+
return this.request("post", this.keyPath("symmetric-keys", keyId, "create-local-key"), null, isSkmLocalKey);
|
|
11503
|
+
}
|
|
11504
|
+
getSymmetricKey(keyId, keyVersion) {
|
|
11505
|
+
return this.request(
|
|
11506
|
+
"get",
|
|
11507
|
+
this.keyPath("symmetric-keys", keyId, "symmetric-key"),
|
|
11508
|
+
null,
|
|
11509
|
+
isSkmSymmetricKey,
|
|
11510
|
+
keyVersionParams(keyVersion)
|
|
11511
|
+
);
|
|
11512
|
+
}
|
|
11513
|
+
sign(keyId, plaintext) {
|
|
11514
|
+
return this.request("post", this.keyPath("asymmetric-keys", keyId, "sign"), null, isSkmSignResult, {
|
|
11515
|
+
json: { plaintext }
|
|
11516
|
+
});
|
|
11517
|
+
}
|
|
11518
|
+
verify(keyId, plaintext, signature) {
|
|
11519
|
+
return this.request("post", this.keyPath("asymmetric-keys", keyId, "verify"), null, isSkmVerifyResult, {
|
|
11520
|
+
json: { plaintext, signature }
|
|
11521
|
+
});
|
|
11522
|
+
}
|
|
11523
|
+
signStandard(keyId, plaintextBase64) {
|
|
11524
|
+
return this.request(
|
|
11525
|
+
"post",
|
|
11526
|
+
this.keyPath("asymmetric-keys", keyId, "sign-standard"),
|
|
11527
|
+
null,
|
|
11528
|
+
isSkmStandardSignResult,
|
|
11529
|
+
{ json: { plaintext: plaintextBase64, algorithm: STANDARD_SIGN_ALGORITHM } }
|
|
11530
|
+
);
|
|
11531
|
+
}
|
|
11532
|
+
verifyStandard(keyId, plaintextBase64, signature, keyVersion) {
|
|
11533
|
+
return this.request("post", this.keyPath("asymmetric-keys", keyId, "verify-standard"), null, isSkmVerifyResult, {
|
|
11534
|
+
json: { plaintext: plaintextBase64, signature, algorithm: STANDARD_SIGN_ALGORITHM, keyVersion }
|
|
11535
|
+
});
|
|
11536
|
+
}
|
|
11537
|
+
getPrivateKey(keyId, keyVersion) {
|
|
11538
|
+
return this.request(
|
|
11539
|
+
"get",
|
|
11540
|
+
this.keyPath("asymmetric-keys", keyId, "privateKey"),
|
|
11541
|
+
null,
|
|
11542
|
+
isSkmAsymmetricKeyMaterial,
|
|
11543
|
+
keyVersionParams(keyVersion)
|
|
11544
|
+
);
|
|
11545
|
+
}
|
|
11546
|
+
getPublicKey(keyId, keyVersion) {
|
|
11547
|
+
return this.request(
|
|
11548
|
+
"get",
|
|
11549
|
+
this.keyPath("asymmetric-keys", keyId, "publicKey"),
|
|
11550
|
+
null,
|
|
11551
|
+
isSkmAsymmetricKeyMaterial,
|
|
11552
|
+
keyVersionParams(keyVersion)
|
|
11553
|
+
);
|
|
11554
|
+
}
|
|
11555
|
+
createSecret(keyStoreName, name, description, secretValue) {
|
|
11556
|
+
return this.request("post", "/keys/secrets/create", null, isSkmCreatedKey, {
|
|
11557
|
+
json: withDescription({ keyStoreName, name, secretValue }, description)
|
|
11558
|
+
});
|
|
11559
|
+
}
|
|
11560
|
+
/** 자동 회전 주기의 단위가 문서에 없어 항상 0(자동 회전 안 함)을 보낸다 (ADR-040). */
|
|
11561
|
+
createSymmetricKey(keyStoreName, name, description) {
|
|
11562
|
+
return this.request("post", "/keys/symmetric-keys/create", null, isSkmCreatedKey, {
|
|
11563
|
+
json: withDescription({ keyStoreName, name, autoRotationPeriod: 0 }, description)
|
|
11564
|
+
});
|
|
11565
|
+
}
|
|
11566
|
+
/** 자동 회전 주기의 단위가 문서에 없어 항상 0(자동 회전 안 함)을 보낸다 (ADR-040). */
|
|
11567
|
+
createAsymmetricKey(keyStoreName, name, description) {
|
|
11568
|
+
return this.request("post", "/keys/asymmetric-keys/create", null, isSkmCreatedKey, {
|
|
11569
|
+
json: withDescription({ keyStoreName, name, autoRotationPeriod: 0 }, description)
|
|
11570
|
+
});
|
|
11571
|
+
}
|
|
11572
|
+
updateSecret(keyId, secretValue) {
|
|
11573
|
+
return this.request("put", `/secrets/${encodeURIComponent(keyId)}`, null, isSkmUpdatedSecret, {
|
|
11574
|
+
json: { secretValue }
|
|
11575
|
+
});
|
|
11576
|
+
}
|
|
11577
|
+
/** 7일 뒤 삭제를 예약한다. */
|
|
11578
|
+
scheduleKeyDeletion(keyId) {
|
|
11579
|
+
return this.request("put", this.keyPath("keys", keyId, "delete"), null, isSkmDeletion);
|
|
11580
|
+
}
|
|
11581
|
+
/** 삭제 예약된 키를 즉시 삭제한다. 되돌릴 수 없다. */
|
|
11582
|
+
deleteKeyNow(keyId) {
|
|
11583
|
+
return this.request("delete", `/keys/${encodeURIComponent(keyId)}`, null, isSkmDeletion);
|
|
11584
|
+
}
|
|
11585
|
+
createKeyStore(input) {
|
|
11586
|
+
return this.request("post", "/keystores", null, isSkmCreatedKeyStore, { json: keyStoreBody(input) });
|
|
11587
|
+
}
|
|
11588
|
+
/** 전체 교체 API 라 주지 않은 값은 호출부가 현재 값으로 채워 넘긴다 (ADR-040). */
|
|
11589
|
+
updateKeyStore(keyStoreId, input) {
|
|
11590
|
+
return this.requestHeaderOnly("put", `/keystores/${keyStoreId}`, { json: keyStoreBody(input) });
|
|
11591
|
+
}
|
|
11592
|
+
deleteKeyStore(keyStoreId) {
|
|
11593
|
+
return this.requestHeaderOnly("delete", `/keystores/${keyStoreId}`);
|
|
11594
|
+
}
|
|
11595
|
+
addAuth(type, keyStoreName, value, description) {
|
|
11596
|
+
return this.request("post", `/auths/${AUTH_WRITE_PATH[type]}`, null, isSkmAuthAdded, {
|
|
11597
|
+
json: withDescription({ keyStoreName, value }, description)
|
|
11598
|
+
});
|
|
11599
|
+
}
|
|
11600
|
+
addCertificate(keyStoreName, name, password, lifeTime, description) {
|
|
11601
|
+
return this.request("post", `/auths/${AUTH_WRITE_PATH.certificate}`, null, isSkmAuthAdded, {
|
|
11602
|
+
json: withDescription({ keyStoreName, name, password, lifeTime }, description)
|
|
11603
|
+
});
|
|
11604
|
+
}
|
|
11605
|
+
/** 7일 뒤 삭제를 예약한다. */
|
|
11606
|
+
scheduleAuthDeletion(type, keyStoreName, value) {
|
|
11607
|
+
return this.request("put", `/auths/${AUTH_WRITE_PATH[type]}/delete`, null, isSkmAuthDeletion, {
|
|
11608
|
+
json: authDeletionBody(type, keyStoreName, value)
|
|
11609
|
+
});
|
|
11610
|
+
}
|
|
11611
|
+
/** 삭제 예약된 인증 정보를 즉시 삭제한다. 되돌릴 수 없다. */
|
|
11612
|
+
deleteAuthNow(type, keyStoreName, value) {
|
|
11613
|
+
return this.request("post", `/auths/${AUTH_WRITE_PATH[type]}/delete`, null, isSkmAuthDeletion, {
|
|
11614
|
+
json: authDeletionBody(type, keyStoreName, value)
|
|
11615
|
+
});
|
|
11616
|
+
}
|
|
11617
|
+
};
|
|
11618
|
+
|
|
11619
|
+
// src/commands/skm/helpers.ts
|
|
11620
|
+
var MAC_ADDRESS_PATTERN = /^[0-9A-Fa-f]{2}(:[0-9A-Fa-f]{2}){5}$/;
|
|
11621
|
+
var KEY_NAME_MAX_LENGTH = 100;
|
|
11622
|
+
var KEY_TYPES = {
|
|
11623
|
+
secret: "SECRET",
|
|
11624
|
+
"symmetric-key": "SYMMETRIC_KEY",
|
|
11625
|
+
"asymmetric-key": "ASYMMETRIC_KEY"
|
|
11626
|
+
};
|
|
11627
|
+
var AUTH_TYPES = ["ipv4", "mac", "certificate"];
|
|
11628
|
+
function withSkmOptions(command) {
|
|
11629
|
+
return command.option("--mac-address <mac>", "\uD0A4 \uC800\uC7A5\uC18C MAC \uC778\uC99D\uC5D0 \uC4F8 \uD074\uB77C\uC774\uC5B8\uD2B8 MAC \uC8FC\uC18C (X-TOAST-CLIENT-MAC-ADDR)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984");
|
|
11630
|
+
}
|
|
11631
|
+
function withTypeOption(command) {
|
|
11632
|
+
return command.requiredOption("--type <type>", "\uC778\uC99D \uC815\uBCF4 \uC885\uB958 (ipv4|mac|certificate)");
|
|
11633
|
+
}
|
|
11634
|
+
function parseMacAddressOption(value) {
|
|
11635
|
+
if (value === void 0) return void 0;
|
|
11636
|
+
if (!MAC_ADDRESS_PATTERN.test(value)) {
|
|
11637
|
+
throw new NhnCloudCliError(
|
|
11638
|
+
`--mac-address\uB294 aa:bb:cc:dd:ee:ff \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11639
|
+
EXIT_PARAM_ERROR
|
|
11640
|
+
);
|
|
11641
|
+
}
|
|
11642
|
+
return value.toLowerCase();
|
|
11643
|
+
}
|
|
11644
|
+
function parseKeyStoreId(value) {
|
|
11645
|
+
return parseNonNegativeIntegerOption(parseRequiredArgument(value, "keystore-id"), "<keystore-id>");
|
|
11646
|
+
}
|
|
11647
|
+
function parseAuthTypeOption(value) {
|
|
11648
|
+
const found = AUTH_TYPES.find((type) => type === value);
|
|
11649
|
+
if (!found) {
|
|
11650
|
+
throw new NhnCloudCliError(
|
|
11651
|
+
`--type\uC740 ipv4, mac, certificate \uC911 \uD558\uB098\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11652
|
+
EXIT_PARAM_ERROR
|
|
11653
|
+
);
|
|
11654
|
+
}
|
|
11655
|
+
return found;
|
|
11656
|
+
}
|
|
11657
|
+
function parseAuthListOption(value) {
|
|
11658
|
+
const items = value.split(",").map((item) => item.trim());
|
|
11659
|
+
if (items.some((item) => !AUTH_TYPES.some((type) => type === item))) {
|
|
11660
|
+
throw new NhnCloudCliError(
|
|
11661
|
+
`--auth\uB294 ipv4, mac, certificate\uB97C \uC27C\uD45C\uB85C \uB098\uC5F4\uD574\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11662
|
+
EXIT_PARAM_ERROR
|
|
11663
|
+
);
|
|
11664
|
+
}
|
|
11665
|
+
const flag = (type) => items.includes(type) ? "Y" : "N";
|
|
11666
|
+
return { ip4AuthUse: flag("ipv4"), macAuthUse: flag("mac"), certificateAuthUse: flag("certificate") };
|
|
11667
|
+
}
|
|
11668
|
+
function parseAuthModeOption(value) {
|
|
11669
|
+
const upper = value.toUpperCase();
|
|
11670
|
+
if (upper !== "AND" && upper !== "OR") {
|
|
11671
|
+
throw new NhnCloudCliError(
|
|
11672
|
+
`--auth-mode\uB294 and \uB610\uB294 or\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11673
|
+
EXIT_PARAM_ERROR
|
|
11674
|
+
);
|
|
11675
|
+
}
|
|
11676
|
+
return upper;
|
|
11677
|
+
}
|
|
11678
|
+
function parseDescriptionOption(value, maxLength) {
|
|
11679
|
+
const trimmed = value?.trim();
|
|
11680
|
+
if (!trimmed) return void 0;
|
|
11681
|
+
if (trimmed.length > maxLength) {
|
|
11682
|
+
throw new NhnCloudCliError(`--description\uC740 ${maxLength}\uC790 \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4.`, EXIT_PARAM_ERROR);
|
|
11683
|
+
}
|
|
11684
|
+
return trimmed;
|
|
11685
|
+
}
|
|
11686
|
+
function isIpv4OrCidr2(value) {
|
|
11687
|
+
const [address, prefix, ...rest] = value.split("/");
|
|
11688
|
+
if (rest.length > 0 || address === void 0 || (0, import_node_net2.isIP)(address) !== 4) return false;
|
|
11689
|
+
return prefix === void 0 || /^(\d|[12]\d|3[0-2])$/.test(prefix);
|
|
11690
|
+
}
|
|
11691
|
+
function parseAuthValue(type, value) {
|
|
11692
|
+
if (type === "ipv4") {
|
|
11693
|
+
if (!isIpv4OrCidr2(value)) {
|
|
11694
|
+
throw new NhnCloudCliError(
|
|
11695
|
+
`IPv4 \uC8FC\uC18C\uB098 CIDR \uB300\uC5ED \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11696
|
+
EXIT_PARAM_ERROR
|
|
11697
|
+
);
|
|
11698
|
+
}
|
|
11699
|
+
return value;
|
|
11700
|
+
}
|
|
11701
|
+
if (type === "mac") {
|
|
11702
|
+
if (!MAC_ADDRESS_PATTERN.test(value)) {
|
|
11703
|
+
throw new NhnCloudCliError(
|
|
11704
|
+
`MAC \uC8FC\uC18C\uB294 aa:bb:cc:dd:ee:ff \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11705
|
+
EXIT_PARAM_ERROR
|
|
11706
|
+
);
|
|
11707
|
+
}
|
|
11708
|
+
return value.toLowerCase();
|
|
11709
|
+
}
|
|
11710
|
+
const name = value.trim();
|
|
11711
|
+
if (!name) {
|
|
11712
|
+
throw new NhnCloudCliError("\uC778\uC99D\uC11C \uC774\uB984\uC774 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
11713
|
+
}
|
|
11714
|
+
return name;
|
|
11715
|
+
}
|
|
11716
|
+
function parseKeyTypeOption(value) {
|
|
11717
|
+
if (value === void 0) return void 0;
|
|
11718
|
+
const found = Object.hasOwn(KEY_TYPES, value) ? KEY_TYPES[value] : void 0;
|
|
11719
|
+
if (!found) {
|
|
11720
|
+
throw new NhnCloudCliError(
|
|
11721
|
+
`--type\uC740 secret, symmetric-key, asymmetric-key \uC911 \uD558\uB098\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11722
|
+
EXIT_PARAM_ERROR
|
|
11723
|
+
);
|
|
11724
|
+
}
|
|
11725
|
+
return found;
|
|
11726
|
+
}
|
|
11727
|
+
function parseKeyStatusOption(value) {
|
|
11728
|
+
if (value === void 0) return void 0;
|
|
11729
|
+
if (value !== "active" && value !== "inactive") {
|
|
11730
|
+
throw new NhnCloudCliError(
|
|
11731
|
+
`--status\uB294 active \uB610\uB294 inactive\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
|
|
11732
|
+
EXIT_PARAM_ERROR
|
|
11733
|
+
);
|
|
11734
|
+
}
|
|
11735
|
+
return value;
|
|
11736
|
+
}
|
|
11737
|
+
function parseKeyNameOption(value) {
|
|
11738
|
+
if (value === void 0) return void 0;
|
|
11739
|
+
const trimmed = value.trim();
|
|
11740
|
+
if (!trimmed) {
|
|
11741
|
+
throw new NhnCloudCliError("--name\uC740 \uBE44\uC5B4 \uC788\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
11742
|
+
}
|
|
11743
|
+
if (trimmed.length > KEY_NAME_MAX_LENGTH) {
|
|
11744
|
+
throw new NhnCloudCliError(`--name\uC740 ${KEY_NAME_MAX_LENGTH}\uC790 \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4.`, EXIT_PARAM_ERROR);
|
|
11745
|
+
}
|
|
11746
|
+
return trimmed;
|
|
11747
|
+
}
|
|
11748
|
+
async function resolveSkmClient(opts) {
|
|
11749
|
+
const profileName = await resolveProfileName(opts.profile);
|
|
11750
|
+
const appKey = await resolveServiceAppKey(
|
|
11751
|
+
"skm",
|
|
11752
|
+
profileName,
|
|
11753
|
+
"Secure Key Manager appkey\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. nhncloud configure --skm-appkey <key>\uB85C \uC124\uC815\uD558\uC138\uC694."
|
|
11754
|
+
);
|
|
11755
|
+
const uak = await getUserAccessKey(profileName);
|
|
11756
|
+
const environment = await getProfileEnvironment(profileName);
|
|
11757
|
+
const accessToken = await getAccessToken(profileName, uak.id, uak.secret, false, environment);
|
|
11758
|
+
return { client: new SkmClient(accessToken, environment, appKey, opts.macAddress), profileName };
|
|
11759
|
+
}
|
|
11760
|
+
function maskAuthDetail(detail) {
|
|
11761
|
+
if (typeof detail.password !== "string") return detail;
|
|
11762
|
+
return { ...detail, password: "***" };
|
|
11763
|
+
}
|
|
11764
|
+
function formatCell(value) {
|
|
11765
|
+
if (value === null || value === void 0) return "-";
|
|
11766
|
+
return sanitizeForTerminal(String(value));
|
|
11767
|
+
}
|
|
11768
|
+
function printSkmValue(opts, value, raw) {
|
|
11769
|
+
if (opts.json) {
|
|
11770
|
+
printJson(raw);
|
|
11771
|
+
} else if (opts.quiet) {
|
|
11772
|
+
process.stdout.write(value + "\n");
|
|
11773
|
+
} else {
|
|
11774
|
+
process.stdout.write(sanitizeMultilineForTerminal(value) + "\n");
|
|
11775
|
+
}
|
|
11776
|
+
}
|
|
11777
|
+
async function resolveKeyStoreName(client, keyStoreId) {
|
|
11778
|
+
const keyStore = await client.getKeyStore(keyStoreId);
|
|
11779
|
+
return keyStore.name;
|
|
11780
|
+
}
|
|
11781
|
+
function outputSkmWriteResult(opts, result, ids) {
|
|
11782
|
+
output(opts, {
|
|
11783
|
+
headers: ["field", "value"],
|
|
11784
|
+
rows: Object.entries(result).map(([key, value]) => [key, formatCell(value)]),
|
|
11785
|
+
raw: result,
|
|
11786
|
+
ids
|
|
11787
|
+
});
|
|
11788
|
+
}
|
|
11789
|
+
function parseKeyVersionOption(value) {
|
|
11790
|
+
return parseNonNegativeIntegerOption(value, "--key-version");
|
|
11791
|
+
}
|
|
11792
|
+
async function withSkmSpinner(text, call) {
|
|
11793
|
+
startSpinner(text);
|
|
11794
|
+
let result;
|
|
11795
|
+
try {
|
|
11796
|
+
result = await call();
|
|
11797
|
+
} catch (err) {
|
|
11798
|
+
stopSpinner(false);
|
|
11799
|
+
throw err;
|
|
11800
|
+
}
|
|
11801
|
+
stopSpinner(true);
|
|
11802
|
+
return result;
|
|
11803
|
+
}
|
|
11804
|
+
|
|
11805
|
+
// src/commands/skm/confirm.ts
|
|
11806
|
+
var confirmCommand = withSkmOptions(
|
|
11807
|
+
new import_commander59.Command("confirm").description("SKM \uC11C\uBC84\uAC00 \uBCF8 \uD074\uB77C\uC774\uC5B8\uD2B8 IP, MAC \uD5E4\uB354\uC640 \uC778\uC99D\uC11C \uC0AC\uC6A9 \uC5EC\uBD80\uB97C \uC870\uD68C\uD55C\uB2E4")
|
|
11808
|
+
).action(async (_opts, command) => {
|
|
11809
|
+
const opts = command.optsWithGlobals();
|
|
11810
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
11811
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
11812
|
+
const info = await withSkmSpinner("SKM \uD074\uB77C\uC774\uC5B8\uD2B8 \uC815\uBCF4 \uC870\uD68C \uC911...", () => client.confirm());
|
|
11813
|
+
output(opts, {
|
|
11814
|
+
headers: ["field", "value"],
|
|
11815
|
+
rows: [
|
|
11816
|
+
["clientIp", formatCell(info.clientIp)],
|
|
11817
|
+
["clientMacHeader", formatCell(info.clientMacHeader)],
|
|
11818
|
+
["clientSentCertificate", formatCell(info.clientSentCertificate)]
|
|
11819
|
+
],
|
|
11820
|
+
raw: info,
|
|
11821
|
+
ids: [formatCell(info.clientIp)]
|
|
11822
|
+
});
|
|
11823
|
+
});
|
|
11824
|
+
|
|
11825
|
+
// src/commands/skm/keystore.ts
|
|
11826
|
+
var import_commander61 = require("commander");
|
|
11827
|
+
|
|
11828
|
+
// src/commands/skm/keystore-manage.ts
|
|
11829
|
+
var import_commander60 = require("commander");
|
|
11830
|
+
|
|
11831
|
+
// src/commands/skm/input.ts
|
|
11832
|
+
var import_node_fs10 = require("fs");
|
|
11833
|
+
var processStdin = {
|
|
11834
|
+
get isTTY() {
|
|
11835
|
+
return process.stdin.isTTY;
|
|
11836
|
+
},
|
|
11837
|
+
read: () => (0, import_node_fs10.readFileSync)(0)
|
|
11838
|
+
};
|
|
11839
|
+
function assertWithinLimit(size, spec) {
|
|
11840
|
+
if (size > spec.maxBytes) {
|
|
11841
|
+
throw new NhnCloudCliError(
|
|
11842
|
+
`${spec.label}\uAC00 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${size}\uBC14\uC774\uD2B8 (\uD55C\uB3C4 ${spec.maxBytes}\uBC14\uC774\uD2B8).`,
|
|
11843
|
+
EXIT_PARAM_ERROR
|
|
11844
|
+
);
|
|
11845
|
+
}
|
|
11846
|
+
}
|
|
11847
|
+
function readInputFile(file, spec) {
|
|
11848
|
+
let stat3;
|
|
11849
|
+
try {
|
|
11850
|
+
stat3 = (0, import_node_fs10.statSync)(file);
|
|
11851
|
+
} catch (e) {
|
|
11852
|
+
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
11853
|
+
throw new NhnCloudCliError(`${spec.label} \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${file} (${reason})`, EXIT_PARAM_ERROR);
|
|
11854
|
+
}
|
|
11855
|
+
if (!stat3.isFile()) {
|
|
11856
|
+
throw new NhnCloudCliError(`${spec.label} \uD30C\uC77C\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${file}`, EXIT_PARAM_ERROR);
|
|
11857
|
+
}
|
|
11858
|
+
assertWithinLimit(stat3.size, spec);
|
|
11859
|
+
return (0, import_node_fs10.readFileSync)(file);
|
|
11860
|
+
}
|
|
11861
|
+
function readStdin(stdin, spec) {
|
|
11862
|
+
try {
|
|
11863
|
+
return stdin.read();
|
|
11864
|
+
} catch (e) {
|
|
11865
|
+
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
11866
|
+
throw new NhnCloudCliError(`${spec.label}\uB97C \uD45C\uC900 \uC785\uB825\uC5D0\uC11C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (${reason}).`, EXIT_PARAM_ERROR);
|
|
11867
|
+
}
|
|
11868
|
+
}
|
|
11869
|
+
function readSkmInput(source, spec, stdin = processStdin) {
|
|
11870
|
+
const fileFlag = spec.fileFlag ?? "--file";
|
|
11871
|
+
if (source.text !== void 0 && source.file !== void 0) {
|
|
11872
|
+
throw new NhnCloudCliError(`${spec.textFlag}\uC640 ${fileFlag}\uC740 \uD568\uAED8 \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`, EXIT_PARAM_ERROR);
|
|
11873
|
+
}
|
|
11874
|
+
let input;
|
|
11875
|
+
if (source.text !== void 0) {
|
|
11876
|
+
input = Buffer.from(source.text, "utf-8");
|
|
11877
|
+
} else if (source.file !== void 0) {
|
|
11878
|
+
input = readInputFile(source.file, spec);
|
|
11879
|
+
} else if (!stdin.isTTY) {
|
|
11880
|
+
input = readStdin(stdin, spec);
|
|
11881
|
+
} else {
|
|
11882
|
+
throw new NhnCloudCliError(
|
|
11883
|
+
`${spec.label}\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. ${spec.textFlag} <\uAC12>, ${fileFlag} <\uACBD\uB85C>, \uD45C\uC900 \uC785\uB825(\uD30C\uC774\uD504) \uC911 \uD558\uB098\uB85C \uC804\uB2EC\uD558\uC138\uC694.`,
|
|
11884
|
+
EXIT_PARAM_ERROR
|
|
11885
|
+
);
|
|
11886
|
+
}
|
|
11887
|
+
assertWithinLimit(input.length, spec);
|
|
11888
|
+
if (input.length === 0) {
|
|
11889
|
+
throw new NhnCloudCliError(`${spec.label}\uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.`, EXIT_PARAM_ERROR);
|
|
11890
|
+
}
|
|
11891
|
+
return input;
|
|
11892
|
+
}
|
|
11893
|
+
function decodeUtf8Input(input, label, hint) {
|
|
11894
|
+
try {
|
|
11895
|
+
return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(input);
|
|
11896
|
+
} catch {
|
|
11897
|
+
throw new NhnCloudCliError(`${label}\uB294 UTF-8 \uD14D\uC2A4\uD2B8\uC5EC\uC57C \uD569\uB2C8\uB2E4. ${hint}`, EXIT_PARAM_ERROR);
|
|
11898
|
+
}
|
|
11899
|
+
}
|
|
11900
|
+
|
|
11901
|
+
// src/commands/skm/keystore-manage.ts
|
|
11902
|
+
var DESCRIPTION_MAX_LENGTH = 1e3;
|
|
11903
|
+
var PASSWORD_MAX_BYTES = 1024;
|
|
11904
|
+
var LOCKOUT_WARNING = "(\uC2E4\uD589 \uC704\uCE58\uAC00 \uD0A4\uB97C \uC4F0\uC9C0 \uBABB\uD558\uAC8C \uB420 \uC218 \uC788\uC74C, \uBA3C\uC800 skm confirm\uC73C\uB85C \uD655\uC778)";
|
|
11905
|
+
var createCommand11 = withSkmOptions(
|
|
11906
|
+
new import_commander60.Command("create").description("\uD0A4 \uC800\uC7A5\uC18C\uB97C \uB9CC\uB4E0\uB2E4").requiredOption("--name <name>", "\uD0A4 \uC800\uC7A5\uC18C \uC774\uB984 (100\uC790 \uC774\uD558)").requiredOption("--auth <list>", "\uC0AC\uC6A9\uD560 \uC778\uC99D (ipv4,mac,certificate \uC911 \uD558\uB098 \uC774\uC0C1\uC744 \uC27C\uD45C\uB85C)").option("--auth-mode <mode>", "\uC778\uC99D \uACB0\uD569 \uBC29\uC2DD (and|or)", "and").option("--description <text>", "\uD0A4 \uC800\uC7A5\uC18C \uC124\uBA85 (1000\uC790 \uC774\uD558)")
|
|
11907
|
+
).action(async (_opts, command) => {
|
|
11908
|
+
const opts = command.optsWithGlobals();
|
|
11909
|
+
const name = parseKeyNameOption(opts.name);
|
|
11910
|
+
const auths = parseAuthListOption(opts.auth);
|
|
11911
|
+
const authMode = parseAuthModeOption(opts.authMode);
|
|
11912
|
+
const description = parseDescriptionOption(opts.description, DESCRIPTION_MAX_LENGTH);
|
|
11913
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
11914
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
11915
|
+
const input = { name, ...auths, authMode };
|
|
11916
|
+
if (description !== void 0) input.description = description;
|
|
11917
|
+
const created = await withSkmSpinner(
|
|
11918
|
+
`SKM \uD0A4 \uC800\uC7A5\uC18C ${formatCell(name)} \uC0DD\uC131 \uC911...`,
|
|
11919
|
+
() => client.createKeyStore(input)
|
|
11920
|
+
);
|
|
11921
|
+
outputSkmWriteResult(opts, { ...created }, [String(created.keyStoreId)]);
|
|
11922
|
+
});
|
|
11923
|
+
var updateCommand4 = withSkmOptions(
|
|
11924
|
+
new import_commander60.Command("update").description(`\uD0A4 \uC800\uC7A5\uC18C\uB97C \uC218\uC815\uD55C\uB2E4. \uC8FC\uC9C0 \uC54A\uC740 \uD56D\uBAA9\uC740 \uD604\uC7AC \uAC12\uC744 \uC720\uC9C0\uD55C\uB2E4 ${LOCKOUT_WARNING}`).argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").requiredOption("--auth-mode <mode>", "\uC778\uC99D \uACB0\uD569 \uBC29\uC2DD (and|or). \uC870\uD68C \uC751\uB2F5\uC5D0 \uC5C6\uC5B4 \uB9E4\uBC88 \uC9C0\uC815\uD55C\uB2E4").option("--name <name>", "\uD0A4 \uC800\uC7A5\uC18C \uC774\uB984 (100\uC790 \uC774\uD558)").option("--description <text>", "\uD0A4 \uC800\uC7A5\uC18C \uC124\uBA85 (1000\uC790 \uC774\uD558)").option("--auth <list>", "\uC0AC\uC6A9\uD560 \uC778\uC99D (ipv4,mac,certificate \uC911 \uD558\uB098 \uC774\uC0C1\uC744 \uC27C\uD45C\uB85C)")
|
|
11925
|
+
).action(async (keyStoreId, _opts, command) => {
|
|
11926
|
+
const opts = command.optsWithGlobals();
|
|
11927
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
11928
|
+
const authMode = parseAuthModeOption(opts.authMode);
|
|
11929
|
+
const name = parseKeyNameOption(opts.name);
|
|
11930
|
+
const description = parseDescriptionOption(opts.description, DESCRIPTION_MAX_LENGTH);
|
|
11931
|
+
const auths = opts.auth === void 0 ? void 0 : parseAuthListOption(opts.auth);
|
|
11932
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
11933
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
11934
|
+
const current2 = await withSkmSpinner(`SKM \uD0A4 \uC800\uC7A5\uC18C ${parsedId} \uC870\uD68C \uC911...`, () => client.getKeyStore(parsedId));
|
|
11935
|
+
const currentDescription = typeof current2.description === "string" ? current2.description : void 0;
|
|
11936
|
+
const yesNo = (value) => value === "Y" ? "Y" : "N";
|
|
11937
|
+
const input = {
|
|
11938
|
+
name: name ?? current2.name,
|
|
11939
|
+
...auths ?? {
|
|
11940
|
+
ip4AuthUse: yesNo(current2.ip4AuthUse),
|
|
11941
|
+
macAuthUse: yesNo(current2.macAuthUse),
|
|
11942
|
+
certificateAuthUse: yesNo(current2.certificateAuthUse)
|
|
11943
|
+
},
|
|
11944
|
+
authMode
|
|
11945
|
+
};
|
|
11946
|
+
const nextDescription = description ?? currentDescription;
|
|
11947
|
+
if (nextDescription !== void 0) input.description = nextDescription;
|
|
11948
|
+
if (input.ip4AuthUse === "N" && input.macAuthUse === "N" && input.certificateAuthUse === "N") {
|
|
11949
|
+
throw new NhnCloudCliError("\uD0A4 \uC800\uC7A5\uC18C \uC778\uC99D\uC740 \uD558\uB098 \uC774\uC0C1 \uCF1C\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
11950
|
+
}
|
|
11951
|
+
await withSkmSpinner(`SKM \uD0A4 \uC800\uC7A5\uC18C ${parsedId} \uC218\uC815 \uC911...`, () => client.updateKeyStore(parsedId, input));
|
|
11952
|
+
outputSkmWriteResult(
|
|
11953
|
+
opts,
|
|
11954
|
+
{ operation: "keystore-update", status: "succeeded", keyStoreId: parsedId, ...input },
|
|
11955
|
+
[String(parsedId)]
|
|
11956
|
+
);
|
|
11957
|
+
});
|
|
11958
|
+
var deleteCommand9 = withSkmOptions(
|
|
11959
|
+
new import_commander60.Command("delete").description("\uD0A4 \uC800\uC7A5\uC18C\uB97C \uC0AD\uC81C(\uBE44\uD65C\uC131\uD654)\uD55C\uB2E4").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").option("--yes", "\uC0AD\uC81C \uD655\uC778")
|
|
11960
|
+
).action(async (keyStoreId, _opts, command) => {
|
|
11961
|
+
const opts = command.optsWithGlobals();
|
|
11962
|
+
requireYes(opts.yes, "\uD0A4 \uC800\uC7A5\uC18C \uC0AD\uC81C");
|
|
11963
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
11964
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
11965
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
11966
|
+
await withSkmSpinner(`SKM \uD0A4 \uC800\uC7A5\uC18C ${parsedId} \uC0AD\uC81C \uC911...`, () => client.deleteKeyStore(parsedId));
|
|
11967
|
+
outputSkmWriteResult(
|
|
11968
|
+
opts,
|
|
11969
|
+
{ operation: "keystore-delete", status: "succeeded", keyStoreId: parsedId },
|
|
11970
|
+
[String(parsedId)]
|
|
11971
|
+
);
|
|
11972
|
+
});
|
|
11973
|
+
function readCertificateOptions(opts) {
|
|
11974
|
+
if (opts.lifeTime === void 0) {
|
|
11975
|
+
throw new NhnCloudCliError("\uC778\uC99D\uC11C \uCD94\uAC00\uC5D0\uB294 --life-time\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
11976
|
+
}
|
|
11977
|
+
const lifeTime = parsePositiveIntegerOption(opts.lifeTime, "--life-time");
|
|
11978
|
+
const input = readSkmInput(
|
|
11979
|
+
{ text: opts.password, file: opts.passwordFile },
|
|
11980
|
+
{ textFlag: "--password", fileFlag: "--password-file", label: "\uC778\uC99D\uC11C \uBE44\uBC00\uBC88\uD638", maxBytes: PASSWORD_MAX_BYTES }
|
|
11981
|
+
);
|
|
11982
|
+
const password = decodeUtf8Input(input, "\uC778\uC99D\uC11C \uBE44\uBC00\uBC88\uD638", "\uD30C\uC77C \uC778\uCF54\uB529\uC744 \uD655\uC778\uD558\uC138\uC694.").replace(/\r?\n$/, "");
|
|
11983
|
+
if (!password) {
|
|
11984
|
+
throw new NhnCloudCliError("\uC778\uC99D\uC11C \uBE44\uBC00\uBC88\uD638\uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
11985
|
+
}
|
|
11986
|
+
return { lifeTime, password };
|
|
11987
|
+
}
|
|
11988
|
+
function rejectCertificateOptions(opts) {
|
|
11989
|
+
if (opts.lifeTime !== void 0 || opts.password !== void 0 || opts.passwordFile !== void 0) {
|
|
11990
|
+
throw new NhnCloudCliError("--life-time\uACFC --password\uB294 --type certificate\uC5D0\uC11C\uB9CC \uC501\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11993
|
+
function authAddedFields(added) {
|
|
11994
|
+
return { value: added.value, name: added.name, description: added.description };
|
|
11995
|
+
}
|
|
11996
|
+
var authAddCommand = withTypeOption(
|
|
11997
|
+
withSkmOptions(
|
|
11998
|
+
new import_commander60.Command("add").description("\uD0A4 \uC800\uC7A5\uC18C\uC5D0 \uC778\uC99D \uC815\uBCF4\uB97C \uCD94\uAC00\uD55C\uB2E4 (\uC778\uC99D\uC11C \uBE44\uBC00\uBC88\uD638\uB294 --password, --password-file, \uD45C\uC900 \uC785\uB825 \uC911 \uD558\uB098)").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").argument("<value>", "IPv4\xB7MAC \uAC12 \uB610\uB294 \uC778\uC99D\uC11C \uC774\uB984").option("--description <text>", "\uC778\uC99D \uC815\uBCF4 \uC124\uBA85 (1000\uC790 \uC774\uD558)").option("--life-time <days>", "\uC778\uC99D\uC11C \uC720\uD6A8 \uAE30\uAC04(\uC77C) (--type certificate \uC804\uC6A9, \uD544\uC218)").option("--password <pw>", "\uC778\uC99D\uC11C \uBE44\uBC00\uBC88\uD638 (--type certificate \uC804\uC6A9)").option("--password-file <path>", "\uC778\uC99D\uC11C \uBE44\uBC00\uBC88\uD638\uB97C \uC77D\uC744 \uD30C\uC77C (--type certificate \uC804\uC6A9)")
|
|
11999
|
+
)
|
|
12000
|
+
).action(async (keyStoreId, value, _opts, command) => {
|
|
12001
|
+
const opts = command.optsWithGlobals();
|
|
12002
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12003
|
+
const type = parseAuthTypeOption(opts.type);
|
|
12004
|
+
const parsedValue = parseAuthValue(type, value);
|
|
12005
|
+
const description = parseDescriptionOption(opts.description, DESCRIPTION_MAX_LENGTH);
|
|
12006
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12007
|
+
if (type !== "certificate") rejectCertificateOptions(opts);
|
|
12008
|
+
const target = type === "certificate" ? { type, ...readCertificateOptions(opts) } : { type };
|
|
12009
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12010
|
+
const added = await withSkmSpinner(`SKM ${type} \uC778\uC99D \uC815\uBCF4 ${formatCell(parsedValue)} \uCD94\uAC00 \uC911...`, async () => {
|
|
12011
|
+
const keyStoreName = await resolveKeyStoreName(client, parsedId);
|
|
12012
|
+
if (target.type === "certificate") {
|
|
12013
|
+
return client.addCertificate(keyStoreName, parsedValue, target.password, target.lifeTime, description);
|
|
12014
|
+
}
|
|
12015
|
+
return client.addAuth(target.type, keyStoreName, parsedValue, description);
|
|
12016
|
+
});
|
|
12017
|
+
outputSkmWriteResult(
|
|
12018
|
+
opts,
|
|
12019
|
+
{ operation: "auth-add", type, keyStoreId: parsedId, ...authAddedFields(added) },
|
|
12020
|
+
[formatCell(parsedValue)]
|
|
12021
|
+
);
|
|
12022
|
+
});
|
|
12023
|
+
var authDeleteCommand = withTypeOption(
|
|
12024
|
+
withSkmOptions(
|
|
12025
|
+
new import_commander60.Command("delete").description(`\uC778\uC99D \uC815\uBCF4 \uC0AD\uC81C\uB97C \uC608\uC57D\uD55C\uB2E4 (7\uC77C \uB4A4 \uC0AD\uC81C) ${LOCKOUT_WARNING}`).argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").argument("<value>", "IPv4\xB7MAC \uAC12 \uB610\uB294 \uC778\uC99D\uC11C \uC774\uB984").option("--yes", "\uC0AD\uC81C \uC608\uC57D \uD655\uC778")
|
|
12026
|
+
)
|
|
12027
|
+
).action(async (keyStoreId, value, _opts, command) => {
|
|
12028
|
+
const opts = command.optsWithGlobals();
|
|
12029
|
+
requireYes(opts.yes, "\uC778\uC99D \uC815\uBCF4 \uC0AD\uC81C \uC608\uC57D");
|
|
12030
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12031
|
+
const type = parseAuthTypeOption(opts.type);
|
|
12032
|
+
const parsedValue = parseAuthValue(type, value);
|
|
12033
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12034
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12035
|
+
const deletion = await withSkmSpinner(`SKM ${type} \uC778\uC99D \uC815\uBCF4 ${formatCell(parsedValue)} \uC0AD\uC81C \uC608\uC57D \uC911...`, async () => {
|
|
12036
|
+
const keyStoreName = await resolveKeyStoreName(client, parsedId);
|
|
12037
|
+
return client.scheduleAuthDeletion(type, keyStoreName, parsedValue);
|
|
12038
|
+
});
|
|
12039
|
+
outputSkmWriteResult(
|
|
12040
|
+
opts,
|
|
12041
|
+
{
|
|
12042
|
+
operation: "auth-delete-scheduled",
|
|
12043
|
+
type,
|
|
12044
|
+
keyStoreId: parsedId,
|
|
12045
|
+
value: deletion.value,
|
|
12046
|
+
name: deletion.name,
|
|
12047
|
+
deletionDateTime: deletion.deletionDateTime
|
|
12048
|
+
},
|
|
12049
|
+
[formatCell(parsedValue)]
|
|
12050
|
+
);
|
|
12051
|
+
});
|
|
12052
|
+
var authPurgeCommand = withTypeOption(
|
|
12053
|
+
withSkmOptions(
|
|
12054
|
+
new import_commander60.Command("purge").description(`\uC778\uC99D \uC815\uBCF4\uB97C \uC989\uC2DC \uC0AD\uC81C\uD55C\uB2E4 (\uC0AD\uC81C \uC608\uC57D\uB41C \uAC83\uB9CC, \uB418\uB3CC\uB9B4 \uC218 \uC5C6\uC74C) ${LOCKOUT_WARNING}`).argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").argument("<value>", "IPv4\xB7MAC \uAC12 \uB610\uB294 \uC778\uC99D\uC11C \uC774\uB984").option("--yes", "\uC989\uC2DC \uC0AD\uC81C \uD655\uC778")
|
|
12055
|
+
)
|
|
12056
|
+
).action(async (keyStoreId, value, _opts, command) => {
|
|
12057
|
+
const opts = command.optsWithGlobals();
|
|
12058
|
+
requireYes(opts.yes, "\uC778\uC99D \uC815\uBCF4 \uC989\uC2DC \uC0AD\uC81C");
|
|
12059
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12060
|
+
const type = parseAuthTypeOption(opts.type);
|
|
12061
|
+
const parsedValue = parseAuthValue(type, value);
|
|
12062
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12063
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12064
|
+
const deletion = await withSkmSpinner(`SKM ${type} \uC778\uC99D \uC815\uBCF4 ${formatCell(parsedValue)} \uC989\uC2DC \uC0AD\uC81C \uC911...`, async () => {
|
|
12065
|
+
const keyStoreName = await resolveKeyStoreName(client, parsedId);
|
|
12066
|
+
return client.deleteAuthNow(type, keyStoreName, parsedValue);
|
|
12067
|
+
});
|
|
12068
|
+
outputSkmWriteResult(
|
|
12069
|
+
opts,
|
|
12070
|
+
{
|
|
12071
|
+
operation: "auth-purge",
|
|
12072
|
+
type,
|
|
12073
|
+
keyStoreId: parsedId,
|
|
12074
|
+
value: deletion.value,
|
|
12075
|
+
name: deletion.name,
|
|
12076
|
+
deletionDateTime: deletion.deletionDateTime
|
|
12077
|
+
},
|
|
12078
|
+
[formatCell(parsedValue)]
|
|
12079
|
+
);
|
|
12080
|
+
});
|
|
12081
|
+
|
|
12082
|
+
// src/commands/skm/keystore.ts
|
|
12083
|
+
var KEYSTORE_FIELDS = [
|
|
12084
|
+
"keyStoreId",
|
|
12085
|
+
"name",
|
|
12086
|
+
"description",
|
|
12087
|
+
"ip4AuthUse",
|
|
12088
|
+
"macAuthUse",
|
|
12089
|
+
"certificateAuthUse",
|
|
12090
|
+
"creationUser",
|
|
12091
|
+
"creationDatetime",
|
|
12092
|
+
"lastChangeUser",
|
|
12093
|
+
"lastChangeDatetime"
|
|
12094
|
+
];
|
|
12095
|
+
var listCommand16 = withSkmOptions(new import_commander61.Command("list").description("\uD0A4 \uC800\uC7A5\uC18C \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)")).action(async (_opts, command) => {
|
|
12096
|
+
const opts = command.optsWithGlobals();
|
|
12097
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12098
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12099
|
+
const stores = await withSkmSpinner("SKM \uD0A4 \uC800\uC7A5\uC18C \uBAA9\uB85D \uC870\uD68C \uC911...", () => client.listKeyStores());
|
|
12100
|
+
output(opts, {
|
|
12101
|
+
headers: ["keyStoreId", "name", "ip4AuthUse", "macAuthUse", "certificateAuthUse", "lastChangeDatetime"],
|
|
12102
|
+
rows: stores.map((s) => [
|
|
12103
|
+
formatCell(s.keyStoreId),
|
|
12104
|
+
formatCell(s.name),
|
|
12105
|
+
formatCell(s.ip4AuthUse),
|
|
12106
|
+
formatCell(s.macAuthUse),
|
|
12107
|
+
formatCell(s.certificateAuthUse),
|
|
12108
|
+
formatCell(s.lastChangeDatetime)
|
|
12109
|
+
]),
|
|
12110
|
+
raw: stores,
|
|
12111
|
+
ids: stores.map((s) => String(s.keyStoreId))
|
|
12112
|
+
});
|
|
12113
|
+
});
|
|
12114
|
+
var getCommand11 = withSkmOptions(
|
|
12115
|
+
new import_commander61.Command("get").description("\uD0A4 \uC800\uC7A5\uC18C \uD55C \uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID")
|
|
12116
|
+
).action(async (keyStoreId, _opts, command) => {
|
|
12117
|
+
const opts = command.optsWithGlobals();
|
|
12118
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12119
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12120
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12121
|
+
const store = await withSkmSpinner(`SKM \uD0A4 \uC800\uC7A5\uC18C ${parsedId} \uC870\uD68C \uC911...`, () => client.getKeyStore(parsedId));
|
|
12122
|
+
output(opts, {
|
|
12123
|
+
headers: ["field", "value"],
|
|
12124
|
+
rows: KEYSTORE_FIELDS.map((field) => [field, formatCell(store[field])]),
|
|
12125
|
+
raw: store,
|
|
12126
|
+
ids: [String(store.keyStoreId)]
|
|
12127
|
+
});
|
|
12128
|
+
});
|
|
12129
|
+
var authListCommand = withTypeOption(
|
|
12130
|
+
withSkmOptions(
|
|
12131
|
+
new import_commander61.Command("list").description("\uD0A4 \uC800\uC7A5\uC18C \uC778\uC99D \uC815\uBCF4 \uAC12 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID")
|
|
12132
|
+
)
|
|
12133
|
+
).action(async (keyStoreId, _opts, command) => {
|
|
12134
|
+
const opts = command.optsWithGlobals();
|
|
12135
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12136
|
+
const type = parseAuthTypeOption(opts.type);
|
|
12137
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12138
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12139
|
+
const values = await withSkmSpinner(`SKM ${type} \uC778\uC99D \uC815\uBCF4 \uBAA9\uB85D \uC870\uD68C \uC911...`, () => client.listAuths(parsedId, type));
|
|
12140
|
+
output(opts, {
|
|
12141
|
+
headers: ["value"],
|
|
12142
|
+
rows: values.map((v) => [formatCell(v)]),
|
|
12143
|
+
raw: values,
|
|
12144
|
+
ids: values.map((v) => formatCell(v))
|
|
12145
|
+
});
|
|
12146
|
+
});
|
|
12147
|
+
var authGetCommand = withTypeOption(
|
|
12148
|
+
withSkmOptions(
|
|
12149
|
+
new import_commander61.Command("get").description("\uD0A4 \uC800\uC7A5\uC18C \uC778\uC99D \uC815\uBCF4 \uC0C1\uC138\uB97C \uC870\uD68C\uD55C\uB2E4 (\uC778\uC99D\uC11C \uBE44\uBC00\uBC88\uD638\uB294 \uAC00\uB9B0\uB2E4)").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").argument("<value>", "IPv4\xB7MAC \uAC12 \uB610\uB294 \uC778\uC99D\uC11C \uC774\uB984")
|
|
12150
|
+
)
|
|
12151
|
+
).action(async (keyStoreId, value, _opts, command) => {
|
|
12152
|
+
const opts = command.optsWithGlobals();
|
|
12153
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12154
|
+
const parsedValue = parseRequiredArgument(value, "value");
|
|
12155
|
+
const type = parseAuthTypeOption(opts.type);
|
|
12156
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12157
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12158
|
+
const details = await withSkmSpinner(
|
|
12159
|
+
`SKM ${type} \uC778\uC99D \uC815\uBCF4 \uC870\uD68C \uC911...`,
|
|
12160
|
+
() => client.getAuth(parsedId, type, parsedValue)
|
|
12161
|
+
);
|
|
12162
|
+
const masked = details.map(maskAuthDetail);
|
|
12163
|
+
const keys = masked.map((d) => formatCell(d.value ?? d.name));
|
|
12164
|
+
output(opts, {
|
|
12165
|
+
headers: ["value", "description", "expirationDate", "lastAccessDatetime", "deletionDatetime", "lastChangeDatetime"],
|
|
12166
|
+
rows: masked.map((d, i) => [
|
|
12167
|
+
keys[i] ?? "-",
|
|
12168
|
+
formatCell(d.description),
|
|
12169
|
+
formatCell(d.expirationDate),
|
|
12170
|
+
formatCell(d.lastAccessDatetime),
|
|
12171
|
+
formatCell(d.deletionDatetime),
|
|
12172
|
+
formatCell(d.lastChangeDatetime)
|
|
12173
|
+
]),
|
|
12174
|
+
raw: masked,
|
|
12175
|
+
ids: keys
|
|
12176
|
+
});
|
|
12177
|
+
});
|
|
12178
|
+
var authCommand = new import_commander61.Command("auth").description("\uD0A4 \uC800\uC7A5\uC18C IPv4\xB7MAC\xB7\uC778\uC99D\uC11C \uC778\uC99D \uC815\uBCF4 \uC870\uD68C\xB7\uAD00\uB9AC").addCommand(authListCommand).addCommand(authGetCommand).addCommand(authAddCommand).addCommand(authDeleteCommand).addCommand(authPurgeCommand);
|
|
12179
|
+
var keystoreCommand = new import_commander61.Command("keystore").description("SKM \uD0A4 \uC800\uC7A5\uC18C\uC640 \uC778\uC99D \uC815\uBCF4 \uC870\uD68C\xB7\uAD00\uB9AC").addCommand(listCommand16).addCommand(getCommand11).addCommand(createCommand11).addCommand(updateCommand4).addCommand(deleteCommand9).addCommand(authCommand);
|
|
12180
|
+
|
|
12181
|
+
// src/commands/skm/key.ts
|
|
12182
|
+
var import_commander63 = require("commander");
|
|
12183
|
+
|
|
12184
|
+
// src/commands/skm/key-manage.ts
|
|
12185
|
+
var import_commander62 = require("commander");
|
|
12186
|
+
var createCommand12 = withSkmOptions(
|
|
12187
|
+
new import_commander62.Command("create").description("\uD0A4 \uC800\uC7A5\uC18C\uC5D0 \uD0A4\uB97C \uB9CC\uB4E0\uB2E4 (\uAE30\uBC00 \uB370\uC774\uD130 \uAC12\uC740 --value, --file, \uD45C\uC900 \uC785\uB825 \uC911 \uD558\uB098)").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").requiredOption("--type <type>", "\uD0A4 \uC885\uB958 (secret|symmetric-key|asymmetric-key)").requiredOption("--name <name>", "\uD0A4 \uC774\uB984 (100\uC790 \uC774\uD558)").option("--description <text>", "\uD0A4 \uC124\uBA85").option("--value <value>", "\uAE30\uBC00 \uB370\uC774\uD130 \uAC12 (--type secret \uC804\uC6A9)").option("--file <path>", "\uAE30\uBC00 \uB370\uC774\uD130 \uAC12\uC744 \uC77D\uC744 \uD30C\uC77C (--type secret \uC804\uC6A9)")
|
|
12188
|
+
).action(async (keyStoreId, _opts, command) => {
|
|
12189
|
+
const opts = command.optsWithGlobals();
|
|
12190
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12191
|
+
const type = parseKeyTypeOption(opts.type);
|
|
12192
|
+
const name = parseKeyNameOption(opts.name);
|
|
12193
|
+
const description = opts.description?.trim() || void 0;
|
|
12194
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12195
|
+
let secretValue;
|
|
12196
|
+
if (type === "SECRET") {
|
|
12197
|
+
const input = readSkmInput(
|
|
12198
|
+
{ text: opts.value, file: opts.file },
|
|
12199
|
+
{ textFlag: "--value", label: "\uAE30\uBC00 \uB370\uC774\uD130", maxBytes: MAX_JSON_INPUT_BYTES }
|
|
12200
|
+
);
|
|
12201
|
+
secretValue = decodeUtf8Input(input, "\uAE30\uBC00 \uB370\uC774\uD130", "\uBC14\uC774\uB108\uB9AC\uB294 base64\uB85C \uC778\uCF54\uB529\uD574 \uC804\uB2EC\uD558\uC138\uC694.");
|
|
12202
|
+
} else if (opts.value !== void 0 || opts.file !== void 0) {
|
|
12203
|
+
throw new NhnCloudCliError("--value\uC640 --file\uC740 --type secret\uC5D0\uC11C\uB9CC \uC501\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
12204
|
+
}
|
|
12205
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12206
|
+
const created = await withSkmSpinner(`SKM \uD0A4 ${formatCell(name)} \uC0DD\uC131 \uC911...`, async () => {
|
|
12207
|
+
const keyStoreName = await resolveKeyStoreName(client, parsedId);
|
|
12208
|
+
if (secretValue !== void 0) {
|
|
12209
|
+
return client.createSecret(keyStoreName, name, description, secretValue);
|
|
12210
|
+
}
|
|
12211
|
+
if (type === "SYMMETRIC_KEY") {
|
|
12212
|
+
return client.createSymmetricKey(keyStoreName, name, description);
|
|
12213
|
+
}
|
|
12214
|
+
return client.createAsymmetricKey(keyStoreName, name, description);
|
|
12215
|
+
});
|
|
12216
|
+
outputSkmWriteResult(
|
|
12217
|
+
opts,
|
|
12218
|
+
{ keyId: created.keyId, keyStatus: created.keyStatus, keyStoreId: parsedId, name },
|
|
12219
|
+
[formatCell(created.keyId)]
|
|
12220
|
+
);
|
|
12221
|
+
});
|
|
12222
|
+
var deleteCommand10 = withSkmOptions(
|
|
12223
|
+
new import_commander62.Command("delete").description("\uD0A4 \uC0AD\uC81C\uB97C \uC608\uC57D\uD55C\uB2E4 (7\uC77C \uB4A4 \uC0AD\uC81C, \uADF8 \uC804\uC5D0\uB294 \uCF58\uC194\uC5D0\uC11C \uCDE8\uC18C \uAC00\uB2A5)").argument("<key-id>", "\uD0A4 ID").option("--yes", "\uC0AD\uC81C \uC608\uC57D \uD655\uC778")
|
|
12224
|
+
).action(async (keyId, _opts, command) => {
|
|
12225
|
+
const opts = command.optsWithGlobals();
|
|
12226
|
+
requireYes(opts.yes, "\uD0A4 \uC0AD\uC81C \uC608\uC57D");
|
|
12227
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12228
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12229
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12230
|
+
const deletion = await withSkmSpinner(
|
|
12231
|
+
`SKM \uD0A4 ${formatCell(parsedKeyId)} \uC0AD\uC81C \uC608\uC57D \uC911...`,
|
|
12232
|
+
() => client.scheduleKeyDeletion(parsedKeyId)
|
|
12233
|
+
);
|
|
12234
|
+
outputSkmWriteResult(
|
|
12235
|
+
opts,
|
|
12236
|
+
{
|
|
12237
|
+
operation: "key-delete-scheduled",
|
|
12238
|
+
status: "succeeded",
|
|
12239
|
+
keyId: deletion.keyId,
|
|
12240
|
+
deletionDateTime: deletion.deletionDateTime
|
|
12241
|
+
},
|
|
12242
|
+
[formatCell(deletion.keyId)]
|
|
12243
|
+
);
|
|
12244
|
+
});
|
|
12245
|
+
var purgeCommand = withSkmOptions(
|
|
12246
|
+
new import_commander62.Command("purge").description("\uD0A4\uB97C \uC989\uC2DC \uC0AD\uC81C\uD55C\uB2E4 (\uC0AD\uC81C \uC608\uC57D\uB41C \uD0A4\uB9CC, \uB418\uB3CC\uB9B4 \uC218 \uC5C6\uC74C)").argument("<key-id>", "\uD0A4 ID").option("--yes", "\uC989\uC2DC \uC0AD\uC81C \uD655\uC778")
|
|
12247
|
+
).action(async (keyId, _opts, command) => {
|
|
12248
|
+
const opts = command.optsWithGlobals();
|
|
12249
|
+
requireYes(opts.yes, "\uD0A4 \uC989\uC2DC \uC0AD\uC81C");
|
|
12250
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12251
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12252
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12253
|
+
const deletion = await withSkmSpinner(
|
|
12254
|
+
`SKM \uD0A4 ${formatCell(parsedKeyId)} \uC989\uC2DC \uC0AD\uC81C \uC911...`,
|
|
12255
|
+
() => client.deleteKeyNow(parsedKeyId)
|
|
12256
|
+
);
|
|
12257
|
+
outputSkmWriteResult(
|
|
12258
|
+
opts,
|
|
12259
|
+
{ operation: "key-purge", status: "succeeded", keyId: deletion.keyId, deletionDateTime: deletion.deletionDateTime },
|
|
12260
|
+
[formatCell(deletion.keyId)]
|
|
12261
|
+
);
|
|
12262
|
+
});
|
|
12263
|
+
|
|
12264
|
+
// src/commands/skm/key.ts
|
|
12265
|
+
var KEY_FIELDS = [
|
|
12266
|
+
"keyId",
|
|
12267
|
+
"name",
|
|
12268
|
+
"description",
|
|
12269
|
+
"keyType",
|
|
12270
|
+
"currentKeyValueVersion",
|
|
12271
|
+
"autoRotationPeriod",
|
|
12272
|
+
"nextAutoRotationDate",
|
|
12273
|
+
"lastAccessDatetime",
|
|
12274
|
+
"deletionDatetime",
|
|
12275
|
+
"creationUser",
|
|
12276
|
+
"creationDatetime",
|
|
12277
|
+
"lastChangeUser",
|
|
12278
|
+
"lastChangeDatetime"
|
|
12279
|
+
];
|
|
12280
|
+
var listCommand17 = withSkmOptions(
|
|
12281
|
+
new import_commander63.Command("list").description("\uD0A4 \uC800\uC7A5\uC18C\uC758 \uD0A4 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").option("--type <type>", "\uD0A4 \uC885\uB958 (secret|symmetric-key|asymmetric-key)").option("--name <name>", "\uD0A4 \uC774\uB984 \uD544\uD130 (100\uC790 \uC774\uD558)").option("--status <status>", "\uD0A4 \uC0C1\uD0DC \uD544\uD130 (active|inactive)")
|
|
12282
|
+
).action(async (keyStoreId, _opts, command) => {
|
|
12283
|
+
const opts = command.optsWithGlobals();
|
|
12284
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12285
|
+
const type = parseKeyTypeOption(opts.type);
|
|
12286
|
+
const name = parseKeyNameOption(opts.name);
|
|
12287
|
+
const status = parseKeyStatusOption(opts.status);
|
|
12288
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12289
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12290
|
+
const filter = {
|
|
12291
|
+
...type !== void 0 && { type },
|
|
12292
|
+
...name !== void 0 && { name },
|
|
12293
|
+
...status !== void 0 && { status }
|
|
12294
|
+
};
|
|
12295
|
+
const keys = await withSkmSpinner(
|
|
12296
|
+
`SKM \uD0A4 \uC800\uC7A5\uC18C ${parsedId} \uD0A4 \uBAA9\uB85D \uC870\uD68C \uC911...`,
|
|
12297
|
+
() => client.listKeys(parsedId, filter)
|
|
12298
|
+
);
|
|
12299
|
+
output(opts, {
|
|
12300
|
+
headers: ["keyId", "name", "keyType", "currentKeyValueVersion", "lastAccessDatetime", "deletionDatetime"],
|
|
12301
|
+
rows: keys.map((k) => [
|
|
12302
|
+
formatCell(k.keyId),
|
|
12303
|
+
formatCell(k.name),
|
|
12304
|
+
formatCell(k.keyType),
|
|
12305
|
+
formatCell(k.currentKeyValueVersion),
|
|
12306
|
+
formatCell(k.lastAccessDatetime),
|
|
12307
|
+
formatCell(k.deletionDatetime)
|
|
12308
|
+
]),
|
|
12309
|
+
raw: keys,
|
|
12310
|
+
ids: keys.map((k) => formatCell(k.keyId))
|
|
12311
|
+
});
|
|
12312
|
+
});
|
|
12313
|
+
var getCommand12 = withSkmOptions(
|
|
12314
|
+
new import_commander63.Command("get").description("\uD0A4 \uD55C \uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<keystore-id>", "\uD0A4 \uC800\uC7A5\uC18C ID").argument("<key-id>", "\uD0A4 ID")
|
|
12315
|
+
).action(async (keyStoreId, keyId, _opts, command) => {
|
|
12316
|
+
const opts = command.optsWithGlobals();
|
|
12317
|
+
const parsedId = parseKeyStoreId(keyStoreId);
|
|
12318
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12319
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12320
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12321
|
+
const key = await withSkmSpinner(
|
|
12322
|
+
`SKM \uD0A4 ${formatCell(parsedKeyId)} \uC870\uD68C \uC911...`,
|
|
12323
|
+
() => client.getKey(parsedId, parsedKeyId)
|
|
12324
|
+
);
|
|
12325
|
+
output(opts, {
|
|
12326
|
+
headers: ["field", "value"],
|
|
12327
|
+
rows: KEY_FIELDS.map((field) => [field, formatCell(key[field])]),
|
|
12328
|
+
raw: key,
|
|
12329
|
+
ids: [formatCell(key.keyId)]
|
|
12330
|
+
});
|
|
12331
|
+
});
|
|
12332
|
+
var keyCommand = new import_commander63.Command("key").description("SKM \uD0A4 \uC870\uD68C\uC640 \uAD00\uB9AC").addCommand(listCommand17).addCommand(getCommand12).addCommand(createCommand12).addCommand(deleteCommand10).addCommand(purgeCommand);
|
|
12333
|
+
|
|
12334
|
+
// src/commands/skm/secret.ts
|
|
12335
|
+
var import_commander64 = require("commander");
|
|
12336
|
+
var getCommand13 = withSkmOptions(
|
|
12337
|
+
new import_commander64.Command("get").description("\uAE30\uBC00 \uB370\uC774\uD130\uB97C \uC870\uD68C\uD55C\uB2E4 (\uC6D0\uBB38\uC744 stdout\uC5D0 \uCD9C\uB825)").argument("<key-id>", "\uD0A4 ID")
|
|
12338
|
+
).action(async (keyId, _opts, command) => {
|
|
12339
|
+
const opts = command.optsWithGlobals();
|
|
12340
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12341
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12342
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12343
|
+
const secret = await withSkmSpinner(
|
|
12344
|
+
`SKM \uAE30\uBC00 \uB370\uC774\uD130 ${formatCell(parsedKeyId)} \uC870\uD68C \uC911...`,
|
|
12345
|
+
() => client.getSecret(parsedKeyId)
|
|
12346
|
+
);
|
|
12347
|
+
printSkmValue(opts, secret, { secret });
|
|
12348
|
+
});
|
|
12349
|
+
var updateCommand5 = withSkmOptions(
|
|
12350
|
+
new import_commander64.Command("update").description("\uAE30\uBC00 \uB370\uC774\uD130 \uAC12\uC744 \uBC14\uAFBC\uB2E4 (\uAC12\uC740 --value, --file, \uD45C\uC900 \uC785\uB825 \uC911 \uD558\uB098)").argument("<key-id>", "\uD0A4 ID").option("--value <value>", "\uC0C8 \uAE30\uBC00 \uB370\uC774\uD130 \uAC12").option("--file <path>", "\uC0C8 \uAE30\uBC00 \uB370\uC774\uD130 \uAC12\uC744 \uC77D\uC744 \uD30C\uC77C")
|
|
12351
|
+
).action(async (keyId, _opts, command) => {
|
|
12352
|
+
const opts = command.optsWithGlobals();
|
|
12353
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12354
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12355
|
+
const input = readSkmInput(
|
|
12356
|
+
{ text: opts.value, file: opts.file },
|
|
12357
|
+
{ textFlag: "--value", label: "\uAE30\uBC00 \uB370\uC774\uD130", maxBytes: MAX_JSON_INPUT_BYTES }
|
|
12358
|
+
);
|
|
12359
|
+
const secretValue = decodeUtf8Input(input, "\uAE30\uBC00 \uB370\uC774\uD130", "\uBC14\uC774\uB108\uB9AC\uB294 base64\uB85C \uC778\uCF54\uB529\uD574 \uC804\uB2EC\uD558\uC138\uC694.");
|
|
12360
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12361
|
+
const updated = await withSkmSpinner(
|
|
12362
|
+
`SKM \uAE30\uBC00 \uB370\uC774\uD130 ${formatCell(parsedKeyId)} \uC218\uC815 \uC911...`,
|
|
12363
|
+
() => client.updateSecret(parsedKeyId, secretValue)
|
|
12364
|
+
);
|
|
12365
|
+
const { secretValue: _omitted, ...result } = updated;
|
|
12366
|
+
outputSkmWriteResult(opts, result, [formatCell(updated.keyId)]);
|
|
12367
|
+
});
|
|
12368
|
+
var secretCommand = new import_commander64.Command("secret").description("SKM \uAE30\uBC00 \uB370\uC774\uD130 \uC870\uD68C\uC640 \uC218\uC815").addCommand(getCommand13).addCommand(updateCommand5);
|
|
12369
|
+
|
|
12370
|
+
// src/commands/skm/symmetric-key.ts
|
|
12371
|
+
var import_commander65 = require("commander");
|
|
12372
|
+
var MAX_ENCRYPT_BYTES = 32768;
|
|
12373
|
+
var encryptCommand = withSkmOptions(
|
|
12374
|
+
new import_commander65.Command("encrypt").description("\uB300\uCE6D\uD0A4\uB85C \uB370\uC774\uD130\uB97C \uC554\uD638\uD654\uD55C\uB2E4 (--plaintext / --file / stdin, UTF-8 \uD14D\uC2A4\uD2B8 32KB \uC774\uD558)").argument("<key-id>", "\uD0A4 ID").option("--plaintext <text>", "\uC554\uD638\uD654\uD560 \uB370\uC774\uD130").option("--file <path>", "\uC554\uD638\uD654\uD560 \uB370\uC774\uD130\uB97C \uC77D\uC744 \uD30C\uC77C \uACBD\uB85C")
|
|
12375
|
+
).action(async (keyId, _opts, command) => {
|
|
12376
|
+
const opts = command.optsWithGlobals();
|
|
12377
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12378
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12379
|
+
const label = "\uC554\uD638\uD654\uD560 \uB370\uC774\uD130";
|
|
12380
|
+
const input = readSkmInput(
|
|
12381
|
+
{ text: opts.plaintext, file: opts.file },
|
|
12382
|
+
{ textFlag: "--plaintext", label, maxBytes: MAX_ENCRYPT_BYTES }
|
|
12383
|
+
);
|
|
12384
|
+
const plaintext = decodeUtf8Input(input, label, "\uBC14\uC774\uB108\uB9AC\uB294 base64\uB85C \uC778\uCF54\uB529\uD574 \uC804\uB2EC\uD558\uC138\uC694.");
|
|
12385
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12386
|
+
const body = await withSkmSpinner(
|
|
12387
|
+
`SKM \uB300\uCE6D\uD0A4 ${formatCell(parsedKeyId)}\uB85C \uC554\uD638\uD654 \uC911...`,
|
|
12388
|
+
() => client.encrypt(parsedKeyId, plaintext)
|
|
12389
|
+
);
|
|
12390
|
+
printSkmValue(opts, body.ciphertext, body);
|
|
12391
|
+
});
|
|
12392
|
+
var decryptCommand = withSkmOptions(
|
|
12393
|
+
new import_commander65.Command("decrypt").description("\uB300\uCE6D\uD0A4\uB85C \uC554\uD638\uBB38\uC744 \uBCF5\uD638\uD654\uD55C\uB2E4 (--ciphertext / --file / stdin, \uD3C9\uBB38\uC744 stdout\uC5D0 \uCD9C\uB825)").argument("<key-id>", "\uD0A4 ID").option("--ciphertext <text>", "\uBCF5\uD638\uD654\uD560 \uC554\uD638\uBB38 (base64)").option("--file <path>", "\uBCF5\uD638\uD654\uD560 \uC554\uD638\uBB38\uC744 \uC77D\uC744 \uD30C\uC77C \uACBD\uB85C")
|
|
12394
|
+
).action(async (keyId, _opts, command) => {
|
|
12395
|
+
const opts = command.optsWithGlobals();
|
|
12396
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12397
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12398
|
+
const label = "\uBCF5\uD638\uD654\uD560 \uC554\uD638\uBB38";
|
|
12399
|
+
const input = readSkmInput(
|
|
12400
|
+
{ text: opts.ciphertext, file: opts.file },
|
|
12401
|
+
{ textFlag: "--ciphertext", label, maxBytes: MAX_JSON_INPUT_BYTES }
|
|
12402
|
+
);
|
|
12403
|
+
const ciphertext = decodeUtf8Input(input, label, "\uC554\uD638\uBB38\uC740 base64 \uBB38\uC790\uC5F4\uC785\uB2C8\uB2E4.").trim();
|
|
12404
|
+
if (!ciphertext) {
|
|
12405
|
+
throw new NhnCloudCliError(`${label}\uC774 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.`, EXIT_PARAM_ERROR);
|
|
12406
|
+
}
|
|
12407
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12408
|
+
const body = await withSkmSpinner(
|
|
12409
|
+
`SKM \uB300\uCE6D\uD0A4 ${formatCell(parsedKeyId)}\uB85C \uBCF5\uD638\uD654 \uC911...`,
|
|
12410
|
+
() => client.decrypt(parsedKeyId, ciphertext)
|
|
12411
|
+
);
|
|
12412
|
+
printSkmValue(opts, body.plaintext, body);
|
|
12413
|
+
});
|
|
12414
|
+
var getCommand14 = withSkmOptions(
|
|
12415
|
+
new import_commander65.Command("get").description("\uB300\uCE6D\uD0A4 \uC6D0\uBB38\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC6D0\uBB38\uC744 stdout\uC5D0 \uCD9C\uB825)").argument("<key-id>", "\uD0A4 ID").option("--key-version <n>", "\uC870\uD68C\uD560 \uD0A4 \uBC84\uC804 (0 \uC774\uC0C1, \uC0DD\uB7B5\uD558\uBA74 \uBC84\uC804\uC744 \uC9C0\uC815\uD558\uC9C0 \uC54A\uACE0 \uC694\uCCAD)")
|
|
12416
|
+
).action(async (keyId, _opts, command) => {
|
|
12417
|
+
const opts = command.optsWithGlobals();
|
|
12418
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12419
|
+
const keyVersion = parseKeyVersionOption(opts.keyVersion);
|
|
12420
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12421
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12422
|
+
const body = await withSkmSpinner(
|
|
12423
|
+
`SKM \uB300\uCE6D\uD0A4 ${formatCell(parsedKeyId)} \uC870\uD68C \uC911...`,
|
|
12424
|
+
() => client.getSymmetricKey(parsedKeyId, keyVersion)
|
|
12425
|
+
);
|
|
12426
|
+
printSkmValue(opts, body.symmetricKey, body);
|
|
12427
|
+
});
|
|
12428
|
+
var createLocalKeyCommand = withSkmOptions(
|
|
12429
|
+
new import_commander65.Command("create-local-key").description("\uB85C\uCEEC \uC554\uD638\uD654\uC5D0 \uC4F8 \uB370\uC774\uD130 \uD0A4\uB97C \uB9CC\uB4E0\uB2E4 (\uD3C9\uBB38 \uD0A4\uB294 \uC774 \uC751\uB2F5\uC5D0\uC11C\uB9CC \uBC1B\uC744 \uC218 \uC788\uB2E4)").argument("<key-id>", "\uD0A4 ID")
|
|
12430
|
+
).action(async (keyId, _opts, command) => {
|
|
12431
|
+
const opts = command.optsWithGlobals();
|
|
12432
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12433
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12434
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12435
|
+
const body = await withSkmSpinner(
|
|
12436
|
+
`SKM \uB300\uCE6D\uD0A4 ${formatCell(parsedKeyId)}\uB85C \uB85C\uCEEC \uD0A4 \uC0DD\uC131 \uC911...`,
|
|
12437
|
+
() => client.createLocalKey(parsedKeyId)
|
|
12438
|
+
);
|
|
12439
|
+
output(opts, {
|
|
12440
|
+
headers: ["field", "value"],
|
|
12441
|
+
rows: [
|
|
12442
|
+
["localKeyPlaintext", formatCell(body.localKeyPlaintext)],
|
|
12443
|
+
["localKeyCiphertext", formatCell(body.localKeyCiphertext)],
|
|
12444
|
+
["keyVersion", formatCell(body.keyVersion)]
|
|
12445
|
+
],
|
|
12446
|
+
raw: body,
|
|
12447
|
+
ids: [body.localKeyPlaintext, body.localKeyCiphertext]
|
|
12448
|
+
});
|
|
12449
|
+
});
|
|
12450
|
+
var symmetricKeyCommand = new import_commander65.Command("symmetric-key").description("SKM \uB300\uCE6D\uD0A4 \uC554\uBCF5\uD638\uD654\uC640 \uD0A4 \uC870\uD68C").addCommand(encryptCommand).addCommand(decryptCommand).addCommand(getCommand14).addCommand(createLocalKeyCommand);
|
|
12451
|
+
|
|
12452
|
+
// src/commands/skm/asymmetric-key.ts
|
|
12453
|
+
var import_commander66 = require("commander");
|
|
12454
|
+
var MAX_SIGN_BYTES = 245;
|
|
12455
|
+
var MAX_STANDARD_SIGN_BYTES = 65536;
|
|
12456
|
+
function readSignPayload(opts, label) {
|
|
12457
|
+
const input = readSkmInput(
|
|
12458
|
+
{ text: opts.plaintext, file: opts.file },
|
|
12459
|
+
{ textFlag: "--plaintext", label, maxBytes: opts.standard ? MAX_STANDARD_SIGN_BYTES : MAX_SIGN_BYTES }
|
|
12460
|
+
);
|
|
12461
|
+
if (opts.standard) return input.toString("base64");
|
|
12462
|
+
return decodeUtf8Input(input, label, "\uBC14\uC774\uB108\uB9AC\uB294 --standard\uB85C \uC11C\uBA85\uD558\uC138\uC694.");
|
|
12463
|
+
}
|
|
12464
|
+
function withSignInputOptions(command) {
|
|
12465
|
+
return command.argument("<key-id>", "\uD0A4 ID").option("--plaintext <text>", "\uB370\uC774\uD130 (\uBBF8\uC9C0\uC815 \uC2DC --file \uB610\uB294 stdin)").option("--file <path>", "\uB370\uC774\uD130\uB97C \uC77D\uC744 \uD30C\uC77C \uACBD\uB85C").option("--standard", "\uD45C\uC900 \uC2A4\uD0B4(RSASSA-PSS)\uC73C\uB85C \uCC98\uB9AC\uD55C\uB2E4 (\uBC14\uC774\uB108\uB9AC \uAC00\uB2A5, 64KB \uC774\uD558)");
|
|
12466
|
+
}
|
|
12467
|
+
var signCommand = withSkmOptions(
|
|
12468
|
+
withSignInputOptions(
|
|
12469
|
+
new import_commander66.Command("sign").description("\uBE44\uB300\uCE6D\uD0A4\uB85C \uB370\uC774\uD130\uC5D0 \uC11C\uBA85\uD55C\uB2E4 (\uC77C\uBC18 \uC11C\uBA85\uC740 UTF-8 \uD14D\uC2A4\uD2B8 245\uBC14\uC774\uD2B8 \uC774\uD558)")
|
|
12470
|
+
)
|
|
12471
|
+
).action(async (keyId, _opts, command) => {
|
|
12472
|
+
const opts = command.optsWithGlobals();
|
|
12473
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12474
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12475
|
+
const payload = readSignPayload(opts, "\uC11C\uBA85\uD560 \uB370\uC774\uD130");
|
|
12476
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12477
|
+
const body = await withSkmSpinner(
|
|
12478
|
+
`SKM \uBE44\uB300\uCE6D\uD0A4 ${formatCell(parsedKeyId)}\uB85C \uC11C\uBA85 \uC911...`,
|
|
12479
|
+
() => opts.standard ? client.signStandard(parsedKeyId, payload) : client.sign(parsedKeyId, payload)
|
|
12480
|
+
);
|
|
12481
|
+
printSkmValue(opts, body.signature, body);
|
|
12482
|
+
});
|
|
12483
|
+
var verifyCommand = withSkmOptions(
|
|
12484
|
+
withSignInputOptions(
|
|
12485
|
+
new import_commander66.Command("verify").description("\uBE44\uB300\uCE6D\uD0A4\uB85C \uC11C\uBA85\uC744 \uAC80\uC99D\uD55C\uB2E4 (\uAC80\uC99D \uC2E4\uD328\uB294 \uC885\uB8CC \uCF54\uB4DC 1)")
|
|
12486
|
+
).requiredOption("--signature <sig>", "\uAC80\uC99D\uD560 \uC11C\uBA85\uAC12 (base64)").option("--key-version <n>", "\uC11C\uBA85\uD55C \uD0A4 \uBC84\uC804 (--standard \uAC80\uC99D\uC5D0 \uD544\uC218)")
|
|
12487
|
+
).action(async (keyId, _opts, command) => {
|
|
12488
|
+
const opts = command.optsWithGlobals();
|
|
12489
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12490
|
+
const signature = opts.signature.trim();
|
|
12491
|
+
if (!signature) {
|
|
12492
|
+
throw new NhnCloudCliError("--signature\uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
12493
|
+
}
|
|
12494
|
+
const keyVersion = parseKeyVersionOption(opts.keyVersion);
|
|
12495
|
+
if (opts.standard && keyVersion === void 0) {
|
|
12496
|
+
throw new NhnCloudCliError("--standard \uAC80\uC99D\uC5D0\uB294 --key-version\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
12497
|
+
}
|
|
12498
|
+
if (!opts.standard && keyVersion !== void 0) {
|
|
12499
|
+
throw new NhnCloudCliError("--key-version\uC740 --standard\uC640 \uD568\uAED8 \uC9C0\uC815\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
|
|
12500
|
+
}
|
|
12501
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12502
|
+
const payload = readSignPayload(opts, "\uAC80\uC99D\uD560 \uB370\uC774\uD130");
|
|
12503
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12504
|
+
const body = await withSkmSpinner(
|
|
12505
|
+
`SKM \uBE44\uB300\uCE6D\uD0A4 ${formatCell(parsedKeyId)}\uB85C \uC11C\uBA85 \uAC80\uC99D \uC911...`,
|
|
12506
|
+
() => keyVersion !== void 0 ? client.verifyStandard(parsedKeyId, payload, signature, keyVersion) : client.verify(parsedKeyId, payload, signature)
|
|
12507
|
+
);
|
|
12508
|
+
if (opts.json) {
|
|
12509
|
+
printJson(body);
|
|
12510
|
+
} else if (!opts.quiet) {
|
|
12511
|
+
const verdict = body.result ? "\uAC80\uC99D \uC131\uACF5" : "\uAC80\uC99D \uC2E4\uD328";
|
|
12512
|
+
process.stdout.write(`${verdict} (keyVersion ${body.keyVersion})
|
|
12513
|
+
`);
|
|
12514
|
+
}
|
|
12515
|
+
if (!body.result) {
|
|
12516
|
+
throw new NhnCloudCliError("\uC11C\uBA85 \uAC80\uC99D\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.", EXIT_API_ERROR);
|
|
12517
|
+
}
|
|
12518
|
+
});
|
|
12519
|
+
function keyMaterialCommand(name, description, fetch, spinnerLabel) {
|
|
12520
|
+
return withSkmOptions(
|
|
12521
|
+
new import_commander66.Command(name).description(description).argument("<key-id>", "\uD0A4 ID").option("--key-version <n>", "\uC870\uD68C\uD560 \uD0A4 \uBC84\uC804 (0 \uC774\uC0C1, \uC0DD\uB7B5\uD558\uBA74 \uBC84\uC804\uC744 \uC9C0\uC815\uD558\uC9C0 \uC54A\uACE0 \uC694\uCCAD)")
|
|
12522
|
+
).action(async (keyId, _opts, command) => {
|
|
12523
|
+
const opts = command.optsWithGlobals();
|
|
12524
|
+
const parsedKeyId = parseRequiredArgument(keyId, "key-id");
|
|
12525
|
+
const keyVersion = parseKeyVersionOption(opts.keyVersion);
|
|
12526
|
+
const macAddress = parseMacAddressOption(opts.macAddress);
|
|
12527
|
+
const { client } = await resolveSkmClient({ profile: opts.profile, macAddress });
|
|
12528
|
+
const body = await withSkmSpinner(
|
|
12529
|
+
`SKM \uBE44\uB300\uCE6D\uD0A4 ${formatCell(parsedKeyId)} ${spinnerLabel} \uC870\uD68C \uC911...`,
|
|
12530
|
+
() => fetch(client, parsedKeyId, keyVersion)
|
|
12531
|
+
);
|
|
12532
|
+
printSkmValue(opts, body.standardEncodedKey ?? body.encodedKey, body);
|
|
12533
|
+
});
|
|
12534
|
+
}
|
|
12535
|
+
var publicKeyCommand = keyMaterialCommand(
|
|
12536
|
+
"public-key",
|
|
12537
|
+
"\uACF5\uAC1C\uD0A4\uB97C \uC870\uD68C\uD55C\uB2E4 (standardEncodedKey\uB97C, \uC5C6\uC73C\uBA74 encodedKey\uB97C stdout\uC5D0 \uCD9C\uB825)",
|
|
12538
|
+
(client, keyId, keyVersion) => client.getPublicKey(keyId, keyVersion),
|
|
12539
|
+
"\uACF5\uAC1C\uD0A4"
|
|
12540
|
+
);
|
|
12541
|
+
var privateKeyCommand = keyMaterialCommand(
|
|
12542
|
+
"private-key",
|
|
12543
|
+
"\uAC1C\uC778\uD0A4 \uC6D0\uBB38\uC744 \uC870\uD68C\uD55C\uB2E4 (standardEncodedKey\uB97C, \uC5C6\uC73C\uBA74 encodedKey\uB97C stdout\uC5D0 \uCD9C\uB825)",
|
|
12544
|
+
(client, keyId, keyVersion) => client.getPrivateKey(keyId, keyVersion),
|
|
12545
|
+
"\uAC1C\uC778\uD0A4"
|
|
12546
|
+
);
|
|
12547
|
+
var asymmetricKeyCommand = new import_commander66.Command("asymmetric-key").description("SKM \uBE44\uB300\uCE6D\uD0A4 \uC11C\uBA85\xB7\uAC80\uC99D\uACFC \uD0A4 \uC870\uD68C").addCommand(signCommand).addCommand(verifyCommand).addCommand(publicKeyCommand).addCommand(privateKeyCommand);
|
|
12548
|
+
|
|
12549
|
+
// src/commands/loadbalancer/list.ts
|
|
12550
|
+
var import_commander67 = require("commander");
|
|
12551
|
+
|
|
12552
|
+
// src/commands/loadbalancer/helpers.ts
|
|
12553
|
+
var import_node_net3 = require("net");
|
|
12554
|
+
|
|
12555
|
+
// src/services/loadbalancer/client.ts
|
|
12556
|
+
var import_ky17 = __toESM(require("ky"));
|
|
12557
|
+
|
|
12558
|
+
// src/services/loadbalancer/types.ts
|
|
12559
|
+
function isRecord5(value) {
|
|
12560
|
+
return typeof value === "object" && value !== null;
|
|
12561
|
+
}
|
|
11216
12562
|
function isNonEmptyString(value) {
|
|
11217
12563
|
return typeof value === "string" && value.length > 0;
|
|
11218
12564
|
}
|
|
@@ -11220,29 +12566,29 @@ function isIpAclAction(value) {
|
|
|
11220
12566
|
return value === "ALLOW" || value === "DENY";
|
|
11221
12567
|
}
|
|
11222
12568
|
function isLoadBalancerIpAclGroup(value) {
|
|
11223
|
-
return
|
|
12569
|
+
return isRecord5(value) && isNonEmptyString(value["ipacl_group_id"]);
|
|
11224
12570
|
}
|
|
11225
12571
|
function isIpAclGroupLoadBalancer(value) {
|
|
11226
|
-
return
|
|
12572
|
+
return isRecord5(value) && isNonEmptyString(value["loadbalancer_id"]);
|
|
11227
12573
|
}
|
|
11228
12574
|
function isLoadBalancer(value) {
|
|
11229
|
-
if (!
|
|
12575
|
+
if (!isRecord5(value)) return false;
|
|
11230
12576
|
return isNonEmptyString(value["id"]) && typeof value["name"] === "string" && typeof value["vip_address"] === "string" && typeof value["provisioning_status"] === "string" && typeof value["operating_status"] === "string" && (value["ipacl_group_action"] === null || isIpAclAction(value["ipacl_group_action"])) && Array.isArray(value["ipacl_groups"]) && value["ipacl_groups"].every(isLoadBalancerIpAclGroup);
|
|
11231
12577
|
}
|
|
11232
12578
|
function isIpAclGroup(value) {
|
|
11233
|
-
if (!
|
|
12579
|
+
if (!isRecord5(value)) return false;
|
|
11234
12580
|
return isNonEmptyString(value["id"]) && typeof value["name"] === "string" && isIpAclAction(value["action"]) && typeof value["ipacl_target_count"] === "string" && Array.isArray(value["loadbalancers"]) && value["loadbalancers"].every(isIpAclGroupLoadBalancer);
|
|
11235
12581
|
}
|
|
11236
12582
|
function isIpAclTarget(value) {
|
|
11237
|
-
if (!
|
|
12583
|
+
if (!isRecord5(value)) return false;
|
|
11238
12584
|
return isNonEmptyString(value["id"]) && typeof value["cidr_address"] === "string" && typeof value["description"] === "string" && isNonEmptyString(value["ipacl_group_id"]);
|
|
11239
12585
|
}
|
|
11240
12586
|
function isIpAclBinding(value) {
|
|
11241
|
-
return
|
|
12587
|
+
return isRecord5(value) && isNonEmptyString(value["loadbalancer_id"]) && isNonEmptyString(value["ipacl_group_id"]);
|
|
11242
12588
|
}
|
|
11243
12589
|
|
|
11244
12590
|
// src/services/loadbalancer/client.ts
|
|
11245
|
-
function
|
|
12591
|
+
function isRecord6(value) {
|
|
11246
12592
|
return typeof value === "object" && value !== null;
|
|
11247
12593
|
}
|
|
11248
12594
|
function requireNonEmptyId(id, label) {
|
|
@@ -11253,7 +12599,7 @@ function requireNonEmptyId(id, label) {
|
|
|
11253
12599
|
return normalized;
|
|
11254
12600
|
}
|
|
11255
12601
|
function readArrayField(response, key, itemGuard, missingKeyMessage, invalidItemMessage) {
|
|
11256
|
-
if (!
|
|
12602
|
+
if (!isRecord6(response) || !Array.isArray(response[key])) {
|
|
11257
12603
|
throw new NhnCloudCliError(missingKeyMessage, EXIT_API_ERROR);
|
|
11258
12604
|
}
|
|
11259
12605
|
const items = response[key];
|
|
@@ -11263,7 +12609,7 @@ function readArrayField(response, key, itemGuard, missingKeyMessage, invalidItem
|
|
|
11263
12609
|
return items;
|
|
11264
12610
|
}
|
|
11265
12611
|
function readObjectField(response, key, itemGuard, missingKeyMessage, invalidItemMessage) {
|
|
11266
|
-
if (!
|
|
12612
|
+
if (!isRecord6(response) || !(key in response)) {
|
|
11267
12613
|
throw new NhnCloudCliError(missingKeyMessage, EXIT_API_ERROR);
|
|
11268
12614
|
}
|
|
11269
12615
|
const item = response[key];
|
|
@@ -11404,7 +12750,7 @@ var LoadBalancerClient = class {
|
|
|
11404
12750
|
async getJson(path5, searchParams) {
|
|
11405
12751
|
const url = `${this.endpoint}${path5}`;
|
|
11406
12752
|
try {
|
|
11407
|
-
return await
|
|
12753
|
+
return await import_ky17.default.get(url, {
|
|
11408
12754
|
headers: this.authHeaders(),
|
|
11409
12755
|
searchParams,
|
|
11410
12756
|
retry: 0,
|
|
@@ -11417,7 +12763,7 @@ var LoadBalancerClient = class {
|
|
|
11417
12763
|
async postJson(path5, json) {
|
|
11418
12764
|
const url = `${this.endpoint}${path5}`;
|
|
11419
12765
|
try {
|
|
11420
|
-
return await
|
|
12766
|
+
return await import_ky17.default.post(url, {
|
|
11421
12767
|
headers: this.authHeaders(),
|
|
11422
12768
|
json,
|
|
11423
12769
|
retry: 0,
|
|
@@ -11430,7 +12776,7 @@ var LoadBalancerClient = class {
|
|
|
11430
12776
|
async putJson(path5, json) {
|
|
11431
12777
|
const url = `${this.endpoint}${path5}`;
|
|
11432
12778
|
try {
|
|
11433
|
-
return await
|
|
12779
|
+
return await import_ky17.default.put(url, {
|
|
11434
12780
|
headers: this.authHeaders(),
|
|
11435
12781
|
json,
|
|
11436
12782
|
retry: 0,
|
|
@@ -11443,7 +12789,7 @@ var LoadBalancerClient = class {
|
|
|
11443
12789
|
async deleteNoContent(path5) {
|
|
11444
12790
|
const url = `${this.endpoint}${path5}`;
|
|
11445
12791
|
try {
|
|
11446
|
-
await
|
|
12792
|
+
await import_ky17.default.delete(url, {
|
|
11447
12793
|
headers: this.authHeaders(),
|
|
11448
12794
|
retry: 0,
|
|
11449
12795
|
timeout: DEFAULT_TIMEOUT_MS
|
|
@@ -11481,7 +12827,7 @@ function parseIpOrCidr(value) {
|
|
|
11481
12827
|
const normalized = value.trim();
|
|
11482
12828
|
const parts = normalized.split("/");
|
|
11483
12829
|
const address = parts[0] ?? "";
|
|
11484
|
-
const version = (0,
|
|
12830
|
+
const version = (0, import_node_net3.isIP)(address);
|
|
11485
12831
|
if (version === 0 || parts.length > 2) {
|
|
11486
12832
|
throw new NhnCloudCliError(
|
|
11487
12833
|
`--cidr\uC740 IP \uC8FC\uC18C \uB610\uB294 CIDR\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4: ${JSON.stringify(value)}`,
|
|
@@ -11534,7 +12880,7 @@ async function resolveLoadBalancerClient(opts) {
|
|
|
11534
12880
|
}
|
|
11535
12881
|
|
|
11536
12882
|
// src/commands/loadbalancer/list.ts
|
|
11537
|
-
var
|
|
12883
|
+
var listCommand18 = new import_commander67.Command("list").description("Load Balancer \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
|
|
11538
12884
|
const opts = cmd.optsWithGlobals();
|
|
11539
12885
|
const { client } = await resolveLoadBalancerClient(opts);
|
|
11540
12886
|
startSpinner("Load Balancer \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
@@ -11572,8 +12918,8 @@ var listCommand16 = new import_commander59.Command("list").description("Load Bal
|
|
|
11572
12918
|
});
|
|
11573
12919
|
|
|
11574
12920
|
// src/commands/loadbalancer/get.ts
|
|
11575
|
-
var
|
|
11576
|
-
var
|
|
12921
|
+
var import_commander68 = require("commander");
|
|
12922
|
+
var getCommand15 = new import_commander68.Command("get").description("Load Balancer\uB97C \uC774\uB984 \uB610\uB294 UUID\uB85C \uC870\uD68C\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (loadBalancerInput, _opts, cmd) => {
|
|
11577
12923
|
const opts = cmd.optsWithGlobals();
|
|
11578
12924
|
const input = requireResourceInput(loadBalancerInput, "Load Balancer");
|
|
11579
12925
|
const { client } = await resolveLoadBalancerClient(opts);
|
|
@@ -11610,10 +12956,10 @@ var getCommand11 = new import_commander60.Command("get").description("Load Balan
|
|
|
11610
12956
|
});
|
|
11611
12957
|
|
|
11612
12958
|
// src/commands/loadbalancer/ipacl.ts
|
|
11613
|
-
var
|
|
12959
|
+
var import_commander70 = require("commander");
|
|
11614
12960
|
|
|
11615
12961
|
// src/commands/loadbalancer/target.ts
|
|
11616
|
-
var
|
|
12962
|
+
var import_commander69 = require("commander");
|
|
11617
12963
|
|
|
11618
12964
|
// src/commands/loadbalancer/rebind.ts
|
|
11619
12965
|
function shellQuote(value) {
|
|
@@ -11744,7 +13090,7 @@ function targetWriteResult(operation, target, rebind) {
|
|
|
11744
13090
|
rebind
|
|
11745
13091
|
};
|
|
11746
13092
|
}
|
|
11747
|
-
var
|
|
13093
|
+
var listCommand19 = new import_commander69.Command("list").description("IP ACL \uB300\uC0C1 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
|
|
11748
13094
|
const opts = cmd.optsWithGlobals();
|
|
11749
13095
|
const input = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
|
|
11750
13096
|
const { client } = await resolveLoadBalancerClient(opts);
|
|
@@ -11773,7 +13119,7 @@ var listCommand17 = new import_commander61.Command("list").description("IP ACL \
|
|
|
11773
13119
|
ids: targets.map((target) => target.id)
|
|
11774
13120
|
});
|
|
11775
13121
|
});
|
|
11776
|
-
var addCommand = new
|
|
13122
|
+
var addCommand = new import_commander69.Command("add").description("IP ACL \uB300\uC0C1\uC744 \uCD94\uAC00\uD558\uACE0 \uC5F0\uACB0\uB41C Load Balancer\uB97C \uC7AC\uBC14\uC778\uB529\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").requiredOption("--cidr <ip-or-cidr>", "\uCD94\uAC00\uD560 IP \uC8FC\uC18C \uB610\uB294 CIDR").option("--description <text>", "IP ACL \uB300\uC0C1 \uC124\uBA85").option("--no-rebind", "\uB300\uC0C1 \uCD94\uAC00 \uD6C4 Load Balancer \uC7AC\uBC14\uC778\uB529 \uC0DD\uB7B5").option("--yes", "\uB300\uC0C1 \uCD94\uAC00 \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
|
|
11777
13123
|
const opts = cmd.optsWithGlobals();
|
|
11778
13124
|
requireYes(opts.yes, "IP ACL \uB300\uC0C1 \uCD94\uAC00");
|
|
11779
13125
|
const parsedGroup = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
|
|
@@ -11810,7 +13156,7 @@ var addCommand = new import_commander61.Command("add").description("IP ACL \uB30
|
|
|
11810
13156
|
writeTargetWarnings(group, result);
|
|
11811
13157
|
if (result.status === "partial") process.exitCode = EXIT_API_ERROR;
|
|
11812
13158
|
});
|
|
11813
|
-
var removeCommand = new
|
|
13159
|
+
var removeCommand = new import_commander69.Command("remove").description("IP ACL \uB300\uC0C1\uC744 \uC0AD\uC81C\uD558\uACE0 \uC5F0\uACB0\uB41C Load Balancer\uB97C \uC7AC\uBC14\uC778\uB529\uD55C\uB2E4").argument("<target-id>", "\uC0AD\uC81C\uD560 IP ACL \uB300\uC0C1 UUID").option("--no-rebind", "\uB300\uC0C1 \uC0AD\uC81C \uD6C4 Load Balancer \uC7AC\uBC14\uC778\uB529 \uC0DD\uB7B5").option("--yes", "\uB300\uC0C1 \uC0AD\uC81C \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (targetInput, _opts, cmd) => {
|
|
11814
13160
|
const opts = cmd.optsWithGlobals();
|
|
11815
13161
|
requireYes(opts.yes, "IP ACL \uB300\uC0C1 \uC0AD\uC81C");
|
|
11816
13162
|
const parsedTargetId = requireResourceInput(targetInput, "IP ACL \uB300\uC0C1");
|
|
@@ -11841,13 +13187,13 @@ var removeCommand = new import_commander61.Command("remove").description("IP ACL
|
|
|
11841
13187
|
writeTargetWarnings(group, result);
|
|
11842
13188
|
if (result.status === "partial") process.exitCode = EXIT_API_ERROR;
|
|
11843
13189
|
});
|
|
11844
|
-
var targetCommand = new
|
|
11845
|
-
targetCommand.addCommand(
|
|
13190
|
+
var targetCommand = new import_commander69.Command("target").description("IP ACL \uB300\uC0C1 \uC870\uD68C\xB7\uAD00\uB9AC");
|
|
13191
|
+
targetCommand.addCommand(listCommand19);
|
|
11846
13192
|
targetCommand.addCommand(addCommand);
|
|
11847
13193
|
targetCommand.addCommand(removeCommand);
|
|
11848
13194
|
|
|
11849
13195
|
// src/commands/loadbalancer/ipacl.ts
|
|
11850
|
-
var
|
|
13196
|
+
var listCommand20 = new import_commander70.Command("list").description("IP ACL \uADF8\uB8F9 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (\uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
|
|
11851
13197
|
const opts = cmd.optsWithGlobals();
|
|
11852
13198
|
const { client } = await resolveLoadBalancerClient(opts);
|
|
11853
13199
|
startSpinner("IP ACL \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
@@ -11875,7 +13221,7 @@ var listCommand18 = new import_commander62.Command("list").description("IP ACL \
|
|
|
11875
13221
|
ids: groups.map((group) => group.id)
|
|
11876
13222
|
});
|
|
11877
13223
|
});
|
|
11878
|
-
var
|
|
13224
|
+
var getCommand16 = new import_commander70.Command("get").description("IP ACL \uADF8\uB8F9\uC744 \uC774\uB984 \uB610\uB294 UUID\uB85C \uC870\uD68C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
|
|
11879
13225
|
const opts = cmd.optsWithGlobals();
|
|
11880
13226
|
const input = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
|
|
11881
13227
|
const { client } = await resolveLoadBalancerClient(opts);
|
|
@@ -11908,7 +13254,7 @@ var getCommand12 = new import_commander62.Command("get").description("IP ACL \uA
|
|
|
11908
13254
|
ids: [group.id]
|
|
11909
13255
|
});
|
|
11910
13256
|
});
|
|
11911
|
-
var
|
|
13257
|
+
var createCommand13 = new import_commander70.Command("create").description("IP ACL \uADF8\uB8F9\uC744 \uC0DD\uC131\uD55C\uB2E4").requiredOption("--name <name>", "IP ACL \uADF8\uB8F9 \uC774\uB984").requiredOption("--action <ALLOW|DENY>", "IP \uC811\uADFC \uC81C\uC5B4 \uB3D9\uC791").option("--description <text>", "IP ACL \uADF8\uB8F9 \uC124\uBA85").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
|
|
11912
13258
|
const opts = cmd.optsWithGlobals();
|
|
11913
13259
|
const parsedName = requireResourceInput(opts.name ?? "", "IP ACL \uADF8\uB8F9");
|
|
11914
13260
|
const parsedAction = parseIpAclAction(opts.action ?? "");
|
|
@@ -11939,7 +13285,7 @@ var createCommand11 = new import_commander62.Command("create").description("IP A
|
|
|
11939
13285
|
ids: [group.id]
|
|
11940
13286
|
});
|
|
11941
13287
|
});
|
|
11942
|
-
var
|
|
13288
|
+
var deleteCommand11 = new import_commander70.Command("delete").description("IP ACL \uADF8\uB8F9\uACFC \uD558\uC704 \uB300\uC0C1\uC744 \uC0AD\uC81C\uD55C\uB2E4").argument("<group>", "IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID").option("--yes", "\uC0AD\uC81C\uC640 \uC5F0\uACB0 \uADDC\uCE59 \uC81C\uAC70 \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (groupInput, _opts, cmd) => {
|
|
11943
13289
|
const opts = cmd.optsWithGlobals();
|
|
11944
13290
|
const confirmedYes = requireYes(opts.yes, "IP ACL \uADF8\uB8F9 \uC0AD\uC81C");
|
|
11945
13291
|
const parsedGroup = requireResourceInput(groupInput, "IP ACL \uADF8\uB8F9");
|
|
@@ -11971,23 +13317,15 @@ var deleteCommand9 = new import_commander62.Command("delete").description("IP AC
|
|
|
11971
13317
|
ids: [groupId]
|
|
11972
13318
|
});
|
|
11973
13319
|
});
|
|
11974
|
-
var ipaclCommand = new
|
|
11975
|
-
ipaclCommand.addCommand(
|
|
11976
|
-
ipaclCommand.addCommand(
|
|
11977
|
-
ipaclCommand.addCommand(
|
|
11978
|
-
ipaclCommand.addCommand(
|
|
13320
|
+
var ipaclCommand = new import_commander70.Command("ipacl").description("IP ACL \uADF8\uB8F9\xB7\uB300\uC0C1 \uC870\uD68C");
|
|
13321
|
+
ipaclCommand.addCommand(listCommand20);
|
|
13322
|
+
ipaclCommand.addCommand(getCommand16);
|
|
13323
|
+
ipaclCommand.addCommand(createCommand13);
|
|
13324
|
+
ipaclCommand.addCommand(deleteCommand11);
|
|
11979
13325
|
ipaclCommand.addCommand(targetCommand);
|
|
11980
13326
|
|
|
11981
|
-
// src/commands/loadbalancer/help.ts
|
|
11982
|
-
function configureLoadBalancerHelp(command) {
|
|
11983
|
-
command.configureHelp({ showGlobalOptions: true });
|
|
11984
|
-
for (const child of command.commands) {
|
|
11985
|
-
configureLoadBalancerHelp(child);
|
|
11986
|
-
}
|
|
11987
|
-
}
|
|
11988
|
-
|
|
11989
13327
|
// src/commands/loadbalancer/binding.ts
|
|
11990
|
-
var
|
|
13328
|
+
var import_commander71 = require("commander");
|
|
11991
13329
|
function bindingResult(operation, loadBalancerId, groupIds) {
|
|
11992
13330
|
return {
|
|
11993
13331
|
operation,
|
|
@@ -12009,7 +13347,7 @@ function outputBindingResult(opts, result) {
|
|
|
12009
13347
|
ids: [result.loadbalancer_id]
|
|
12010
13348
|
});
|
|
12011
13349
|
}
|
|
12012
|
-
var setIpAclCommand2 = new
|
|
13350
|
+
var setIpAclCommand2 = new import_commander71.Command("set-ipacl").description("Load Balancer\uC758 IP ACL \uADF8\uB8F9 \uC5F0\uACB0\uC744 \uC804\uCCB4 \uAD50\uCCB4\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").requiredOption(
|
|
12013
13351
|
"--group <group>",
|
|
12014
13352
|
"\uC801\uC6A9\uD560 IP ACL \uADF8\uB8F9 \uC774\uB984 \uB610\uB294 UUID (\uBC18\uBCF5 \uAC00\uB2A5)",
|
|
12015
13353
|
collectOption
|
|
@@ -12049,7 +13387,7 @@ var setIpAclCommand2 = new import_commander63.Command("set-ipacl").description("
|
|
|
12049
13387
|
bindingResult("loadbalancer-set-ipacl", loadBalancerId, groupIds)
|
|
12050
13388
|
);
|
|
12051
13389
|
});
|
|
12052
|
-
var clearIpAclCommand = new
|
|
13390
|
+
var clearIpAclCommand = new import_commander71.Command("clear-ipacl").description("Load Balancer\uC758 \uBAA8\uB4E0 IP ACL \uADF8\uB8F9 \uC5F0\uACB0\uC744 \uD574\uC81C\uD55C\uB2E4").argument("<loadbalancer>", "Load Balancer \uC774\uB984 \uB610\uB294 UUID").option("--yes", "\uBAA8\uB4E0 IP ACL \uC5F0\uACB0 \uD574\uC81C \uD655\uC778").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (loadBalancerInput, _opts, cmd) => {
|
|
12053
13391
|
const opts = cmd.optsWithGlobals();
|
|
12054
13392
|
const confirmedYes = requireYes(opts.yes, "Load Balancer IP ACL \uC5F0\uACB0 \uD574\uC81C");
|
|
12055
13393
|
const parsedLoadBalancer = requireResourceInput(loadBalancerInput, "Load Balancer");
|
|
@@ -12140,8 +13478,8 @@ Agent workflow:
|
|
|
12140
13478
|
2. nhncloud ncs workload list --json
|
|
12141
13479
|
3. nhncloud ncs workload get <id> --json
|
|
12142
13480
|
`;
|
|
12143
|
-
var program = new
|
|
12144
|
-
program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version(
|
|
13481
|
+
var program = new import_commander72.Command();
|
|
13482
|
+
program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version(CLI_VERSION).option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "\uCD5C\uC18C \uCD9C\uB825 (\uC790\uB3D9\uD654\uC6A9)").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654").option("--request-timeout <sec>", "HTTP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3 (\uCD08, \uAE30\uBCF8 30, \uBC94\uC704 1~3600). NHNCLOUD_REQUEST_TIMEOUT \uB85C\uB3C4 \uC9C0\uC815").addHelpText("after", rootAgentHints);
|
|
12145
13483
|
program.hook("preAction", () => {
|
|
12146
13484
|
const opts = program.opts();
|
|
12147
13485
|
const rawTimeout = opts.requestTimeout ?? process.env["NHNCLOUD_REQUEST_TIMEOUT"];
|
|
@@ -12162,13 +13500,13 @@ program.hook("preAction", () => {
|
|
|
12162
13500
|
}
|
|
12163
13501
|
});
|
|
12164
13502
|
program.addCommand(configureCommand);
|
|
12165
|
-
var logncrashCommand = new
|
|
13503
|
+
var logncrashCommand = new import_commander72.Command("logncrash").description("Log & Crash \uAD00\uB828 \uBA85\uB839").addHelpText("after", logncrashAgentWorkflow);
|
|
12166
13504
|
logncrashCommand.addCommand(availableTokenCommand);
|
|
12167
13505
|
logncrashCommand.addCommand(searchCommand);
|
|
12168
13506
|
logncrashCommand.addCommand(sendCommand);
|
|
12169
13507
|
logncrashCommand.addCommand(exportCommand);
|
|
12170
13508
|
program.addCommand(logncrashCommand);
|
|
12171
|
-
var deployCommand2 = new
|
|
13509
|
+
var deployCommand2 = new import_commander72.Command("deploy").description("NHN Cloud Deploy \uAD00\uB828 \uBA85\uB839").addHelpText("after", deployAgentWorkflow);
|
|
12172
13510
|
deployCommand2.hook("preSubcommand", async () => {
|
|
12173
13511
|
await warnLegacyDeployTargets();
|
|
12174
13512
|
});
|
|
@@ -12182,7 +13520,7 @@ deployCommand2.addCommand(binariesCommand);
|
|
|
12182
13520
|
deployCommand2.addCommand(uploadCommand);
|
|
12183
13521
|
deployCommand2.addCommand(downloadCommand);
|
|
12184
13522
|
program.addCommand(deployCommand2);
|
|
12185
|
-
var instanceCommand = new
|
|
13523
|
+
var instanceCommand = new import_commander72.Command("instance").description("Compute \uC778\uC2A4\uD134\uC2A4 \uAD00\uB828 \uBA85\uB839").addHelpText("after", instanceAgentWorkflow);
|
|
12186
13524
|
instanceCommand.addCommand(listCommand);
|
|
12187
13525
|
instanceCommand.addCommand(flavorsCommand);
|
|
12188
13526
|
instanceCommand.addCommand(availabilityZonesCommand);
|
|
@@ -12202,60 +13540,68 @@ instanceCommand.addCommand(volumeCommand);
|
|
|
12202
13540
|
instanceCommand.addCommand(volumesCommand);
|
|
12203
13541
|
instanceCommand.addCommand(securityGroupCommand2);
|
|
12204
13542
|
program.addCommand(instanceCommand);
|
|
12205
|
-
var networkCommand = new
|
|
13543
|
+
var networkCommand = new import_commander72.Command("network").description("VPC\xB7\uC11C\uBE0C\uB137 \uC870\uD68C\uC640 \uBCF4\uC548\uADF8\uB8F9 \uAD00\uB9AC").addHelpText("after", networkAgentWorkflow);
|
|
12206
13544
|
networkCommand.addCommand(listCommand3);
|
|
12207
13545
|
networkCommand.addCommand(subnetCommand);
|
|
12208
13546
|
networkCommand.addCommand(securityGroupCommand);
|
|
12209
13547
|
program.addCommand(networkCommand);
|
|
12210
|
-
var volumeCommand2 = new
|
|
13548
|
+
var volumeCommand2 = new import_commander72.Command("volume").description("Block Storage \uBCFC\uB968 \uAD00\uB828 \uBA85\uB839").addHelpText("after", volumeAgentWorkflow);
|
|
12211
13549
|
volumeCommand2.addCommand(listCommand2);
|
|
12212
13550
|
volumeCommand2.addCommand(getCommand);
|
|
12213
13551
|
volumeCommand2.addCommand(createCommand);
|
|
12214
13552
|
program.addCommand(volumeCommand2);
|
|
12215
|
-
var floatingipCommand = new
|
|
13553
|
+
var floatingipCommand = new import_commander72.Command("floatingip").description(
|
|
12216
13554
|
"Floating IP(\uC778\uC2A4\uD134\uC2A4 \uACF5\uC778 IP) \uAD00\uB9AC"
|
|
12217
13555
|
).addHelpText("after", floatingIpAgentWorkflow);
|
|
12218
13556
|
floatingipCommand.addCommand(listCommand6);
|
|
12219
13557
|
floatingipCommand.addCommand(createCommand4);
|
|
12220
13558
|
floatingipCommand.addCommand(deleteCommand3);
|
|
12221
13559
|
program.addCommand(floatingipCommand);
|
|
12222
|
-
var loadbalancerCommand = new
|
|
12223
|
-
loadbalancerCommand.addCommand(
|
|
12224
|
-
loadbalancerCommand.addCommand(
|
|
13560
|
+
var loadbalancerCommand = new import_commander72.Command("loadbalancer").description("Load Balancer\xB7IP ACL \uC870\uD68C\xB7\uAD00\uB9AC").addHelpText("after", loadbalancerAgentWorkflow);
|
|
13561
|
+
loadbalancerCommand.addCommand(listCommand18);
|
|
13562
|
+
loadbalancerCommand.addCommand(getCommand15);
|
|
12225
13563
|
loadbalancerCommand.addCommand(ipaclCommand);
|
|
12226
13564
|
loadbalancerCommand.addCommand(setIpAclCommand2);
|
|
12227
13565
|
loadbalancerCommand.addCommand(clearIpAclCommand);
|
|
12228
|
-
configureLoadBalancerHelp(loadbalancerCommand);
|
|
12229
13566
|
program.addCommand(loadbalancerCommand);
|
|
12230
|
-
var ncrCommand = new
|
|
13567
|
+
var ncrCommand = new import_commander72.Command("ncr").description("NHN Container Registry \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncrAgentWorkflow);
|
|
12231
13568
|
ncrCommand.addCommand(listCommand7);
|
|
12232
13569
|
ncrCommand.addCommand(getCommand5);
|
|
12233
13570
|
ncrCommand.addCommand(imagesCommand2);
|
|
12234
13571
|
ncrCommand.addCommand(tagsCommand);
|
|
12235
13572
|
program.addCommand(ncrCommand);
|
|
12236
|
-
var nksCommand = new
|
|
13573
|
+
var nksCommand = new import_commander72.Command("nks").description("NHN Kubernetes Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", nksAgentWorkflow);
|
|
12237
13574
|
nksCommand.addCommand(supportsCommand);
|
|
12238
13575
|
nksCommand.addCommand(clusterCommand);
|
|
12239
13576
|
nksCommand.addCommand(nodegroupCommand);
|
|
12240
13577
|
nksCommand.addCommand(addonTypeCommand);
|
|
12241
13578
|
nksCommand.addCommand(addonCommand);
|
|
12242
13579
|
program.addCommand(nksCommand);
|
|
12243
|
-
var ncsCommand = new
|
|
13580
|
+
var ncsCommand = new import_commander72.Command("ncs").description("NHN Container Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncsAgentWorkflow);
|
|
12244
13581
|
ncsCommand.addCommand(templateCommand);
|
|
12245
13582
|
ncsCommand.addCommand(workloadCommand);
|
|
12246
13583
|
ncsCommand.addCommand(malwareCommand);
|
|
12247
13584
|
program.addCommand(ncsCommand);
|
|
12248
|
-
var apiGatewayCommand = new
|
|
13585
|
+
var apiGatewayCommand = new import_commander72.Command("apigateway").description("NHN API Gateway \uC870\uD68C \uBA85\uB839");
|
|
12249
13586
|
apiGatewayCommand.addCommand(serviceCommand);
|
|
12250
13587
|
apiGatewayCommand.addCommand(resourceCommand);
|
|
12251
13588
|
apiGatewayCommand.addCommand(stageCommand);
|
|
12252
13589
|
program.addCommand(apiGatewayCommand);
|
|
13590
|
+
var skmCommand = new import_commander72.Command("skm").description("NHN Secure Key Manager \uD0A4 \uC800\uC7A5\uC18C\xB7\uD0A4 \uAD00\uB9AC\uC640 \uAE30\uBC00 \uB370\uC774\uD130\xB7\uC554\uBCF5\uD638\uD654\xB7\uC11C\uBA85 \uBA85\uB839");
|
|
13591
|
+
skmCommand.addCommand(confirmCommand);
|
|
13592
|
+
skmCommand.addCommand(keystoreCommand);
|
|
13593
|
+
skmCommand.addCommand(keyCommand);
|
|
13594
|
+
skmCommand.addCommand(secretCommand);
|
|
13595
|
+
skmCommand.addCommand(symmetricKeyCommand);
|
|
13596
|
+
skmCommand.addCommand(asymmetricKeyCommand);
|
|
13597
|
+
program.addCommand(skmCommand);
|
|
12253
13598
|
program.addCommand(skillsCommand);
|
|
12254
13599
|
program.addCommand(doctorCommand);
|
|
12255
13600
|
program.addCommand(createCommandsCommand(program));
|
|
12256
13601
|
configureCommanderExitCodes(program);
|
|
13602
|
+
configureGlobalOptionsHelp(program);
|
|
12257
13603
|
program.parseAsync().catch((err) => {
|
|
12258
|
-
if (err instanceof
|
|
13604
|
+
if (err instanceof import_commander72.CommanderError) {
|
|
12259
13605
|
process.exit(err.exitCode);
|
|
12260
13606
|
}
|
|
12261
13607
|
const message = sanitizeMultilineForTerminal(
|