#!/bin/bash
# Install (or verify) the WAN-follows-VRRP mechanism on a VyOS router.
#
# This exists because on 2026-09-05 the sim's failover proof was obtained from
# scripts that had been hand-`sed`-ed in place: /config/vrrp-wan-health and
# -reconcile differed from git by an edited VIP, so the tested behaviour was not
# the committed behaviour and any reinstall would have silently reverted it.
# `--check` makes that class of drift a hard failure instead of a discovery.
#
# It installs ONLY the mechanism -- scripts, units, drop-in, settings. It never
# touches VyOS configuration: the `interfaces pppoe` node, `vif 53 disable` and
# the VRRP sync-group hooks are config and belong in the config model
# (labsim/sim-*.py for the sim, infra/vyos/subtrees/overrides.json for
# production), not in an installer.
#
#   vrrp-wan-install --vip 192.168.1.1 [--host vyos@10.0.1.253]
#   vrrp-wan-install --check [--host ...]     # exits non-zero on any drift
#
# With no --host it operates on the local machine, so it can be scp'd to a
# router and run there.
set -uo pipefail

HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VIP=""; HOST=""; MODE=install; PW="${VYOS_PW:-vyos}"

while [ $# -gt 0 ]; do
  case "$1" in
    --vip)   VIP="$2"; shift 2 ;;
    --host)  HOST="$2"; shift 2 ;;
    --check) MODE=check; shift ;;
    *) echo "usage: $0 [--vip A.B.C.D] [--host user@ip] [--check]" >&2; exit 2 ;;
  esac
done

SSH_OPTS=(-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
          -o LogLevel=ERROR -o ConnectTimeout=8 -o PreferredAuthentications=password)
run() {  # run a command on the target
  if [ -n "$HOST" ]; then timeout 60 sshpass -p "$PW" ssh "${SSH_OPTS[@]}" "$HOST" "$@"
  else bash -c "$*"; fi
}
put() {  # copy a file to the target
  if [ -n "$HOST" ]; then timeout 60 sshpass -p "$PW" scp "${SSH_OPTS[@]}" "$1" "$HOST:$2" >/dev/null
  else cp "$1" "$2"; fi
}

# script -> destination. take/release are hooks keepalived calls; both exec the
# reconciler, so there is one code path.
SCRIPTS="vrrp-wan-reconcile vrrp-wan-apply vrrp-wan-health vrrp-wan-guard vrrp-wan-take vrrp-wan-release"
UNITS="vrrp-wan-reconcile.service vrrp-wan-reconcile.timer vrrp-wan-guard.service vrrp-wan-guard.timer"
GATE_DIR=/etc/systemd/system/ppp@pppoe0.service.d
GATE=$GATE_DIR/10-vrrp-wan-gate.conf

if [ "$MODE" = check ]; then
  rc=0
  for f in $SCRIPTS; do
    local_sum=$(md5sum "$HERE/$f" | cut -d' ' -f1)
    remote_sum=$(run "md5sum /config/$f 2>/dev/null | cut -d' ' -f1")
    [ "$local_sum" = "$remote_sum" ] || { echo "  DRIFT /config/$f"; rc=1; }
  done
  for f in $UNITS; do
    local_sum=$(md5sum "$HERE/$f" | cut -d' ' -f1)
    remote_sum=$(run "md5sum /etc/systemd/system/$f 2>/dev/null | cut -d' ' -f1")
    [ "$local_sum" = "$remote_sum" ] || { echo "  DRIFT /etc/systemd/system/$f"; rc=1; }
  done
  gate_sum=$(md5sum "$HERE/ppp-vrrp-gate.conf" | cut -d' ' -f1)
  remote_gate=$(run "md5sum $GATE 2>/dev/null | cut -d' ' -f1")
  [ "$gate_sum" = "$remote_gate" ] || { echo "  DRIFT $GATE (a VyOS upgrade wipes /etc -- both routers would dial)"; rc=1; }
  run "[ -r /config/vrrp-wan.conf ]" || { echo "  MISSING /config/vrrp-wan.conf"; rc=1; }
  for t in vrrp-wan-reconcile.timer vrrp-wan-guard.timer; do
    [ "$(run "systemctl is-enabled $t 2>/dev/null")" = enabled ] || { echo "  NOT ENABLED $t"; rc=1; }
  done
  [ "$rc" -eq 0 ] && echo "  vrrp-wan in sync"
  exit "$rc"
fi

[ -n "$VIP" ] || { echo "--vip is required to install" >&2; exit 2; }

for f in $SCRIPTS; do
  put "$HERE/$f" "/tmp/$f"
  # root:vyattacfg 0775 -- vrrp-wan-apply enters config mode, which requires
  # membership of vyattacfg.
  run "sudo install -o root -g vyattacfg -m 0775 /tmp/$f /config/$f"
done

# Settings, with the VIP substituted. One file, read by BOTH the reconciler and
# the health check -- keepalived invokes the latter with no environment at all,
# so an Environment= line in the unit would be read by one and not the other.
sed "s|^VRRP_WAN_VIP=.*|VRRP_WAN_VIP=${VIP}|" "$HERE/vrrp-wan.conf" > /tmp/vrrp-wan.conf.gen
put /tmp/vrrp-wan.conf.gen /tmp/vrrp-wan.conf.gen
run "sudo install -o root -g vyattacfg -m 0664 /tmp/vrrp-wan.conf.gen /config/vrrp-wan.conf"

for f in $UNITS; do
  put "$HERE/$f" "/tmp/$f"
  run "sudo install -m 0644 /tmp/$f /etc/systemd/system/$f"
done

put "$HERE/ppp-vrrp-gate.conf" /tmp/ppp-vrrp-gate.conf
run "sudo mkdir -p $GATE_DIR && sudo install -m 0644 /tmp/ppp-vrrp-gate.conf $GATE"

run "sudo systemctl daemon-reload && sudo systemctl enable --now vrrp-wan-reconcile.timer vrrp-wan-guard.timer" >/dev/null 2>&1

echo "  installed (vip=$VIP)"
run "sudo /config/vrrp-wan-reconcile --status"
