feat: initial orchestrator service with FastAPI backend and premium GUI
- FastAPI backend with full Proxmox VE API integration - ISO builder using proxmox-auto-install-assistant - Premium dark-mode SPA frontend with glassmorphism design - VM lifecycle management (create, start, stop, destroy) - Build pipeline tracking with real-time logs - Deployment automation for custom auto-installer ISOs - Production deployment script (setup.sh + systemd) - Comprehensive README with API documentation
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
"""
|
||||
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()
|
||||
Reference in New Issue
Block a user