175 lines
10 KiB
Markdown
175 lines
10 KiB
Markdown
# polygon v0.5.18
|
||
|
||
Эмулятор REST API облачной платформы Nubes для интеграционных тестов app-autotest.
|
||
|
||
Отдельный managed-сервис на Nubes pythonk8s: `polygon.pythonk8s.dev.nubes.ru`.
|
||
Притворяется реальным Nubes API (префикс `/api/v1/svc`).
|
||
|
||
## Архитектура
|
||
|
||
```
|
||
polygon/
|
||
├── requirements.txt # Flask>=3.0, gunicorn>=21.2, PyYAML>=6.0
|
||
├── tests/
|
||
│ ├── test_converter.py # тесты from_stands.py
|
||
│ ├── test_loader.py # тесты CWD-independent loader
|
||
│ ├── test_state_machine.py # тесты state_machine.py
|
||
│ └── test_route_regressions.py # локальные регрессионные тесты API
|
||
└── site/
|
||
├── app.py # Flask: только blueprint'ы + app.run() (57 строк)
|
||
├── routes/ # blueprint-файлы по доменам
|
||
│ ├── root.py # /health, /, /swagger
|
||
│ ├── services_routes.py# /api/v1/svc/services
|
||
│ ├── instances_routes.py# /api/v1/svc/instances
|
||
│ ├── operations_routes.py# /api/v1/svc/instanceOperations/*
|
||
│ ├── run.py # /api/v1/svc/instanceOperations/<uid>/run
|
||
│ ├── mock_routes.py # /api/v1/svc/_mock/*
|
||
│ └── openapi.py # /api/v1/svc/openapi.json
|
||
├── mock_state.py # MockState: instances, operations, op_params
|
||
├── state_machine.py # apply_effect() — мутация состояния
|
||
├── config/
|
||
│ └── loader.py # загрузка YAML + SERVICES/OPS_INDEX/DELAY/VERSION
|
||
├── utils/
|
||
│ ├── now.py # now() — UTC ISO с 'Z'
|
||
│ └── pluralize.py # pluralize() — плюрализация
|
||
├── from_stands.py # конвертер STANDS YAML → polygon config
|
||
├── static/
|
||
│ └── style.css # тёмная тема
|
||
├── templates/
|
||
│ ├── index.html # главная и инструкции API
|
||
│ └── swagger.html # Swagger UI и инструкция Authorize
|
||
└── services/ # fallback YAML, также генерируются from_stands.py
|
||
```
|
||
|
||
⛔ **Ровно 1 gunicorn-воркер.** Состояние в памяти, не shared.
|
||
|
||
## Запуск
|
||
|
||
```bash
|
||
# Локально
|
||
cd site && python app.py # порт 5000
|
||
|
||
# Тесты
|
||
pytest tests/ -v # локальные тесты Polygon
|
||
```
|
||
|
||
## Откуда берутся сервисы (YAML)
|
||
|
||
Polygon эмулирует API Nubes. Чтобы знать какие сервисы, операции и параметры
|
||
существуют — он читает YAML-конфиги. Но Nubes генерит YAML в **другом формате**,
|
||
неудобном для полигона. Поэтому есть двухэтапный процесс:
|
||
|
||
```
|
||
~/TF/tf_provider/generated/{dev,test,prod}/resources_yaml/*.yaml ← источник истины
|
||
│
|
||
│ from_stands.py — конвертация формата, дедупликация, нормализация
|
||
│ Запускается ВРУЧНУЮ при изменении терраформ-репы
|
||
│
|
||
▼
|
||
polygon/site/services/{dev,test,prod}/*.yaml ← скоммичены в git-репу полигона
|
||
│
|
||
│ config/loader.py — загрузка ВСЕХ YAML в память при старте
|
||
│
|
||
▼
|
||
Память Flask-процесса (конфиги загружаются один раз при старте)
|
||
```
|
||
|
||
Если `POLYGON_STANDS` не задан, loader использует один стенд `default` из `site/services/`. Значения относительных путей в `POLYGON_STANDS` разрешаются относительно `site/`.
|
||
|
||
### Почему нельзя читать терраформ-формат напрямую?
|
||
|
||
Терраформ-формат хранит параметры **внутри** операций, с дубликатами.
|
||
Например параметр `resourceRealm` повторяется в create, modify и delete —
|
||
три копии одного и того же.
|
||
|
||
Полигону нужен плоский список **уникальных** параметров (`cfsParams`),
|
||
плюс индекс «какой параметр к какой операции» (`cfsParamsByOp`).
|
||
Плюс `stateParams` (дефолты для create), `stateOut` (subresource-ключи),
|
||
раскодированные HTML-entities (`"` → `"`).
|
||
|
||
Всё это делает `from_stands.py` **один раз**, а не на лету при каждом запросе.
|
||
|
||
### Когда запускать обновление?
|
||
|
||
Когда терраформ-репа обновилась (добавили/удалили сервис, изменили параметры) —
|
||
нужно перегенерить YAML и передеплоить полигон:
|
||
|
||
```bash
|
||
cd site
|
||
python from_stands.py ~/TF/tf_provider/generated/dev/resources_yaml services/dev
|
||
python from_stands.py ~/TF/tf_provider/generated/test/resources_yaml services/test
|
||
python from_stands.py ~/TF/tf_provider/generated/prod/resources_yaml services/prod
|
||
|
||
cd ..
|
||
git add services/
|
||
git commit -m "regenerate YAML from terraform (добавлен сервис X)"
|
||
git push
|
||
# → редеплоить polygon через Nubes UI
|
||
```
|
||
|
||
После успешной конвертации генератор удаляет из целевого каталога YAML, которых больше нет в источнике. Если конвертация завершилась ошибками, устаревшие файлы не удаляются.
|
||
Если `SERVICES_DIR` не передан, генератор пишет в `site/services/` независимо от CWD. Явно переданные относительные `STANDS_DIR` и `SERVICES_DIR` остаются относительно CWD.
|
||
|
||
### Как проверить что всё загрузилось?
|
||
|
||
```bash
|
||
curl https://polygon.pythonk8s.dev.nubes.ru/dev/api/v1/svc/services | python3 -m json.tool | head -20
|
||
```
|
||
|
||
## API
|
||
|
||
| Метод | Путь | Назначение |
|
||
|-------|------|------------|
|
||
| GET | `/health` | Healthcheck |
|
||
| GET | `/` | HTML с версией |
|
||
| GET | `/swagger` | Swagger UI |
|
||
| GET | `/api/v1/svc/openapi.json` | OpenAPI JSON |
|
||
| GET | `/api/v1/svc/services` | Список сервисов |
|
||
| GET | `/api/v1/svc/services/<id>` | Операции сервиса |
|
||
| GET | `/api/v1/svc/instances` | Пагинация |
|
||
| GET | `/api/v1/svc/instances/<uid>` | Инстанс + state |
|
||
| POST | `/api/v1/svc/instances` | Создать → 201 + Location |
|
||
| GET | `/api/v1/svc/instanceOperations/default/<id>` | Шаблон операции и cfsParams |
|
||
| POST | `/api/v1/svc/instanceOperations` | Создать операцию → 201 + Location |
|
||
| GET | `/api/v1/svc/instanceOperations/<uid>` | Статус + cfsParams |
|
||
| POST | `/api/v1/svc/instanceOperationCfsParams` | param → value |
|
||
| GET | `/api/v1/svc/instanceOperations/<uid>/validate-cfs` | 200, пустое тело |
|
||
| POST | `/api/v1/svc/instanceOperations/<uid>/run` | Выполнить |
|
||
| POST | `/api/v1/svc/_mock/reset` | Сброс |
|
||
| GET | `/api/v1/svc/_mock/state` | Отладка: состояние |
|
||
| GET | `/api/v1/svc/_mock/services` | Отладка: сервисы |
|
||
| POST | `/api/v1/svc/_mock/delay/<s>` | MOCK_OP_DELAY |
|
||
| POST | `/api/v1/svc/_mock/fail-next` | Следующий run завершится ошибкой |
|
||
|
||
Основные API-маршруты не требуют авторизации. Если задан `MOCK_AUTH_TOKEN`, запросы к `/_mock/*` должны передавать заголовок `X-Mock-Auth`.
|
||
|
||
### Где взять и куда вводить токен
|
||
|
||
`MOCK_AUTH_TOKEN` задаёт администратор в переменных окружения запущенного сервиса Polygon. Приложение не генерирует и не показывает это значение. Если у вас нет доступа к настройкам сервиса, запросите токен у его администратора.
|
||
|
||
В Swagger нажмите **Authorize**, в поле `X-Mock-Auth` → **Value** вставьте выданный токен и нажмите **Authorize** в диалоге. После этого Swagger автоматически добавит заголовок к запросам `/_mock/*`. В curl передавайте его явно: `-H "X-Mock-Auth: <token>"`. Если `MOCK_AUTH_TOKEN` на сервере не задан, токен вводить не нужно.
|
||
|
||
## Переменные окружения
|
||
|
||
| Переменная | По умолчанию | Описание |
|
||
|------------|-------------|----------|
|
||
| `POLYGON_STANDS` | `default:services` | Список стендов `name:path,name:path`; относительные пути считаются от `site/` |
|
||
| `MOCK_OP_DELAY` | `0.1` | Задержка операции в секундах |
|
||
| `MOCK_AUTH_TOKEN` | пусто | Опциональный токен для `/_mock/*`; при пустом значении локальные mock endpoints открыты |
|
||
| `POLYGON_ENDPOINT` | `https://polygon.pythonk8s.dev.nubes.ru` | Базовый URL для серверов в OpenAPI |
|
||
| `WEB_CONCURRENCY` | `1` | Использовать один gunicorn-воркер, поскольку состояние хранится в памяти |
|
||
|
||
## Деплой
|
||
|
||
- Репозиторий: `https://gitea.services.ngcloud.ru/forcloud/polygon.git`
|
||
- URL: `https://polygon.pythonk8s.dev.nubes.ru/`
|
||
- Nubes pythonk8s managed service
|
||
|
||
## Связанные документы
|
||
|
||
- [DEPLOYMENT_DIAGNOSIS.md](DEPLOYMENT_DIAGNOSIS.md) — разбор `201` при создании, NXDOMAIN и риска пути к YAML
|
||
- [DOCS/polygon-plan.md](../DOCS/polygon-plan.md) — план реализации
|
||
- [polygon-docs/sonnet-code-review-prompt.md](../polygon-docs/sonnet-code-review-prompt.md) — промпт code review
|
||
- [polygon-docs/tf-provider-refs.md](../polygon-docs/tf-provider-refs.md) — ссылки на генератор YAML
|
||
|