fix: harden Polygon operation validation
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# polygon v0.2.2
|
||||
# polygon v0.5.17
|
||||
|
||||
Эмулятор REST API облачной платформы Nubes для интеграционных тестов app-autotest.
|
||||
|
||||
@@ -11,17 +11,19 @@
|
||||
polygon/
|
||||
├── requirements.txt # Flask>=3.0, gunicorn>=21.2, PyYAML>=6.0
|
||||
├── tests/
|
||||
│ ├── test_converter.py # 10 юнит-тестов from_stands.py
|
||||
│ └── test_state_machine.py # 9 юнит-тестов state_machine.py
|
||||
│ ├── test_converter.py # тесты from_stands.py
|
||||
│ ├── test_state_machine.py # тесты state_machine.py
|
||||
│ └── test_route_regressions.py # локальные регрессионные тесты API
|
||||
└── site/
|
||||
├── app.py # Flask: только blueprint'ы + app.run() (57 строк)
|
||||
├── routes/ # 6 blueprint-файлов по доменам
|
||||
├── routes/ # blueprint-файлы по доменам
|
||||
│ ├── root.py # /health, /
|
||||
│ ├── 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/*
|
||||
│ ├── 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/
|
||||
@@ -34,7 +36,7 @@ polygon/
|
||||
│ └── style.css # тёмная тема
|
||||
├── templates/
|
||||
│ └── index.html # Jinja2-шаблон
|
||||
└── services/ # YAML-конфиги (сгенерированы from_stands.py)
|
||||
└── services/ # fallback YAML, также генерируются from_stands.py
|
||||
```
|
||||
|
||||
⛔ **Ровно 1 gunicorn-воркер.** Состояние в памяти, не shared.
|
||||
@@ -46,7 +48,7 @@ polygon/
|
||||
cd site && python app.py # порт 5000
|
||||
|
||||
# Тесты
|
||||
pytest tests/ -v # 19 тестов
|
||||
pytest tests/ -v # локальные тесты Polygon
|
||||
```
|
||||
|
||||
## Откуда берутся сервисы (YAML)
|
||||
@@ -70,6 +72,8 @@ polygon/site/services/{dev,test,prod}/*.yaml ← скоммичены в git-
|
||||
Память Flask-процесса (конфиги загружаются один раз при старте)
|
||||
```
|
||||
|
||||
Если `POLYGON_STANDS` не задан, loader использует один стенд `default` из `site/services/`. Значения относительных путей в `POLYGON_STANDS` разрешаются относительно `site/`.
|
||||
|
||||
### Почему нельзя читать терраформ-формат напрямую?
|
||||
|
||||
Терраформ-формат хранит параметры **внутри** операций, с дубликатами.
|
||||
@@ -102,6 +106,7 @@ git push
|
||||
```
|
||||
|
||||
После успешной конвертации генератор удаляет из целевого каталога YAML, которых больше нет в источнике. Если конвертация завершилась ошибками, устаревшие файлы не удаляются.
|
||||
Если `SERVICES_DIR` не передан, генератор пишет в `site/services/` независимо от CWD. Явно переданные относительные `STANDS_DIR` и `SERVICES_DIR` остаются относительно CWD.
|
||||
|
||||
### Как проверить что всё загрузилось?
|
||||
|
||||
@@ -109,18 +114,20 @@ git push
|
||||
curl https://polygon.pythonk8s.dev.nubes.ru/dev/api/v1/svc/services | python3 -m json.tool | head -20
|
||||
```
|
||||
|
||||
## API (17 эндпоинтов)
|
||||
## 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 |
|
||||
| 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 |
|
||||
@@ -130,13 +137,19 @@ curl https://polygon.pythonk8s.dev.nubes.ru/dev/api/v1/svc/services | python3 -m
|
||||
| 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`.
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
| Переменная | По умолчанию | Описание |
|
||||
|------------|-------------|----------|
|
||||
| `POLYGON_STANDS` | `default:services` | Список стендов `name:path,name:path`; относительные пути считаются от `site/` |
|
||||
| `MOCK_OP_DELAY` | `0.1` | Задержка операции в секундах |
|
||||
| `WEB_CONCURRENCY` | `1` | ⛔ Не менять — ровно 1 воркер |
|
||||
| `MOCK_AUTH_TOKEN` | пусто | Опциональный токен для `/_mock/*`; при пустом значении локальные mock endpoints открыты |
|
||||
| `POLYGON_ENDPOINT` | `https://polygon.pythonk8s.dev.nubes.ru` | Базовый URL для серверов в OpenAPI |
|
||||
| `WEB_CONCURRENCY` | `1` | Использовать один gunicorn-воркер, поскольку состояние хранится в памяти |
|
||||
|
||||
## Деплой
|
||||
|
||||
|
||||
Reference in New Issue
Block a user