Source code for constellation_utils.cli

"""`constellation` CLI — currently just `constellation doctor` for the MVP.

Usage:
    constellation doctor [--profile testing|production]

Reads the active R2 credentials via the secrets backend and prints a
green/red status. Designed for fast feedback during onboarding and as
a smoke step in rig deploy scripts.
"""

from __future__ import annotations

import os
import sys

import tyro

from constellation_utils.secrets import ConstellationAuthError, cloudflare, r2
from constellation_utils.secrets._backends import select_backend
from constellation_utils.secrets._config import current_profile, load_profile

_GREEN = "\033[32m"
_RED = "\033[31m"
_DIM = "\033[2m"
_RESET = "\033[0m"


def _supports_color() -> bool:
    return sys.stdout.isatty() and os.environ.get("NO_COLOR") is None


def _ok(msg: str) -> str:
    return f"{_GREEN}{_RESET} {msg}" if _supports_color() else f"[OK]   {msg}"


def _fail(msg: str) -> str:
    return f"{_RED}{_RESET} {msg}" if _supports_color() else f"[FAIL] {msg}"


def _dim(msg: str) -> str:
    return f"{_DIM}{msg}{_RESET}" if _supports_color() else msg


[docs] def doctor(profile: str | None = None) -> int: """Smoke-test that the active profile can read its credentials. Args: profile: Override CONSTELLATION_PROFILE for this run (testing|production). When unset, uses the env var (defaults to testing). """ if profile: os.environ["CONSTELLATION_PROFILE"] = profile try: active_profile = current_profile() except ValueError as exc: print(_fail(f"profile resolution failed: {exc}")) return 1 try: backend = select_backend() except ConstellationAuthError as exc: print(_fail("auth backend selection failed:")) for line in str(exc).splitlines(): print(f" {line}") return 1 backend_name = backend.__class__.__name__ print(_dim(f"profile: {active_profile} backend: {backend_name}")) # Force the cache miss in case `r2()` was somehow invoked earlier # in the same process (e.g. importing for side effects). r2.cache_clear() try: creds = r2() except ConstellationAuthError as exc: print(_fail("R2 credentials could not be read:")) for line in str(exc).splitlines(): print(f" {line}") return 1 except Exception as exc: # noqa: BLE001 — surface anything unexpected with context print(_fail(f"R2 credentials could not be read: {exc.__class__.__name__}: {exc}")) return 1 masked_key = ( creds.access_key_id[:4] + "…" + creds.access_key_id[-2:] if creds.access_key_id else "<empty>" ) print(_ok(f"R2 ({active_profile}) reachable")) print(_dim(f" endpoint : {creds.endpoint}")) print(_dim(f" bucket : {creds.bucket}")) print(_dim(f" region : {creds.region}")) print(_dim(f" access_key_id : {masked_key}")) # Cloudflare is optional in the active profile — only smoke-test # when the YAML maps it. Keeps doctor green for older profiles. cfg = load_profile(active_profile) if "cloudflare" in cfg: cloudflare.cache_clear() try: cf = cloudflare() except ConstellationAuthError as exc: print(_fail("Cloudflare credentials could not be read:")) for line in str(exc).splitlines(): print(f" {line}") return 1 except Exception as exc: # noqa: BLE001 print(_fail( f"Cloudflare credentials could not be read: " f"{exc.__class__.__name__}: {exc}" )) return 1 masked_token = ( cf.api_token[:4] + "…" + cf.api_token[-4:] if cf.api_token else "<empty>" ) print(_ok(f"Cloudflare ({active_profile}) reachable")) print(_dim(f" account_id : {cf.account_id}")) print(_dim(f" api_token : {masked_token}")) return 0
[docs] def main() -> None: """Tyro entry point. Dispatches subcommands. Currently `doctor` is the only subcommand. Adding more later (e.g. `bootstrap`, `audit`) is a one-line change to the dict below. """ rc = tyro.extras.subcommand_cli_from_dict( {"doctor": doctor}, prog="constellation", description=__doc__, ) sys.exit(rc if isinstance(rc, int) else 0)
if __name__ == "__main__": main()