Files
MessageGateway/app/core/config.py
Sergey Antropov b90def35ed Initial commit: Message Gateway project
- FastAPI приложение для отправки мониторинговых алертов в мессенджеры
- Поддержка Telegram и MAX/VK
- Интеграция с Grafana, Zabbix, AlertManager
- Автоматическое создание тикетов в Jira
- Управление группами мессенджеров через API
- Декораторы для авторизации и скрытия эндпоинтов
- Подробная документация в папке docs/

Автор: Сергей Антропов
Сайт: https://devops.org.ru
2025-11-12 20:25:11 +03:00

133 lines
4.9 KiB
Python
Raw Permalink 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.

"""
Конфигурация приложения.
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import os
import logging
from typing import Optional
from pydantic_settings import BaseSettings, SettingsConfigDict
logger = logging.getLogger(__name__)
class Settings(BaseSettings):
"""Настройки приложения из переменных окружения."""
# Telegram настройки
telegram_bot_token: Optional[str] = None
telegram_enabled: bool = True
# MAX/VK настройки
max_access_token: Optional[str] = None
max_api_version: str = "5.131"
max_enabled: bool = False
# Общие настройки мессенджеров
default_messenger: str = "telegram" # По умолчанию Telegram
# Файлы конфигурации
groups_config_path: str = "/app/config/groups.json"
templates_path: str = "/app/templates"
# API ключ для авторизации
api_key: Optional[str] = None
# Grafana настройки
grafana_url: Optional[str] = None
# Zabbix настройки
zabbix_url: Optional[str] = None
# Kubernetes кластер настройки
k8s_cluster_grafana_subdomain: Optional[str] = None
k8s_cluster_prometheus_subdomain: Optional[str] = None
k8s_cluster_alertmanager_subdomain: Optional[str] = None
# Prometheus Pushgateway настройки
pushgateway_url: Optional[str] = None
pushgateway_job: str = "MessageGateway"
# OpenTelemetry настройки
otel_enabled: bool = False
otel_service_name: str = "monitoring-message-gateway"
otel_exporter_otlp_endpoint: Optional[str] = None
otel_exporter_otlp_protocol: str = "http/json"
otel_traces_exporter: str = "otlp_proto_http"
otel_exporter_otlp_insecure: bool = True
otel_python_log_correlation: bool = False
# Jira настройки
jira_enabled: bool = False
jira_url: Optional[str] = None
jira_email: Optional[str] = None
jira_api_token: Optional[str] = None
jira_project_key: Optional[str] = None
jira_default_assignee: Optional[str] = None
jira_default_issue_type: str = "Bug"
jira_mapping_config_path: str = "/app/config/jira_mapping.json"
jira_create_on_alert: bool = True
jira_create_on_resolved: bool = False
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
extra="ignore",
env_ignore_empty=True
)
def validate_required(self) -> None:
"""Проверка обязательных переменных окружения."""
if not self.telegram_bot_token:
logger.warning("TELEGRAM_BOT_TOKEN не установлен - приложение может не работать")
# Не выбрасываем исключение, чтобы приложение могло запуститься
def get_k8s_grafana_url(self, cluster: str) -> str:
"""Получить URL Grafana для Kubernetes кластера."""
if not self.k8s_cluster_grafana_subdomain:
raise ValueError("K8S_CLUSTER_GRAFANA_SUBDOMAIN не установлен")
return f"{cluster}.{self.k8s_cluster_grafana_subdomain}"
def get_k8s_prometheus_url(self, cluster: str) -> str:
"""Получить URL Prometheus для Kubernetes кластера."""
if not self.k8s_cluster_prometheus_subdomain:
raise ValueError("K8S_CLUSTER_PROMETHEUS_SUBDOMAIN не установлен")
return f"{cluster}.{self.k8s_cluster_prometheus_subdomain}"
def get_k8s_alertmanager_url(self, cluster: str) -> str:
"""Получить URL AlertManager для Kubernetes кластера."""
if not self.k8s_cluster_alertmanager_subdomain:
raise ValueError("K8S_CLUSTER_ALERTMANAGER_SUBDOMAIN не установлен")
return f"{cluster}.{self.k8s_cluster_alertmanager_subdomain}"
# Глобальный экземпляр настроек (валидация отложена до первого использования)
_settings_instance: Optional[Settings] = None
def get_settings() -> Settings:
"""
Получить экземпляр настроек (lazy initialization).
Returns:
Экземпляр Settings.
"""
global _settings_instance
if _settings_instance is None:
_settings_instance = Settings()
return _settings_instance
# Глобальный экземпляр настроек (lazy initialization)
class _SettingsProxy:
"""Прокси для ленивой инициализации settings."""
def __getattr__(self, name):
"""Получить атрибут из settings."""
return getattr(get_settings(), name)
settings = _SettingsProxy()