This commit is contained in:
2025-12-06 12:28:55 +01:00
parent 56d633e296
commit 13b3c58ec8
56 changed files with 4328 additions and 1 deletions

111
backend/app/core/config.py Normal file
View File

@@ -0,0 +1,111 @@
"""
Configuration management pour IPWatch
Charge et valide le fichier config.yaml
"""
import yaml
from pathlib import Path
from typing import Dict, Any, List, Optional
from pydantic import BaseModel, Field
class AppConfig(BaseModel):
"""Configuration de l'application"""
name: str = "IPWatch"
version: str = "1.0.0"
debug: bool = False
class NetworkConfig(BaseModel):
"""Configuration réseau"""
cidr: str
gateway: Optional[str] = None
dns: Optional[List[str]] = None
class ScanConfig(BaseModel):
"""Configuration des scans"""
ping_interval: int = 60 # secondes
port_scan_interval: int = 300 # secondes
parallel_pings: int = 50
timeout: float = 1.0
class PortsConfig(BaseModel):
"""Configuration des ports à scanner"""
ranges: List[str] = ["22", "80", "443", "3389", "8080"]
class HistoryConfig(BaseModel):
"""Configuration de l'historique"""
retention_hours: int = 24
class UIConfig(BaseModel):
"""Configuration UI"""
offline_transparency: float = 0.5
show_mac: bool = True
show_vendor: bool = True
class ColorsConfig(BaseModel):
"""Configuration des couleurs"""
free: str = "#75715E"
online_known: str = "#A6E22E"
online_unknown: str = "#66D9EF"
offline_known: str = "#F92672"
offline_unknown: str = "#AE81FF"
class DatabaseConfig(BaseModel):
"""Configuration base de données"""
path: str = "./data/db.sqlite"
class IPWatchConfig(BaseModel):
"""Configuration complète IPWatch"""
app: AppConfig = Field(default_factory=AppConfig)
network: NetworkConfig
ip_classes: Dict[str, Any] = Field(default_factory=dict)
scan: ScanConfig = Field(default_factory=ScanConfig)
ports: PortsConfig = Field(default_factory=PortsConfig)
locations: List[str] = Field(default_factory=list)
hosts: List[str] = Field(default_factory=list)
history: HistoryConfig = Field(default_factory=HistoryConfig)
ui: UIConfig = Field(default_factory=UIConfig)
colors: ColorsConfig = Field(default_factory=ColorsConfig)
database: DatabaseConfig = Field(default_factory=DatabaseConfig)
class ConfigManager:
"""Gestionnaire de configuration singleton"""
_instance: Optional['ConfigManager'] = None
_config: Optional[IPWatchConfig] = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def load_config(self, config_path: str = "./config.yaml") -> IPWatchConfig:
"""Charge la configuration depuis le fichier YAML"""
path = Path(config_path)
if not path.exists():
raise FileNotFoundError(f"Fichier de configuration non trouvé: {config_path}")
with open(path, 'r', encoding='utf-8') as f:
yaml_data = yaml.safe_load(f)
self._config = IPWatchConfig(**yaml_data)
return self._config
@property
def config(self) -> IPWatchConfig:
"""Retourne la configuration actuelle"""
if self._config is None:
raise RuntimeError("Configuration non chargée. Appelez load_config() d'abord.")
return self._config
# Instance globale
config_manager = ConfigManager()