124 lines
4.1 KiB
Python

"""
Configuration centralisée de l'application.
Toutes les variables d'environnement et paramètres sont centralisés ici.
"""
import os
from pathlib import Path
from typing import Optional
from pydantic import Field
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
"""Configuration de l'application Homelab Automation."""
# === Chemins ===
base_dir: Path = Field(default_factory=lambda: Path(__file__).resolve().parent.parent)
logs_dir: Path = Field(default_factory=lambda: Path(os.environ.get("LOGS_DIR", "/logs")))
@property
def ansible_dir(self) -> Path:
"""Répertoire Ansible (relatif à base_dir.parent)"""
return self.base_dir.parent / "ansible"
@property
def tasks_logs_dir(self) -> Path:
"""Répertoire des logs de tâches markdown"""
return Path(os.environ.get("DIR_LOGS_TASKS", str(self.base_dir.parent / "tasks_logs")))
@property
def db_path(self) -> Path:
"""Chemin de la base de données SQLite"""
return self.logs_dir / "homelab.db"
# === SSH ===
ssh_key_path: str = Field(
default_factory=lambda: os.environ.get("SSH_KEY_PATH", str(Path.home() / ".ssh" / "id_rsa"))
)
ssh_user: str = Field(default_factory=lambda: os.environ.get("SSH_USER", "automation"))
ssh_remote_user: str = Field(default_factory=lambda: os.environ.get("SSH_REMOTE_USER", "root"))
# === API ===
api_key: str = Field(default_factory=lambda: os.environ.get("API_KEY", "dev-key-12345"))
api_title: str = "Homelab Automation Dashboard API"
api_version: str = "1.0.0"
api_description: str = "API REST moderne pour la gestion automatique d'homelab"
# === JWT Authentication ===
jwt_secret_key: str = Field(
default_factory=lambda: os.environ.get("JWT_SECRET_KEY", "dev-secret-key-change-in-production")
)
jwt_expire_minutes: int = Field(
default_factory=lambda: int(os.environ.get("JWT_EXPIRE_MINUTES", "1440"))
)
jwt_algorithm: str = "HS256"
# === Database ===
database_url: Optional[str] = Field(default=None)
@property
def async_database_url(self) -> str:
"""URL de connexion async pour SQLAlchemy"""
if self.database_url:
return self.database_url
return f"sqlite+aiosqlite:///{self.db_path}"
# === CORS ===
cors_origins: list = Field(default=["*"])
cors_allow_credentials: bool = True
cors_allow_methods: list = Field(default=["*"])
cors_allow_headers: list = Field(default=["*"])
# === Notifications ntfy ===
ntfy_enabled: bool = Field(
default_factory=lambda: os.environ.get("NTFY_ENABLED", "true").lower() == "true"
)
ntfy_base_url: str = Field(
default_factory=lambda: os.environ.get("NTFY_BASE_URL", "https://ntfy.sh")
)
ntfy_default_topic: str = Field(
default_factory=lambda: os.environ.get("NTFY_TOPIC", "homelab-automation")
)
ntfy_timeout: int = Field(
default_factory=lambda: int(os.environ.get("NTFY_TIMEOUT", "10"))
)
ntfy_username: Optional[str] = Field(
default_factory=lambda: os.environ.get("NTFY_USERNAME")
)
ntfy_password: Optional[str] = Field(
default_factory=lambda: os.environ.get("NTFY_PASSWORD")
)
ntfy_token: Optional[str] = Field(
default_factory=lambda: os.environ.get("NTFY_TOKEN")
)
# === Scheduler ===
scheduler_timezone: str = Field(
default_factory=lambda: os.environ.get("SCHEDULER_TIMEZONE", "America/Montreal")
)
scheduler_misfire_grace_time: int = 300
# === Cache ===
hosts_cache_ttl: int = 60 # secondes
inventory_cache_ttl: int = 60 # secondes
logs_index_rebuild_interval: int = 60 # secondes
# === Server ===
host: str = "0.0.0.0"
port: int = 8008
reload: bool = Field(
default_factory=lambda: os.environ.get("RELOAD", "true").lower() == "true"
)
log_level: str = "info"
class Config:
env_file = ".env"
env_file_encoding = "utf-8"
extra = "ignore"
# Instance singleton de la configuration
settings = Settings()