Initial commit: stateful OpenStack API laboratory simulator.

Ship Keystone auth, multi-service handlers (Yoga→Dalmatian), Compose/Helm
packaging, API contract packs, and pytest/Pulumi coverage labs.
This commit is contained in:
2026-07-18 04:26:48 +03:00
commit 6033967e6a
509 changed files with 464404 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
**Language / Язык:** [English](../README.md) | [Русский](README.md)
# Документация
Руководства по лабораторному симулятору OpenStack API. Переключайте язык
заголовком на каждой странице. Английские оригиналы — в родительском
каталоге [`docs/`](../README.md).
| Руководство | Тема |
|---|---|
| [Быстрый старт](getting-started.md) | Первая лабораторная сессия (Compose) |
| [Kubernetes / Helm](kubernetes.md) | Установка в кластер, Ingress, cert-manager |
| [Конфигурация](configuration.md) | Переменные окружения, Compose, Helm |
| [Аутентификация](authentication.md) | Токены Keystone и seed-пользователи |
| [Порты](ports.md) | Реальные порты API OpenStack (публикация 1:1) |
| [API surface](api-surface.md) | Специализированные vs schema-пакеты |
| [Версии API](api-versions.md) | Серии Yoga → Dalmatian |
| [Покрытие API](api_coverage.md) | Счётчики операций |
| [Seed-профили](seed-profiles.md) | `minimal` / `demo` |
| [Клиенты](clients.md) | SDK / CLI |
| [Web UI](web-ui.md) | Консоль и drawers |
| [Эксплуатация](operations.md) | Day-2, релиз, reseed |
| [Архитектура](architecture.md) | Компоненты и путь запроса |
| [Безопасность](security.md) | Threat model лаборатории |
| [Наблюдаемость](observability.md) | Health и логи |
| [Устранение неполадок](troubleshooting.md) | Типичные сбои |
| [FAQ](faq.md) | Краткие ответы |
| [Домены](domains/README.md) | Заметки по сервисам |
| [Примеры](examples/overview.md) | Cookbook'и клиентов |
| [Hypervisor-lab](hypervisor-lab.md) | Pulumi-покрытие API (все ops × серии) |
Исполняемые cookbook'и: [`examples/`](../../examples/README.ru.md).
Интеграционные сьюты: [`pulumi-tests/`](../../pulumi-tests/README.ru.md).
Назад к [README](../../README.ru.md).
+44
View File
@@ -0,0 +1,44 @@
**Language / Язык:** [English](../api-surface.md) | [Русский](api-surface.md)
# Поверхность API
## Surface-complete пакеты
Каждый пакет серии OpenStack перечисляет операции **method + path**. При старте
каждая уникальная пара `(method, path)` регистрируется как отдельный маршрут FastAPI
(`os-contract:…`), в стиле Proxmox. Stateful-обработчики из специализированных
модулей ищутся через `HandlerRegistry`; всё остальное уходит в schema-движок
(лабораторный JSON `os_api_objects`).
| Series | Services | Operations (approx.) |
|---|---|---|
| Yoga | 28 | ~1060 |
| Antelope | 28 | ~1108 |
| Caracal | 28 | ~1196 |
| Dalmatian | 28 | ~1357 |
Авторитетные числа: [api_coverage.md](api_coverage.md).
## Handlers vs schema fallback
| Слой | Сервисы / ресурсы |
|---|---|
| **Специализированные handlers** | Keystone tokens/catalog, Nova servers/flavors/keypairs/…, Neutron nets/ports/…, Glance images, Cinder volumes, Heat stacks, Swift, Ironic nodes, Octavia LBs, Placement RPs |
| **Schema fallback** | Остальные коллекции пакета (Barbican, Manila, Designate, Magnum, …), включая вложенные пути |
## Microversions
Заголовки вроде `OpenStack-API-Version: compute 2.79` и
`X-OpenStack-Nova-API-Version` принимаются и фильтруются по метаданным пакета.
Переопределения можно задать в Web UI Environment drawer.
## Actions
Nova-style `POST /servers/{id}/action` и аналогичные ops пакета `kind=action`
обрабатываются schema/action-путём (обновление power state для типичных actions).
## Ошибки
Ошибки в форме OpenStack (`OpenStackError`) с `code`, `title`, `message`.
Неизвестные маршруты, отсутствующие в активном contract-пакете, возвращают
стандартный FastAPI `404`.
+56
View File
@@ -0,0 +1,56 @@
**Language / Язык:** [English](../api-versions.md) | [Русский](api-versions.md)
# Версии API (series packs)
Симулятор поставляет **четыре** серии релизов OpenStack как contract-пакеты:
| Series | OpenStack release family | Cold-start env |
|---|---|---|
| `yoga` | Yoga | `OPENSTACK_SERIES=yoga` |
| `antelope` | Antelope | `OPENSTACK_SERIES=antelope` |
| `caracal` | Caracal | `OPENSTACK_SERIES=caracal` |
| `dalmatian` | Dalmatian (default) | `OPENSTACK_SERIES=dalmatian` |
## Cold start
Compose / процесс:
```bash
OPENSTACK_SERIES=caracal docker compose up -d
```
Helm:
```bash
--set config.openstackSeries=yoga
```
## Hot-swap
```bash
curl -X POST http://127.0.0.1:5000/ui/api/openstack/contracts/activate \
-H 'Content-Type: application/json' \
-d '{"series":"dalmatian"}'
```
Или Web UI → Environment → OpenStack API pack → Activate.
Hot-swap перемонтирует schema-маршруты (`remount_schema_services`) без пересборки
образа.
## Структура пакета
```
contracts/openstack/<series>/
manifest.json
keystone/api.json
nova/api.json
neutron/api.json
```
Перегенерация:
```bash
PYTHONPATH=tools python3 tools/os_api_inventory/generate_packs.py
```
+64
View File
@@ -0,0 +1,64 @@
**Language / Язык:** [English](../api_coverage.md) | [Русский](api_coverage.md)
# Покрытие OpenStack API — dalmatian
Сгенерировано из `contracts/openstack/dalmatian/manifest.json`.
- **Services:** 28
- **Operations:** 1357
- **Checksum:** `5d8f32baa835db2b556b6f33ac3c1b67b74db8194f00ce7d6eb8c59e3bbd7063`
- **Generated at:** 2026-07-16T00:28:30Z
## Дельты серий
| Series | Major | Operations |
|---|---:|---:|
| Antelope | 7 | 1108 |
| Caracal | 8 | 1196 |
| Dalmatian | 9 | 1357 |
| Yoga | 6 | 1060 |
Более старые серии опускают пути, добавленные позже (`tools/os_api_inventory/series_deltas.py`),
и используют более низкие потолки microversion. Примените пакет в Environment drawer для hot-swap.
Surface-complete означает, что каждая операция пакета смонтирована schema-движком
(специализированные роутеры по-прежнему выигрывают на пересекающихся stateful-путях).
| Service | Type | Port | Operations | Microversions |
|---|---|---:|---:|---|
| adjutant | admin-logic | 5050 | 24 | — |
| aodh | alarming | 8042 | 19 | — |
| barbican | key-manager | 9311 | 25 | — |
| blazar | reservation | 1234 | 19 | — |
| cinder | volumev3 | 8776 | 98 | 3.03.70 |
| cloudkitty | rating | 8889 | 25 | — |
| designate | dns | 9001 | 37 | — |
| freezer | backup | 9090 | 31 | — |
| glance | image | 9292 | 39 | — |
| heat | orchestration | 8004 | 38 | — |
| heat-cfn | cloudformation | 8000 | 8 | — |
| ironic | baremetal | 6385 | 58 | 1.11.90 |
| keystone | identity | 5000 | 77 | — |
| magnum | container-infra | 9511 | 25 | — |
| manila | sharev2 | 8786 | 50 | 2.02.82 |
| masakari | instance-ha | 15868 | 19 | — |
| mistral | workflowv2 | 8989 | 37 | — |
| neutron | network | 9696 | 290 | — |
| nova | compute | 8774 | 124 | 2.12.96 |
| octavia | load-balancer | 9876 | 74 | — |
| placement | placement | 8003 | 30 | 1.01.39 |
| swift | object-store | 8080 | 10 | — |
| tacker | nfv-orchestration | 9890 | 30 | — |
| trove | database | 8779 | 31 | — |
| vitrage | rca | 8999 | 30 | — |
| watcher | infra-optim | 9322 | 49 | — |
| zaqar | messaging | 8888 | 27 | — |
| zun | container | 9517 | 33 | — |
## Минимумы core
| Service | Required | Actual |
|---|---:|---:|
| keystone | 40 | 77 (OK) |
| neutron | 70 | 290 (OK) |
| nova | 70 | 124 (OK) |
+58
View File
@@ -0,0 +1,58 @@
**Language / Язык:** [English](../architecture.md) | [Русский](architecture.md)
# Архитектура
## Компоненты
```
┌─────────────┐ ┌──────────────────┐ ┌────────────┐
│ Clients │────▶│ api-gateway │────▶│ simulator │
│ SDK / CLI │ │ nginx multi-port│ │ FastAPI │
│ Web UI │ │ :5000,:8774,… │ │ :8080 │
└─────────────┘ └──────────────────┘ └─────┬──────┘
┌─────▼──────┐
│ PostgreSQL │
└────────────┘
```
| Компонент | Ответственность |
|---|---|
| **api-gateway** | Публикация стандартных портов OpenStack; выставление `X-OpenStack-Service` / `X-Forwarded-Port` |
| **ServiceDispatchMiddleware** | Переписывание в `/_os/<service>/…` |
| **Специализированные роутеры** | Stateful Keystone, Nova, Neutron, Glance, Cinder, Heat, Swift, Ironic, Octavia, Placement |
| **Schema engine** | Surface-complete ops из `contracts/openstack/<series>/` |
| **PostgreSQL** | Identity, IaaS-таблицы, generic store `os_api_objects` |
## Жизненный цикл запроса
1. Клиент обращается, например, к `http://host:8774/v2.1/servers`.
2. Gateway добавляет service headers.
3. Dispatch монтирует запрос под `/_os/nova/…`.
4. Выполняется специализированный Nova handler **или** schema pack operation.
5. Чтение/запись идут в PostgreSQL (типизированные таблицы или `os_api_objects`).
## Contract-пакеты
- Сгенерированный inventory → `contracts/openstack/{yoga,antelope,caracal,dalmatian}/`
- Hot-swap через Web UI / `/ui/api/openstack/contracts/activate`
- Отчёт покрытия: [api_coverage.md](api_coverage.md)
## Seed-профили
| Profile | Содержимое |
|---|---|
| `minimal` | Небольшой Keystone + несколько IaaS-ресурсов |
| `demo` | ~1000 servers, multi-project topology, nested collections |
Подробности: [seed-profiles.md](seed-profiles.md).
## Модель развёртывания
| Mode | Gateway | DB |
|---|---|---|
| Compose | nginx container | bundled Postgres |
| Helm | nginx Deployment + multi-port Service | bundled StatefulSet или external |
| Ingress | TLS terminates at Ingress → gateway:5000 | — |
См. [kubernetes.md](kubernetes.md).
+80
View File
@@ -0,0 +1,80 @@
**Language / Язык:** [English](../authentication.md) | [Русский](authentication.md)
# Аутентификация
Симулятор реализует **Keystone v3** password-аутентификацию и project scoping
(лабораторное подмножество).
## Password auth
```http
POST /v3/auth/tokens
Content-Type: application/json
{
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "admin",
"domain": {"name": "Default"},
"password": "secret"
}
}
},
"scope": {
"project": {"name": "demo", "domain": {"name": "Default"}}
}
}
}
```
Ответ:
- Заголовок **`X-Subject-Token`** — используйте как **`X-Auth-Token`** в следующих запросах
- Тело `token.catalog` — endpoints сервисов (порты соответствуют [ports.md](ports.md))
## Seed-принципалы
Пароль для всех пользователей: **`secret`**. Домен: **`Default`**.
### Minimal seed
| Пользователь | Проекты | Роль |
|---|---|---|
| `admin` | `admin`, `demo` | admin |
| `demo` | `demo` | member |
### Demo cloud
| Пользователь | Типичные проекты |
|---|---|
| `admin` | все |
| `ops` | production, staging |
| `developer` | development, staging |
| `demo` / `auditor` | demo / production |
## Unscoped / ошибки
- Нет токена → `401 Unauthorized`
- Неверный пароль → `401`
- Project-scoped API без project scope → `401` с понятным сообщением
## openstacksdk / CLI
```bash
export OS_AUTH_URL=http://127.0.0.1:5000/v3
export OS_USERNAME=admin
export OS_PASSWORD=secret
export OS_PROJECT_NAME=demo
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_IDENTITY_API_VERSION=3
openstack server list
openstack network list
```
Против Helm Ingress задайте `OS_AUTH_URL=https://os-sim.example.com/v3`
(и доверьте сертификат или используйте `--insecure` в лаборатории).
+46
View File
@@ -0,0 +1,46 @@
**Language / Язык:** [English](../clients.md) | [Русский](clients.md)
# Клиенты
## Матрица подключения
| Client | Auth URL | Примечания |
|---|---|---|
| curl | `http://127.0.0.1:5000/v3` | Используйте `X-Subject-Token``X-Auth-Token` |
| openstack CLI | `OS_AUTH_URL=…/v3` | См. [authentication.md](authentication.md) |
| openstacksdk | same | Порты service catalog должны совпадать с gateway |
| Terraform OpenStack provider | `auth_url` | Укажите Keystone; catalog направляет Nova/Neutron |
| Ansible `openstack.*` | clouds.yaml | Те же credentials, что и для CLI |
## Compose (локально)
```bash
export OS_AUTH_URL=http://127.0.0.1:5000/v3
export OS_USERNAME=admin
export OS_PASSWORD=secret
export OS_PROJECT_NAME=demo
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_IDENTITY_API_VERSION=3
```
## Helm / Ingress
```bash
export OS_AUTH_URL=https://os-sim.example.com/v3
# Другие сервисы: port-forward портов gateway или catalog URLs,
# которые ваш Ingress/DNS корректно мапят.
```
Для multi-port доступа без Ingress TCP используйте port-forward gateway Service
(см. [kubernetes.md](kubernetes.md)).
## Примеры в репозитории
| Path | Назначение |
|---|---|
| `examples/python/openstack_smoke.py` | Multi-port GET smoke |
| `examples/python/openstack_conformance.py` | Write-path sample |
| `examples/python/openstack_surface_probe.py` | Полный lifecycle probe пакета |
Cookbook'и: [examples/overview.md](examples/overview.md).
+59
View File
@@ -0,0 +1,59 @@
**Language / Язык:** [English](../configuration.md) | [Русский](configuration.md)
# Конфигурация
## Переменные окружения
| Переменная | По умолчанию | Назначение |
|---|---|---|
| `APP_HOST` | `0.0.0.0` | Адрес привязки |
| `APP_PORT` | `8080` | Внутренний порт FastAPI (не публичный порт Keystone) |
| `DATABASE_URL` | (compose/helm) | PostgreSQL DSN |
| `TICKET_SIGNING_KEY` | lab secret | Материал подписи токенов (ротируйте в общих лабораториях) |
| `LOG_LEVEL` | `INFO` | Уровень логирования |
| `OPENSTACK_SERIES` | `dalmatian` | Серия contract-пакета при холодном старте |
| `REQUEST_ID_HEADER` | `X-Request-ID` | Заголовок корреляции запросов |
| `SEED_PROFILE` | `minimal` | Для `seed_cli` / Helm seed Job (`minimal` / `demo`) |
## Compose
| Файл | Роль |
|---|---|
| `docker-compose.yml` | Dev-стек (build + bind mounts) |
| `docker-compose.release.yml` | Опубликованный Hub-образ |
| `.env` / `.env.example` | Локальные переопределения |
Сервисы:
- **simulator** — FastAPI на внутреннем `8080`
- **api-gateway** — nginx, публикующий реальные порты API OpenStack 1:1 ([ports.md](ports.md))
- **postgres** — `postgres:17.5-bookworm` на хосте `127.0.0.1:5433`
## Helm
См. [kubernetes.md](kubernetes.md) и
[`helm/openstack-api-simulator/values.yaml`](../../helm/openstack-api-simulator/values.yaml).
Важные параметры:
| Value | Назначение |
|---|---|
| `gateway.enabled` | Multi-port nginx (по умолчанию `true`) |
| `config.openstackSeries` | Env `OPENSTACK_SERIES` |
| `seed.profile` | `minimal` / `demo` |
| `postgresql.enabled` | Встроенная БД |
| `secret.ticketSigningKey` | Нужно ротировать для общих кластеров |
## Contract-пакеты
Расположение: `contracts/openstack/<series>/`.
В каждой серии — per-service пакеты `api.json`, потребляемые schema-движком.
Специализированные роутеры (Keystone, Nova, Neutron, …) остаются stateful для happy-path'ов.
## Переопределения Web UI
Environment drawer → **OpenStack API pack**:
- Активация серии (hot remount)
- Переопределение microversion по сервисам
+22
View File
@@ -0,0 +1,22 @@
**Language / Язык:** [English](../../domains/README.md) | [Русский](README.md)
# Домены сервисов OpenStack
Руководства по основным специализированным поверхностям. Pack-only сервисы
(Barbican, Manila, Designate, …) покрываются schema-движком и засеваются в
`os_api_objects` — см. [api-surface.md](../api-surface.md) и
[api_coverage.md](../api_coverage.md).
| Руководство | Сервис | Порт |
|---|---|---|
| [keystone.md](keystone.md) | Identity | 5000 |
| [nova.md](nova.md) | Compute | 8774 |
| [neutron.md](neutron.md) | Network | 9696 |
| [glance.md](glance.md) | Image | 9292 |
| [cinder.md](cinder.md) | Block storage | 8776 |
| [placement.md](placement.md) | Placement | 8003 |
| [heat.md](heat.md) | Orchestration | 8004 |
| [swift.md](swift.md) | Object storage | 8080 |
| [ironic.md](ironic.md) | Bare metal | 6385 |
| [octavia.md](octavia.md) | Load balancer | 9876 |
| [schema-services.md](schema-services.md) | Остальные pack-сервисы | разные |
+10
View File
@@ -0,0 +1,10 @@
**Language / Язык:** [English](../../domains/cinder.md) | [Русский](cinder.md)
# Cinder (block storage)
Порт **8776**. Пути под `/v3/``/v3/{project_id}/…`).
## Stateful
CRUD томов. Demo cloud: ~600 volumes (`in-use` / `available`).
Snapshots, types, backups и связанные коллекции — pack/schema-backed.
+10
View File
@@ -0,0 +1,10 @@
**Language / Язык:** [English](../../domains/glance.md) | [Русский](glance.md)
# Glance (image)
Порт **9292**. Пути под `/v2/`.
## Stateful
Список/просмотр/создание/обновление/удаление образов; публичные и project-owned
images. Members/tags обслуживаются из `os_api_objects` в demo seed.
+11
View File
@@ -0,0 +1,11 @@
**Language / Язык:** [English](../../domains/heat.md) | [Русский](heat.md)
# Heat (orchestration)
Порт **8004**. Пути `/v1/{tenant_id}/…`.
## Stateful
Стеки в `os_stacks`. Demo seed добавляет stacks плюс вложенные строки
`stack_resource` / `stack_event` / `software_config` / `software_deployment`
для pack GET-probe'ов.
+10
View File
@@ -0,0 +1,10 @@
**Language / Язык:** [English](../../domains/ironic.md) | [Русский](ironic.md)
# Ironic (bare metal)
Порт **6385**.
## Stateful
Nodes в `os_nodes`. Demo seed создаёт пул ironic-нод; ports/chassis/
allocations — schema-backed примеры.
+21
View File
@@ -0,0 +1,21 @@
**Language / Язык:** [English](../../domains/keystone.md) | [Русский](keystone.md)
# Keystone (identity)
Порт **5000**. Пути под `/v3/`.
## Реализовано (lab)
- `POST /v3/auth/tokens` — password auth, project scope
- Catalog с multi-port endpoints
- Projects, users, roles, role assignments (seed + CRUD через pack/schema)
- Domains (`Default`)
## Seed
Профили minimal и demo создают домен `Default`, роли `admin`/`member` и
пользователей, описанных в [authentication.md](../authentication.md).
## Примечания
Federation, application credentials и полный policy engine вне scope.
+16
View File
@@ -0,0 +1,16 @@
**Language / Язык:** [English](../../domains/neutron.md) | [Русский](neutron.md)
# Neutron (network)
Порт **9696**. Пути под `/v2.0/`.
## Stateful-ресурсы
Networks, subnets, ports, routers, security groups/rules, floating IPs, agents.
## Schema / seeded-расширения
QoS, trunks, RBAC, address scopes, subnet pools, conntrack helpers, port
forwardings, примеры FWaaS/VPNaaS/BGP VPN в demo seed.
Demo добавляет несколько nets/SGs/routers на проект для реалистичной плотности списков.
+21
View File
@@ -0,0 +1,21 @@
**Language / Язык:** [English](../../domains/nova.md) | [Русский](nova.md)
# Nova (compute)
Порт **8774**. Пути под `/v2.1/`.
## Stateful-ресурсы
Servers, flavors, keypairs, server groups, AZ, hypervisors, aggregates,
services, migrations, volume/interface attachments, metadata, tags,
instance actions, consoles (лабораторные URL).
## Demo cloud
~1000 серверов по проектам, metadata/`_tags`, attachments, связанные с volumes
и ports.
## Microversions
Отправляйте `OpenStack-API-Version: compute X.Y` или legacy-заголовок Nova.
Применяются ограничения пакета.
+10
View File
@@ -0,0 +1,10 @@
**Language / Язык:** [English](../../domains/octavia.md) | [Русский](octavia.md)
# Octavia (load balancer)
Порт **9876**. Пути под `/v2/lbaas/…`.
## Stateful
Load balancers в `os_loadbalancers`. Listeners/pools/healthmonitors/providers/
flavors обслуживаются из `os_api_objects` (demo seed их заполняет).
+10
View File
@@ -0,0 +1,10 @@
**Language / Язык:** [English](../../domains/placement.md) | [Русский](placement.md)
# Placement
Порт **8003**.
## Поведение в лаборатории
- `GET /resource_providers` — из demo `os_api_objects` (или fallback stub)
- `GET/PUT /allocations/{consumer_uuid}` — сохраняемые allocations с lab fallback
+14
View File
@@ -0,0 +1,14 @@
**Language / Язык:** [English](../../domains/schema-services.md) | [Русский](schema-services.md)
# Schema-backed сервисы
Эти проекты в основном обслуживаются contract-пакетами + `os_api_objects`
(demo seed вставляет несколько строк на тип ресурса):
Barbican, Manila, Designate, Magnum, Zun, Trove, Mistral, Aodh, CloudKitty,
Freezer, Blazar, Vitrage, Masakari, Tacker, Adjutant, Watcher, Zaqar, Heat-CFN.
Порты: [ports.md](../ports.md). Операции: [api_coverage.md](../api_coverage.md).
CRUD lifecycle проверяется через `examples/python/openstack_surface_probe.py`
и `tests/openstack/conformance/`.
+10
View File
@@ -0,0 +1,10 @@
**Language / Язык:** [English](../../domains/swift.md) | [Русский](swift.md)
# Swift (object storage)
Порт **8080** на **gateway** (внутренний simulator остаётся на 8080 за nginx).
## Stateful
Accounts/containers/objects в таблицах `os_swift_*`. Demo seed создаёт
контейнеры `images` / `backups` / `artifacts` с readme-объектом на проект.
+19
View File
@@ -0,0 +1,19 @@
**Language / Язык:** [English](../../examples/ansible.md) | [Русский](ansible.md)
# Ansible (openstack.cloud)
## Cookbook (один stack)
[`examples/ansible/playbook.yml`](../../../examples/ansible/playbook.yml) —
`ansible.builtin.uri` против Keystone/Nova/Neutron/Glance.
```bash
make up && make seed-demo
cd examples/ansible
ansible-playbook -i inventory.ini playbook.yml
```
Auth: `http://127.0.0.1:5000/v3`, `admin` / `secret`, проект `demo`.
Интеграционное покрытие API теперь в [`pulumi-tests/`](../../../pulumi-tests/)
(Pulumi / `pulumi_openstack`). См. [hypervisor-lab.md](../hypervisor-lab.md).
+21
View File
@@ -0,0 +1,21 @@
**Language / Язык:** [English](../../examples/openstack-cli.md) | [Русский](openstack-cli.md)
# OpenStack CLI
Типовой набор переменных окружения и команд против локального gateway:
```bash
export OS_AUTH_URL=http://127.0.0.1:5000/v3
export OS_USERNAME=admin
export OS_PASSWORD=secret
export OS_PROJECT_NAME=demo
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_IDENTITY_API_VERSION=3
openstack token issue
openstack server list
openstack network list
openstack volume list
openstack stack list
```
+53
View File
@@ -0,0 +1,53 @@
**Language / Язык:** [English](../../examples/overview.md) | [Русский](overview.md)
# Обзор примеров клиентов
Исполняемые скрипты — в [`examples/`](../../../examples/).
Лаборатория покрытия API на Pulumi — в [`pulumi-tests/`](../../../pulumi-tests/).
## Краткая справка
| Path | Tool | Purpose |
|---|---|---|
| `examples/python/openstacksdk_cookbook.py` | openstacksdk | net + server + volume lifecycle |
| `examples/ansible/playbook.yml` | Ansible `uri` | минимальный Keystone/Nova/Neutron |
| `examples/terraform/main.tf` | Terraform | `openstack_compute_instance_v2` + volume |
| `examples/pulumi/` | Pulumi | `pulumi_openstack` Instance + Network |
| `examples/run_iac_stack.sh` | все четыре | последовательный smoke cookbook'ов |
| `pulumi-tests/` | Pulumi | каждая pack-операция × yoga→dalmatian + HTML-отчёт |
## Auth
1. `POST /v3/auth/tokens``X-Subject-Token`
2. Вызовы сервисов с `X-Auth-Token` на нужном [порту](../ports.md)
Лаборатория по умолчанию: `admin` / `secret`, проект `demo`, домен `Default`.
## Cookbook'и
- [Python (requests)](python-requests.md)
- [Python (openstacksdk)](python-openstacksdk.md)
- [Ansible](ansible.md)
- [Terraform](terraform.md)
- [Pulumi](pulumi.md)
- [CLI](openstack-cli.md)
- [Troubleshooting](troubleshooting-clients.md)
## Лаборатория покрытия API (Pulumi)
Полное руководство: [hypervisor-lab.md](../hypervisor-lab.md)
```bash
cd pulumi-tests
make up
make test-pulumi-smoke
make test-pulumi
open reports/pulumi-report.html
```
Probe-скрипты:
| Script | Purpose |
|---|---|
| `examples/python/openstack_smoke.py` | Multi-port GET smoke |
| `examples/python/openstack_surface_probe.py` | Pack operation probe (также используется Pulumi-лабой) |
+30
View File
@@ -0,0 +1,30 @@
**Language / Язык:** [English](../../examples/pulumi.md) | [Русский](pulumi.md)
# Pulumi (pulumi_openstack)
## Cookbook (один stack)
[`examples/pulumi/`](../../../examples/pulumi/) — `pulumi_openstack` Instance,
Network, Subnet.
```bash
make up && make seed-demo
cd examples/pulumi
pulumi stack init dev --secrets-provider passphrase
export PULUMI_CONFIG_PASSPHRASE=lab
pulumi up
pulumi destroy
```
## Лаборатория покрытия (`pulumi-tests`)
[`pulumi-tests/`](../../../pulumi-tests/) — стеки `pulumi_openstack` на каждую
серию, проверка непустых export'ов, затем HTTP-probe pack-операций с
непустыми телами.
```bash
make pulumi-tests
open pulumi-tests/reports/pulumi-report.html
```
См. [hypervisor-lab.md](../hypervisor-lab.md).
+24
View File
@@ -0,0 +1,24 @@
**Language / Язык:** [English](../../examples/python-openstacksdk.md) | [Русский](python-openstacksdk.md)
# Python + openstacksdk
```python
import openstack
conn = openstack.connect(
auth_url="http://127.0.0.1:5000/v3",
project_name="demo",
username="admin",
password="secret",
user_domain_name="Default",
project_domain_name="Default",
)
for server in conn.compute.servers():
print(server.name, server.status)
for network in conn.network.networks():
print(network.name)
```
Убедитесь, что порты из service catalog доступны (Compose gateway или Helm
port-forward). См. [clients.md](../clients.md).
+37
View File
@@ -0,0 +1,37 @@
**Language / Язык:** [English](../../examples/python-requests.md) | [Русский](python-requests.md)
# Python + requests
Минимальный пример password-auth и списка серверов Nova:
```python
import requests
AUTH = "http://127.0.0.1:5000/v3/auth/tokens"
r = requests.post(
AUTH,
json={
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "admin",
"domain": {"name": "Default"},
"password": "secret",
}
},
},
"scope": {
"project": {"name": "demo", "domain": {"name": "Default"}}
},
}
},
)
r.raise_for_status()
token = r.headers["X-Subject-Token"]
headers = {"X-Auth-Token": token}
servers = requests.get("http://127.0.0.1:8774/v2.1/servers", headers=headers)
print(servers.status_code, len(servers.json().get("servers", [])))
```
+21
View File
@@ -0,0 +1,21 @@
**Language / Язык:** [English](../../examples/terraform.md) | [Русский](terraform.md)
# Terraform (openstack provider)
## Cookbook (один stack)
[`examples/terraform/main.tf`](../../../examples/terraform/main.tf) —
**`terraform-provider-openstack/openstack`**.
```bash
make up && make seed-demo
cd examples/terraform
terraform init
terraform apply
terraform destroy
```
По умолчанию: `auth_url = http://127.0.0.1:5000/v3`, `admin` / `secret`, проект `demo`.
Интеграционное покрытие API — в [`pulumi-tests/`](../../../pulumi-tests/)
(Pulumi / `pulumi_openstack`). См. [hypervisor-lab.md](../hypervisor-lab.md).
@@ -0,0 +1,27 @@
**Language / Язык:** [English](../../examples/troubleshooting-clients.md) | [Русский](troubleshooting-clients.md)
# Устранение неполадок клиентов
## Каталог указывает на недоступные хосты
Seed-каталог в некоторых конфигурациях использует `host.docker.internal` или
имена compose-сервисов. Переопределите endpoints или используйте host gateway,
который вы реально публикуете (`127.0.0.1` с port-forward).
## SSL-ошибки против Ingress
Staging-issuers лаборатории не доверенные — используйте `curl -k` /
`OS_INSECURE=true` только в lab.
## Пустой список серверов
Неверный project scope или demo не загружен. Проверьте:
```bash
openstack project list
make seed-demo
```
## Microversion отклонён
Понизьте запрошенную compute microversion или сбросьте переопределения в Web UI.
+39
View File
@@ -0,0 +1,39 @@
**Language / Язык:** [English](../faq.md) | [Русский](faq.md)
# FAQ
## Это настоящее OpenStack cloud?
Нет. Это **surface-complete API laboratory**: состояние в PostgreSQL,
ответы в форме API-ref, без оркестрации гипервизора.
## Какой релиз использовать?
По умолчанию пакет **Dalmatian**. Переключайте через `OPENSTACK_SERIES` или Web UI.
См. [api-versions.md](api-versions.md).
## Compose vs Helm?
| Need | Use |
|---|---|
| Local hack / CI on Docker | Compose |
| Cluster + Ingress TLS | Helm ([kubernetes.md](kubernetes.md)) |
## Зачем так много портов?
Service catalog OpenStack ожидает отдельные endpoints. api-gateway публикует
[реальную матрицу портов по умолчанию](ports.md) **один в один** (без смещения на хосте).
## Demo cloud стёр мои ресурсы
Lifecycle-тесты и reseed очищают lab tables. Перезагрузите через `make seed-demo`.
## Можно ли направить Terraform / Ansible сюда?
Да — используйте Keystone URL и seed credentials. Ожидайте lab limitations
(policy, async workflows, Ceph и т.д.). См. [clients.md](clients.md).
## Где Helm chart?
[`helm/openstack-api-simulator`](../../helm/openstack-api-simulator/README.ru.md) — руководство в
[kubernetes.md](kubernetes.md).
+123
View File
@@ -0,0 +1,123 @@
**Language / Язык:** [English](../getting-started.md) | [Русский](getting-started.md)
# Быстрый старт
Сквозная первая лабораторная сессия на Docker Compose. Для Kubernetes см.
[kubernetes.md](kubernetes.md).
## Требования
- Docker / Docker Compose
- Python 3.13+ (опционально, для smoke-скриптов на хосте)
- `curl` или OpenStack CLI / `openstacksdk`
## Выберите путь
| Путь | Когда |
|---|---|
| **1a. Опубликованный образ** | Лаборатория с Hub-образом (`docker-compose.release.yml`; нужен checkout репо для mount gateway/TLS) |
| **1b. Development checkout** | Будете менять код / пакеты |
| **Helm** | Установка в кластер — [kubernetes.md](kubernetes.md) |
## 1a. Опубликованный образ (Docker Hub)
Нужен **git checkout** этого репозитория: Compose монтирует
`./docker/gateway` и `./docker/tls` в nginx gateway. Контейнер симулятора
берётся с Docker Hub (локальная сборка приложения не нужна).
```bash
git clone https://github.com/inecs/openstack-api-simulator.git
cd openstack-api-simulator
docker compose -f docker-compose.release.yml up -d --wait
# или: make release-up
```
Образ: [`inecs/openstack-api-simulator`](https://hub.docker.com/r/inecs/openstack-api-simulator).
Тег при необходимости: `IMAGE_TAG=0.1.0`.
## 1b. Development checkout
```bash
cp .env.example .env
docker compose up -d --build --wait
```
## 2. Дождитесь готовности
```bash
curl -sf http://127.0.0.1:5000/health/ready
```
## 3. Загрузите seed-профиль
Minimal seed выполняется при первом старте. Опционально — полное синтетическое облако:
```bash
make seed-demo
# или
docker compose exec simulator python -m app.openstack.seed_cli --profile demo
```
Профили: [seed-profiles.md](seed-profiles.md).
## 4. Аутентификация (Keystone)
```bash
export OS_AUTH_URL=http://127.0.0.1:5000/v3
TOKEN=$(curl -si -X POST "$OS_AUTH_URL/auth/tokens" \
-H 'Content-Type: application/json' \
-d '{
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "admin",
"domain": {"name": "Default"},
"password": "secret"
}
}
},
"scope": {
"project": {"name": "demo", "domain": {"name": "Default"}}
}
}
}' | awk -F': ' 'tolower($1)=="x-subject-token"{print $2}' | tr -d '\r')
echo "token=$TOKEN"
```
## 5. Вызовы Nova / Neutron
```bash
curl -sH "X-Auth-Token: $TOKEN" http://127.0.0.1:8774/v2.1/servers/detail | head -c 400
curl -sH "X-Auth-Token: $TOKEN" http://127.0.0.1:9696/v2.0/networks
```
## 6. Откройте Web UI
[http://localhost:5000/](http://localhost:5000/) — консоль, Environment drawer
(серия OpenStack pack + microversions), Data drawer (загрузка/выгрузка demo cloud).
## 7. Smoke / conformance
```bash
make smoke
python3 examples/python/openstack_smoke.py
python3 examples/python/openstack_conformance.py
```
## Готово, когда…
- `/health/ready` возвращает 200
- Keystone выдаёт `X-Subject-Token`
- списки Nova/Neutron содержат seed-ресурсы
- (опционально) demo cloud показывает ~1000 серверов
## Дальше
- [Порты](ports.md) — полная матрица портов сервисов
- [Покрытие API](api_coverage.md) — операции пакетов по сериям
- [Клиенты](clients.md) — openstacksdk / CLI
- [Kubernetes / Helm](kubernetes.md)
- [Hypervisor-lab](hypervisor-lab.md) — Pulumi-покрытие API (все ops × серии)
- [Эксплуатация](operations.md)
+33
View File
@@ -0,0 +1,33 @@
**Language / Язык:** [English](../hypervisor-lab.md) | [Русский](hypervisor-lab.md)
# Лаборатория покрытия Pulumi OpenStack
Сьют в [`pulumi-tests/`](../../pulumi-tests/): максимально **`pulumi_openstack`**,
затем HTTP-probe pack-операций с проверкой **непустых** ответов для серий
**yoga → dalmatian**.
## Быстрый старт
```bash
make pulumi-tests # из корня (полный сьют)
make test-pulumi-smoke # быстрый режим
```
Или:
```bash
cd pulumi-tests
make up && make build
make test-pulumi
open reports/pulumi-report.html
```
## Ход (на серию)
1. Активация pack серии
2. Pulumi Automation API → `programs/os_coverage` (`pulumi_openstack`)
3. Каждый export стека должен быть непустым
4. HTTP-probe pack-операций; непустые тела на успешных GET/POST
5. Destroy; HTML + JUnit
См. [`pulumi-tests/README.ru.md`](../../pulumi-tests/README.ru.md).
+184
View File
@@ -0,0 +1,184 @@
**Language / Язык:** [English](../kubernetes.md) | [Русский](kubernetes.md)
# Kubernetes / Helm
Развёртывание опубликованного runtime-образа с Docker Hub чартом
[`helm/openstack-api-simulator`](../../helm/openstack-api-simulator/README.ru.md).
Образ: [`inecs/openstack-api-simulator`](https://hub.docker.com/r/inecs/openstack-api-simulator)
Чарт зеркалирует Docker Compose:
| Компонент | Роль |
|---|---|
| **simulator** Deployment | FastAPI-приложение на `:8080` |
| **api-gateway** Deployment | nginx multi-port шлюз OpenStack |
| **PostgreSQL** StatefulSet | Встроенный Postgres 17 (опционально) |
| **migrate** initContainer | Идемпотентные миграции схемы |
| **seed** Job (опционально) | Лабораторные данные `minimal` или `demo` |
## Требования
- Kubernetes 1.27+ (или аналог)
- Helm 3.14+
- Для Ingress TLS: [Ingress NGINX](https://kubernetes.github.io/ingress-nginx/) и
[cert-manager](https://cert-manager.io/)
Пример установки cert-manager:
```bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml
```
## Быстрая установка (Hub release + Ingress + Let's Encrypt)
Из git checkout этого репозитория:
```bash
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)"
```
Что происходит:
1. Скачивается `inecs/openstack-api-simulator:0.1.0`.
2. Устанавливается PostgreSQL 17 (`postgres:17.5-bookworm`).
3. Выполняются миграции схемы в init-контейнере (идемпотентно).
4. Засевается профиль **demo** (`seed.enabled=true`, ~1000 серверов).
5. Разворачивается nginx **api-gateway** со стандартными портами OpenStack (5000, 8774, 9696, …).
6. Создаются ресурсы `ClusterIssuer` (`letsencrypt-prod` / `letsencrypt-staging`).
7. Создаётся Ingress → gateway `:5000` (Keystone + Web UI) с TLS.
DNS для `os-sim.example.com` должен указывать на Ingress controller. Затем:
```bash
kubectl -n openstack-sim get certificate,ingress,pods
curl -sS https://os-sim.example.com/health/ready
open https://os-sim.example.com/
```
Логин по умолчанию: `admin` / `secret` (проект `demo` или `admin`, домен `Default`).
### Сначала staging (рекомендуется)
```bash
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 certManager.useStaging=true \
--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)"
```
Используйте `curl -k` против staging CA. Для production переключите `certManager.useStaging=false`.
## Минимальная установка (ClusterIP + port-forward)
```bash
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:8776
```
| URL | Сервис |
|---|---|
| http://127.0.0.1:5000/ | Keystone + консоль |
| http://127.0.0.1:8774/v2.1/ | Nova |
| http://127.0.0.1:9696/v2.0/ | Neutron |
Полная матрица портов: [ports.md](ports.md).
## Внешний PostgreSQL
```bash
helm upgrade --install os-sim ./helm/openstack-api-simulator \
-n openstack-sim --create-namespace \
--set postgresql.enabled=false \
--set secret.ticketSigningKey="$(openssl rand -hex 32)" \
--set secret.databaseUrl='postgresql://user:pass@pg.example.com:5432/openstack_simulator'
```
Или `secret.existingSecret` с ключами `DATABASE_URL` и `TICKET_SIGNING_KEY`.
## Как работает api-gateway
Та же модель, что и в Compose (`docker/gateway/openstack-ports.conf`):
1. Клиент подключается к **порту сервиса** (например Nova `8774`).
2. nginx выставляет `X-OpenStack-Service` и `X-Forwarded-Port`.
3. FastAPI переписывает путь в `/_os/<service>/…`, чтобы `/v3` (Keystone vs Cinder) не конфликтовал.
Ingress (если включён) обслуживает **Keystone/UI на порту 5000**. Для Nova/Neutron
извне кластера:
- `kubectl port-forward` дополнительных портов, или
- expose `*-gateway` как `LoadBalancer` / `NodePort` (`gateway.service.type`), или
- дополнительные Ingress rules / TCP-сервисы для этих портов.
## Как выпускается TLS
При `certManager.enabled=true` и `certManager.createClusterIssuer=true` чарт
создаёт ACME `ClusterIssuer` (HTTP-01). Шаблон Ingress добавляет:
```yaml
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- secretName: openstack-api-simulator-tls
hosts: [os-sim.example.com]
```
Чарт **не** устанавливает cert-manager или Ingress controller.
## Эксплуатация
```bash
# логи
kubectl -n openstack-sim logs -l app.kubernetes.io/component=simulator -f
kubectl -n openstack-sim logs -l app.kubernetes.io/component=gateway -f
# reseed minimal
kubectl -n openstack-sim exec deploy/os-sim-openstack-api-simulator -- \
python -m app.openstack.seed_cli --profile minimal
# reseed demo cloud
kubectl -n openstack-sim exec deploy/os-sim-openstack-api-simulator -- \
python -m app.openstack.seed_cli --profile demo
# активировать серию OpenStack pack
kubectl -n openstack-sim set env deploy/os-sim-openstack-api-simulator \
OPENSTACK_SERIES=caracal
# затем перезапустить pod / helm upgrade с --set config.openstackSeries=caracal
# удаление
helm -n openstack-sim uninstall os-sim
```
## Справка по values
См. [`helm/openstack-api-simulator/values.yaml`](../../helm/openstack-api-simulator/values.yaml)
и [README чарта](../../helm/openstack-api-simulator/README.ru.md).
Связанные документы:
- [Быстрый старт](getting-started.md) — путь Compose
- [Эксплуатация](operations.md) — публикация на Docker Hub / day-2
- [Порты](ports.md) — матрица портов OpenStack
- [Seed-профили](seed-profiles.md) — `minimal` / `demo`
- [Безопасность](security.md) — лабораторные учётные данные
+39
View File
@@ -0,0 +1,39 @@
**Language / Язык:** [English](../observability.md) | [Русский](observability.md)
# Наблюдаемость
## Health endpoints
| Path | Значение |
|---|---|
| `/health/live` | Процесс работает |
| `/health/ready` | БД доступна + миграции применены |
Оба доступны на simulator и через gateway (на любом опубликованном порту).
## Request IDs
Заголовок `X-Request-ID` (настраивается через `REQUEST_ID_HEADER`) принимается и
эхом возвращается там, где применяется middleware.
## Логи
Compose:
```bash
make logs
docker compose logs -f simulator api-gateway
```
Helm:
```bash
kubectl logs -l app.kubernetes.io/component=simulator -f
kubectl logs -l app.kubernetes.io/component=gateway -f
```
## Доказательства совместимости / покрытия
- Покрытие пакетов: [api_coverage.md](api_coverage.md)
- Live lifecycle: `examples/python/openstack_surface_probe.py`
- pytest: `tests/openstack/` (включая real-DB conformance)
+117
View File
@@ -0,0 +1,117 @@
**Language / Язык:** [English](../operations.md) | [Русский](operations.md)
# Эксплуатация
## Day-2 команды (Compose)
```bash
make up # start stack
make down # stop stack
make restart
make logs
make db-migrate # idempotent migrations
make seed # minimal OpenStack seed
make seed-demo # demo cloud (~1000 servers)
make smoke # multi-service GET smoke
```
## Миграции
Упорядоченный SQL в `app/db/migrations/` применяется транзакционно.
Повторный запуск `make db-migrate` безопасен. `/health/ready` остаётся недоступным,
пока миграции не применены. Helm выполняет тот же migrate-шаг как initContainer.
## Reseed
```bash
make seed # minimal
make seed-demo # replaces state with demo cloud
```
Или:
```bash
docker compose exec simulator python -m app.openstack.seed_cli --profile demo
```
Reseed **очищает** лабораторные таблицы OpenStack и перезагружает данные. Внешняя
автоматизация с закэшированными UUID ресурсов должна обновить их.
## OpenStack pack series
Cold start (env):
```bash
OPENSTACK_SERIES=caracal docker compose up -d
```
Helm:
```bash
--set config.openstackSeries=yoga
```
Hot-swap (Web UI или API):
```bash
curl -X POST http://127.0.0.1:5000/ui/api/openstack/contracts/activate \
-H 'Content-Type: application/json' \
-d '{"series":"dalmatian"}'
```
Серии: `yoga`, `antelope`, `caracal`, `dalmatian`. Покрытие:
[api_coverage.md](api_coverage.md).
## Перегенерация contract-пакетов
```bash
PYTHONPATH=tools python3 tools/os_api_inventory/generate_packs.py
PYTHONPATH=tools python3 tools/os_api_inventory/coverage_report.py
```
## Резервное копирование состояния лаборатории
PostgreSQL — источник истины. Используйте `pg_dump` / снимки volume.
Контейнеры приложения одноразовые, если volume БД сохранён.
## Публикация на Docker Hub
```bash
docker login
make release
```
| Variable | Default | Meaning |
|---|---|---|
| `DOCKERHUB_USER` | `inecs` | Docker Hub namespace |
| `IMAGE_NAME` | `openstack-api-simulator` | Repository name |
| `VERSION` | from `pyproject.toml` | Image tag |
```bash
make release VERSION=0.2.0
make release-build # local tags only
```
## Kubernetes day-2
См. [kubernetes.md](kubernetes.md) для логов, reseed через `kubectl exec` и
удаления.
## CI лаборатории покрытия API (pulumi-tests)
Pulumi прогоняет каждую pack-операцию по сериям — см.
[hypervisor-lab.md](hypervisor-lab.md).
```bash
make test-pulumi-smoke # from repo root
make test-pulumi
```
Отчёты: `pulumi-tests/reports/pulumi-report.html` и `pulumi-junit.xml`.
## Обновления
1. Pull / build нового тега образа.
2. Примените миграции (автоматически при старте / Helm initContainer).
3. Опционально reseed, если изменилась seed-схема.
4. Повторите `make smoke` или lifecycle probes.
+56
View File
@@ -0,0 +1,56 @@
**Language / Язык:** [English](../ports.md) | [Русский](ports.md)
# Стандартные порты OpenStack в этом симуляторе
Справка: [Firewalls and default ports](https://docs.openstack.org/install-guide/firewalls-default-ports.html).
Это **реальные публичные порты API OpenStack по умолчанию**. Compose и Helm
публикуют их **один в один** на хосте / Service (без смещения): хост `5000`
Keystone, хост `8774` — Nova и т.д. Запускайте стек на отдельном хосте/ВМ,
чтобы эти порты не пересекались с другими лабораторными симуляторами.
Клиенты обращаются к **api-gateway** (nginx) — сервис Compose или Helm
Deployment/Service `*-gateway`. На каждом listen-порту выставляются
`X-OpenStack-Service` и `X-Forwarded-Port`; процесс FastAPI переписывает путь в
`/_os/<service>/…`, чтобы пересекающиеся корни API (`/v3`, `/v1`, …) не конфликтовали.
Типичный auth URL: `http://127.0.0.1:5000/v3` (или HTTPS на `:5000` / `:443`
через gateway).
Список в Helm values: `gateway.service.ports` в
[`helm/openstack-api-simulator/values.yaml`](../../helm/openstack-api-simulator/values.yaml).
| Порт | Сервис | За что отвечает | Основные пути |
|------|--------|-----------------|---------------|
| 5000 | keystone | Identity — токены, проекты, пользователи, роли, service catalog | `/v3/auth/tokens`, `/v3/projects`, … |
| 8774 | nova | Compute — серверы (ВМ), flavors, keypairs, AZ, hypervisors | `/v2.1/servers`, flavors, keypairs, AZ, hypervisors, … |
| 9696 | neutron | Network — сети, подсети, порты, роутеры, SG, floating IP | `/v2.0/networks`, subnets, ports, routers, SG, FIPs, QoS, trunks, … |
| 9292 | glance | Image — образы | `/v2/images` |
| 8776 | cinder | Block storage — тома, снапшоты, типы томов | `/v3/volumes` |
| 8003 | placement | Placement — resource providers и inventories | `/resource_providers` |
| 8004 | heat | Orchestration — стеки Heat | `/v1/{project_id}/stacks` |
| 8000 | heat-cfn | CloudFormation-совместимый API Heat | `/stacks` |
| 8080 | swift | Object storage — аккаунты, контейнеры, объекты | `/v1/{account}/{container}/…`, `/info` |
| 6385 | ironic | Bare metal — ноды, порты, chassis | `/v1/nodes` |
| 9876 | octavia | Load balancing — балансировщики, listeners, pools | `/v2/lbaas/loadbalancers` |
| 9311 | barbican | Key manager — секреты, контейнеры | `/v1/secrets` |
| 8786 | manila | Shared file systems — shares | `/v2/shares` |
| 9001 | designate | DNS — зоны и recordsets | `/v2/zones` |
| 9511 | magnum | Container infra — кластеры (например Kubernetes) | `/v1/clusters` |
| 9517 | zun | Containers — жизненный цикл контейнеров | `/v1/containers` |
| 8779 | trove | Database as a service — экземпляры БД | `/v1.0/instances` |
| 8989 | mistral | Workflows | `/v2/workflows` |
| 8042 | aodh | Alarming — алармы | `/v2/alarms` |
| 8889 | cloudkitty | Rating / биллинг-метрики | `/v1/rating/…` |
| 9090 | freezer | Backup — задания резервного копирования | `/v2/jobs` |
| 1234 | blazar | Reservation — leases | `/leases` |
| 8999 | vitrage | Root cause analysis (RCA) | `/v1/alarm` |
| 15868 | masakari | Instance HA — высокая доступность инстансов | `/v1/segments` |
| 9890 | tacker | NFV orchestration | `/v1.0/vnfs` |
| 5050 | adjutant | Admin workflows / self-service задачи | `/v1/tasks` |
| 9322 | watcher | Infrastructure optimization | `/v1/…` |
| 8888 | zaqar | Messaging | `/v2/…` |
| 80 | http | Reverse proxy консоли (Compose + Helm gateway) | — |
| 443 | https | TLS reverse proxy (**только Compose**; в Helm TLS завершается на Ingress) | — |
Внутренний FastAPI слушает `8080` только внутри Docker (не Swift public port с хоста — хост `8080` это Swift через gateway). Postgres публикуется только как `127.0.0.1:5433` (это не порт OpenStack API).
+33
View File
@@ -0,0 +1,33 @@
**Language / Язык:** [English](../security.md) | [Русский](security.md)
# Безопасность
Этот проект — **лабораторный симулятор**, а не production OpenStack cloud.
## Граница доверия
- Пароли по умолчанию (`secret`) намеренно простые для лабораторий.
- `TICKET_SIGNING_KEY` / `secret.ticketSigningKey` нужно ротировать перед любым
общим или internet-facing развёртыванием.
- Пароли bundled Postgres в values/compose — лабораторные defaults.
## Сетевая экспозиция
| Surface | Риск |
|---|---|
| Compose ports on `0.0.0.0` | Вся поверхность API доступна на хосте |
| Helm Ingress | Публичный HTTPS к Keystone/UI; другие OS-порты требуют явной экспозиции |
| Read-only root FS (Helm) | Снижает write surface контейнера |
## TLS
- Compose: опциональный nginx TLS на `:443` с lab cert в `docker/tls/`
- Helm: terminate TLS на Ingress + cert-manager (рекомендуется)
## Что не реализовано
- Реальная federation Keystone / семантика ротации Fernet keys
- Паритет правил oslo.policy
- Multi-tenant isolation beyond project_id filters в handlers
Считайте все данные одноразовыми lab fixtures.
+30
View File
@@ -0,0 +1,30 @@
**Language / Язык:** [English](../seed-profiles.md) | [Русский](seed-profiles.md)
# Seed-профили OpenStack
| Profile | Как загрузить | Содержимое |
|---|---|---|
| `minimal` | startup / `make seed` / `python -m app.openstack.seed_cli --profile minimal` | Default domain, admin+demo users, flavors, images, небольшой IaaS sample |
| `demo` | `make seed-demo` / UI Data drawer / Helm `seed.profile=demo` / `--profile demo` | ~1000 servers, 16 hypervisors, 3 AZs, 5 projects, multi-net/SG topology, 600 volumes, ports/FIPs, Octavia/Heat/Ironic/Swift, nested pack samples |
Пароль для всех пользователей: **`secret`**. Домен: **`Default`**.
## Helm
```yaml
seed:
enabled: true
profile: demo # or minimal
```
Post-install Job запускает `python -m app.openstack.seed_cli`. Ручной reseed:
```bash
kubectl exec deploy/<release>-openstack-api-simulator -- \
python -m app.openstack.seed_cli --profile demo
```
## Поведение
Оба профиля **очищают** лабораторные таблицы OpenStack и перезагружают данные.
Предпочитайте `demo` для плотности / nested GET probes; `minimal` для быстрого CI.
+55
View File
@@ -0,0 +1,55 @@
**Language / Язык:** [English](../troubleshooting.md) | [Русский](troubleshooting.md)
# Устранение неполадок
## `/health/ready` возвращает 503
- Postgres не поднят или неверный `DATABASE_URL`
- Миграции не применены — проверьте migrate initContainer / `make db-migrate`
- Helm: `kubectl logs` на pod simulator (migrate init)
## Auth 401
- Неверный user/password/domain (`Default`)
- Отсутствует project scope для project-scoped API
- Токен от другого экземпляра simulator (reseed меняет ID)
## Пустые списки после lifecycle probe
Lifecycle DELETE может удалить demo-scoped строки. Перезагрузите:
```bash
make seed-demo
# or Helm:
kubectl exec deploy/… -- python -m app.openstack.seed_cli --profile demo
```
## Неверный сервис отвечает на порту
Проверьте gateway headers:
```bash
curl -sI http://127.0.0.1:8774/ | grep -i openstack
```
Ожидайте `X-OpenStack-Service: nova`. Если обращаетесь к simulator `:8080` напрямую,
задайте `X-OpenStack-Route-Service` / `X-OpenStack-Service` сами.
## Helm port-forward на 5000 не работает
Forward **gateway** Service, а не simulator Service:
```bash
kubectl port-forward svc/<release>-openstack-api-simulator-gateway 5000:5000
```
## Pack activate 404 / пустые ops
Убедитесь, что `contracts/openstack/<series>/` есть в образе и
`OPENSTACK_SERIES` — известное имя серии.
## Порты catalog недоступны клиенту
Catalog рекламирует per-service порты. При только Ingress на `:443→5000` Nova
`:8774` не публикуется автоматически. Используйте port-forward или expose gateway
Service (см. [kubernetes.md](kubernetes.md)).
+31
View File
@@ -0,0 +1,31 @@
**Language / Язык:** [English](../web-ui.md) | [Русский](web-ui.md)
# Web UI
Консоль обслуживается с Keystone/UI порта (**5000** на gateway).
| URL | Назначение |
|---|---|
| `/` или `/console` | Интерактивная консоль |
| `/docs` | OpenAPI (simulator) |
| `/ui/api/…` | UI JSON APIs |
## Environment drawer
- **OpenStack API pack** — список серий, активация пакета, переопределения microversion
- Apply немедленно перемонтирует schema-маршруты
## Data drawer
- **Load demo cloud** — `POST /ui/api/demo/load``seed_openstack_demo`
- **Unload / minimal** — сброс к minimal seed
## Брендинг
OpenStack red `#ED1C24`, console wordmark. Темы следуют общему chrome консоли
(light/dark).
## Health
- `/health/live` — процесс работает
- `/health/ready` — миграции применены + БД доступна