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
proxmox-api-simulator
Stateful asynchronous Proxmox VE API simulator for testing API clients and infrastructure tooling without a real hypervisor cluster.
The simulator is backed by PostgreSQL, driven by imported official API
contracts, and exposes the same /api2/json and /api2/extjs surfaces as
Proxmox VE. Semantic handlers persist mutations; long-running work returns
durable UPIDs executed by leased task workers.
Verified API coverage
Handler registry and verified surface ledgers are 100% for every bundled major:
| Contract | Declared | Implemented | Verified |
|---|---|---|---|
| PVE 6.4-15 | 504 | 504 | 504 |
| PVE 7.4-16 | 540 | 540 | 540 |
| PVE 8.4.5 | 605 | 605 | 605 |
| PVE 9.2.3 | 675 | 675 | 675 |
Switch the active contract at runtime from the Web UI (Apply as runtime) or
POST /ui/api/contract/apply?major=N — each Apply loads
evidence/pve-{version}.json so observed/verified scores follow the selected
major. Regenerate ledgers after importing a new contract with make evidence.
Live reports: /admin/compatibility (also .md / .html). See
Compatibility and API versions.
This is measurable contract and handler coverage for a laboratory simulator — not a claim that every Proxmox edge case or remote integration behaves identically to production hardware.
Quick start (published image)
Image: inecs/proxmox-api-simulator
Docker Compose
docker compose -f docker-compose.release.yml up -d
docker compose -f docker-compose.release.yml run --rm --entrypoint python \
simulator -m app.simulation.seed_cli
curl http://localhost:8006/health/ready
curl http://localhost:8006/api2/json/version
Or: make release-up && make release-seed PROFILE=small
Helm (Kubernetes + Ingress + Let's Encrypt)
helm upgrade --install pve-sim ./helm/proxmox-api-simulator \
-n proxmox-sim --create-namespace \
-f ./helm/proxmox-api-simulator/values-ingress-example.yaml \
--set certManager.email=you@example.com \
--set ingress.hosts[0].host=pve-sim.example.com \
--set ingress.tls[0].hosts[0]=pve-sim.example.com \
--set secret.ticketSigningKey="$(openssl rand -hex 32)"
Requires an Ingress controller and cert-manager. Details: Kubernetes / Helm.
- HTTP API and Web UI (Compose): http://localhost:8006/
- FastAPI schema docs: http://localhost:8006/docs
- Default seeded admin:
root@pam/secret
Quick start (development checkout)
Build and run the bind-mounted development stack from this repository:
make install
make up
make seed PROFILE=small
curl http://localhost:8006/health/ready
curl http://localhost:8006/api2/json/version
curl -X POST -d 'username=root@pam&password=secret' \
http://localhost:8006/api2/json/access/ticket
- HTTP API and Web UI: http://localhost:8006/
- HTTPS gateway (self-signed, development only):
https://localhost:8007— checked-indocker/tls/server.keyis a lab-only localhost cert; do not reuse it outside local Compose. - FastAPI schema docs: http://localhost:8006/docs
Web UI
Interactive console with light/dark themes, endpoint catalog for PVE 6–9, and runtime contract hot-swap. More detail: Web UI.
Documentation
| Guide | Description |
|---|---|
| Getting started | First successful lab session |
| Configuration | Environment variables and Compose |
| Authentication | Tickets, CSRF, API tokens, ACLs |
| API versions | Contracts 6–9 and hot-swap |
| Clients & examples | Python, Go, Java, Perl, Ansible, Terraform, Pulumi |
| Seed profiles | Deterministic cluster fixtures |
| API surface | Routing, handlers, fallbacks |
| Domains | QEMU, LXC, storage, HA, SDN, … |
| Web UI | Interactive console and catalogs |
| Operations | Migrate, reseed, upgrade |
| Kubernetes / Helm | Hub image + Ingress + Let's Encrypt |
| Security | Lab threat model and credentials |
| Observability | Health endpoints and logging |
| Troubleshooting | Common failure modes |
| FAQ | Short answers |
| Architecture | Component boundaries |
| Compatibility | Evidence model and release matrix |
Runnable cookbooks live under examples/.
proxmoxer (HTTPS gateway)
from proxmoxer import ProxmoxAPI
proxmox = ProxmoxAPI(
"localhost",
port=8007,
user="root@pam",
password="secret",
verify_ssl=False, # local self-signed development certificate only
)
print(proxmox.version.get())
print(proxmox.nodes("pve01").qemu.get())
API token example: user root@pam, token_name="automation",
token_value="automation-secret". Token requests do not need CSRF; ticket
mutations do.
Common Make targets
make up / make down / make logs / make dev
make test # unit + contract (includes verified surface)
make test-integration # PostgreSQL-backed
make test-surface # all verbs × majors 6-9 (0x501 / 0xexception)
make test-compatibility # proxmoxer against Compose
make evidence # regenerate evidence/pve-*.json ledgers
make seed PROFILE=small
make db-migrate
make shell
make ci # ruff + mypy + offline pytest + surface probe
make release # build + push runtime image to Docker Hub
make release-up # pull/start docker-compose.release.yml
make release-seed PROFILE=small
Docker Hub release (requires docker login as the Hub owner; see
Operations):
make release # inecs/proxmox-api-simulator:<pyproject version> + :latest
make release VERSION=0.2.0 # override tag
make release-build # build/tag only, no push
make release-up && make release-seed # run the published stack locally
What this is not
- Not a hypervisor: no KVM/LXC execution on bare metal or nested hosts.
- Not a drop-in multi-tenant production Proxmox replacement.
- Remote IdP / LDAP / live Ceph / live ACME directories are simulated locally; they do not call real external systems.

