Go backend + React SPA: каталог Helm-чартов из Harbor, self-service заказ managed-services через GitOps-MR в GitLab, наблюдение за деплоем через Argo CD.
Полная спецификация - docs/idp-spec.md, конвенция чартов -
docs/chart-convention.md.
- Каталог чартов из Harbor (живой листинг, новые версии видны сразу), README / CHANGELOG / values / schema из артефакта.
- Заказ сервиса -> коммит
application.yaml+values.yamlв GitLab -> MR -> Argo CD деплоит чарт из Harbor. Статус заказа (DRAFT -> ... -> HEALTHY) через поллер + live-обновления по SSE. - Обратная синхронизация с Git: drift-детект (правки мимо портала), pull («Подтянуть из Git»), import осиротевших манифестов.
- Страница «Статус»: здоровье интеграций (Keycloak / Harbor / GitLab / Argo CD) и хранилищ.
В разработке инфраструктура крутится в Docker, а portal и web запускаются из исходников (live-reload) - так правится и бэкенд, и фронт без пересборки контейнеров.
| Слой | Где | Команда |
|---|---|---|
| Postgres + Valkey + Keycloak | Docker (compose) | make infra |
| Backend (portal) | хост, go run |
make run-oidc |
| Frontend (SPA) | хост, Vite | make web |
Upstream'ы (Harbor / GitLab / Argo CD) по умолчанию fake (in-memory) - happy-path заказа гоняется без какой-либо инфраструктуры. Реальный стек - опциональный e2e-стенд (см. ниже).
- Docker + docker compose (Docker Desktop или engine + plugin)
- Go 1.26+
- bun 1.x (фронтенд; npm не используется)
make,git
Полный локальный запуск - три команды по порядку, каждая в своём терминале:
- Инфраструктура в Docker (Postgres + Valkey + Keycloak), detached:
make infra
- Бэкенд на :8080 - OIDC против Keycloak + Postgres/Valkey (сессии и заказы
переживают рестарт):
make run-oidc
- Фронтенд (Vite) на :5173 (live-reload, проксирует
/api-> :8080):make web
Открыть http://localhost:5173 -> «Войти через Keycloak». Браузер и портал делят
один issuer http://localhost:8081/realms/internal, поэтому портал запускается на
хосте. Метрики/дашборды: добавь make obs. Полный e2e с настоящими GitLab /
Harbor / Argo CD - отдельный KinD-стенд, см. deployments/kind/README.md.
Остановить инфраструктуру: make down (сносит контейнеры и volume'ы).
Аутентификация - только OIDC. Режим без Keycloak (
AUTH_MODE=dev) остался лишь как тестовая заглушка (internal/auth/dev.go) и при запуске бинаря отклоняется.
Тестовые пользователи (realm internal, импортируется в Keycloak автоматически):
| Пользователь | Пароль | Группы | Роль |
|---|---|---|---|
alice |
alice |
team-core, team-dbaas |
member (команды core, dbaas) |
padmin |
padmin |
platform-admins, team-core, team-dbaas |
admin |
support |
support |
support |
support (просмотр/правка заказов всех команд) |
security |
security |
security |
security (раздел ИБ) |
Keycloak admin-консоль: http://localhost:8081 (admin / admin).
Доступ с другой машины (LAN): добавь
http://<твой-host>:5173/иhttp://<твой-host>:5173/api/v1/auth/callbackв клиентportal(Valid redirect URIs / Web origins / Valid post logout redirect URIs) и запусти бэкенд с соответствующимиOIDC_*(на Windows удобноdeployments/scripts/run-oidc.ps1 -BindHost <ip>).
| URL | Что |
|---|---|
| http://localhost:5173 | Фронтенд (Vite, dev) - открывать здесь |
| http://localhost:8080 | Портал: API + встроенный SPA (/health, /ready, /metrics) |
| http://localhost:8081 | Keycloak (admin / admin) |
Portal отдаёт метрики в формате Prometheus на /metrics. Поднять стек мониторинга
(работает вместе с make run-oidc):
make obs # Prometheus на :9090, Grafana на :3000 (anonymous, дашборд "IDP Platform")Grafana с автоподключённым datasource и дашбордом - открыть http://localhost:3000
(раздел Dashboards -> IDP -> IDP Platform). Prometheus скрейпит host-run portal
(make run-oidc).
Прикладные метрики (префикс console_):
| Метрика | Тип | Лейблы | Смысл |
|---|---|---|---|
console_component_up |
gauge | component, kind, mode |
доступность компонента платформы (1/0), как на /api/v1/status |
console_component_probe_duration_seconds |
histogram | component |
латентность health-пробы |
console_component_last_probe_timestamp_seconds |
gauge | component |
время последней пробы (детект зависшего рефрешера) |
console_orders |
gauge | status |
число заказов в каждом статусе lifecycle |
console_reconcile_runs_total |
counter | reconciler, result |
тики фонового reconcile (ok/error) |
console_reconcile_duration_seconds |
histogram | reconciler |
длительность тика reconcile |
console_reconcile_last_success_timestamp_seconds |
gauge | reconciler |
время последнего успешного тика |
Gauge'и обновляются в фоне с интервалом STATUS_POLL_INTERVAL. Помимо них /metrics
отдаёт стандартные Go/process-метрики.
Структурный лог (log/slog) в stdout. Формат - LOG_FORMAT (json по умолчанию, text
для dev), уровень - LOG_LEVEL (debug/info/warn/error, по умолчанию info).
LOG_LEVEL=debug включает детальный трейс: HTTP-запросы, тики reconcile, переходы FSM
заказов и согласований публикаций.
Каждая строка несёт component= (api, provisioning, publications, poller, ...), так что
видно, откуда лог. Сообщения стабильные и событийного стиля, переменные - в атрибутах
(order_id, request_id, from/to, duration_ms, ...). Конвенция целиком - в
doc-комментарии internal/observability/logger.go. Пример (LOG_FORMAT=text):
level=INFO msg="http request" component=api method=GET path=/api/v1/status status=200 duration_ms=0 request_id=...
level=DEBUG msg="order transition" component=provisioning order_id=... from=MR_MERGED to=DEPLOYING actor=system
Полный стек с реальными GitLab CE + Harbor + Argo CD поднимается отдельным
KinD-стендом. Он тяжёлый (GitLab ~4 ГБ ОЗУ) и только под Windows/PowerShell.
Порядок: make stand-up (KinD + Argo CD + Harbor), затем:
make up-upstreams-infra- в Docker бэкенд-сервисы (GitLab + Postgres + Valkey- Keycloak);
run-oidc.ps1 -RealGitlab+make web- portal и фронт на хосте (OIDC, хотрелоад), SPA на :5173.
Затем make gitlab-seed (после healthy). Полная инструкция -
в deployments/kind/README.md.
Чарты в репозитории не вендорятся - их источник Harbor. Засеять Harbor стенда из
внешнего каталога чартов: make stand-charts со STAND_CHARTS_DIR=<path>.
Все переменные с описанием - в .env.example (он же источник
правды наравне с internal/config/config.go; синхронность проверяет тест
TestEnvExampleInSync). Ключевое:
| Переменная | Значения | Назначение |
|---|---|---|
HARBOR_MODE / GITLAB_MODE / ARGOCD_MODE |
real (деф.) | fake |
upstream'ы; real требует URL/токен (иначе старт падает) |
STORE / CACHE |
memory (деф.) | postgres / redis |
состояние / кэш + сессии |
AUTH_MODE |
oidc | dev |
аутентификация |
RBAC_TEAM_GROUP_PREFIX / RBAC_TEAM_GROUP_REGEX |
строка | маппинг групп IdP -> команды |
CHART_REGISTRY |
строка | OCI-база chart-source в application.yaml (Harbor) |
GITLAB_AUTO_MERGE |
false | true |
поллер сам мёржит MR (локалка / демо) |
DRIFT_DETECTION_ENABLED / IMPORT_DISCOVERY_ENABLED |
bool | обратная синхронизация с Git |
SPA на React + React Aria + Tailwind + Monaco (Vite, TS) в web/:
каталог, динамическая форма по values.schema.json (+ raw-YAML в Monaco), заказы
с live-статусом по SSE, страница статуса. Dev-сервер: make web (или
cd web && bun install && bun run dev). Пакетный менеджер - bun (не npm).
cmd/portal/ - entrypoint
internal/
config/ - env-конфиг (источник правды для .env.example)
auth/ - OIDC + сессии (Valkey) + RBAC + dev-режим
harbor/ gitlab/ argocd/ - порты + fake (тесты) + real HTTP/OCI-клиенты
store/ cache/ - Postgres/Valkey (+ миграции) и memory
catalog/ changelog/- каталог чартов + парсер CHANGELOG
provisioning/ - заказы: FSM, gitops, реконсиляция, drift/import/pull
status/ events/ - read-only Argo + поллер; in-process pub/sub для SSE
api/ - chi-роутер, хендлеры, SSE, /status
pkg/models/ - доменные типы
web/ - фронтенд
deployments/
docker-compose.yml - инфра (infra) + полный контейнерный стек (up)
docker-compose.upstreams.yml - оверлей с реальным GitLab CE (для KinD-стенда)
keycloak/ gitlab/ - realm-импорт и сид GitLab
kind/ - реальный e2e-стенд (KinD + Argo CD + Harbor), Windows
scripts/ - хост-хелперы (run-oidc, reset-state, seed-import)
internal/harbor/charts/ - минимальная тест-фикстура чарта (НЕ деплоится)
- Источник чартов - Harbor; репозиторий chart-agnostic (реальные чарты живут отдельно и публикуются в Harbor своим пайплайном).
- Git - источник истины для values;
values_yamlв БД - снимок для UI (drift/pull синхронизируют его с Git). - Одна реплика: поллер/SSE in-process (техдолг до масштабирования -
TODO.md). - Один открытый MR на заказ + оптимистичная блокировка (
version).