**Language / Язык:** [English](../troubleshooting.md) | [Русский](troubleshooting.md) # Устранение неполадок ## Ready остаётся недоступным 1. Проверьте Postgres: `make logs` / health в Compose. 2. Выполните `make db-migrate`. 3. Снова вызовите `/health/ready`. Task workers могут повторять попытки, пока миграции не догонят после позднего migrate. ## Неожиданный HTTP 501 У каждого зарегистрированного маршрута должен быть реальный обработчик или DB-backed стаб — 501 не должен появляться для известного пути. Если вы его видите: - Убедитесь, что вызываете точный зарегистрированный path/verb (проверьте `app/vsphere/rest/coverage.py` или `/docs`). - 501 от опционального legacy-стаба (`ENABLE_PVE_STUB=true`) ожидается для необъявленных методов в стиле PVE, когда `CONTRACT_FALLBACK=error`; это не относится к native vSphere-поверхности. - Сообщите о регрессии — на native vSphere-плоскости ожидается полное покрытие реестра. ## 401 / 403 - Сессия истекла (скользящий TTL 2 часа) или заголовок/cookie `vmware-api-session-id` не отправлен. - Некорректный Basic auth на `/api/session` (отсутствует заголовок, неверный base64 от `user:password`). - Отказ по правам — попробуйте сравнить `administrator@vsphere.local` и `readonly@vsphere.local` (см. [Авторизация](domains/authz.md)). - В Web UI ответ 401 очищает сохранённую сессию и переключает бейдж в шапке на **Guest** с toast «Session expired — sign in again». ## Ingress возвращает брендированный HTML 404 / nginx 405 вместо JSON Симулятор отвечает на API-ошибки JSON (`detail` / `error_type` / `messages`). Если вы видите HTML «page not found» сайта или голую страницу nginx **405**, **Ingress / reverse proxy** подменил тело upstream (часто через `custom-http-errors` у ingress-nginx). Исправьте аннотации Ingress для этого хоста (см. `helm/vmware-api-simulator/values-ingress-example.yaml`): ```yaml annotations: nginx.ingress.kubernetes.io/proxy-intercept-errors: "false" nginx.ingress.kubernetes.io/custom-http-errors: "502,503" ``` Затем перепроверьте с `Accept: application/json`. Отсутствующий host должен выглядеть так: ```json { "detail": { "error_type": "not_found", "messages": [ { "default_message": "No such host ('host-999')", "id": "com.vmware.vapi.std.errors.not_found", "args": ["host-999"] } ], "data": { "host": "No such host ('host-999')" } } } ``` Seeded id хостов для `small` / `large` / `big` начинаются с `host-11`. Cookbook-ВМ включают `vm-101` (`web-01`). ### Корректная authenticated-мутация (vSphere Automation) Сессия в заголовке/cookie + JSON-тело (не form-urlencoded): ```bash SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' -X POST \ "https://HOST/api/session" | tr -d '"') curl -sk -X POST "https://HOST/api/vcenter/vm" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "vmware-api-session-id: $SID" \ -d '{"name":"lab-vm","guest_os":"OTHER_GUEST_64","placement":{"folder":"group-v23","host":"host-11","datastore":"datastore-31","resource_pool":"resgroup-22"}}' ``` ## Задача никогда не завершается - Изучите `/api/cis/tasks/{task}`. - Проверьте логи worker/симулятора (`make logs`). - Убедитесь, что `TASK_WORKER_CONCURRENCY` > 0 и аренды в базе данных можно забрать (claim). - Очень высокий `SIMULATION_TIME_SCALE` даёт необычные замедления (больше = быстрее симуляция); чаще виноваты неверно заданные worker-аренды. ## Сбои TLS / gateway - Используйте порт хоста **443** (gateway) для TLS-клиентов — pyvmomi, govmomi, провайдер Terraform `hashicorp/vsphere`, Pulumi. - Устанавливайте `verify_ssl=False` / `allow_unverified_ssl=true` **только** для локального self-signed development-сертификата. - Внутри Compose обращайтесь напрямую к `simulator:8080` (обычный HTTP, без gateway). - Seeded-имена ВМ для `small` — `web-01`, `web-02`, `db-01`, `app-01`, `jumpbox`, а не Proxmox-style `pve01`/VMID. ## Drift Terraform / Pulumi / Ansible после reseed Reseed заменяет инвентарь в PostgreSQL (MOID-ы и имена ВМ могут измениться); состояние внешних инструментов автоматически не обновляется. Выполните refresh, import или пересоберите стеки после `make seed`. ## Hot-swap «ничего не сделал» - Просмотр каталога ≠ apply. Используйте **Apply as runtime** или `POST /ui/api/contract/apply?major=N`. - Применение мажора меняет **каталог Web UI / представление evidence**, а не живую таблицу маршрутов — runtime всегда обслуживает полную зарегистрированную поверхность. См. [Версии API](api-versions.md). - Apply локален для процесса; перезапуск Compose возвращает к значению по умолчанию (мажор 9). ## Demo unload удивил `POST /ui/api/demo/unload` очищает состояние, созданное через API, и загружает `small`. Повторите `make seed` (или снова загрузите `demo-cluster`), чтобы восстановить более богатую фикстуру.