mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Configuration loader for infra_controller. Parses YAML, resolves paths."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
CONFIG_DIR = Path(__file__).resolve().parent.parent / "config"
|
|
|
|
|
|
def load_yaml(path: Path) -> dict[str, Any]:
|
|
"""Load YAML file, supporting both PyYAML and syck."""
|
|
try:
|
|
import yaml
|
|
with open(path) as fh:
|
|
return yaml.safe_load(fh) or {}
|
|
except ImportError:
|
|
pass
|
|
# pyyaml not available? try syck (python3-syck on Debian)
|
|
try:
|
|
import syck
|
|
return syck.load(open(path, 'rb').read()) or {}
|
|
except ImportError:
|
|
raise ImportError("No YAML library available. Install python3-pyyaml or python3-syck")
|
|
|
|
|
|
def resolve_env_vars(data: dict) -> dict:
|
|
"""Recursively resolve ${VAR} in string values."""
|
|
if isinstance(data, dict):
|
|
return {k: resolve_env_vars(v) for k, v in data.items()}
|
|
if isinstance(data, list):
|
|
return [resolve_env_vars(v) for v in data]
|
|
if isinstance(data, str) and "${" in data:
|
|
import re
|
|
def _repl(m):
|
|
return os.environ.get(m.group(1), "")
|
|
return re.sub(r'\$\{([^}]+)\}', _repl, data)
|
|
return data
|
|
|
|
|
|
def load_config(path: Path | None = None) -> dict[str, Any]:
|
|
"""Load and process the main config file."""
|
|
if path is None:
|
|
path = CONFIG_DIR / "nodes.yaml"
|
|
raw = load_yaml(path)
|
|
config = resolve_env_vars(raw)
|
|
|
|
# Flatten nodes dict for convenience
|
|
node_entries = config.get("nodes", {})
|
|
flat_nodes = {}
|
|
for name, cfg in node_entries.items():
|
|
flat_nodes[name] = {
|
|
"ip": cfg["tailscale_ip"],
|
|
"ssh_target": cfg.get("ssh_target", f"root@{cfg['tailscale_ip']}"),
|
|
"roles": cfg.get("roles", []),
|
|
"probes": cfg.get("probes", ["system"]),
|
|
"optional": cfg.get("optional", False),
|
|
}
|
|
config["nodes"] = flat_nodes
|
|
return config
|