keepalived_cable.sh

#!/bin/bash
# Cambia la interfaz VRRP de keepalived a la de cable (procedimiento de docs/operacion.md).
# Uso, en el propio nodo:  sudo bash keepalived_cable.sh enp1s0   (master-2)
#                          sudo bash keepalived_cable.sh enp2s0   (master-3)
# Se para sin cambiar nada si algo no está bien.
set -euo pipefail
NUEVA="${1:?Indica la interfaz: enp1s0 en master-2, enp2s0 en master-3}"
CONF=/etc/keepalived/keepalived.conf

[ "$(id -u)" -eq 0 ] || { echo "Lánzalo con sudo"; exit 1; }
ip link show "$NUEVA" >/dev/null 2>&1 || { echo "✘ No existe la interfaz $NUEVA en $(hostname)"; exit 1; }

echo "1/4 ¿Llegan por $NUEVA los anuncios VRRP del master-1 (192.0.2.112)?"
n=$(timeout 12 tcpdump -ni "$NUEVA" -c 10 vrrp 2>/dev/null | grep -c "192.0.2.112" || true)
echo "    $n de 10 anuncios recibidos"
[ "$n" -ge 8 ] || { echo "✘ Llegan pocos anuncios: NO cambio nada (el BACKUP no oiría al MASTER)"; exit 1; }

echo "2/4 Copia y cambio de interfaz"
cp -a "$CONF" "$CONF.bak-$(date +%F-%H%M)"
[ "$(grep -cE '^\s*interface\s' "$CONF")" -eq 1 ] || { echo "✘ Hay más de una línea interface: edítalo a mano"; exit 1; }
sed -i -E "s/^(\s*interface\s+)\S+/\1$NUEVA/" "$CONF"
grep -nE '^\s*interface\s' "$CONF"

echo "3/4 Validar la configuración"
out=$(keepalived -t -f "$CONF" 2>&1 || true)
otros=$(grep -v 'Truncating auth_pass' <<<"$out" | grep . || true)
if [ -n "$otros" ]; then
  echo "$otros"
  cp -a "$(ls -t "$CONF".bak-* | head -1)" "$CONF"
  echo "✘ La configuración da errores: he dejado la anterior y NO reinicio keepalived"
  exit 1
fi
echo "    OK"

echo "4/4 Reiniciar keepalived"
systemctl restart keepalived
sleep 5
estado=$(journalctl -u keepalived -n 50 --no-pager | grep -oiE 'entering (master|backup|fault) state' | tail -1 || true)
echo "    $estado"
case "${estado,,}" in
  *backup*) echo "✓ $(hostname): keepalived en BACKUP por $NUEVA" ;;
  *master*) echo "⚠ $(hostname) se ha quedado la VIP (MASTER): avisa a Claude" ;;
  *)        echo "✘ Estado inesperado: avisa a Claude" ;;
esac