railiance-infra/scripts/new_host.py
codex b93af8cc78
Some checks failed
CI Smoke / source-contract (push) Failing after 2s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Implement reproducible S1 handoff contracts
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02994-7685-7940-bf34-3555b8256018
2026-08-23 12:02:23 +02:00

63 lines
2 KiB
Python

#!/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()