9.7 KiB
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 slashgetViaProxy()→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.goAddress =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 defaultdocs_template_gen/main.go:81— flag defaultinternal/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:
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.
Без токена (публичные эндпоинты):
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)
# 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, не в провайдере.