iac/apps/transmittal/CONFIGURATION.md

263 lines
22 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.

# Конфигурация проекта transmittal-api
Документ описывает все переменные окружения и способы конфигурирования сервиса.
## Способы конфигурирования
Сервис настраивается **только через переменные окружения**. Разбор выполняется в `src/transmittal_service/infra/settings.py` через библиотеку [`pydantic-settings`](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) (класс `AppSettings`).
Особенности разбора (`SettingsConfigDict`):
- `env_prefix="TRANSMITTAL_SERVICE_"` — все переменные приложения начинаются с этого префикса;
- `env_nested_delimiter="__"` — вложенные секции задаются двойным подчёркиванием, напр. `TRANSMITTAL_SERVICE_DATABASE__HOST``database.host`;
- `env_ignore_empty=False` — пустая строка считается заданным значением (не игнорируется), поэтому пустое обязательное поле-строка проходит валидацию, а вот отсутствие обязательного поля приводит к ошибке старта.
Отдельного конфиг-файла (yaml/toml) у приложения нет. Настройки Uvicorn читаются отдельным классом `UvicornSettings` (тот же префикс/делимитер).
Источники переменных по способам запуска:
| Способ запуска | Откуда берутся переменные |
| --- | --- |
| Локально (бинарник) | Переменные окружения процесса. `make config` копирует `.example.env``.env` как шаблон, но приложение **не загружает `.env` автоматически** (в коде нет `env_file`/`dotenv`) — файл нужно экспортировать самому, напр. `set -a && . ./.env && set +a` |
| Локально (контейнеры) | `makefile`: цели `container-run`, `container-run-database`, `container-run-rabbitmq` пробрасывают переменные хоста через `--env` |
| Kubernetes (Helm) | `.helm/values-<env>.yaml`: блок `envs` (обычные значения) и `secrets` (значения из k8s-секретов); шаблоны `deployment.yaml`, `worker.yaml`, `crontab_periodic.yaml` |
| CI/CD (GitLab) | `.gitlab-ci.yml`: переменные пайплайна (`workflow.rules`) и переменные job-а `test-unit` для запуска тестов |
Способы запуска процессов (`[project.scripts]` в `pyproject.toml`):
| Команда | Точка входа | Назначение |
| --- | --- | --- |
| `start_api` (`make run-api`) | `cmd/api.py` | HTTP API (uvicorn/gunicorn) |
| `taskiq worker …` (`make run-worker`) | `tasks.broker:broker` | Обработчик фоновых задач |
| `process_expired_transmittals` | `cmd/process_expired_transmittals.py` | Разовая задача обработки просроченных трансмитталов (в k8s — CronJob `0 3 * * *`) |
| `create_system_values` | `cmd/create_system_values.py` | Создание системных значений |
| `generate-act` | `cmd/generate_act.py` | Генерация акта |
Порядок запуска в контейнере (`scripts/entrypoint.sh`): сначала выполняются миграции (`alembic upgrade heads`), затем стартует gunicorn с воркерами `ConfigurableWorker`.
## Переменные приложения
Все перечисленные ниже переменные имеют префикс `TRANSMITTAL_SERVICE_`. В столбце «Переменная» указано полное имя. Дефолт `—` означает, что значение обязательно (иначе ошибка старта).
### App (`app.*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_APP__NAME` | string | `Transmittal Service` | Имя приложения |
| `TRANSMITTAL_SERVICE_APP__LOG_LEVEL` | enum | `INFO` | Уровень логирования: `CRITICAL`/`FATAL`/`ERROR`/`WARNING`/`WARN`/`INFO`/`DEBUG`/`NOTSET` |
| `TRANSMITTAL_SERVICE_APP__ENVIRONMENT` | enum | — | Окружение развёртывания: `stage`/`preprod`/`prod` |
| `TRANSMITTAL_SERVICE_APP__HOST` | string | — | Внешний базовый URL сервиса (используется в письмах/ссылках) |
### Auth (`auth.*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_AUTH__PUBLIC_KEY` | string | — | Публичный RSA-ключ для проверки JWT. Экранированные `\n` автоматически заменяются на реальные переводы строк |
### CORS (`cors.*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_CORS__ALLOW_ORIGINS` | list[str] (JSON) | — | Разрешённые Origin, напр. `["*"]` |
| `TRANSMITTAL_SERVICE_CORS__ALLOW_METHODS` | list[str] (JSON) | — | Разрешённые HTTP-методы |
| `TRANSMITTAL_SERVICE_CORS__ALLOW_HEADERS` | list[str] (JSON) | — | Разрешённые заголовки |
| `TRANSMITTAL_SERVICE_CORS__ALLOW_CREDENTIALS` | bool | — | Разрешить передачу учётных данных |
### Uvicorn (`uvicorn.*`)
Читаются отдельным классом `UvicornSettings`.
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_UVICORN__HOST` | string | `127.0.0.1` | Адрес прослушивания |
| `TRANSMITTAL_SERVICE_UVICORN__PORT` | int | `8001` | Порт |
| `TRANSMITTAL_SERVICE_UVICORN__ENABLE_AUTO_RELOAD` | bool | `False` | Live/hot-reload (для разработки) |
| `TRANSMITTAL_SERVICE_UVICORN__LOG_LEVEL` | enum | `info` | `critical`/`error`/`warning`/`info`/`debug`/`trace` |
| `TRANSMITTAL_SERVICE_UVICORN__NUM_WORKERS` | int | `1` | Число воркеров gunicorn |
| `TRANSMITTAL_SERVICE_UVICORN__ROOT_PATH` | string | `""` | Root path (префикс за реверс-прокси) |
### Database (`database.*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_DATABASE__HOST` | string | — | Хост PostgreSQL |
| `TRANSMITTAL_SERVICE_DATABASE__PORT` | int | — | Порт PostgreSQL |
| `TRANSMITTAL_SERVICE_DATABASE__USER` | string | — | Пользователь БД |
| `TRANSMITTAL_SERVICE_DATABASE__PASSWORD` | string | — | Пароль пользователя БД |
| `TRANSMITTAL_SERVICE_DATABASE__NAME` | string | — | Имя базы данных |
| `TRANSMITTAL_SERVICE_DATABASE__POOL_SIZE` | int | `5` | Размер пула соединений |
| `TRANSMITTAL_SERVICE_DATABASE__MAX_POOL_OVERFLOW` | int | `5` | Доп. соединения сверх пула |
| `TRANSMITTAL_SERVICE_DATABASE__ENABLE_SSL` | bool | — | Подключение к БД по TLS |
| `TRANSMITTAL_SERVICE_DATABASE__SSL_MODE` | enum | — | `verify-full`/`verify-ca`/`""`. Обязателен при `ENABLE_SSL=true` |
| `TRANSMITTAL_SERVICE_DATABASE__SSL_ROOT_CERT_PATH` | string | — | Путь к CA-сертификату. Обязателен при `ENABLE_SSL=true` |
> При `ENABLE_SSL=true` валидатор требует непустые `SSL_MODE` и `SSL_ROOT_CERT_PATH`, иначе — ошибка старта. Итоговый DSN собирается в `database.uri`.
### RabbitMQ (`rabbitmq.*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_RABBITMQ__USER` | string | — | Пользователь |
| `TRANSMITTAL_SERVICE_RABBITMQ__PASSWORD` | string | — | Пароль |
| `TRANSMITTAL_SERVICE_RABBITMQ__VHOST` | string | — | Виртуальный хост |
| `TRANSMITTAL_SERVICE_RABBITMQ__HOST` | string | — | Хост |
| `TRANSMITTAL_SERVICE_RABBITMQ__PORT` | int | — | Порт |
### HTTP-клиенты внешних сервисов
Все клиенты наследуют общий набор полей (`HttpClient`): `BASE_URL`, `MAX_CONNECTIONS`, `MAX_KEEPALIVE_CONNECTIONS`, `TIMEOUT`. Все четыре поля обязательны (дефолтов нет).
| Секция / префикс | Назначение | Доп. поля |
| --- | --- | --- |
| `TRANSMITTAL_SERVICE_SAREX_BACKEND_REPOSITORY__*` | Основной backend Sarex | `BASIC_AUTH_ENCODED` — base64 от `login:password` (обязателен), декодируется в пару login/password |
| `TRANSMITTAL_SERVICE_RESOURCE_REPOSITORY__*` | Сервис ресурсов (IAM/resources) | — |
| `TRANSMITTAL_SERVICE_DOCUMENTATIONS_REPOSITORY__*` | Сервис документаций | — |
| `TRANSMITTAL_SERVICE_FLOWS_REPOSITORY__*` | Сервис flows | — |
| `TRANSMITTAL_SERVICE_HTML_TO_PDF_CONVERTER__*` | Конвертер HTML→PDF (export-project) | — |
| `TRANSMITTAL_SERVICE_MARKINGS__*` | Сервис PDF-маркировок | — |
Для каждого — четыре переменные, напр. для markings:
| Переменная | Тип | Назначение |
| --- | --- | --- |
| `TRANSMITTAL_SERVICE_MARKINGS__BASE_URL` | string | Базовый URL сервиса |
| `TRANSMITTAL_SERVICE_MARKINGS__MAX_CONNECTIONS` | int | Макс. число соединений |
| `TRANSMITTAL_SERVICE_MARKINGS__MAX_KEEPALIVE_CONNECTIONS` | int | Макс. keep-alive соединений |
| `TRANSMITTAL_SERVICE_MARKINGS__TIMEOUT` | int | Таймаут запроса (сек) |
Для `SAREX_BACKEND_REPOSITORY` дополнительно:
| Переменная | Тип | Назначение |
| --- | --- | --- |
| `TRANSMITTAL_SERVICE_SAREX_BACKEND_REPOSITORY__BASIC_AUTH_ENCODED` | string (base64) | Basic-auth в виде base64(`login:password`) |
### S3 (`s3_client.*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_S3_CLIENT__ENDPOINT` | string | — | Эндпоинт S3. Если без `http(s)://` — префикс добавляется автоматически по `USE_SSL` |
| `TRANSMITTAL_SERVICE_S3_CLIENT__REGION_NAME` | string | — | Регион |
| `TRANSMITTAL_SERVICE_S3_CLIENT__DEFAULT_BUCKET` | string | — | Бакет по умолчанию |
| `TRANSMITTAL_SERVICE_S3_CLIENT__ACCESS_KEY` | string | — | Access key |
| `TRANSMITTAL_SERVICE_S3_CLIENT__SECRET_KEY` | string | — | Secret key |
| `TRANSMITTAL_SERVICE_S3_CLIENT__USE_SSL` | bool | — | Использовать SSL |
| `TRANSMITTAL_SERVICE_S3_CLIENT__VERIFY` | bool | — | Проверять TLS-сертификат |
| `TRANSMITTAL_SERVICE_S3_CLIENT__MAX_POOL_CONNECTIONS` | int | `10` | Размер пула соединений |
| `TRANSMITTAL_SERVICE_S3_CLIENT__CONNECT_TIMEOUT` | int | `10` | Таймаут подключения (сек) |
| `TRANSMITTAL_SERVICE_S3_CLIENT__READ_TIMEOUT` | int | `30` | Таймаут чтения (сек) |
| `TRANSMITTAL_SERVICE_S3_CLIENT__USE_PATH_STYLE` | bool | `True` | Path-style адресация |
| `TRANSMITTAL_SERVICE_S3_CLIENT__REQUEST_CHECKSUM_CALCULATION` | enum | `when_required` | `when_supported`/`when_required` |
| `TRANSMITTAL_SERVICE_S3_CLIENT__RESPONSE_CHECKSUM_VALIDATION` | enum | `when_required` | `when_supported`/`when_required` |
### Почта: Mailgun или SMTP
Должен быть настроен **ровно один** из двух сервисов (валидатор `check_mailing_service`), иначе — ошибка старта. По умолчанию используется Mailgun.
Mailgun (`mailgun.*`) — наследует поля `HttpClient` плюс:
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_MAILGUN__BASE_URL` | string | — | URL API, напр. `https://api.mailgun.net/v3/<domain>` |
| `TRANSMITTAL_SERVICE_MAILGUN__MAX_CONNECTIONS` | int | — | Макс. соединений |
| `TRANSMITTAL_SERVICE_MAILGUN__MAX_KEEPALIVE_CONNECTIONS` | int | — | Макс. keep-alive |
| `TRANSMITTAL_SERVICE_MAILGUN__TIMEOUT` | int | — | Таймаут (сек) |
| `TRANSMITTAL_SERVICE_MAILGUN__EMAIL` | string | — | Адрес отправителя |
| `TRANSMITTAL_SERVICE_MAILGUN__API_KEY` | string | — | API-ключ Mailgun |
SMTP (`smtp.*`) — альтернатива Mailgun:
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_SMTP__HOST` | string | — | SMTP-хост |
| `TRANSMITTAL_SERVICE_SMTP__PORT` | int | — | SMTP-порт |
| `TRANSMITTAL_SERVICE_SMTP__EMAIL` | string | — | Адрес отправителя |
| `TRANSMITTAL_SERVICE_SMTP__ENABLE_TLS` | bool | `False` | Включить TLS |
| `TRANSMITTAL_SERVICE_SMTP__LOGIN` | string \| null | `None` | Логин |
| `TRANSMITTAL_SERVICE_SMTP__PASSWORD` | string \| null | `None` | Пароль |
### OpenTelemetry (`otel.*`)
| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRANSMITTAL_SERVICE_OTEL__ENABLE` | bool | `False` | Включить трейсинг |
| `TRANSMITTAL_SERVICE_OTEL__HOST` | string | — | Адрес OTLP-коллектора |
| `TRANSMITTAL_SERVICE_OTEL__SERVICE_NAME` | string | — | Имя сервиса в трейсах |
| `TRANSMITTAL_SERVICE_OTEL__INSECURE` | bool | `False` | Небезопасное (без TLS) подключение к коллектору |
## Переменные инфраструктуры, сборки и вспомогательных утилит
Не читаются кодом приложения, но участвуют в запуске/сборке/деплое.
| Переменная | Где используется | Назначение |
| --- | --- | --- |
| `TRANSMITTAL_SERVICE_PGDATA` | `.example.env` (закомментировано) | Каталог данных локального PostgreSQL |
| `TRANSMITTAL_SERVICE_PGHOST` | `.example.env` (закомментировано) | Хост локального PostgreSQL |
| `TRANSMITTAL_SERVICE_PGPORT` | `makefile` (`container-run-database`) | Внутренний порт контейнера Postgres при пробросе |
| `OCI` | `makefile` | Инструмент контейнеризации (`docker`/`podman`), по умолчанию `docker` |
| `TRANSMITTAL_SERVICE_IMAGE_NAME` / `TRANSMITTAL_SERVICE_IMAGE_VERSION` | `makefile` | Имя/тег собираемого образа |
| `TRANSMITTAL_SERVICE_CONTAINER__NETWORK_NAME` | `makefile` | Имя docker-сети |
| `TRANSMITTAL_SERVICE_DATABASE_CONTAINER__*` | `makefile` | Параметры контейнера Postgres (образ, имя, volume) |
| `TRANSMITTAL_SERVICE_RABBITMQ_CONATINER__*` | `makefile` | Параметры контейнера RabbitMQ |
| `PIP_INDEX_URL`, `PIP_TRUSTED_HOST` | `Dockerfile` (build-arg) | Приватный индекс пакетов при сборке |
| `TRANSMITTAL_SERVICE_PYTHON_IMAGE_NAME`, `TRANSMITTAL_SERVICE_PYTHON_IMAGE_TAG` | `Dockerfile` (build-arg) | Базовый образ Python (по умолчанию `python:3.12-slim`) |
| `UID`, `GID`, `USERNAME` | `Dockerfile` (build-arg) | Пользователь внутри образа (по умолчанию `10000`/`10001`/`transmittal_service`) |
## Переменные из Helm-чарта (`.helm/values-<env>.yaml`)
Обычные значения задаются в блоке `envs` для каждого окружения (`stage`/`preprod`/`production`) и содержат те же переменные приложения `TRANSMITTAL_SERVICE_*`, что описаны выше (различаются адресами БД/сервисов, портами, `LOG_LEVEL`, `ROOT_PATH`, бакетом, доменом Mailgun и т.п.).
Значения из секретов (блок `secrets`, монтируются как env через `secretKeyRef`):
| Переменная | Секрет (`secret_name`) | Ключ (`secret_key`) |
| --- | --- | --- |
| `TRANSMITTAL_SERVICE_DATABASE__USER` | `ya-pg-secret` | `username` |
| `TRANSMITTAL_SERVICE_DATABASE__PASSWORD` | `ya-pg-secret` | `password` |
| `YC-PG-CERTIFICATE` | `ya-pg-secret` | `certificate` |
| `TRANSMITTAL_SERVICE_AUTH__PUBLIC_KEY` | `public-key` | `key` |
| `TRANSMITTAL_SERVICE_SAREX_BACKEND_REPOSITORY__BASIC_AUTH_ENCODED` | `django-auth` | `key` |
| `TRANSMITTAL_SERVICE_S3_CLIENT__ACCESS_KEY` | `s3-secret` | `access_key` |
| `TRANSMITTAL_SERVICE_S3_CLIENT__SECRET_KEY` | `s3-secret` | `secret_key` |
| `TRANSMITTAL_SERVICE_RABBITMQ__USER` | `rabbitmq-cred` | `username` |
| `TRANSMITTAL_SERVICE_RABBITMQ__PASSWORD` | `rabbitmq-cred` | `password` |
| `TRANSMITTAL_SERVICE_MAILGUN__API_KEY` | `mailgun-cred` | `api_key` |
Помимо env, чарт монтирует CA-сертификат PostgreSQL из секрета `ya-pg-secret` (ключ `certificate`) как файл `/opt/.postgresql/root.crt` — именно на него указывает `TRANSMITTAL_SERVICE_DATABASE__SSL_ROOT_CERT_PATH` в prod-конфигурации.
Прочие значения чарта (не переменные приложения): `deployment.*` (имя, образ, порт, реплики, ресурсы), `api.*` (host/prefix/path ingress), `worker.*`, `job.name_periodic`, `imagePullSecrets`.
## Переменные в CI (`.gitlab-ci.yml`)
Пайплайн подключает общие шаблоны из `generic/common-ci` и переключает окружение по ветке/тегу через `workflow.rules`:
| Условие | STAND | Namespace |
| --- | --- | --- |
| ветка `master` | `preprod` | `transmittal-api-preprod` |
| ветка `stage` | `stage` | `transmittal-api-stage` |
| тег (`CI_COMMIT_TAG`) | `prod` | `transmittal-api-prod` |
Ключевые переменные пайплайна: `RELEASE_NAME`, `CHART_NAME`, `CHART_VERSION`, `DOCKERFILE_PATH`, `HELM_SET_ARGS` (`--set deployment.image=…`), флаги `ENABLE_LINTER`/`ENABLE_BUILD_CHART`/`ENABLE_BUILD_IMAGE`/`ENABLE_DEPLOY`. Job `test-unit` задаёт полный набор `TRANSMITTAL_SERVICE_*` переменных для прогона юнит-тестов.
## Замечания и потенциальные проблемы
- Переменные БД в `.example.env` должны иметь префикс `TRANSMITTAL_SERVICE_DATABASE__*` — код читает их именно так. Ранее в файле они были записаны без префикса (`DATABASE__USER` и т.д.) и не подхватывались; сейчас исправлено. В `makefile`, `.gitlab-ci.yml` и Helm имена с префиксом корректны.
- Приложение **не загружает `.env` автоматически**`settings.py` не задан `env_file`, зависимости `python-dotenv` нет). `make config` лишь создаёт файл-шаблон; переменные нужно экспортировать в окружение вручную либо задавать через `--env` (см. `make container-run`).
- `env_ignore_empty=False`: пустая строка воспринимается как заданное значение. Например `TRANSMITTAL_SERVICE_AUTH__PUBLIC_KEY=''` — валидное (пустой ключ), а вот полностью отсутствующая обязательная переменная вызовет ошибку старта.
- Переменная `YC-PG-CERTIFICATE` прокидывается из секрета в окружение, но **кодом приложения не читается** — сертификат используется как смонтированный файл (`root.crt`). Имя с дефисами не соответствует схеме `TRANSMITTAL_SERVICE_*`.
- Почтовый сервис: должен быть задан ровно один из `mailgun`/`smtp`. Если заданы оба или ни одного — сервис не стартует.
- В `.example.env` секция `FLOWS_REPOSITORY__BASE_URL` пустая, но поле обязательно — для реального запуска его нужно заполнить.
## Минимальный набор для локального запуска
Postgres и RabbitMQ поднимаются через `make container-deps`, приложение — через `make run-api` / `make run-worker`. Минимально необходимо задать (с префиксом `TRANSMITTAL_SERVICE_`):
- `APP__ENVIRONMENT`, `APP__HOST`
- `AUTH__PUBLIC_KEY` (можно пустой для локальной разработки)
- `CORS__ALLOW_ORIGINS`, `CORS__ALLOW_METHODS`, `CORS__ALLOW_HEADERS`, `CORS__ALLOW_CREDENTIALS`
- `DATABASE__HOST`, `DATABASE__PORT`, `DATABASE__USER`, `DATABASE__PASSWORD`, `DATABASE__NAME`, `DATABASE__ENABLE_SSL` (`false` локально), `DATABASE__SSL_MODE`, `DATABASE__SSL_ROOT_CERT_PATH`
- `RABBITMQ__USER`, `RABBITMQ__PASSWORD`, `RABBITMQ__VHOST`, `RABBITMQ__HOST`, `RABBITMQ__PORT`
- `BASE_URL`/`MAX_CONNECTIONS`/`MAX_KEEPALIVE_CONNECTIONS`/`TIMEOUT` для всех шести HTTP-клиентов (`SAREX_BACKEND_REPOSITORY` + `BASIC_AUTH_ENCODED`, `RESOURCE_REPOSITORY`, `DOCUMENTATIONS_REPOSITORY`, `FLOWS_REPOSITORY`, `HTML_TO_PDF_CONVERTER`, `MARKINGS`)
- `S3_CLIENT__*` (эндпоинт, регион, бакет, ключи, `USE_SSL`, `VERIFY`)
- один из почтовых сервисов: `MAILGUN__*` **или** `SMTP__*`
- `OTEL__ENABLE` (`False` локально), при `True``OTEL__HOST`, `OTEL__SERVICE_NAME`
Готовые значения-примеры для всех переменных приведены в `.example.env` (с учётом замечаний выше по префиксу БД).