Add a stateful Proxmox API console and broad handler coverage beyond the

initial QEMU slice, backed by imported contracts for majors 6–9.
- Implement durable handlers for access/auth, cluster, LXC, storage, HA,
  firewall, Ceph, SDN, ACME, notifications, pools, mapping, and node ops
- Serve an interactive Web UI with catalog browsing, demo seed controls,
  and OpenAPI/help surfaces
- Bundle PVE 6.4-15, 7.4-16, and 8.4.5 contract revisions alongside 9.2.3
- Support in-memory runtime contract Apply (POST /ui/api/contract/apply)
  so /version and /api2 routes follow the selected major until restart
- Expand seed profiles (including demo-cluster), migrations 007–008, TLS
  gateway config, Compose/Makefile tooling, and compatibility evidence
- Tighten .gitignore for macOS, hidden directories (.*/), and local secrets
This commit is contained in:
Sergey Antropoff
2026-07-16 01:08:01 +03:00
parent 003ee5d634
commit 777926487b
189 changed files with 241501 additions and 944 deletions
+83
View File
@@ -0,0 +1,83 @@
# API surface
## Request path
1. Middleware assigns or forwards a request ID.
2. The active contract snapshot selects declared paths and schemas.
3. Authentication resolves a principal (ticket or API token).
4. ACL / privilege checks run before revealing or mutating resources.
5. Path, query, and body inputs are validated against contract-derived schemas.
6. A semantic handler executes against PostgreSQL-backed state.
7. Long operations create a durable task (+ lock when required) and return a UPID.
8. Responses use the Proxmox envelope under `/api2/json` or `/api2/extjs`.
## Dual renderers
Every contract method is registered under both:
- `/api2/json/...`
- `/api2/extjs/...`
Clients and the Web UI typically use the JSON renderer.
## Handlers vs contracts
- **Declared** — present in the imported API Viewer snapshot for the major.
- **Implemented** — a semantic handler is registered for that verb + path.
- Majors **69** have **100%** implemented coverage for declared methods.
Handlers must persist create/update/delete effects. Empty no-op mutations are
not part of the product contract. See the workspace durable-simulator rule.
## OpenAPI and exploration
- Interactive FastAPI docs: `/docs`
- Web UI method inspector: `/` → catalog → method
- UI APIs: `/ui/api/catalog`, `/ui/api/method`, `/ui/api/compatibility`
## Compatibility endpoints
| Path | Format |
|---|---|
| `/admin/compatibility` | JSON |
| `/admin/compatibility.md` | Markdown |
| `/admin/compatibility.html` | HTML |
Reports follow the active runtime contract after hot-swap.
## Tasks (UPID)
Async work (guest power, clone, migrate, many deletes, backups, …) returns a
UPID. Poll:
```text
GET /nodes/{node}/tasks/{upid}/status
GET /nodes/{node}/tasks/{upid}/log
```
Workers claim tasks with `FOR UPDATE SKIP LOCKED`, renew leases, and recover
after process restart. HTTP 200 on the mutation request means “accepted”, not
“guest already in final state”.
## Errors (common)
| Status | Typical cause |
|---|---|
| 401 | Missing/invalid ticket or token |
| 403 | ACL denial or missing CSRF on ticket mutation |
| 409 | VMID conflict, illegal state transition, lock contention |
| 501 | Handler missing (should not appear for declared methods on 69) |
| 503 | Readiness failure (database / migrations) |
## Importing contracts
```bash
make shell
proxmox-api-contract validate path/to/source.json
proxmox-api-contract --store contracts import --file path/to/source.json --version 9.2.3
proxmox-api-contract --store contracts list
proxmox-api-contract diff old.json new.json --format markdown
```
Remote import enforces HTTPS, an official-host allowlist, size/redirect/timeout
limits, and checksummed immutable revisions.