#!/usr/bin/env bash
# Stellt einen Frontend-Knoten von der festen Redis-Adresse auf die Waechter um.
#
#   redis-auf-sentinel-umstellen.sh pruefen <ip>
#   redis-auf-sentinel-umstellen.sh umstellen <ip>
#
# Form der DSN - hier steckt die ganze Arbeit:
#
#   redis://:PASSWORT@10.0.3.1:26379?host[10.0.3.2:26379]&host[10.0.3.3:26379]&redis_sentinel=riccardo
#
#   * Das Passwort steht in der BENUTZERINFO, nicht als auth= in der Query.
#     Symfony trennt beides: Benutzerinfo ist der Zugang zu Redis, auth= der
#     Zugang zum Waechter. Unsere Waechter verlangen keinen; stuende das
#     Passwort in der Query, schickte Symfony es ihnen und die Anmeldung
#     scheiterte mit "no password configured for the default user".
#   * Der erste Waechter steht als Host in der Adresse, die anderen beiden
#     als host[] in der Query - parse_url() lehnt eine Benutzerinfo ohne
#     Host ab.
#   * Die Datenbanknummer kommt als &dbindex=N. Die alte Schreibweise /7
#     funktioniert hier nicht mehr: bei einer Sentinel-DSN gibt es keinen
#     Pfad, aus dem Symfony sie lesen koennte.
#
# Geht nach der Umstellung etwas schief, wird die gesicherte .env.local
# automatisch zurueckgespielt. Deshalb immer nur EIN Knoten auf einmal - der
# andere traegt derweil den Verkehr.
set -uo pipefail

BEFEHL="${1:?pruefen oder umstellen}"
IP="${2:?IP des Frontends}"
VERBUND=riccardo
WAECHTER1=10.0.3.1:26379
WEITERE='host[10.0.3.2:26379]&host[10.0.3.3:26379]'
ZIEL=/var/www/riccardo

cd "$(dirname "$0")"
source ./lib-knoten.sh
rz_pruefe_schluessel || exit 1

echo "== $IP =="
rz_ssh "$IP" "cd $ZIEL && grep -oE '^(REDIS_URL|MESSENGER_TRANSPORT_DSN|MESSENGER_TRANSPORT_LOW_PRIORITY_DSN)=redis://[^@]*@[^ ]*' .env.local \
  | sed -E 's#(redis://)[^@]*@#\1***@#' | sed 's/^/   ist:  /'"

[ "$BEFEHL" = umstellen ] || { echo "   Nur geprueft."; exit 0; }

SICHERUNG="/root/.env.local.vor-sentinel-$(date +%Y%m%d-%H%M%S)"
rz_ssh "$IP" "cp $ZIEL/.env.local $SICHERUNG && echo '   gesichert nach $SICHERUNG'"

rz_ssh "$IP" "cd $ZIEL && python3 - <<'PYEOF'
import re
from urllib.parse import urlparse, quote

datei = '.env.local'
inhalt = open(datei, encoding='utf-8').read()

alt = re.search(r'^REDIS_URL=(.+)\$', inhalt, re.M).group(1).strip()
pw = quote(urlparse(alt).password or '', safe='')

vorn = 'redis://:%s@$WAECHTER1' % pw
neu = {
    'REDIS_URL': '%s?$WEITERE&redis_sentinel=$VERBUND' % vorn,
    'MESSENGER_TRANSPORT_DSN':
        '%s?$WEITERE&sentinel=$VERBUND&dbindex=11&stream=rz_messages&group=rz_workers' % vorn,
    'MESSENGER_TRANSPORT_LOW_PRIORITY_DSN':
        '%s?$WEITERE&sentinel=$VERBUND&dbindex=11&stream=rz_messages_low&group=rz_workers' % vorn,
}
for name, wert in neu.items():
    inhalt, anzahl = re.subn(r'^%s=.*\$' % name, '%s=%s' % (name, wert), inhalt, flags=re.M)
    if anzahl != 1:
        raise SystemExit('   %s kam %d mal vor - abgebrochen' % (name, anzahl))

open(datei, 'w', encoding='utf-8').write(inhalt)
print('   drei Adressen umgeschrieben')
PYEOF" || { echo "   Umschreiben fehlgeschlagen"; exit 1; }

echo "   Datenbanknummern in redis.yaml auf dbindex umstellen"
rz_ssh "$IP" "cd $ZIEL && sed -i -E 's#%env\(REDIS_URL\)%/([0-9]+)#%env(REDIS_URL)%\&dbindex=\1#g' config/packages/redis.yaml \
  && grep -c 'dbindex=' config/packages/redis.yaml | sed 's/^/   Stellen: /'"

echo "   Cache leeren und FPM neu laden"
rz_ssh "$IP" "cd $ZIEL && sudo -u www-data /usr/bin/php8.5 bin/console cache:clear -q 2>&1 | tail -2; systemctl reload php8.5-fpm"

echo "   Gegenprobe"
CODE=$(rz_ssh "$IP" "curl -s -o /dev/null -w '%{http_code}' -H 'Host: shop.riccardo-zigarette.de' http://127.0.0.1/")
ADMIN=$(rz_ssh "$IP" "curl -s -o /dev/null -w '%{http_code}' -H 'Host: shop.riccardo-zigarette.de' http://127.0.0.1/admin")
echo "   Shop $CODE, Admin $ADMIN"

if [ "$CODE" = 200 ] && [ "$ADMIN" = 200 ]; then
    echo "   umgestellt"
    exit 0
fi

echo "   ANTWORTET NICHT - alter Stand wird zurueckgespielt"
rz_ssh "$IP" "cp $SICHERUNG $ZIEL/.env.local \
  && cd $ZIEL && git checkout config/packages/redis.yaml 2>/dev/null || sed -i -E 's#%env\(REDIS_URL\)%&dbindex=([0-9]+)#%env(REDIS_URL)%/\1#g' config/packages/redis.yaml; \
  sudo -u www-data /usr/bin/php8.5 bin/console cache:clear -q; systemctl reload php8.5-fpm"
rz_ssh "$IP" "curl -s -o /dev/null -w '   nach Rueckbau: %{http_code}\n' -H 'Host: shop.riccardo-zigarette.de' http://127.0.0.1/"
exit 1
