fisrt
This commit is contained in:
1
backend/app/core/__init__.py
Normal file
1
backend/app/core/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Core configuration modules
|
||||
111
backend/app/core/config.py
Normal file
111
backend/app/core/config.py
Normal 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()
|
||||
47
backend/app/core/database.py
Normal file
47
backend/app/core/database.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Configuration de la base de données SQLAlchemy
|
||||
"""
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from pathlib import Path
|
||||
|
||||
# Base pour les modèles SQLAlchemy
|
||||
Base = declarative_base()
|
||||
|
||||
# Engine et session
|
||||
engine = None
|
||||
SessionLocal = None
|
||||
|
||||
|
||||
def init_database(db_path: str = "./data/db.sqlite"):
|
||||
"""Initialise la connexion à la base de données"""
|
||||
global engine, SessionLocal
|
||||
|
||||
# Créer le dossier data si nécessaire
|
||||
Path(db_path).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Créer l'engine SQLite
|
||||
database_url = f"sqlite:///{db_path}"
|
||||
engine = create_engine(
|
||||
database_url,
|
||||
connect_args={"check_same_thread": False},
|
||||
echo=False
|
||||
)
|
||||
|
||||
# Créer la session factory
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
# Créer les tables
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
return engine
|
||||
|
||||
|
||||
def get_db():
|
||||
"""Dependency pour obtenir une session DB"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
Reference in New Issue
Block a user