Language / Язык: English | Русский
Stateful laboratory simulator for OpenStack APIs: Keystone auth, a multi-port gateway on OpenStack default ports, specialized Nova/Neutron/Glance/Cinder/Heat/Swift/Ironic/Octavia handlers, and schema-complete coverage for the remaining catalog services (Yoga → Dalmatian).
Clone this repository (api-gateway nginx config and lab TLS files are bind-mounted
from ./docker/), then pull and run the published runtime image — no local app
build:
git clone https://github.com/inecs/openstack-api-simulator.git
cd openstack-api-simulator
docker compose -f docker-compose.release.yml up -d --wait
# or: make release-up
curl -sf http://127.0.0.1:5000/health/ready
# Optional full synthetic cloud (~1000 servers)
make release-seed PROFILE=demoImage: inecs/openstack-api-simulator
(publish with make release when ready).
cp .env.example .env
docker compose up -d --build --wait
# Optional full synthetic cloud (~1000 servers)
make seed-demo
# Full multi-service smoke
make smoke- Console: http://localhost:5000/
- OpenAPI: http://localhost:5000/docs
More detail: Getting started.
helm upgrade --install os-sim ./helm/openstack-api-simulator \
-n openstack-sim --create-namespace \
-f ./helm/openstack-api-simulator/values-ingress-example.yaml \
--set certManager.email=you@example.com \
--set ingress.hosts[0].host=os-sim.example.com \
--set ingress.tls[0].hosts[0]=os-sim.example.com \
--set secret.ticketSigningKey="$(openssl rand -hex 32)" \
--set postgresql.auth.password="$(openssl rand -hex 16)"Details: Kubernetes / Helm · chart README:
helm/openstack-api-simulator.
Minimal ClusterIP + port-forward:
helm upgrade --install os-sim ./helm/openstack-api-simulator \
-n openstack-sim --create-namespace \
--set secret.ticketSigningKey="$(openssl rand -hex 32)" \
--set seed.enabled=true --set seed.profile=minimal
kubectl -n openstack-sim port-forward \
svc/os-sim-openstack-api-simulator-gateway \
5000:5000 8774:8774 9696:9696 9292:9292 8776:8776Minimal seed (default on startup):
| User | Password | Project | Role |
|---|---|---|---|
admin |
secret |
admin / demo |
admin |
demo |
secret |
demo |
member |
Demo cloud (Data drawer → Load demo cloud / make seed-demo): ~1000 servers,
16 hypervisors, 3 AZs, 5 projects, networks/ports/FIPs, 600 volumes, LBs, stacks,
Ironic, Swift.
| User | Password | Typical projects |
|---|---|---|
admin |
secret |
all projects |
ops |
secret |
production, staging |
developer |
secret |
development, staging |
demo / auditor |
secret |
demo / production |
Domain: Default.
curl -i -X POST http://localhost:5000/v3/auth/tokens \
-H 'Content-Type: application/json' \
-d '{
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "demo",
"domain": {"name": "Default"},
"password": "secret"
}
}
},
"scope": {
"project": {"name": "demo", "domain": {"name": "Default"}}
}
}
}'
# Use X-Subject-Token as X-Auth-Token.
curl -sH "X-Auth-Token: $TOKEN" -H "OpenStack-API-Version: compute 2.79" \
http://localhost:8774/v2.1/servers/detail
curl -sH "X-Auth-Token: $TOKEN" http://localhost:9696/v2.0/routersDocumentation is bilingual. Use the Language / Язык switcher at the top of each page, or open the Russian root README.ru.md. Index: docs/README.md · docs/ru/README.md.
| Guide | Topic |
|---|---|
| Getting started | First lab session (Compose) |
| Kubernetes / Helm | Cluster install, Ingress, cert-manager |
| Configuration | Env vars, Compose, Helm knobs |
| Authentication | Keystone tokens & seeded users |
| Ports | Real OpenStack API ports (1:1 host publish) |
| API surface | Specialized vs schema packs |
| API versions | Yoga → Dalmatian series |
| API coverage | Generated operation counts |
| Seed profiles | minimal / demo |
| Clients | SDK / CLI |
| Web UI | Console drawers |
| Operations | Day-2, release, reseed |
| Architecture | Components & request path |
| Security | Lab threat model |
| Observability | Health & logs |
| Troubleshooting | Common failures |
| FAQ | Short Q&A |
| Domains | Per-service notes |
| Examples | Client cookbooks |
| Hypervisor-lab | Pulumi API coverage (all ops × series) |
Suite under pulumi-tests/ maximises pulumi_openstack,
then HTTP-probes pack ops with non-empty checks for yoga → dalmatian.
make pulumi-tests # from repo root
# or:
cd pulumi-tests && make test-pulumi-smoke && make test-pulumi
open pulumi-tests/reports/pulumi-report.htmlDetails: docs/hypervisor-lab.md.
Latest full-matrix result (2026-07-18): HTTP 6514 / 6514, http_critical=0
(yoga→dalmatian). Pytest / smoke map: docs/operations.md — Testing.
Full matrix of real OpenStack default ports published 1:1 (Keystone :5000,
Nova :8774, Neutron :9696, Glance :9292, Cinder :8776, …): see
docs/ports.md.
Nginx sets X-OpenStack-Service / X-Forwarded-Port. The app rewrites to
/_os/<service>/… so /v3 (Keystone vs Cinder) and /v1 (Heat vs Swift) do not collide.
Contract packs under contracts/openstack/<series>/ drive 1300+ operations
across 28 services (Yoga → Dalmatian). The schema engine mounts every pack
operation; specialized routers keep stateful happy-paths.
| Tooling | Purpose |
|---|---|
PYTHONPATH=tools python3 tools/os_api_inventory/generate_packs.py |
Regenerate series packs |
python3 tools/os_api_inventory/coverage_report.py |
Write docs/api_coverage.md |
python3 examples/python/openstack_smoke.py |
Multi-port GET smoke |
python3 examples/python/openstack_surface_probe.py |
Full lifecycle probe |
WebUI: Environment → OpenStack API pack — activate series and microversions.
This is a lab surface-complete simulator (API-ref shaped responses), not bit-identical upstream OpenStack.
Console drawers, request parameters, and screenshots: Web UI.
Apache-2.0 — see LICENSE.
