Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions services/bin/octobus-tentacles.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,10 @@ const services = {
entryFile: "../elastic__elasticsearch_7-10-0/bin/elasticsearch-7-10-0.js",
serviceModule: "../elastic__elasticsearch_7-10-0/src/service.js",
},
"ve-8-3-5": {
entryFile: "../proxmox__ve_8-3-5/bin/ve-8-3-5.js",
serviceModule: "../proxmox__ve_8-3-5/src/service.js",
},
"wangsu-label-ip": {
entryFile: "../wangsu__label-ip/bin/wangsu-label-ip.js",
serviceModule: "../wangsu__label-ip/src/service.js",
Expand Down
10 changes: 10 additions & 0 deletions services/bin/ve-8-3-5.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env node

import { fileURLToPath } from "node:url";
import { runServiceMain } from "@chaitin-ai/octobus-sdk";

import { service } from "../proxmox__ve_8-3-5/src/service.js";

runServiceMain(service, {
entryFile: fileURLToPath(new URL("../proxmox__ve_8-3-5/bin/ve-8-3-5.js", import.meta.url)),
});
3 changes: 3 additions & 0 deletions services/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"alertmanager-0-27-0": "bin/alertmanager-0-27-0.js",
"prometheus-3-0-1": "bin/prometheus-3-0-1.js",
"elasticsearch-7-10-0": "bin/elasticsearch-7-10-0.js",
"ve-8-3-5": "bin/ve-8-3-5.js",
"dptech-eds": "bin/dptech-eds.js",
"dptech-fw-v4-6-10": "bin/dptech-fw-v4-6-10.js",
"dptech-umc-ads-v5-3-29": "bin/dptech-umc-ads-v5-3-29.js",
Expand Down Expand Up @@ -197,6 +198,7 @@
"crowdsec__security-engine",
"bin/prometheus-3-0-1.js",
"bin/elasticsearch-7-10-0.js",
"bin/ve-8-3-5.js",
"bin/dptech-eds.js",
"bin/dptech-fw-v4-6-10.js",
"bin/dptech-umc-ads-v5-3-29.js",
Expand Down Expand Up @@ -315,6 +317,7 @@
"dingtalk__group-robot",
"openobserve__openobserve_v0-15-1",
"elastic__elasticsearch_7-10-0",
"proxmox__ve_8-3-5",
"dptech__eds",
"dptech__fw_v4-6-10",
"dptech__umc-ads_v5-3-29",
Expand Down
46 changes: 46 additions & 0 deletions services/proxmox__ve_8-3-5/PR_BODY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## Mock 联调记录:ListNodes

以下内容来自 `test/mock_upstream.js`,仅验证请求构造和响应解析,不是
Proxmox VE 8.3.5 真实环境兼容性证据。

# Request
```
GET https://<pve-host>:8006/api2/json/nodes
Authorization: PVEAPIToken=root@pam!automation=<redacted>
```

# Response HTTP/1.1 200 OK
```json
{
"data": [
{
"node": "pve-node-1",
"status": "online",
"level": "c",
"ip": "10.0.0.11",
"cpu": 0.12,
"cpu_count": 16,
"maxcpu": 16,
"mem": 8589934592,
"maxmem": 34359738368,
"disk": 107374182400,
"maxdisk": 536870912000,
"uptime": 9000
},
{
"node": "pve-node-2",
"status": "offline",
"level": "",
"ip": "10.0.0.12",
"cpu": 0,
"cpu_count": 8,
"maxcpu": 8,
"mem": 0,
"maxmem": 16777216000,
"disk": 0,
"maxdisk": 268435456000,
"uptime": 0
}
]
}
```
72 changes: 72 additions & 0 deletions services/proxmox__ve_8-3-5/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Proxmox VE 8.3.5

OctoBus service package for the Proxmox VE 8.3.5 REST API (`/api2/json/`). This package exposes a small, read-only inventory surface that is useful for agents and tools that need to look up Proxmox cluster resources without depending on the full official SDK.

## Import

```bash
octobus service import --id ve-8-3-5 ./services/proxmox__ve_8-3-5
```

## Package Layout

- `service.json`: OctoBus service package manifest.
- `proto/proxmox_ve_8_3_5.proto`: Protobuf contract for the read-only inventory RPCs.
- `src/ve-8-3-5.js`: Runtime handler, request validation, HTTP request building, and error mapping.
- `config.schema.json`: Non-secret binding schema.
- `secret.schema.json`: Proxmox API token schema.
- `test/`: Node test coverage and mock upstream.

## Bindings

Configuration:

- `baseUrl` (or `base_url`, `host`, `restBaseUrl`, `url`): Proxmox API base URL, e.g. `https://pve.example.com:8006`.
- `defaultNode` (or `default_node`, `node`): Default Proxmox node name used when a per-RPC request omits `node`.
- `allowInsecureHttp` (or `allow_insecure_http`): when `true`, allows plain HTTP base URLs (default `false`). Loopback HTTP URLs are accepted for local tests without this flag.
- `skipTlsVerify` (or `tlsInsecureSkipVerify`, `insecureSkipVerify`, `tls_skip_verify`): skip TLS certificate verification for self-signed deployments (default `false`).
- `timeoutMs` (or `timeout_ms`, `timeout`): HTTP timeout in milliseconds, default `5000`.
- `headers`: optional additional HTTP headers merged into every request.

Secrets:

- `tokenId` (or `token_id`): Proxmox API token identifier in the form `USER@REALM!TOKENID` (e.g. `root@pam!automation`).
- `tokenSecret` (or `token_secret`): the token secret value associated with the token ID.
- `username`, `realm`: optional metadata describing the principal and authentication realm of the token.
- `pveAuthTicket`: optional legacy PVE auth cookie, reserved for future ticket-based flows.

## RPC Methods

- `Proxmox_VE_8_3_5.Proxmox_VE_8_3_5/ListNodes` -> `GET /api2/json/nodes`
- `Proxmox_VE_8_3_5.Proxmox_VE_8_3_5/ListQemuVMs` -> `GET /api2/json/nodes/{node}/qemu`
- `Proxmox_VE_8_3_5.Proxmox_VE_8_3_5/GetQemuVMConfig` -> `GET /api2/json/nodes/{node}/qemu/{vmid}/config`
- `Proxmox_VE_8_3_5.Proxmox_VE_8_3_5/ListLXCs` -> `GET /api2/json/nodes/{node}/lxc`
- `Proxmox_VE_8_3_5.Proxmox_VE_8_3_5/ListStorage` -> `GET /api2/json/nodes/{node}/storage`
- `Proxmox_VE_8_3_5.Proxmox_VE_8_3_5/GetNodeStatus` -> `GET /api2/json/nodes/{node}/status`

## Authentication

Each request is signed with the Proxmox API token by setting:

```
Authorization: PVEAPIToken=USER@REALM!TOKENID=TOKENSECRET
```

The header is built from `tokenId` and `tokenSecret`. Plain `PVEAuthCookie` ticket flows are not exercised by the read-only methods here.

## Behavior

- All RPCs are GET requests against the `/api2/json/` prefix.
- `ListNodes` does not need a `node` argument; everything else uses `req.node` (or `bindings.defaultNode`).
- `GetQemuVMConfig` requires both `node` and `vmid`.
- Responses are decoded from Proxmox's `{ "data": ... }` envelope and projected to compact proto messages. The raw upstream body and HTTP status are also returned for callers that need the full payload.
- HTTP `401` / `403` map to `PERMISSION_DENIED`; other `4xx` map to `FAILED_PRECONDITION`. Proxmox's HTTP 500 "resource does not exist" response maps to `NOT_FOUND`, other permanent `500`/`501` failures map to `FAILED_PRECONDITION`, and `502`/`503`/`504` plus network failures map to `UNAVAILABLE`. A sanitized, bounded upstream error summary is retained for diagnosis; non-JSON or empty successful responses map to `UNKNOWN`.

## Validation

```bash
cd services
npm run validate -- --service-dir proxmox__ve_8-3-5
npm test -- --service-dir proxmox__ve_8-3-5 --coverage
npm run pack:check
```
6 changes: 6 additions & 0 deletions services/proxmox__ve_8-3-5/bin/ve-8-3-5.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env node
import { runServiceMain } from '@chaitin-ai/octobus-sdk';

import { service } from '../src/service.js';

await runServiceMain(service);
101 changes: 101 additions & 0 deletions services/proxmox__ve_8-3-5/config.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"anyOf": [
{ "required": ["baseUrl"] },
{ "required": ["base_url"] },
{ "required": ["host"] },
{ "required": ["restBaseUrl"] },
{ "required": ["url"] }
],
"properties": {
"baseUrl": {
"type": "string",
"description": "Proxmox VE API base URL (scheme + host[:port]), for example https://pve.example.com:8006."
},
"base_url": {
"type": "string",
"description": "Alias for baseUrl."
},
"host": {
"type": "string",
"description": "Legacy alias for baseUrl."
},
"restBaseUrl": {
"type": "string",
"description": "Alias for baseUrl."
},
"url": {
"type": "string",
"description": "Alias for baseUrl."
},
"defaultNode": {
"type": "string",
"description": "Default Proxmox node name when callers do not provide one in the request."
},
"default_node": {
"type": "string",
"description": "Alias for defaultNode."
},
"node": {
"type": "string",
"description": "Alias for defaultNode."
},
"allowInsecureHttp": {
"type": "boolean",
"description": "Allow plain HTTP baseUrl for Proxmox deployments without TLS."
},
"allow_insecure_http": {
"type": "boolean",
"description": "Alias for allowInsecureHttp."
},
"allowHttp": {
"type": "boolean",
"description": "Explicitly allow a plain HTTP baseUrl. Defaults to false when omitted."
},
"skipTlsVerify": {
"type": "boolean",
"default": false,
"description": "Skip TLS certificate verification for private deployments with self-signed certs."
},
"tlsInsecureSkipVerify": {
"type": "boolean",
"default": false,
"description": "Alias for skipTlsVerify."
},
"insecureSkipVerify": {
"type": "boolean",
"default": false,
"description": "Alias for skipTlsVerify."
},
"tls_skip_verify": {
"type": "boolean",
"default": false,
"description": "Alias for skipTlsVerify."
},
"timeoutMs": {
"type": "integer",
"minimum": 1,
"default": 5000,
"description": "HTTP timeout in milliseconds."
},
"timeout_ms": {
"type": "integer",
"minimum": 1,
"description": "Alias for timeoutMs."
},
"timeout": {
"type": "integer",
"minimum": 1,
"description": "Alias for timeoutMs."
},
"headers": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Optional additional HTTP headers."
}
}
}
47 changes: 47 additions & 0 deletions services/proxmox__ve_8-3-5/integration-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## Mock Integration Evidence: ListNodes successful

This transcript was produced by the local `test/mock_upstream.js` fixture. It
validates request construction and response decoding, but it is not evidence
of compatibility with a real Proxmox VE 8.3.5 installation.

# Request
```
https://<pve-host>:8006/api2/json/nodes
Authorization: PVEAPIToken=root@pam!automation=<redacted>
```

# Response HTTP/1.1 200 OK
```json
{
"data": [
{
"node": "pve-node-1",
"status": "online",
"level": "c",
"ip": "10.0.0.11",
"cpu": 0.12,
"cpu_count": 16,
"maxcpu": 16,
"mem": 8589934592,
"maxmem": 34359738368,
"disk": 107374182400,
"maxdisk": 536870912000,
"uptime": 9000
},
{
"node": "pve-node-2",
"status": "offline",
"level": "",
"ip": "10.0.0.12",
"cpu": 0,
"cpu_count": 8,
"maxcpu": 8,
"mem": 0,
"maxmem": 16777216000,
"disk": 0,
"maxdisk": 268435456000,
"uptime": 0
}
]
}
```
15 changes: 15 additions & 0 deletions services/proxmox__ve_8-3-5/offline-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Offline Test

Use this directory for customer-site read-only checks against a real
Proxmox VE 8.3.5 deployment. Start with status or list methods before running any
write operation.

Recommended first checks:
- `ListNodes`
- `ListQemuVMs`

Replace placeholder values in `config.example.json` with the customer's actual
base URL. Configure `tokenId` and `tokenSecret` using a read-only Proxmox API
token; username/password and bearer-token authentication are not supported.
Install the package dependencies declared in `package.json`, including
`@chaitin-ai/octobus-sdk` 0.6.x, before running the service entry.
10 changes: 10 additions & 0 deletions services/proxmox__ve_8-3-5/offline-test/config.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"config": {
"baseUrl": "https://PVE_HOST:8006",
"allowInsecureHttp": false
},
"secret": {
"token_id": "root@pam!TOKENID",
"token_secret": "PROXMOX_TOKEN"
}
}
13 changes: 13 additions & 0 deletions services/proxmox__ve_8-3-5/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "ve-8-3-5",
"version": "0.0.0",
"private": true,
"type": "module",
"bin": {
"ve-8-3-5": "bin/ve-8-3-5.js"
},
"dependencies": {
"@chaitin-ai/octobus-sdk": "^0.6.0",
"undici": "^7.16.0"
}
}
Loading
Loading