#!/usr/bin/env bash
# Holt die Binärprotokolle vom Datenbankknoten und legt sie im Object Storage ab.
#
# Warum: Die Binlogs liegen auf den Datenbankknoten. Fällt ein Knoten aus, ist
# eine Wiederherstellung auf einen Zeitpunkt nur möglich, wenn die Protokolle
# woanders liegen. Zusammen mit der Nachtsicherung (3:17 Uhr) lässt sich damit
# jeder Stand dazwischen herstellen.
#
# Läuft stündlich auf Frontend 1. Zugangsdaten in /etc/riccardo-backup.env.
set -euo pipefail

exec 9>/var/lock/riccardo-binlog.lock
flock -n 9 || { echo "Ein anderer Lauf ist aktiv."; exit 0; }

ZIEL=/var/backups/riccardo-binlog
BEHALTEN_TAGE=7
BEHALTEN_TAGE_FERN=30

[ -f /etc/riccardo-backup.env ] && . /etc/riccardo-backup.env
: "${BINLOG_HOST:=10.0.3.3}"
: "${BINLOG_USER:?BINLOG_USER fehlt in /etc/riccardo-backup.env}"
: "${BINLOG_PASS:?BINLOG_PASS fehlt in /etc/riccardo-backup.env}"
: "${S3_BUCKET_PRIVATE:?Bucket fehlt}"

mkdir -p "$ZIEL"
cd "$ZIEL"

host="${S3_ENDPOINT#https://}"

hochladen() {
    local datei="$1" ziel="binlog/$(basename "$1")"
    if command -v aws >/dev/null; then
        AWS_ACCESS_KEY_ID="$S3_KEY" AWS_SECRET_ACCESS_KEY="$S3_SECRET" \
        aws --endpoint-url "$S3_ENDPOINT" --region "${S3_REGION:-nbg1}" \
            s3 cp "$datei" "s3://$S3_BUCKET_PRIVATE/$ziel" --only-show-errors
    else
        s3cmd --access_key="$S3_KEY" --secret_key="$S3_SECRET" \
              --host="$host" --host-bucket="%(bucket)s.$host" \
              --quiet put "$datei" "s3://$S3_BUCKET_PRIVATE/$ziel"
    fi
}

# Alle vorhandenen Protokolle abrufen. Die jüngste Datei wächst noch, sie wird
# bei jedem Lauf erneut geholt und überschrieben – dadurch ist der Abstand zum
# letzten gesicherten Stand höchstens eine Stunde.
protokolle=$(mariadb -h "$BINLOG_HOST" -u "$BINLOG_USER" "-p$BINLOG_PASS" -N -e 'SHOW BINARY LOGS' | awk '{print $1}')
[ -n "$protokolle" ] || { echo "Keine Binärprotokolle gefunden – ist log_bin aktiv?"; exit 1; }

anzahl=0
for name in $protokolle; do
    mariadb-binlog --read-from-remote-server --host="$BINLOG_HOST" \
        --user="$BINLOG_USER" --password="$BINLOG_PASS" \
        --raw --result-file="$ZIEL/" "$name" 2>/dev/null || {
            echo "Konnte $name nicht holen"
            continue
        }
    [ -f "$ZIEL/$name" ] && hochladen "$ZIEL/$name" && anzahl=$((anzahl+1))
done

# Aufräumen: lokal und im Bucket
find "$ZIEL" -name 'mysql-bin.*' -mtime +$BEHALTEN_TAGE -delete

if command -v aws >/dev/null && [ -n "${S3_KEY:-}" ]; then
    grenze=$(date -d "-$BEHALTEN_TAGE_FERN days" +%Y-%m-%d)
    AWS_ACCESS_KEY_ID="$S3_KEY" AWS_SECRET_ACCESS_KEY="$S3_SECRET" \
    aws --endpoint-url "$S3_ENDPOINT" --region "${S3_REGION:-nbg1}" \
        s3 ls "s3://$S3_BUCKET_PRIVATE/binlog/" | while read -r datum _ _ name; do
        [ -n "$name" ] || continue
        if [[ "$datum" < "$grenze" ]]; then
            AWS_ACCESS_KEY_ID="$S3_KEY" AWS_SECRET_ACCESS_KEY="$S3_SECRET" \
            aws --endpoint-url "$S3_ENDPOINT" --region "${S3_REGION:-nbg1}" \
                s3 rm "s3://$S3_BUCKET_PRIVATE/binlog/$name" --only-show-errors
        fi
    done
fi

echo "$(date '+%Y-%m-%d %H:%M') $anzahl Protokolldateien gesichert ($(du -sh "$ZIEL" | cut -f1) lokal)"
