diff --git a/bin/homelab b/bin/homelab index aba2f93..aa3ef04 100755 --- a/bin/homelab +++ b/bin/homelab @@ -703,6 +703,7 @@ def _vps_send(remote_path: str, content: str, mode: str) -> None: def cmd_render_vps_configs(args: argparse.Namespace) -> int: """Re-render /etc/turnserver.conf + /opt/management.json on the IONOS netbird VPS from templates in vps/, substituting secrets decrypted from sops.""" + import difflib # Decrypt the two sops files we need. turn = _decrypt_secret("turn-shared-secret") auth = _decrypt_secret("netbird-authentik-oidc") @@ -727,6 +728,7 @@ def cmd_render_vps_configs(args: argparse.Namespace) -> int: plans.append({ **t, "rendered": rendered, + "current": current, "changed": current != rendered, "current_present": cat.returncode == 0 and bool(current), }) @@ -743,8 +745,29 @@ def cmd_render_vps_configs(args: argparse.Namespace) -> int: print("Nothing to do — every target matches the rendered template.") return 0 + # Show diffs (always — both dry-run and live). + print() + for p in plans: + if not p["changed"]: + continue + print(f"--- diff for {p['remote']} ---") + # Mask any sops-decrypted secret values so they don't print to stdout. + def _mask(s): + for v in subs.values(): + s = s.replace(v, "") + return s + diff = difflib.unified_diff( + _mask(p["current"]).splitlines(keepends=True), + _mask(p["rendered"]).splitlines(keepends=True), + fromfile=f"vps:{p['remote']}", + tofile=f"rendered:{p['tmpl']}", + n=3, + ) + sys.stdout.writelines(diff) + print() + if args.dry_run: - print("\n--- dry-run: not applying ---") + print("--- dry-run: not applying ---") return 0 if not args.yes: