#!/bin/bash
# hapman-apply: install HAPMan's staged HAProxy config and reload HAProxy.
#
# Runs as root via a single sudoers rule. Takes no arguments: it only ever
# reads the fixed staging file, copies it somewhere the hapman user can't
# touch, validates that copy, then installs it. If the reload fails the
# previous config is put back.
set -euo pipefail

STAGE=/var/lib/hapman/staging.cfg
TARGET=/etc/haproxy/haproxy.cfg
BACKUP=/etc/haproxy/haproxy.cfg.hapman-prev
HAPROXY=/usr/sbin/haproxy

if [[ $# -ne 0 ]]; then
  echo "hapman-apply takes no arguments" >&2
  exit 64
fi
if [[ ! -s "$STAGE" ]]; then
  echo "No staged config at $STAGE" >&2
  exit 66
fi

WORK=$(mktemp -d /run/hapman-apply.XXXXXX)
trap 'rm -rf "$WORK"' EXIT
install -m 0644 -o root -g root "$STAGE" "$WORK/haproxy.cfg"

if ! head -n1 "$WORK/haproxy.cfg" | grep -q '^# Managed by HAPMan'; then
  echo "Staged file is not a HAPMan config; refusing" >&2
  exit 65
fi

if ! "$HAPROXY" -c -q -f "$WORK/haproxy.cfg"; then
  echo "Validation failed; live config unchanged" >&2
  "$HAPROXY" -c -f "$WORK/haproxy.cfg" 2>&1 | sed "s#$WORK/##g" >&2 || true
  exit 2
fi

if [[ -f "$TARGET" ]]; then
  cp -a "$TARGET" "$BACKUP"
fi
install -m 0644 -o root -g root "$WORK/haproxy.cfg" "$TARGET"

if systemctl is-active --quiet haproxy; then
  ACTION=reload
else
  ACTION=start
fi

if ! systemctl "$ACTION" haproxy; then
  echo "HAProxy $ACTION failed; restoring previous config" >&2
  if [[ -f "$BACKUP" ]]; then
    install -m 0644 -o root -g root "$BACKUP" "$TARGET"
    systemctl restart haproxy || true
  fi
  journalctl -u haproxy -n 15 --no-pager >&2 || true
  exit 3
fi

echo "HAProxy ${ACTION}ed with the new config"
