@bifos/nhncloud-cli 0.6.0 → 0.8.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/dist/index.js CHANGED
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/index.ts
27
- var import_commander42 = require("commander");
28
- var import_chalk14 = __toESM(require("chalk"));
27
+ var import_commander46 = require("commander");
28
+ var import_chalk16 = __toESM(require("chalk"));
29
29
 
30
30
  // src/utils/spinner.ts
31
31
  var import_ora = __toESM(require("ora"));
@@ -567,6 +567,20 @@ function nksHost(region) {
567
567
  }
568
568
  return host;
569
569
  }
570
+ var NCS_HOST = {
571
+ kr1: "kr1-ncs.api.nhncloudservice.com",
572
+ kr3: "kr3-ncs.api.nhncloudservice.com"
573
+ };
574
+ function ncsHost(region) {
575
+ const host = NCS_HOST[region];
576
+ if (!host) {
577
+ throw new NhnCloudCliError(
578
+ `\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 NCS region \uC785\uB2C8\uB2E4: "${region}". \uC0AC\uC6A9 \uAC00\uB2A5\uD55C region: ${Object.keys(NCS_HOST).join(", ")}`,
579
+ EXIT_PARAM_ERROR
580
+ );
581
+ }
582
+ return host;
583
+ }
570
584
 
571
585
  // src/api/keystone.ts
572
586
  function isKeystoneTokenResponse(val) {
@@ -1238,6 +1252,40 @@ function output(opts, data) {
1238
1252
  }
1239
1253
  }
1240
1254
 
1255
+ // src/commands/parse-options.ts
1256
+ var POSITIVE_INTEGER_PATTERN = /^[1-9]\d*$/;
1257
+ var NON_NEGATIVE_INTEGER_PATTERN = /^(0|[1-9]\d*)$/;
1258
+ function describeRange({ min, max }) {
1259
+ if (min !== void 0 && max !== void 0) return `${min} \uC774\uC0C1 ${max} \uC774\uD558\uC758 \uC815\uC218`;
1260
+ if (min !== void 0) return `${min} \uC774\uC0C1\uC758 \uC815\uC218`;
1261
+ if (max !== void 0) return `${max} \uC774\uD558\uC758 \uC815\uC218`;
1262
+ return "0 \uC774\uC0C1\uC758 \uC815\uC218";
1263
+ }
1264
+ function throwIntegerOptionError(value, flag, range) {
1265
+ throw new NhnCloudCliError(
1266
+ `${flag} \uB294 ${describeRange(range)}\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
1267
+ EXIT_PARAM_ERROR
1268
+ );
1269
+ }
1270
+ function parseIntegerOption(value, flag, range) {
1271
+ if (value === void 0) return void 0;
1272
+ const pattern = range.min !== void 0 && range.min > 0 ? POSITIVE_INTEGER_PATTERN : NON_NEGATIVE_INTEGER_PATTERN;
1273
+ if (!pattern.test(value)) {
1274
+ throwIntegerOptionError(value, flag, range);
1275
+ }
1276
+ const parsed = Number(value);
1277
+ if (!Number.isInteger(parsed) || range.min !== void 0 && parsed < range.min || range.max !== void 0 && parsed > range.max) {
1278
+ throwIntegerOptionError(value, flag, range);
1279
+ }
1280
+ return parsed;
1281
+ }
1282
+ function parsePositiveIntegerOption(value, flag) {
1283
+ return parseIntegerOption(value, flag, { min: 1 });
1284
+ }
1285
+ function parseNonNegativeIntegerOption(value, flag) {
1286
+ return parseIntegerOption(value, flag, { min: 0 });
1287
+ }
1288
+
1241
1289
  // src/commands/logncrash/search.ts
1242
1290
  function getString(value) {
1243
1291
  return typeof value === "string" ? value : String(value ?? "");
@@ -1259,17 +1307,8 @@ var searchCommand = new import_commander2.Command("search").description("Log & C
1259
1307
  if (!opts.to) {
1260
1308
  throw new NhnCloudCliError("--to \uC635\uC158\uC740 \uD544\uC218\uC785\uB2C8\uB2E4. \uC608: --to now", EXIT_PARAM_ERROR);
1261
1309
  }
1262
- const page = parseInt(opts.page ?? "0", 10);
1263
- const size = parseInt(opts.size ?? "10", 10);
1264
- if (isNaN(page) || page < 0) {
1265
- throw new NhnCloudCliError("--page \uB294 0 \uC774\uC0C1\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
1266
- }
1267
- if (isNaN(size) || size < 1) {
1268
- throw new NhnCloudCliError("--size \uB294 1 \uC774\uC0C1\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
1269
- }
1270
- if (size > 100) {
1271
- throw new NhnCloudCliError("--size \uB294 \uCD5C\uB300 100 \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
1272
- }
1310
+ const page = parseNonNegativeIntegerOption(opts.page ?? "0", "--page");
1311
+ const size = parseIntegerOption(opts.size ?? "10", "--size", { min: 1, max: 100 });
1273
1312
  const fromIso = resolveTime(opts.from);
1274
1313
  const toIso = resolveTime(opts.to);
1275
1314
  assertSearchRange(fromIso, toIso);
@@ -1797,6 +1836,7 @@ async function createDeployClient(profileOpt) {
1797
1836
  // src/commands/deploy/run.ts
1798
1837
  var runCommand = new import_commander5.Command("run").description("\uBC30\uD3EC\uB97C \uC2E4\uD589\uD55C\uB2E4").argument("<target>", "config.json \uC5D0 \uC815\uC758\uB41C deploy target \uC774\uB984").option("--app-key <k>", "target \uC758 appKey override").option("--artifact-id <id>", "target \uC758 artifactId override").option("--server-group-id <id>", "target \uC758 serverGroupId override").option("--scenario-ids <csv>", "target \uC758 scenarioIds override").option("--target-hosts <csv>", "\uB300\uC0C1 \uD638\uC2A4\uD2B8 (\uC0DD\uB7B5 \uC2DC \uC11C\uBC84\uADF8\uB8F9 \uC804\uCCB4)").option("--concurrent <n>", "\uBCD1\uB82C \uBC30\uD3EC \uC218 (\uAE30\uBCF8 1)", "1").option("--next-when-fail", "\uC2DC\uB098\uB9AC\uC624 \uC2E4\uD328 \uC2DC\uC5D0\uB3C4 \uC9C4\uD589").option("--note <s>", "\uBC30\uD3EC \uBA54\uBAA8").option("--async", "\uC989\uC2DC \uBC18\uD658 (\uAE30\uBCF8\uC740 \uC644\uB8CC \uB300\uAE30)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (targetName, _opts, cmd) => {
1799
1838
  const opts = cmd.optsWithGlobals();
1839
+ const concurrentNum = parsePositiveIntegerOption(opts.concurrent ?? "1", "--concurrent");
1800
1840
  const target = await getDeployTarget(targetName);
1801
1841
  const appKey = opts.appKey ?? target.appKey;
1802
1842
  const artifactId = opts.artifactId ?? target.artifactId;
@@ -1812,7 +1852,7 @@ var runCommand = new import_commander5.Command("run").description("\uBC30\uD3EC\
1812
1852
  serverGroupId,
1813
1853
  scenarioIds,
1814
1854
  targetHosts: opts.targetHosts,
1815
- concurrentNum: parseInt(opts.concurrent ?? "1", 10),
1855
+ concurrentNum,
1816
1856
  nextWhenFail: opts.nextWhenFail ?? false,
1817
1857
  deployNote: opts.note,
1818
1858
  async: opts.async ?? false
@@ -2148,6 +2188,15 @@ var downloadCommand = new import_commander12.Command("download").description("\u
2148
2188
  // src/commands/instance/list.ts
2149
2189
  var import_commander13 = require("commander");
2150
2190
 
2191
+ // src/commands/iaas.ts
2192
+ async function resolveIaasTokenContext(opts) {
2193
+ const profileName = await resolveProfileName(opts.profile);
2194
+ const iaas = await getIaasCredential(profileName);
2195
+ const effectiveIaas = opts.region ? { ...iaas, region: opts.region } : iaas;
2196
+ const tokenContext = await getIaasToken(profileName, effectiveIaas);
2197
+ return { profileName, ...tokenContext };
2198
+ }
2199
+
2151
2200
  // src/services/instance/client.ts
2152
2201
  var import_ky7 = __toESM(require("ky"));
2153
2202
  var DEFAULT_TIMEOUT_MS3 = 3e4;
@@ -2695,10 +2744,7 @@ var InstanceClient = class {
2695
2744
 
2696
2745
  // src/commands/instance/helpers.ts
2697
2746
  async function resolveInstanceClient(opts) {
2698
- const profileName = await resolveProfileName(opts.profile);
2699
- const iaas = await getIaasCredential(profileName);
2700
- const effectiveIaas = opts.region ? { ...iaas, region: opts.region } : iaas;
2701
- const { tokenId, computeEndpoint, imageEndpoint } = await getIaasToken(profileName, effectiveIaas);
2747
+ const { profileName, tokenId, computeEndpoint, imageEndpoint } = await resolveIaasTokenContext(opts);
2702
2748
  return { client: new InstanceClient(tokenId, computeEndpoint, imageEndpoint), profileName };
2703
2749
  }
2704
2750
 
@@ -2736,7 +2782,7 @@ function isVolume(val) {
2736
2782
  if (typeof val !== "object" || val === null) return false;
2737
2783
  const obj = val;
2738
2784
  return typeof obj["id"] === "string" && // Cinder 는 --name 미지정 시 null — null 인 볼륨 하나가 list 전체를 거부하지 않게 허용 (isImage 선례).
2739
- (typeof obj["name"] === "string" || obj["name"] === null) && typeof obj["size"] === "number" && typeof obj["status"] === "string" && Array.isArray(obj["attachments"]);
2785
+ (typeof obj["name"] === "string" || obj["name"] === null) && typeof obj["size"] === "number" && typeof obj["status"] === "string" && (obj["availability_zone"] === void 0 || typeof obj["availability_zone"] === "string") && Array.isArray(obj["attachments"]);
2740
2786
  }
2741
2787
  function isVolumesResponse(val) {
2742
2788
  if (typeof val !== "object" || val === null) return false;
@@ -2800,6 +2846,7 @@ var BlockStorageClient = class {
2800
2846
  if (params.name !== void 0) volumeBody["name"] = params.name;
2801
2847
  if (params.description !== void 0) volumeBody["description"] = params.description;
2802
2848
  if (params.volume_type !== void 0) volumeBody["volume_type"] = params.volume_type;
2849
+ if (params.availability_zone !== void 0) volumeBody["availability_zone"] = params.availability_zone;
2803
2850
  if (params.snapshot_id !== void 0) volumeBody["snapshot_id"] = params.snapshot_id;
2804
2851
  try {
2805
2852
  const raw = await import_ky8.default.post(url, {
@@ -2823,10 +2870,7 @@ var BlockStorageClient = class {
2823
2870
 
2824
2871
  // src/commands/volume/helpers.ts
2825
2872
  async function resolveVolumeClient(opts) {
2826
- const profileName = await resolveProfileName(opts.profile);
2827
- const iaas = await getIaasCredential(profileName);
2828
- const effectiveIaas = opts.region ? { ...iaas, region: opts.region } : iaas;
2829
- const { tokenId, blockStorageEndpoint } = await getIaasToken(profileName, effectiveIaas);
2873
+ const { profileName, tokenId, blockStorageEndpoint } = await resolveIaasTokenContext(opts);
2830
2874
  return { client: new BlockStorageClient(tokenId, blockStorageEndpoint), profileName };
2831
2875
  }
2832
2876
 
@@ -2908,7 +2952,7 @@ var getCommand = new import_commander15.Command("get").description("\uB2E8\uC77C
2908
2952
  // src/commands/volume/create.ts
2909
2953
  var import_commander16 = require("commander");
2910
2954
  var import_chalk3 = __toESM(require("chalk"));
2911
- var createCommand = new import_commander16.Command("create").description("\uBCFC\uB968\uC744 \uBC1C\uAE09\uD55C\uB2E4").requiredOption("--size <gb>", "\uBCFC\uB968 \uD06C\uAE30(GB) \u2014 \uD544\uC218").option("--name <name>", "\uBCFC\uB968 \uC774\uB984").option("--description <text>", "\uBCFC\uB968 \uC124\uBA85").option("--volume-type <type>", "\uBCFC\uB968 \uD0C0\uC785").option("--snapshot-id <id>", "\uC2A4\uB0C5\uC0F7 ID (\uC2A4\uB0C5\uC0F7\uC5D0\uC11C \uBCFC\uB968 \uC0DD\uC131)").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) => {
2955
+ var createCommand = new import_commander16.Command("create").description("\uBCFC\uB968\uC744 \uBC1C\uAE09\uD55C\uB2E4").requiredOption("--size <gb>", "\uBCFC\uB968 \uD06C\uAE30(GB) \u2014 \uD544\uC218").option("--name <name>", "\uBCFC\uB968 \uC774\uB984").option("--description <text>", "\uBCFC\uB968 \uC124\uBA85").option("--volume-type <type>", "\uBCFC\uB968 \uD0C0\uC785").option("--availability-zone <az>", "\uAC00\uC6A9\uC131 \uC601\uC5ED(AZ). instance availability-zones \uB85C \uC870\uD68C\uD55C zoneName \uC9C0\uC815").option("--snapshot-id <id>", "\uC2A4\uB0C5\uC0F7 ID (\uC2A4\uB0C5\uC0F7\uC5D0\uC11C \uBCFC\uB968 \uC0DD\uC131)").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) => {
2912
2956
  const opts = cmd.optsWithGlobals();
2913
2957
  if (!/^[1-9]\d*$/.test(opts.size)) {
2914
2958
  throw new NhnCloudCliError(
@@ -2917,6 +2961,13 @@ var createCommand = new import_commander16.Command("create").description("\uBCFC
2917
2961
  );
2918
2962
  }
2919
2963
  const sizeNum = Number(opts.size);
2964
+ const availabilityZone = opts.availabilityZone?.trim();
2965
+ if (opts.availabilityZone !== void 0 && availabilityZone === "") {
2966
+ throw new NhnCloudCliError(
2967
+ `--availability-zone \uC740 \uACF5\uBC31\uC774 \uC544\uB2CC \uBB38\uC790\uC5F4\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4: ${JSON.stringify(opts.availabilityZone)}`,
2968
+ EXIT_PARAM_ERROR
2969
+ );
2970
+ }
2920
2971
  const { client } = await resolveVolumeClient(opts);
2921
2972
  startSpinner("\uBCFC\uB968 \uBC1C\uAE09 \uC911...");
2922
2973
  let volume;
@@ -2926,6 +2977,7 @@ var createCommand = new import_commander16.Command("create").description("\uBCFC
2926
2977
  name: opts.name,
2927
2978
  description: opts.description,
2928
2979
  volume_type: opts.volumeType,
2980
+ availability_zone: availabilityZone,
2929
2981
  snapshot_id: opts.snapshotId
2930
2982
  });
2931
2983
  } catch (err) {
@@ -2941,6 +2993,7 @@ var createCommand = new import_commander16.Command("create").description("\uBCFC
2941
2993
  ["size", String(volume.size)],
2942
2994
  ["status", volume.status],
2943
2995
  ["volume_type", volume.volume_type ?? ""],
2996
+ ["availability_zone", volume.availability_zone ?? ""],
2944
2997
  ["created_at", volume.created_at]
2945
2998
  ];
2946
2999
  output(opts, {
@@ -3127,10 +3180,7 @@ var NetworkClient = class {
3127
3180
 
3128
3181
  // src/commands/network/helpers.ts
3129
3182
  async function resolveNetworkClient(opts) {
3130
- const profileName = await resolveProfileName(opts.profile);
3131
- const iaas = await getIaasCredential(profileName);
3132
- const effectiveIaas = opts.region ? { ...iaas, region: opts.region } : iaas;
3133
- const { tokenId, networkEndpoint } = await getIaasToken(profileName, effectiveIaas);
3183
+ const { profileName, tokenId, networkEndpoint } = await resolveIaasTokenContext(opts);
3134
3184
  return { client: new NetworkClient(tokenId, networkEndpoint), profileName };
3135
3185
  }
3136
3186
 
@@ -3295,18 +3345,10 @@ var deleteCommand = new import_commander21.Command("delete").description("Floati
3295
3345
 
3296
3346
  // src/commands/instance/flavors.ts
3297
3347
  var import_commander22 = require("commander");
3298
- function parseNonNegInt(value, flag) {
3299
- if (value === void 0) return void 0;
3300
- const n = Number(value);
3301
- if (!Number.isInteger(n) || n < 0) {
3302
- throw new NhnCloudCliError(`${flag} \uB294 0 \uC774\uC0C1\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${value}).`, EXIT_PARAM_ERROR);
3303
- }
3304
- return n;
3305
- }
3306
3348
  var flavorsCommand = new import_commander22.Command("flavors").description("\uC778\uC2A4\uD134\uC2A4 \uD0C0\uC785(flavor)\uC744 \uC870\uD68C\uD55C\uB2E4 (\uAE30\uBCF8 id\xB7name, --detail \uB85C \uC2A4\uD399, \uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--detail", "vcpus\xB7ram\xB7disk \uB4F1 \uC2A4\uD399 \uD3EC\uD568 (GET /flavors/detail)").option("--min-disk <gb>", "\uCD5C\uC18C \uBE14\uB85D \uC2A4\uD1A0\uB9AC\uC9C0 \uD06C\uAE30(GB) \uC774\uC0C1\uB9CC \uD544\uD130").option("--min-ram <mb>", "\uCD5C\uC18C RAM \uD06C\uAE30(MB) \uC774\uC0C1\uB9CC \uD544\uD130").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) => {
3307
3349
  const opts = cmd.optsWithGlobals();
3308
- const minDisk = parseNonNegInt(opts.minDisk, "--min-disk");
3309
- const minRam = parseNonNegInt(opts.minRam, "--min-ram");
3350
+ const minDisk = parseNonNegativeIntegerOption(opts.minDisk, "--min-disk");
3351
+ const minRam = parseNonNegativeIntegerOption(opts.minRam, "--min-ram");
3310
3352
  const { client } = await resolveInstanceClient(opts);
3311
3353
  startSpinner("\uC778\uC2A4\uD134\uC2A4 \uD0C0\uC785 \uC870\uD68C \uC911...");
3312
3354
  try {
@@ -3463,7 +3505,9 @@ var createCommand3 = new import_commander25.Command("create").description("\uC77
3463
3505
  );
3464
3506
  }
3465
3507
  }
3466
- const timeoutMs = parseInt(opts.timeout ?? "300", 10) * 1e3;
3508
+ const timeoutMs = parsePositiveIntegerOption(opts.timeout ?? "300", "--timeout") * 1e3;
3509
+ const bootVolumeSize = parsePositiveIntegerOption(opts.bootVolumeSize, "--boot-volume-size");
3510
+ const ephemeralDiskSize = parsePositiveIntegerOption(opts.ephemeralDiskSize, "--ephemeral-disk-size");
3467
3511
  const { client } = await resolveInstanceClient(opts);
3468
3512
  startSpinner("\uC778\uC2A4\uD134\uC2A4 \uC0DD\uC131 \uC911...");
3469
3513
  let server;
@@ -3473,10 +3517,10 @@ var createCommand3 = new import_commander25.Command("create").description("\uC77
3473
3517
  flavorRef: opts.flavor,
3474
3518
  imageRef: opts.image,
3475
3519
  networks,
3476
- bootVolumeSize: opts.bootVolumeSize !== void 0 ? parseInt(opts.bootVolumeSize, 10) : void 0,
3520
+ bootVolumeSize,
3477
3521
  keyName: opts.keyName,
3478
3522
  securityGroups: opts.securityGroup && opts.securityGroup.length > 0 ? opts.securityGroup : void 0,
3479
- ephemeralDiskSize: opts.ephemeralDiskSize !== void 0 ? parseInt(opts.ephemeralDiskSize, 10) : void 0,
3523
+ ephemeralDiskSize,
3480
3524
  protect: opts.protect,
3481
3525
  userDataBase64
3482
3526
  });
@@ -3658,17 +3702,9 @@ var resizeRevertCommand = new import_commander28.Command("resize-revert").descri
3658
3702
  // src/commands/instance/images.ts
3659
3703
  var import_commander29 = require("commander");
3660
3704
  var VISIBILITY_VALUES = ["public", "private", "shared"];
3661
- function parsePositiveInt5(value, flag) {
3662
- if (value === void 0) return void 0;
3663
- const n = Number(value);
3664
- if (!Number.isInteger(n) || n < 1) {
3665
- throw new NhnCloudCliError(`${flag} \uB294 1 \uC774\uC0C1\uC758 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${value}).`, EXIT_PARAM_ERROR);
3666
- }
3667
- return n;
3668
- }
3669
3705
  var imagesCommand = new import_commander29.Command("images").description("\uC774\uBBF8\uC9C0 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4 (create --image <id> \uC18C\uC2A4, \uC804\uCCB4 \uD544\uB4DC\uB294 --json)").option("--limit <n>", "\uD55C \uD398\uC774\uC9C0 \uCD5C\uB300 \uAC1C\uC218 (\uAE30\uBCF8: \uC11C\uBC84 \uAE30\uBCF8\uAC12 25)").option("--marker <id>", "\uC774 image id \uB2E4\uC74C\uBD80\uD130 \uC870\uD68C (\uD398\uC774\uC9C0\uB124\uC774\uC158)").option("--name <name>", "\uC774\uB984\uC73C\uB85C \uD544\uD130").option("--visibility <v>", `\uB178\uCD9C \uBC94\uC704 \uD544\uD130 (${VISIBILITY_VALUES.join("|")})`).option("--owner <id>", "\uC18C\uC720\uC790(\uD504\uB85C\uC81D\uD2B8 id)\uB85C \uD544\uD130").option("--status <status>", "\uC0C1\uD0DC\uB85C \uD544\uD130 (\uC608: active)").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) => {
3670
3706
  const opts = cmd.optsWithGlobals();
3671
- const limit = parsePositiveInt5(opts.limit, "--limit");
3707
+ const limit = parsePositiveIntegerOption(opts.limit, "--limit");
3672
3708
  if (opts.visibility !== void 0 && !VISIBILITY_VALUES.includes(opts.visibility)) {
3673
3709
  throw new NhnCloudCliError(
3674
3710
  `--visibility \uB294 ${VISIBILITY_VALUES.join(" | ")} \uC911 \uD558\uB098\uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${opts.visibility}).`,
@@ -4225,8 +4261,63 @@ var tagsCommand = new import_commander37.Command("tags").description("\uD2B9\uC8
4225
4261
  });
4226
4262
  });
4227
4263
 
4228
- // src/commands/nks/supports.ts
4264
+ // src/commands/commands.ts
4229
4265
  var import_commander38 = require("commander");
4266
+ function commandPath(command) {
4267
+ const names = [];
4268
+ let current2 = command;
4269
+ while (current2?.parent) {
4270
+ names.unshift(current2.name());
4271
+ current2 = current2.parent;
4272
+ }
4273
+ return names.join(" ");
4274
+ }
4275
+ function collectCommand(command) {
4276
+ const path = commandPath(command);
4277
+ if (!path || path === "help") return null;
4278
+ return {
4279
+ path,
4280
+ description: command.description() || command.summary() || "",
4281
+ arguments: command.registeredArguments.map((arg) => arg.name()),
4282
+ options: command.options.filter((option) => !option.hidden).map((option) => option.flags),
4283
+ subcommands: command.commands.map((subcommand) => subcommand.name()).filter((name) => name !== "help"),
4284
+ ...path === "commands" ? { metadata: true } : {}
4285
+ };
4286
+ }
4287
+ function collectCommandCatalog(program2) {
4288
+ const commands = [];
4289
+ function visit(command) {
4290
+ const entry = collectCommand(command);
4291
+ if (entry) commands.push(entry);
4292
+ for (const subcommand of command.commands) {
4293
+ visit(subcommand);
4294
+ }
4295
+ }
4296
+ for (const command of program2.commands) {
4297
+ visit(command);
4298
+ }
4299
+ commands.sort((a, b) => a.path.localeCompare(b.path));
4300
+ return { commands };
4301
+ }
4302
+ function createCommandsCommand(program2) {
4303
+ return new import_commander38.Command("commands").description("\uBA85\uB839 \uACBD\uB85C\uC640 \uC635\uC158 catalog\uB97C \uCD9C\uB825\uD55C\uB2E4").action((_opts, cmd) => {
4304
+ const opts = cmd.optsWithGlobals();
4305
+ const catalog = collectCommandCatalog(program2);
4306
+ output(opts, {
4307
+ headers: ["path", "description", "options"],
4308
+ rows: catalog.commands.map((entry) => [
4309
+ entry.path,
4310
+ entry.description,
4311
+ entry.options.join(", ")
4312
+ ]),
4313
+ raw: catalog,
4314
+ ids: catalog.commands.map((entry) => entry.path)
4315
+ });
4316
+ });
4317
+ }
4318
+
4319
+ // src/commands/nks/supports.ts
4320
+ var import_commander39 = require("commander");
4230
4321
 
4231
4322
  // src/commands/nks/helpers.ts
4232
4323
  var import_promises4 = require("fs/promises");
@@ -4238,7 +4329,13 @@ var import_ky11 = __toESM(require("ky"));
4238
4329
  function isNksClusterSummary(val) {
4239
4330
  if (typeof val !== "object" || val === null) return false;
4240
4331
  const obj = val;
4241
- return typeof obj["uuid"] === "string" && typeof obj["name"] === "string" && typeof obj["status"] === "string" && typeof obj["health_status"] === "string" && (typeof obj["node_count"] === "number" || typeof obj["node_count"] === "string") && typeof obj["kube_tag"] === "string";
4332
+ return typeof obj["uuid"] === "string" && typeof obj["name"] === "string" && typeof obj["status"] === "string" && typeof obj["health_status"] === "string" && (typeof obj["node_count"] === "number" || typeof obj["node_count"] === "string");
4333
+ }
4334
+ function nksClusterKubeTag(cluster) {
4335
+ const fromLabels = cluster.labels?.["kube_tag"];
4336
+ if (typeof fromLabels === "string") return fromLabels;
4337
+ if (typeof cluster.kube_tag === "string") return cluster.kube_tag;
4338
+ return "-";
4242
4339
  }
4243
4340
  function isNksSupports(val) {
4244
4341
  if (typeof val !== "object" || val === null) return false;
@@ -4287,15 +4384,16 @@ function isNksUuidResponse(val) {
4287
4384
 
4288
4385
  // src/services/nks/client.ts
4289
4386
  var DEFAULT_TIMEOUT_MS7 = 3e4;
4290
- function isClustersResponse(val) {
4387
+ function isArrayFieldResponse(key, val, itemGuard) {
4291
4388
  if (typeof val !== "object" || val === null) return false;
4292
- const obj = val;
4293
- return Array.isArray(obj["clusters"]) && obj["clusters"].every(isNksClusterSummary);
4389
+ const field = val[key];
4390
+ return Array.isArray(field) && field.every(itemGuard);
4391
+ }
4392
+ function isClustersResponse(val) {
4393
+ return isArrayFieldResponse("clusters", val, isNksClusterSummary);
4294
4394
  }
4295
4395
  function isNamedResourceArrayResponse(key, val) {
4296
- if (typeof val !== "object" || val === null) return false;
4297
- const obj = val;
4298
- return Array.isArray(obj[key]) && obj[key].every(isNksNamedResource);
4396
+ return isArrayFieldResponse(key, val, isNksNamedResource);
4299
4397
  }
4300
4398
  function isConfigResponse(val) {
4301
4399
  if (typeof val !== "object" || val === null) return false;
@@ -4303,19 +4401,13 @@ function isConfigResponse(val) {
4303
4401
  return typeof obj["config"] === "string";
4304
4402
  }
4305
4403
  function isNodeGroupsResponse(val) {
4306
- if (typeof val !== "object" || val === null) return false;
4307
- const obj = val;
4308
- return Array.isArray(obj["nodegroups"]) && obj["nodegroups"].every(isNksNodeGroupSummary);
4404
+ return isArrayFieldResponse("nodegroups", val, isNksNodeGroupSummary);
4309
4405
  }
4310
4406
  function isAddonTypesResponse(val) {
4311
- if (typeof val !== "object" || val === null) return false;
4312
- const obj = val;
4313
- return Array.isArray(obj["addon_types"]) && obj["addon_types"].every(isNksAddonType);
4407
+ return isArrayFieldResponse("addon_types", val, isNksAddonType);
4314
4408
  }
4315
4409
  function isAddonsResponse(val) {
4316
- if (typeof val !== "object" || val === null) return false;
4317
- const obj = val;
4318
- return Array.isArray(obj["addons"]) && obj["addons"].every(isNksAddon);
4410
+ return isArrayFieldResponse("addons", val, isNksAddon);
4319
4411
  }
4320
4412
  var NksClient = class {
4321
4413
  tokenId;
@@ -4730,10 +4822,7 @@ var NksClient = class {
4730
4822
 
4731
4823
  // src/commands/nks/helpers.ts
4732
4824
  async function resolveNksClient(opts) {
4733
- const profileName = await resolveProfileName(opts.profile);
4734
- const iaas = await getIaasCredential(profileName);
4735
- const effectiveIaas = opts.region ? { ...iaas, region: opts.region } : iaas;
4736
- const { tokenId, nksEndpoint } = await getIaasToken(profileName, effectiveIaas);
4825
+ const { profileName, tokenId, nksEndpoint } = await resolveIaasTokenContext(opts);
4737
4826
  return { client: new NksClient(tokenId, nksEndpoint), profileName };
4738
4827
  }
4739
4828
  async function readJsonFile(path) {
@@ -4777,7 +4866,7 @@ function parseNonNegativeInteger(value, optionName) {
4777
4866
  }
4778
4867
 
4779
4868
  // src/commands/nks/supports.ts
4780
- var supportsCommand = new import_commander38.Command("supports").description("NKS \uC9C0\uC6D0 Kubernetes \uBC84\uC804\uACFC event type \uC744 \uC870\uD68C\uD55C\uB2E4").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) => {
4869
+ var supportsCommand = new import_commander39.Command("supports").description("NKS \uC9C0\uC6D0 Kubernetes \uBC84\uC804\uACFC event type \uC744 \uC870\uD68C\uD55C\uB2E4").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) => {
4781
4870
  const opts = cmd.optsWithGlobals();
4782
4871
  const { client } = await resolveNksClient(opts);
4783
4872
  startSpinner("NKS \uC9C0\uC6D0 \uC815\uBCF4 \uC870\uD68C \uC911...");
@@ -4802,9 +4891,9 @@ var supportsCommand = new import_commander38.Command("supports").description("NK
4802
4891
 
4803
4892
  // src/commands/nks/cluster.ts
4804
4893
  var import_promises5 = require("fs/promises");
4805
- var import_commander39 = require("commander");
4894
+ var import_commander40 = require("commander");
4806
4895
  var import_chalk12 = __toESM(require("chalk"));
4807
- var listCommand6 = new import_commander39.Command("list").description("NKS \uD074\uB7EC\uC2A4\uD130 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").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) => {
4896
+ var listCommand6 = new import_commander40.Command("list").description("NKS \uD074\uB7EC\uC2A4\uD130 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").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) => {
4808
4897
  const opts = cmd.optsWithGlobals();
4809
4898
  const { client } = await resolveNksClient(opts);
4810
4899
  startSpinner("NKS \uD074\uB7EC\uC2A4\uD130 \uBAA9\uB85D \uC870\uD68C \uC911...");
@@ -4824,7 +4913,7 @@ var listCommand6 = new import_commander39.Command("list").description("NKS \uD07
4824
4913
  cluster.status,
4825
4914
  cluster.health_status,
4826
4915
  String(cluster.node_count),
4827
- cluster.kube_tag
4916
+ nksClusterKubeTag(cluster)
4828
4917
  ]),
4829
4918
  raw: clusters,
4830
4919
  ids: clusters.map((cluster) => cluster.uuid)
@@ -4900,7 +4989,7 @@ async function writeKubeconfigFile(path, contents, force) {
4900
4989
  throw err;
4901
4990
  }
4902
4991
  }
4903
- var createCommand4 = new import_commander39.Command("create").description("NKS \uD074\uB7EC\uC2A4\uD130\uB97C \uC0DD\uC131\uD55C\uB2E4").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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) => {
4992
+ var createCommand4 = new import_commander40.Command("create").description("NKS \uD074\uB7EC\uC2A4\uD130\uB97C \uC0DD\uC131\uD55C\uB2E4").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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) => {
4904
4993
  const opts = cmd.optsWithGlobals();
4905
4994
  const payload = await readJsonFile(opts.file);
4906
4995
  const { client } = await resolveNksClient(opts);
@@ -4915,7 +5004,7 @@ var createCommand4 = new import_commander39.Command("create").description("NKS \
4915
5004
  stopSpinner(true);
4916
5005
  uuidOutput(opts, result, "\uD074\uB7EC\uC2A4\uD130 \uC0DD\uC131");
4917
5006
  });
4918
- var deleteCommand3 = new import_commander39.Command("delete").description("NKS \uD074\uB7EC\uC2A4\uD130\uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").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 (cluster, _opts, cmd) => {
5007
+ var deleteCommand3 = new import_commander40.Command("delete").description("NKS \uD074\uB7EC\uC2A4\uD130\uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").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 (cluster, _opts, cmd) => {
4919
5008
  const opts = cmd.optsWithGlobals();
4920
5009
  const ok = await confirmDangerousAction(`NKS \uD074\uB7EC\uC2A4\uD130 "${cluster}" \uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
4921
5010
  if (!ok) return;
@@ -4931,7 +5020,7 @@ var deleteCommand3 = new import_commander39.Command("delete").description("NKS \
4931
5020
  process.stderr.write(import_chalk12.default.green(`\u2713 NKS \uD074\uB7EC\uC2A4\uD130 "${cluster}" \uC0AD\uC81C \uC694\uCCAD \uC644\uB8CC
4932
5021
  `));
4933
5022
  });
4934
- var resizeCommand2 = new import_commander39.Command("resize").description("NKS \uD074\uB7EC\uC2A4\uD130 \uB178\uB4DC \uADF8\uB8F9 \uD06C\uAE30\uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--nodegroup <name-or-uuid>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--node-count <n>", "\uBCC0\uACBD\uD560 \uB178\uB4DC \uC218").option("--nodes-to-remove <csv>", "\uC0AD\uC81C\uD560 \uB178\uB4DC \uC774\uB984/ID CSV").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 (cluster, _opts, cmd) => {
5023
+ var resizeCommand2 = new import_commander40.Command("resize").description("NKS \uD074\uB7EC\uC2A4\uD130 \uB178\uB4DC \uADF8\uB8F9 \uD06C\uAE30\uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--nodegroup <name-or-uuid>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--node-count <n>", "\uBCC0\uACBD\uD560 \uB178\uB4DC \uC218").option("--nodes-to-remove <csv>", "\uC0AD\uC81C\uD560 \uB178\uB4DC \uC774\uB984/ID CSV").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 (cluster, _opts, cmd) => {
4935
5024
  const opts = cmd.optsWithGlobals();
4936
5025
  const nodeCount = parsePositiveInteger(opts.nodeCount, "--node-count");
4937
5026
  const nodesToRemove = opts.nodesToRemove?.split(",").map((node) => node.trim()).filter(Boolean);
@@ -4955,7 +5044,7 @@ var resizeCommand2 = new import_commander39.Command("resize").description("NKS \
4955
5044
  stopSpinner(true);
4956
5045
  uuidOutput(opts, result, "\uD074\uB7EC\uC2A4\uD130 resize");
4957
5046
  });
4958
- var setIpAclCommand = new import_commander39.Command("set-ipacl").description("NKS \uD074\uB7EC\uC2A4\uD130 API endpoint IP ACL \uC744 \uC124\uC815\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, _opts, cmd) => {
5047
+ var setIpAclCommand = new import_commander40.Command("set-ipacl").description("NKS \uD074\uB7EC\uC2A4\uD130 API endpoint IP ACL \uC744 \uC124\uC815\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, _opts, cmd) => {
4959
5048
  const opts = cmd.optsWithGlobals();
4960
5049
  const payload = await readJsonFile(opts.file);
4961
5050
  const { client } = await resolveNksClient(opts);
@@ -4970,7 +5059,7 @@ var setIpAclCommand = new import_commander39.Command("set-ipacl").description("N
4970
5059
  stopSpinner(true);
4971
5060
  uuidOutput(opts, result, "IP ACL \uC124\uC815");
4972
5061
  });
4973
- var renewCertificateCommand = new import_commander39.Command("renew-certificate").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC778\uC99D\uC11C\uB97C \uAC31\uC2E0\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--term-of-validity <1-5>", "\uC778\uC99D\uC11C \uC720\uD6A8 \uAE30\uAC04(\uB144)").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 (cluster, _opts, cmd) => {
5062
+ var renewCertificateCommand = new import_commander40.Command("renew-certificate").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC778\uC99D\uC11C\uB97C \uAC31\uC2E0\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--term-of-validity <1-5>", "\uC778\uC99D\uC11C \uC720\uD6A8 \uAE30\uAC04(\uB144)").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 (cluster, _opts, cmd) => {
4974
5063
  const opts = cmd.optsWithGlobals();
4975
5064
  const term = parsePositiveInteger(opts.termOfValidity, "--term-of-validity");
4976
5065
  if (term < 1 || term > 5) {
@@ -4988,7 +5077,7 @@ var renewCertificateCommand = new import_commander39.Command("renew-certificate"
4988
5077
  stopSpinner(true);
4989
5078
  uuidOutput(opts, result, "\uC778\uC99D\uC11C \uAC31\uC2E0");
4990
5079
  });
4991
- var updateSgwCommand = new import_commander39.Command("update-sgw").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC11C\uBE44\uC2A4 \uAC8C\uC774\uD2B8\uC6E8\uC774\uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--ncr-sgw <uuid>", "NCR service gateway UUID").requiredOption("--obs-sgw <uuid>", "Object Storage service gateway 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 (cluster, _opts, cmd) => {
5080
+ var updateSgwCommand = new import_commander40.Command("update-sgw").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC11C\uBE44\uC2A4 \uAC8C\uC774\uD2B8\uC6E8\uC774\uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--ncr-sgw <uuid>", "NCR service gateway UUID").requiredOption("--obs-sgw <uuid>", "Object Storage service gateway 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 (cluster, _opts, cmd) => {
4992
5081
  const opts = cmd.optsWithGlobals();
4993
5082
  const { client } = await resolveNksClient(opts);
4994
5083
  startSpinner("NKS \uC11C\uBE44\uC2A4 \uAC8C\uC774\uD2B8\uC6E8\uC774 \uBCC0\uACBD \uC694\uCCAD \uC911...");
@@ -5002,7 +5091,7 @@ var updateSgwCommand = new import_commander39.Command("update-sgw").description(
5002
5091
  stopSpinner(true);
5003
5092
  uuidOutput(opts, result, "\uC11C\uBE44\uC2A4 \uAC8C\uC774\uD2B8\uC6E8\uC774 \uBCC0\uACBD");
5004
5093
  });
5005
- var setControlPlaneLogCommand = new import_commander39.Command("set-control-plane-log").description("NKS \uD074\uB7EC\uC2A4\uD130 control plane log \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "control_plane_log \uAC1D\uCCB4 JSON \uD30C\uC77C").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 (cluster, _opts, cmd) => {
5094
+ var setControlPlaneLogCommand = new import_commander40.Command("set-control-plane-log").description("NKS \uD074\uB7EC\uC2A4\uD130 control plane log \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "control_plane_log \uAC1D\uCCB4 JSON \uD30C\uC77C").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 (cluster, _opts, cmd) => {
5006
5095
  const opts = cmd.optsWithGlobals();
5007
5096
  const controlPlaneLog = await readJsonFile(opts.file);
5008
5097
  const { client } = await resolveNksClient(opts);
@@ -5017,7 +5106,7 @@ var setControlPlaneLogCommand = new import_commander39.Command("set-control-plan
5017
5106
  stopSpinner(true);
5018
5107
  uuidOutput(opts, result, "control plane log \uC124\uC815");
5019
5108
  });
5020
- var getCommand4 = new import_commander39.Command("get").description("NKS \uD074\uB7EC\uC2A4\uD130\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5109
+ var getCommand4 = new import_commander40.Command("get").description("NKS \uD074\uB7EC\uC2A4\uD130\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5021
5110
  const opts = cmd.optsWithGlobals();
5022
5111
  const { client } = await resolveNksClient(opts);
5023
5112
  startSpinner("NKS \uD074\uB7EC\uC2A4\uD130 \uC870\uD68C \uC911...");
@@ -5036,7 +5125,7 @@ var getCommand4 = new import_commander39.Command("get").description("NKS \uD074\
5036
5125
  ids: [resourceId(result)]
5037
5126
  });
5038
5127
  });
5039
- var eventsCommand = new import_commander39.Command("events").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC791\uC5C5 \uC774\uB825\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5128
+ var eventsCommand = new import_commander40.Command("events").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC791\uC5C5 \uC774\uB825\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5040
5129
  const opts = cmd.optsWithGlobals();
5041
5130
  const { client } = await resolveNksClient(opts);
5042
5131
  startSpinner("NKS \uD074\uB7EC\uC2A4\uD130 \uC791\uC5C5 \uC774\uB825 \uC870\uD68C \uC911...");
@@ -5055,7 +5144,7 @@ var eventsCommand = new import_commander39.Command("events").description("NKS \u
5055
5144
  ids: events.map(resourceId)
5056
5145
  });
5057
5146
  });
5058
- var eventCommand = new import_commander39.Command("event").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC791\uC5C5 \uC774\uB825 \uB2E8\uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<event>", "\uC791\uC5C5 \uC774\uB825 UUID \uB610\uB294 ID").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 (cluster, event, _opts, cmd) => {
5147
+ var eventCommand = new import_commander40.Command("event").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC791\uC5C5 \uC774\uB825 \uB2E8\uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<event>", "\uC791\uC5C5 \uC774\uB825 UUID \uB610\uB294 ID").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 (cluster, event, _opts, cmd) => {
5059
5148
  const opts = cmd.optsWithGlobals();
5060
5149
  const { client } = await resolveNksClient(opts);
5061
5150
  startSpinner("NKS \uD074\uB7EC\uC2A4\uD130 \uC791\uC5C5 \uC774\uB825 \uC870\uD68C \uC911...");
@@ -5074,7 +5163,7 @@ var eventCommand = new import_commander39.Command("event").description("NKS \uD0
5074
5163
  ids: [resourceId(result)]
5075
5164
  });
5076
5165
  });
5077
- var kubeconfigCommand = new import_commander39.Command("kubeconfig").description("NKS \uD074\uB7EC\uC2A4\uD130 kubeconfig \uB97C \uCD9C\uB825\uD558\uAC70\uB098 \uC800\uC7A5\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").option("--output <file>", "kubeconfig \uC800\uC7A5 \uACBD\uB85C").option("--force", "\uAE30\uC874 \uD30C\uC77C \uB36E\uC5B4\uC4F0\uAE30").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 (cluster, _opts, cmd) => {
5166
+ var kubeconfigCommand = new import_commander40.Command("kubeconfig").description("NKS \uD074\uB7EC\uC2A4\uD130 kubeconfig \uB97C \uCD9C\uB825\uD558\uAC70\uB098 \uC800\uC7A5\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").option("--output <file>", "kubeconfig \uC800\uC7A5 \uACBD\uB85C").option("--force", "\uAE30\uC874 \uD30C\uC77C \uB36E\uC5B4\uC4F0\uAE30").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 (cluster, _opts, cmd) => {
5078
5167
  const opts = cmd.optsWithGlobals();
5079
5168
  const { client } = await resolveNksClient(opts);
5080
5169
  startSpinner("NKS kubeconfig \uC870\uD68C \uC911...");
@@ -5094,7 +5183,7 @@ var kubeconfigCommand = new import_commander39.Command("kubeconfig").description
5094
5183
  }
5095
5184
  process.stdout.write(kubeconfig.endsWith("\n") ? kubeconfig : kubeconfig + "\n");
5096
5185
  });
5097
- var ipAclCommand = new import_commander39.Command("ipacl").description("NKS \uD074\uB7EC\uC2A4\uD130 API endpoint IP ACL \uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5186
+ var ipAclCommand = new import_commander40.Command("ipacl").description("NKS \uD074\uB7EC\uC2A4\uD130 API endpoint IP ACL \uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5098
5187
  const opts = cmd.optsWithGlobals();
5099
5188
  const { client } = await resolveNksClient(opts);
5100
5189
  startSpinner("NKS IP ACL \uC870\uD68C \uC911...");
@@ -5113,7 +5202,7 @@ var ipAclCommand = new import_commander39.Command("ipacl").description("NKS \uD0
5113
5202
  ids: [result.cluster_uuid]
5114
5203
  });
5115
5204
  });
5116
- var clusterAddonListCommand = new import_commander39.Command("list").description("NKS \uD074\uB7EC\uC2A4\uD130\uC5D0 \uC124\uCE58\uB41C \uC560\uB4DC\uC628 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5205
+ var clusterAddonListCommand = new import_commander40.Command("list").description("NKS \uD074\uB7EC\uC2A4\uD130\uC5D0 \uC124\uCE58\uB41C \uC560\uB4DC\uC628 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5117
5206
  const opts = cmd.optsWithGlobals();
5118
5207
  const { client } = await resolveNksClient(opts);
5119
5208
  startSpinner("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 \uBAA9\uB85D \uC870\uD68C \uC911...");
@@ -5132,7 +5221,7 @@ var clusterAddonListCommand = new import_commander39.Command("list").description
5132
5221
  ids: addons.map((addon) => addon.uuid ?? addon.id ?? addon.name)
5133
5222
  });
5134
5223
  });
5135
- var clusterAddonGetCommand = new import_commander39.Command("get").description("NKS \uD074\uB7EC\uC2A4\uD130\uC5D0 \uC124\uCE58\uB41C \uC560\uB4DC\uC628\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").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 (cluster, addon, _opts, cmd) => {
5224
+ var clusterAddonGetCommand = new import_commander40.Command("get").description("NKS \uD074\uB7EC\uC2A4\uD130\uC5D0 \uC124\uCE58\uB41C \uC560\uB4DC\uC628\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").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 (cluster, addon, _opts, cmd) => {
5136
5225
  const opts = cmd.optsWithGlobals();
5137
5226
  const { client } = await resolveNksClient(opts);
5138
5227
  startSpinner("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 \uC870\uD68C \uC911...");
@@ -5160,7 +5249,7 @@ function parseResolveConflicts(value) {
5160
5249
  EXIT_PARAM_ERROR
5161
5250
  );
5162
5251
  }
5163
- var clusterAddonInstallCommand = new import_commander39.Command("install").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628\uC744 \uC124\uCE58\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--name <name>", "\uC560\uB4DC\uC628 \uC774\uB984").requiredOption("--version <version>", "\uC560\uB4DC\uC628 \uBC84\uC804").requiredOption("--resolve-conflicts <none|overwrite|preserve>", "\uCDA9\uB3CC \uD574\uACB0 \uC815\uCC45").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 (cluster, _opts, cmd) => {
5252
+ var clusterAddonInstallCommand = new import_commander40.Command("install").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628\uC744 \uC124\uCE58\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--name <name>", "\uC560\uB4DC\uC628 \uC774\uB984").requiredOption("--version <version>", "\uC560\uB4DC\uC628 \uBC84\uC804").requiredOption("--resolve-conflicts <none|overwrite|preserve>", "\uCDA9\uB3CC \uD574\uACB0 \uC815\uCC45").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 (cluster, _opts, cmd) => {
5164
5253
  const opts = cmd.optsWithGlobals();
5165
5254
  const resolveConflicts = parseResolveConflicts(opts.resolveConflicts);
5166
5255
  const { client } = await resolveNksClient(opts);
@@ -5179,7 +5268,7 @@ var clusterAddonInstallCommand = new import_commander39.Command("install").descr
5179
5268
  stopSpinner(true);
5180
5269
  uuidOutput(opts, result, "\uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 \uC124\uCE58");
5181
5270
  });
5182
- var clusterAddonUpdateCommand = new import_commander39.Command("update").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628\uC744 \uC5C5\uB370\uC774\uD2B8\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").requiredOption("--version <version>", "\uC560\uB4DC\uC628 \uBC84\uC804").requiredOption("--resolve-conflicts <none|overwrite|preserve>", "\uCDA9\uB3CC \uD574\uACB0 \uC815\uCC45").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 (cluster, addon, _opts, cmd) => {
5271
+ var clusterAddonUpdateCommand = new import_commander40.Command("update").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628\uC744 \uC5C5\uB370\uC774\uD2B8\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").requiredOption("--version <version>", "\uC560\uB4DC\uC628 \uBC84\uC804").requiredOption("--resolve-conflicts <none|overwrite|preserve>", "\uCDA9\uB3CC \uD574\uACB0 \uC815\uCC45").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 (cluster, addon, _opts, cmd) => {
5183
5272
  const opts = cmd.optsWithGlobals();
5184
5273
  const resolveConflicts = parseResolveConflicts(opts.resolveConflicts);
5185
5274
  const { client } = await resolveNksClient(opts);
@@ -5197,7 +5286,7 @@ var clusterAddonUpdateCommand = new import_commander39.Command("update").descrip
5197
5286
  stopSpinner(true);
5198
5287
  uuidOutput(opts, result, "\uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 \uC5C5\uB370\uC774\uD2B8");
5199
5288
  });
5200
- var clusterAddonRemoveCommand = new import_commander39.Command("remove").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628\uC744 \uC81C\uAC70\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").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 (cluster, addon, _opts, cmd) => {
5289
+ var clusterAddonRemoveCommand = new import_commander40.Command("remove").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628\uC744 \uC81C\uAC70\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").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 (cluster, addon, _opts, cmd) => {
5201
5290
  const opts = cmd.optsWithGlobals();
5202
5291
  const ok = await confirmDangerousAction(`NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 "${addon}" \uC744 \uC81C\uAC70\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
5203
5292
  if (!ok) return;
@@ -5213,11 +5302,11 @@ var clusterAddonRemoveCommand = new import_commander39.Command("remove").descrip
5213
5302
  stopSpinner(true);
5214
5303
  uuidOutput(opts, result, "\uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 \uC81C\uAC70");
5215
5304
  });
5216
- var clusterAddonCommand = new import_commander39.Command("addon").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 \uAD00\uB828 \uBA85\uB839").addCommand(clusterAddonListCommand).addCommand(clusterAddonGetCommand).addCommand(clusterAddonInstallCommand).addCommand(clusterAddonUpdateCommand).addCommand(clusterAddonRemoveCommand);
5217
- var clusterCommand = new import_commander39.Command("cluster").description("NKS \uD074\uB7EC\uC2A4\uD130 \uAD00\uB828 \uBA85\uB839").addCommand(listCommand6).addCommand(getCommand4).addCommand(createCommand4).addCommand(deleteCommand3).addCommand(resizeCommand2).addCommand(eventsCommand).addCommand(eventCommand).addCommand(kubeconfigCommand).addCommand(ipAclCommand).addCommand(setIpAclCommand).addCommand(renewCertificateCommand).addCommand(updateSgwCommand).addCommand(setControlPlaneLogCommand).addCommand(clusterAddonCommand);
5305
+ var clusterAddonCommand = new import_commander40.Command("addon").description("NKS \uD074\uB7EC\uC2A4\uD130 \uC560\uB4DC\uC628 \uAD00\uB828 \uBA85\uB839").addCommand(clusterAddonListCommand).addCommand(clusterAddonGetCommand).addCommand(clusterAddonInstallCommand).addCommand(clusterAddonUpdateCommand).addCommand(clusterAddonRemoveCommand);
5306
+ var clusterCommand = new import_commander40.Command("cluster").description("NKS \uD074\uB7EC\uC2A4\uD130 \uAD00\uB828 \uBA85\uB839").addCommand(listCommand6).addCommand(getCommand4).addCommand(createCommand4).addCommand(deleteCommand3).addCommand(resizeCommand2).addCommand(eventsCommand).addCommand(eventCommand).addCommand(kubeconfigCommand).addCommand(ipAclCommand).addCommand(setIpAclCommand).addCommand(renewCertificateCommand).addCommand(updateSgwCommand).addCommand(setControlPlaneLogCommand).addCommand(clusterAddonCommand);
5218
5307
 
5219
5308
  // src/commands/nks/nodegroup.ts
5220
- var import_commander40 = require("commander");
5309
+ var import_commander41 = require("commander");
5221
5310
  var import_chalk13 = __toESM(require("chalk"));
5222
5311
  function nodeGroupRow(nodegroup) {
5223
5312
  return [
@@ -5271,7 +5360,7 @@ async function confirmDangerousAction2(message, yes) {
5271
5360
  if (!ok) process.stderr.write(import_chalk13.default.yellow("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
5272
5361
  return ok;
5273
5362
  }
5274
- var listCommand7 = new import_commander40.Command("list").description("NKS \uB178\uB4DC \uADF8\uB8F9 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5363
+ var listCommand7 = new import_commander41.Command("list").description("NKS \uB178\uB4DC \uADF8\uB8F9 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").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 (cluster, _opts, cmd) => {
5275
5364
  const opts = cmd.optsWithGlobals();
5276
5365
  const { client } = await resolveNksClient(opts);
5277
5366
  startSpinner("NKS \uB178\uB4DC \uADF8\uB8F9 \uBAA9\uB85D \uC870\uD68C \uC911...");
@@ -5290,7 +5379,7 @@ var listCommand7 = new import_commander40.Command("list").description("NKS \uB17
5290
5379
  ids: nodegroups.map((nodegroup) => nodegroup.uuid)
5291
5380
  });
5292
5381
  });
5293
- var getCommand5 = new import_commander40.Command("get").description("NKS \uB178\uB4DC \uADF8\uB8F9\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").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 (cluster, nodegroup, _opts, cmd) => {
5382
+ var getCommand5 = new import_commander41.Command("get").description("NKS \uB178\uB4DC \uADF8\uB8F9\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").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 (cluster, nodegroup, _opts, cmd) => {
5294
5383
  const opts = cmd.optsWithGlobals();
5295
5384
  const { client } = await resolveNksClient(opts);
5296
5385
  startSpinner("NKS \uB178\uB4DC \uADF8\uB8F9 \uC870\uD68C \uC911...");
@@ -5309,7 +5398,7 @@ var getCommand5 = new import_commander40.Command("get").description("NKS \uB178\
5309
5398
  ids: [result.uuid]
5310
5399
  });
5311
5400
  });
5312
- var createCommand5 = new import_commander40.Command("create").description("NKS \uB178\uB4DC \uADF8\uB8F9\uC744 \uC0DD\uC131\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, _opts, cmd) => {
5401
+ var createCommand5 = new import_commander41.Command("create").description("NKS \uB178\uB4DC \uADF8\uB8F9\uC744 \uC0DD\uC131\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, _opts, cmd) => {
5313
5402
  const opts = cmd.optsWithGlobals();
5314
5403
  const payload = await readJsonFile(opts.file);
5315
5404
  const { client } = await resolveNksClient(opts);
@@ -5324,7 +5413,7 @@ var createCommand5 = new import_commander40.Command("create").description("NKS \
5324
5413
  stopSpinner(true);
5325
5414
  uuidOutput2(opts, result, "\uB178\uB4DC \uADF8\uB8F9 \uC0DD\uC131");
5326
5415
  });
5327
- var deleteCommand4 = new import_commander40.Command("delete").description("NKS \uB178\uB4DC \uADF8\uB8F9\uC744 \uC0AD\uC81C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").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 (cluster, nodegroup, _opts, cmd) => {
5416
+ var deleteCommand4 = new import_commander41.Command("delete").description("NKS \uB178\uB4DC \uADF8\uB8F9\uC744 \uC0AD\uC81C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").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 (cluster, nodegroup, _opts, cmd) => {
5328
5417
  const opts = cmd.optsWithGlobals();
5329
5418
  const ok = await confirmDangerousAction2(`NKS \uB178\uB4DC \uADF8\uB8F9 "${nodegroup}" \uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
5330
5419
  if (!ok) return;
@@ -5341,7 +5430,7 @@ var deleteCommand4 = new import_commander40.Command("delete").description("NKS \
5341
5430
  `));
5342
5431
  });
5343
5432
  function nodeActionCommand(name) {
5344
- return new import_commander40.Command(name).description(`NKS \uB178\uB4DC \uADF8\uB8F9 \uB178\uB4DC\uB97C ${name === "stop-node" ? "\uC911\uC9C0" : "\uC2DC\uC791"}\uD55C\uB2E4`).argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--nodes <csv>", "\uB300\uC0C1 \uB178\uB4DC CSV").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 (cluster, nodegroup, _opts, cmd) => {
5433
+ return new import_commander41.Command(name).description(`NKS \uB178\uB4DC \uADF8\uB8F9 \uB178\uB4DC\uB97C ${name === "stop-node" ? "\uC911\uC9C0" : "\uC2DC\uC791"}\uD55C\uB2E4`).argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--nodes <csv>", "\uB300\uC0C1 \uB178\uB4DC CSV").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 (cluster, nodegroup, _opts, cmd) => {
5345
5434
  const opts = cmd.optsWithGlobals();
5346
5435
  const nodes = parseCsv(opts.nodes, "--nodes");
5347
5436
  const { client } = await resolveNksClient(opts);
@@ -5357,7 +5446,7 @@ function nodeActionCommand(name) {
5357
5446
  uuidOutput2(opts, result, `\uB178\uB4DC ${name === "stop-node" ? "\uC911\uC9C0" : "\uC2DC\uC791"}`);
5358
5447
  });
5359
5448
  }
5360
- var autoscaleCommand = new import_commander40.Command("autoscale").description("NKS \uB178\uB4DC \uADF8\uB8F9 autoscale \uC124\uC815\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").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 (cluster, nodegroup, _opts, cmd) => {
5449
+ var autoscaleCommand = new import_commander41.Command("autoscale").description("NKS \uB178\uB4DC \uADF8\uB8F9 autoscale \uC124\uC815\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").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 (cluster, nodegroup, _opts, cmd) => {
5361
5450
  const opts = cmd.optsWithGlobals();
5362
5451
  const { client } = await resolveNksClient(opts);
5363
5452
  startSpinner("NKS \uB178\uB4DC \uADF8\uB8F9 autoscale \uC870\uD68C \uC911...");
@@ -5376,7 +5465,7 @@ var autoscaleCommand = new import_commander40.Command("autoscale").description("
5376
5465
  ids: []
5377
5466
  });
5378
5467
  });
5379
- var setAutoscaleCommand = new import_commander40.Command("set-autoscale").description("NKS \uB178\uB4DC \uADF8\uB8F9 autoscale \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5468
+ var setAutoscaleCommand = new import_commander41.Command("set-autoscale").description("NKS \uB178\uB4DC \uADF8\uB8F9 autoscale \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5380
5469
  const opts = cmd.optsWithGlobals();
5381
5470
  const payload = await readJsonFile(opts.file);
5382
5471
  const { client } = await resolveNksClient(opts);
@@ -5391,7 +5480,7 @@ var setAutoscaleCommand = new import_commander40.Command("set-autoscale").descri
5391
5480
  stopSpinner(true);
5392
5481
  uuidOutput2(opts, result, "autoscale \uBCC0\uACBD");
5393
5482
  });
5394
- var setMetricAutoscaleCommand = new import_commander40.Command("set-metric-autoscale").description("NKS \uB178\uB4DC \uADF8\uB8F9 metric autoscale \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5483
+ var setMetricAutoscaleCommand = new import_commander41.Command("set-metric-autoscale").description("NKS \uB178\uB4DC \uADF8\uB8F9 metric autoscale \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5395
5484
  const opts = cmd.optsWithGlobals();
5396
5485
  const payload = await readJsonFile(opts.file);
5397
5486
  const { client } = await resolveNksClient(opts);
@@ -5406,7 +5495,7 @@ var setMetricAutoscaleCommand = new import_commander40.Command("set-metric-autos
5406
5495
  stopSpinner(true);
5407
5496
  uuidOutput2(opts, result, "metric autoscale \uBCC0\uACBD");
5408
5497
  });
5409
- var upgradeCommand = new import_commander40.Command("upgrade").description("NKS \uB178\uB4DC \uADF8\uB8F9 Kubernetes version \uC744 \uC5C5\uADF8\uB808\uC774\uB4DC\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--version <v>", "\uB300\uC0C1 Kubernetes version").option("--num-buffer-nodes <n>", "buffer node \uC218").option("--num-max-unavailable-nodes <n>", "\uCD5C\uB300 unavailable node \uC218").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 (cluster, nodegroup, _opts, cmd) => {
5498
+ var upgradeCommand = new import_commander41.Command("upgrade").description("NKS \uB178\uB4DC \uADF8\uB8F9 Kubernetes version \uC744 \uC5C5\uADF8\uB808\uC774\uB4DC\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--version <v>", "\uB300\uC0C1 Kubernetes version").option("--num-buffer-nodes <n>", "buffer node \uC218").option("--num-max-unavailable-nodes <n>", "\uCD5C\uB300 unavailable node \uC218").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 (cluster, nodegroup, _opts, cmd) => {
5410
5499
  const opts = cmd.optsWithGlobals();
5411
5500
  const { client } = await resolveNksClient(opts);
5412
5501
  startSpinner("NKS \uB178\uB4DC \uADF8\uB8F9 upgrade \uC694\uCCAD \uC911...");
@@ -5424,7 +5513,7 @@ var upgradeCommand = new import_commander40.Command("upgrade").description("NKS
5424
5513
  stopSpinner(true);
5425
5514
  uuidOutput2(opts, result, "\uB178\uB4DC \uADF8\uB8F9 upgrade");
5426
5515
  });
5427
- var setUserscriptCommand = new import_commander40.Command("set-userscript").description("NKS \uB178\uB4DC \uADF8\uB8F9 user script \uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <script>", "script \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5516
+ var setUserscriptCommand = new import_commander41.Command("set-userscript").description("NKS \uB178\uB4DC \uADF8\uB8F9 user script \uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <script>", "script \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5428
5517
  const opts = cmd.optsWithGlobals();
5429
5518
  const contents = await readTextFile(opts.file);
5430
5519
  const { client } = await resolveNksClient(opts);
@@ -5439,7 +5528,7 @@ var setUserscriptCommand = new import_commander40.Command("set-userscript").desc
5439
5528
  stopSpinner(true);
5440
5529
  uuidOutput2(opts, result, "user script \uBCC0\uACBD");
5441
5530
  });
5442
- var updateFlavorCommand = new import_commander40.Command("update-flavor").description("NKS \uB178\uB4DC \uADF8\uB8F9 flavor \uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--flavor <uuid>", "\uBCC0\uACBD\uD560 flavor UUID").option("--num-buffer-nodes <n>", "buffer node \uC218").option("--num-max-unavailable-nodes <n>", "\uCD5C\uB300 unavailable node \uC218").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 (cluster, nodegroup, _opts, cmd) => {
5531
+ var updateFlavorCommand = new import_commander41.Command("update-flavor").description("NKS \uB178\uB4DC \uADF8\uB8F9 flavor \uB97C \uBCC0\uACBD\uD55C\uB2E4").argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--flavor <uuid>", "\uBCC0\uACBD\uD560 flavor UUID").option("--num-buffer-nodes <n>", "buffer node \uC218").option("--num-max-unavailable-nodes <n>", "\uCD5C\uB300 unavailable node \uC218").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 (cluster, nodegroup, _opts, cmd) => {
5443
5532
  const opts = cmd.optsWithGlobals();
5444
5533
  const { client } = await resolveNksClient(opts);
5445
5534
  startSpinner("NKS \uB178\uB4DC \uADF8\uB8F9 flavor \uBCC0\uACBD \uC694\uCCAD \uC911...");
@@ -5458,7 +5547,7 @@ var updateFlavorCommand = new import_commander40.Command("update-flavor").descri
5458
5547
  uuidOutput2(opts, result, "flavor \uBCC0\uACBD");
5459
5548
  });
5460
5549
  function patchPayloadCommand(name) {
5461
- return new import_commander40.Command(name).description(`NKS \uB178\uB4DC \uADF8\uB8F9 ${name === "set-fip-auto-bind" ? "Floating IP \uC790\uB3D9 \uC5F0\uACB0" : "Kubernetes labels"} \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4`).argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5550
+ return new import_commander41.Command(name).description(`NKS \uB178\uB4DC \uADF8\uB8F9 ${name === "set-fip-auto-bind" ? "Floating IP \uC790\uB3D9 \uC5F0\uACB0" : "Kubernetes labels"} \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4`).argument("<cluster>", "\uD074\uB7EC\uC2A4\uD130 UUID \uB610\uB294 \uC774\uB984").argument("<nodegroup>", "\uB178\uB4DC \uADF8\uB8F9 UUID \uB610\uB294 \uC774\uB984").requiredOption("--file <json>", "\uACF5\uC2DD API payload JSON \uD30C\uC77C").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 (cluster, nodegroup, _opts, cmd) => {
5462
5551
  const opts = cmd.optsWithGlobals();
5463
5552
  const payload = await readJsonFile(opts.file);
5464
5553
  const { client } = await resolveNksClient(opts);
@@ -5474,10 +5563,10 @@ function patchPayloadCommand(name) {
5474
5563
  uuidOutput2(opts, result, name);
5475
5564
  });
5476
5565
  }
5477
- var nodegroupCommand = new import_commander40.Command("nodegroup").description("NKS \uB178\uB4DC \uADF8\uB8F9 \uAD00\uB828 \uBA85\uB839").addCommand(listCommand7).addCommand(getCommand5).addCommand(createCommand5).addCommand(deleteCommand4).addCommand(nodeActionCommand("stop-node")).addCommand(nodeActionCommand("start-node")).addCommand(autoscaleCommand).addCommand(setAutoscaleCommand).addCommand(setMetricAutoscaleCommand).addCommand(upgradeCommand).addCommand(setUserscriptCommand).addCommand(updateFlavorCommand).addCommand(patchPayloadCommand("set-fip-auto-bind")).addCommand(patchPayloadCommand("set-labels"));
5566
+ var nodegroupCommand = new import_commander41.Command("nodegroup").description("NKS \uB178\uB4DC \uADF8\uB8F9 \uAD00\uB828 \uBA85\uB839").addCommand(listCommand7).addCommand(getCommand5).addCommand(createCommand5).addCommand(deleteCommand4).addCommand(nodeActionCommand("stop-node")).addCommand(nodeActionCommand("start-node")).addCommand(autoscaleCommand).addCommand(setAutoscaleCommand).addCommand(setMetricAutoscaleCommand).addCommand(upgradeCommand).addCommand(setUserscriptCommand).addCommand(updateFlavorCommand).addCommand(patchPayloadCommand("set-fip-auto-bind")).addCommand(patchPayloadCommand("set-labels"));
5478
5567
 
5479
5568
  // src/commands/nks/addon.ts
5480
- var import_commander41 = require("commander");
5569
+ var import_commander42 = require("commander");
5481
5570
  function addonTypeRow(addonType) {
5482
5571
  return [
5483
5572
  addonType.uuid ?? addonType.id ?? addonType.name,
@@ -5493,7 +5582,7 @@ function addonRow2(addon) {
5493
5582
  addon.status ?? ""
5494
5583
  ];
5495
5584
  }
5496
- var addonTypeListCommand = new import_commander41.Command("list").description("NKS \uC560\uB4DC\uC628 \uD0C0\uC785 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").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) => {
5585
+ var addonTypeListCommand = new import_commander42.Command("list").description("NKS \uC560\uB4DC\uC628 \uD0C0\uC785 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").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) => {
5497
5586
  const opts = cmd.optsWithGlobals();
5498
5587
  const { client } = await resolveNksClient(opts);
5499
5588
  startSpinner("NKS \uC560\uB4DC\uC628 \uD0C0\uC785 \uBAA9\uB85D \uC870\uD68C \uC911...");
@@ -5512,7 +5601,7 @@ var addonTypeListCommand = new import_commander41.Command("list").description("N
5512
5601
  ids: addonTypes.map((addonType) => addonType.uuid ?? addonType.id ?? addonType.name)
5513
5602
  });
5514
5603
  });
5515
- var addonTypeGetCommand = new import_commander41.Command("get").description("NKS \uC560\uB4DC\uC628 \uD0C0\uC785\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<addon-type>", "\uC560\uB4DC\uC628 \uD0C0\uC785 UUID \uB610\uB294 \uC774\uB984").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 (addonType, _opts, cmd) => {
5604
+ var addonTypeGetCommand = new import_commander42.Command("get").description("NKS \uC560\uB4DC\uC628 \uD0C0\uC785\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<addon-type>", "\uC560\uB4DC\uC628 \uD0C0\uC785 UUID \uB610\uB294 \uC774\uB984").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 (addonType, _opts, cmd) => {
5516
5605
  const opts = cmd.optsWithGlobals();
5517
5606
  const { client } = await resolveNksClient(opts);
5518
5607
  startSpinner("NKS \uC560\uB4DC\uC628 \uD0C0\uC785 \uC870\uD68C \uC911...");
@@ -5531,8 +5620,8 @@ var addonTypeGetCommand = new import_commander41.Command("get").description("NKS
5531
5620
  ids: [result.uuid ?? result.id ?? result.name]
5532
5621
  });
5533
5622
  });
5534
- var addonTypeCommand = new import_commander41.Command("addon-type").description("NKS \uC560\uB4DC\uC628 \uD0C0\uC785 \uAD00\uB828 \uBA85\uB839").addCommand(addonTypeListCommand).addCommand(addonTypeGetCommand);
5535
- var addonListCommand = new import_commander41.Command("list").description("NKS \uC560\uB4DC\uC628 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").option("--k8s-version <version>", "Kubernetes version filter").option("--image <image>", "image filter").option("--platform-version <version>", "platform version filter").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) => {
5623
+ var addonTypeCommand = new import_commander42.Command("addon-type").description("NKS \uC560\uB4DC\uC628 \uD0C0\uC785 \uAD00\uB828 \uBA85\uB839").addCommand(addonTypeListCommand).addCommand(addonTypeGetCommand);
5624
+ var addonListCommand = new import_commander42.Command("list").description("NKS \uC560\uB4DC\uC628 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").option("--k8s-version <version>", "Kubernetes version filter").option("--image <image>", "image filter").option("--platform-version <version>", "platform version filter").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) => {
5536
5625
  const opts = cmd.optsWithGlobals();
5537
5626
  const { client } = await resolveNksClient(opts);
5538
5627
  startSpinner("NKS \uC560\uB4DC\uC628 \uBAA9\uB85D \uC870\uD68C \uC911...");
@@ -5555,7 +5644,7 @@ var addonListCommand = new import_commander41.Command("list").description("NKS \
5555
5644
  ids: addons.map((addon) => addon.uuid ?? addon.id ?? addon.name)
5556
5645
  });
5557
5646
  });
5558
- var addonGetCommand = new import_commander41.Command("get").description("NKS \uC560\uB4DC\uC628\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").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 (addon, _opts, cmd) => {
5647
+ var addonGetCommand = new import_commander42.Command("get").description("NKS \uC560\uB4DC\uC628\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<addon>", "\uC560\uB4DC\uC628 UUID \uB610\uB294 \uC774\uB984").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 (addon, _opts, cmd) => {
5559
5648
  const opts = cmd.optsWithGlobals();
5560
5649
  const { client } = await resolveNksClient(opts);
5561
5650
  startSpinner("NKS \uC560\uB4DC\uC628 \uC870\uD68C \uC911...");
@@ -5574,87 +5663,1740 @@ var addonGetCommand = new import_commander41.Command("get").description("NKS \uC
5574
5663
  ids: [result.uuid ?? result.id ?? result.name]
5575
5664
  });
5576
5665
  });
5577
- var addonCommand = new import_commander41.Command("addon").description("NKS \uC560\uB4DC\uC628 \uAD00\uB828 \uBA85\uB839").addCommand(addonListCommand).addCommand(addonGetCommand);
5666
+ var addonCommand = new import_commander42.Command("addon").description("NKS \uC560\uB4DC\uC628 \uAD00\uB828 \uBA85\uB839").addCommand(addonListCommand).addCommand(addonGetCommand);
5578
5667
 
5579
- // src/index.ts
5580
- var program = new import_commander42.Command();
5581
- program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version("0.6.0").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");
5582
- program.hook("preAction", () => {
5583
- const opts = program.opts();
5584
- if (!opts.color || process.env["NO_COLOR"]) {
5585
- import_chalk14.default.level = 0;
5668
+ // src/commands/ncs/template.ts
5669
+ var import_commander43 = require("commander");
5670
+ var import_chalk14 = __toESM(require("chalk"));
5671
+
5672
+ // src/commands/ncs/helpers.ts
5673
+ var import_node_fs7 = require("fs");
5674
+
5675
+ // src/services/ncs/client.ts
5676
+ var import_ky12 = __toESM(require("ky"));
5677
+
5678
+ // src/services/ncs/types.ts
5679
+ function isNcsTemplateSummary(val) {
5680
+ if (typeof val !== "object" || val === null) return false;
5681
+ const obj = val;
5682
+ return typeof obj["id"] === "string" && typeof obj["name"] === "string";
5683
+ }
5684
+ function isNcsTemplateDetail(val) {
5685
+ return isNcsTemplateSummary(val);
5686
+ }
5687
+ function isNcsTemplateVersionSummary(val) {
5688
+ if (typeof val !== "object" || val === null) return false;
5689
+ const obj = val;
5690
+ return typeof obj["id"] === "string" && typeof obj["version"] === "string";
5691
+ }
5692
+ function isNcsTemplateVersionDetail(val) {
5693
+ return isNcsTemplateVersionSummary(val);
5694
+ }
5695
+ function isNcsWorkloadSummary(val) {
5696
+ if (typeof val !== "object" || val === null) return false;
5697
+ const obj = val;
5698
+ return typeof obj["id"] === "string" && typeof obj["name"] === "string" && typeof obj["status"] === "string";
5699
+ }
5700
+ function isNcsWorkloadDetail(val) {
5701
+ return isNcsWorkloadSummary(val);
5702
+ }
5703
+ function isNcsWorkloadLog(val) {
5704
+ if (typeof val !== "object" || val === null) return false;
5705
+ const obj = val;
5706
+ return typeof obj["log"] === "string" && typeof obj["time"] === "string";
5707
+ }
5708
+ function isNcsWorkloadEvent(val) {
5709
+ if (typeof val !== "object" || val === null) return false;
5710
+ const obj = val;
5711
+ return typeof obj["type"] === "string" && typeof obj["reason"] === "string" && typeof obj["message"] === "string";
5712
+ }
5713
+ function isNcsWorkloadHistorySummary(val) {
5714
+ if (typeof val !== "object" || val === null) return false;
5715
+ const obj = val;
5716
+ return typeof obj["id"] === "number" && typeof obj["status"] === "string";
5717
+ }
5718
+ function isNcsWorkloadHistoryDetail(val) {
5719
+ return isNcsWorkloadHistorySummary(val);
5720
+ }
5721
+ function isNcsWorkloadScheduleHistory(val) {
5722
+ if (typeof val !== "object" || val === null) return false;
5723
+ const obj = val;
5724
+ return typeof obj["id"] === "string" && typeof obj["status"] === "string";
5725
+ }
5726
+ function isNcsMalwareConfig(val) {
5727
+ if (typeof val !== "object" || val === null) return false;
5728
+ const obj = val;
5729
+ return typeof obj["enabled"] === "boolean";
5730
+ }
5731
+ function isNcsMalwareReport(val) {
5732
+ if (typeof val !== "object" || val === null) return false;
5733
+ const obj = val;
5734
+ return typeof obj["image"] === "string" && typeof obj["result"] === "string";
5735
+ }
5736
+
5737
+ // src/services/ncs/client.ts
5738
+ var DEFAULT_TIMEOUT_MS8 = 3e4;
5739
+ var DEFAULT_WAIT_POLL_INTERVAL_MS = 5e3;
5740
+ var NcsClient = class {
5741
+ accessToken;
5742
+ baseUrl;
5743
+ constructor(accessToken, region, appKey) {
5744
+ this.accessToken = accessToken;
5745
+ this.baseUrl = `https://${ncsHost(region)}/ncs/v1.0/appkeys/${encodeURIComponent(appKey)}`;
5586
5746
  }
5587
- if (opts.json || opts.quiet) {
5588
- setQuiet(true);
5747
+ authHeaders() {
5748
+ return { "x-nhn-authorization": `Bearer ${this.accessToken}` };
5589
5749
  }
5590
- });
5591
- program.addCommand(configureCommand);
5592
- var logncrashCommand = new import_commander42.Command("logncrash").description("Log & Crash \uAD00\uB828 \uBA85\uB839");
5593
- logncrashCommand.addCommand(searchCommand);
5594
- logncrashCommand.addCommand(sendCommand);
5595
- logncrashCommand.addCommand(exportCommand);
5596
- program.addCommand(logncrashCommand);
5597
- var deployCommand = new import_commander42.Command("deploy").description("NHN Cloud Deploy \uAD00\uB828 \uBA85\uB839");
5598
- deployCommand.addCommand(runCommand);
5599
- deployCommand.addCommand(artifactsCommand);
5600
- deployCommand.addCommand(serverGroupsCommand);
5601
- deployCommand.addCommand(historiesCommand);
5602
- deployCommand.addCommand(binaryGroupsCommand);
5603
- deployCommand.addCommand(binariesCommand);
5604
- deployCommand.addCommand(uploadCommand);
5605
- deployCommand.addCommand(downloadCommand);
5606
- program.addCommand(deployCommand);
5607
- var instanceCommand = new import_commander42.Command("instance").description("Compute \uC778\uC2A4\uD134\uC2A4 \uAD00\uB828 \uBA85\uB839");
5608
- instanceCommand.addCommand(listCommand);
5609
- instanceCommand.addCommand(flavorsCommand);
5610
- instanceCommand.addCommand(availabilityZonesCommand);
5611
- instanceCommand.addCommand(getCommand2);
5612
- instanceCommand.addCommand(createCommand3);
5613
- instanceCommand.addCommand(deleteCommand2);
5614
- instanceCommand.addCommand(startCommand);
5615
- instanceCommand.addCommand(stopCommand);
5616
- instanceCommand.addCommand(rebootCommand);
5617
- instanceCommand.addCommand(resizeCommand);
5618
- instanceCommand.addCommand(resizeConfirmCommand);
5619
- instanceCommand.addCommand(resizeRevertCommand);
5620
- instanceCommand.addCommand(imagesCommand);
5621
- instanceCommand.addCommand(keypairsCommand);
5622
- instanceCommand.addCommand(keypairCommand);
5623
- instanceCommand.addCommand(volumeCommand);
5624
- instanceCommand.addCommand(volumesCommand);
5625
- program.addCommand(instanceCommand);
5626
- var networkCommand = new import_commander42.Command("network").description("VPC\xB7\uC11C\uBE0C\uB137 \uC870\uD68C");
5627
- networkCommand.addCommand(listCommand3);
5628
- networkCommand.addCommand(subnetCommand);
5629
- program.addCommand(networkCommand);
5630
- var volumeCommand2 = new import_commander42.Command("volume").description("Block Storage \uBCFC\uB968 \uAD00\uB828 \uBA85\uB839");
5631
- volumeCommand2.addCommand(listCommand2);
5632
- volumeCommand2.addCommand(getCommand);
5633
- volumeCommand2.addCommand(createCommand);
5634
- program.addCommand(volumeCommand2);
5635
- var floatingipCommand = new import_commander42.Command("floatingip").description(
5636
- "Floating IP(\uC778\uC2A4\uD134\uC2A4 \uACF5\uC778 IP) \uAD00\uB9AC"
5637
- );
5750
+ /**
5751
+ * 설계도(template) 목록을 반환한다.
5752
+ * GET /ncs/v1.0/appkeys/{appKey}/templates
5753
+ * 응답: { header, templates: [...] } — body 가 아니라 named 필드(docs 예제 확정).
5754
+ *
5755
+ * pagination: 기본 page size 10(docs 확정). 목록이 앞부분만 조용히 반환(silent truncation)하지
5756
+ * 않도록 page/size 를 그대로 노출한다. 총 개수는 응답 헤더 X-Total-Count 로 온다(docs 확정) —
5757
+ * body/JSON 필드가 아니므로 ky Response 에서 header 를 직접 읽는다(harbor-client.ts 의
5758
+ * .json()+.headers.get() 분리 패턴과 동일 — .json<T>() 체이닝으로는 헤더를 못 본다).
5759
+ */
5760
+ async listTemplates(query = {}) {
5761
+ const url = `${this.baseUrl}/templates`;
5762
+ const searchParams = {};
5763
+ if (query.page !== void 0) searchParams["page"] = query.page;
5764
+ if (query.size !== void 0) searchParams["size"] = query.size;
5765
+ if (query.disableContainers !== void 0) {
5766
+ searchParams["disable_containers"] = query.disableContainers;
5767
+ }
5768
+ try {
5769
+ const res = await import_ky12.default.get(url, {
5770
+ headers: this.authHeaders(),
5771
+ searchParams,
5772
+ retry: 0,
5773
+ timeout: DEFAULT_TIMEOUT_MS8
5774
+ });
5775
+ const body = await res.json();
5776
+ unwrapHeader(body);
5777
+ if (!Array.isArray(body.templates)) {
5778
+ if (body.templates === void 0) return { totalCount: 0, templates: [] };
5779
+ throw new NhnCloudCliError(
5780
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: templates \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
5781
+ EXIT_API_ERROR
5782
+ );
5783
+ }
5784
+ const templates = body.templates.filter(isNcsTemplateSummary);
5785
+ const headerTotal = res.headers.get("x-total-count");
5786
+ const totalCount = headerTotal !== null && /^\d+$/.test(headerTotal) ? Number(headerTotal) : templates.length;
5787
+ return { totalCount, templates };
5788
+ } catch (err) {
5789
+ if (err instanceof NhnCloudCliError) throw err;
5790
+ throw toNhnCloudCliError(err);
5791
+ }
5792
+ }
5793
+ /**
5794
+ * 설계도(template) 단건을 반환한다.
5795
+ * GET /ncs/v1.0/appkeys/{appKey}/templates/{id}
5796
+ * 응답: { header, template: {...} } — named 필드(listTemplates 와 같은 패턴).
5797
+ */
5798
+ async getTemplate(id) {
5799
+ const url = `${this.baseUrl}/templates/${encodeURIComponent(id)}`;
5800
+ try {
5801
+ const res = await import_ky12.default.get(url, {
5802
+ headers: this.authHeaders(),
5803
+ retry: 0,
5804
+ timeout: DEFAULT_TIMEOUT_MS8
5805
+ });
5806
+ const body = await res.json();
5807
+ unwrapHeader(body);
5808
+ if (!isNcsTemplateDetail(body.template)) {
5809
+ throw new NhnCloudCliError(
5810
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: template \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
5811
+ EXIT_API_ERROR
5812
+ );
5813
+ }
5814
+ return body.template;
5815
+ } catch (err) {
5816
+ if (err instanceof NhnCloudCliError) throw err;
5817
+ throw toNhnCloudCliError(err);
5818
+ }
5819
+ }
5820
+ /**
5821
+ * 설계도(template) 의 버전 목록을 반환한다.
5822
+ * GET /ncs/v1.0/appkeys/{appKey}/templates/{id}/versions
5823
+ * 응답: { header, versions: [...] } — named 필드. pagination 은 listTemplates 와 동일하게
5824
+ * X-Total-Count 응답 헤더 + page/size 노출(silent truncation 방지).
5825
+ */
5826
+ async listTemplateVersions(id, query = {}) {
5827
+ const url = `${this.baseUrl}/templates/${encodeURIComponent(id)}/versions`;
5828
+ const searchParams = {};
5829
+ if (query.q !== void 0) searchParams["q"] = query.q;
5830
+ if (query.sort !== void 0) searchParams["sort"] = query.sort;
5831
+ if (query.page !== void 0) searchParams["page"] = query.page;
5832
+ if (query.size !== void 0) searchParams["size"] = query.size;
5833
+ try {
5834
+ const res = await import_ky12.default.get(url, {
5835
+ headers: this.authHeaders(),
5836
+ searchParams,
5837
+ retry: 0,
5838
+ timeout: DEFAULT_TIMEOUT_MS8
5839
+ });
5840
+ const body = await res.json();
5841
+ unwrapHeader(body);
5842
+ if (!Array.isArray(body.versions)) {
5843
+ if (body.versions === void 0) return { totalCount: 0, versions: [] };
5844
+ throw new NhnCloudCliError(
5845
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: versions \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
5846
+ EXIT_API_ERROR
5847
+ );
5848
+ }
5849
+ const versions = body.versions.filter(isNcsTemplateVersionSummary);
5850
+ const headerTotal = res.headers.get("x-total-count");
5851
+ const totalCount = headerTotal !== null && /^\d+$/.test(headerTotal) ? Number(headerTotal) : versions.length;
5852
+ return { totalCount, versions };
5853
+ } catch (err) {
5854
+ if (err instanceof NhnCloudCliError) throw err;
5855
+ throw toNhnCloudCliError(err);
5856
+ }
5857
+ }
5858
+ /**
5859
+ * 설계도(template) 버전 단건을 반환한다.
5860
+ * GET /ncs/v1.0/appkeys/{appKey}/templates/{id}/versions/{version}
5861
+ * 응답: { header, version: {...} } — named 필드.
5862
+ */
5863
+ async getTemplateVersion(id, version) {
5864
+ const url = `${this.baseUrl}/templates/${encodeURIComponent(id)}/versions/${encodeURIComponent(version)}`;
5865
+ try {
5866
+ const res = await import_ky12.default.get(url, {
5867
+ headers: this.authHeaders(),
5868
+ retry: 0,
5869
+ timeout: DEFAULT_TIMEOUT_MS8
5870
+ });
5871
+ const body = await res.json();
5872
+ unwrapHeader(body);
5873
+ if (!isNcsTemplateVersionDetail(body.version)) {
5874
+ throw new NhnCloudCliError(
5875
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: version \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
5876
+ EXIT_API_ERROR
5877
+ );
5878
+ }
5879
+ return body.version;
5880
+ } catch (err) {
5881
+ if (err instanceof NhnCloudCliError) throw err;
5882
+ throw toNhnCloudCliError(err);
5883
+ }
5884
+ }
5885
+ /**
5886
+ * workload(런타임 실행) 목록을 반환한다.
5887
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads
5888
+ * 응답: { header, workloads: [...] } — named 필드(listTemplates 와 동일 패턴).
5889
+ * pagination: X-Total-Count 응답 헤더 + page/size 노출(listTemplates 와 동일 규약).
5890
+ */
5891
+ async listWorkloads(query = {}) {
5892
+ const url = `${this.baseUrl}/workloads`;
5893
+ const searchParams = {};
5894
+ if (query.q !== void 0) searchParams["q"] = query.q;
5895
+ if (query.page !== void 0) searchParams["page"] = query.page;
5896
+ if (query.size !== void 0) searchParams["size"] = query.size;
5897
+ try {
5898
+ const res = await import_ky12.default.get(url, {
5899
+ headers: this.authHeaders(),
5900
+ searchParams,
5901
+ retry: 0,
5902
+ timeout: DEFAULT_TIMEOUT_MS8
5903
+ });
5904
+ const body = await res.json();
5905
+ unwrapHeader(body);
5906
+ if (!Array.isArray(body.workloads)) {
5907
+ if (body.workloads === void 0) return { totalCount: 0, workloads: [] };
5908
+ throw new NhnCloudCliError(
5909
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: workloads \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
5910
+ EXIT_API_ERROR
5911
+ );
5912
+ }
5913
+ const workloads = body.workloads.filter(isNcsWorkloadSummary);
5914
+ const headerTotal = res.headers.get("x-total-count");
5915
+ const totalCount = headerTotal !== null && /^\d+$/.test(headerTotal) ? Number(headerTotal) : workloads.length;
5916
+ return { totalCount, workloads };
5917
+ } catch (err) {
5918
+ if (err instanceof NhnCloudCliError) throw err;
5919
+ throw toNhnCloudCliError(err);
5920
+ }
5921
+ }
5922
+ /**
5923
+ * workload 단건을 반환한다 (tasks[] 런타임 상태 포함).
5924
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads/{workloadId}
5925
+ * 응답: { header, workload: {...} } — named 필드.
5926
+ */
5927
+ async getWorkload(id) {
5928
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}`;
5929
+ try {
5930
+ const res = await import_ky12.default.get(url, {
5931
+ headers: this.authHeaders(),
5932
+ retry: 0,
5933
+ timeout: DEFAULT_TIMEOUT_MS8
5934
+ });
5935
+ const body = await res.json();
5936
+ unwrapHeader(body);
5937
+ if (!isNcsWorkloadDetail(body.workload)) {
5938
+ throw new NhnCloudCliError(
5939
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: workload \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
5940
+ EXIT_API_ERROR
5941
+ );
5942
+ }
5943
+ return body.workload;
5944
+ } catch (err) {
5945
+ if (err instanceof NhnCloudCliError) throw err;
5946
+ throw toNhnCloudCliError(err);
5947
+ }
5948
+ }
5949
+ /**
5950
+ * workload task 의 컨테이너 로그를 반환한다.
5951
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads/{workloadId}/tasks/{taskId}/logs
5952
+ * docs 확정 필수 쿼리는 `containerName` — CLI 시그니처 일관성을 위해 `container` 로 받고 여기서 매핑한다.
5953
+ * container 누락(빈 문자열 포함) 시 EXIT_PARAM_ERROR — API 호출 전 파라미터 검증(1-3 회피).
5954
+ * 응답: { header, logs: [...] } — named 필드. docs 에 X-Total-Count 헤더가 없어 totalCount 는 반환하지 않는다.
5955
+ */
5956
+ async getWorkloadLogs(id, taskId, query) {
5957
+ if (!query.container || !query.container.trim()) {
5958
+ throw new NhnCloudCliError(
5959
+ "container \uCFFC\uB9AC\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. \uCEE8\uD14C\uC774\uB108 \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC138\uC694.",
5960
+ EXIT_PARAM_ERROR
5961
+ );
5962
+ }
5963
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/tasks/${encodeURIComponent(taskId)}/logs`;
5964
+ const searchParams = { containerName: query.container };
5965
+ if (query.from !== void 0) searchParams["from"] = query.from;
5966
+ if (query.to !== void 0) searchParams["to"] = query.to;
5967
+ if (query.page !== void 0) searchParams["page"] = query.page;
5968
+ if (query.size !== void 0) searchParams["size"] = query.size;
5969
+ try {
5970
+ const res = await import_ky12.default.get(url, {
5971
+ headers: this.authHeaders(),
5972
+ searchParams,
5973
+ retry: 0,
5974
+ timeout: DEFAULT_TIMEOUT_MS8
5975
+ });
5976
+ const body = await res.json();
5977
+ unwrapHeader(body);
5978
+ if (!Array.isArray(body.logs)) {
5979
+ if (body.logs === void 0) return { logs: [] };
5980
+ throw new NhnCloudCliError(
5981
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: logs \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
5982
+ EXIT_API_ERROR
5983
+ );
5984
+ }
5985
+ return { logs: body.logs.filter(isNcsWorkloadLog) };
5986
+ } catch (err) {
5987
+ if (err instanceof NhnCloudCliError) throw err;
5988
+ throw toNhnCloudCliError(err);
5989
+ }
5990
+ }
5991
+ /**
5992
+ * workload task 의 이벤트 목록을 반환한다.
5993
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads/{workloadId}/tasks/{taskId}/events
5994
+ * 응답: { header, events: [...] } — named 필드.
5995
+ * pagination: X-Total-Count 헤더가 docs 에 명시되진 않았으나, 있으면 정확히 반영하고 없으면
5996
+ * 현재 페이지 길이로 fallback(listTemplates 와 동일한 방어적 패턴 — 실제 헤더 부재와도 호환).
5997
+ */
5998
+ async getWorkloadEvents(id, taskId, query = {}) {
5999
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/tasks/${encodeURIComponent(taskId)}/events`;
6000
+ const searchParams = {};
6001
+ if (query.type !== void 0) searchParams["type"] = query.type;
6002
+ if (query.q !== void 0) searchParams["q"] = query.q;
6003
+ if (query.from !== void 0) searchParams["from"] = query.from;
6004
+ if (query.to !== void 0) searchParams["to"] = query.to;
6005
+ if (query.page !== void 0) searchParams["page"] = query.page;
6006
+ if (query.size !== void 0) searchParams["size"] = query.size;
6007
+ try {
6008
+ const res = await import_ky12.default.get(url, {
6009
+ headers: this.authHeaders(),
6010
+ searchParams,
6011
+ retry: 0,
6012
+ timeout: DEFAULT_TIMEOUT_MS8
6013
+ });
6014
+ const body = await res.json();
6015
+ unwrapHeader(body);
6016
+ if (!Array.isArray(body.events)) {
6017
+ if (body.events === void 0) return { totalCount: 0, events: [] };
6018
+ throw new NhnCloudCliError(
6019
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: events \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
6020
+ EXIT_API_ERROR
6021
+ );
6022
+ }
6023
+ const events = body.events.filter(isNcsWorkloadEvent);
6024
+ const headerTotal = res.headers.get("x-total-count");
6025
+ const totalCount = headerTotal !== null && /^\d+$/.test(headerTotal) ? Number(headerTotal) : events.length;
6026
+ return { totalCount, events };
6027
+ } catch (err) {
6028
+ if (err instanceof NhnCloudCliError) throw err;
6029
+ throw toNhnCloudCliError(err);
6030
+ }
6031
+ }
6032
+ /**
6033
+ * workload 의 실행 히스토리 목록을 반환한다.
6034
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads/{workloadId}/history
6035
+ * 응답: { header, history: [...] } — named 필드.
6036
+ * pagination: getWorkloadEvents 와 동일한 방어적 X-Total-Count fallback 패턴.
6037
+ */
6038
+ async listWorkloadHistory(id, query = {}) {
6039
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/history`;
6040
+ const searchParams = {};
6041
+ if (query.page !== void 0) searchParams["page"] = query.page;
6042
+ if (query.size !== void 0) searchParams["size"] = query.size;
6043
+ if (query.sort !== void 0) searchParams["sort"] = query.sort;
6044
+ try {
6045
+ const res = await import_ky12.default.get(url, {
6046
+ headers: this.authHeaders(),
6047
+ searchParams,
6048
+ retry: 0,
6049
+ timeout: DEFAULT_TIMEOUT_MS8
6050
+ });
6051
+ const body = await res.json();
6052
+ unwrapHeader(body);
6053
+ if (!Array.isArray(body.history)) {
6054
+ if (body.history === void 0) return { totalCount: 0, history: [] };
6055
+ throw new NhnCloudCliError(
6056
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: history \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
6057
+ EXIT_API_ERROR
6058
+ );
6059
+ }
6060
+ const history = body.history.filter(isNcsWorkloadHistorySummary);
6061
+ const headerTotal = res.headers.get("x-total-count");
6062
+ const totalCount = headerTotal !== null && /^\d+$/.test(headerTotal) ? Number(headerTotal) : history.length;
6063
+ return { totalCount, history };
6064
+ } catch (err) {
6065
+ if (err instanceof NhnCloudCliError) throw err;
6066
+ throw toNhnCloudCliError(err);
6067
+ }
6068
+ }
6069
+ /**
6070
+ * workload 실행 히스토리 단건을 반환한다 (당시 사용한 template 스냅샷 포함).
6071
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads/{workloadId}/history/{historyId}
6072
+ * 응답: { header, history: {...}, template: {...} } — history/template 이 sibling named 필드(docs 예제 확정).
6073
+ */
6074
+ async getWorkloadHistory(id, historyId) {
6075
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/history/${encodeURIComponent(historyId)}`;
6076
+ try {
6077
+ const res = await import_ky12.default.get(url, {
6078
+ headers: this.authHeaders(),
6079
+ retry: 0,
6080
+ timeout: DEFAULT_TIMEOUT_MS8
6081
+ });
6082
+ const body = await res.json();
6083
+ unwrapHeader(body);
6084
+ if (!isNcsWorkloadHistoryDetail(body.history)) {
6085
+ throw new NhnCloudCliError(
6086
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: history \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6087
+ EXIT_API_ERROR
6088
+ );
6089
+ }
6090
+ return { ...body.history, template: body.template };
6091
+ } catch (err) {
6092
+ if (err instanceof NhnCloudCliError) throw err;
6093
+ throw toNhnCloudCliError(err);
6094
+ }
6095
+ }
6096
+ /**
6097
+ * workload 의 예약 실행 히스토리 목록을 반환한다.
6098
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads/{workloadId}/schedulehistory
6099
+ * 응답: { header, schedulehistory: [...] } — named 필드. docs 에 X-Total-Count 헤더가 없어
6100
+ * totalCount 는 반환하지 않는다(phase 범위 — page/size 는 후속 필요 시 추가, ADR-020 표 갱신 불필요한 범위 내 결정).
6101
+ */
6102
+ async getWorkloadScheduleHistory(id) {
6103
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/schedulehistory`;
6104
+ try {
6105
+ const res = await import_ky12.default.get(url, {
6106
+ headers: this.authHeaders(),
6107
+ retry: 0,
6108
+ timeout: DEFAULT_TIMEOUT_MS8
6109
+ });
6110
+ const body = await res.json();
6111
+ unwrapHeader(body);
6112
+ if (!Array.isArray(body.schedulehistory)) {
6113
+ if (body.schedulehistory === void 0) return { scheduleHistory: [] };
6114
+ throw new NhnCloudCliError(
6115
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: schedulehistory \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
6116
+ EXIT_API_ERROR
6117
+ );
6118
+ }
6119
+ return { scheduleHistory: body.schedulehistory.filter(isNcsWorkloadScheduleHistory) };
6120
+ } catch (err) {
6121
+ if (err instanceof NhnCloudCliError) throw err;
6122
+ throw toNhnCloudCliError(err);
6123
+ }
6124
+ }
6125
+ /**
6126
+ * 설계도(template) 를 생성한다.
6127
+ * POST /ncs/v1.0/appkeys/{appKey}/templates
6128
+ * 요청 body 는 `--file <json>` 로 읽은 값을 그대로 전달한다(필수값 검증은 API 오류에 위임).
6129
+ * 응답: { header, template: {...} } — named 필드(getTemplate 과 동일 패턴).
6130
+ */
6131
+ async createTemplate(body) {
6132
+ const url = `${this.baseUrl}/templates`;
6133
+ try {
6134
+ const res = await import_ky12.default.post(url, {
6135
+ headers: this.authHeaders(),
6136
+ json: body,
6137
+ retry: 0,
6138
+ timeout: DEFAULT_TIMEOUT_MS8
6139
+ });
6140
+ const resBody = await res.json();
6141
+ unwrapHeader(resBody);
6142
+ if (!isNcsTemplateDetail(resBody.template)) {
6143
+ throw new NhnCloudCliError(
6144
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: template \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6145
+ EXIT_API_ERROR
6146
+ );
6147
+ }
6148
+ return resBody.template;
6149
+ } catch (err) {
6150
+ if (err instanceof NhnCloudCliError) throw err;
6151
+ throw toNhnCloudCliError(err);
6152
+ }
6153
+ }
6154
+ /**
6155
+ * 설계도(template) 를 삭제한다.
6156
+ * DELETE /ncs/v1.0/appkeys/{appKey}/templates/{id}
6157
+ */
6158
+ async deleteTemplate(id) {
6159
+ const url = `${this.baseUrl}/templates/${encodeURIComponent(id)}`;
6160
+ try {
6161
+ const res = await import_ky12.default.delete(url, {
6162
+ headers: this.authHeaders(),
6163
+ retry: 0,
6164
+ timeout: DEFAULT_TIMEOUT_MS8
6165
+ });
6166
+ unwrapHeader(await res.json());
6167
+ } catch (err) {
6168
+ if (err instanceof NhnCloudCliError) throw err;
6169
+ throw toNhnCloudCliError(err);
6170
+ }
6171
+ }
6172
+ /**
6173
+ * 설계도(template) 의 새 버전을 생성한다.
6174
+ * POST /ncs/v1.0/appkeys/{appKey}/templates/{id}/versions
6175
+ * body 에 `sourceVersion` 이 필수(docs 확정)이나 클라이언트는 그대로 전달하고
6176
+ * 필수값 검증은 API 응답 오류에 위임한다(1-3 회피 — API 경로에서 EXIT_PARAM_ERROR 를 만들지 않음).
6177
+ * 응답: { header, version: {...} } — named 필드(getTemplateVersion 과 동일 패턴).
6178
+ */
6179
+ async createTemplateVersion(id, body) {
6180
+ const url = `${this.baseUrl}/templates/${encodeURIComponent(id)}/versions`;
6181
+ try {
6182
+ const res = await import_ky12.default.post(url, {
6183
+ headers: this.authHeaders(),
6184
+ json: body,
6185
+ retry: 0,
6186
+ timeout: DEFAULT_TIMEOUT_MS8
6187
+ });
6188
+ const resBody = await res.json();
6189
+ unwrapHeader(resBody);
6190
+ if (!isNcsTemplateVersionDetail(resBody.version)) {
6191
+ throw new NhnCloudCliError(
6192
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: version \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6193
+ EXIT_API_ERROR
6194
+ );
6195
+ }
6196
+ return resBody.version;
6197
+ } catch (err) {
6198
+ if (err instanceof NhnCloudCliError) throw err;
6199
+ throw toNhnCloudCliError(err);
6200
+ }
6201
+ }
6202
+ /**
6203
+ * 설계도(template) 버전을 삭제한다.
6204
+ * DELETE /ncs/v1.0/appkeys/{appKey}/templates/{id}/versions/{version}
6205
+ */
6206
+ async deleteTemplateVersion(id, version) {
6207
+ const url = `${this.baseUrl}/templates/${encodeURIComponent(id)}/versions/${encodeURIComponent(version)}`;
6208
+ try {
6209
+ const res = await import_ky12.default.delete(url, {
6210
+ headers: this.authHeaders(),
6211
+ retry: 0,
6212
+ timeout: DEFAULT_TIMEOUT_MS8
6213
+ });
6214
+ unwrapHeader(await res.json());
6215
+ } catch (err) {
6216
+ if (err instanceof NhnCloudCliError) throw err;
6217
+ throw toNhnCloudCliError(err);
6218
+ }
6219
+ }
6220
+ /**
6221
+ * workload 를 일시정지한다.
6222
+ * POST /ncs/v1.0/appkeys/{appKey}/workloads/{id}/pause
6223
+ */
6224
+ async pauseWorkload(id) {
6225
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/pause`;
6226
+ try {
6227
+ const res = await import_ky12.default.post(url, {
6228
+ headers: this.authHeaders(),
6229
+ retry: 0,
6230
+ timeout: DEFAULT_TIMEOUT_MS8
6231
+ });
6232
+ unwrapHeader(await res.json());
6233
+ } catch (err) {
6234
+ if (err instanceof NhnCloudCliError) throw err;
6235
+ throw toNhnCloudCliError(err);
6236
+ }
6237
+ }
6238
+ /**
6239
+ * workload 를 재개한다.
6240
+ * POST /ncs/v1.0/appkeys/{appKey}/workloads/{id}/resume
6241
+ */
6242
+ async resumeWorkload(id) {
6243
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/resume`;
6244
+ try {
6245
+ const res = await import_ky12.default.post(url, {
6246
+ headers: this.authHeaders(),
6247
+ retry: 0,
6248
+ timeout: DEFAULT_TIMEOUT_MS8
6249
+ });
6250
+ unwrapHeader(await res.json());
6251
+ } catch (err) {
6252
+ if (err instanceof NhnCloudCliError) throw err;
6253
+ throw toNhnCloudCliError(err);
6254
+ }
6255
+ }
6256
+ /**
6257
+ * workload task 를 재시작한다.
6258
+ * POST /ncs/v1.0/appkeys/{appKey}/workloads/{id}/tasks/{taskId}/restart
6259
+ */
6260
+ async restartWorkloadTask(id, taskId) {
6261
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}/tasks/${encodeURIComponent(taskId)}/restart`;
6262
+ try {
6263
+ const res = await import_ky12.default.post(url, {
6264
+ headers: this.authHeaders(),
6265
+ retry: 0,
6266
+ timeout: DEFAULT_TIMEOUT_MS8
6267
+ });
6268
+ unwrapHeader(await res.json());
6269
+ } catch (err) {
6270
+ if (err instanceof NhnCloudCliError) throw err;
6271
+ throw toNhnCloudCliError(err);
6272
+ }
6273
+ }
6274
+ /**
6275
+ * workload 를 생성한다.
6276
+ * POST /ncs/v1.0/appkeys/{appKey}/workloads
6277
+ * 요청 body 는 `--file <json>` 로 읽은 값을 그대로 전달한다(필수값 검증은 API 오류에 위임 — createTemplate 과 동일).
6278
+ * 응답: { header, workload: {...} } — 생성된 workload 전체 객체(id 만 반환하는 축약 응답 아님, docs 예제 실측 확정).
6279
+ */
6280
+ async createWorkload(body) {
6281
+ const url = `${this.baseUrl}/workloads`;
6282
+ try {
6283
+ const res = await import_ky12.default.post(url, {
6284
+ headers: this.authHeaders(),
6285
+ json: body,
6286
+ retry: 0,
6287
+ timeout: DEFAULT_TIMEOUT_MS8
6288
+ });
6289
+ const resBody = await res.json();
6290
+ unwrapHeader(resBody);
6291
+ if (!isNcsWorkloadDetail(resBody.workload)) {
6292
+ throw new NhnCloudCliError(
6293
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: workload \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6294
+ EXIT_API_ERROR
6295
+ );
6296
+ }
6297
+ return resBody.workload;
6298
+ } catch (err) {
6299
+ if (err instanceof NhnCloudCliError) throw err;
6300
+ throw toNhnCloudCliError(err);
6301
+ }
6302
+ }
6303
+ /**
6304
+ * workload 를 전체 교체한다.
6305
+ * PUT /ncs/v1.0/appkeys/{appKey}/workloads/{id}
6306
+ * 응답: { header, workload: {...} } — createWorkload 와 동일한 전체 객체 응답(docs 예제 실측 확정).
6307
+ */
6308
+ async updateWorkload(id, body) {
6309
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}`;
6310
+ try {
6311
+ const res = await import_ky12.default.put(url, {
6312
+ headers: this.authHeaders(),
6313
+ json: body,
6314
+ retry: 0,
6315
+ timeout: DEFAULT_TIMEOUT_MS8
6316
+ });
6317
+ const resBody = await res.json();
6318
+ unwrapHeader(resBody);
6319
+ if (!isNcsWorkloadDetail(resBody.workload)) {
6320
+ throw new NhnCloudCliError(
6321
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: workload \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6322
+ EXIT_API_ERROR
6323
+ );
6324
+ }
6325
+ return resBody.workload;
6326
+ } catch (err) {
6327
+ if (err instanceof NhnCloudCliError) throw err;
6328
+ throw toNhnCloudCliError(err);
6329
+ }
6330
+ }
6331
+ /**
6332
+ * workload 를 부분 변경한다 (JSON Patch 배열, RFC 6902).
6333
+ * PATCH /ncs/v1.0/appkeys/{appKey}/workloads/{id}
6334
+ * Content-Type 이 application/json-patch+json 이어야 한다(docs 확정) — authHeaders() 에 덮어써서 명시 지정.
6335
+ * 응답: { header, workload: {...} } — createWorkload 와 동일한 전체 객체 응답(docs 예제 실측 확정).
6336
+ * redirect/status 분기 불필요 — 공통 봉투 응답(HTTP 200 고정, ADR-006).
6337
+ */
6338
+ async patchWorkload(id, patch) {
6339
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}`;
6340
+ try {
6341
+ const res = await import_ky12.default.patch(url, {
6342
+ headers: { ...this.authHeaders(), "Content-Type": "application/json-patch+json" },
6343
+ json: patch,
6344
+ retry: 0,
6345
+ timeout: DEFAULT_TIMEOUT_MS8
6346
+ });
6347
+ const resBody = await res.json();
6348
+ unwrapHeader(resBody);
6349
+ if (!isNcsWorkloadDetail(resBody.workload)) {
6350
+ throw new NhnCloudCliError(
6351
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: workload \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6352
+ EXIT_API_ERROR
6353
+ );
6354
+ }
6355
+ return resBody.workload;
6356
+ } catch (err) {
6357
+ if (err instanceof NhnCloudCliError) throw err;
6358
+ throw toNhnCloudCliError(err);
6359
+ }
6360
+ }
6361
+ /**
6362
+ * workload 가 `Running` 상태에 도달할 때까지 폴링한다 (instance client 의 waitForActive 선례, ADR-011).
6363
+ * 데드라인을 고정해두고 매 반복 남은 시간만큼만 대기해 timeoutMs 를 초과하지 않는다.
6364
+ * 타임아웃 시 마지막으로 조회한 상태를 메시지에 포함해 NhnCloudCliError(EXIT_API_ERROR) 를 던진다.
6365
+ */
6366
+ async waitForRunning(id, opts) {
6367
+ const intervalMs = opts.intervalMs ?? DEFAULT_WAIT_POLL_INTERVAL_MS;
6368
+ const deadline = Date.now() + opts.timeoutMs;
6369
+ let lastWorkload = null;
6370
+ while (Date.now() < deadline) {
6371
+ const workload = await this.getWorkload(id);
6372
+ lastWorkload = workload;
6373
+ if (workload.status === "Running") {
6374
+ return workload;
6375
+ }
6376
+ const remaining = deadline - Date.now();
6377
+ if (remaining <= 0) break;
6378
+ await new Promise((resolve) => setTimeout(resolve, Math.min(intervalMs, remaining)));
6379
+ }
6380
+ const lastStatus = lastWorkload ? lastWorkload.status : "unknown";
6381
+ throw new NhnCloudCliError(
6382
+ `NCS workload ${id} \uAC00 Running \uC0C1\uD0DC\uAC00 \uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4 (\uB9C8\uC9C0\uB9C9 \uC0C1\uD0DC: ${lastStatus}). --wait \uD0C0\uC784\uC544\uC6C3(${Math.round(opts.timeoutMs / 1e3)}\uCD08) \uCD08\uACFC.`,
6383
+ EXIT_API_ERROR
6384
+ );
6385
+ }
6386
+ /**
6387
+ * workload 를 삭제한다.
6388
+ * DELETE /ncs/v1.0/appkeys/{appKey}/workloads/{id}
6389
+ */
6390
+ async deleteWorkload(id) {
6391
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(id)}`;
6392
+ try {
6393
+ const res = await import_ky12.default.delete(url, {
6394
+ headers: this.authHeaders(),
6395
+ retry: 0,
6396
+ timeout: DEFAULT_TIMEOUT_MS8
6397
+ });
6398
+ unwrapHeader(await res.json());
6399
+ } catch (err) {
6400
+ if (err instanceof NhnCloudCliError) throw err;
6401
+ throw toNhnCloudCliError(err);
6402
+ }
6403
+ }
6404
+ /**
6405
+ * 악성코드 검사 설정을 조회한다.
6406
+ * GET /ncs/v1.0/appkeys/{appKey}/malware/config (appkey-scoped, docs 예제 실측 확정 — 계정 레벨 아님)
6407
+ * 응답: { header, enabled: true|false } — named 필드 없이 header 와 나란히 flat 필드(docs 예제 실측 확정).
6408
+ */
6409
+ async getMalwareConfig() {
6410
+ const url = `${this.baseUrl}/malware/config`;
6411
+ try {
6412
+ const res = await import_ky12.default.get(url, {
6413
+ headers: this.authHeaders(),
6414
+ retry: 0,
6415
+ timeout: DEFAULT_TIMEOUT_MS8
6416
+ });
6417
+ const body = await res.json();
6418
+ unwrapHeader(body);
6419
+ if (!isNcsMalwareConfig(body)) {
6420
+ throw new NhnCloudCliError(
6421
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: enabled \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6422
+ EXIT_API_ERROR
6423
+ );
6424
+ }
6425
+ return { enabled: body.enabled };
6426
+ } catch (err) {
6427
+ if (err instanceof NhnCloudCliError) throw err;
6428
+ throw toNhnCloudCliError(err);
6429
+ }
6430
+ }
6431
+ /**
6432
+ * 악성코드 검사 설정을 변경한다.
6433
+ * POST /ncs/v1.0/appkeys/{appKey}/malware/config (method 는 POST — docs 예제 실측 확정, PUT 아님)
6434
+ * 요청 body: { enabled: boolean } — docs 필드 표기는 "String" 이나 예제 JSON 이 quote 없는 boolean
6435
+ * 리터럴이라 실제 wire 타입은 boolean(malware.enabled 실측 확정, ADR-020 트레이드오프 절 참조).
6436
+ * 응답: { header, enabled: true|false } — getMalwareConfig 와 동일한 flat 패턴.
6437
+ */
6438
+ async setMalwareConfig(enabled) {
6439
+ const url = `${this.baseUrl}/malware/config`;
6440
+ try {
6441
+ const res = await import_ky12.default.post(url, {
6442
+ headers: this.authHeaders(),
6443
+ json: { enabled },
6444
+ retry: 0,
6445
+ timeout: DEFAULT_TIMEOUT_MS8
6446
+ });
6447
+ const body = await res.json();
6448
+ unwrapHeader(body);
6449
+ if (!isNcsMalwareConfig(body)) {
6450
+ throw new NhnCloudCliError(
6451
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: enabled \uD544\uB4DC\uAC00 \uC5C6\uAC70\uB098 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
6452
+ EXIT_API_ERROR
6453
+ );
6454
+ }
6455
+ return { enabled: body.enabled };
6456
+ } catch (err) {
6457
+ if (err instanceof NhnCloudCliError) throw err;
6458
+ throw toNhnCloudCliError(err);
6459
+ }
6460
+ }
6461
+ /**
6462
+ * workload 실행 히스토리의 악성코드 검사 결과를 조회한다.
6463
+ * GET /ncs/v1.0/appkeys/{appKey}/workloads/{workloadId}/history/{historyId}/malware
6464
+ * 응답: { header, scannedAt, infectedFiles, scannedDirectories, scannedFiles, reports: [...] } —
6465
+ * named 필드로 감싸지 않고 header 와 나란히 flat 필드(docs 예제 실측 확정, malware config 와 동일 패턴).
6466
+ * 모든 top-level 필드가 docs 상 optional(미검사 워크로드는 누락 가능) — 존재하면 그대로 통과시킨다.
6467
+ */
6468
+ async getMalwareResult(workloadId, historyId) {
6469
+ const url = `${this.baseUrl}/workloads/${encodeURIComponent(workloadId)}/history/${encodeURIComponent(historyId)}/malware`;
6470
+ try {
6471
+ const res = await import_ky12.default.get(url, {
6472
+ headers: this.authHeaders(),
6473
+ retry: 0,
6474
+ timeout: DEFAULT_TIMEOUT_MS8
6475
+ });
6476
+ const body = await res.json();
6477
+ unwrapHeader(body);
6478
+ if (body.reports !== void 0 && !Array.isArray(body.reports)) {
6479
+ throw new NhnCloudCliError(
6480
+ "NCS API \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: reports \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4.",
6481
+ EXIT_API_ERROR
6482
+ );
6483
+ }
6484
+ return {
6485
+ scannedAt: body.scannedAt,
6486
+ infectedFiles: body.infectedFiles,
6487
+ scannedDirectories: body.scannedDirectories,
6488
+ scannedFiles: body.scannedFiles,
6489
+ reports: body.reports?.filter(isNcsMalwareReport) ?? []
6490
+ };
6491
+ } catch (err) {
6492
+ if (err instanceof NhnCloudCliError) throw err;
6493
+ throw toNhnCloudCliError(err);
6494
+ }
6495
+ }
6496
+ };
6497
+
6498
+ // src/commands/ncs/helpers.ts
6499
+ var MAX_JSON_PAYLOAD_BYTES = 1e6;
6500
+ async function resolveNcsAppKey(profileName, appKeyOpt) {
6501
+ if (appKeyOpt) return appKeyOpt;
6502
+ let cred;
6503
+ try {
6504
+ cred = await getServiceCredential("ncs", profileName);
6505
+ } catch (err) {
6506
+ if (!(err instanceof NhnCloudCliError) || err.exitCode !== EXIT_CONFIG_ERROR) {
6507
+ throw err;
6508
+ }
6509
+ }
6510
+ if (!cred?.appkey) {
6511
+ throw new NhnCloudCliError(
6512
+ "NCS appKey \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. --app-key \uC635\uC158\uC73C\uB85C \uC9C0\uC815\uD558\uAC70\uB098\n~/.nhncloud/credentials.json \uC758 profiles.<profile>.ncs.appkey \uB97C \uC9C1\uC811 \uCD94\uAC00\uD558\uC138\uC694.\n(nhncloud configure \uB294 \uC544\uC9C1 ncs \uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.)",
6513
+ EXIT_CONFIG_ERROR
6514
+ );
6515
+ }
6516
+ return cred.appkey;
6517
+ }
6518
+ async function resolveNcsClient(opts) {
6519
+ const profileName = await resolveProfileName(opts.profile);
6520
+ const uak = await getUserAccessKey(profileName);
6521
+ const accessToken = await getAccessToken(profileName, uak.id, uak.secret);
6522
+ const appKey = await resolveNcsAppKey(profileName, opts.appKey);
6523
+ const region = opts.region ?? "kr1";
6524
+ return { client: new NcsClient(accessToken, region, appKey), profileName };
6525
+ }
6526
+ function readJsonPayload(filePath) {
6527
+ let stat;
6528
+ try {
6529
+ stat = (0, import_node_fs7.statSync)(filePath);
6530
+ } catch (err) {
6531
+ const reason = err.code ?? (err instanceof Error ? err.message : String(err));
6532
+ throw new NhnCloudCliError(
6533
+ `\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${filePath} (${reason})`,
6534
+ EXIT_PARAM_ERROR
6535
+ );
6536
+ }
6537
+ if (!stat.isFile()) {
6538
+ throw new NhnCloudCliError(`--file \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${filePath}`, EXIT_PARAM_ERROR);
6539
+ }
6540
+ if (stat.size > MAX_JSON_PAYLOAD_BYTES) {
6541
+ throw new NhnCloudCliError(
6542
+ `--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat.size} \uBC14\uC774\uD2B8). JSON spec \uD55C\uB3C4 ${MAX_JSON_PAYLOAD_BYTES} \uBC14\uC774\uD2B8.`,
6543
+ EXIT_PARAM_ERROR
6544
+ );
6545
+ }
6546
+ const raw = (0, import_node_fs7.readFileSync)(filePath, "utf-8");
6547
+ try {
6548
+ return JSON.parse(raw);
6549
+ } catch (err) {
6550
+ const detail = err instanceof Error ? err.message : String(err);
6551
+ throw new NhnCloudCliError(
6552
+ `JSON \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4: ${filePath} (${detail})`,
6553
+ EXIT_PARAM_ERROR
6554
+ );
6555
+ }
6556
+ }
6557
+ function requireNonEmpty(value, label) {
6558
+ if (!value.trim()) {
6559
+ throw new NhnCloudCliError(`${label} \uC778\uC218\uAC00 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4.`, EXIT_PARAM_ERROR);
6560
+ }
6561
+ }
6562
+ async function confirmDestructive(message, yes) {
6563
+ const isTTY = process.stdin.isTTY;
6564
+ if (!isTTY && !yes) {
6565
+ throw new NhnCloudCliError(
6566
+ "\uBE44\uB300\uD654\uD615 \uD658\uACBD\uC5D0\uC11C\uB294 --yes \uD50C\uB798\uADF8\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",
6567
+ EXIT_PARAM_ERROR
6568
+ );
6569
+ }
6570
+ if (isTTY && !yes) {
6571
+ const { confirm } = await import("@inquirer/prompts");
6572
+ return confirm({ message, default: false });
6573
+ }
6574
+ return true;
6575
+ }
6576
+
6577
+ // src/commands/ncs/template.ts
6578
+ var listCommand8 = new import_commander43.Command("list").description("NCS \uC124\uACC4\uB3C4(template) \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--page <page>", "\uC870\uD68C\uD560 page \uBC88\uD638").option("--size <size>", "page \uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: API \uAE30\uBCF8\uAC12 10)").action(async (_opts, cmd) => {
6579
+ const opts = cmd.optsWithGlobals();
6580
+ const { client } = await resolveNcsClient(opts);
6581
+ startSpinner("NCS \uC124\uACC4\uB3C4 \uBAA9\uB85D \uC870\uD68C \uC911...");
6582
+ let totalCount;
6583
+ let templates;
6584
+ try {
6585
+ const result = await client.listTemplates({
6586
+ page: parsePositiveIntegerOption(opts.page, "--page"),
6587
+ size: parsePositiveIntegerOption(opts.size, "--size")
6588
+ });
6589
+ totalCount = result.totalCount;
6590
+ templates = result.templates;
6591
+ } catch (err) {
6592
+ stopSpinner(false);
6593
+ throw err;
6594
+ }
6595
+ stopSpinner(true);
6596
+ output(opts, {
6597
+ headers: ["id", "name", "version", "versionCount", "workloadCount"],
6598
+ rows: templates.map((t) => [
6599
+ t.id,
6600
+ t.name,
6601
+ t.version ?? "",
6602
+ String(t.versionCount ?? ""),
6603
+ String(t.workloadCount ?? "")
6604
+ ]),
6605
+ raw: { totalCount, templates },
6606
+ ids: templates.map((t) => t.id)
6607
+ });
6608
+ });
6609
+ var getCommand6 = new import_commander43.Command("get").description("NCS \uC124\uACC4\uB3C4(template) \uB2E8\uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<id>", "template ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
6610
+ const opts = cmd.optsWithGlobals();
6611
+ requireNonEmpty(id, "id");
6612
+ const { client } = await resolveNcsClient(opts);
6613
+ startSpinner(`NCS \uC124\uACC4\uB3C4 "${id}" \uC870\uD68C \uC911...`);
6614
+ let template;
6615
+ try {
6616
+ template = await client.getTemplate(id);
6617
+ } catch (err) {
6618
+ stopSpinner(false);
6619
+ throw err;
6620
+ }
6621
+ stopSpinner(true);
6622
+ output(opts, {
6623
+ headers: ["id", "name", "version", "versionCount", "workloadCount"],
6624
+ rows: [
6625
+ [
6626
+ template.id,
6627
+ template.name,
6628
+ template.version ?? "",
6629
+ String(template.versionCount ?? ""),
6630
+ String(template.workloadCount ?? "")
6631
+ ]
6632
+ ],
6633
+ raw: template,
6634
+ ids: [template.id]
6635
+ });
6636
+ });
6637
+ var createCommand6 = new import_commander43.Command("create").description("NCS \uC124\uACC4\uB3C4(template) \uB97C \uC0DD\uC131\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC)").requiredOption("--file <path>", "template \uC0DD\uC131 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
6638
+ const opts = cmd.optsWithGlobals();
6639
+ const payload = readJsonPayload(opts.file);
6640
+ const { client } = await resolveNcsClient(opts);
6641
+ startSpinner("NCS \uC124\uACC4\uB3C4 \uC0DD\uC131 \uC911...");
6642
+ let template;
6643
+ try {
6644
+ template = await client.createTemplate(payload);
6645
+ } catch (err) {
6646
+ stopSpinner(false);
6647
+ throw err;
6648
+ }
6649
+ stopSpinner(true);
6650
+ output(opts, {
6651
+ headers: ["id", "name", "version", "versionCount", "workloadCount"],
6652
+ rows: [
6653
+ [
6654
+ template.id,
6655
+ template.name,
6656
+ template.version ?? "",
6657
+ String(template.versionCount ?? ""),
6658
+ String(template.workloadCount ?? "")
6659
+ ]
6660
+ ],
6661
+ raw: template,
6662
+ ids: [template.id]
6663
+ });
6664
+ });
6665
+ var deleteCommand5 = new import_commander43.Command("delete").description("NCS \uC124\uACC4\uB3C4(template) \uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<id>", "template ID").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
6666
+ const opts = cmd.optsWithGlobals();
6667
+ requireNonEmpty(id, "id");
6668
+ const ok = await confirmDestructive(`NCS \uC124\uACC4\uB3C4 "${id}" \uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
6669
+ if (!ok) {
6670
+ process.stderr.write(import_chalk14.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
6671
+ return;
6672
+ }
6673
+ const { client } = await resolveNcsClient(opts);
6674
+ startSpinner(`NCS \uC124\uACC4\uB3C4 \uC0AD\uC81C \uC911... (id: ${id})`);
6675
+ try {
6676
+ await client.deleteTemplate(id);
6677
+ } catch (err) {
6678
+ stopSpinner(false);
6679
+ throw err;
6680
+ }
6681
+ stopSpinner(true);
6682
+ process.stderr.write(import_chalk14.default.green(`\u2713 NCS \uC124\uACC4\uB3C4 "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
6683
+ `));
6684
+ });
6685
+ var versionListCommand = new import_commander43.Command("list").description("NCS \uC124\uACC4\uB3C4(template) \uC758 \uBC84\uC804 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<id>", "template ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--q <query>", "\uAC80\uC0C9\uC5B4").option("--sort <sort>", "\uC815\uB82C \uC870\uAC74").option("--page <page>", "\uC870\uD68C\uD560 page \uBC88\uD638").option("--size <size>", "page \uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: API \uAE30\uBCF8\uAC12 10)").action(async (id, _opts, cmd) => {
6686
+ const opts = cmd.optsWithGlobals();
6687
+ requireNonEmpty(id, "id");
6688
+ const { client } = await resolveNcsClient(opts);
6689
+ startSpinner(`NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 \uBAA9\uB85D \uC870\uD68C \uC911...`);
6690
+ let totalCount;
6691
+ let versions;
6692
+ try {
6693
+ const result = await client.listTemplateVersions(id, {
6694
+ q: opts.q,
6695
+ sort: opts.sort,
6696
+ page: parsePositiveIntegerOption(opts.page, "--page"),
6697
+ size: parsePositiveIntegerOption(opts.size, "--size")
6698
+ });
6699
+ totalCount = result.totalCount;
6700
+ versions = result.versions;
6701
+ } catch (err) {
6702
+ stopSpinner(false);
6703
+ throw err;
6704
+ }
6705
+ stopSpinner(true);
6706
+ output(opts, {
6707
+ headers: ["id", "version", "workloadCount", "createdAt"],
6708
+ rows: versions.map((v) => [
6709
+ v.id,
6710
+ v.version,
6711
+ String(v.workloadCount ?? ""),
6712
+ v.createdAt ?? ""
6713
+ ]),
6714
+ raw: { totalCount, versions },
6715
+ ids: versions.map((v) => v.id)
6716
+ });
6717
+ });
6718
+ var versionGetCommand = new import_commander43.Command("get").description("NCS \uC124\uACC4\uB3C4(template) \uBC84\uC804 \uB2E8\uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<id>", "template ID").argument("<version>", "\uBC84\uC804 \uAC12").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, version, _opts, cmd) => {
6719
+ const opts = cmd.optsWithGlobals();
6720
+ requireNonEmpty(id, "id");
6721
+ requireNonEmpty(version, "version");
6722
+ const { client } = await resolveNcsClient(opts);
6723
+ startSpinner(`NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 "${version}" \uC870\uD68C \uC911...`);
6724
+ let detail;
6725
+ try {
6726
+ detail = await client.getTemplateVersion(id, version);
6727
+ } catch (err) {
6728
+ stopSpinner(false);
6729
+ throw err;
6730
+ }
6731
+ stopSpinner(true);
6732
+ output(opts, {
6733
+ headers: ["id", "version", "workloadCount", "createdAt"],
6734
+ rows: [[detail.id, detail.version, String(detail.workloadCount ?? ""), detail.createdAt ?? ""]],
6735
+ raw: detail,
6736
+ ids: [detail.id]
6737
+ });
6738
+ });
6739
+ var versionCreateCommand = new import_commander43.Command("create").description("NCS \uC124\uACC4\uB3C4(template) \uC758 \uC0C8 \uBC84\uC804\uC744 \uC0DD\uC131\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC, sourceVersion \uD544\uC218)").argument("<id>", "template ID").requiredOption("--file <path>", "\uBC84\uC804 \uC0DD\uC131 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C (sourceVersion \uD544\uB4DC \uD544\uC218)").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
6740
+ const opts = cmd.optsWithGlobals();
6741
+ requireNonEmpty(id, "id");
6742
+ const payload = readJsonPayload(opts.file);
6743
+ const { client } = await resolveNcsClient(opts);
6744
+ startSpinner(`NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 \uC0DD\uC131 \uC911...`);
6745
+ let version;
6746
+ try {
6747
+ version = await client.createTemplateVersion(id, payload);
6748
+ } catch (err) {
6749
+ stopSpinner(false);
6750
+ throw err;
6751
+ }
6752
+ stopSpinner(true);
6753
+ output(opts, {
6754
+ headers: ["id", "version", "workloadCount", "createdAt"],
6755
+ rows: [[version.id, version.version, String(version.workloadCount ?? ""), version.createdAt ?? ""]],
6756
+ raw: version,
6757
+ ids: [version.id]
6758
+ });
6759
+ });
6760
+ var versionDeleteCommand = new import_commander43.Command("delete").description("NCS \uC124\uACC4\uB3C4(template) \uBC84\uC804\uC744 \uC0AD\uC81C\uD55C\uB2E4").argument("<id>", "template ID").argument("<version>", "\uBC84\uC804 \uAC12").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, version, _opts, cmd) => {
6761
+ const opts = cmd.optsWithGlobals();
6762
+ requireNonEmpty(id, "id");
6763
+ requireNonEmpty(version, "version");
6764
+ const ok = await confirmDestructive(
6765
+ `NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 "${version}" \uC744 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`,
6766
+ opts.yes
6767
+ );
6768
+ if (!ok) {
6769
+ process.stderr.write(import_chalk14.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
6770
+ return;
6771
+ }
6772
+ const { client } = await resolveNcsClient(opts);
6773
+ startSpinner(`NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 "${version}" \uC0AD\uC81C \uC911...`);
6774
+ try {
6775
+ await client.deleteTemplateVersion(id, version);
6776
+ } catch (err) {
6777
+ stopSpinner(false);
6778
+ throw err;
6779
+ }
6780
+ stopSpinner(true);
6781
+ process.stderr.write(
6782
+ import_chalk14.default.green(`\u2713 NCS \uC124\uACC4\uB3C4 "${id}" \uBC84\uC804 "${version}" \uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
6783
+ `)
6784
+ );
6785
+ });
6786
+ var versionCommand = new import_commander43.Command("version").description("NCS \uC124\uACC4\uB3C4(template) \uBC84\uC804 \uAD00\uB9AC").addCommand(versionListCommand).addCommand(versionGetCommand).addCommand(versionCreateCommand).addCommand(versionDeleteCommand);
6787
+ var templateCommand = new import_commander43.Command("template").description("NCS \uC124\uACC4\uB3C4(template) \uAD00\uB9AC").addCommand(listCommand8).addCommand(getCommand6).addCommand(createCommand6).addCommand(deleteCommand5).addCommand(versionCommand);
6788
+
6789
+ // src/commands/ncs/workload.ts
6790
+ var import_commander44 = require("commander");
6791
+ var import_chalk15 = __toESM(require("chalk"));
6792
+ function workloadRows(w) {
6793
+ return [
6794
+ [
6795
+ w.id,
6796
+ w.name,
6797
+ w.type ?? "",
6798
+ w.status,
6799
+ String(w.desired ?? ""),
6800
+ String(w.available ?? "")
6801
+ ]
6802
+ ];
6803
+ }
6804
+ var WORKLOAD_HEADERS = ["id", "name", "type", "status", "desired", "available"];
6805
+ var listCommand9 = new import_commander44.Command("list").description("NCS workload(\uB7F0\uD0C0\uC784 \uC2E4\uD589) \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--q <query>", "\uC6CC\uD06C\uB85C\uB4DC \uC774\uB984\xB7\uD15C\uD50C\uB9BF ID\xB7\uD15C\uD50C\uB9BF \uBC84\uC804\uC73C\uB85C \uD544\uD130\uB9C1").option("--page <page>", "\uC870\uD68C\uD560 page \uBC88\uD638").option("--size <size>", "page \uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: API \uAE30\uBCF8\uAC12 10)").action(async (_opts, cmd) => {
6806
+ const opts = cmd.optsWithGlobals();
6807
+ const { client } = await resolveNcsClient(opts);
6808
+ startSpinner("NCS workload \uBAA9\uB85D \uC870\uD68C \uC911...");
6809
+ let totalCount;
6810
+ let workloads;
6811
+ try {
6812
+ const result = await client.listWorkloads({
6813
+ q: opts.q,
6814
+ page: parsePositiveIntegerOption(opts.page, "--page"),
6815
+ size: parsePositiveIntegerOption(opts.size, "--size")
6816
+ });
6817
+ totalCount = result.totalCount;
6818
+ workloads = result.workloads;
6819
+ } catch (err) {
6820
+ stopSpinner(false);
6821
+ throw err;
6822
+ }
6823
+ stopSpinner(true);
6824
+ output(opts, {
6825
+ headers: ["id", "name", "type", "status", "desired", "available"],
6826
+ rows: workloads.map((w) => [
6827
+ w.id,
6828
+ w.name,
6829
+ w.type ?? "",
6830
+ w.status,
6831
+ String(w.desired ?? ""),
6832
+ String(w.available ?? "")
6833
+ ]),
6834
+ raw: { totalCount, workloads },
6835
+ ids: workloads.map((w) => w.id)
6836
+ });
6837
+ });
6838
+ var getCommand7 = new import_commander44.Command("get").description("NCS workload \uB2E8\uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
6839
+ const opts = cmd.optsWithGlobals();
6840
+ requireNonEmpty(id, "id");
6841
+ const { client } = await resolveNcsClient(opts);
6842
+ startSpinner(`NCS workload "${id}" \uC870\uD68C \uC911...`);
6843
+ let workload;
6844
+ try {
6845
+ workload = await client.getWorkload(id);
6846
+ } catch (err) {
6847
+ stopSpinner(false);
6848
+ throw err;
6849
+ }
6850
+ stopSpinner(true);
6851
+ output(opts, {
6852
+ headers: ["id", "name", "type", "status", "desired", "available", "tasks"],
6853
+ rows: [
6854
+ [
6855
+ workload.id,
6856
+ workload.name,
6857
+ workload.type ?? "",
6858
+ workload.status,
6859
+ String(workload.desired ?? ""),
6860
+ String(workload.available ?? ""),
6861
+ String(workload.tasks?.length ?? 0)
6862
+ ]
6863
+ ],
6864
+ raw: workload,
6865
+ ids: [workload.id]
6866
+ });
6867
+ });
6868
+ var logsCommand = new import_commander44.Command("logs").description("NCS workload task \uC758 \uCEE8\uD14C\uC774\uB108 \uB85C\uADF8\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--task <taskId>", "task ID (\uD544\uC218)").option("--container <name>", "\uCEE8\uD14C\uC774\uB108 \uC774\uB984 (\uD544\uC218)").option("--from <time>", "\uB85C\uADF8 \uC2DC\uC791 \uC2DC\uAC04 (\uAE30\uBCF8: \uD604\uC7AC\uB85C\uBD80\uD130 5\uBD84 \uC804)").option("--to <time>", "\uB85C\uADF8 \uC885\uB8CC \uC2DC\uAC04 (\uAE30\uBCF8: \uD604\uC7AC \uC2DC\uAC04)").option("--page <page>", "\uC870\uD68C\uD560 page \uBC88\uD638").option("--size <size>", "page \uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: API \uAE30\uBCF8\uAC12 100)").action(async (id, _opts, cmd) => {
6869
+ const opts = cmd.optsWithGlobals();
6870
+ requireNonEmpty(id, "id");
6871
+ if (!opts.task || !opts.task.trim()) {
6872
+ throw new NhnCloudCliError(
6873
+ "--task \uC635\uC158\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. task ID \uB97C \uC9C0\uC815\uD558\uC138\uC694.",
6874
+ EXIT_PARAM_ERROR
6875
+ );
6876
+ }
6877
+ if (!opts.container || !opts.container.trim()) {
6878
+ throw new NhnCloudCliError(
6879
+ "--container \uC635\uC158\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. \uCEE8\uD14C\uC774\uB108 \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC138\uC694.",
6880
+ EXIT_PARAM_ERROR
6881
+ );
6882
+ }
6883
+ const { client } = await resolveNcsClient(opts);
6884
+ startSpinner(`NCS workload "${id}" task "${opts.task}" \uB85C\uADF8 \uC870\uD68C \uC911...`);
6885
+ let logs;
6886
+ try {
6887
+ const result = await client.getWorkloadLogs(id, opts.task, {
6888
+ container: opts.container,
6889
+ from: opts.from,
6890
+ to: opts.to,
6891
+ page: parsePositiveIntegerOption(opts.page, "--page"),
6892
+ size: parsePositiveIntegerOption(opts.size, "--size")
6893
+ });
6894
+ logs = result.logs;
6895
+ } catch (err) {
6896
+ stopSpinner(false);
6897
+ throw err;
6898
+ }
6899
+ stopSpinner(true);
6900
+ output(opts, {
6901
+ headers: ["time", "log"],
6902
+ rows: logs.map((l) => [l.time, l.log]),
6903
+ raw: { logs },
6904
+ ids: []
6905
+ });
6906
+ });
6907
+ var eventsCommand2 = new import_commander44.Command("events").description("NCS workload task \uC758 \uC774\uBCA4\uD2B8\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--task <taskId>", "task ID (\uD544\uC218)").option("--type <type>", "\uC774\uBCA4\uD2B8 \uD0C0\uC785 (Normal | Warning)").option("--q <query>", "\uC774\uBCA4\uD2B8 \uB0B4\uC6A9 \uD544\uD130\uB9C1").option("--from <time>", "\uC774\uBCA4\uD2B8 \uB9C8\uC9C0\uB9C9 \uBC1C\uC0DD \uC2DC\uC791 \uC2DC\uAC04 (\uAE30\uBCF8: \uD604\uC7AC\uB85C\uBD80\uD130 1\uC2DC\uAC04 \uC804)").option("--to <time>", "\uC774\uBCA4\uD2B8 \uB9C8\uC9C0\uB9C9 \uBC1C\uC0DD \uC885\uB8CC \uC2DC\uAC04 (\uAE30\uBCF8: \uD604\uC7AC \uC2DC\uAC04)").option("--page <page>", "\uC870\uD68C\uD560 page \uBC88\uD638").option("--size <size>", "page \uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: API \uAE30\uBCF8\uAC12 10)").action(async (id, _opts, cmd) => {
6908
+ const opts = cmd.optsWithGlobals();
6909
+ requireNonEmpty(id, "id");
6910
+ if (!opts.task || !opts.task.trim()) {
6911
+ throw new NhnCloudCliError(
6912
+ "--task \uC635\uC158\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. task ID \uB97C \uC9C0\uC815\uD558\uC138\uC694.",
6913
+ EXIT_PARAM_ERROR
6914
+ );
6915
+ }
6916
+ const { client } = await resolveNcsClient(opts);
6917
+ startSpinner(`NCS workload "${id}" task "${opts.task}" \uC774\uBCA4\uD2B8 \uC870\uD68C \uC911...`);
6918
+ let totalCount;
6919
+ let events;
6920
+ try {
6921
+ const result = await client.getWorkloadEvents(id, opts.task, {
6922
+ type: opts.type,
6923
+ q: opts.q,
6924
+ from: opts.from,
6925
+ to: opts.to,
6926
+ page: parsePositiveIntegerOption(opts.page, "--page"),
6927
+ size: parsePositiveIntegerOption(opts.size, "--size")
6928
+ });
6929
+ totalCount = result.totalCount;
6930
+ events = result.events;
6931
+ } catch (err) {
6932
+ stopSpinner(false);
6933
+ throw err;
6934
+ }
6935
+ stopSpinner(true);
6936
+ output(opts, {
6937
+ headers: ["type", "reason", "message", "count", "lastTimestamp"],
6938
+ rows: events.map((e) => [e.type, e.reason, e.message, String(e.count), e.lastTimestamp]),
6939
+ raw: { totalCount, events },
6940
+ ids: []
6941
+ });
6942
+ });
6943
+ var historyGetCommand = new import_commander44.Command("get").description("NCS workload \uC2E4\uD589 \uD788\uC2A4\uD1A0\uB9AC \uB2E8\uAC74\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<id>", "workload ID").argument("<historyId>", "\uD788\uC2A4\uD1A0\uB9AC ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, historyId, _opts, cmd) => {
6944
+ const opts = cmd.optsWithGlobals();
6945
+ requireNonEmpty(id, "id");
6946
+ requireNonEmpty(historyId, "historyId");
6947
+ const { client } = await resolveNcsClient(opts);
6948
+ startSpinner(`NCS workload "${id}" \uD788\uC2A4\uD1A0\uB9AC "${historyId}" \uC870\uD68C \uC911...`);
6949
+ let detail;
6950
+ try {
6951
+ detail = await client.getWorkloadHistory(id, historyId);
6952
+ } catch (err) {
6953
+ stopSpinner(false);
6954
+ throw err;
6955
+ }
6956
+ stopSpinner(true);
6957
+ output(opts, {
6958
+ headers: ["id", "status", "templateId", "createdAt", "deletedAt"],
6959
+ rows: [
6960
+ [
6961
+ String(detail.id),
6962
+ detail.status,
6963
+ detail.templateId ?? "",
6964
+ detail.createdAt,
6965
+ detail.deletedAt ?? ""
6966
+ ]
6967
+ ],
6968
+ raw: detail,
6969
+ ids: [String(detail.id)]
6970
+ });
6971
+ });
6972
+ var historyCommand = new import_commander44.Command("history").description("NCS workload \uC2E4\uD589 \uD788\uC2A4\uD1A0\uB9AC \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--page <page>", "\uC870\uD68C\uD560 page \uBC88\uD638").option("--size <size>", "page \uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: API \uAE30\uBCF8\uAC12 10)").option("--sort <sort>", "\uC815\uB82C \uAE30\uC900 \uD544\uB4DC\uBA85 (\uC5ED\uC21C\uC740 \uD544\uB4DC\uBA85 \uC55E\uC5D0 - \uB97C \uBD99\uC784, \uC608: -id)").action(async (id, _opts, cmd) => {
6973
+ const opts = cmd.optsWithGlobals();
6974
+ requireNonEmpty(id, "id");
6975
+ const { client } = await resolveNcsClient(opts);
6976
+ startSpinner(`NCS workload "${id}" \uD788\uC2A4\uD1A0\uB9AC \uBAA9\uB85D \uC870\uD68C \uC911...`);
6977
+ let totalCount;
6978
+ let history;
6979
+ try {
6980
+ const result = await client.listWorkloadHistory(id, {
6981
+ page: parsePositiveIntegerOption(opts.page, "--page"),
6982
+ size: parsePositiveIntegerOption(opts.size, "--size"),
6983
+ sort: opts.sort
6984
+ });
6985
+ totalCount = result.totalCount;
6986
+ history = result.history;
6987
+ } catch (err) {
6988
+ stopSpinner(false);
6989
+ throw err;
6990
+ }
6991
+ stopSpinner(true);
6992
+ output(opts, {
6993
+ headers: ["id", "status", "templateId", "createdAt", "deletedAt"],
6994
+ rows: history.map((h) => [
6995
+ String(h.id),
6996
+ h.status,
6997
+ h.templateId ?? "",
6998
+ h.createdAt,
6999
+ h.deletedAt ?? ""
7000
+ ]),
7001
+ raw: { totalCount, history },
7002
+ ids: history.map((h) => String(h.id))
7003
+ });
7004
+ }).addCommand(historyGetCommand);
7005
+ var scheduleHistoryCommand = new import_commander44.Command("schedule-history").description("NCS workload \uC608\uC57D \uC2E4\uD589 \uD788\uC2A4\uD1A0\uB9AC\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7006
+ const opts = cmd.optsWithGlobals();
7007
+ requireNonEmpty(id, "id");
7008
+ const { client } = await resolveNcsClient(opts);
7009
+ startSpinner(`NCS workload "${id}" \uC608\uC57D \uC2E4\uD589 \uD788\uC2A4\uD1A0\uB9AC \uC870\uD68C \uC911...`);
7010
+ let scheduleHistory;
7011
+ try {
7012
+ const result = await client.getWorkloadScheduleHistory(id);
7013
+ scheduleHistory = result.scheduleHistory;
7014
+ } catch (err) {
7015
+ stopSpinner(false);
7016
+ throw err;
7017
+ }
7018
+ stopSpinner(true);
7019
+ output(opts, {
7020
+ headers: ["id", "status", "createdAt", "finishedAt"],
7021
+ rows: scheduleHistory.map((s) => [s.id, s.status, s.createdAt, s.finishedAt ?? ""]),
7022
+ raw: { scheduleHistory },
7023
+ ids: scheduleHistory.map((s) => s.id)
7024
+ });
7025
+ });
7026
+ var createCommand7 = new import_commander44.Command("create").description("NCS workload(\uB7F0\uD0C0\uC784 \uC2E4\uD589) \uB97C \uC0DD\uC131\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC)").requiredOption("--file <path>", "workload \uC0DD\uC131 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C").option("--wait", "workload \uAC00 Running \uC0C1\uD0DC\uAC00 \uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30").option("--timeout <sec>", "wait \uD0C0\uC784\uC544\uC6C3 (\uCD08, \uAE30\uBCF8 300)", "300").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
7027
+ const opts = cmd.optsWithGlobals();
7028
+ const payload = readJsonPayload(opts.file);
7029
+ const timeoutMs = parsePositiveIntegerOption(opts.timeout ?? "300", "--timeout") * 1e3;
7030
+ const { client } = await resolveNcsClient(opts);
7031
+ startSpinner("NCS workload \uC0DD\uC131 \uC911...");
7032
+ let workload;
7033
+ try {
7034
+ workload = await client.createWorkload(payload);
7035
+ } catch (err) {
7036
+ stopSpinner(false);
7037
+ throw err;
7038
+ }
7039
+ stopSpinner(true);
7040
+ if (opts.wait) {
7041
+ startSpinner(`NCS workload "${workload.id}" Running \uB300\uAE30 \uC911...`);
7042
+ try {
7043
+ workload = await client.waitForRunning(workload.id, { timeoutMs });
7044
+ } catch (err) {
7045
+ stopSpinner(false);
7046
+ throw err;
7047
+ }
7048
+ stopSpinner(true, `Running \uD655\uC778 (id: ${workload.id})`);
7049
+ }
7050
+ output(opts, {
7051
+ headers: WORKLOAD_HEADERS,
7052
+ rows: workloadRows(workload),
7053
+ raw: workload,
7054
+ ids: [workload.id]
7055
+ });
7056
+ });
7057
+ var updateCommand = new import_commander44.Command("update").description("NCS workload \uB97C \uC804\uCCB4 \uAD50\uCCB4\uD55C\uB2E4 (--file \uB85C JSON spec \uC804\uB2EC, PUT)").argument("<id>", "workload ID").requiredOption("--file <path>", "workload \uAD50\uCCB4 spec \uC774 \uB2F4\uAE34 JSON \uD30C\uC77C \uACBD\uB85C").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7058
+ const opts = cmd.optsWithGlobals();
7059
+ requireNonEmpty(id, "id");
7060
+ const payload = readJsonPayload(opts.file);
7061
+ const { client } = await resolveNcsClient(opts);
7062
+ startSpinner(`NCS workload "${id}" \uAD50\uCCB4 \uC911...`);
7063
+ let workload;
7064
+ try {
7065
+ workload = await client.updateWorkload(id, payload);
7066
+ } catch (err) {
7067
+ stopSpinner(false);
7068
+ throw err;
7069
+ }
7070
+ stopSpinner(true);
7071
+ output(opts, {
7072
+ headers: WORKLOAD_HEADERS,
7073
+ rows: workloadRows(workload),
7074
+ raw: workload,
7075
+ ids: [workload.id]
7076
+ });
7077
+ });
7078
+ var patchCommand = new import_commander44.Command("patch").description("NCS workload \uB97C \uBD80\uBD84 \uBCC0\uACBD\uD55C\uB2E4 (--file \uB85C JSON Patch \uBC30\uC5F4 \uC804\uB2EC, RFC 6902)").argument("<id>", "workload ID").requiredOption("--file <path>", "JSON Patch \uBC30\uC5F4(op/path/value)\uC774 \uB2F4\uAE34 \uD30C\uC77C \uACBD\uB85C").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7079
+ const opts = cmd.optsWithGlobals();
7080
+ requireNonEmpty(id, "id");
7081
+ const payload = readJsonPayload(opts.file);
7082
+ const { client } = await resolveNcsClient(opts);
7083
+ startSpinner(`NCS workload "${id}" \uBD80\uBD84 \uBCC0\uACBD \uC911...`);
7084
+ let workload;
7085
+ try {
7086
+ workload = await client.patchWorkload(id, payload);
7087
+ } catch (err) {
7088
+ stopSpinner(false);
7089
+ throw err;
7090
+ }
7091
+ stopSpinner(true);
7092
+ output(opts, {
7093
+ headers: WORKLOAD_HEADERS,
7094
+ rows: workloadRows(workload),
7095
+ raw: workload,
7096
+ ids: [workload.id]
7097
+ });
7098
+ });
7099
+ var pauseCommand = new import_commander44.Command("pause").description("NCS workload \uB97C \uC77C\uC2DC\uC815\uC9C0\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7100
+ const opts = cmd.optsWithGlobals();
7101
+ requireNonEmpty(id, "id");
7102
+ const { client } = await resolveNcsClient(opts);
7103
+ startSpinner(`NCS workload "${id}" \uC77C\uC2DC\uC815\uC9C0 \uC911...`);
7104
+ try {
7105
+ await client.pauseWorkload(id);
7106
+ } catch (err) {
7107
+ stopSpinner(false);
7108
+ throw err;
7109
+ }
7110
+ stopSpinner(true);
7111
+ process.stderr.write(import_chalk15.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC77C\uC2DC\uC815\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7112
+ `));
7113
+ });
7114
+ var resumeCommand = new import_commander44.Command("resume").description("NCS workload \uB97C \uC7AC\uAC1C\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7115
+ const opts = cmd.optsWithGlobals();
7116
+ requireNonEmpty(id, "id");
7117
+ const { client } = await resolveNcsClient(opts);
7118
+ startSpinner(`NCS workload "${id}" \uC7AC\uAC1C \uC911...`);
7119
+ try {
7120
+ await client.resumeWorkload(id);
7121
+ } catch (err) {
7122
+ stopSpinner(false);
7123
+ throw err;
7124
+ }
7125
+ stopSpinner(true);
7126
+ process.stderr.write(import_chalk15.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC7AC\uAC1C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7127
+ `));
7128
+ });
7129
+ var restartCommand = new import_commander44.Command("restart").description("NCS workload task \uB97C \uC7AC\uC2DC\uC791\uD55C\uB2E4").argument("<id>", "workload ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").option("--task <taskId>", "task ID (\uD544\uC218)").action(async (id, _opts, cmd) => {
7130
+ const opts = cmd.optsWithGlobals();
7131
+ requireNonEmpty(id, "id");
7132
+ if (!opts.task || !opts.task.trim()) {
7133
+ throw new NhnCloudCliError(
7134
+ "--task \uC635\uC158\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4. task ID \uB97C \uC9C0\uC815\uD558\uC138\uC694.",
7135
+ EXIT_PARAM_ERROR
7136
+ );
7137
+ }
7138
+ const { client } = await resolveNcsClient(opts);
7139
+ startSpinner(`NCS workload "${id}" task "${opts.task}" \uC7AC\uC2DC\uC791 \uC911...`);
7140
+ try {
7141
+ await client.restartWorkloadTask(id, opts.task);
7142
+ } catch (err) {
7143
+ stopSpinner(false);
7144
+ throw err;
7145
+ }
7146
+ stopSpinner(true);
7147
+ process.stderr.write(
7148
+ import_chalk15.default.green(`\u2713 NCS workload "${id}" task "${opts.task}" \uAC00 \uC7AC\uC2DC\uC791\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7149
+ `)
7150
+ );
7151
+ });
7152
+ var deleteCommand6 = new import_commander44.Command("delete").description("NCS workload \uB97C \uC0AD\uC81C\uD55C\uB2E4").argument("<id>", "workload ID").option("--yes", "\uD655\uC778 \uD504\uB86C\uD504\uD2B8 \uC0DD\uB7B5 (CI/\uBE44\uB300\uD654\uD615 \uD544\uC218)").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (id, _opts, cmd) => {
7153
+ const opts = cmd.optsWithGlobals();
7154
+ requireNonEmpty(id, "id");
7155
+ const ok = await confirmDestructive(`NCS workload "${id}" \uB97C \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`, opts.yes);
7156
+ if (!ok) {
7157
+ process.stderr.write(import_chalk15.default.yellow("\uC0AD\uC81C\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n"));
7158
+ return;
7159
+ }
7160
+ const { client } = await resolveNcsClient(opts);
7161
+ startSpinner(`NCS workload \uC0AD\uC81C \uC911... (id: ${id})`);
7162
+ try {
7163
+ await client.deleteWorkload(id);
7164
+ } catch (err) {
7165
+ stopSpinner(false);
7166
+ throw err;
7167
+ }
7168
+ stopSpinner(true);
7169
+ process.stderr.write(import_chalk15.default.green(`\u2713 NCS workload "${id}" \uAC00 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
7170
+ `));
7171
+ });
7172
+ var workloadCommand = new import_commander44.Command("workload").description("NCS workload(\uB7F0\uD0C0\uC784 \uC2E4\uD589) \uAD00\uB9AC").addCommand(listCommand9).addCommand(getCommand7).addCommand(logsCommand).addCommand(eventsCommand2).addCommand(historyCommand).addCommand(scheduleHistoryCommand).addCommand(createCommand7).addCommand(updateCommand).addCommand(patchCommand).addCommand(pauseCommand).addCommand(resumeCommand).addCommand(restartCommand).addCommand(deleteCommand6);
7173
+
7174
+ // src/commands/ncs/malware.ts
7175
+ var import_commander45 = require("commander");
7176
+ function parseEnabledOption(value) {
7177
+ if (value === "true") return true;
7178
+ if (value === "false") return false;
7179
+ throw new NhnCloudCliError(
7180
+ `--enabled \uB294 true \uB610\uB294 false \uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${JSON.stringify(value)}).`,
7181
+ EXIT_PARAM_ERROR
7182
+ );
7183
+ }
7184
+ var configGetCommand = new import_commander45.Command("get").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
7185
+ const opts = cmd.optsWithGlobals();
7186
+ const { client } = await resolveNcsClient(opts);
7187
+ startSpinner("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uC870\uD68C \uC911...");
7188
+ let config;
7189
+ try {
7190
+ config = await client.getMalwareConfig();
7191
+ } catch (err) {
7192
+ stopSpinner(false);
7193
+ throw err;
7194
+ }
7195
+ stopSpinner(true);
7196
+ output(opts, {
7197
+ headers: ["enabled"],
7198
+ rows: [[String(config.enabled)]],
7199
+ raw: config,
7200
+ ids: []
7201
+ });
7202
+ });
7203
+ var configSetCommand = new import_commander45.Command("set").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815\uC744 \uBCC0\uACBD\uD55C\uB2E4").requiredOption("--enabled <true|false>", "\uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC0AC\uC6A9 \uC5EC\uBD80").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
7204
+ const opts = cmd.optsWithGlobals();
7205
+ const enabled = parseEnabledOption(opts.enabled);
7206
+ const { client } = await resolveNcsClient(opts);
7207
+ startSpinner("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uBCC0\uACBD \uC911...");
7208
+ let config;
7209
+ try {
7210
+ config = await client.setMalwareConfig(enabled);
7211
+ } catch (err) {
7212
+ stopSpinner(false);
7213
+ throw err;
7214
+ }
7215
+ stopSpinner(true);
7216
+ output(opts, {
7217
+ headers: ["enabled"],
7218
+ rows: [[String(config.enabled)]],
7219
+ raw: config,
7220
+ ids: []
7221
+ });
7222
+ });
7223
+ var configCommand = new import_commander45.Command("config").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uC124\uC815 \uAD00\uB9AC").addCommand(configGetCommand).addCommand(configSetCommand);
7224
+ var resultCommand = new import_commander45.Command("result").description("NCS workload \uC2E4\uD589 \uD788\uC2A4\uD1A0\uB9AC\uC758 \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uACB0\uACFC\uB97C \uC870\uD68C\uD55C\uB2E4").argument("<workloadId>", "workload ID").argument("<historyId>", "\uD788\uC2A4\uD1A0\uB9AC ID").option("--region <region>", "NCS region (\uAE30\uBCF8: kr1, kr1/kr3 \uB9CC \uC9C0\uC6D0)", "kr1").option("--app-key <key>", "NCS appKey (profile \uC758 ncs.appkey \uBCF4\uB2E4 \uC6B0\uC120)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (workloadId, historyId, _opts, cmd) => {
7225
+ const opts = cmd.optsWithGlobals();
7226
+ requireNonEmpty(workloadId, "workloadId");
7227
+ requireNonEmpty(historyId, "historyId");
7228
+ const { client } = await resolveNcsClient(opts);
7229
+ startSpinner(
7230
+ `NCS workload "${workloadId}" \uD788\uC2A4\uD1A0\uB9AC "${historyId}" \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uACB0\uACFC \uC870\uD68C \uC911...`
7231
+ );
7232
+ let result;
7233
+ try {
7234
+ result = await client.getMalwareResult(workloadId, historyId);
7235
+ } catch (err) {
7236
+ stopSpinner(false);
7237
+ throw err;
7238
+ }
7239
+ stopSpinner(true);
7240
+ output(opts, {
7241
+ headers: ["scannedAt", "infectedFiles", "scannedDirectories", "scannedFiles", "reports"],
7242
+ rows: [
7243
+ [
7244
+ result.scannedAt ?? "",
7245
+ String(result.infectedFiles ?? ""),
7246
+ String(result.scannedDirectories ?? ""),
7247
+ String(result.scannedFiles ?? ""),
7248
+ String(result.reports?.length ?? 0)
7249
+ ]
7250
+ ],
7251
+ raw: result,
7252
+ ids: []
7253
+ });
7254
+ });
7255
+ var malwareCommand = new import_commander45.Command("malware").description("NCS \uC545\uC131\uCF54\uB4DC \uAC80\uC0AC \uAD00\uB9AC").addCommand(configCommand).addCommand(resultCommand);
7256
+
7257
+ // src/index.ts
7258
+ var rootAgentHints = `
7259
+ Agent hints:
7260
+ - Prefer --json for structured output.
7261
+ - Use --quiet only when the command documents an identifier output.
7262
+ - Use --profile <name> to avoid relying on default profile.
7263
+ - For IaaS/NKS commands, use --region <region> when region matters.
7264
+ - Run "nhncloud commands --json" to inspect command paths and options.
7265
+ `;
7266
+ var logncrashAgentWorkflow = `
7267
+ Agent workflow:
7268
+ 1. nhncloud logncrash search --query '*' --from 1h --to now --json
7269
+ 2. nhncloud logncrash export --query '<lucene>' --from 1h --to now --output logs.jsonl
7270
+ `;
7271
+ var deployAgentWorkflow = `
7272
+ Agent workflow:
7273
+ 1. nhncloud deploy artifacts <target> --json
7274
+ 2. nhncloud deploy server-groups <target> --json
7275
+ 3. nhncloud deploy run <target>
7276
+ `;
7277
+ var instanceAgentWorkflow = `
7278
+ Agent workflow:
7279
+ 1. nhncloud instance images --json
7280
+ 2. nhncloud instance flavors --detail --json
7281
+ 3. nhncloud instance list --json
7282
+ `;
7283
+ var networkAgentWorkflow = `
7284
+ Agent workflow:
7285
+ 1. nhncloud network list --json
7286
+ 2. nhncloud network subnet list --json
7287
+ `;
7288
+ var volumeAgentWorkflow = `
7289
+ Agent workflow:
7290
+ 1. nhncloud volume list --json
7291
+ 2. nhncloud volume get <volume-id> --json
7292
+ `;
7293
+ var floatingIpAgentWorkflow = `
7294
+ Agent workflow:
7295
+ 1. nhncloud floatingip list --json
7296
+ 2. nhncloud floatingip create --json
7297
+ `;
7298
+ var ncrAgentWorkflow = `
7299
+ Agent workflow:
7300
+ 1. nhncloud ncr list --json
7301
+ 2. nhncloud ncr images <registry> --json
7302
+ 3. nhncloud ncr tags <registry> <repository> --json
7303
+ `;
7304
+ var nksAgentWorkflow = `
7305
+ Agent workflow:
7306
+ 1. nhncloud nks supports --json
7307
+ 2. nhncloud nks cluster list --json
7308
+ 3. nhncloud nks cluster get <cluster> --json
7309
+ `;
7310
+ var ncsAgentWorkflow = `
7311
+ Agent workflow:
7312
+ 1. nhncloud ncs template list --json
7313
+ 2. nhncloud ncs workload list --json
7314
+ 3. nhncloud ncs workload get <id> --json
7315
+ `;
7316
+ var program = new import_commander46.Command();
7317
+ program.name("nhncloud").description("NHN Cloud CLI \u2014 AI agent & terminal friendly").version("0.8.0").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").addHelpText("after", rootAgentHints);
7318
+ program.hook("preAction", () => {
7319
+ const opts = program.opts();
7320
+ if (!opts.color || process.env["NO_COLOR"]) {
7321
+ import_chalk16.default.level = 0;
7322
+ }
7323
+ if (opts.json || opts.quiet) {
7324
+ setQuiet(true);
7325
+ }
7326
+ });
7327
+ program.addCommand(configureCommand);
7328
+ var logncrashCommand = new import_commander46.Command("logncrash").description("Log & Crash \uAD00\uB828 \uBA85\uB839").addHelpText("after", logncrashAgentWorkflow);
7329
+ logncrashCommand.addCommand(searchCommand);
7330
+ logncrashCommand.addCommand(sendCommand);
7331
+ logncrashCommand.addCommand(exportCommand);
7332
+ program.addCommand(logncrashCommand);
7333
+ var deployCommand = new import_commander46.Command("deploy").description("NHN Cloud Deploy \uAD00\uB828 \uBA85\uB839").addHelpText("after", deployAgentWorkflow);
7334
+ deployCommand.addCommand(runCommand);
7335
+ deployCommand.addCommand(artifactsCommand);
7336
+ deployCommand.addCommand(serverGroupsCommand);
7337
+ deployCommand.addCommand(historiesCommand);
7338
+ deployCommand.addCommand(binaryGroupsCommand);
7339
+ deployCommand.addCommand(binariesCommand);
7340
+ deployCommand.addCommand(uploadCommand);
7341
+ deployCommand.addCommand(downloadCommand);
7342
+ program.addCommand(deployCommand);
7343
+ var instanceCommand = new import_commander46.Command("instance").description("Compute \uC778\uC2A4\uD134\uC2A4 \uAD00\uB828 \uBA85\uB839").addHelpText("after", instanceAgentWorkflow);
7344
+ instanceCommand.addCommand(listCommand);
7345
+ instanceCommand.addCommand(flavorsCommand);
7346
+ instanceCommand.addCommand(availabilityZonesCommand);
7347
+ instanceCommand.addCommand(getCommand2);
7348
+ instanceCommand.addCommand(createCommand3);
7349
+ instanceCommand.addCommand(deleteCommand2);
7350
+ instanceCommand.addCommand(startCommand);
7351
+ instanceCommand.addCommand(stopCommand);
7352
+ instanceCommand.addCommand(rebootCommand);
7353
+ instanceCommand.addCommand(resizeCommand);
7354
+ instanceCommand.addCommand(resizeConfirmCommand);
7355
+ instanceCommand.addCommand(resizeRevertCommand);
7356
+ instanceCommand.addCommand(imagesCommand);
7357
+ instanceCommand.addCommand(keypairsCommand);
7358
+ instanceCommand.addCommand(keypairCommand);
7359
+ instanceCommand.addCommand(volumeCommand);
7360
+ instanceCommand.addCommand(volumesCommand);
7361
+ program.addCommand(instanceCommand);
7362
+ var networkCommand = new import_commander46.Command("network").description("VPC\xB7\uC11C\uBE0C\uB137 \uC870\uD68C").addHelpText("after", networkAgentWorkflow);
7363
+ networkCommand.addCommand(listCommand3);
7364
+ networkCommand.addCommand(subnetCommand);
7365
+ program.addCommand(networkCommand);
7366
+ var volumeCommand2 = new import_commander46.Command("volume").description("Block Storage \uBCFC\uB968 \uAD00\uB828 \uBA85\uB839").addHelpText("after", volumeAgentWorkflow);
7367
+ volumeCommand2.addCommand(listCommand2);
7368
+ volumeCommand2.addCommand(getCommand);
7369
+ volumeCommand2.addCommand(createCommand);
7370
+ program.addCommand(volumeCommand2);
7371
+ var floatingipCommand = new import_commander46.Command("floatingip").description(
7372
+ "Floating IP(\uC778\uC2A4\uD134\uC2A4 \uACF5\uC778 IP) \uAD00\uB9AC"
7373
+ ).addHelpText("after", floatingIpAgentWorkflow);
5638
7374
  floatingipCommand.addCommand(listCommand4);
5639
7375
  floatingipCommand.addCommand(createCommand2);
5640
7376
  floatingipCommand.addCommand(deleteCommand);
5641
7377
  program.addCommand(floatingipCommand);
5642
- var ncrCommand = new import_commander42.Command("ncr").description("NHN Container Registry \uAD00\uB828 \uBA85\uB839");
7378
+ var ncrCommand = new import_commander46.Command("ncr").description("NHN Container Registry \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncrAgentWorkflow);
5643
7379
  ncrCommand.addCommand(listCommand5);
5644
7380
  ncrCommand.addCommand(getCommand3);
5645
7381
  ncrCommand.addCommand(imagesCommand2);
5646
7382
  ncrCommand.addCommand(tagsCommand);
5647
7383
  program.addCommand(ncrCommand);
5648
- var nksCommand = new import_commander42.Command("nks").description("NHN Kubernetes Service \uAD00\uB828 \uBA85\uB839");
7384
+ var nksCommand = new import_commander46.Command("nks").description("NHN Kubernetes Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", nksAgentWorkflow);
5649
7385
  nksCommand.addCommand(supportsCommand);
5650
7386
  nksCommand.addCommand(clusterCommand);
5651
7387
  nksCommand.addCommand(nodegroupCommand);
5652
7388
  nksCommand.addCommand(addonTypeCommand);
5653
7389
  nksCommand.addCommand(addonCommand);
5654
7390
  program.addCommand(nksCommand);
7391
+ var ncsCommand = new import_commander46.Command("ncs").description("NHN Container Service \uAD00\uB828 \uBA85\uB839").addHelpText("after", ncsAgentWorkflow);
7392
+ ncsCommand.addCommand(templateCommand);
7393
+ ncsCommand.addCommand(workloadCommand);
7394
+ ncsCommand.addCommand(malwareCommand);
7395
+ program.addCommand(ncsCommand);
7396
+ program.addCommand(createCommandsCommand(program));
5655
7397
  program.parseAsync().catch((err) => {
5656
7398
  const message = err instanceof Error ? err.message : String(err);
5657
7399
  const exitCode = err instanceof NhnCloudCliError ? err.exitCode : 1;
5658
- process.stderr.write(import_chalk14.default.red(`\uC624\uB958: ${message}`) + "\n");
7400
+ process.stderr.write(import_chalk16.default.red(`\uC624\uB958: ${message}`) + "\n");
5659
7401
  process.exit(exitCode);
5660
7402
  });