#!/usr/bin/env python3 """Bootstrap ops-hub in Inter-Hub using the prepared ops-hub seeds. The script never prints full API keys. The operator key is read from IHUB_OPERATOR_KEY or IHUB_OPERATOR_KEY_FILE. If an ops-hub runtime key is created, the full key is written to a 0600 temp file and only the file path and key prefix are printed. """ from __future__ import annotations import argparse import json import os import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from ops_hub.bootstrap import ( # noqa: E402 DEFAULT_BASE, BootstrapError, dry_run_bootstrap, load_secret, run_bootstrap, ) def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--base", default=os.environ.get("IHUB_BASE", DEFAULT_BASE).rstrip("/")) parser.add_argument("--runtime-key-output", default=os.environ.get("OPS_HUB_RUNTIME_KEY_OUTPUT")) parser.add_argument("--dry-run", action="store_true", help="Plan bootstrap actions without mutating Inter-Hub") parser.add_argument("--skip-event", action="store_true", help="Do not submit the initial Gitea readiness event") return parser def main() -> int: args = build_parser().parse_args() operator_key = load_secret("IHUB_OPERATOR_KEY", "IHUB_OPERATOR_KEY_FILE") if not operator_key: print("ERROR: set IHUB_OPERATOR_KEY or IHUB_OPERATOR_KEY_FILE", file=sys.stderr) return 2 if args.dry_run: summary = dry_run_bootstrap(args.base, operator_key, skip_event=args.skip_event) else: summary = run_bootstrap( args.base, operator_key, runtime_key_output=args.runtime_key_output, skip_event=args.skip_event, ) print(json.dumps(summary, indent=2, sort_keys=True)) return 0 if __name__ == "__main__": try: raise SystemExit(main()) except BootstrapError as exc: print(f"ERROR: {exc}", file=sys.stderr) raise SystemExit(1)