freeleaps-ops/apps/gitea-webhook-ambassador-python/app/config.py

189 lines
6.0 KiB
Python

"""
Configuration management module
Supports environment dispatch, deduplication strategy, and queue configuration
"""
from typing import Dict, List, Optional
from pydantic import Field, validator
from pydantic_settings import BaseSettings
import yaml
from pathlib import Path
class EnvironmentConfig(BaseSettings):
"""Environment configuration"""
branches: List[str] = Field(default_factory=list)
jenkins_job: str
jenkins_url: str
priority: int = Field(default=1, ge=1, le=10)
class DeduplicationConfig(BaseSettings):
"""Deduplication configuration"""
enabled: bool = True
window_seconds: int = Field(default=300, ge=1) # 5-minute deduplication window
strategy: str = Field(default="commit_branch") # commit_hash + branch
cache_ttl: int = Field(default=3600, ge=1) # Cache for 1 hour
class QueueConfig(BaseSettings):
"""Queue configuration"""
max_concurrent: int = Field(default=10, ge=1)
max_retries: int = Field(default=3, ge=0)
retry_delay: int = Field(default=60, ge=1) # seconds
priority_levels: int = Field(default=3, ge=1, le=10)
class JenkinsConfig(BaseSettings):
"""Jenkins configuration"""
username: str
token: str
timeout: int = Field(default=30, ge=1)
retry_attempts: int = Field(default=3, ge=1)
class DatabaseConfig(BaseSettings):
"""Database configuration"""
url: str = Field(default="sqlite:///./webhook_ambassador.db")
echo: bool = False
pool_size: int = Field(default=10, ge=1)
max_overflow: int = Field(default=20, ge=0)
class RedisConfig(BaseSettings):
"""Redis configuration"""
url: str = Field(default="redis://localhost:6379/0")
password: Optional[str] = None
db: int = Field(default=0, ge=0)
class LoggingConfig(BaseSettings):
"""Logging configuration"""
level: str = Field(default="INFO")
format: str = Field(default="json")
file: Optional[str] = None
class SecurityConfig(BaseSettings):
"""Security configuration"""
secret_key: str
webhook_secret_header: str = Field(default="X-Gitea-Signature")
rate_limit_per_minute: int = Field(default=100, ge=1)
class Settings(BaseSettings):
"""Main configuration class"""
# Basic configuration
app_name: str = "Gitea Webhook Ambassador"
version: str = "1.0.0"
debug: bool = False
# Server configuration
host: str = "0.0.0.0"
port: int = Field(default=8000, ge=1, le=65535)
# Database configuration
database_url: str = Field(default="sqlite:///./webhook_ambassador.db")
# Redis configuration
redis_url: str = Field(default="redis://localhost:6379/0")
redis_password: str = Field(default="")
redis_db: int = Field(default=0)
# Jenkins configuration
jenkins_username: str = Field(default="admin")
jenkins_token: str = Field(default="")
jenkins_timeout: int = Field(default=30)
# Security configuration
security_secret_key: str = Field(default="")
security_webhook_secret_header: str = Field(default="X-Gitea-Signature")
security_rate_limit_per_minute: int = Field(default=100)
# Logging configuration
logging_level: str = Field(default="INFO")
logging_format: str = Field(default="json")
logging_file: str = Field(default="")
# Queue configuration
queue_max_concurrent: int = Field(default=10)
queue_max_retries: int = Field(default=3)
queue_retry_delay: int = Field(default=60)
queue_priority_levels: int = Field(default=3)
# Deduplication configuration
deduplication_enabled: bool = Field(default=True)
deduplication_window_seconds: int = Field(default=300)
deduplication_strategy: str = Field(default="commit_branch")
deduplication_cache_ttl: int = Field(default=3600)
# Business configuration
environments: Dict[str, EnvironmentConfig] = Field(default_factory=dict)
deduplication: DeduplicationConfig = DeduplicationConfig()
queue: QueueConfig = QueueConfig()
class Config:
env_file = ".env"
env_nested_delimiter = "__"
@validator("environments", pre=True)
def load_environments_from_file(cls, v):
"""Load environment configuration from file"""
if isinstance(v, dict) and v:
return v
# Try to load from config file
config_file = Path("config/environments.yaml")
if config_file.exists():
with open(config_file, "r", encoding="utf-8") as f:
config_data = yaml.safe_load(f)
return config_data.get("environments", {})
# Default configuration
return {
"dev": EnvironmentConfig(
branches=["dev", "develop", "development"],
jenkins_job="alpha-build",
jenkins_url="https://jenkins-alpha.example.com",
priority=2
),
"prod": EnvironmentConfig(
branches=["prod", "production", "main", "master"],
jenkins_job="production-build",
jenkins_url="https://jenkins-prod.example.com",
priority=1
),
"default": EnvironmentConfig(
branches=["*"],
jenkins_job="default-build",
jenkins_url="https://jenkins-default.example.com",
priority=3
)
}
def get_environment_for_branch(self, branch: str) -> Optional[EnvironmentConfig]:
"""Get environment configuration by branch name"""
for env_name, env_config in self.environments.items():
if branch in env_config.branches or "*" in env_config.branches:
return env_config
return None
def get_environment_by_name(self, name: str) -> Optional[EnvironmentConfig]:
"""Get configuration by environment name"""
return self.environments.get(name)
# Global configuration instance
settings = Settings()
def get_settings() -> Settings:
"""Get configuration instance"""
return settings
def reload_settings():
"""Reload configuration"""
global settings
settings = Settings()