175 lines
9.7 KiB
Markdown
175 lines
9.7 KiB
Markdown
# 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, не в провайдере.
|