#!/usr/bin/env bash
# =============================================================================
# agent-promtail.sh — Installe Promtail (systemd) et expédie les logs vers Loki
# Lib-Lab — cible Loki : srv-obs (172.0.16.80:3100)
# Remplace l'ancien envoi rsyslog (install-client-rsyslog.sh)
# -----------------------------------------------------------------------------
# Sources de logs collectées :
#   - journald (systemd-journal)         job=journal
#   - /var/log/*.log                     job=varlogs
#   - logs des containers Docker (si présent)  job=docker
# Usage :
#   sudo bash agent-promtail.sh                 # interactif (Loki par défaut)
#   sudo LOKI_URL=http://172.0.16.80:3100 bash agent-promtail.sh --yes
# =============================================================================
set -euo pipefail

die(){ echo "ERROR: $*" >&2; exit 1; }
msg(){ echo "[*] $*"; }
ok(){  echo "[✓] $*"; }

# -------- Paramètres (overridables par variables d'env) --------
LOKI_HOST="${LOKI_HOST:-172.0.16.80}"
LOKI_PORT="${LOKI_PORT:-3100}"
LOKI_URL="${LOKI_URL:-http://${LOKI_HOST}:${LOKI_PORT}}"
PROMTAIL_VERSION="${PROMTAIL_VERSION:-}"     # vide = dernière release GitHub
ASSUME_YES="${ASSUME_YES:-false}"
HOSTLABEL="${HOSTLABEL:-$(hostname -s 2>/dev/null || hostname)}"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --loki)    LOKI_URL="$2"; shift 2 ;;
    --version) PROMTAIL_VERSION="$2"; shift 2 ;;
    --host)    HOSTLABEL="$2"; shift 2 ;;
    --yes)     ASSUME_YES=true; shift ;;
    --help)    grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) die "Option inconnue : $1" ;;
  esac
done

[[ ${EUID:-$(id -u)} -eq 0 ]] || die "Exécute en root (sudo $0)."

# -------- Prérequis --------
if command -v apt-get >/dev/null 2>&1; then
  export DEBIAN_FRONTEND=noninteractive
  apt-get update -y >/dev/null 2>&1 || true
  apt-get install -y curl unzip ca-certificates acl >/dev/null 2>&1 || true
fi
command -v curl >/dev/null 2>&1 || die "curl requis"
command -v unzip >/dev/null 2>&1 || die "unzip requis"

ARCH="$(uname -m)"
case "$ARCH" in
  x86_64|amd64) PT_ARCH="amd64" ;;
  aarch64|arm64) PT_ARCH="arm64" ;;
  *) die "Architecture non gérée : $ARCH" ;;
esac

# -------- Détermination de la version --------
# ⚠️ Promtail est EOL chez Grafana : les dernières releases Loki (>= 3.7) ne
#    publient PLUS le binaire promtail-linux-*.zip. On épingle une version
#    connue qui fournit l'asset et on vérifie sa présence (fallback auto).
#    Migration future recommandée : Grafana Alloy.
PROMTAIL_KNOWN_GOOD="3.5.5"     # dernière connue avec asset : 3.6.1
asset_url(){ echo "https://github.com/grafana/loki/releases/download/v$1/promtail-linux-${PT_ARCH}.zip"; }
[[ -n "$PROMTAIL_VERSION" ]] || PROMTAIL_VERSION="$PROMTAIL_KNOWN_GOOD"
if [[ "$(curl -s -o /dev/null -w '%{http_code}' -I -L "$(asset_url "$PROMTAIL_VERSION")")" != "200" ]]; then
  msg "Binaire promtail v${PROMTAIL_VERSION} indisponible (EOL ?) → bascule sur v${PROMTAIL_KNOWN_GOOD}"
  PROMTAIL_VERSION="$PROMTAIL_KNOWN_GOOD"
fi
ok "Version Promtail : ${PROMTAIL_VERSION} (${PT_ARCH})"

if [[ "$ASSUME_YES" != "true" ]]; then
  read -r -p "Installer Promtail et envoyer les logs vers ${LOKI_URL} ? [O/n] " a
  [[ "${a,,}" == "n" ]] && { msg "Abandon."; exit 0; }
fi

# -------- Téléchargement du binaire --------
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
URL="https://github.com/grafana/loki/releases/download/v${PROMTAIL_VERSION}/promtail-linux-${PT_ARCH}.zip"
msg "Téléchargement : $URL"
curl -fSL "$URL" -o "$TMP/promtail.zip" || die "Téléchargement échoué"
unzip -o "$TMP/promtail.zip" -d "$TMP" >/dev/null
install -D -m 0755 "$TMP/promtail-linux-${PT_ARCH}" /usr/local/bin/promtail
ok "Binaire installé : /usr/local/bin/promtail"

# -------- Utilisateur & dossiers --------
id promtail >/dev/null 2>&1 || useradd -r -M -s /usr/sbin/nologin promtail
# Accès aux logs système et au journal
usermod -aG adm,systemd-journal promtail 2>/dev/null || true
install -d -m 0750 -o promtail -g promtail /etc/promtail /var/lib/promtail

# -------- Détection Docker --------
DOCKER_BLOCK=""
if [[ -d /var/lib/docker/containers ]]; then
  setfacl -R -m u:promtail:rX /var/lib/docker/containers 2>/dev/null || true
  DOCKER_BLOCK=$(cat <<'YML'

  - job_name: docker
    static_configs:
      - targets: [localhost]
        labels:
          job: docker
          host: __HOST__
          __path__: /var/lib/docker/containers/*/*-json.log
    pipeline_stages:
      - json:
          expressions:
            output: log
            stream: stream
      - labels:
          stream:
      - output:
          source: output
YML
)
fi

# -------- Configuration --------
cat > /etc/promtail/promtail-config.yml <<YML
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /var/lib/promtail/positions.yaml

clients:
  - url: ${LOKI_URL}/loki/api/v1/push

scrape_configs:
  - job_name: journal
    journal:
      max_age: 12h
      labels:
        job: journal
        host: ${HOSTLABEL}
    relabel_configs:
      - source_labels: ['__journal__systemd_unit']
        target_label: unit

  - job_name: varlogs
    static_configs:
      - targets: [localhost]
        labels:
          job: varlogs
          host: ${HOSTLABEL}
          __path__: /var/log/*log
${DOCKER_BLOCK}
YML
sed -i "s/__HOST__/${HOSTLABEL}/g" /etc/promtail/promtail-config.yml
chown -R promtail:promtail /etc/promtail
ok "Config écrite : /etc/promtail/promtail-config.yml (host=${HOSTLABEL})"

# -------- Service systemd --------
# Durcissement désactivé en conteneur (LXC) où le namespacing échoue
HARDENING="NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true"
if systemd-detect-virt --container --quiet 2>/dev/null; then
  msg "Conteneur (LXC) détecté — durcissement systemd allégé"
  HARDENING="# (durcissement désactivé : conteneur LXC)"
fi

cat > /etc/systemd/system/promtail.service <<EOF
[Unit]
Description=Promtail (Loki agent)
Wants=network-online.target
After=network-online.target

[Service]
User=promtail
Group=promtail
ExecStart=/usr/local/bin/promtail -config.file=/etc/promtail/promtail-config.yml
Restart=on-failure
RestartSec=5
${HARDENING}

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now promtail
sleep 2
systemctl is-active --quiet promtail || { journalctl -u promtail --no-pager -n 20; die "promtail n'a pas démarré"; }
ok "Service promtail actif"

echo
ok "Promtail installé."
echo "  - Loki   : ${LOKI_URL}"
echo "  - Host   : ${HOSTLABEL}"
echo "  - Config : /etc/promtail/promtail-config.yml"
echo "  - Vérif  : journalctl -u promtail -f   |   curl -s localhost:9080/metrics | head"
