ncloud-mcp-server 1.0.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/LICENSE +21 -0
- package/README.md +159 -0
- package/README_EN.md +159 -0
- package/dist/auth/signature.d.ts +16 -0
- package/dist/auth/signature.js +18 -0
- package/dist/auth/signature.js.map +1 -0
- package/dist/auth/signature.test.d.ts +1 -0
- package/dist/auth/signature.test.js +90 -0
- package/dist/auth/signature.test.js.map +1 -0
- package/dist/client/ncloud-client.d.ts +27 -0
- package/dist/client/ncloud-client.js +270 -0
- package/dist/client/ncloud-client.js.map +1 -0
- package/dist/client/ncloud-client.test.d.ts +1 -0
- package/dist/client/ncloud-client.test.js +477 -0
- package/dist/client/ncloud-client.test.js.map +1 -0
- package/dist/client/s3-compatible-client.d.ts +49 -0
- package/dist/client/s3-compatible-client.js +210 -0
- package/dist/client/s3-compatible-client.js.map +1 -0
- package/dist/client/swift-compatible-client.d.ts +68 -0
- package/dist/client/swift-compatible-client.js +173 -0
- package/dist/client/swift-compatible-client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +362 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/acg.d.ts +3 -0
- package/dist/tools/acg.js +220 -0
- package/dist/tools/acg.js.map +1 -0
- package/dist/tools/activity-tracer.d.ts +3 -0
- package/dist/tools/activity-tracer.js +77 -0
- package/dist/tools/activity-tracer.js.map +1 -0
- package/dist/tools/analytics-cdss.d.ts +3 -0
- package/dist/tools/analytics-cdss.js +618 -0
- package/dist/tools/analytics-cdss.js.map +1 -0
- package/dist/tools/analytics-datacatalog.d.ts +10 -0
- package/dist/tools/analytics-datacatalog.js +409 -0
- package/dist/tools/analytics-datacatalog.js.map +1 -0
- package/dist/tools/analytics-dataflow.d.ts +16 -0
- package/dist/tools/analytics-dataflow.js +478 -0
- package/dist/tools/analytics-dataflow.js.map +1 -0
- package/dist/tools/analytics-dataforest.d.ts +10 -0
- package/dist/tools/analytics-dataforest.js +379 -0
- package/dist/tools/analytics-dataforest.js.map +1 -0
- package/dist/tools/analytics-dataquery.d.ts +16 -0
- package/dist/tools/analytics-dataquery.js +143 -0
- package/dist/tools/analytics-dataquery.js.map +1 -0
- package/dist/tools/analytics-datastream.d.ts +13 -0
- package/dist/tools/analytics-datastream.js +359 -0
- package/dist/tools/analytics-datastream.js.map +1 -0
- package/dist/tools/analytics-hadoop.d.ts +12 -0
- package/dist/tools/analytics-hadoop.js +450 -0
- package/dist/tools/analytics-hadoop.js.map +1 -0
- package/dist/tools/analytics-ses.d.ts +3 -0
- package/dist/tools/analytics-ses.js +653 -0
- package/dist/tools/analytics-ses.js.map +1 -0
- package/dist/tools/api-gateway.d.ts +3 -0
- package/dist/tools/api-gateway.js +202 -0
- package/dist/tools/api-gateway.js.map +1 -0
- package/dist/tools/autoscaling.d.ts +3 -0
- package/dist/tools/autoscaling.js +430 -0
- package/dist/tools/autoscaling.js.map +1 -0
- package/dist/tools/billing.d.ts +14 -0
- package/dist/tools/billing.js +545 -0
- package/dist/tools/billing.js.map +1 -0
- package/dist/tools/certificate-manager.d.ts +18 -0
- package/dist/tools/certificate-manager.js +84 -0
- package/dist/tools/certificate-manager.js.map +1 -0
- package/dist/tools/cloud-advisor.d.ts +3 -0
- package/dist/tools/cloud-advisor.js +202 -0
- package/dist/tools/cloud-advisor.js.map +1 -0
- package/dist/tools/cloud-functions.d.ts +3 -0
- package/dist/tools/cloud-functions.js +497 -0
- package/dist/tools/cloud-functions.js.map +1 -0
- package/dist/tools/cloud-insight-integration.d.ts +3 -0
- package/dist/tools/cloud-insight-integration.js +90 -0
- package/dist/tools/cloud-insight-integration.js.map +1 -0
- package/dist/tools/cloud-insight-plugin.d.ts +3 -0
- package/dist/tools/cloud-insight-plugin.js +600 -0
- package/dist/tools/cloud-insight-plugin.js.map +1 -0
- package/dist/tools/cloud-insight-rule.d.ts +3 -0
- package/dist/tools/cloud-insight-rule.js +570 -0
- package/dist/tools/cloud-insight-rule.js.map +1 -0
- package/dist/tools/cloud-insight.d.ts +3 -0
- package/dist/tools/cloud-insight.js +246 -0
- package/dist/tools/cloud-insight.js.map +1 -0
- package/dist/tools/common.d.ts +3 -0
- package/dist/tools/common.js +120 -0
- package/dist/tools/common.js.map +1 -0
- package/dist/tools/compute-initscript.d.ts +3 -0
- package/dist/tools/compute-initscript.js +62 -0
- package/dist/tools/compute-initscript.js.map +1 -0
- package/dist/tools/compute-loginkey.d.ts +3 -0
- package/dist/tools/compute-loginkey.js +59 -0
- package/dist/tools/compute-loginkey.js.map +1 -0
- package/dist/tools/compute-placement.d.ts +3 -0
- package/dist/tools/compute-placement.js +196 -0
- package/dist/tools/compute-placement.js.map +1 -0
- package/dist/tools/compute-publicip.d.ts +3 -0
- package/dist/tools/compute-publicip.js +97 -0
- package/dist/tools/compute-publicip.js.map +1 -0
- package/dist/tools/compute-server.d.ts +3 -0
- package/dist/tools/compute-server.js +445 -0
- package/dist/tools/compute-server.js.map +1 -0
- package/dist/tools/compute-server.test.d.ts +1 -0
- package/dist/tools/compute-server.test.js +224 -0
- package/dist/tools/compute-server.test.js.map +1 -0
- package/dist/tools/compute-storage.d.ts +3 -0
- package/dist/tools/compute-storage.js +240 -0
- package/dist/tools/compute-storage.js.map +1 -0
- package/dist/tools/containers-nks.d.ts +13 -0
- package/dist/tools/containers-nks.js +576 -0
- package/dist/tools/containers-nks.js.map +1 -0
- package/dist/tools/containers-registry.d.ts +3 -0
- package/dist/tools/containers-registry.js +181 -0
- package/dist/tools/containers-registry.js.map +1 -0
- package/dist/tools/database-cache.d.ts +3 -0
- package/dist/tools/database-cache.js +388 -0
- package/dist/tools/database-cache.js.map +1 -0
- package/dist/tools/database-mongodb.d.ts +3 -0
- package/dist/tools/database-mongodb.js +460 -0
- package/dist/tools/database-mongodb.js.map +1 -0
- package/dist/tools/database-mssql.d.ts +3 -0
- package/dist/tools/database-mssql.js +345 -0
- package/dist/tools/database-mssql.js.map +1 -0
- package/dist/tools/database-mysql.d.ts +3 -0
- package/dist/tools/database-mysql.js +500 -0
- package/dist/tools/database-mysql.js.map +1 -0
- package/dist/tools/database-postgresql.d.ts +3 -0
- package/dist/tools/database-postgresql.js +432 -0
- package/dist/tools/database-postgresql.js.map +1 -0
- package/dist/tools/global-dns.d.ts +3 -0
- package/dist/tools/global-dns.js +207 -0
- package/dist/tools/global-dns.js.map +1 -0
- package/dist/tools/global-edge.d.ts +3 -0
- package/dist/tools/global-edge.js +386 -0
- package/dist/tools/global-edge.js.map +1 -0
- package/dist/tools/global-traffic-manager.d.ts +3 -0
- package/dist/tools/global-traffic-manager.js +497 -0
- package/dist/tools/global-traffic-manager.js.map +1 -0
- package/dist/tools/index.d.ts +63 -0
- package/dist/tools/index.js +64 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/kms.d.ts +8 -0
- package/dist/tools/kms.js +529 -0
- package/dist/tools/kms.js.map +1 -0
- package/dist/tools/loadbalancer.d.ts +3 -0
- package/dist/tools/loadbalancer.js +341 -0
- package/dist/tools/loadbalancer.js.map +1 -0
- package/dist/tools/log-analytics.d.ts +3 -0
- package/dist/tools/log-analytics.js +183 -0
- package/dist/tools/log-analytics.js.map +1 -0
- package/dist/tools/media-imageoptimizer.d.ts +3 -0
- package/dist/tools/media-imageoptimizer.js +187 -0
- package/dist/tools/media-imageoptimizer.js.map +1 -0
- package/dist/tools/media-livestation.d.ts +3 -0
- package/dist/tools/media-livestation.js +252 -0
- package/dist/tools/media-livestation.js.map +1 -0
- package/dist/tools/media-vodstation.d.ts +3 -0
- package/dist/tools/media-vodstation.js +197 -0
- package/dist/tools/media-vodstation.js.map +1 -0
- package/dist/tools/nat-gateway.d.ts +3 -0
- package/dist/tools/nat-gateway.js +91 -0
- package/dist/tools/nat-gateway.js.map +1 -0
- package/dist/tools/network-acl.d.ts +3 -0
- package/dist/tools/network-acl.js +322 -0
- package/dist/tools/network-acl.js.map +1 -0
- package/dist/tools/network-interface.d.ts +3 -0
- package/dist/tools/network-interface.js +193 -0
- package/dist/tools/network-interface.js.map +1 -0
- package/dist/tools/private-ca.d.ts +8 -0
- package/dist/tools/private-ca.js +368 -0
- package/dist/tools/private-ca.js.map +1 -0
- package/dist/tools/resource-manager.d.ts +3 -0
- package/dist/tools/resource-manager.js +151 -0
- package/dist/tools/resource-manager.js.map +1 -0
- package/dist/tools/route-table.d.ts +3 -0
- package/dist/tools/route-table.js +205 -0
- package/dist/tools/route-table.js.map +1 -0
- package/dist/tools/security-monitoring.d.ts +3 -0
- package/dist/tools/security-monitoring.js +182 -0
- package/dist/tools/security-monitoring.js.map +1 -0
- package/dist/tools/sens.d.ts +3 -0
- package/dist/tools/sens.js +240 -0
- package/dist/tools/sens.js.map +1 -0
- package/dist/tools/sourcebuild.d.ts +3 -0
- package/dist/tools/sourcebuild.js +481 -0
- package/dist/tools/sourcebuild.js.map +1 -0
- package/dist/tools/sourcecommit.d.ts +13 -0
- package/dist/tools/sourcecommit.js +228 -0
- package/dist/tools/sourcecommit.js.map +1 -0
- package/dist/tools/sourcedeploy.d.ts +3 -0
- package/dist/tools/sourcedeploy.js +448 -0
- package/dist/tools/sourcedeploy.js.map +1 -0
- package/dist/tools/sourcepipeline.d.ts +12 -0
- package/dist/tools/sourcepipeline.js +357 -0
- package/dist/tools/sourcepipeline.js.map +1 -0
- package/dist/tools/storage-archive.d.ts +3 -0
- package/dist/tools/storage-archive.js +337 -0
- package/dist/tools/storage-archive.js.map +1 -0
- package/dist/tools/storage-nas.d.ts +3 -0
- package/dist/tools/storage-nas.js +288 -0
- package/dist/tools/storage-nas.js.map +1 -0
- package/dist/tools/storage-ncloud.d.ts +3 -0
- package/dist/tools/storage-ncloud.js +864 -0
- package/dist/tools/storage-ncloud.js.map +1 -0
- package/dist/tools/storage-object.d.ts +3 -0
- package/dist/tools/storage-object.js +982 -0
- package/dist/tools/storage-object.js.map +1 -0
- package/dist/tools/sub-account.d.ts +3 -0
- package/dist/tools/sub-account.js +311 -0
- package/dist/tools/sub-account.js.map +1 -0
- package/dist/tools/target-group.d.ts +3 -0
- package/dist/tools/target-group.js +207 -0
- package/dist/tools/target-group.js.map +1 -0
- package/dist/tools/vpc-peering.d.ts +3 -0
- package/dist/tools/vpc-peering.js +109 -0
- package/dist/tools/vpc-peering.js.map +1 -0
- package/dist/tools/vpc.d.ts +3 -0
- package/dist/tools/vpc.js +194 -0
- package/dist/tools/vpc.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* NKS (Ncloud Kubernetes Service) API Tools
|
|
4
|
+
*
|
|
5
|
+
* Base URL: https://nks.apigw.ntruss.com
|
|
6
|
+
* API Style: RESTful (GET/POST/PATCH/PUT/DELETE with JSON body)
|
|
7
|
+
* Auth: x-ncp-apigw-timestamp, x-ncp-iam-access-key, x-ncp-apigw-signature-v2, Content-Type: application/json
|
|
8
|
+
*
|
|
9
|
+
* NOTE: NKS API does NOT use responseFormatType=json (always returns JSON).
|
|
10
|
+
* All requests use client.requestRaw() instead of client.request().
|
|
11
|
+
*/
|
|
12
|
+
export function registerContainersNksTools(server, client) {
|
|
13
|
+
// ─── Cluster Query Tools ───────────────────────────────────────────────────
|
|
14
|
+
server.tool("ncloud_nks_list_clusters", "List all NKS (Ncloud Kubernetes Service) clusters in the current region", {}, async () => {
|
|
15
|
+
try {
|
|
16
|
+
const result = await client.requestRaw("GET", "/vnks/v2/clusters");
|
|
17
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
server.tool("ncloud_nks_get_cluster", "Get detailed information about a specific NKS cluster", {
|
|
24
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster to query"),
|
|
25
|
+
}, async (params) => {
|
|
26
|
+
try {
|
|
27
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}`);
|
|
28
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
// ─── Cluster Create Tool ───────────────────────────────────────────────────
|
|
35
|
+
server.tool("ncloud_nks_create_cluster", "Create a new NKS Kubernetes cluster. Use dryRun=true to preview without creating. Requires loginKeyName, regionCode, vpcNo, subnetNoList, lbPublicSubnetNo.", {
|
|
36
|
+
name: z.string({ required_error: "필수 파라미터 'name'이 누락되었습니다." }).describe("Cluster name (3-30 chars, lowercase+numbers+'-')"),
|
|
37
|
+
clusterType: z.string({ required_error: "필수 파라미터 'clusterType'이 누락되었습니다." }).describe("Cluster type (e.g., SVR.VNKS.STAND.C004.M016.G003)"),
|
|
38
|
+
loginKeyName: z.string({ required_error: "필수 파라미터 'loginKeyName'이 누락되었습니다." }).describe("Login key name for node access"),
|
|
39
|
+
regionCode: z.string({ required_error: "필수 파라미터 'regionCode'가 누락되었습니다." }).describe("Region code (e.g., KR, SGN, JPN)"),
|
|
40
|
+
vpcNo: z.number({ required_error: "필수 파라미터 'vpcNo'가 누락되었습니다." }).describe("VPC number"),
|
|
41
|
+
subnetNoList: z.array(z.number(), { required_error: "필수 파라미터 'subnetNoList'가 누락되었습니다." }).describe("Subnet number list for the cluster"),
|
|
42
|
+
lbPublicSubnetNo: z.number({ required_error: "필수 파라미터 'lbPublicSubnetNo'가 누락되었습니다." }).describe("Load balancer public subnet number"),
|
|
43
|
+
k8sVersion: z.string().optional().describe("Kubernetes version (from ncloud_nks_get_versions)"),
|
|
44
|
+
hypervisorCode: z.string().optional().describe("Hypervisor code: XEN (default) or KVM"),
|
|
45
|
+
zoneCode: z.string().optional().describe("Zone code (e.g., KR-1). Not needed if isRegional=true"),
|
|
46
|
+
lbPrivateSubnetNo: z.number().optional().describe("Load balancer private subnet number"),
|
|
47
|
+
isRegional: z.boolean().optional().describe("Multi-zone (Regional) cluster. Default: false"),
|
|
48
|
+
publicNetwork: z.boolean().optional().describe("Subnet network type. true=Public, false=Private (default)"),
|
|
49
|
+
log: z.object({ audit: z.boolean().optional() }).optional().describe("Log settings (audit log)"),
|
|
50
|
+
nodePool: z.array(z.object({
|
|
51
|
+
name: z.string().optional().describe("Node pool name"),
|
|
52
|
+
nodeCount: z.number().optional().describe("Number of nodes"),
|
|
53
|
+
softwareCode: z.string().optional().describe("Server image code (from ncloud_nks_get_server_images)"),
|
|
54
|
+
productCode: z.string().optional().describe("Product code (XEN only)"),
|
|
55
|
+
serverSpecCode: z.string().optional().describe("Server spec code (KVM only, from ncloud_nks_get_server_specs)"),
|
|
56
|
+
storageSize: z.number().optional().describe("Storage size in GB (KVM only, 100-2000)"),
|
|
57
|
+
labels: z.array(z.object({ key: z.string(), value: z.string() })).optional().describe("Node labels"),
|
|
58
|
+
taints: z.array(z.object({ key: z.string(), value: z.string().optional(), effect: z.string() })).optional().describe("Node taints"),
|
|
59
|
+
serverRoleId: z.string().optional().describe("IAM server role ID"),
|
|
60
|
+
zoneCode: z.string().optional().describe("Zone code (required for Regional clusters)"),
|
|
61
|
+
})).optional().describe("Initial node pool configurations"),
|
|
62
|
+
dryRun: z.boolean().optional().default(false).describe("If true, returns a preview without actually creating"),
|
|
63
|
+
}, async (params) => {
|
|
64
|
+
try {
|
|
65
|
+
if (params.dryRun) {
|
|
66
|
+
const preview = {
|
|
67
|
+
label: "🔍 Dry-Run Preview: NKS Cluster Creation",
|
|
68
|
+
...params,
|
|
69
|
+
dryRun: undefined,
|
|
70
|
+
message: "이 요청은 실제 클러스터를 생성하지 않습니다. dryRun=false로 호출하면 클러스터가 생성됩니다.",
|
|
71
|
+
};
|
|
72
|
+
return { content: [{ type: "text", text: JSON.stringify(preview, null, 2) }] };
|
|
73
|
+
}
|
|
74
|
+
const { dryRun, ...body } = params;
|
|
75
|
+
const result = await client.requestRaw("POST", "/vnks/v2/clusters", undefined, body);
|
|
76
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// ─── Cluster Delete Tool ───────────────────────────────────────────────────
|
|
83
|
+
// ⚠️ Destructive: DELETE method, confirm=true required, description has warning
|
|
84
|
+
server.tool("ncloud_nks_delete_cluster", "⚠️ Destructive: Permanently delete an NKS Kubernetes cluster. Set confirm=true to execute.", {
|
|
85
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster to delete"),
|
|
86
|
+
confirm: z.boolean().optional().default(false).describe("Must be true to actually execute the destructive operation"),
|
|
87
|
+
}, async (params) => {
|
|
88
|
+
try {
|
|
89
|
+
if (!params.confirm) {
|
|
90
|
+
const message = `⚠️ This will permanently delete NKS Cluster [${params.clusterUuid}]. All node pools and workloads will be destroyed.\n\nTo execute, call this tool again with confirm=true.`;
|
|
91
|
+
return { content: [{ type: "text", text: message }] };
|
|
92
|
+
}
|
|
93
|
+
const result = await client.requestRaw("DELETE", `/vnks/v2/clusters/${params.clusterUuid}`);
|
|
94
|
+
return { content: [{ type: "text", text: JSON.stringify(result ?? { success: true }, null, 2) }] };
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// ─── Cluster Upgrade Tool ──────────────────────────────────────────────────
|
|
101
|
+
server.tool("ncloud_nks_upgrade_cluster", "Upgrade the Kubernetes version of an NKS cluster. Uses PATCH with query parameters.", {
|
|
102
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster to upgrade"),
|
|
103
|
+
k8sVersion: z.string({ required_error: "필수 파라미터 'k8sVersion'이 누락되었습니다." }).describe("Target Kubernetes version (e.g., 1.27.9-nks.1)"),
|
|
104
|
+
maxSurge: z.number().optional().describe("Max nodes that can be added during upgrade (default: 1)"),
|
|
105
|
+
maxUnavailable: z.number().optional().describe("Max nodes that can be unavailable during upgrade (default: 0)"),
|
|
106
|
+
}, async (params) => {
|
|
107
|
+
try {
|
|
108
|
+
const queryParams = { k8sVersion: params.k8sVersion };
|
|
109
|
+
if (params.maxSurge !== undefined)
|
|
110
|
+
queryParams.maxSurge = String(params.maxSurge);
|
|
111
|
+
if (params.maxUnavailable !== undefined)
|
|
112
|
+
queryParams.maxUnavailable = String(params.maxUnavailable);
|
|
113
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/upgrade`, queryParams);
|
|
114
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// ─── Cluster Configuration Tools ──────────────────────────────────────────
|
|
121
|
+
server.tool("ncloud_nks_set_audit_log", "Configure audit log collection via Cloud Log Analytics for an NKS cluster", {
|
|
122
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
123
|
+
audit: z.boolean({ required_error: "필수 파라미터 'audit'가 누락되었습니다." }).describe("Whether to enable audit log collection (true/false)"),
|
|
124
|
+
}, async (params) => {
|
|
125
|
+
try {
|
|
126
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/log`, undefined, { audit: params.audit });
|
|
127
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
server.tool("ncloud_nks_add_subnet", "Add subnets to an NKS cluster", {
|
|
134
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
135
|
+
subnetNoList: z.array(z.number(), { required_error: "필수 파라미터 'subnetNoList'가 누락되었습니다." }).describe("List of subnet numbers to add"),
|
|
136
|
+
}, async (params) => {
|
|
137
|
+
try {
|
|
138
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/subnet`, undefined, { subnetNoList: params.subnetNoList });
|
|
139
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
server.tool("ncloud_nks_set_oidc", "Configure OIDC (OpenID Connect) authentication for an NKS cluster", {
|
|
146
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
147
|
+
status: z.boolean({ required_error: "필수 파라미터 'status'가 누락되었습니다." }).describe("OIDC activation status (true=enable, false=disable)"),
|
|
148
|
+
clientId: z.string({ required_error: "필수 파라미터 'clientId'가 누락되었습니다." }).describe("OIDC provider Client ID"),
|
|
149
|
+
issuerURL: z.string({ required_error: "필수 파라미터 'issuerURL'이 누락되었습니다." }).describe("OIDC provider URL"),
|
|
150
|
+
usernameClaim: z.string().optional().describe("JWT claim for username"),
|
|
151
|
+
usernamePrefix: z.string().optional().describe("Prefix for username claim"),
|
|
152
|
+
groupsClaim: z.string().optional().describe("JWT claim for groups"),
|
|
153
|
+
groupsPrefix: z.string().optional().describe("Prefix for groups claim"),
|
|
154
|
+
requiredClaim: z.string().optional().describe("Required claim as key=value pair"),
|
|
155
|
+
}, async (params) => {
|
|
156
|
+
try {
|
|
157
|
+
const { clusterUuid, ...body } = params;
|
|
158
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${clusterUuid}/oidc`, undefined, body);
|
|
159
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
server.tool("ncloud_nks_get_oidc", "Get OIDC (OpenID Connect) provider configuration for an NKS cluster", {
|
|
166
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
167
|
+
}, async (params) => {
|
|
168
|
+
try {
|
|
169
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}/oidc`);
|
|
170
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
server.tool("ncloud_nks_get_ip_acl", "Get IP ACL configuration for an NKS cluster", {
|
|
177
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
178
|
+
}, async (params) => {
|
|
179
|
+
try {
|
|
180
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}/ip-acl`);
|
|
181
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
server.tool("ncloud_nks_set_ip_acl", "Configure IP ACL for an NKS cluster to restrict API server access", {
|
|
188
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
189
|
+
entries: z.array(z.object({
|
|
190
|
+
action: z.string().describe("ACL action (allow or deny)"),
|
|
191
|
+
address: z.string().describe("IP address or CIDR block"),
|
|
192
|
+
}), { required_error: "필수 파라미터 'entries'가 누락되었습니다." }).describe("IP ACL entries"),
|
|
193
|
+
}, async (params) => {
|
|
194
|
+
try {
|
|
195
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/ip-acl`, undefined, { entries: params.entries });
|
|
196
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
server.tool("ncloud_nks_set_return_protection", "Configure return (deletion) protection for an NKS cluster", {
|
|
203
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
204
|
+
returnProtection: z.boolean({ required_error: "필수 파라미터 'returnProtection'이 누락되었습니다." }).describe("Enable/disable deletion protection"),
|
|
205
|
+
}, async (params) => {
|
|
206
|
+
try {
|
|
207
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/return-protection`, undefined, { returnProtection: params.returnProtection });
|
|
208
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
server.tool("ncloud_nks_update_lb_subnet", "Update load balancer subnet for an NKS cluster", {
|
|
215
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
216
|
+
lbPrivateSubnetNo: z.number().optional().describe("New LB private subnet number"),
|
|
217
|
+
lbPublicSubnetNo: z.number().optional().describe("New LB public subnet number"),
|
|
218
|
+
}, async (params) => {
|
|
219
|
+
try {
|
|
220
|
+
const { clusterUuid, ...body } = params;
|
|
221
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${clusterUuid}/lb-subnet`, undefined, body);
|
|
222
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
server.tool("ncloud_nks_update_secret_encryption", "Configure secret encryption for an NKS cluster", {
|
|
229
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
230
|
+
kmsKeyTag: z.string().optional().describe("KMS key tag for secret encryption"),
|
|
231
|
+
}, async (params) => {
|
|
232
|
+
try {
|
|
233
|
+
const { clusterUuid, ...body } = params;
|
|
234
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${clusterUuid}/secret-encryption`, undefined, body);
|
|
235
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
server.tool("ncloud_nks_update_auth_type", "Update authentication mode for an NKS cluster", {
|
|
242
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
243
|
+
authType: z.string({ required_error: "필수 파라미터 'authType'가 누락되었습니다." }).describe("Auth type: API or CONFIG_MAP"),
|
|
244
|
+
}, async (params) => {
|
|
245
|
+
try {
|
|
246
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/auth-type`, undefined, { authType: params.authType });
|
|
247
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
// ─── Kubeconfig Tools ──────────────────────────────────────────────────────
|
|
254
|
+
server.tool("ncloud_nks_get_kubeconfig", "Retrieve the kubeconfig for a specified NKS cluster", {
|
|
255
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
256
|
+
}, async (params) => {
|
|
257
|
+
try {
|
|
258
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}/kubeconfig`);
|
|
259
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
server.tool("ncloud_nks_reset_kubeconfig", "Reset the kubeconfig credentials for a specified NKS cluster", {
|
|
266
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
267
|
+
}, async (params) => {
|
|
268
|
+
try {
|
|
269
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/kubeconfig`);
|
|
270
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
// ─── Worker Node Tools ─────────────────────────────────────────────────────
|
|
277
|
+
server.tool("ncloud_nks_list_worker_nodes", "List worker nodes in an NKS cluster", {
|
|
278
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
279
|
+
}, async (params) => {
|
|
280
|
+
try {
|
|
281
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}/nodes`);
|
|
282
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
// ⚠️ Destructive: DELETE worker node, confirm=true required
|
|
289
|
+
server.tool("ncloud_nks_delete_worker_node", "⚠️ Destructive: Delete a specific worker node from an NKS cluster. Set confirm=true to execute.", {
|
|
290
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
291
|
+
instanceNo: z.number({ required_error: "필수 파라미터 'instanceNo'가 누락되었습니다." }).describe("Instance number of the worker node to delete"),
|
|
292
|
+
confirm: z.boolean().optional().default(false).describe("Must be true to execute"),
|
|
293
|
+
}, async (params) => {
|
|
294
|
+
try {
|
|
295
|
+
if (!params.confirm) {
|
|
296
|
+
return { content: [{ type: "text", text: `⚠️ This will permanently delete Worker Node [${params.instanceNo}] from Cluster [${params.clusterUuid}].\n\nTo execute, call this tool again with confirm=true.` }] };
|
|
297
|
+
}
|
|
298
|
+
const result = await client.requestRaw("DELETE", `/vnks/v2/clusters/${params.clusterUuid}/nodes/${params.instanceNo}`);
|
|
299
|
+
return { content: [{ type: "text", text: JSON.stringify(result ?? { success: true }, null, 2) }] };
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
// ─── Node Pool Tools ───────────────────────────────────────────────────────
|
|
306
|
+
server.tool("ncloud_nks_list_node_pools", "List all node pools in a specified NKS cluster", {
|
|
307
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
308
|
+
}, async (params) => {
|
|
309
|
+
try {
|
|
310
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}/node-pool`);
|
|
311
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
server.tool("ncloud_nks_create_node_pool", "Create a new node pool in an NKS cluster. Use dryRun=true to preview.", {
|
|
318
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
319
|
+
name: z.string({ required_error: "필수 파라미터 'name'이 누락되었습니다." }).describe("Node pool name"),
|
|
320
|
+
nodeCount: z.number().optional().describe("Number of nodes (required if autoscale not set)"),
|
|
321
|
+
softwareCode: z.string().optional().describe("Server image code"),
|
|
322
|
+
serverSpecCode: z.string().optional().describe("Server spec code (KVM)"),
|
|
323
|
+
storageSize: z.number().optional().describe("Storage size in GB (KVM, 100-2000)"),
|
|
324
|
+
autoscale: z.object({
|
|
325
|
+
enabled: z.boolean().optional(),
|
|
326
|
+
min: z.number().optional(),
|
|
327
|
+
max: z.number().optional(),
|
|
328
|
+
}).optional().describe("Autoscale configuration"),
|
|
329
|
+
labels: z.array(z.object({ key: z.string(), value: z.string() })).optional().describe("Node labels"),
|
|
330
|
+
taints: z.array(z.object({ key: z.string(), value: z.string().optional(), effect: z.string() })).optional().describe("Node taints"),
|
|
331
|
+
serverRoleId: z.string().optional().describe("IAM server role ID"),
|
|
332
|
+
zoneCode: z.string().optional().describe("Zone code (required for Regional clusters)"),
|
|
333
|
+
dryRun: z.boolean().optional().default(false).describe("If true, preview only"),
|
|
334
|
+
}, async (params) => {
|
|
335
|
+
try {
|
|
336
|
+
if (params.dryRun) {
|
|
337
|
+
const preview = { label: "🔍 Dry-Run Preview: Node Pool Creation", ...params, dryRun: undefined, message: "dryRun=false로 호출하면 노드풀이 생성됩니다." };
|
|
338
|
+
return { content: [{ type: "text", text: JSON.stringify(preview, null, 2) }] };
|
|
339
|
+
}
|
|
340
|
+
const { clusterUuid, dryRun, ...body } = params;
|
|
341
|
+
const result = await client.requestRaw("POST", `/vnks/v2/clusters/${clusterUuid}/node-pool`, undefined, body);
|
|
342
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
server.tool("ncloud_nks_update_node_pool", "Update node pool settings (node count or autoscale) in an NKS cluster", {
|
|
349
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
350
|
+
instanceNo: z.number({ required_error: "필수 파라미터 'instanceNo'가 누락되었습니다." }).describe("Node pool instance number"),
|
|
351
|
+
nodeCount: z.number().optional().describe("Desired node count (required if autoscale disabled)"),
|
|
352
|
+
autoscale: z.object({
|
|
353
|
+
enabled: z.boolean().optional(),
|
|
354
|
+
min: z.number().optional(),
|
|
355
|
+
max: z.number().optional(),
|
|
356
|
+
}).optional().describe("Autoscale configuration"),
|
|
357
|
+
}, async (params) => {
|
|
358
|
+
try {
|
|
359
|
+
const body = {};
|
|
360
|
+
if (params.nodeCount !== undefined)
|
|
361
|
+
body.nodeCount = params.nodeCount;
|
|
362
|
+
if (params.autoscale !== undefined)
|
|
363
|
+
body.autoscale = params.autoscale;
|
|
364
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/node-pool/${params.instanceNo}`, undefined, body);
|
|
365
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
// ⚠️ Destructive: DELETE node pool, confirm=true required
|
|
372
|
+
server.tool("ncloud_nks_delete_node_pool", "⚠️ Destructive: Permanently delete a node pool from an NKS cluster. Set confirm=true to execute.", {
|
|
373
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
374
|
+
instanceNo: z.number({ required_error: "필수 파라미터 'instanceNo'가 누락되었습니다." }).describe("Node pool instance number to delete"),
|
|
375
|
+
confirm: z.boolean().optional().default(false).describe("Must be true to execute"),
|
|
376
|
+
}, async (params) => {
|
|
377
|
+
try {
|
|
378
|
+
if (!params.confirm) {
|
|
379
|
+
return { content: [{ type: "text", text: `⚠️ This will permanently delete Node Pool [${params.instanceNo}] from Cluster [${params.clusterUuid}].\n\nTo execute, call this tool again with confirm=true.` }] };
|
|
380
|
+
}
|
|
381
|
+
const result = await client.requestRaw("DELETE", `/vnks/v2/clusters/${params.clusterUuid}/node-pool/${params.instanceNo}`);
|
|
382
|
+
return { content: [{ type: "text", text: JSON.stringify(result ?? { success: true }, null, 2) }] };
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
// ─── Node Pool Label / Taint / Upgrade / Subnet ────────────────────────────
|
|
389
|
+
server.tool("ncloud_nks_update_node_pool_label", "Update labels on a node pool in an NKS cluster (PUT replaces all labels)", {
|
|
390
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
391
|
+
instanceNo: z.number({ required_error: "필수 파라미터 'instanceNo'가 누락되었습니다." }).describe("Node pool instance number"),
|
|
392
|
+
labels: z.array(z.object({
|
|
393
|
+
key: z.string({ required_error: "필수 파라미터 'labels[].key'가 누락되었습니다." }),
|
|
394
|
+
value: z.string({ required_error: "필수 파라미터 'labels[].value'가 누락되었습니다." }),
|
|
395
|
+
}), { required_error: "필수 파라미터 'labels'가 누락되었습니다." }).describe("Label key/value pairs"),
|
|
396
|
+
}, async (params) => {
|
|
397
|
+
try {
|
|
398
|
+
const result = await client.requestRaw("PUT", `/vnks/v2/clusters/${params.clusterUuid}/node-pool/${params.instanceNo}/labels`, undefined, { labels: params.labels });
|
|
399
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
server.tool("ncloud_nks_update_node_pool_taint", "Update taints on a node pool in an NKS cluster (PUT replaces all taints)", {
|
|
406
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
407
|
+
instanceNo: z.number({ required_error: "필수 파라미터 'instanceNo'가 누락되었습니다." }).describe("Node pool instance number"),
|
|
408
|
+
taints: z.array(z.object({
|
|
409
|
+
key: z.string({ required_error: "필수 파라미터 'taints[].key'가 누락되었습니다." }),
|
|
410
|
+
value: z.string().optional().describe("Taint value"),
|
|
411
|
+
effect: z.string({ required_error: "필수 파라미터 'taints[].effect'가 누락되었습니다." }).describe("NoSchedule | PreferNoSchedule | NoExecute"),
|
|
412
|
+
}), { required_error: "필수 파라미터 'taints'가 누락되었습니다." }).describe("Taint key/value/effect objects"),
|
|
413
|
+
}, async (params) => {
|
|
414
|
+
try {
|
|
415
|
+
const result = await client.requestRaw("PUT", `/vnks/v2/clusters/${params.clusterUuid}/node-pool/${params.instanceNo}/taints`, undefined, { taints: params.taints });
|
|
416
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
server.tool("ncloud_nks_upgrade_node_pool", "Upgrade the Kubernetes version of a node pool. Uses PATCH with query parameters.", {
|
|
423
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
424
|
+
instanceNo: z.number({ required_error: "필수 파라미터 'instanceNo'가 누락되었습니다." }).describe("Node pool instance number"),
|
|
425
|
+
k8sVersion: z.string({ required_error: "필수 파라미터 'k8sVersion'이 누락되었습니다." }).describe("Target Kubernetes version"),
|
|
426
|
+
maxSurge: z.number().optional().describe("Max nodes added during upgrade (default: 1)"),
|
|
427
|
+
maxUnavailable: z.number().optional().describe("Max unavailable nodes during upgrade (default: 0)"),
|
|
428
|
+
}, async (params) => {
|
|
429
|
+
try {
|
|
430
|
+
const queryParams = { k8sVersion: params.k8sVersion };
|
|
431
|
+
if (params.maxSurge !== undefined)
|
|
432
|
+
queryParams.maxSurge = String(params.maxSurge);
|
|
433
|
+
if (params.maxUnavailable !== undefined)
|
|
434
|
+
queryParams.maxUnavailable = String(params.maxUnavailable);
|
|
435
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/node-pool/${params.instanceNo}/upgrade`, queryParams);
|
|
436
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
server.tool("ncloud_nks_update_node_pool_subnet", "Update subnet for a node pool in an NKS cluster", {
|
|
443
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
444
|
+
instanceNo: z.number({ required_error: "필수 파라미터 'instanceNo'가 누락되었습니다." }).describe("Node pool instance number"),
|
|
445
|
+
subnetNoList: z.array(z.number(), { required_error: "필수 파라미터 'subnetNoList'가 누락되었습니다." }).describe("New subnet number list"),
|
|
446
|
+
}, async (params) => {
|
|
447
|
+
try {
|
|
448
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${params.clusterUuid}/node-pool/${params.instanceNo}/subnet`, undefined, { subnetNoList: params.subnetNoList });
|
|
449
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
// ─── IAM Access Entry Tools ────────────────────────────────────────────────
|
|
456
|
+
server.tool("ncloud_nks_list_access_entries", "List IAM access entries for an NKS cluster", {
|
|
457
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
458
|
+
}, async (params) => {
|
|
459
|
+
try {
|
|
460
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}/access-entry`);
|
|
461
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
server.tool("ncloud_nks_get_access_entry", "Get a specific IAM access entry for an NKS cluster", {
|
|
468
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
469
|
+
accessEntryNo: z.number({ required_error: "필수 파라미터 'accessEntryNo'가 누락되었습니다." }).describe("Access entry number"),
|
|
470
|
+
}, async (params) => {
|
|
471
|
+
try {
|
|
472
|
+
const result = await client.requestRaw("GET", `/vnks/v2/clusters/${params.clusterUuid}/access-entry/${params.accessEntryNo}`);
|
|
473
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
server.tool("ncloud_nks_create_access_entry", "Create an IAM access entry for an NKS cluster", {
|
|
480
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
481
|
+
principalArn: z.string().optional().describe("IAM principal ARN"),
|
|
482
|
+
kubernetesGroups: z.array(z.string()).optional().describe("Kubernetes groups"),
|
|
483
|
+
type: z.string().optional().describe("Access entry type"),
|
|
484
|
+
}, async (params) => {
|
|
485
|
+
try {
|
|
486
|
+
const { clusterUuid, ...body } = params;
|
|
487
|
+
const result = await client.requestRaw("POST", `/vnks/v2/clusters/${clusterUuid}/access-entry`, undefined, body);
|
|
488
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
489
|
+
}
|
|
490
|
+
catch (error) {
|
|
491
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
server.tool("ncloud_nks_update_access_entry", "Update an IAM access entry for an NKS cluster", {
|
|
495
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
496
|
+
accessEntryNo: z.number({ required_error: "필수 파라미터 'accessEntryNo'가 누락되었습니다." }).describe("Access entry number"),
|
|
497
|
+
kubernetesGroups: z.array(z.string()).optional().describe("Kubernetes groups"),
|
|
498
|
+
}, async (params) => {
|
|
499
|
+
try {
|
|
500
|
+
const { clusterUuid, accessEntryNo, ...body } = params;
|
|
501
|
+
const result = await client.requestRaw("PATCH", `/vnks/v2/clusters/${clusterUuid}/access-entry/${accessEntryNo}`, undefined, body);
|
|
502
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
503
|
+
}
|
|
504
|
+
catch (error) {
|
|
505
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
// ⚠️ Destructive: DELETE access entry, confirm=true required
|
|
509
|
+
server.tool("ncloud_nks_delete_access_entry", "⚠️ Destructive: Delete an IAM access entry from an NKS cluster. Set confirm=true to execute.", {
|
|
510
|
+
clusterUuid: z.string({ required_error: "필수 파라미터 'clusterUuid'가 누락되었습니다." }).describe("UUID of the cluster"),
|
|
511
|
+
accessEntryNo: z.number({ required_error: "필수 파라미터 'accessEntryNo'가 누락되었습니다." }).describe("Access entry number to delete"),
|
|
512
|
+
confirm: z.boolean().optional().default(false).describe("Must be true to execute"),
|
|
513
|
+
}, async (params) => {
|
|
514
|
+
try {
|
|
515
|
+
if (!params.confirm) {
|
|
516
|
+
return { content: [{ type: "text", text: `⚠️ This will delete IAM Access Entry [${params.accessEntryNo}] from Cluster [${params.clusterUuid}].\n\nTo execute, call this tool again with confirm=true.` }] };
|
|
517
|
+
}
|
|
518
|
+
const result = await client.requestRaw("DELETE", `/vnks/v2/clusters/${params.clusterUuid}/access-entry/${params.accessEntryNo}`);
|
|
519
|
+
return { content: [{ type: "text", text: JSON.stringify(result ?? { success: true }, null, 2) }] };
|
|
520
|
+
}
|
|
521
|
+
catch (error) {
|
|
522
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
// ─── Reference/Query Tools (Versions, Images, Specs) ───────────────────────
|
|
526
|
+
server.tool("ncloud_nks_get_versions", "List available Kubernetes versions for NKS cluster creation", {
|
|
527
|
+
hypervisorCode: z.string().optional().describe("Hypervisor code filter: XEN (default) or KVM"),
|
|
528
|
+
isRegionalSupport: z.boolean().optional().describe("Filter only Regional (multi-zone) cluster supported versions"),
|
|
529
|
+
}, async (params) => {
|
|
530
|
+
try {
|
|
531
|
+
const queryParams = {};
|
|
532
|
+
if (params.hypervisorCode)
|
|
533
|
+
queryParams.hypervisorCode = params.hypervisorCode;
|
|
534
|
+
if (params.isRegionalSupport !== undefined)
|
|
535
|
+
queryParams.isRegionalSupport = String(params.isRegionalSupport);
|
|
536
|
+
const result = await client.requestRaw("GET", "/vnks/v2/option/version", Object.keys(queryParams).length > 0 ? queryParams : undefined);
|
|
537
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
538
|
+
}
|
|
539
|
+
catch (error) {
|
|
540
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
server.tool("ncloud_nks_get_server_images", "List available server image types for NKS cluster/node pool creation", {
|
|
544
|
+
hypervisorCode: z.string().optional().describe("Hypervisor type code filter: XEN (default) or KVM"),
|
|
545
|
+
}, async (params) => {
|
|
546
|
+
try {
|
|
547
|
+
const queryParams = {};
|
|
548
|
+
if (params.hypervisorCode)
|
|
549
|
+
queryParams.hypervisorCode = params.hypervisorCode;
|
|
550
|
+
const result = await client.requestRaw("GET", "/vnks/v2/option/server-image", Object.keys(queryParams).length > 0 ? queryParams : undefined);
|
|
551
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
552
|
+
}
|
|
553
|
+
catch (error) {
|
|
554
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
server.tool("ncloud_nks_get_server_specs", "List available server specifications for NKS cluster/node pool creation. Requires softwareCode (from ncloud_nks_get_server_images) and zoneCode or zoneNo.", {
|
|
558
|
+
softwareCode: z.string({ required_error: "필수 파라미터 'softwareCode'가 누락되었습니다." }).describe("Server image code (value from ncloud_nks_get_server_images)"),
|
|
559
|
+
zoneCode: z.string().optional().describe("Zone code (e.g., KR-1). Required if zoneNo not provided."),
|
|
560
|
+
zoneNo: z.string().optional().describe("Zone number. Required if zoneCode not provided."),
|
|
561
|
+
}, async (params) => {
|
|
562
|
+
try {
|
|
563
|
+
const queryParams = { softwareCode: params.softwareCode };
|
|
564
|
+
if (params.zoneCode)
|
|
565
|
+
queryParams.zoneCode = params.zoneCode;
|
|
566
|
+
if (params.zoneNo)
|
|
567
|
+
queryParams.zoneNo = params.zoneNo;
|
|
568
|
+
const result = await client.requestRaw("GET", "/vnks/v2/option/server-product-code", queryParams);
|
|
569
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
570
|
+
}
|
|
571
|
+
catch (error) {
|
|
572
|
+
return { content: [{ type: "text", text: error.message }], isError: true };
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
//# sourceMappingURL=containers-nks.js.map
|