from __future__ import annotations from pathlib import Path from ._services_common import ( _LogFn, _detect_mode, _ensure_namespace, _exists, _kubectl, _log, _manifest_path, _namespace, _to_bool, _wait_rollout, ) def _opentofu_namespace(namespace: str | None, env: dict | None) -> str: if env: explicit = str(env.get("OPENTOFU_NAMESPACE") or "").strip() if explicit: return explicit return _namespace(namespace, env, default="default") def _manifest(project_root: str | Path) -> Path: return _manifest_path(project_root, "k8s", "opentofu", "deployment.yaml") def initialize( *, namespace: str | None = None, env: dict | None = None, project_root: str | Path = ".", log: _LogFn | None = None, mode: str | None = None, ) -> None: update(namespace=namespace, env=env, project_root=project_root, log=log, mode=mode) def start( *, namespace: str | None = None, env: dict | None = None, project_root: str | Path = ".", log: _LogFn | None = None, mode: str | None = None, ) -> None: update(namespace=namespace, env=env, project_root=project_root, log=log, mode=mode) def update( *, namespace: str | None = None, env: dict | None = None, project_root: str | Path = ".", log: _LogFn | None = None, mode: str | None = None, ) -> None: _detect_mode(mode, env) # mode kept for API parity target_ns = _opentofu_namespace(namespace, env) _ensure_namespace(target_ns, env) manifest = _manifest(project_root) if not manifest.exists(): raise RuntimeError(f"OpenTofu manifest not found: {manifest}") _log(log, f"[OPENTOFU] Applying {manifest}") _kubectl( ["-n", target_ns, "apply", "-f", str(manifest)], env=env, timeout=240, check=True, ) _wait_rollout("deployment", "opentofu", target_ns, env=env) def stop( *, namespace: str | None = None, env: dict | None = None, log: _LogFn | None = None, ) -> None: target_ns = _opentofu_namespace(namespace, env) if _exists("deployment", "opentofu", target_ns, env=env): _log(log, f"[OPENTOFU] Scaling deployment/opentofu to 0 in namespace {target_ns}") _kubectl( ["-n", target_ns, "scale", "deployment/opentofu", "--replicas=0"], env=env, timeout=90, check=True, ) def restart( *, namespace: str | None = None, env: dict | None = None, log: _LogFn | None = None, ) -> None: target_ns = _opentofu_namespace(namespace, env) if _exists("deployment", "opentofu", target_ns, env=env): _log(log, f"[OPENTOFU] Restarting deployment/opentofu in namespace {target_ns}") _kubectl( ["-n", target_ns, "rollout", "restart", "deployment/opentofu"], env=env, timeout=120, check=True, ) _wait_rollout("deployment", "opentofu", target_ns, env=env) def status( *, namespace: str | None = None, env: dict | None = None, ) -> bool: target_ns = _opentofu_namespace(namespace, env) dep = _kubectl( ["-n", target_ns, "get", "deployment", "opentofu", "-o", "jsonpath={.status.readyReplicas}"], env=env, timeout=20, ) svc = _kubectl(["-n", target_ns, "get", "svc", "opentofu"], env=env, timeout=20) return _to_bool( dep.returncode == 0 and (dep.stdout or "0").strip() not in {"", "0"} and svc.returncode == 0 )