iac/apps/documentations/dps-message-hub.CONFIGURATION.md

16 KiB
Raw Permalink Blame History

Конфигурация проекта dps-message-hub

Версия: 0.1.0

Документ описывает все переменные окружения и способы конфигурирования сервиса.

dps-message-hub (dps_message_hub) — это Kafka-воркер на базе FastStream, потребляющий сообщения об изменении ассетов и обновляющий данные разметки (markup_event) в PostgreSQL домена «documentations». HTTP API у сервиса нет.

Это отдельный сервис, не путать с приложением message-hub (домен planning): у них разные префиксы переменных, набор интеграций и назначение.

Способы конфигурирования

Сервис настраивается только через переменные окружения. Разбор выполняется в src/dps_message_hub/infra/config.py через библиотеку pydantic-settings (класс AppSettings(BaseSettings)).

Особенности разбора (SettingsConfigDict):

  • env_prefix="DPS_MESSAGE_HUB_" — все переменные приложения начинаются с этого префикса;
  • env_nested_delimiter="__" — вложенные секции задаются двойным подчёркиванием, напр. DPS_MESSAGE_HUB_DOCUMENTATION_DB__HOSTdocumentation_db.host;
  • env_ignore_empty=False — пустая строка считается заданным значением (не игнорируется);
  • frozen=True — объект настроек неизменяем после инициализации.

Настройки разбиты на три вложенные секции (модели pydantic.BaseModel), читаемые одним классом AppSettings:

  • app (App) — префикс DPS_MESSAGE_HUB_APP__;
  • documentation_db (Database) — префикс DPS_MESSAGE_HUB_DOCUMENTATION_DB__;
  • kafka (Kafka) — префикс DPS_MESSAGE_HUB_KAFKA__.

Класс Settings (src/dps_message_hub/infra/config.py) — синглтон (wiring.SingletonMeta) поверх AppSettings, отдаёт настройки через свойство .settings.

Отдельного конфиг-файла (yaml/toml) у приложения нет. У классов настроек не задан env_file, поэтому файл .env автоматически не загружается — переменные нужно экспортировать в окружение процесса самостоятельно (make config лишь копирует .example.env.env как шаблон), либо пробрасывать их в контейнер через --env-file (см. Makefile, цель container-run).

Источники переменных по способам запуска:

Способ запуска Откуда берутся переменные
Локально (бинарник) Переменные окружения процесса. make config копирует .example.env.env, но приложение не загружает .env автоматически — экспортируйте сами, напр. set -a && . ./.env && set +a
Локально (контейнер) Makefile: цель container-run пробрасывает переменные через --env-file .env
Kubernetes (Helm) .helm/values.yaml: блок universal-chart.services.api.envs (обычные значения) и secretEnvs (значения из k8s-секретов); базовый чарт — universal-chart (oci://.../charts, версия 0.1.7)
CI/CD (GitLab) .gitlab-ci.yml: переменные пайплайна (workflow.rules) и HELM_SET_ARGS

Запуск процесса (scripts/entrypoint.sh): единый FastStream-процесс с брокером Kafka:

faststream run \
    --factory \
    --workers ${DPS_MESSAGE_HUB_NUM_WORKERS} \
    'dps_message_hub.infra.app:get_app'

Фабрика dps_message_hub.infra.app:get_app (src/dps_message_hub/infra/app.py) собирает FastStream-приложение: создаёт KafkaBroker, подключает роутер-потребитель топика assets и открывает пул соединений PostgreSQL в lifespan. Отдельных точек входа для воркеров/крон-задач нет — pyproject.toml не содержит [project.scripts].

Переменные приложения

Дефолт означает, что значение обязательно (иначе ошибка старта настроек).

Приложение (DPS_MESSAGE_HUB_APP__*) — класс App

Переменная Тип Значение по умолчанию Назначение
DPS_MESSAGE_HUB_APP__LOG_LEVEL enum (LogLevel) INFO Уровень логирования. Допустимо: CRITICAL/FATAL/ERROR/WARNING/WARN/INFO/DEBUG/NOTSET
DPS_MESSAGE_HUB_APP__IS_DEV bool False Признак dev-режима. Поле объявлено в настройках, но в текущем коде не используется
DPS_MESSAGE_HUB_APP__BROKER_TYPE enum (BrokerType) (обязательно) Тип брокера сообщений. Поддерживается только значение kafka

База данных PostgreSQL (DPS_MESSAGE_HUB_DOCUMENTATION_DB__*) — класс Database

Переменная Тип Значение по умолчанию Назначение
DPS_MESSAGE_HUB_DOCUMENTATION_DB__HOST string Хост PostgreSQL
DPS_MESSAGE_HUB_DOCUMENTATION_DB__PORT int Порт PostgreSQL
DPS_MESSAGE_HUB_DOCUMENTATION_DB__USER string Пользователь БД
DPS_MESSAGE_HUB_DOCUMENTATION_DB__PASSWORD string Пароль пользователя БД
DPS_MESSAGE_HUB_DOCUMENTATION_DB__NAME string Имя базы данных
DPS_MESSAGE_HUB_DOCUMENTATION_DB__ENABLE_SSL bool Включить TLS-подключение к БД
DPS_MESSAGE_HUB_DOCUMENTATION_DB__SSL_MODE enum (verify-full/verify-ca/"") Режим проверки TLS (параметр sslmode DSN). При ENABLE_SSL=true не должно быть пустым
DPS_MESSAGE_HUB_DOCUMENTATION_DB__SSL_ROOT_CERT_PATH string Путь к CA-сертификату (параметр sslrootcert DSN). При ENABLE_SSL=true не должно быть пустым

Валидатор check_ssl_options_configured_when_ssl_enabled: если ENABLE_SSL=true, то SSL_MODE и SSL_ROOT_CERT_PATH обязаны быть непустыми, иначе ошибка старта. Итоговый DSN собирается в вычисляемом поле documentation_db.uri (postgresql://user:password@host:port/name, при SSL добавляются ?sslmode=...&sslrootcert=...).

Kafka (DPS_MESSAGE_HUB_KAFKA__*) — класс Kafka

Переменная Тип Значение по умолчанию Назначение
DPS_MESSAGE_HUB_KAFKA__HOST string Хост брокера Kafka
DPS_MESSAGE_HUB_KAFKA__PORT int Порт брокера Kafka
DPS_MESSAGE_HUB_KAFKA__USERNAME string Логин SASL (SCRAM-SHA-512)
DPS_MESSAGE_HUB_KAFKA__PASSWORD string Пароль SASL (SCRAM-SHA-512)
DPS_MESSAGE_HUB_KAFKA__SSL_CAFILE string | null None Путь к CA-сертификату для SSL-контекста. Если задан — используется SASL_SSL, иначе SASL без TLS
DPS_MESSAGE_HUB_KAFKA__TOPICS dict (JSON) → KafkaTopics Соответствие логического топика реальному имени в Kafka. Обязателен ключ assets, напр. {"assets": "assets_broadcast"}

Формирование параметров подключения (src/dps_message_hub/infra/app.py): адрес брокера — вычисляемое поле kafka.uri (host:port). Безопасность через faststream.security.SASLScram512:

  • если заданы USERNAME и PASSWORD и SSL_CAFILE пуст — SASLScram512(..., use_ssl=False);
  • если задан SSL_CAFILESASLScram512(..., ssl_context=create_ssl_context(cafile=...)).

Переменные инфраструктуры, сборки и запуска

Не читаются классами настроек приложения, но участвуют в запуске/сборке/деплое.

Переменная Где используется Назначение
DPS_MESSAGE_HUB_NUM_WORKERS scripts/entrypoint.sh, Helm envs Число воркеров FastStream (faststream run --workers). В Helm _default: '2'
DPS_MESSAGE_HUB_PYTHON_IMAGE_NAME Dockerfile (ARG) Базовый образ Python (по умолчанию python)
DPS_MESSAGE_HUB_PYTHON_IMAGE_TAG Dockerfile (ARG) Тег базового образа (по умолчанию 3.13-slim)
PIP_INDEX_URL, PIP_TRUSTED_HOST Dockerfile (ARG) Индекс/доверенный хост pip при сборке

Сборка (Dockerfile): многостадийная — стадия builder собирает wheel'ы из requirements/requirements.txt, стадия runner ставит их, копирует src/ и устанавливает пакет (pip install . --no-deps); процесс запускается непривилегированным пользователем dps_message_hub. Целевая версия Python — 3.13 (.python-version, requires-python >=3.13).

Переменные из Helm-чарта (.helm/values.yaml)

Сервис деплоится через зависимость universal-chart (.helm/Chart.yaml, версия 0.1.7). Настраивается один сервис — services.api (тип нагрузки — deployment, replicaCount._default: 1). HTTP-service и ingress отключены, health-пробы (liveness/readiness, путь /ping) — enabled: false (у сервиса нет HTTP-эндпоинтов).

Обычные значения (блок services.api.envs) различаются по окружениям (_default/stage/preprod/production) адресами БД и Kafka, именем БД и именами топиков. В Helm дополнительно заданы (отсутствуют в .example.env): DPS_MESSAGE_HUB_KAFKA__HOST, DPS_MESSAGE_HUB_KAFKA__PORT (9091), DPS_MESSAGE_HUB_KAFKA__SSL_CAFILE (/opt/config/ca.crt), DPS_MESSAGE_HUB_DOCUMENTATION_DB__ENABLE_SSL=true, SSL_MODE=verify-full, SSL_ROOT_CERT_PATH=/opt/config/ca.crt.

Значения из секретов (блок secretEnvs, монтируются как env через secretKeyRef):

Переменная Секрет (_default / stage) Ключ (secretKey)
DPS_MESSAGE_HUB_DOCUMENTATION_DB__USER ya-pg-secret / documentations-postgresql-secret username
DPS_MESSAGE_HUB_DOCUMENTATION_DB__PASSWORD ya-pg-secret / documentations-postgresql-secret password
DPS_MESSAGE_HUB_KAFKA__USERNAME kafka-secret username
DPS_MESSAGE_HUB_KAFKA__PASSWORD kafka-secret password

Помимо env, чарт монтирует CA-сертификат Яндекса из ConfigMap ya-ca-cert (ключ ca.crt) как файл /opt/config/ca.crt (том cm-ya-ca-cert, readOnly) — на него указывают DPS_MESSAGE_HUB_KAFKA__SSL_CAFILE и DPS_MESSAGE_HUB_DOCUMENTATION_DB__SSL_ROOT_CERT_PATH.

Переменные в CI (.gitlab-ci.yml)

Пайплайн подключает общие шаблоны из generic/common-ci (common-security-scan.yaml, universal-pipeline.yaml, ref apps-business) и переключает окружение по ветке/тегу через workflow.rules:

Условие STAND NAMESPACE CHART_VERSION K8S_HUSTLER_BRANCH
MR (merge_request_event) сборка образа отключена (ENABLE_BUILD_IMAGE=false)
ветка stage stage documentations 0.0.1-stage stage
ветка master preprod documentations-preprod 0.0.1-preprod preprod
тег (CI_COMMIT_TAG) prod documentations-prod 0.0.1-prod master

Ключевые переменные пайплайна: SERVICE_NAME=dps-message-hub, DOCKERFILE_PATH=Dockerfile, CI_TRIGGER_SOURCE=app, RELEASE_NAME=dps-message-hub, CHART_NAME=dps-message-hub, флаги ENABLE_BUILD_CHART/ENABLE_BUILD_IMAGE/ENABLE_DEPLOY, HELM_SET_ARGS (--set universal-chart...). Отдельные job'ы format (ruff format --diff) и lint (ruff check) на образе python:3.13-slim.

Замечания и потенциальные проблемы

  • Приложение не читает .env автоматически (в SettingsConfigDict нет env_file). make config только создаёт .env из шаблона — переменные нужно экспортировать самому либо передавать контейнеру через --env-file.
  • Большинство полей БД и Kafka обязательны (без дефолтов): при пустом окружении настройки не пройдут валидацию и сервис не стартует. Единственные необязательные — APP__LOG_LEVEL, APP__IS_DEV, KAFKA__SSL_CAFILE.
  • DPS_MESSAGE_HUB_APP__BROKER_TYPE обязателен; поддерживается только kafka (иных веток в match нет). При другом значении брокер не будет создан.
  • При ENABLE_SSL=true обязательно задавать SSL_MODE и SSL_ROOT_CERT_PATH, иначе валидатор настроек прервёт старт.
  • DPS_MESSAGE_HUB_KAFKA__TOPICS обязан содержать ключ assets (модель KafkaTopics); прочие ключи игнорируются, отсутствие assets — ошибка старта.
  • Поле APP__IS_DEV присутствует в настройках, но в текущем коде нигде не задействовано.
  • Обработка Kafka-сообщений идёт с auto_commit=False и middleware Retry (src/dps_message_hub/interface/middleware.py), которая повторяет обработку бесконечно с экспоненциальной задержкой (до 1<<10 = 1024 сек) — «отравленное» сообщение может заблокировать партицию.

Минимальный набор для локального запуска

Kafka и Zookeeper поднимаются через Makefile (цели run-deps/run-zookeeper/run-kafka); PostgreSQL — внешний. Минимально нужно задать:

  • DPS_MESSAGE_HUB_APP__BROKER_TYPE=kafka;
  • DPS_MESSAGE_HUB_DOCUMENTATION_DB__HOST, __PORT, __USER, __PASSWORD, __NAME, __ENABLE_SSL (для локали false), __SSL_MODE, __SSL_ROOT_CERT_PATH (при ENABLE_SSL=false можно пустыми);
  • DPS_MESSAGE_HUB_KAFKA__HOST, __PORT, __USERNAME, __PASSWORD, __TOPICS (JSON с ключом assets);
  • DPS_MESSAGE_HUB_NUM_WORKERS (для entrypoint.sh).

Локальный запуск: make run (через entrypoint.sh) либо make run-dev (faststream run --factory --reload dps_message_hub.infra.app:get_app). Готовые значения-примеры приведены в dps-message-hub.env.example рядом с этим документом.