2026-02-05 11:29:34 +01:00
|
|
|
import os
|
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
|
|
DEFAULT_CONFIG_PATH = os.path.expanduser("~/.config/loopaware/infra-cli.yaml")
|
|
|
|
|
|
|
|
|
|
class Config:
|
|
|
|
|
def __init__(self, config_path=None):
|
|
|
|
|
self.path = config_path or os.environ.get("INFRA_CONFIG") or DEFAULT_CONFIG_PATH
|
|
|
|
|
self.data = self._load()
|
|
|
|
|
|
|
|
|
|
def _load(self):
|
|
|
|
|
if not os.path.exists(self.path):
|
|
|
|
|
# Fallback to local config if exists
|
|
|
|
|
if os.path.exists("config.yaml"):
|
2026-02-05 17:13:40 +01:00
|
|
|
self.path = os.path.abspath("config.yaml")
|
2026-02-05 11:29:34 +01:00
|
|
|
else:
|
|
|
|
|
raise FileNotFoundError(f"Config file not found at {self.path}. Please create it based on config.yaml.example")
|
|
|
|
|
|
|
|
|
|
with open(self.path, 'r') as f:
|
2026-02-05 17:13:40 +01:00
|
|
|
return yaml.safe_load(f)
|
2026-02-05 11:29:34 +01:00
|
|
|
|
|
|
|
|
def get(self, key, default=None):
|
|
|
|
|
parts = key.split('.')
|
|
|
|
|
val = self.data
|
|
|
|
|
for part in parts:
|
|
|
|
|
if isinstance(val, dict) and part in val:
|
|
|
|
|
val = val[part]
|
|
|
|
|
else:
|
|
|
|
|
return default
|
|
|
|
|
return val
|
2026-02-05 17:13:40 +01:00
|
|
|
|
|
|
|
|
def get_node(self, node_name):
|
|
|
|
|
"""Helper to get proxmox node details by name or default to first if none provided"""
|
|
|
|
|
nodes = self.get('proxmox.nodes', {})
|
|
|
|
|
if not nodes:
|
|
|
|
|
# Fallback for old single-host config if present
|
|
|
|
|
host = self.get('proxmox.host')
|
|
|
|
|
if host:
|
|
|
|
|
return {"host": host, "pass": self.get('proxmox.password')}
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
if not node_name:
|
|
|
|
|
# Default to first node found
|
|
|
|
|
return next(iter(nodes.values()))
|
|
|
|
|
|
|
|
|
|
return nodes.get(node_name)
|
|
|
|
|
|