freeleaps-ops/apps/gitea-webhook-ambassador-python/app/config.py
Nicolas f6c515157c feat: 添加 Python 版本的 Gitea Webhook Ambassador
- 新增完整的 Python 实现,替代 Go 版本
- 添加 Web 登录界面和仪表板
- 实现 JWT 认证和 API 密钥管理
- 添加数据库存储功能
- 保持与 Go 版本一致的目录结构和启动脚本
- 包含完整的文档和测试脚本
2025-07-20 21:17:10 +08:00

189 lines
5.8 KiB
Python

"""
配置管理模块
支持环境分发、防抖策略和队列配置
"""
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):
"""环境配置"""
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):
"""防抖配置"""
enabled: bool = True
window_seconds: int = Field(default=300, ge=1) # 5分钟防抖窗口
strategy: str = Field(default="commit_branch") # commit_hash + branch
cache_ttl: int = Field(default=3600, ge=1) # 缓存1小时
class QueueConfig(BaseSettings):
"""队列配置"""
max_concurrent: int = Field(default=10, ge=1)
max_retries: int = Field(default=3, ge=0)
retry_delay: int = Field(default=60, ge=1) # 秒
priority_levels: int = Field(default=3, ge=1, le=10)
class JenkinsConfig(BaseSettings):
"""Jenkins 配置"""
username: str
token: str
timeout: int = Field(default=30, ge=1)
retry_attempts: int = Field(default=3, ge=1)
class DatabaseConfig(BaseSettings):
"""数据库配置"""
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 配置"""
url: str = Field(default="redis://localhost:6379/0")
password: Optional[str] = None
db: int = Field(default=0, ge=0)
class LoggingConfig(BaseSettings):
"""日志配置"""
level: str = Field(default="INFO")
format: str = Field(default="json")
file: Optional[str] = None
class SecurityConfig(BaseSettings):
"""安全配置"""
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):
"""主配置类"""
# 基础配置
app_name: str = "Gitea Webhook Ambassador"
version: str = "1.0.0"
debug: bool = False
# 服务器配置
host: str = "0.0.0.0"
port: int = Field(default=8000, ge=1, le=65535)
# 数据库配置
database_url: str = Field(default="sqlite:///./webhook_ambassador.db")
# Redis 配置
redis_url: str = Field(default="redis://localhost:6379/0")
redis_password: str = Field(default="")
redis_db: int = Field(default=0)
# Jenkins 配置
jenkins_username: str = Field(default="admin")
jenkins_token: str = Field(default="")
jenkins_timeout: int = Field(default=30)
# 安全配置
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_level: str = Field(default="INFO")
logging_format: str = Field(default="json")
logging_file: str = Field(default="")
# 队列配置
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_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)
# 业务配置
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):
"""从配置文件加载环境配置"""
if isinstance(v, dict) and v:
return v
# 尝试从配置文件加载
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", {})
# 默认配置
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]:
"""根据分支名获取对应的环境配置"""
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]:
"""根据环境名获取配置"""
return self.environments.get(name)
# 全局配置实例
settings = Settings()
def get_settings() -> Settings:
"""获取配置实例"""
return settings
def reload_settings():
"""重新加载配置"""
global settings
settings = Settings()