Files
tf_provider/HISTORY/2026-07-02_api_gateway_migration.md
T

175 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-07-02 — Миграция с deck-api на API Gateway (lk-api-gateway)
## Контекст
Старый API: `https://deck-api-{stand}.ngcloud.ru/api/v1/index.cfm?endpoint=/services/123`
Новый API Gateway: `https://lk-api-gateway-{stand}.ngcloud.ru/api/v1/svc/services/123`
Ответы JSON идентичны. Различается только формат URL:
- Старый: proxy через `index.cfm?endpoint=`
- Новый: прямые REST-пути
Цель: перевести TEST-стенд на новый Gateway, сохранив совместимость со старым для dev/prod.
## Архитектурное решение
Авто-детект режима по наличию `index.cfm` в URL:
- Есть `index.cfm` → старый proxy (`?endpoint=`)
- Нет `index.cfm` → новый REST (прямая конкатенация пути)
Один env-параметр `NUBES_API_ENDPOINT` управляет всем.
## Изменения (11 файлов)
### 1. Генератор YAML: `universal_rebuild/tools/service_spec_gen/generate_service_spec.go`
- `normalizeAPIEndpoint()` — убрано принудительное добавление `/index.cfm`, теперь только trim trailing slash
- `getViaProxy()``callAPI()` — авто-детект: если `index.cfm` в URL → `?endpoint=`, иначе → прямая конкатенация `{base}{path}`
- Добавлен метод `isProxyAPI()` для детекта
- Обновлён комментарий с документированием двух режимов
### 2. Ядро провайдера: `universal_rebuild/internal/core/client.go`
- Добавлены `isProxyAPI()` и `buildURL(path string) string` — единая точка конструирования URL
- Заменены все 4 места с хардкодом `?endpoint=`:
- `FindExistingInstances` (пагинированный поиск, строка ~515)
- `GetInstanceState` (строка ~590)
- `GetInstanceStateRaw` (строка ~637)
- `doRequest` (POST/PUT/GET, строки ~838-853)
### 3. Оркестратор YAML: `devops/01_generate_yamls.sh`
- Убрана принудительная нормализация `if [[ "$API_ENDPOINT" != */index.cfm ]]` → автоматическая
- Python-скрипт: авто-детект `"index.cfm" in endpoint``?endpoint=` vs прямой путь
### 4. Генератор документации: `devops/02_generate_resources_and_docs_v2.sh`
- Добавлена передача `-api-endpoint "$DOCS_API_ENDPOINT"` в `docs_template_gen_v2`
- Нормализация: если нет ни `index.cfm`, ни `/svc` → дописать `/index.cfm` (обратная совместимость)
### 5. Публикация доков: `devops/04_build_and_publish_docs.sh`
- `normalize_api_endpoint()` — убрано принудительное `/index.cfm`, только trim
### 6. Корневой скрипт: `01_generate_yamls.sh` (корень)
- Python-скрипт: такой же авто-детект, как в devops/01
### 7-8. Шаблоны документации: `docs_template_gen_v2/main.go` + `docs_template_gen/main.go`
- Добавлен флаг `-api-endpoint` (default: старый deck-api)
- Все хардкоды `api_endpoint = "https://deck-api...index.cfm"` заменены на `fmt.Sprintf`
- Проброшено через `writeResourceDocs``buildExamplePage``exampleBlock``buildSubresourceExamplePage`
### 9-10. Провайдеры: `internal/provider/provider.go` + `universal_rebuild/internal/provider/provider.go`
- Добавлен `TODO(api-gateway)` комментарий над дефолтным `apiEndpoint`
- Сам дефолт не менялся (runtime провайдера теперь использует `core.buildURL()`)
### 11. Профиль TEST: `devops/profiles/test/profile.env`
- `NUBES_API_ENDPOINT``https://lk-api-gateway-test.ngcloud.ru/api/v1/svc`
### Бонус: версия в бинарник
- `devops/build-provider.sh`: `go build` теперь с `-ldflags "-X main.version=${VERSION}"` — версия из профиля вшивается в бинарник (раньше всегда была из main.go)
## Анализ пайплайна (попутно)
Полный пайплайн: `services_list.txt``01_generate_yamls.sh``02_generate_resources_and_docs_v2.sh``03_build_and_upload_provider.sh``04_build_and_publish_docs.sh`.
Найденные проблемы (не исправлялись, зафиксированы):
- `main.go` Address = `nubes-test` (только для test, для prod нужно `nubes`)
- Нет сборки под `darwin/arm64` (Apple Silicon)
- Корневой `01_generate_yamls.sh` ссылается на несуществующий `service_params_gen`
- Кросс-стадийная валидация отсутствует (сбои 01 не видны в 02)
## Оставшиеся `deck-api` в коде
Только как **значения по умолчанию** (переопределяются через `NUBES_API_ENDPOINT`):
- `service_spec_gen/generate_service_spec.go:150``getenvDefault("NUBES_API_ENDPOINT", "https://deck-api...")`
- `devops/01_generate_yamls.sh:108``${NUBES_API_ENDPOINT:-https://deck-api...}`
- `devops/02_generate_resources_and_docs_v2.sh:95` — аналогично
- `devops/04_build_and_publish_docs.sh:13,87` — аналогично
- `docs_template_gen_v2/main.go:91` — flag default
- `docs_template_gen/main.go:81` — flag default
- `internal/provider/provider.go:105` + `universal_rebuild/...`с TODO
Хардкодов в теле функций/примеров больше нет.
## Для перехода dev/prod
Достаточно поменять одну строку в `profile.env`:
```
NUBES_API_ENDPOINT="https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc" # dev
NUBES_API_ENDPOINT="https://lk-api-gateway.ngcloud.ru/api/v1/svc" # prod
```
Всё остальное — авто-детект.
---
## Доступ к СТАРОМУ deck-api (DDoS-Guard 403)
Старый API **жив**, но DDoS-Guard усилил фильтрацию. Просто `User-Agent: Mozilla/5.0` уже недостаточно.
### Рабочие заголовки для curl:
```bash
curl -H "Authorization: Bearer $TOKEN" \
-H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \
-H "Referer: https://deck-test.ngcloud.ru/" \
"https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/services/90"
```
**Ключевое**: `Referer` с доменом того же стенда. Без него — 403.
### Без токена (публичные эндпоинты):
```bash
curl -H "User-Agent: Mozilla/5.0" \
"https://deck-api-test.ngcloud.ru/api/v1"
# → 200 (OK)
```
### Что изменилось с июля 2026
DDoS-Guard ужесточил правила:
- Старый `User-Agent: Mozilla/5.0` + `Accept: */*` → 403
- Новый: нужен полный браузерный User-Agent + Referer
- Провайдер (v5.0.75) использовал старые заголовки — при следующем билде надо обновить
- Новый Gateway (`lk-api-gateway`) — 403 не выдаёт, работает с любым User-Agent
---
## Проблема map-fixed параметров и dataDescriptor
### Суть
Новый Gateway группирует плоские параметры в map-fixed JSON-блоки. Sub-поля (`dataDescriptor`) не видны в `/serviceOperation/{id}` — появляются только в ответе уже выполненной операции `/instanceOperations/{uid}`.
### Как получить sub-поля (на примере postgres)
```bash
# 1. Найти любой успешный инстанс postgres
curl ... "https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/instances?serviceId=90&page=1&size=1"
# 2. Взять instanceUid → запросить операции → взять create-операцию
curl ... "https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/instances/{uid}"
# 3. Запросить операцию — в cfsParams будет dataDescriptor с sub-полями
curl ... "https://deck-api-test.ngcloud.ru/api/v1/index.cfm?endpoint=/instanceOperations/{opUid}"
```
### Правильные JSON-ключи для postgres (из dataDescriptor)
| Блок | Поля |
|---|---|
| `startupConfiguration` | `resourceRealm` |
| `clusterConfiguration` | `cpu`, `memory`, `replicas`, `disk` |
| `accessConfiguration` | `masterIpSpace`, `masterAccessList`, `slaveIpSpace`, `slaveAccessList` |
| `postgresConfiguration` | `version`, `sslRequired`, `poolerMaster`, `poolerSlave` |
| `postgresConf` | `paramName`, `paramValue` (массив) |
| `backupConfiguration` | `s3Uid`, `retain`, `schedule` |
| `autoscaleConfiguration` | `enabled`, `schedule`, `quota`, `percent` |
### Обсуждение с девопсами (02.07.2026)
- Плоские параметры **не вернутся** — map-fixed остаётся (нужно для групп ключей, нод, учёток)
- Структуру блоков обещают давать в API, но пока не придумали формат
- Пока единственный источник структуры — Jenkins-конфиги
### CMDB backend bug
При run операции бэкенд `/app/cmdb` падает с `ValidationError: InstanceState: version, instanceUid, dtState, isTest, instanceOperationUid — can't be blank`. Это баг в Gateway→CMDB, не в провайдере.