"""Host configuration and tool-host validation. All host IPs are Tailscale IPs (except nas-company which also works via Tailscale). """ from __future__ import annotations import os from dataclasses import dataclass, field from dotenv import load_dotenv load_dotenv() @dataclass(frozen=True) class HostConfig: ip: str user: str auth: str # "key" | "password" docker_path: str = "docker" needs_sudo: bool = False password: str | None = None # only for auth="password" HOSTS: dict[str, HostConfig] = { "gpu": HostConfig( ip="100.111.160.84", user="hyungi", auth="key", ), "macmini": HostConfig( ip="100.76.254.116", user="hyungi", auth="key", ), "nas-company": HostConfig( ip="100.71.132.52", user="hyungi", auth="password", docker_path="/usr/local/bin/docker", needs_sudo=True, password=os.getenv("NAS_COMPANY_PASSWORD"), ), } # Per-tool allowed hosts — invalid host → immediate error TOOL_HOST_MAP: dict[str, list[str]] = { "docker_status": ["gpu", "nas-company"], "docker_logs": ["gpu", "nas-company"], "disk_usage": ["gpu", "macmini", "nas-company"], "ollama_models": ["gpu", "macmini"], "mlx_models": ["macmini"], } # SSH timeouts SSH_TIMEOUT = 5 # connection timeout (seconds) CMD_TIMEOUT = 10 # command execution timeout (seconds) MAX_RETRIES = 1 # retry once on failure def validate_host(tool: str, host: str) -> HostConfig: """Validate host is allowed for tool and return config. Raises ValueError if invalid.""" allowed = TOOL_HOST_MAP.get(tool) if allowed and host not in allowed: raise ValueError( f"'{host}'는 {tool}에서 지원하지 않습니다. 허용: {', '.join(allowed)}" ) config = HOSTS.get(host) if not config: raise ValueError( f"알 수 없는 호스트: '{host}'. 허용: {', '.join(HOSTS.keys())}" ) return config