UNPKG

@gorizond/mcp-rancher-multi

Version:

MCP server for multiple Rancher Manager backends with Fleet GitOps support

77 lines (76 loc) 2.78 kB
import { resolveToken } from './utils.js'; // Minimal Rancher client (v3 + k8s proxy) export class RancherClient { baseUrl; token; insecure; caCertPemBase64; constructor(cfg) { this.baseUrl = cfg.baseUrl.replace(/\/$/, ""); this.token = resolveToken(cfg.token); this.insecure = !!cfg.insecureSkipTlsVerify; this.caCertPemBase64 = cfg.caCertPemBase64; } headers(extra) { const h = { "Authorization": `Bearer ${this.token}`, "Accept": "application/json", ...extra, }; return h; } async requestJSON(url, init) { const res = await fetch(url, { ...init, headers: this.headers(init?.headers), }); if (!res.ok) { const text = await res.text().catch(() => ""); throw new Error(`HTTP ${res.status} ${res.statusText}${url} ${text}`); } return (await res.json()); } async listClusters() { const url = `${this.baseUrl}/v3/clusters`; const res = await this.requestJSON(url); return res.data; } async listNodes(clusterId) { const p = clusterId ? `?clusterId=${encodeURIComponent(clusterId)}` : ""; const url = `${this.baseUrl}/v3/nodes${p}`; const res = await this.requestJSON(url); return res.data; } async listProjects(clusterId) { const url = `${this.baseUrl}/v3/projects?clusterId=${encodeURIComponent(clusterId)}`; const res = await this.requestJSON(url); return res.data; } async generateKubeconfig(clusterId) { const url = `${this.baseUrl}/v3/clusters/${encodeURIComponent(clusterId)}?action=generateKubeconfig`; const res = await this.requestJSON(url, { method: "POST", headers: { "content-type": "application/json" } }); return res.config; } async k8s(clusterId, k8sPath, init) { const pathClean = k8sPath.startsWith("/") ? k8sPath : `/${k8sPath}`; const url = `${this.baseUrl}/k8s/clusters/${encodeURIComponent(clusterId)}${pathClean}`; const res = await fetch(url, { ...init, headers: this.headers({ "Accept": "application/json", ...init?.headers }), }); if (!res.ok) { const text = await res.text().catch(() => ""); throw new Error(`K8s proxy HTTP ${res.status} ${res.statusText}${url} ${text}`); } const ct = res.headers.get("content-type") || ""; if (ct.includes("application/json")) return res.json(); return res.text(); } async listNamespaces(clusterId) { const out = await this.k8s(clusterId, "/api/v1/namespaces"); return out?.items ?? out; } }