@bifos/nhncloud-cli 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -2
- package/dist/index.js +513 -80
- package/package.json +1 -1
- package/skills/nhncloud-cli/SKILL.md +119 -2
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_commander38 = require("commander");
|
|
28
28
|
var import_chalk12 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// src/utils/spinner.ts
|
|
@@ -495,6 +495,21 @@ var BLOCKSTORAGE_HOST = {
|
|
|
495
495
|
jp1: "jp1-api-block-storage-infrastructure.nhncloudservice.com"
|
|
496
496
|
};
|
|
497
497
|
var IAAS_REGIONS = Object.keys(INSTANCE_HOST).join(", ");
|
|
498
|
+
var NCR_HOST = {
|
|
499
|
+
kr1: "kr1-ncr.api.nhncloudservice.com",
|
|
500
|
+
kr2: "kr2-ncr.api.nhncloudservice.com",
|
|
501
|
+
kr3: "kr3-ncr.api.nhncloudservice.com"
|
|
502
|
+
};
|
|
503
|
+
function ncrHost(region) {
|
|
504
|
+
const host = NCR_HOST[region];
|
|
505
|
+
if (!host) {
|
|
506
|
+
throw new NhnCloudCliError(
|
|
507
|
+
`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 NCR region \uC785\uB2C8\uB2E4: "${region}". \uC0AC\uC6A9 \uAC00\uB2A5\uD55C region: ${Object.keys(NCR_HOST).join(", ")}`,
|
|
508
|
+
EXIT_PARAM_ERROR
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
return host;
|
|
512
|
+
}
|
|
498
513
|
function instanceHost(region) {
|
|
499
514
|
const host = INSTANCE_HOST[region];
|
|
500
515
|
if (!host) {
|
|
@@ -740,6 +755,96 @@ var LogncrashClient = class {
|
|
|
740
755
|
}
|
|
741
756
|
};
|
|
742
757
|
|
|
758
|
+
// src/services/ncr/client.ts
|
|
759
|
+
var import_ky5 = __toESM(require("ky"));
|
|
760
|
+
|
|
761
|
+
// src/services/ncr/types.ts
|
|
762
|
+
function isRegistry(val) {
|
|
763
|
+
if (typeof val !== "object" || val === null) return false;
|
|
764
|
+
const obj = val;
|
|
765
|
+
return typeof obj["name"] === "string";
|
|
766
|
+
}
|
|
767
|
+
function isRepository(val) {
|
|
768
|
+
if (typeof val !== "object" || val === null) return false;
|
|
769
|
+
const obj = val;
|
|
770
|
+
return typeof obj["name"] === "string";
|
|
771
|
+
}
|
|
772
|
+
function isArtifact(val) {
|
|
773
|
+
return typeof val === "object" && val !== null;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// src/services/ncr/client.ts
|
|
777
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
778
|
+
var NcrClient = class {
|
|
779
|
+
uakId;
|
|
780
|
+
uakSecret;
|
|
781
|
+
baseUrl;
|
|
782
|
+
constructor(uakId, uakSecret, region) {
|
|
783
|
+
this.uakId = uakId;
|
|
784
|
+
this.uakSecret = uakSecret;
|
|
785
|
+
this.baseUrl = `https://${ncrHost(region)}`;
|
|
786
|
+
}
|
|
787
|
+
authHeaders() {
|
|
788
|
+
return {
|
|
789
|
+
"X-TC-AUTHENTICATION-ID": this.uakId,
|
|
790
|
+
"X-TC-AUTHENTICATION-SECRET": this.uakSecret
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* 레지스트리 목록을 반환한다.
|
|
795
|
+
* GET /ncr/v2.0/appkeys/{appKey}/registries
|
|
796
|
+
* 응답: { header, registries: [...] } — body 가 아니라 named 필드.
|
|
797
|
+
*/
|
|
798
|
+
async listRegistries(appKey) {
|
|
799
|
+
const url = `${this.baseUrl}/ncr/v2.0/appkeys/${encodeURIComponent(appKey)}/registries`;
|
|
800
|
+
try {
|
|
801
|
+
const res = await import_ky5.default.get(url, {
|
|
802
|
+
headers: this.authHeaders(),
|
|
803
|
+
retry: 0,
|
|
804
|
+
timeout: DEFAULT_TIMEOUT_MS
|
|
805
|
+
}).json();
|
|
806
|
+
unwrapHeader(res);
|
|
807
|
+
if (!Array.isArray(res.registries)) {
|
|
808
|
+
if (res.registries === void 0) return [];
|
|
809
|
+
throw new NhnCloudCliError(
|
|
810
|
+
"NCR API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: registries \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
|
|
811
|
+
EXIT_API_ERROR
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
return res.registries.filter(isRegistry);
|
|
815
|
+
} catch (err) {
|
|
816
|
+
if (err instanceof NhnCloudCliError) throw err;
|
|
817
|
+
throw toNhnCloudCliError(err);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* 단일 레지스트리를 반환한다.
|
|
822
|
+
* GET /ncr/v2.0/appkeys/{appKey}/registries/{registryNameOrId}
|
|
823
|
+
* 응답: { header, registry: {...} } — body 가 아니라 named 필드.
|
|
824
|
+
*/
|
|
825
|
+
async getRegistry(appKey, registry) {
|
|
826
|
+
const url = `${this.baseUrl}/ncr/v2.0/appkeys/${encodeURIComponent(appKey)}/registries/${encodeURIComponent(registry)}`;
|
|
827
|
+
try {
|
|
828
|
+
const res = await import_ky5.default.get(url, {
|
|
829
|
+
headers: this.authHeaders(),
|
|
830
|
+
retry: 0,
|
|
831
|
+
timeout: DEFAULT_TIMEOUT_MS
|
|
832
|
+
}).json();
|
|
833
|
+
unwrapHeader(res);
|
|
834
|
+
if (res.registry && isRegistry(res.registry)) {
|
|
835
|
+
return res.registry;
|
|
836
|
+
}
|
|
837
|
+
throw new NhnCloudCliError(
|
|
838
|
+
"NCR API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: registry \uAC1D\uCCB4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
839
|
+
EXIT_API_ERROR
|
|
840
|
+
);
|
|
841
|
+
} catch (err) {
|
|
842
|
+
if (err instanceof NhnCloudCliError) throw err;
|
|
843
|
+
throw toNhnCloudCliError(err);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
|
|
743
848
|
// src/commands/configure-verify.ts
|
|
744
849
|
async function verifyUserAccessKey(uak) {
|
|
745
850
|
try {
|
|
@@ -763,6 +868,19 @@ async function verifyIaas(iaas) {
|
|
|
763
868
|
throw err;
|
|
764
869
|
}
|
|
765
870
|
}
|
|
871
|
+
async function verifyNcr(uak, appkey) {
|
|
872
|
+
if (!appkey) return false;
|
|
873
|
+
const client = new NcrClient(uak.id, uak.secret, "kr1");
|
|
874
|
+
try {
|
|
875
|
+
await client.listRegistries(appkey);
|
|
876
|
+
return true;
|
|
877
|
+
} catch (err) {
|
|
878
|
+
if (err instanceof NhnCloudCliError && err.exitCode === EXIT_AUTH_ERROR) {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
throw err;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
766
884
|
async function verifyLogncrash(cred) {
|
|
767
885
|
if (!cred.appkey || !cred.secret) return false;
|
|
768
886
|
const client = new LogncrashClient(cred.appkey, cred.secret);
|
|
@@ -786,7 +904,7 @@ async function verifyLogncrash(cred) {
|
|
|
786
904
|
}
|
|
787
905
|
|
|
788
906
|
// src/commands/configure.ts
|
|
789
|
-
async function saveAndVerify(profileName, uak, logncrash, iaas, doVerify) {
|
|
907
|
+
async function saveAndVerify(profileName, uak, logncrash, iaas, ncr, doVerify) {
|
|
790
908
|
if (doVerify) {
|
|
791
909
|
if (uak) {
|
|
792
910
|
const ok = await verifyUserAccessKey(uak);
|
|
@@ -821,6 +939,26 @@ async function saveAndVerify(profileName, uak, logncrash, iaas, doVerify) {
|
|
|
821
939
|
);
|
|
822
940
|
}
|
|
823
941
|
}
|
|
942
|
+
if (ncr) {
|
|
943
|
+
if (uak) {
|
|
944
|
+
const appkey = ncr.appkey ?? "";
|
|
945
|
+
const ok = await verifyNcr(uak, appkey);
|
|
946
|
+
if (ok) {
|
|
947
|
+
process.stderr.write(import_chalk.default.green(" \u2713 ncr \uC5F0\uACB0 \uC131\uACF5 (kr1)\n"));
|
|
948
|
+
} else {
|
|
949
|
+
throw new NhnCloudCliError(
|
|
950
|
+
"ncr \uC778\uC99D \uC2E4\uD328 \u2014 appkey \uB610\uB294 UAK \uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
951
|
+
EXIT_AUTH_ERROR
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
} else {
|
|
955
|
+
process.stderr.write(
|
|
956
|
+
import_chalk.default.yellow(
|
|
957
|
+
" \u26A0 ncr verify \uAC74\uB108\uB700 \u2014 \uC774\uBC88 \uC124\uC815\uC5D0 UAK \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. ncr \uBA85\uB839\uC740 \uACF5\uD1B5 UAK \uAC00 \uD544\uC694\uD558\uB2C8 \uBA3C\uC800 \uC124\uC815\uD558\uC138\uC694.\n"
|
|
958
|
+
)
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
824
962
|
}
|
|
825
963
|
if (uak) {
|
|
826
964
|
await setUserAccessKey(profileName, uak);
|
|
@@ -831,6 +969,9 @@ async function saveAndVerify(profileName, uak, logncrash, iaas, doVerify) {
|
|
|
831
969
|
if (iaas) {
|
|
832
970
|
await setIaasCredential(profileName, iaas);
|
|
833
971
|
}
|
|
972
|
+
if (ncr) {
|
|
973
|
+
await setServiceCredential(profileName, "ncr", ncr);
|
|
974
|
+
}
|
|
834
975
|
process.stderr.write(import_chalk.default.green(`
|
|
835
976
|
\u2713 profile "${profileName}" \uC124\uC815\uC774 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
|
836
977
|
`));
|
|
@@ -890,12 +1031,25 @@ async function runInteractive(opts) {
|
|
|
890
1031
|
});
|
|
891
1032
|
iaas = { tenantId, username: iaasUsername, password: iaasPassword, region };
|
|
892
1033
|
}
|
|
1034
|
+
let ncr;
|
|
1035
|
+
const setupNcr = await confirm({
|
|
1036
|
+
message: "ncr \uC790\uACA9\uC99D\uBA85\uB3C4 \uC124\uC815\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
1037
|
+
default: false
|
|
1038
|
+
});
|
|
1039
|
+
if (setupNcr) {
|
|
1040
|
+
process.stderr.write(import_chalk.default.gray("\n\u2014 ncr (Container Registry) \uC790\uACA9\uC99D\uBA85 \u2014\n"));
|
|
1041
|
+
const ncrAppkey = await input({
|
|
1042
|
+
message: "ncr appkey",
|
|
1043
|
+
validate: (v) => v.trim().length > 0 || "ncr appkey \uB97C \uC785\uB825\uD558\uC138\uC694"
|
|
1044
|
+
});
|
|
1045
|
+
ncr = { appkey: ncrAppkey.trim() };
|
|
1046
|
+
}
|
|
893
1047
|
if (opts.verify) {
|
|
894
1048
|
process.stderr.write(import_chalk.default.gray("\n\u2014 \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC911\u2026 \u2014\n"));
|
|
895
1049
|
}
|
|
896
1050
|
if (opts.verify) {
|
|
897
1051
|
try {
|
|
898
|
-
await saveAndVerify(profileName, uak, logncrash, iaas, true);
|
|
1052
|
+
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, true);
|
|
899
1053
|
} catch (err) {
|
|
900
1054
|
if (err instanceof NhnCloudCliError && err.exitCode === EXIT_AUTH_ERROR) {
|
|
901
1055
|
process.stderr.write(import_chalk.default.red(` \u2717 ${err.message}
|
|
@@ -908,13 +1062,13 @@ async function runInteractive(opts) {
|
|
|
908
1062
|
process.stderr.write(import_chalk.default.yellow("\uC800\uC7A5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
|
|
909
1063
|
return;
|
|
910
1064
|
}
|
|
911
|
-
await saveAndVerify(profileName, uak, logncrash, iaas, false);
|
|
1065
|
+
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, false);
|
|
912
1066
|
} else {
|
|
913
1067
|
throw err;
|
|
914
1068
|
}
|
|
915
1069
|
}
|
|
916
1070
|
} else {
|
|
917
|
-
await saveAndVerify(profileName, uak, logncrash, iaas, false);
|
|
1071
|
+
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, false);
|
|
918
1072
|
}
|
|
919
1073
|
}
|
|
920
1074
|
async function runNonInteractive(opts) {
|
|
@@ -930,22 +1084,23 @@ async function runNonInteractive(opts) {
|
|
|
930
1084
|
password: iaasPassword,
|
|
931
1085
|
region: opts.iaasRegion ?? "kr1"
|
|
932
1086
|
} : void 0;
|
|
933
|
-
|
|
1087
|
+
const ncr = opts.ncrAppkey?.trim() ? { appkey: opts.ncrAppkey.trim() } : void 0;
|
|
1088
|
+
if (!uak && !logncrash && !iaas && !ncr) {
|
|
934
1089
|
throw new NhnCloudCliError(
|
|
935
|
-
"\uBE44\uB300\uD654\uD615 \uBAA8\uB4DC: --uak-id + UAK secret, --logncrash-appkey + logncrash secret,\n
|
|
1090
|
+
"\uBE44\uB300\uD654\uD615 \uBAA8\uB4DC: --uak-id + UAK secret, --logncrash-appkey + logncrash secret,\n--iaas-tenant-id + --iaas-username + iaas password,\n\uB610\uB294 --ncr-appkey \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_LOGNCRASH_SECRET / NHNCLOUD_IAAS_PASSWORD.",
|
|
936
1091
|
EXIT_PARAM_ERROR
|
|
937
1092
|
);
|
|
938
1093
|
}
|
|
939
1094
|
if (opts.verify) {
|
|
940
1095
|
process.stderr.write(import_chalk.default.gray("\uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC911\u2026\n"));
|
|
941
1096
|
}
|
|
942
|
-
await saveAndVerify(profileName, uak, logncrash, iaas, opts.verify);
|
|
1097
|
+
await saveAndVerify(profileName, uak, logncrash, iaas, ncr, opts.verify);
|
|
943
1098
|
}
|
|
944
1099
|
var configureCommand = new import_commander.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>", "logncrash secret (\uBE44\uB300\uD654\uD615, env NHNCLOUD_LOGNCRASH_SECRET \uAD8C\uC7A5)").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(
|
|
945
1100
|
"--iaas-password <pass>",
|
|
946
1101
|
"iaas API \uBE44\uBC00\uBC88\uD638 (\uBE44\uB300\uD654\uD615, \uB178\uCD9C \uBC29\uC9C0\uB85C env NHNCLOUD_IAAS_PASSWORD \uAD8C\uC7A5)"
|
|
947
|
-
).option("--iaas-region <region>", "iaas region (\uAE30\uBCF8: kr1)", "kr1").option("--no-verify", "\uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC0DD\uB7B5").action(async (opts) => {
|
|
948
|
-
const hasFlag = opts.uakId || opts.uakSecret || opts.logncrashAppkey || opts.logncrashSecret || opts.iaasTenantId || opts.iaasUsername || opts.iaasPassword;
|
|
1102
|
+
).option("--iaas-region <region>", "iaas region (\uAE30\uBCF8: kr1)", "kr1").option("--ncr-appkey <key>", "ncr appkey (\uBE44\uB300\uD654\uD615)").option("--no-verify", "\uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC0DD\uB7B5").action(async (opts) => {
|
|
1103
|
+
const hasFlag = opts.uakId || opts.uakSecret || opts.logncrashAppkey || opts.logncrashSecret || opts.iaasTenantId || opts.iaasUsername || opts.iaasPassword || opts.ncrAppkey;
|
|
949
1104
|
try {
|
|
950
1105
|
if (hasFlag) {
|
|
951
1106
|
await runNonInteractive(opts);
|
|
@@ -1375,12 +1530,13 @@ async function scrollNextOrExpire(client, scrollKey) {
|
|
|
1375
1530
|
var import_commander5 = require("commander");
|
|
1376
1531
|
|
|
1377
1532
|
// src/services/deploy/client.ts
|
|
1378
|
-
var
|
|
1533
|
+
var import_ky6 = __toESM(require("ky"));
|
|
1379
1534
|
function isBinaryGroup(val) {
|
|
1380
1535
|
if (typeof val !== "object" || val === null) return false;
|
|
1381
1536
|
const obj = val;
|
|
1382
1537
|
const keyType = typeof obj["key"];
|
|
1383
|
-
|
|
1538
|
+
const descriptionType = typeof obj["description"];
|
|
1539
|
+
return (keyType === "number" || keyType === "string") && typeof obj["name"] === "string" && (descriptionType === "undefined" || descriptionType === "string" || obj["description"] === null);
|
|
1384
1540
|
}
|
|
1385
1541
|
function isBinary(val) {
|
|
1386
1542
|
if (typeof val !== "object" || val === null) return false;
|
|
@@ -1390,7 +1546,7 @@ function isBinary(val) {
|
|
|
1390
1546
|
return (binaryKeyType === "number" || binaryKeyType === "string") && (binarySizeType === "number" || binarySizeType === "string");
|
|
1391
1547
|
}
|
|
1392
1548
|
var SYNC_TIMEOUT_MS = 6e5;
|
|
1393
|
-
var
|
|
1549
|
+
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
1394
1550
|
var DeployClient = class {
|
|
1395
1551
|
accessToken;
|
|
1396
1552
|
baseUrl;
|
|
@@ -1422,14 +1578,14 @@ var DeployClient = class {
|
|
|
1422
1578
|
payload["targetServerHostnames"] = params.targetHosts;
|
|
1423
1579
|
}
|
|
1424
1580
|
try {
|
|
1425
|
-
const res = await
|
|
1581
|
+
const res = await import_ky6.default.post(url, {
|
|
1426
1582
|
headers: {
|
|
1427
1583
|
...this.authHeaders(),
|
|
1428
1584
|
"Content-Type": "application/json"
|
|
1429
1585
|
},
|
|
1430
1586
|
json: payload,
|
|
1431
1587
|
retry: 0,
|
|
1432
|
-
timeout: isAsync ?
|
|
1588
|
+
timeout: isAsync ? DEFAULT_TIMEOUT_MS2 : SYNC_TIMEOUT_MS
|
|
1433
1589
|
}).json();
|
|
1434
1590
|
return unwrap(res);
|
|
1435
1591
|
} catch (err) {
|
|
@@ -1442,10 +1598,10 @@ var DeployClient = class {
|
|
|
1442
1598
|
async artifacts(appKey) {
|
|
1443
1599
|
const url = `${this.baseUrl}/api/v2.1/projects/${encodeURIComponent(appKey)}/artifacts`;
|
|
1444
1600
|
try {
|
|
1445
|
-
const res = await
|
|
1601
|
+
const res = await import_ky6.default.get(url, {
|
|
1446
1602
|
headers: this.authHeaders(),
|
|
1447
1603
|
retry: 0,
|
|
1448
|
-
timeout:
|
|
1604
|
+
timeout: DEFAULT_TIMEOUT_MS2
|
|
1449
1605
|
}).json();
|
|
1450
1606
|
return unwrap(res);
|
|
1451
1607
|
} catch (err) {
|
|
@@ -1458,10 +1614,10 @@ var DeployClient = class {
|
|
|
1458
1614
|
async serverGroups(appKey, artifactId) {
|
|
1459
1615
|
const url = `${this.baseUrl}/api/v2.1/projects/${encodeURIComponent(appKey)}/artifacts/${encodeURIComponent(artifactId)}/server-groups`;
|
|
1460
1616
|
try {
|
|
1461
|
-
const res = await
|
|
1617
|
+
const res = await import_ky6.default.get(url, {
|
|
1462
1618
|
headers: this.authHeaders(),
|
|
1463
1619
|
retry: 0,
|
|
1464
|
-
timeout:
|
|
1620
|
+
timeout: DEFAULT_TIMEOUT_MS2
|
|
1465
1621
|
}).json();
|
|
1466
1622
|
return unwrap(res);
|
|
1467
1623
|
} catch (err) {
|
|
@@ -1474,10 +1630,10 @@ var DeployClient = class {
|
|
|
1474
1630
|
async histories(appKey, artifactId) {
|
|
1475
1631
|
const url = `${this.baseUrl}/api/v2.1/projects/${encodeURIComponent(appKey)}/artifacts/${encodeURIComponent(artifactId)}/deploy-histories`;
|
|
1476
1632
|
try {
|
|
1477
|
-
const res = await
|
|
1633
|
+
const res = await import_ky6.default.get(url, {
|
|
1478
1634
|
headers: this.authHeaders(),
|
|
1479
1635
|
retry: 0,
|
|
1480
|
-
timeout:
|
|
1636
|
+
timeout: DEFAULT_TIMEOUT_MS2
|
|
1481
1637
|
}).json();
|
|
1482
1638
|
return unwrap(res);
|
|
1483
1639
|
} catch (err) {
|
|
@@ -1490,10 +1646,10 @@ var DeployClient = class {
|
|
|
1490
1646
|
async binaryGroups(appKey, artifactId) {
|
|
1491
1647
|
const url = `${this.baseUrl}/api/v2.1/projects/${encodeURIComponent(appKey)}/artifacts/${encodeURIComponent(artifactId)}/binary-groups`;
|
|
1492
1648
|
try {
|
|
1493
|
-
const res = await
|
|
1649
|
+
const res = await import_ky6.default.get(url, {
|
|
1494
1650
|
headers: this.authHeaders(),
|
|
1495
1651
|
retry: 0,
|
|
1496
|
-
timeout:
|
|
1652
|
+
timeout: DEFAULT_TIMEOUT_MS2
|
|
1497
1653
|
}).json();
|
|
1498
1654
|
const body = unwrap(res);
|
|
1499
1655
|
const list = body.binaryGroups;
|
|
@@ -1520,11 +1676,11 @@ var DeployClient = class {
|
|
|
1520
1676
|
if (params.sortKey !== void 0) searchParams["sortKey"] = params.sortKey;
|
|
1521
1677
|
if (params.sortDirection !== void 0) searchParams["sortDirection"] = params.sortDirection;
|
|
1522
1678
|
try {
|
|
1523
|
-
const res = await
|
|
1679
|
+
const res = await import_ky6.default.get(url, {
|
|
1524
1680
|
headers: this.authHeaders(),
|
|
1525
1681
|
searchParams,
|
|
1526
1682
|
retry: 0,
|
|
1527
|
-
timeout:
|
|
1683
|
+
timeout: DEFAULT_TIMEOUT_MS2
|
|
1528
1684
|
}).json();
|
|
1529
1685
|
const body = unwrap(res);
|
|
1530
1686
|
const list = body.binaries;
|
|
@@ -1562,7 +1718,7 @@ var DeployClient = class {
|
|
|
1562
1718
|
form.append("description", params.description);
|
|
1563
1719
|
}
|
|
1564
1720
|
try {
|
|
1565
|
-
const res = await
|
|
1721
|
+
const res = await import_ky6.default.post(url, {
|
|
1566
1722
|
headers: this.authHeaders(),
|
|
1567
1723
|
// 인증 헤더만 — multipart boundary 는 ky 가 자동 설정
|
|
1568
1724
|
body: form,
|
|
@@ -1598,7 +1754,7 @@ var DeployClient = class {
|
|
|
1598
1754
|
async downloadBinary(appKey, artifactId, binaryGroupKey, binaryKey) {
|
|
1599
1755
|
const url = `${this.baseUrl}/api/v2.1/projects/${encodeURIComponent(appKey)}/artifacts/${encodeURIComponent(artifactId)}/binary-group/${binaryGroupKey}/binaries/${binaryKey}`;
|
|
1600
1756
|
try {
|
|
1601
|
-
const ab = await
|
|
1757
|
+
const ab = await import_ky6.default.get(url, {
|
|
1602
1758
|
headers: this.authHeaders(),
|
|
1603
1759
|
retry: 0,
|
|
1604
1760
|
timeout: SYNC_TIMEOUT_MS
|
|
@@ -1974,8 +2130,8 @@ var downloadCommand = new import_commander12.Command("download").description("\u
|
|
|
1974
2130
|
var import_commander13 = require("commander");
|
|
1975
2131
|
|
|
1976
2132
|
// src/services/instance/client.ts
|
|
1977
|
-
var
|
|
1978
|
-
var
|
|
2133
|
+
var import_ky7 = __toESM(require("ky"));
|
|
2134
|
+
var DEFAULT_TIMEOUT_MS3 = 3e4;
|
|
1979
2135
|
var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
1980
2136
|
function isServer(val) {
|
|
1981
2137
|
if (typeof val !== "object" || val === null) return false;
|
|
@@ -2104,10 +2260,10 @@ var InstanceClient = class {
|
|
|
2104
2260
|
async list() {
|
|
2105
2261
|
const url = `${this.computeEndpoint}/servers/detail`;
|
|
2106
2262
|
try {
|
|
2107
|
-
const raw = await
|
|
2263
|
+
const raw = await import_ky7.default.get(url, {
|
|
2108
2264
|
headers: this.authHeaders(),
|
|
2109
2265
|
retry: 0,
|
|
2110
|
-
timeout:
|
|
2266
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2111
2267
|
}).json();
|
|
2112
2268
|
if (!isServersResponse(raw)) {
|
|
2113
2269
|
throw new NhnCloudCliError(
|
|
@@ -2126,10 +2282,10 @@ var InstanceClient = class {
|
|
|
2126
2282
|
async get(id) {
|
|
2127
2283
|
const url = `${this.computeEndpoint}/servers/${encodeURIComponent(id)}`;
|
|
2128
2284
|
try {
|
|
2129
|
-
const raw = await
|
|
2285
|
+
const raw = await import_ky7.default.get(url, {
|
|
2130
2286
|
headers: this.authHeaders(),
|
|
2131
2287
|
retry: 0,
|
|
2132
|
-
timeout:
|
|
2288
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2133
2289
|
}).json();
|
|
2134
2290
|
if (!isServerResponse(raw)) {
|
|
2135
2291
|
throw new NhnCloudCliError(
|
|
@@ -2185,11 +2341,11 @@ var InstanceClient = class {
|
|
|
2185
2341
|
}
|
|
2186
2342
|
let raw;
|
|
2187
2343
|
try {
|
|
2188
|
-
raw = await
|
|
2344
|
+
raw = await import_ky7.default.post(url, {
|
|
2189
2345
|
headers: this.authHeaders(),
|
|
2190
2346
|
json: { server: serverBody },
|
|
2191
2347
|
retry: 0,
|
|
2192
|
-
timeout:
|
|
2348
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2193
2349
|
}).json();
|
|
2194
2350
|
} catch (err) {
|
|
2195
2351
|
throw toNhnCloudCliError(err);
|
|
@@ -2208,10 +2364,10 @@ var InstanceClient = class {
|
|
|
2208
2364
|
async delete(id) {
|
|
2209
2365
|
const url = `${this.computeEndpoint}/servers/${encodeURIComponent(id)}`;
|
|
2210
2366
|
try {
|
|
2211
|
-
await
|
|
2367
|
+
await import_ky7.default.delete(url, {
|
|
2212
2368
|
headers: this.authHeaders(),
|
|
2213
2369
|
retry: 0,
|
|
2214
|
-
timeout:
|
|
2370
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2215
2371
|
});
|
|
2216
2372
|
} catch (err) {
|
|
2217
2373
|
throw toNhnCloudCliError(err);
|
|
@@ -2226,11 +2382,11 @@ var InstanceClient = class {
|
|
|
2226
2382
|
async serverAction(id, payload) {
|
|
2227
2383
|
const url = `${this.computeEndpoint}/servers/${encodeURIComponent(id)}/action`;
|
|
2228
2384
|
try {
|
|
2229
|
-
await
|
|
2385
|
+
await import_ky7.default.post(url, {
|
|
2230
2386
|
headers: this.authHeaders(),
|
|
2231
2387
|
json: payload,
|
|
2232
2388
|
retry: 0,
|
|
2233
|
-
timeout:
|
|
2389
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2234
2390
|
});
|
|
2235
2391
|
} catch (err) {
|
|
2236
2392
|
throw toNhnCloudCliError(err);
|
|
@@ -2271,11 +2427,11 @@ var InstanceClient = class {
|
|
|
2271
2427
|
if (params.minDisk !== void 0) searchParams["minDisk"] = params.minDisk;
|
|
2272
2428
|
if (params.minRam !== void 0) searchParams["minRam"] = params.minRam;
|
|
2273
2429
|
try {
|
|
2274
|
-
const raw = await
|
|
2430
|
+
const raw = await import_ky7.default.get(url, {
|
|
2275
2431
|
headers: this.authHeaders(),
|
|
2276
2432
|
searchParams,
|
|
2277
2433
|
retry: 0,
|
|
2278
|
-
timeout:
|
|
2434
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2279
2435
|
}).json();
|
|
2280
2436
|
if (params.detail) {
|
|
2281
2437
|
if (!isFlavorDetailsResponse(raw)) {
|
|
@@ -2304,10 +2460,10 @@ var InstanceClient = class {
|
|
|
2304
2460
|
async listAvailabilityZones() {
|
|
2305
2461
|
const url = `${this.computeEndpoint}/os-availability-zone`;
|
|
2306
2462
|
try {
|
|
2307
|
-
const raw = await
|
|
2463
|
+
const raw = await import_ky7.default.get(url, {
|
|
2308
2464
|
headers: this.authHeaders(),
|
|
2309
2465
|
retry: 0,
|
|
2310
|
-
timeout:
|
|
2466
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2311
2467
|
}).json();
|
|
2312
2468
|
if (!isAvailabilityZonesResponse(raw)) {
|
|
2313
2469
|
throw new NhnCloudCliError(
|
|
@@ -2324,7 +2480,7 @@ var InstanceClient = class {
|
|
|
2324
2480
|
async listKeypairs() {
|
|
2325
2481
|
const url = `${this.computeEndpoint}/os-keypairs`;
|
|
2326
2482
|
try {
|
|
2327
|
-
const raw = await
|
|
2483
|
+
const raw = await import_ky7.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS3 }).json();
|
|
2328
2484
|
if (!isKeypairsResponse(raw)) {
|
|
2329
2485
|
throw new NhnCloudCliError(
|
|
2330
2486
|
"instance keypairs \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 keypairs \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
@@ -2340,7 +2496,7 @@ var InstanceClient = class {
|
|
|
2340
2496
|
async getKeypair(name) {
|
|
2341
2497
|
const url = `${this.computeEndpoint}/os-keypairs/${encodeURIComponent(name)}`;
|
|
2342
2498
|
try {
|
|
2343
|
-
const raw = await
|
|
2499
|
+
const raw = await import_ky7.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS3 }).json();
|
|
2344
2500
|
if (!isKeypairDetailResponse(raw)) {
|
|
2345
2501
|
throw new NhnCloudCliError(
|
|
2346
2502
|
`instance keypair get(${name}) \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 keypair \uC0C1\uC138 \uD544\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`,
|
|
@@ -2365,11 +2521,11 @@ var InstanceClient = class {
|
|
|
2365
2521
|
}
|
|
2366
2522
|
let raw;
|
|
2367
2523
|
try {
|
|
2368
|
-
raw = await
|
|
2524
|
+
raw = await import_ky7.default.post(url, {
|
|
2369
2525
|
headers: this.authHeaders(),
|
|
2370
2526
|
json: { keypair: keypairBody },
|
|
2371
2527
|
retry: 0,
|
|
2372
|
-
timeout:
|
|
2528
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2373
2529
|
}).json();
|
|
2374
2530
|
} catch (err) {
|
|
2375
2531
|
throw toNhnCloudCliError(err);
|
|
@@ -2394,7 +2550,7 @@ var InstanceClient = class {
|
|
|
2394
2550
|
async deleteKeypair(name) {
|
|
2395
2551
|
const url = `${this.computeEndpoint}/os-keypairs/${encodeURIComponent(name)}`;
|
|
2396
2552
|
try {
|
|
2397
|
-
await
|
|
2553
|
+
await import_ky7.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS3 });
|
|
2398
2554
|
} catch (err) {
|
|
2399
2555
|
throw toNhnCloudCliError(err);
|
|
2400
2556
|
}
|
|
@@ -2414,11 +2570,11 @@ var InstanceClient = class {
|
|
|
2414
2570
|
if (params.owner !== void 0) searchParams["owner"] = params.owner;
|
|
2415
2571
|
if (params.status !== void 0) searchParams["status"] = params.status;
|
|
2416
2572
|
try {
|
|
2417
|
-
const raw = await
|
|
2573
|
+
const raw = await import_ky7.default.get(url, {
|
|
2418
2574
|
headers: this.authHeaders(),
|
|
2419
2575
|
searchParams,
|
|
2420
2576
|
retry: 0,
|
|
2421
|
-
timeout:
|
|
2577
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2422
2578
|
}).json();
|
|
2423
2579
|
if (!isImagesResponse(raw)) {
|
|
2424
2580
|
throw new NhnCloudCliError(
|
|
@@ -2438,7 +2594,7 @@ var InstanceClient = class {
|
|
|
2438
2594
|
async listVolumeAttachments(serverId) {
|
|
2439
2595
|
const url = `${this.computeEndpoint}/servers/${encodeURIComponent(serverId)}/os-volume_attachments`;
|
|
2440
2596
|
try {
|
|
2441
|
-
const raw = await
|
|
2597
|
+
const raw = await import_ky7.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS3 }).json();
|
|
2442
2598
|
if (!isVolumeAttachmentsResponse(raw)) {
|
|
2443
2599
|
throw new NhnCloudCliError(
|
|
2444
2600
|
"instance volumes \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 volumeAttachments \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
@@ -2457,11 +2613,11 @@ var InstanceClient = class {
|
|
|
2457
2613
|
async attachVolume(serverId, volumeId) {
|
|
2458
2614
|
const url = `${this.computeEndpoint}/servers/${encodeURIComponent(serverId)}/os-volume_attachments`;
|
|
2459
2615
|
try {
|
|
2460
|
-
const res = await
|
|
2616
|
+
const res = await import_ky7.default.post(url, {
|
|
2461
2617
|
headers: this.authHeaders(),
|
|
2462
2618
|
json: { volumeAttachment: { volumeId } },
|
|
2463
2619
|
retry: 0,
|
|
2464
|
-
timeout:
|
|
2620
|
+
timeout: DEFAULT_TIMEOUT_MS3
|
|
2465
2621
|
});
|
|
2466
2622
|
if (res.status === 202 || res.headers.get("content-length") === "0") {
|
|
2467
2623
|
return { id: volumeId, volumeId, serverId, device: "" };
|
|
@@ -2485,7 +2641,7 @@ var InstanceClient = class {
|
|
|
2485
2641
|
async detachVolume(serverId, volumeId) {
|
|
2486
2642
|
const url = `${this.computeEndpoint}/servers/${encodeURIComponent(serverId)}/os-volume_attachments/${encodeURIComponent(volumeId)}`;
|
|
2487
2643
|
try {
|
|
2488
|
-
await
|
|
2644
|
+
await import_ky7.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS3 });
|
|
2489
2645
|
} catch (err) {
|
|
2490
2646
|
throw toNhnCloudCliError(err);
|
|
2491
2647
|
}
|
|
@@ -2555,8 +2711,8 @@ var listCommand = new import_commander13.Command("list").description("\uC778\uC2
|
|
|
2555
2711
|
var import_commander14 = require("commander");
|
|
2556
2712
|
|
|
2557
2713
|
// src/services/blockstorage/client.ts
|
|
2558
|
-
var
|
|
2559
|
-
var
|
|
2714
|
+
var import_ky8 = __toESM(require("ky"));
|
|
2715
|
+
var DEFAULT_TIMEOUT_MS4 = 3e4;
|
|
2560
2716
|
function isVolume(val) {
|
|
2561
2717
|
if (typeof val !== "object" || val === null) return false;
|
|
2562
2718
|
const obj = val;
|
|
@@ -2592,7 +2748,7 @@ var BlockStorageClient = class {
|
|
|
2592
2748
|
if (params?.offset !== void 0) searchParams["offset"] = params.offset;
|
|
2593
2749
|
if (params?.marker !== void 0) searchParams["marker"] = params.marker;
|
|
2594
2750
|
try {
|
|
2595
|
-
const raw = await
|
|
2751
|
+
const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), searchParams, retry: 0, timeout: DEFAULT_TIMEOUT_MS4 }).json();
|
|
2596
2752
|
if (!isVolumesResponse(raw)) {
|
|
2597
2753
|
throw new NhnCloudCliError(
|
|
2598
2754
|
"volume list \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 volumes \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
@@ -2607,7 +2763,7 @@ var BlockStorageClient = class {
|
|
|
2607
2763
|
async get(id) {
|
|
2608
2764
|
const url = `${this.endpoint}/volumes/${encodeURIComponent(id)}`;
|
|
2609
2765
|
try {
|
|
2610
|
-
const raw = await
|
|
2766
|
+
const raw = await import_ky8.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS4 }).json();
|
|
2611
2767
|
if (!isVolumeResponse(raw)) {
|
|
2612
2768
|
throw new NhnCloudCliError(
|
|
2613
2769
|
"volume get \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 volume \uAC1D\uCCB4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
@@ -2627,11 +2783,11 @@ var BlockStorageClient = class {
|
|
|
2627
2783
|
if (params.volume_type !== void 0) volumeBody["volume_type"] = params.volume_type;
|
|
2628
2784
|
if (params.snapshot_id !== void 0) volumeBody["snapshot_id"] = params.snapshot_id;
|
|
2629
2785
|
try {
|
|
2630
|
-
const raw = await
|
|
2786
|
+
const raw = await import_ky8.default.post(url, {
|
|
2631
2787
|
headers: this.authHeaders(),
|
|
2632
2788
|
json: { volume: volumeBody },
|
|
2633
2789
|
retry: 0,
|
|
2634
|
-
timeout:
|
|
2790
|
+
timeout: DEFAULT_TIMEOUT_MS4
|
|
2635
2791
|
}).json();
|
|
2636
2792
|
if (!isVolumeResponse(raw)) {
|
|
2637
2793
|
throw new NhnCloudCliError(
|
|
@@ -2780,8 +2936,8 @@ var createCommand = new import_commander16.Command("create").description("\uBCFC
|
|
|
2780
2936
|
var import_commander17 = require("commander");
|
|
2781
2937
|
|
|
2782
2938
|
// src/services/network/client.ts
|
|
2783
|
-
var
|
|
2784
|
-
var
|
|
2939
|
+
var import_ky9 = __toESM(require("ky"));
|
|
2940
|
+
var DEFAULT_TIMEOUT_MS5 = 3e4;
|
|
2785
2941
|
function isVpc(val) {
|
|
2786
2942
|
if (typeof val !== "object" || val === null) return false;
|
|
2787
2943
|
const obj = val;
|
|
@@ -2834,10 +2990,10 @@ var NetworkClient = class {
|
|
|
2834
2990
|
async listVpcs() {
|
|
2835
2991
|
const url = `${this.networkEndpoint}/vpcs`;
|
|
2836
2992
|
try {
|
|
2837
|
-
const raw = await
|
|
2993
|
+
const raw = await import_ky9.default.get(url, {
|
|
2838
2994
|
headers: this.authHeaders(),
|
|
2839
2995
|
retry: 0,
|
|
2840
|
-
timeout:
|
|
2996
|
+
timeout: DEFAULT_TIMEOUT_MS5
|
|
2841
2997
|
}).json();
|
|
2842
2998
|
if (!isVpcsResponse(raw)) {
|
|
2843
2999
|
throw new NhnCloudCliError(
|
|
@@ -2856,10 +3012,10 @@ var NetworkClient = class {
|
|
|
2856
3012
|
async listSubnets() {
|
|
2857
3013
|
const url = `${this.networkEndpoint}/vpcsubnets`;
|
|
2858
3014
|
try {
|
|
2859
|
-
const raw = await
|
|
3015
|
+
const raw = await import_ky9.default.get(url, {
|
|
2860
3016
|
headers: this.authHeaders(),
|
|
2861
3017
|
retry: 0,
|
|
2862
|
-
timeout:
|
|
3018
|
+
timeout: DEFAULT_TIMEOUT_MS5
|
|
2863
3019
|
}).json();
|
|
2864
3020
|
if (!isSubnetsResponse(raw)) {
|
|
2865
3021
|
throw new NhnCloudCliError(
|
|
@@ -2876,7 +3032,7 @@ var NetworkClient = class {
|
|
|
2876
3032
|
async listFloatingIps() {
|
|
2877
3033
|
const url = `${this.networkEndpoint}/floatingips`;
|
|
2878
3034
|
try {
|
|
2879
|
-
const raw = await
|
|
3035
|
+
const raw = await import_ky9.default.get(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS5 }).json();
|
|
2880
3036
|
if (!isFloatingIpsResponse(raw)) {
|
|
2881
3037
|
throw new NhnCloudCliError(
|
|
2882
3038
|
"floatingip list \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 floatingips \uBC30\uC5F4\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
@@ -2892,11 +3048,11 @@ var NetworkClient = class {
|
|
|
2892
3048
|
async createFloatingIp(params) {
|
|
2893
3049
|
const url = `${this.networkEndpoint}/floatingips`;
|
|
2894
3050
|
try {
|
|
2895
|
-
const raw = await
|
|
3051
|
+
const raw = await import_ky9.default.post(url, {
|
|
2896
3052
|
headers: this.authHeaders(),
|
|
2897
3053
|
json: { floatingip: { floating_network_id: params.floating_network_id } },
|
|
2898
3054
|
retry: 0,
|
|
2899
|
-
timeout:
|
|
3055
|
+
timeout: DEFAULT_TIMEOUT_MS5
|
|
2900
3056
|
}).json();
|
|
2901
3057
|
if (!isFloatingIpResponse(raw)) {
|
|
2902
3058
|
throw new NhnCloudCliError(
|
|
@@ -2913,7 +3069,7 @@ var NetworkClient = class {
|
|
|
2913
3069
|
async deleteFloatingIp(id) {
|
|
2914
3070
|
const url = `${this.networkEndpoint}/floatingips/${encodeURIComponent(id)}`;
|
|
2915
3071
|
try {
|
|
2916
|
-
await
|
|
3072
|
+
await import_ky9.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS5 });
|
|
2917
3073
|
} catch (err) {
|
|
2918
3074
|
throw toNhnCloudCliError(err);
|
|
2919
3075
|
}
|
|
@@ -2927,11 +3083,11 @@ var NetworkClient = class {
|
|
|
2927
3083
|
async findExternalNetworkId() {
|
|
2928
3084
|
const url = `${this.networkEndpoint}/vpcs`;
|
|
2929
3085
|
try {
|
|
2930
|
-
const raw = await
|
|
3086
|
+
const raw = await import_ky9.default.get(url, {
|
|
2931
3087
|
headers: this.authHeaders(),
|
|
2932
3088
|
searchParams: { "router:external": "true" },
|
|
2933
3089
|
retry: 0,
|
|
2934
|
-
timeout:
|
|
3090
|
+
timeout: DEFAULT_TIMEOUT_MS5
|
|
2935
3091
|
}).json();
|
|
2936
3092
|
if (typeof raw !== "object" || raw === null) return null;
|
|
2937
3093
|
const vpcs = raw["vpcs"];
|
|
@@ -3779,9 +3935,280 @@ var volumesCommand = new import_commander33.Command("volumes").description("\uC7
|
|
|
3779
3935
|
});
|
|
3780
3936
|
});
|
|
3781
3937
|
|
|
3938
|
+
// src/commands/ncr/list.ts
|
|
3939
|
+
var import_commander34 = require("commander");
|
|
3940
|
+
|
|
3941
|
+
// src/services/ncr/harbor-client.ts
|
|
3942
|
+
var import_ky10 = __toESM(require("ky"));
|
|
3943
|
+
var DEFAULT_TIMEOUT_MS6 = 3e4;
|
|
3944
|
+
var PAGE_SIZE = 100;
|
|
3945
|
+
var MAX_PAGES = 1e3;
|
|
3946
|
+
var HarborClient = class {
|
|
3947
|
+
uakId;
|
|
3948
|
+
uakSecret;
|
|
3949
|
+
host;
|
|
3950
|
+
constructor(uakId, uakSecret, host) {
|
|
3951
|
+
this.uakId = uakId;
|
|
3952
|
+
this.uakSecret = uakSecret;
|
|
3953
|
+
this.host = host;
|
|
3954
|
+
}
|
|
3955
|
+
basicAuthHeaders() {
|
|
3956
|
+
const token = Buffer.from(`${this.uakId}:${this.uakSecret}`).toString("base64");
|
|
3957
|
+
return { Authorization: `Basic ${token}` };
|
|
3958
|
+
}
|
|
3959
|
+
/**
|
|
3960
|
+
* Harbor REST 페이지네이션 전수 수집 (ADR-017 — silent truncation 방지).
|
|
3961
|
+
*
|
|
3962
|
+
* Harbor 응답 Link: <...?page=N+1...>; rel="next" 헤더가 없으면 종료.
|
|
3963
|
+
* ky.get() 이 Response 를 반환하므로 .json() 과 .headers.get("link") 를 함께 사용한다
|
|
3964
|
+
* (체이닝하면 헤더를 못 본다 — 기존 NCR client 의 .json<T>() 체이닝 패턴과 다름).
|
|
3965
|
+
*/
|
|
3966
|
+
async getAllPages(path) {
|
|
3967
|
+
const acc = [];
|
|
3968
|
+
let page = 1;
|
|
3969
|
+
try {
|
|
3970
|
+
for (; ; ) {
|
|
3971
|
+
const url = `https://${this.host}${path}?page=${page}&page_size=${PAGE_SIZE}`;
|
|
3972
|
+
const res = await import_ky10.default.get(url, {
|
|
3973
|
+
headers: this.basicAuthHeaders(),
|
|
3974
|
+
retry: 0,
|
|
3975
|
+
timeout: DEFAULT_TIMEOUT_MS6
|
|
3976
|
+
});
|
|
3977
|
+
const data = await res.json();
|
|
3978
|
+
if (!Array.isArray(data)) {
|
|
3979
|
+
throw new NhnCloudCliError(
|
|
3980
|
+
"Harbor REST \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
|
|
3981
|
+
EXIT_API_ERROR
|
|
3982
|
+
);
|
|
3983
|
+
}
|
|
3984
|
+
acc.push(...data);
|
|
3985
|
+
const link = res.headers.get("link");
|
|
3986
|
+
if (!link || !link.includes('rel="next"')) break;
|
|
3987
|
+
page++;
|
|
3988
|
+
if (page > MAX_PAGES) {
|
|
3989
|
+
throw new NhnCloudCliError(
|
|
3990
|
+
`Harbor pagination \uCD5C\uB300 \uD398\uC774\uC9C0(${MAX_PAGES}) \uCD08\uACFC \u2014 \uBE44\uC815\uC0C1 \uC751\uB2F5\uC73C\uB85C \uC911\uB2E8\uD569\uB2C8\uB2E4.`,
|
|
3991
|
+
EXIT_API_ERROR
|
|
3992
|
+
);
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3995
|
+
} catch (err) {
|
|
3996
|
+
if (err instanceof NhnCloudCliError) throw err;
|
|
3997
|
+
throw toNhnCloudCliError(err);
|
|
3998
|
+
}
|
|
3999
|
+
return acc;
|
|
4000
|
+
}
|
|
4001
|
+
/**
|
|
4002
|
+
* 프로젝트(레지스트리)의 repository(이미지) 목록을 반환한다.
|
|
4003
|
+
* GET /api/v2.0/projects/{project}/repositories
|
|
4004
|
+
*/
|
|
4005
|
+
async listRepositories(project) {
|
|
4006
|
+
const enc = encodeURIComponent(project);
|
|
4007
|
+
const data = await this.getAllPages(`/api/v2.0/projects/${enc}/repositories`);
|
|
4008
|
+
return data.filter(isRepository);
|
|
4009
|
+
}
|
|
4010
|
+
/**
|
|
4011
|
+
* repository 의 artifact 목록을 반환한다.
|
|
4012
|
+
* GET /api/v2.0/projects/{project}/repositories/{repository}/artifacts
|
|
4013
|
+
* repository 의 '/' 는 %2F 로 인코딩(path-traversal 방지).
|
|
4014
|
+
*/
|
|
4015
|
+
async listArtifacts(project, repository) {
|
|
4016
|
+
const encProject = encodeURIComponent(project);
|
|
4017
|
+
const encRepo = encodeURIComponent(repository);
|
|
4018
|
+
const data = await this.getAllPages(
|
|
4019
|
+
`/api/v2.0/projects/${encProject}/repositories/${encRepo}/artifacts`
|
|
4020
|
+
);
|
|
4021
|
+
return data.filter(isArtifact);
|
|
4022
|
+
}
|
|
4023
|
+
};
|
|
4024
|
+
|
|
4025
|
+
// src/commands/ncr/helpers.ts
|
|
4026
|
+
async function createNcrClient(opts) {
|
|
4027
|
+
const profileName = await resolveProfileName(opts.profile);
|
|
4028
|
+
const uak = await getUserAccessKey(profileName);
|
|
4029
|
+
const region = opts.region ?? "kr1";
|
|
4030
|
+
return { client: new NcrClient(uak.id, uak.secret, region), profileName };
|
|
4031
|
+
}
|
|
4032
|
+
async function resolveAppKey(profileName, appKeyOpt) {
|
|
4033
|
+
if (appKeyOpt) return appKeyOpt;
|
|
4034
|
+
let cred;
|
|
4035
|
+
try {
|
|
4036
|
+
cred = await getServiceCredential("ncr", profileName);
|
|
4037
|
+
} catch (err) {
|
|
4038
|
+
if (!(err instanceof NhnCloudCliError) || err.exitCode !== EXIT_CONFIG_ERROR) {
|
|
4039
|
+
throw err;
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
if (!cred?.appkey) {
|
|
4043
|
+
throw new NhnCloudCliError(
|
|
4044
|
+
"NCR appKey \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. --app-key \uC635\uC158\uC73C\uB85C \uC9C0\uC815\uD558\uAC70\uB098\nnhncloud configure --ncr-appkey <key> \uB97C \uC2E4\uD589\uD574 \uC124\uC815\uD558\uC138\uC694.",
|
|
4045
|
+
EXIT_CONFIG_ERROR
|
|
4046
|
+
);
|
|
4047
|
+
}
|
|
4048
|
+
return cred.appkey;
|
|
4049
|
+
}
|
|
4050
|
+
async function createHarborClient(opts, registryArg) {
|
|
4051
|
+
const { client: ncrClient, profileName } = await createNcrClient(opts);
|
|
4052
|
+
const appKey = await resolveAppKey(profileName, opts.appKey);
|
|
4053
|
+
const uak = await getUserAccessKey(profileName);
|
|
4054
|
+
const reg = await ncrClient.getRegistry(appKey, registryArg);
|
|
4055
|
+
const host = parseHarborHost(reg.uri);
|
|
4056
|
+
const project = typeof reg.name === "string" ? reg.name : registryArg;
|
|
4057
|
+
return { harbor: new HarborClient(uak.id, uak.secret, host), project };
|
|
4058
|
+
}
|
|
4059
|
+
function parseHarborHost(uri) {
|
|
4060
|
+
if (!uri) {
|
|
4061
|
+
throw new NhnCloudCliError(
|
|
4062
|
+
"\uB808\uC9C0\uC2A4\uD2B8\uB9AC uri \uAC00 \uC5C6\uC5B4 \uC774\uBBF8\uC9C0 host \uB97C \uD574\uC11D\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
4063
|
+
EXIT_API_ERROR
|
|
4064
|
+
);
|
|
4065
|
+
}
|
|
4066
|
+
const noScheme = uri.replace(/^https?:\/\//, "");
|
|
4067
|
+
const host = noScheme.split("/")[0];
|
|
4068
|
+
if (!host) {
|
|
4069
|
+
throw new NhnCloudCliError(
|
|
4070
|
+
"\uB808\uC9C0\uC2A4\uD2B8\uB9AC uri \uD615\uC2DD \uC624\uB958 \u2014 host \uCD94\uCD9C \uC2E4\uD328.",
|
|
4071
|
+
EXIT_API_ERROR
|
|
4072
|
+
);
|
|
4073
|
+
}
|
|
4074
|
+
return host;
|
|
4075
|
+
}
|
|
4076
|
+
|
|
4077
|
+
// src/commands/ncr/list.ts
|
|
4078
|
+
var listCommand5 = new import_commander34.Command("list").description("NCR \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "NCR region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "NCR appKey (profile \uC758 ncr.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
|
|
4079
|
+
const opts = cmd.optsWithGlobals();
|
|
4080
|
+
const { client, profileName } = await createNcrClient(opts);
|
|
4081
|
+
const appKey = await resolveAppKey(profileName, opts.appKey);
|
|
4082
|
+
startSpinner("\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
4083
|
+
let registries;
|
|
4084
|
+
try {
|
|
4085
|
+
registries = await client.listRegistries(appKey);
|
|
4086
|
+
} catch (err) {
|
|
4087
|
+
stopSpinner(false);
|
|
4088
|
+
throw err;
|
|
4089
|
+
}
|
|
4090
|
+
stopSpinner(true);
|
|
4091
|
+
output(opts, {
|
|
4092
|
+
headers: ["name", "repo_count", "uri"],
|
|
4093
|
+
rows: registries.map((r) => [
|
|
4094
|
+
r.name,
|
|
4095
|
+
String(r.repo_count ?? ""),
|
|
4096
|
+
r.uri ?? ""
|
|
4097
|
+
]),
|
|
4098
|
+
raw: registries,
|
|
4099
|
+
ids: registries.map((r) => r.name)
|
|
4100
|
+
});
|
|
4101
|
+
});
|
|
4102
|
+
|
|
4103
|
+
// src/commands/ncr/get.ts
|
|
4104
|
+
var import_commander35 = require("commander");
|
|
4105
|
+
var getCommand3 = new import_commander35.Command("get").description("\uB2E8\uC77C NCR \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<registry>", "\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC774\uB984 \uB610\uB294 ID").option("--region <region>", "NCR region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "NCR appKey (profile \uC758 ncr.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (registry, _opts, cmd) => {
|
|
4106
|
+
const opts = cmd.optsWithGlobals();
|
|
4107
|
+
if (!registry.trim()) {
|
|
4108
|
+
throw new NhnCloudCliError(
|
|
4109
|
+
"registry \uC778\uC218\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC774\uB984 \uB610\uB294 ID \uB97C \uC9C0\uC815\uD558\uC138\uC694.",
|
|
4110
|
+
EXIT_PARAM_ERROR
|
|
4111
|
+
);
|
|
4112
|
+
}
|
|
4113
|
+
const { client, profileName } = await createNcrClient(opts);
|
|
4114
|
+
const appKey = await resolveAppKey(profileName, opts.appKey);
|
|
4115
|
+
startSpinner(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC "${registry}" \uC870\uD68C \uC911...`);
|
|
4116
|
+
let reg;
|
|
4117
|
+
try {
|
|
4118
|
+
reg = await client.getRegistry(appKey, registry);
|
|
4119
|
+
} catch (err) {
|
|
4120
|
+
stopSpinner(false);
|
|
4121
|
+
throw err;
|
|
4122
|
+
}
|
|
4123
|
+
stopSpinner(true);
|
|
4124
|
+
output(opts, {
|
|
4125
|
+
headers: ["name", "repo_count", "uri", "private_uri"],
|
|
4126
|
+
rows: [[reg.name, String(reg.repo_count ?? ""), reg.uri ?? "", reg.private_uri ?? ""]],
|
|
4127
|
+
raw: reg,
|
|
4128
|
+
ids: [reg.name]
|
|
4129
|
+
});
|
|
4130
|
+
});
|
|
4131
|
+
|
|
4132
|
+
// src/commands/ncr/images.ts
|
|
4133
|
+
var import_commander36 = require("commander");
|
|
4134
|
+
var imagesCommand2 = new import_commander36.Command("images").description("\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uC774\uBBF8\uC9C0(repository) \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<registry>", "\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC774\uB984").option("--region <region>", "NCR region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "NCR appKey (profile \uC758 ncr.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (registry, _opts, cmd) => {
|
|
4135
|
+
const opts = cmd.optsWithGlobals();
|
|
4136
|
+
if (!registry.trim()) {
|
|
4137
|
+
throw new NhnCloudCliError(
|
|
4138
|
+
"registry \uC778\uC218\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC138\uC694.",
|
|
4139
|
+
EXIT_PARAM_ERROR
|
|
4140
|
+
);
|
|
4141
|
+
}
|
|
4142
|
+
const { harbor, project } = await createHarborClient(opts, registry);
|
|
4143
|
+
startSpinner(`"${registry}" \uC774\uBBF8\uC9C0 \uBAA9\uB85D \uC870\uD68C \uC911...`);
|
|
4144
|
+
let repos;
|
|
4145
|
+
try {
|
|
4146
|
+
repos = await harbor.listRepositories(project);
|
|
4147
|
+
} catch (err) {
|
|
4148
|
+
stopSpinner(false);
|
|
4149
|
+
throw err;
|
|
4150
|
+
}
|
|
4151
|
+
stopSpinner(true);
|
|
4152
|
+
const rows = repos.map((r) => {
|
|
4153
|
+
const short = r.name.startsWith(project + "/") ? r.name.slice(project.length + 1) : r.name;
|
|
4154
|
+
return [short, String(r.artifact_count ?? ""), String(r.pull_count ?? "")];
|
|
4155
|
+
});
|
|
4156
|
+
const ids = repos.map(
|
|
4157
|
+
(r) => r.name.startsWith(project + "/") ? r.name.slice(project.length + 1) : r.name
|
|
4158
|
+
);
|
|
4159
|
+
output(opts, {
|
|
4160
|
+
headers: ["repository", "artifact_count", "pull_count"],
|
|
4161
|
+
rows,
|
|
4162
|
+
raw: repos,
|
|
4163
|
+
ids
|
|
4164
|
+
});
|
|
4165
|
+
});
|
|
4166
|
+
|
|
4167
|
+
// src/commands/ncr/tags.ts
|
|
4168
|
+
var import_commander37 = require("commander");
|
|
4169
|
+
var tagsCommand = new import_commander37.Command("tags").description("\uD2B9\uC815 \uC774\uBBF8\uC9C0\uC758 \uD0DC\uADF8 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<registry>", "\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC774\uB984").argument("<repository>", "\uC774\uBBF8\uC9C0(repository) \uC774\uB984 (\uC9E7\uC740 \uC774\uB984 \uB610\uB294 {project}/{repo})").option("--region <region>", "NCR region (\uAE30\uBCF8: kr1)", "kr1").option("--app-key <key>", "NCR appKey (profile \uC758 ncr.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (registry, repository, _opts, cmd) => {
|
|
4170
|
+
const opts = cmd.optsWithGlobals();
|
|
4171
|
+
if (!registry.trim()) {
|
|
4172
|
+
throw new NhnCloudCliError(
|
|
4173
|
+
"registry \uC778\uC218\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC138\uC694.",
|
|
4174
|
+
EXIT_PARAM_ERROR
|
|
4175
|
+
);
|
|
4176
|
+
}
|
|
4177
|
+
if (!repository.trim()) {
|
|
4178
|
+
throw new NhnCloudCliError(
|
|
4179
|
+
"repository \uC778\uC218\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. \uC774\uBBF8\uC9C0 \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC138\uC694.",
|
|
4180
|
+
EXIT_PARAM_ERROR
|
|
4181
|
+
);
|
|
4182
|
+
}
|
|
4183
|
+
const { harbor, project } = await createHarborClient(opts, registry);
|
|
4184
|
+
const repo = repository.startsWith(project + "/") ? repository.slice(project.length + 1) : repository;
|
|
4185
|
+
startSpinner(`"${registry}/${repo}" \uD0DC\uADF8 \uBAA9\uB85D \uC870\uD68C \uC911...`);
|
|
4186
|
+
let tagRows;
|
|
4187
|
+
try {
|
|
4188
|
+
const artifacts = await harbor.listArtifacts(project, repo);
|
|
4189
|
+
tagRows = artifacts.flatMap(
|
|
4190
|
+
(a) => (a.tags ?? []).map((t) => ({
|
|
4191
|
+
tag: t.name,
|
|
4192
|
+
push_time: t.push_time ?? a.push_time,
|
|
4193
|
+
size: String(a.size ?? "")
|
|
4194
|
+
}))
|
|
4195
|
+
);
|
|
4196
|
+
} catch (err) {
|
|
4197
|
+
stopSpinner(false);
|
|
4198
|
+
throw err;
|
|
4199
|
+
}
|
|
4200
|
+
stopSpinner(true);
|
|
4201
|
+
output(opts, {
|
|
4202
|
+
headers: ["tag", "push_time", "size"],
|
|
4203
|
+
rows: tagRows.map((r) => [r.tag, r.push_time ?? "", r.size]),
|
|
4204
|
+
raw: tagRows,
|
|
4205
|
+
ids: tagRows.map((r) => r.tag)
|
|
4206
|
+
});
|
|
4207
|
+
});
|
|
4208
|
+
|
|
3782
4209
|
// src/index.ts
|
|
3783
|
-
var program = new
|
|
3784
|
-
program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version("0.
|
|
4210
|
+
var program = new import_commander38.Command();
|
|
4211
|
+
program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version("0.5.1").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");
|
|
3785
4212
|
program.hook("preAction", () => {
|
|
3786
4213
|
const opts = program.opts();
|
|
3787
4214
|
if (!opts.color || process.env["NO_COLOR"]) {
|
|
@@ -3792,12 +4219,12 @@ program.hook("preAction", () => {
|
|
|
3792
4219
|
}
|
|
3793
4220
|
});
|
|
3794
4221
|
program.addCommand(configureCommand);
|
|
3795
|
-
var logncrashCommand = new
|
|
4222
|
+
var logncrashCommand = new import_commander38.Command("logncrash").description("Log & Crash \uAD00\uB828 \uBA85\uB839");
|
|
3796
4223
|
logncrashCommand.addCommand(searchCommand);
|
|
3797
4224
|
logncrashCommand.addCommand(sendCommand);
|
|
3798
4225
|
logncrashCommand.addCommand(exportCommand);
|
|
3799
4226
|
program.addCommand(logncrashCommand);
|
|
3800
|
-
var deployCommand = new
|
|
4227
|
+
var deployCommand = new import_commander38.Command("deploy").description("NHN Cloud Deploy \uAD00\uB828 \uBA85\uB839");
|
|
3801
4228
|
deployCommand.addCommand(runCommand);
|
|
3802
4229
|
deployCommand.addCommand(artifactsCommand);
|
|
3803
4230
|
deployCommand.addCommand(serverGroupsCommand);
|
|
@@ -3807,7 +4234,7 @@ deployCommand.addCommand(binariesCommand);
|
|
|
3807
4234
|
deployCommand.addCommand(uploadCommand);
|
|
3808
4235
|
deployCommand.addCommand(downloadCommand);
|
|
3809
4236
|
program.addCommand(deployCommand);
|
|
3810
|
-
var instanceCommand = new
|
|
4237
|
+
var instanceCommand = new import_commander38.Command("instance").description("Compute \uC778\uC2A4\uD134\uC2A4 \uAD00\uB828 \uBA85\uB839");
|
|
3811
4238
|
instanceCommand.addCommand(listCommand);
|
|
3812
4239
|
instanceCommand.addCommand(flavorsCommand);
|
|
3813
4240
|
instanceCommand.addCommand(availabilityZonesCommand);
|
|
@@ -3826,22 +4253,28 @@ instanceCommand.addCommand(keypairCommand);
|
|
|
3826
4253
|
instanceCommand.addCommand(volumeCommand);
|
|
3827
4254
|
instanceCommand.addCommand(volumesCommand);
|
|
3828
4255
|
program.addCommand(instanceCommand);
|
|
3829
|
-
var networkCommand = new
|
|
4256
|
+
var networkCommand = new import_commander38.Command("network").description("VPC\xB7\uC11C\uBE0C\uB137 \uC870\uD68C");
|
|
3830
4257
|
networkCommand.addCommand(listCommand3);
|
|
3831
4258
|
networkCommand.addCommand(subnetCommand);
|
|
3832
4259
|
program.addCommand(networkCommand);
|
|
3833
|
-
var volumeCommand2 = new
|
|
4260
|
+
var volumeCommand2 = new import_commander38.Command("volume").description("Block Storage \uBCFC\uB968 \uAD00\uB828 \uBA85\uB839");
|
|
3834
4261
|
volumeCommand2.addCommand(listCommand2);
|
|
3835
4262
|
volumeCommand2.addCommand(getCommand);
|
|
3836
4263
|
volumeCommand2.addCommand(createCommand);
|
|
3837
4264
|
program.addCommand(volumeCommand2);
|
|
3838
|
-
var floatingipCommand = new
|
|
4265
|
+
var floatingipCommand = new import_commander38.Command("floatingip").description(
|
|
3839
4266
|
"Floating IP(\uC778\uC2A4\uD134\uC2A4 \uACF5\uC778 IP) \uAD00\uB9AC"
|
|
3840
4267
|
);
|
|
3841
4268
|
floatingipCommand.addCommand(listCommand4);
|
|
3842
4269
|
floatingipCommand.addCommand(createCommand2);
|
|
3843
4270
|
floatingipCommand.addCommand(deleteCommand);
|
|
3844
4271
|
program.addCommand(floatingipCommand);
|
|
4272
|
+
var ncrCommand = new import_commander38.Command("ncr").description("NHN Container Registry \uAD00\uB828 \uBA85\uB839");
|
|
4273
|
+
ncrCommand.addCommand(listCommand5);
|
|
4274
|
+
ncrCommand.addCommand(getCommand3);
|
|
4275
|
+
ncrCommand.addCommand(imagesCommand2);
|
|
4276
|
+
ncrCommand.addCommand(tagsCommand);
|
|
4277
|
+
program.addCommand(ncrCommand);
|
|
3845
4278
|
program.parseAsync().catch((err) => {
|
|
3846
4279
|
const message = err instanceof Error ? err.message : String(err);
|
|
3847
4280
|
const exitCode = err instanceof NhnCloudCliError ? err.exitCode : 1;
|