iac/apps/resources/CONFIGURATION.md

20 KiB
Raw Permalink Blame History

Конфигурация проекта sarex-resources

Документ описывает все переменные окружения и способы конфигурирования сервиса ресурсов (sarex-resources, backend модуля «Ресурсы/Проекты»).

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

Сервис — приложение на Django 4.1 + Django REST Framework (GeoDjango/PostGIS). В отличие от сервисов на pydantic-settings, конфигурация задаётся классическими Django settings-модулями в server/config/settings/, а не единым классом настроек:

  • base.py — общие настройки (приложения, middleware, DRF, S3, интеграция с Sarex, OpenTelemetry);
  • production.py — наследует base.py (from .base import *), задаёт DEBUG=False, ALLOWED_HOSTS, БД, CORS, S3, статику;
  • test.py — наследует base.py, отдельная тестовая БД, снятие permission-классов DRF.

Активный модуль выбирается переменной DJANGO_SETTINGS_MODULE. По умолчанию (server/config/wsgi.py, server/manage.py) — config.settings.production.

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

  • префикса у переменных нет — имена плоские (DATABASE_HOST, YC_S3_BUCKET_NAME и т.п.);
  • значения читаются напрямую через os.getenv(...); вложенных секций/делимитеров (как __ в pydantic-сервисах) нет;
  • типизация и валидация окружения отсутствуют — всё приходит строками; булевы флаги (USE_OTEL, USE_INSECURE) проверяются на «truthy», поэтому любая непустая строка, включая "False", считается истиной (см. «Замечания»);
  • .env-файл приложением не загружается автоматически — переменные должны быть в окружении процесса (docker-compose environment, k8s env/secretKeyRef, либо set -a && . ./.env && set +a).

Важно для прод-развёртывания. В кластере файл server/config/settings/production.py подменяется содержимым ConfigMap django-configmap (монтируется на /server/config/settings/production.py, см. infra/iac/apps/resources/base/django-configmap.yaml и .helm/templates/api.yaml). Именно версия из ConfigMap определяет фактические ALLOWED_HOSTS, CORS_*, SERVICE_ACCOUNTS_HOST, cookie-имена и часть значений Sarex. Репозиторный production.py — это шаблон/локальный вариант.

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

Способ запуска Откуда берутся переменные
Локально (docker-compose) docker-compose.yml — сервисы postgres/api; переменные Postgres задаются в environment, приложение читает окружение контейнера
Локально (тесты) docker-compose.test.yml + pytest.ini (DJANGO_SETTINGS_MODULE=config.settings.test), переменные DJANGO_POSTGRES_*
Kubernetes (Helm-чарт репозитория) .helm/values-<env>.yaml: блоки envs (обычные значения) и secrets (из k8s-секретов); шаблон .helm/templates/api.yaml
Kubernetes (infra, GitOps) infra/iac/apps/resources/* — kustomize base (Vault-инъекция env в аннотациях Deployment + ConfigMaps) и оверлеи brusnika-stage/brusnika-prod (helmrelease.yaml, universal-chart)
CI/CD (GitLab) .gitlab-ci.yml: подключает общие шаблоны generic/common-ci, переключает окружение по ветке/тегу через workflow.rules

Способы запуска процессов:

Команда Точка входа Назначение
uwsgi --ini /opt/server/uwsgi.ini config.wsgi:application HTTP API (uWSGI, порт 8000)
python manage.py migrate manage.py Применение миграций (в entrypoint.sh перед стартом uWSGI)
python manage.py <command> manage.py Служебные Django-команды (createsuperuser, shell, миграции и т.п.)
pytest config.settings.test Юнит-тесты (compose/test_server/entrypoint.sh)

Порядок запуска в контейнере (compose/server/entrypoint.sh): сначала python manage.py migrate, затем opentelemetry-instrument uwsgi --plugin python3 --ini /opt/server/uwsgi.ini с DJANGO_SETTINGS_MODULE=config.settings.production.

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

Все переменные плоские (без префикса). Дефолт означает, что значение при обращении вернёт None/пусто (Django/psycopg2 или интеграции могут упасть уже в рантайме, а не на старте).

Выбор настроек

Переменная Тип Значение по умолчанию Назначение
DJANGO_SETTINGS_MODULE string config.settings.production Модуль настроек Django. Значения: config.settings.production / config.settings.test

Окружение и трейсинг (base.py)

Блок OpenTelemetry активируется целиком по USE_OTEL (django-otel-tools): добавляется OtelMiddleware, настраивается трейсер и OTEL-логгер.

Переменная Тип Значение по умолчанию Назначение
USE_OTEL bool-ish False (выкл.) Включение трейсинга. Truthy-проверка: любая непустая строка включает
SERVICE_NAME string resources-backend.sarex-resources Имя сервиса в трейсах
TRACER_ENDPOINT string localhost:4375 Адрес OTLP-коллектора
USE_INSECURE bool-ish False Небезопасное (без TLS) подключение к коллектору; та же truthy-проверка
ENVIRONMENT string prod Метка окружения в атрибутах трейсинга (stage/preprod/prod)
MODULE string resources Атрибут module в трейсинге
TEAM string platform_team Атрибут team в трейсинге
COMPONENT string backend Атрибут component в трейсинге

База данных (production.py, django.contrib.gis.db.backends.postgis)

Переменная Тип Значение по умолчанию Назначение
DATABASE_HOST string Хост PostgreSQL/PostGIS
DATABASE_PORT int (string) Порт PostgreSQL
DATABASE_NAME string Имя базы данных
DATABASE_USER string Пользователь БД
DATABASE_PASSWORD string Пароль пользователя БД

БД требует расширения PostGIS (образ postgis/postgis), т.к. используются гео-поля (Location.geometry/geography) и django.contrib.gis. TLS к БД настраивается на уровне libpq: в Helm-чарте секрет yc-pg-certificate монтируется как /root/.postgresql/root.crt (в settings отдельного sslmode нет).

База данных для тестов (test.py)

Переменная Тип Значение по умолчанию Назначение
DJANGO_POSTGRES_DB string resources Имя тестовой БД
DJANGO_POSTGRES_USER string postgres Пользователь тестовой БД
DJANGO_POSTGRES_PASSWORD string 12345678dev Пароль тестовой БД
DJANGO_POSTGRES_HOST string test_postgres Хост тестовой БД
DJANGO_POSTGRES_PORT int (string) 5432 Порт тестовой БД

Дополнительно test.py выставляет DJANGO_ALLOW_ASYNC_UNSAFE=true в коде.

S3 / объектное хранилище (base.py и production.py, django-storages + boto3)

Файлы (ResourcePhoto.image и т.п.) хранятся в S3-совместимом хранилище; DEFAULT_FILE_STORAGE=storages.backends.s3boto3.S3Boto3Storage, AWS_DEFAULT_ACL="public-read".

Переменная Тип Значение по умолчанию Назначение (Django-настройка)
YC_S3_ACCESS_KEY_ID string AWS_ACCESS_KEY_ID
YC_S3_SECRET_ACCESS_KEY string AWS_SECRET_ACCESS_KEY
YC_S3_BUCKET_NAME string AWS_STORAGE_BUCKET_NAME
YC_S3_ENDPOINT_URL string AWS_S3_ENDPOINT_URL

Интеграция с ядром Sarex (base.py)

Используется для получения токена (/api/token/) и списка пользователей (/api/core/users/) в эндпоинтах группировки пользователей/ресурсов (users-grouped-by-resource, users-with-resources).

Переменная Тип Значение по умолчанию Назначение
SAREX_HOST string https://lk.sarex.io Базовый хост Sarex (SAREX_BASE_HOST)
SAREX_ADMIN_USERNAME string Логин сервисной учётки Sarex
SAREX_ADMIN_PASSWORD string Пароль сервисной учётки Sarex
SERVICE_ACCOUNTS_HOST string https://lk.sarex.io/api/core Определяется в production.py; кодом приложения напрямую не читается (см. «Замечания»)

Переменные инфраструктуры, сборки и вспомогательных утилит

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

Переменная Где используется Назначение
API_ADDRESS .helm/values-*.yaml, infra/.../backend-deployment.yaml Задаётся в окружении (8000), кодом не читается — порт фактически берётся из uwsgi.ini (http = 0.0.0.0:8000)
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB docker-compose.yml, docker-compose.test.yml Инициализация контейнера Postgres (не путать с DATABASE_*, которые читает Django)
PYTHONUNBUFFERED Dockerfile Небуферизованный stdout/stderr
build-настройки uWSGI compose/server/uwsgi.ini processes=8, http=0.0.0.0:8000, harakiri, buffer-size, static-map для /static и /media

Приватный индекс пакетов для сборки (django-otel-tools) задан прямо в requirements/base.txt через --extra-index-url (nexus.infra.sarex.io).

Переменные из Helm-чарта репозитория (.helm/values-<env>.yaml)

Обычные значения — блок envs, секреты — блок secrets (монтируются как env через secretKeyRef). Значения различаются по окружениям (stage/preprod/production): адрес БД (DATABASE_HOST), SERVICE_NAME, TRACER_ENDPOINT, ENVIRONMENT, число реплик.

Значения из секретов:

Переменная Секрет (secret_name) Ключ (secret_key)
DATABASE_USER ya-pg-secret user
DATABASE_PASSWORD ya-pg-secret password
YC_S3_ACCESS_KEY_ID yc-s3-secret key_id
YC_S3_SECRET_ACCESS_KEY yc-s3-secret access_key
YC_S3_BUCKET_NAME yc-s3-secret storage_bucket_name
YC_S3_ENDPOINT_URL yc-s3-secret endpoint_url
SAREX_ADMIN_USERNAME sarex-auth-secret username
SAREX_ADMIN_PASSWORD sarex-auth-secret password

Помимо env, чарт монтирует CA-сертификат PostgreSQL из секрета yc-pg-certificate (ключ certificate) как файл /root/.postgresql/root.crt, а также ConfigMap uwsgi-configmap (файл uwsgi.ini). Прочие значения чарта (не переменные приложения): deployment.* (имя, образ, порт, реплики, ресурсы), service_*, api_host (istio VirtualService, prefix /resource-management).

Переменные из infra (GitOps, kustomize base)

В infra/iac/apps/resources/base/backend-deployment.yaml секреты БД и S3 подаются через HashiCorp Vault Agent (аннотации vault.hashicorp.com/*), который рендерит файлы /vault/secrets/resources-db и /vault/secrets/resources-s3; они подгружаются в окружение в args контейнера (set -a && . /vault/secrets/... && set +a) перед запуском entrypoint.sh.

Переменная Источник (Vault path / значение)
DATABASE_HOST postgresql.resources.svc.cluster.local (шаблон Vault)
DATABASE_PORT 5432
DATABASE_NAME resources_db
DATABASE_USER secrets/data/postgresql/apps/resourcesusername
DATABASE_PASSWORD secrets/data/postgresql/apps/resourcespassword
YC_S3_ENDPOINT_URL secrets/data/minio/apps/resourcesclient.endpoint
YC_S3_BUCKET_NAME resources
YC_S3_ACCESS_KEY_ID secrets/data/minio/apps/resourcesaccess_key
YC_S3_SECRET_ACCESS_KEY secrets/data/minio/apps/resourcessecret_key
DJANGO_SETTINGS_MODULE config.settings.production (env Deployment)
API_ADDRESS 8000 (env Deployment)

Оверлеи brusnika-stage/brusnika-prod используют HelmRelease (universal-chart): env DJANGO_SETTINGS_MODULE, DATABASE_HOST/PORT/NAME, API_ADDRESS, YC_S3_ENDPOINT_URL, YC_S3_BUCKET_NAME; секреты DATABASE_USER/PASSWORD (postgres-secret), YC_S3_ACCESS_KEY_ID/SECRET_ACCESS_KEY (yc-s3-secret, ключи key-id/access-key).

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

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

Условие STAND Namespace RELEASE_NAME
ветка master preprod resources-preprod resources
ветка stage stage resources-stage sarex-resources
тег (CI_COMMIT_TAG) prod resources-prod sarex-resources

Ключевые переменные пайплайна: CHART_NAME=sarex-resources, CHART_VERSION, DOCKERFILE_PATH=./compose/server/Dockerfile, IMAGE_PATH=deployment.image, HELM_SET_ARGS (--set deployment.image=…), флаги ENABLE_LINTER/ENABLE_BUILD_CHART/ENABLE_BUILD_IMAGE/ENABLE_STATE_UPDATE/ENABLE_DEPLOY. Job linter запускает flake8 (образ python:3.8-buster).

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

  • Truthy-флаги. USE_OTEL и USE_INSECURE читаются как os.getenv(name, False) без приведения типа. Любая непустая строка — истина, включая "False", "0", "no". Чтобы выключить трейсинг, переменную USE_OTEL нужно не задавать вовсе (а не ставить в False). В Helm-values она задана строкой "True".
  • .env не загружается автоматически. В settings нет python-dotenv/env_file; переменные должны попадать в окружение процесса (compose environment, k8s env/Vault, ручной export).
  • production.py подменяется в кластере. Репозиторный production.py содержит хардкод ALLOWED_HOSTS, CORS_*, тестовый SECRET_KEY и др.; в проде используется версия из ConfigMap django-configmap. Различия: ALLOWED_HOSTS=['*'], другой SERVICE_ACCOUNTS_HOST, хардкод SAREX_ADMIN_*/SAREX_BASE_HOST, cookie-имена resource-sessionid/resource-csrftoken.
  • SECRET_KEY захардкожен в base.py/production.py (в т.ч. пометка # Delete after Test) — секрет не берётся из окружения. Для реального прода его следует вынести в секрет.
  • SERVICE_ACCOUNTS_HOST определяется, но напрямую в коде не используется (интеграции ходят по SAREX_BASE_HOST); переменная задаётся «на вырост».
  • DATABASE_* без дефолтов. При отсутствии переменных Django получит None и подключение к БД упадёт в рантайме (не на импортстарте). Пять переменных БД обязательны для рабочего запуска.
  • Аутентификация DRF отключена. DEFAULT_AUTHENTICATION_CLASSES=[], permission-классы не заданы (эффективно AllowAny) — доступ ограничивается только сетевым слоем/istio. Учитывать при публикации.
  • Имя релиза различается между окружениями (resources на preprod vs sarex-resources на stage/prod) — при работе с Helm/namespace это легко перепутать.

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

Postgres (PostGIS) поднимается через docker-compose up postgres, приложение — через сервис api (docker-compose.yml) или локально uwsgi/manage.py runserver. Минимально необходимо задать:

  • DJANGO_SETTINGS_MODULE=config.settings.production (или свой dev-модуль)
  • DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD
  • YC_S3_* — если задействуется загрузка файлов/статики в S3 (иначе операции с файлами упадут)
  • SAREX_HOST, SAREX_ADMIN_USERNAME, SAREX_ADMIN_PASSWORD — если нужны эндпоинты интеграции с пользователями Sarex
  • OTEL — по умолчанию не задавать (USE_OTEL отсутствует); при включении — USE_OTEL=1, SERVICE_NAME, TRACER_ENDPOINT, при необходимости USE_INSECURE

Для тестов достаточно поднять docker-compose.test.yml — переменные DJANGO_POSTGRES_* имеют рабочие дефолты, pytest.ini уже указывает config.settings.test.

Готовые значения-примеры для всех переменных приведены в .env.example.