""" Sovereign Orchestrator - Configuration Module Loads application configuration from environment variables and the ~/.proxmox-credentials file. """ import os import logging from pathlib import Path from dataclasses import dataclass, field logger = logging.getLogger(__name__) _CREDENTIALS_PATH = Path.home() / ".proxmox-credentials" def _load_credentials_file() -> dict[str, str]: """Parse the ~/.proxmox-credentials file into a dict of key=value pairs.""" creds: dict[str, str] = {} if not _CREDENTIALS_PATH.exists(): logger.warning("Credentials file not found at %s", _CREDENTIALS_PATH) return creds try: for line in _CREDENTIALS_PATH.read_text().splitlines(): line = line.strip() if not line or line.startswith("#"): continue if "=" in line: key, _, value = line.partition("=") creds[key.strip()] = value.strip() except OSError as exc: logger.error("Failed to read credentials file: %s", exc) return creds _creds = _load_credentials_file() @dataclass(frozen=True) class Settings: """Application settings with env-var overrides.""" # Proxmox connection proxmox_host: str = os.getenv( "PROXMOX_HOST", _creds.get("PROXMOX_HOST", "https://localhost:8006") ) proxmox_token_id: str = os.getenv( "PROXMOX_TOKEN_ID", _creds.get("PROXMOX_TOKEN_ID", "") ) proxmox_token_secret: str = os.getenv( "PROXMOX_TOKEN_SECRET", _creds.get("PROXMOX_TOKEN_SECRET", "") ) # Storage paths iso_storage_path: str = os.getenv( "ISO_STORAGE_PATH", "/var/lib/vz/template/iso" ) build_output_path: str = os.getenv( "BUILD_OUTPUT_PATH", "/tmp/sovereign-orchestrator/builds" ) # Defaults default_node: str = os.getenv("DEFAULT_NODE", "dl380-0") default_vmid: int = int(os.getenv("DEFAULT_VMID", "900")) default_storage: str = os.getenv("DEFAULT_STORAGE", "local") # App app_host: str = os.getenv("APP_HOST", "0.0.0.0") app_port: int = int(os.getenv("APP_PORT", "8888")) # Reference answers.toml template answers_template_path: str = os.getenv( "ANSWERS_TEMPLATE_PATH", "/home/william/dev/theta42/proxmox-appliance-automation/files/answers.toml", ) settings = Settings()