@calltelemetry/ct-lab-mcp 0.1.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 +309 -0
- package/dist/bin/ct-lab-mcp.d.ts +60 -0
- package/dist/bin/ct-lab-mcp.d.ts.map +1 -0
- package/dist/bin/ct-lab-mcp.js +261 -0
- package/dist/bin/ct-lab-mcp.js.map +1 -0
- package/dist/bin/proxmox-mcp.d.ts +58 -0
- package/dist/bin/proxmox-mcp.d.ts.map +1 -0
- package/dist/bin/proxmox-mcp.js +248 -0
- package/dist/bin/proxmox-mcp.js.map +1 -0
- package/dist/src/appliance/commands.d.ts +33 -0
- package/dist/src/appliance/commands.d.ts.map +1 -0
- package/dist/src/appliance/commands.js +241 -0
- package/dist/src/appliance/commands.js.map +1 -0
- package/dist/src/appliance/executor.d.ts +34 -0
- package/dist/src/appliance/executor.d.ts.map +1 -0
- package/dist/src/appliance/executor.js +214 -0
- package/dist/src/appliance/executor.js.map +1 -0
- package/dist/src/appliance/index.d.ts +8 -0
- package/dist/src/appliance/index.d.ts.map +1 -0
- package/dist/src/appliance/index.js +8 -0
- package/dist/src/appliance/index.js.map +1 -0
- package/dist/src/appliance/mock.d.ts +66 -0
- package/dist/src/appliance/mock.d.ts.map +1 -0
- package/dist/src/appliance/mock.js +339 -0
- package/dist/src/appliance/mock.js.map +1 -0
- package/dist/src/appliance/types.d.ts +83 -0
- package/dist/src/appliance/types.d.ts.map +1 -0
- package/dist/src/appliance/types.js +58 -0
- package/dist/src/appliance/types.js.map +1 -0
- package/dist/src/credentials/doppler.d.ts +25 -0
- package/dist/src/credentials/doppler.d.ts.map +1 -0
- package/dist/src/credentials/doppler.js +68 -0
- package/dist/src/credentials/doppler.js.map +1 -0
- package/dist/src/credentials/index.d.ts +4 -0
- package/dist/src/credentials/index.d.ts.map +1 -0
- package/dist/src/credentials/index.js +4 -0
- package/dist/src/credentials/index.js.map +1 -0
- package/dist/src/credentials/resolver.d.ts +36 -0
- package/dist/src/credentials/resolver.d.ts.map +1 -0
- package/dist/src/credentials/resolver.js +427 -0
- package/dist/src/credentials/resolver.js.map +1 -0
- package/dist/src/credentials/types.d.ts +73 -0
- package/dist/src/credentials/types.d.ts.map +1 -0
- package/dist/src/credentials/types.js +5 -0
- package/dist/src/credentials/types.js.map +1 -0
- package/dist/src/guardrails/index.d.ts +3 -0
- package/dist/src/guardrails/index.d.ts.map +1 -0
- package/dist/src/guardrails/index.js +3 -0
- package/dist/src/guardrails/index.js.map +1 -0
- package/dist/src/guardrails/safety.d.ts +45 -0
- package/dist/src/guardrails/safety.d.ts.map +1 -0
- package/dist/src/guardrails/safety.js +217 -0
- package/dist/src/guardrails/safety.js.map +1 -0
- package/dist/src/guardrails/types.d.ts +36 -0
- package/dist/src/guardrails/types.d.ts.map +1 -0
- package/dist/src/guardrails/types.js +20 -0
- package/dist/src/guardrails/types.js.map +1 -0
- package/dist/src/hypervisors/esxi/client.d.ts +103 -0
- package/dist/src/hypervisors/esxi/client.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/client.js +395 -0
- package/dist/src/hypervisors/esxi/client.js.map +1 -0
- package/dist/src/hypervisors/esxi/mock.d.ts +45 -0
- package/dist/src/hypervisors/esxi/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/mock.js +202 -0
- package/dist/src/hypervisors/esxi/mock.js.map +1 -0
- package/dist/src/hypervisors/index.d.ts +10 -0
- package/dist/src/hypervisors/index.d.ts.map +1 -0
- package/dist/src/hypervisors/index.js +10 -0
- package/dist/src/hypervisors/index.js.map +1 -0
- package/dist/src/hypervisors/manager.d.ts +78 -0
- package/dist/src/hypervisors/manager.d.ts.map +1 -0
- package/dist/src/hypervisors/manager.js +415 -0
- package/dist/src/hypervisors/manager.js.map +1 -0
- package/dist/src/hypervisors/proxmox/client.d.ts +29 -0
- package/dist/src/hypervisors/proxmox/client.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/client.js +278 -0
- package/dist/src/hypervisors/proxmox/client.js.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts +17 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.js +26 -0
- package/dist/src/hypervisors/proxmox/mock.js.map +1 -0
- package/dist/src/hypervisors/types.d.ts +159 -0
- package/dist/src/hypervisors/types.d.ts.map +1 -0
- package/dist/src/hypervisors/types.js +6 -0
- package/dist/src/hypervisors/types.js.map +1 -0
- package/dist/src/index.d.ts +19 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +19 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/proxmox/client.d.ts +37 -0
- package/dist/src/proxmox/client.d.ts.map +1 -0
- package/dist/src/proxmox/client.js +282 -0
- package/dist/src/proxmox/client.js.map +1 -0
- package/dist/src/proxmox/index.d.ts +53 -0
- package/dist/src/proxmox/index.d.ts.map +1 -0
- package/dist/src/proxmox/index.js +109 -0
- package/dist/src/proxmox/index.js.map +1 -0
- package/dist/src/proxmox/mock.d.ts +40 -0
- package/dist/src/proxmox/mock.d.ts.map +1 -0
- package/dist/src/proxmox/mock.js +362 -0
- package/dist/src/proxmox/mock.js.map +1 -0
- package/dist/src/proxmox/poller.d.ts +29 -0
- package/dist/src/proxmox/poller.d.ts.map +1 -0
- package/dist/src/proxmox/poller.js +107 -0
- package/dist/src/proxmox/poller.js.map +1 -0
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +2 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/mcp-server.d.ts +5 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -0
- package/dist/src/server/mcp-server.js +5 -0
- package/dist/src/server/mcp-server.js.map +1 -0
- package/dist/src/server.d.ts +35 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +95 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/slot/gc.d.ts +42 -0
- package/dist/src/slot/gc.d.ts.map +1 -0
- package/dist/src/slot/gc.js +79 -0
- package/dist/src/slot/gc.js.map +1 -0
- package/dist/src/slot/index.d.ts +4 -0
- package/dist/src/slot/index.d.ts.map +1 -0
- package/dist/src/slot/index.js +4 -0
- package/dist/src/slot/index.js.map +1 -0
- package/dist/src/slot/manager.d.ts +92 -0
- package/dist/src/slot/manager.d.ts.map +1 -0
- package/dist/src/slot/manager.js +650 -0
- package/dist/src/slot/manager.js.map +1 -0
- package/dist/src/slot/types.d.ts +184 -0
- package/dist/src/slot/types.d.ts.map +1 -0
- package/dist/src/slot/types.js +67 -0
- package/dist/src/slot/types.js.map +1 -0
- package/dist/src/tools/appliance-exec.d.ts +81 -0
- package/dist/src/tools/appliance-exec.d.ts.map +1 -0
- package/dist/src/tools/appliance-exec.js +134 -0
- package/dist/src/tools/appliance-exec.js.map +1 -0
- package/dist/src/tools/claim-slot.d.ts +5 -0
- package/dist/src/tools/claim-slot.d.ts.map +1 -0
- package/dist/src/tools/claim-slot.js +5 -0
- package/dist/src/tools/claim-slot.js.map +1 -0
- package/dist/src/tools/index.d.ts +26 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +63 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/list-hosts.d.ts +41 -0
- package/dist/src/tools/list-hosts.d.ts.map +1 -0
- package/dist/src/tools/list-hosts.js +91 -0
- package/dist/src/tools/list-hosts.js.map +1 -0
- package/dist/src/tools/list-inventory.d.ts +50 -0
- package/dist/src/tools/list-inventory.d.ts.map +1 -0
- package/dist/src/tools/list-inventory.js +112 -0
- package/dist/src/tools/list-inventory.js.map +1 -0
- package/dist/src/tools/list-slots.d.ts +5 -0
- package/dist/src/tools/list-slots.d.ts.map +1 -0
- package/dist/src/tools/list-slots.js +5 -0
- package/dist/src/tools/list-slots.js.map +1 -0
- package/dist/src/tools/provision-tools.d.ts +231 -0
- package/dist/src/tools/provision-tools.d.ts.map +1 -0
- package/dist/src/tools/provision-tools.js +289 -0
- package/dist/src/tools/provision-tools.js.map +1 -0
- package/dist/src/tools/release-slot.d.ts +5 -0
- package/dist/src/tools/release-slot.d.ts.map +1 -0
- package/dist/src/tools/release-slot.js +5 -0
- package/dist/src/tools/release-slot.js.map +1 -0
- package/dist/src/tools/slot-tools.d.ts +173 -0
- package/dist/src/tools/slot-tools.d.ts.map +1 -0
- package/dist/src/tools/slot-tools.js +296 -0
- package/dist/src/tools/slot-tools.js.map +1 -0
- package/dist/src/tools/vm-action.d.ts +189 -0
- package/dist/src/tools/vm-action.d.ts.map +1 -0
- package/dist/src/tools/vm-action.js +300 -0
- package/dist/src/tools/vm-action.js.map +1 -0
- package/dist/src/transports/index.d.ts +3 -0
- package/dist/src/transports/index.d.ts.map +1 -0
- package/dist/src/transports/index.js +3 -0
- package/dist/src/transports/index.js.map +1 -0
- package/dist/src/transports/sse.d.ts +38 -0
- package/dist/src/transports/sse.d.ts.map +1 -0
- package/dist/src/transports/sse.js +167 -0
- package/dist/src/transports/sse.js.map +1 -0
- package/dist/src/transports/stdio.d.ts +15 -0
- package/dist/src/transports/stdio.d.ts.map +1 -0
- package/dist/src/transports/stdio.js +34 -0
- package/dist/src/transports/stdio.js.map +1 -0
- package/dist/src/types/config.d.ts +17 -0
- package/dist/src/types/config.d.ts.map +1 -0
- package/dist/src/types/config.js +5 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/index.d.ts +4 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +4 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/mcp.d.ts +38 -0
- package/dist/src/types/mcp.d.ts.map +1 -0
- package/dist/src/types/mcp.js +46 -0
- package/dist/src/types/mcp.js.map +1 -0
- package/dist/src/types/proxmox.d.ts +181 -0
- package/dist/src/types/proxmox.d.ts.map +1 -0
- package/dist/src/types/proxmox.js +5 -0
- package/dist/src/types/proxmox.js.map +1 -0
- package/dist/src/types/slot.d.ts +5 -0
- package/dist/src/types/slot.d.ts.map +1 -0
- package/dist/src/types/slot.js +5 -0
- package/dist/src/types/slot.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +71 -0
- package/dist/src/utils/formatters.d.ts.map +1 -0
- package/dist/src/utils/formatters.js +480 -0
- package/dist/src/utils/formatters.js.map +1 -0
- package/dist/src/utils/index.d.ts +6 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +6 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/logger.d.ts +28 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +74 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/mutex.d.ts +32 -0
- package/dist/src/utils/mutex.d.ts.map +1 -0
- package/dist/src/utils/mutex.js +86 -0
- package/dist/src/utils/mutex.js.map +1 -0
- package/dist/src/utils/redact.d.ts +6 -0
- package/dist/src/utils/redact.d.ts.map +1 -0
- package/dist/src/utils/redact.js +6 -0
- package/dist/src/utils/redact.js.map +1 -0
- package/dist/src/utils/redactor.d.ts +50 -0
- package/dist/src/utils/redactor.d.ts.map +1 -0
- package/dist/src/utils/redactor.js +170 -0
- package/dist/src/utils/redactor.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Proxmox VE Model Context Protocol (MCP) Server CLI
|
|
4
|
+
*
|
|
5
|
+
* Command-line runner supporting Stdio and HTTP/SSE transports,
|
|
6
|
+
* Doppler credential resolution, custom configuration files,
|
|
7
|
+
* and graceful lifecycle management.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from "commander";
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { SseServerInstance } from "../src/transports/sse.js";
|
|
13
|
+
import { ServerConfig } from "../src/types/config.js";
|
|
14
|
+
export declare const VERSION = "0.1.0";
|
|
15
|
+
export interface CliOptions {
|
|
16
|
+
transport: "stdio" | "sse";
|
|
17
|
+
port: number;
|
|
18
|
+
host: string;
|
|
19
|
+
config?: string;
|
|
20
|
+
dopplerToken?: string;
|
|
21
|
+
dopplerProject?: string;
|
|
22
|
+
dopplerConfig?: string;
|
|
23
|
+
forceMock?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface CliExecutionResult {
|
|
26
|
+
server: McpServer;
|
|
27
|
+
transport: StdioServerTransport | SseServerInstance;
|
|
28
|
+
close: () => Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export interface RunCliOptions {
|
|
31
|
+
installSignalHandlers?: boolean;
|
|
32
|
+
suppressLogs?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Builds the Commander CLI program definition.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildCli(exitOverride?: boolean): Command;
|
|
38
|
+
/**
|
|
39
|
+
* Parses and validates command-line arguments.
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseCliOptions(argv?: string[], exitOverride?: boolean): {
|
|
42
|
+
options: CliOptions;
|
|
43
|
+
program: Command;
|
|
44
|
+
raw: Record<string, any>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Loads and validates a JSON configuration file if specified.
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadConfigFile(configPath: string): Partial<ServerConfig>;
|
|
50
|
+
/**
|
|
51
|
+
* Runs the Proxmox MCP Server CLI.
|
|
52
|
+
*/
|
|
53
|
+
export declare function runCli(argv?: string[], runOptions?: RunCliOptions): Promise<CliExecutionResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Detects whether this file was executed directly as the main Node.js entrypoint.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isMainModule(metaUrl: string): boolean;
|
|
58
|
+
//# sourceMappingURL=proxmox-mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxmox-mcp.d.ts","sourceRoot":"","sources":["../../bin/proxmox-mcp.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAIjF,OAAO,EAAmB,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAqB,MAAM,wBAAwB,CAAC;AAKzE,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,GAAG,KAAK,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,oBAAoB,GAAG,iBAAiB,CAAC;IACpD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,YAAY,UAAQ,GAAG,OAAO,CAkCtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,GAAE,MAAM,EAAiB,EAC7B,YAAY,UAAQ,GACnB;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAiDrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAuBxE;AAED;;GAEG;AACH,wBAAsB,MAAM,CAC1B,IAAI,GAAE,MAAM,EAAiB,EAC7B,UAAU,GAAE,aAAkB,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CA4H7B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAcrD"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Proxmox VE Model Context Protocol (MCP) Server CLI
|
|
4
|
+
*
|
|
5
|
+
* Command-line runner supporting Stdio and HTTP/SSE transports,
|
|
6
|
+
* Doppler credential resolution, custom configuration files,
|
|
7
|
+
* and graceful lifecycle management.
|
|
8
|
+
*/
|
|
9
|
+
import process from "node:process";
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
import { Command } from "commander";
|
|
14
|
+
import dotenv from "dotenv";
|
|
15
|
+
import { createMcpServer } from "../src/server/mcp-server.js";
|
|
16
|
+
import { credentialResolver } from "../src/credentials/resolver.js";
|
|
17
|
+
import { startStdioServer } from "../src/transports/stdio.js";
|
|
18
|
+
import { createSseServer } from "../src/transports/sse.js";
|
|
19
|
+
// Load environment variables from .env if present
|
|
20
|
+
dotenv.config();
|
|
21
|
+
export const VERSION = "0.1.0";
|
|
22
|
+
/**
|
|
23
|
+
* Builds the Commander CLI program definition.
|
|
24
|
+
*/
|
|
25
|
+
export function buildCli(exitOverride = false) {
|
|
26
|
+
const program = new Command();
|
|
27
|
+
program
|
|
28
|
+
.name("proxmox-mcp")
|
|
29
|
+
.description("Proxmox VE Model Context Protocol (MCP) Server and automated slot scheduler")
|
|
30
|
+
.version(VERSION, "-v, --version", "Output the current version")
|
|
31
|
+
.helpOption("-h, --help", "Display help for command")
|
|
32
|
+
.option("-t, --transport <type>", "Transport mode: 'stdio' or 'sse'", process.env.PROXMOX_MCP_TRANSPORT || "stdio")
|
|
33
|
+
.option("-p, --port <number>", "Port for SSE transport (default: 3000 or PORT env var)", process.env.PORT || "3000")
|
|
34
|
+
.option("-H, --host <string>", "Host interface for SSE (default: '127.0.0.1' or HOST env var)", process.env.HOST || "127.0.0.1")
|
|
35
|
+
.option("-c, --config <path>", "Path to optional JSON configuration file")
|
|
36
|
+
.option("--doppler-token <token>", "Doppler API token override")
|
|
37
|
+
.option("--doppler-project <project>", "Doppler project override")
|
|
38
|
+
.option("--doppler-config <config>", "Doppler environment/config override")
|
|
39
|
+
.option("--force-mock", "Force in-memory mock hypervisor mode (for testing/offline dev)");
|
|
40
|
+
if (exitOverride) {
|
|
41
|
+
program.exitOverride();
|
|
42
|
+
}
|
|
43
|
+
return program;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parses and validates command-line arguments.
|
|
47
|
+
*/
|
|
48
|
+
export function parseCliOptions(argv = process.argv, exitOverride = false) {
|
|
49
|
+
const program = buildCli(exitOverride);
|
|
50
|
+
program.parse(argv);
|
|
51
|
+
const raw = program.opts();
|
|
52
|
+
const transportSource = program.getOptionValueSource("transport");
|
|
53
|
+
const portSource = program.getOptionValueSource("port");
|
|
54
|
+
const hostSource = program.getOptionValueSource("host");
|
|
55
|
+
// Validate transport
|
|
56
|
+
const rawTransport = String(raw.transport || "stdio").toLowerCase();
|
|
57
|
+
if (rawTransport !== "stdio" && rawTransport !== "sse") {
|
|
58
|
+
throw new Error(`Invalid transport mode: '${raw.transport}'. Supported transports are 'stdio' and 'sse'.`);
|
|
59
|
+
}
|
|
60
|
+
const transport = rawTransport;
|
|
61
|
+
// Validate port (allow 0 for ephemeral OS port allocation)
|
|
62
|
+
const parsedPort = parseInt(String(raw.port), 10);
|
|
63
|
+
if (isNaN(parsedPort) || parsedPort < 0 || parsedPort > 65535) {
|
|
64
|
+
throw new Error(`Invalid port number: '${raw.port}'. Port must be an integer between 0 and 65535.`);
|
|
65
|
+
}
|
|
66
|
+
const host = String(raw.host || "127.0.0.1");
|
|
67
|
+
const options = {
|
|
68
|
+
transport,
|
|
69
|
+
port: parsedPort,
|
|
70
|
+
host,
|
|
71
|
+
config: raw.config ? String(raw.config) : undefined,
|
|
72
|
+
dopplerToken: raw.dopplerToken ? String(raw.dopplerToken) : undefined,
|
|
73
|
+
dopplerProject: raw.dopplerProject ? String(raw.dopplerProject) : undefined,
|
|
74
|
+
dopplerConfig: raw.dopplerConfig ? String(raw.dopplerConfig) : undefined,
|
|
75
|
+
forceMock: Boolean(raw.forceMock),
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
options,
|
|
79
|
+
program,
|
|
80
|
+
raw: {
|
|
81
|
+
...raw,
|
|
82
|
+
transportSource,
|
|
83
|
+
portSource,
|
|
84
|
+
hostSource,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Loads and validates a JSON configuration file if specified.
|
|
90
|
+
*/
|
|
91
|
+
export function loadConfigFile(configPath) {
|
|
92
|
+
const resolvedPath = path.resolve(process.cwd(), configPath);
|
|
93
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
94
|
+
throw new Error(`Configuration file not found: '${configPath}' (resolved to '${resolvedPath}')`);
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const rawContent = fs.readFileSync(resolvedPath, "utf-8");
|
|
98
|
+
const parsed = JSON.parse(rawContent);
|
|
99
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
100
|
+
throw new Error(`Configuration file '${configPath}' must contain a valid JSON object.`);
|
|
101
|
+
}
|
|
102
|
+
return parsed;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
if (err instanceof SyntaxError) {
|
|
106
|
+
throw new Error(`Failed to parse configuration file '${configPath}': Invalid JSON - ${err.message}`);
|
|
107
|
+
}
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Runs the Proxmox MCP Server CLI.
|
|
113
|
+
*/
|
|
114
|
+
export async function runCli(argv = process.argv, runOptions = {}) {
|
|
115
|
+
const { options, raw } = parseCliOptions(argv);
|
|
116
|
+
// Load config file if specified
|
|
117
|
+
let fileConfig = {};
|
|
118
|
+
if (options.config) {
|
|
119
|
+
fileConfig = loadConfigFile(options.config);
|
|
120
|
+
}
|
|
121
|
+
// Precedence: CLI flag > Config file > Environment variables > Defaults
|
|
122
|
+
const effectiveTransport = raw.transportSource === "cli"
|
|
123
|
+
? options.transport
|
|
124
|
+
: fileConfig.transport || options.transport || "stdio";
|
|
125
|
+
const effectivePort = raw.portSource === "cli"
|
|
126
|
+
? options.port
|
|
127
|
+
: fileConfig.port !== undefined
|
|
128
|
+
? fileConfig.port
|
|
129
|
+
: options.port;
|
|
130
|
+
const effectiveHost = raw.hostSource === "cli"
|
|
131
|
+
? options.host
|
|
132
|
+
: fileConfig.host || options.host || "127.0.0.1";
|
|
133
|
+
const effectiveForceMock = options.forceMock || fileConfig.mockMode || false;
|
|
134
|
+
let hostConfigs = fileConfig.hosts;
|
|
135
|
+
if (!hostConfigs || hostConfigs.length === 0) {
|
|
136
|
+
const resolution = await credentialResolver.resolve({
|
|
137
|
+
env: process.env,
|
|
138
|
+
dopplerToken: options.dopplerToken || fileConfig.doppler?.token,
|
|
139
|
+
dopplerProject: options.dopplerProject || fileConfig.doppler?.project,
|
|
140
|
+
dopplerConfig: options.dopplerConfig || fileConfig.doppler?.config,
|
|
141
|
+
forceMock: effectiveForceMock,
|
|
142
|
+
});
|
|
143
|
+
hostConfigs = resolution.hosts;
|
|
144
|
+
}
|
|
145
|
+
// Create the MCP server instance
|
|
146
|
+
const server = createMcpServer({
|
|
147
|
+
hostConfigs,
|
|
148
|
+
});
|
|
149
|
+
const installSignals = runOptions.installSignalHandlers !== false;
|
|
150
|
+
if (effectiveTransport === "sse") {
|
|
151
|
+
const slotManager = server._context
|
|
152
|
+
?.slotManager;
|
|
153
|
+
const sseServer = createSseServer(server, {
|
|
154
|
+
port: effectivePort,
|
|
155
|
+
host: effectiveHost,
|
|
156
|
+
slotManager,
|
|
157
|
+
});
|
|
158
|
+
await sseServer.listen(effectivePort, effectiveHost);
|
|
159
|
+
const close = async () => {
|
|
160
|
+
if (!runOptions.suppressLogs) {
|
|
161
|
+
console.error("[proxmox-mcp] Shutting down SSE server...");
|
|
162
|
+
}
|
|
163
|
+
await sseServer.close();
|
|
164
|
+
await server.close();
|
|
165
|
+
};
|
|
166
|
+
if (installSignals) {
|
|
167
|
+
const handleSig = async (sig) => {
|
|
168
|
+
console.error(`[proxmox-mcp] Received ${sig}, terminating...`);
|
|
169
|
+
try {
|
|
170
|
+
await close();
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
console.error("[proxmox-mcp] Error during shutdown:", err);
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
process.exit(0);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
process.once("SIGINT", () => handleSig("SIGINT"));
|
|
180
|
+
process.once("SIGTERM", () => handleSig("SIGTERM"));
|
|
181
|
+
}
|
|
182
|
+
return { server, transport: sseServer, close };
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// Default stdio transport
|
|
186
|
+
let activeTransport;
|
|
187
|
+
const close = async () => {
|
|
188
|
+
if (!runOptions.suppressLogs) {
|
|
189
|
+
console.error("[proxmox-mcp] Shutting down stdio server...");
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
await server.close();
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
try {
|
|
196
|
+
if (activeTransport) {
|
|
197
|
+
await activeTransport.close();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch { }
|
|
201
|
+
};
|
|
202
|
+
if (installSignals) {
|
|
203
|
+
const handleSig = async (sig) => {
|
|
204
|
+
console.error(`[proxmox-mcp] Received ${sig}, terminating...`);
|
|
205
|
+
try {
|
|
206
|
+
await close();
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
console.error("[proxmox-mcp] Error during shutdown:", err);
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
process.exit(0);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
process.once("SIGINT", () => handleSig("SIGINT"));
|
|
216
|
+
process.once("SIGTERM", () => handleSig("SIGTERM"));
|
|
217
|
+
}
|
|
218
|
+
activeTransport = await startStdioServer(server, { installSignalHandlers: false });
|
|
219
|
+
return { server, transport: activeTransport, close };
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Detects whether this file was executed directly as the main Node.js entrypoint.
|
|
224
|
+
*/
|
|
225
|
+
export function isMainModule(metaUrl) {
|
|
226
|
+
if (!process.argv[1])
|
|
227
|
+
return false;
|
|
228
|
+
try {
|
|
229
|
+
const scriptPath = fs.realpathSync(process.argv[1]);
|
|
230
|
+
const modulePath = fs.realpathSync(fileURLToPath(metaUrl));
|
|
231
|
+
return scriptPath === modulePath;
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
const raw = process.argv[1];
|
|
235
|
+
return (raw.endsWith("proxmox-mcp") ||
|
|
236
|
+
raw.endsWith("proxmox-mcp.ts") ||
|
|
237
|
+
raw.endsWith("proxmox-mcp.js"));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Auto-run if executed as CLI entrypoint
|
|
241
|
+
if (isMainModule(import.meta.url)) {
|
|
242
|
+
runCli().catch((err) => {
|
|
243
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
244
|
+
console.error(`[proxmox-mcp] Fatal error: ${msg}`);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=proxmox-mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxmox-mcp.js","sourceRoot":"","sources":["../../bin/proxmox-mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mediated Call Telemetry Appliance CLI Command Builder & Validator
|
|
3
|
+
*
|
|
4
|
+
* Translates structured command invocations into validated shell command strings.
|
|
5
|
+
* Enforces strict input validation and shell injection prevention.
|
|
6
|
+
*/
|
|
7
|
+
import { ApplianceCommandType, ApplianceExecParams } from "./types.js";
|
|
8
|
+
export declare const APPROVED_CONTAINERS: Set<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Validate that an input string does not contain any shell injection metacharacters.
|
|
11
|
+
*/
|
|
12
|
+
export declare function assertNoInjectionTokens(input: string, fieldName?: string): void;
|
|
13
|
+
/**
|
|
14
|
+
* Validate SQL table name identifier.
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateTableName(tableName: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Validate log tail line count (must be an integer between 1 and 5000).
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateLogTail(tail: unknown): number;
|
|
21
|
+
/**
|
|
22
|
+
* Validate container name against approved Call Telemetry containers.
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateContainerName(container: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Normalize action/commandType string from parameters.
|
|
27
|
+
*/
|
|
28
|
+
export declare function normalizeCommandType(params: ApplianceExecParams): ApplianceCommandType;
|
|
29
|
+
/**
|
|
30
|
+
* Build and validate the exact shell command string to execute on the remote appliance.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildApplianceCommand(params: ApplianceExecParams): string;
|
|
33
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../src/appliance/commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EAEpB,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,mBAAmB,aAW9B,CAAC;AAuBH;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,MAAgB,GAAG,IAAI,CAUxF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAYzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAcrD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAY7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,mBAAmB,GAAG,oBAAoB,CAKtF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAqLzE"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mediated Call Telemetry Appliance CLI Command Builder & Validator
|
|
3
|
+
*
|
|
4
|
+
* Translates structured command invocations into validated shell command strings.
|
|
5
|
+
* Enforces strict input validation and shell injection prevention.
|
|
6
|
+
*/
|
|
7
|
+
import { InvalidCommandViolationError } from "./types.js";
|
|
8
|
+
// Approved Call Telemetry service containers
|
|
9
|
+
export const APPROVED_CONTAINERS = new Set([
|
|
10
|
+
"calltelemetry-web-1",
|
|
11
|
+
"calltelemetry-db-1",
|
|
12
|
+
"calltelemetry-nats-1",
|
|
13
|
+
"calltelemetry-jtapi-sidecar-1",
|
|
14
|
+
"calltelemetry-ct-media-1",
|
|
15
|
+
"calltelemetry-seaweedfs-1",
|
|
16
|
+
"calltelemetry-grafana-1",
|
|
17
|
+
"calltelemetry-caddy-1",
|
|
18
|
+
"calltelemetry-redis-1",
|
|
19
|
+
"calltelemetry-worker-1"
|
|
20
|
+
]);
|
|
21
|
+
// Table name regex: standard SQL identifier (or "all" for vacuum)
|
|
22
|
+
const TABLE_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
23
|
+
// Banned shell metacharacters and injection tokens
|
|
24
|
+
const BANNED_SHELL_TOKENS = /[;&|`$()<>\n\r\0]/;
|
|
25
|
+
// Approved command prefixes for raw / whitelisted execution
|
|
26
|
+
const APPROVED_RAW_PREFIXES = [
|
|
27
|
+
"sudo /home/calltelemetry/cli.sh",
|
|
28
|
+
"/home/calltelemetry/cli.sh",
|
|
29
|
+
"cli.sh",
|
|
30
|
+
"docker ps",
|
|
31
|
+
"docker logs",
|
|
32
|
+
"journalctl",
|
|
33
|
+
"systemctl status",
|
|
34
|
+
"cat /etc/os-release",
|
|
35
|
+
"hostname",
|
|
36
|
+
"uptime",
|
|
37
|
+
"echo"
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Validate that an input string does not contain any shell injection metacharacters.
|
|
41
|
+
*/
|
|
42
|
+
export function assertNoInjectionTokens(input, fieldName = "Input") {
|
|
43
|
+
if (typeof input !== "string") {
|
|
44
|
+
throw new InvalidCommandViolationError(`${fieldName} must be a string.`);
|
|
45
|
+
}
|
|
46
|
+
if (BANNED_SHELL_TOKENS.test(input)) {
|
|
47
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: ${fieldName} contains illegal shell injection metacharacters: ${input}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate SQL table name identifier.
|
|
52
|
+
*/
|
|
53
|
+
export function validateTableName(tableName) {
|
|
54
|
+
if (!tableName || typeof tableName !== "string") {
|
|
55
|
+
throw new InvalidCommandViolationError("Table name must be a non-empty string.");
|
|
56
|
+
}
|
|
57
|
+
assertNoInjectionTokens(tableName, "Table name");
|
|
58
|
+
if (!TABLE_NAME_REGEX.test(tableName)) {
|
|
59
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: Table name '${tableName}' contains illegal characters. Identifier must match ^[a-zA-Z_][a-zA-Z0-9_]*$`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate log tail line count (must be an integer between 1 and 5000).
|
|
64
|
+
*/
|
|
65
|
+
export function validateLogTail(tail) {
|
|
66
|
+
if (tail === undefined || tail === null) {
|
|
67
|
+
return 100;
|
|
68
|
+
}
|
|
69
|
+
const num = typeof tail === "number" ? tail : Number(tail);
|
|
70
|
+
if (!Number.isInteger(num) || num < 1 || num > 5000) {
|
|
71
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: logTail must be an integer between 1 and 5000 lines (received: ${tail}).`);
|
|
72
|
+
}
|
|
73
|
+
return num;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Validate container name against approved Call Telemetry containers.
|
|
77
|
+
*/
|
|
78
|
+
export function validateContainerName(container) {
|
|
79
|
+
if (!container || typeof container !== "string") {
|
|
80
|
+
throw new InvalidCommandViolationError("Container name must be a non-empty string.");
|
|
81
|
+
}
|
|
82
|
+
assertNoInjectionTokens(container, "Container name");
|
|
83
|
+
if (!APPROVED_CONTAINERS.has(container)) {
|
|
84
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: Container '${container}' is not an approved Call Telemetry service container.`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Normalize action/commandType string from parameters.
|
|
89
|
+
*/
|
|
90
|
+
export function normalizeCommandType(params) {
|
|
91
|
+
const raw = params.commandType || params.action || "status";
|
|
92
|
+
const normalized = raw.trim().toLowerCase().replace(/\s+/g, "_");
|
|
93
|
+
return normalized;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build and validate the exact shell command string to execute on the remote appliance.
|
|
97
|
+
*/
|
|
98
|
+
export function buildApplianceCommand(params) {
|
|
99
|
+
const action = normalizeCommandType(params);
|
|
100
|
+
const args = params.args || params.params || {};
|
|
101
|
+
switch (action) {
|
|
102
|
+
case "status":
|
|
103
|
+
return "sudo /home/calltelemetry/cli.sh status";
|
|
104
|
+
case "jtapi_status":
|
|
105
|
+
case "jtapi status":
|
|
106
|
+
return "sudo /home/calltelemetry/cli.sh jtapi status";
|
|
107
|
+
case "health":
|
|
108
|
+
case "health_report":
|
|
109
|
+
return "sudo /home/calltelemetry/cli.sh health report --pretty";
|
|
110
|
+
case "diag": {
|
|
111
|
+
const sub = (args.subcommand || args.service || "network").toString().toLowerCase().trim();
|
|
112
|
+
assertNoInjectionTokens(sub, "Diag subcommand");
|
|
113
|
+
if (sub === "network" || sub === "database" || sub === "service") {
|
|
114
|
+
return `sudo /home/calltelemetry/cli.sh diag ${sub}`;
|
|
115
|
+
}
|
|
116
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: Unsupported diag subcommand '${sub}'. Allowed: network, database, service.`);
|
|
117
|
+
}
|
|
118
|
+
case "diag_network":
|
|
119
|
+
case "diag network":
|
|
120
|
+
return "sudo /home/calltelemetry/cli.sh diag network";
|
|
121
|
+
case "diag_database":
|
|
122
|
+
case "diag database":
|
|
123
|
+
return "sudo /home/calltelemetry/cli.sh diag database";
|
|
124
|
+
case "diag_service":
|
|
125
|
+
case "diag service":
|
|
126
|
+
return "sudo /home/calltelemetry/cli.sh diag service";
|
|
127
|
+
case "db_status":
|
|
128
|
+
case "db status":
|
|
129
|
+
return "sudo /home/calltelemetry/cli.sh db status";
|
|
130
|
+
case "db_size":
|
|
131
|
+
case "db size":
|
|
132
|
+
return "sudo /home/calltelemetry/cli.sh db size";
|
|
133
|
+
case "db_tables":
|
|
134
|
+
case "db tables": {
|
|
135
|
+
if (args.table) {
|
|
136
|
+
validateTableName(args.table);
|
|
137
|
+
return `sudo /home/calltelemetry/cli.sh db tables ${args.table}`;
|
|
138
|
+
}
|
|
139
|
+
return "sudo /home/calltelemetry/cli.sh db tables";
|
|
140
|
+
}
|
|
141
|
+
case "db_vacuum":
|
|
142
|
+
case "db vacuum": {
|
|
143
|
+
const table = args.table || "all";
|
|
144
|
+
validateTableName(table);
|
|
145
|
+
const flags = [];
|
|
146
|
+
if (args.vacuumFull)
|
|
147
|
+
flags.push("--full");
|
|
148
|
+
if (args.vacuumAnalyze)
|
|
149
|
+
flags.push("--analyze");
|
|
150
|
+
const flagStr = flags.length > 0 ? ` ${flags.join(" ")}` : "";
|
|
151
|
+
return `sudo /home/calltelemetry/cli.sh db vacuum ${table}${flagStr}`;
|
|
152
|
+
}
|
|
153
|
+
case "db_compact":
|
|
154
|
+
case "db compact":
|
|
155
|
+
return "sudo /home/calltelemetry/cli.sh db compact";
|
|
156
|
+
case "db_backup":
|
|
157
|
+
case "db backup":
|
|
158
|
+
return "sudo /home/calltelemetry/cli.sh db backup";
|
|
159
|
+
case "db_list":
|
|
160
|
+
case "db list":
|
|
161
|
+
return "sudo /home/calltelemetry/cli.sh db list";
|
|
162
|
+
case "migrate": {
|
|
163
|
+
const sub = (args.subcommand || "status").toString().toLowerCase().trim();
|
|
164
|
+
assertNoInjectionTokens(sub, "Migrate subcommand");
|
|
165
|
+
if (sub === "status") {
|
|
166
|
+
return "sudo /home/calltelemetry/cli.sh migrate status";
|
|
167
|
+
}
|
|
168
|
+
if (sub === "legacy") {
|
|
169
|
+
return "sudo /home/calltelemetry/cli.sh migrate legacy --json";
|
|
170
|
+
}
|
|
171
|
+
if (sub === "run") {
|
|
172
|
+
return "sudo /home/calltelemetry/cli.sh migrate run";
|
|
173
|
+
}
|
|
174
|
+
if (sub === "drain") {
|
|
175
|
+
return "sudo /home/calltelemetry/cli.sh migrate drain";
|
|
176
|
+
}
|
|
177
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: Unsupported migrate subcommand '${sub}'. Allowed: status, legacy, run, drain.`);
|
|
178
|
+
}
|
|
179
|
+
case "migrate_status":
|
|
180
|
+
case "migrate status":
|
|
181
|
+
return "sudo /home/calltelemetry/cli.sh migrate status";
|
|
182
|
+
case "migrate_legacy":
|
|
183
|
+
case "migrate legacy":
|
|
184
|
+
return "sudo /home/calltelemetry/cli.sh migrate legacy --json";
|
|
185
|
+
case "migrate_run":
|
|
186
|
+
case "migrate run":
|
|
187
|
+
return "sudo /home/calltelemetry/cli.sh migrate run";
|
|
188
|
+
case "migrate_drain":
|
|
189
|
+
case "migrate drain":
|
|
190
|
+
return "sudo /home/calltelemetry/cli.sh migrate drain";
|
|
191
|
+
case "docker": {
|
|
192
|
+
const sub = (args.subcommand || "ps").toString().toLowerCase().trim();
|
|
193
|
+
assertNoInjectionTokens(sub, "Docker subcommand");
|
|
194
|
+
if (sub === "ps") {
|
|
195
|
+
return "docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Ports}}'";
|
|
196
|
+
}
|
|
197
|
+
if (sub === "logs") {
|
|
198
|
+
const container = args.container || "calltelemetry-web-1";
|
|
199
|
+
validateContainerName(container);
|
|
200
|
+
const tail = validateLogTail(args.logTail);
|
|
201
|
+
return `docker logs --tail ${tail} ${container}`;
|
|
202
|
+
}
|
|
203
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: Unsupported docker subcommand '${sub}'. Allowed: ps, logs.`);
|
|
204
|
+
}
|
|
205
|
+
case "docker_ps":
|
|
206
|
+
case "docker ps":
|
|
207
|
+
return "docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Ports}}'";
|
|
208
|
+
case "docker_logs":
|
|
209
|
+
case "logs": {
|
|
210
|
+
const container = args.container || "calltelemetry-web-1";
|
|
211
|
+
validateContainerName(container);
|
|
212
|
+
const tail = validateLogTail(args.logTail);
|
|
213
|
+
return `docker logs --tail ${tail} ${container}`;
|
|
214
|
+
}
|
|
215
|
+
case "journalctl":
|
|
216
|
+
case "system_logs": {
|
|
217
|
+
const tail = validateLogTail(args.logTail);
|
|
218
|
+
return `journalctl -u docker-compose-app --no-pager -n ${tail}`;
|
|
219
|
+
}
|
|
220
|
+
case "version":
|
|
221
|
+
return "cli.sh version && grep '^CT_RELEASE_VERSION=' /home/calltelemetry/.env";
|
|
222
|
+
case "raw_whitelisted":
|
|
223
|
+
case "raw": {
|
|
224
|
+
const rawCmd = args.rawCommand;
|
|
225
|
+
if (!rawCmd || typeof rawCmd !== "string" || !rawCmd.trim()) {
|
|
226
|
+
throw new InvalidCommandViolationError("INVALID_COMMAND_VIOLATION: rawCommand is required for 'raw' action.");
|
|
227
|
+
}
|
|
228
|
+
const trimmed = rawCmd.trim();
|
|
229
|
+
assertNoInjectionTokens(trimmed, "Raw command");
|
|
230
|
+
// Verify approved prefix
|
|
231
|
+
const isApproved = APPROVED_RAW_PREFIXES.some((prefix) => trimmed.startsWith(prefix));
|
|
232
|
+
if (!isApproved) {
|
|
233
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: Raw command '${trimmed}' does not start with an approved command prefix.`);
|
|
234
|
+
}
|
|
235
|
+
return trimmed;
|
|
236
|
+
}
|
|
237
|
+
default:
|
|
238
|
+
throw new InvalidCommandViolationError(`INVALID_COMMAND_VIOLATION: Unsupported appliance command action '${action}'.`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/appliance/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote Appliance SSH Executor using pure-JS ssh2 Client
|
|
3
|
+
*
|
|
4
|
+
* Connects to Call Telemetry appliances on Port 2222 using Doppler-resolved credentials.
|
|
5
|
+
* Handles connect & execution timeouts, and guarantees output sanitization & secret redaction.
|
|
6
|
+
*/
|
|
7
|
+
import { ApplianceExecParams, ApplianceExecResult, IApplianceExecutor } from "./types.js";
|
|
8
|
+
import { CredentialResolver } from "../credentials/resolver.js";
|
|
9
|
+
import { SecretRedactor } from "../utils/redactor.js";
|
|
10
|
+
export interface ApplianceSshExecutorOptions {
|
|
11
|
+
resolver?: CredentialResolver;
|
|
12
|
+
redactor?: SecretRedactor;
|
|
13
|
+
defaultPort?: number;
|
|
14
|
+
defaultConnectTimeoutMs?: number;
|
|
15
|
+
defaultExecutionTimeoutMs?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class ApplianceSshExecutor implements IApplianceExecutor {
|
|
18
|
+
private resolver;
|
|
19
|
+
private redactor;
|
|
20
|
+
private defaultPort;
|
|
21
|
+
private defaultConnectTimeoutMs;
|
|
22
|
+
private defaultExecutionTimeoutMs;
|
|
23
|
+
constructor(options?: ApplianceSshExecutorOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Execute a mediated command on the target appliance over SSH.
|
|
26
|
+
*/
|
|
27
|
+
execute(params: ApplianceExecParams): Promise<ApplianceExecResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Test SSH connectivity and authentication against the target appliance.
|
|
30
|
+
*/
|
|
31
|
+
testConnection(targetIp: string, port?: number, timeoutMs?: number): Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
export declare const applianceSshExecutor: ApplianceSshExecutor;
|
|
34
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/appliance/executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAKnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAsB,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,cAAc,EAAmC,MAAM,sBAAsB,CAAC;AAGvF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,yBAAyB,CAAS;gBAE9B,OAAO,GAAE,2BAAgC;IAQrD;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA0NxE;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAgB5F;AAED,eAAO,MAAM,oBAAoB,sBAA6B,CAAC"}
|