100 lines
7.9 KiB
Markdown
100 lines
7.9 KiB
Markdown
# Интерфейсы сервиса ams-sync
|
||
# Версия: 1.0.0
|
||
|
||
Документ описывает интерфейсную поверхность сервиса: потребляемый топик Kafka, входящий TCP-healthcheck, исходящие HTTP-запросы к внешним сервисам (Zitadel, sarex-backend) и обращения к БД.
|
||
|
||
> `ams-sync` — не backend-сервис с REST API, а утилита синхронизации: демон-потребитель Kafka (`run`) плюс набор CLI-команд (`migrate`/`sync`/`diff`). Публичного HTTP API у сервиса нет — единственный входящий сокет отвечает на healthcheck сырой строкой (не HTTP). Поэтому файла `openapi.yaml` для сервиса нет.
|
||
|
||
## Как устроено взаимодействие
|
||
|
||
Приложение построено по слоям (adapter → repository → usecase → controller). Исходящие вызовы к внешним сервисам выполняются через `requests` (`requests.Session` с ретраями на `5xx`), к БД — через `psycopg2`. Все HTTP-запросы идут с `verify=False` (без проверки TLS). Базовые хосты берутся из переменных окружения (см. `CONFIGURATION.md`): `ZITADEL_HOST`, `AUTH_HOST`, `USER_SERVER_HOST`.
|
||
|
||
Аутентификация исходящих запросов:
|
||
|
||
- **Zitadel** — заголовок `Authorization: Bearer <ZITADEL_SERVICE_ACCESS_TOKEN>` (service-токен из конфига). Для части операций дополнительно проставляется `x-zitadel-orgid`.
|
||
- **sarex-backend** — JWT, получаемый под админом (`AUTH_ADMIN_USERNAME`/`AUTH_ADMIN_PASSWORD`) через `POST api/token/`; кешируется и обновляется за 30 секунд до `exp`.
|
||
|
||
## Входящие интерфейсы
|
||
|
||
### TCP Healthcheck
|
||
|
||
Только режим `run`. Сырой TCP-сокет (не HTTP): на каждое подключение отправляет строку `HEALTHCHECK_REPLY` (по умолчанию `healthy`) и закрывает соединение. Слушает `HEALTHCHECK_HOST:HEALTHCHECK_PORT` (по умолчанию `0.0.0.0:8008`). В Helm k8s-пробы настроены на TCP-порт `8008` (по умолчанию отключены).
|
||
|
||
### Kafka-потребитель
|
||
|
||
Топик — переменная `AMS_SYNC_TOPIC` (по умолчанию `ams-sync`). Параметры консьюмера (`src/internal/controller/sync_service/controller.py`):
|
||
|
||
| Параметр | Значение |
|
||
| --- | --- |
|
||
| `group_id` | `ams_sync_group` |
|
||
| `auto_offset_reset` | `earliest` |
|
||
| `enable_auto_commit` | `True` |
|
||
| десериализация | JSON (`utf-8`) |
|
||
|
||
Формат сообщения — объект с полями `type` и `body`. Диспетчеризация по `type`:
|
||
|
||
| `type` сообщения | Тело (`body`) | Обработчик | Действие |
|
||
| --- | --- | --- | --- |
|
||
| `model_created` | `SarexUserWithPermissions` | при `VERIFY_USERS=True` — `import_user` UC, иначе `user` UC `create` | Создание пользователя в Zitadel + запись метадаты |
|
||
| `model_updated` | `Metadata` | `user` UC `update_metadata` | Обновление метадаты существующего пользователя в Zitadel |
|
||
|
||
Сообщения без `type` или `body` пропускаются с предупреждением. Ошибки обработки логируются (traceback), сообщение не переотправляется (auto-commit включён).
|
||
|
||
## Исходящие HTTP-запросы
|
||
|
||
### Zitadel (`ZITADEL_HOST`)
|
||
|
||
Адаптеры `users/zitadel/adapter.py` и `organizations/adapter.py`. Итоговый URL = `<ZITADEL_HOST>` + путь.
|
||
|
||
| Метод | Путь | Назначение |
|
||
| --- | --- | --- |
|
||
| POST | `/v2/users/new` | Создать пользователя (human) |
|
||
| POST | `/management/v1/users/human/_import` | Импортировать пользователя (заголовок `x-zitadel-orgid`) |
|
||
| POST | `/admin/v1/import` | Массовый импорт пользователей (bulk, с таймаутом) |
|
||
| POST | `/v2/users` | Поиск пользователей (по username / email / org) |
|
||
| GET | `/management/v1/users/{id}` | Получить пользователя по id |
|
||
| GET | `/management/v1/users/{id}/metadata/{key}` | Получить метадату пользователя по ключу |
|
||
| POST | `/v2/users/{id}/metadata` | Массово задать метадату пользователя (значения в base64) |
|
||
| POST | `/v2/users/{id}/deactivate` | Деактивировать пользователя |
|
||
| DELETE | `/v2/users/{id}` | Удалить пользователя |
|
||
| POST | `/v2/organizations/_search` | Найти организацию по имени |
|
||
|
||
> Пути `/v2/...` частично захардкожены в адаптере, часть базовых путей управляется `ZITADEL_USERS_MANAGEMENT_ENDPOINT` (`management/v1/users`) и `ZITADEL_USERS_ENDPOINT` (`v2/users`). Методы грантов (`grants/adapter.py`) в текущей версии закомментированы.
|
||
|
||
### sarex-backend — авторизация (`AUTH_HOST`)
|
||
|
||
Адаптер `auth/http/adapter.py`.
|
||
|
||
| Метод | Путь | Назначение |
|
||
| --- | --- | --- |
|
||
| POST | `{AUTH_AUTH_ENDPOINT}` (по умолчанию `api/token/`) | Получить JWT по логину/паролю админа. Возвращает поле `access` |
|
||
|
||
### sarex-backend — сервис пользователей (`USER_SERVER_HOST`), только CLI
|
||
|
||
Адаптер `users/http/adapter.py`. Сессия с ретраями на `500/502/503/504` (до 5 попыток).
|
||
|
||
| Метод | Путь | Назначение |
|
||
| --- | --- | --- |
|
||
| GET | `{USER_SERVER_USERS_ENDPOINT}/{user_id}/metadata` (по умолчанию `api/core/admin/users/{user_id}/metadata`) | Получить метадату пользователя sarex для синхронизации в Zitadel |
|
||
|
||
## Обращения к БД sarex-backend (`USER_DB_*`), только CLI
|
||
|
||
Репозитории `repository/users` и `repository/companies` читают данные напрямую из PostgreSQL sarex-backend (только чтение, серверный курсор `itersize`).
|
||
|
||
| Операция | Таблицы | Назначение |
|
||
| --- | --- | --- |
|
||
| Пользователь по id | `base_baseuser` | `migrate --user-id` / `sync --user-id` |
|
||
| Все пользователи (итерация) | `base_baseuser` | `migrate` / `sync` / `diff` (bulk) |
|
||
| Пользователи компании | `core_companyuser` ⋈ `base_baseuser` | `sync --company-id` (только с непустым email) |
|
||
| Компания по id / имени | `core_company` | Вспомогательные запросы |
|
||
|
||
## Внешние зависимости (инфраструктура)
|
||
|
||
| Зависимость | Режим | Назначение |
|
||
| --- | --- | --- |
|
||
| Kafka | `run` | Источник событий пользователей (топик `AMS_SYNC_TOPIC`) |
|
||
| Zitadel (AMS) | `run` + CLI | Целевая система управления доступом (создание/обновление/удаление пользователей и метадаты) |
|
||
| sarex-backend (auth) | `run` + CLI | Получение JWT под админом |
|
||
| sarex-backend (user server) | CLI | Источник метадаты пользователя |
|
||
| PostgreSQL sarex-backend | CLI | Источник пользователей и компаний для миграции/синхронизации |
|