#!/usr/bin/env python3 import argparse, os, sys try: import yaml except Exception as e: print("ERROR: PyYAML is required. Install with: pip install pyyaml", file=sys.stderr) sys.exit(2) def main(): p = argparse.ArgumentParser(description="Add a host to inventory/servers.yaml") p.add_argument("--name", required=True) p.add_argument("--type", default="cpx11") p.add_argument("--region", default="nbg1") p.add_argument("--role", default="test") p.add_argument("--image", default="ubuntu-24.04") p.add_argument("--user", default="admin") p.add_argument( "--reuse-existing", action="store_true", help="succeed only when an existing record exactly matches the request", ) args = p.parse_args() inv_path = os.path.join("inventory", "servers.yaml") data = {} if os.path.exists(inv_path): with open(inv_path, "r", encoding="utf-8") as f: data = yaml.safe_load(f) or {} servers = data.setdefault("servers", []) candidate = { "name": args.name, "provider": "hetzner", "lifecycle_mode": "provider-managed", "ssh_user": args.user, "baseline_profile": "ufw-managed", "provisioning": { "server_type": args.type, "region": args.region, "role": args.role, "image": args.image, "labels": [], }, } existing = next((s for s in servers if s.get("name") == args.name), None) if existing is not None: if args.reuse_existing and existing == candidate: print(f"Reusing matching host '{args.name}' from {inv_path}") return print( f"ERROR: host '{args.name}' already exists with a different declaration", file=sys.stderr, ) sys.exit(1) data.setdefault("schema_version", "1.0") servers.append(candidate) with open(inv_path, "w", encoding="utf-8") as f: yaml.safe_dump(data, f, sort_keys=False) if __name__ == "__main__": main()