fix : correctifs multiples

This commit is contained in:
AkiNoKure
2026-03-09 09:08:44 +01:00
parent 081e9de1a3
commit c2d1b716e0
15 changed files with 731 additions and 233 deletions

48
.gitignore vendored
View File

@@ -1,9 +1,51 @@
# Secrets / environment ########################################
# Environment / secrets
########################################
# Fichiers .env réels (contiennent des secrets)
.env .env
.env.* .env.*
!.env.example !.env.example
!.env.exemple !.env.exemple
# Sous-dossiers
RecetteScripts/.env
CheckStorage/.env
# Garder les fichiers exemple
!*.env.exemple
!*.env.example
!CheckStorage/.env.exemple
!RecetteScripts/.env.exemple
########################################
# Logs
########################################
*.log
logs/
var/log/
backup.log
########################################
# Temporary / system files
########################################
*.tmp
*.swp
*.swo
*~
########################################
# IDE / Editors
########################################
# IDE / editor
.idea/ .idea/
.vscode/ .vscode/
*.iml
########################################
# OS files
########################################
.DS_Store
Thumbs.db

32
CHANGELOG.md Normal file
View File

@@ -0,0 +1,32 @@
# Changelog
Liste des évolutions du projet Scripts Serveur
## [0.0.0]
### Parameters
Ajouter dans le fichier /RecetteScripts/.env
SSH_TIMEOUT
BACKUP_LOG_DIR
APP_LOG_DIR
DISCORD_WEBHOOK_URL
DISCORD_PING
CHECK_CONNECT_TIMEOUT
CHECK_MAX_TIME
APP_URLS
Ajouter dans le fichier /CheckStorage/.env
WEBHOOK_URL
### Added
* [#361] Script dump BDD
* [#367] Avoir une notification discord quand les backup sont faites
* [#368] Script pour check que les applis ne sont pas hors-ligne
* first push
* Reorganisation des fichiers et dossiers
* [#372] Script de check si la machine a le stockage plein
* [#378] Script Backup BDD Vaultwarden
* [#381] Variabiliser tous les scripts
* [#] Fix Correctif
### Changed
### Fixed

View File

@@ -22,11 +22,11 @@ La limite d'alerte est fixée à 70% d'utilisation, mais vous pouvez ajuster cet
## Utilisation du script ## Utilisation du script
1. Donnez les permissions d'exécution au script : 1. Donnez les permissions d'exécution au script :
```bash ```bash
chmod +x check_storage.sh chmod +x check-storage.sh
``` ```
2. Exécutez le script pour vérifier l'espace de stockage : 2. Exécutez le script pour vérifier l'espace de stockage :
```bash ```bash
./check_storage.sh ./check-storage.sh
``` ```
## Initialisé un cron pour exécuter le script régulièrement ## Initialisé un cron pour exécuter le script régulièrement
@@ -36,8 +36,8 @@ La limite d'alerte est fixée à 70% d'utilisation, mais vous pouvez ajuster cet
``` ```
2. Ajoutez la ligne suivante pour exécuter le script tous les jours à 7h50 du matin : 2. Ajoutez la ligne suivante pour exécuter le script tous les jours à 7h50 du matin :
```bash ```bash
50 7 * * * /chemin/vers/le/script/check_storage.sh 50 7 * * * /chemin/vers/le/script/check-storage.sh
``` ```
## Avertissement ## Avertissement
Assurez-vous de remplacer `/chemin/vers/le/script/check_storage.sh` par le chemin réel où se trouve le script sur votre système. Assurez-vous de remplacer `/chemin/vers/le/script/check-storage.sh` par le chemin réel où se trouve le script sur votre système.

View File

@@ -1,4 +1,40 @@
# Scripts Serveur MALIO # Scripts Serveur MALIO
Ce dépôt sert au **versionnement des scripts utilisés dans linfrastructure du projet Ferme**.
Lobjectif est de conserver un historique clair des scripts, suivre les évolutions et permettre leur amélioration progressive.
## Contenu du dépôt
Le dépôt peut contenir différents types de scripts utilisés pour lexploitation technique :
* scripts de **backup PostgreSQL**
* scripts de **monitoring des applications**
* scripts **dautomatisation système**
* scripts **dadministration ou de maintenance**
## Objectif
Ce dépôt permet de :
* suivre les **modifications des scripts dans le temps**
* garder une **version stable et reproductible**
* faciliter la **maintenance et les corrections**
* centraliser les scripts utilisés sur les serveurs
## Organisation
Les évolutions importantes sont documentées dans le fichier :
```
CHANGELOG.md
```
Ce fichier décrit les nouvelles fonctionnalités, corrections et modifications apportées aux scripts.
## Remarque
Ce dépôt est dédié au **versionnement des scripts uniquement**.
Les configurations sensibles (mots de passe, clés, variables denvironnement) ne doivent pas être stockées directement dans le dépôt et doivent être placées dans des fichiers `.env` locaux.
Ce projet contient des scripts pour la gestion et la maintenance des serveurs de MALIO. Ce projet contient des scripts pour la gestion et la maintenance des serveurs de MALIO.

View File

@@ -0,0 +1,87 @@
#############################################
# ENVIRONNEMENT
#############################################
# Nom de l'environnement (ex: DEV / RECETTE / PROD)
ENV_NAME=RECETTE
#############################################
# POSTGRESQL
#############################################
# Host PostgreSQL
PGHOST=localhost
# Port PostgreSQL
PGPORT=5432
# Utilisateur utilisé pour les dumps
PGUSER=backup_user
# Mot de passe PostgreSQL
PGPASSWORD=change_me_secure_password
# Bases à sauvegarder (séparées par espace)
DBS="sirh inventory ferme"
#############################################
# SERVEUR DE STOCKAGE DES BACKUPS
#############################################
# Utilisateur du serveur distant
BACKUP_REMOTE_USER=backup
# Host ou IP du serveur distant
BACKUP_REMOTE_HOST=192.168.1.50
# Dossier distant pour stocker les backups
BACKUP_REMOTE_DIR=/home/backup/backups
#############################################
# SSH
#############################################
# Clé SSH utilisée pour envoyer les dumps
SSH_KEY=/home/backup/.ssh/id_ed25519_backup
# Timeout SSH (secondes)
SSH_TIMEOUT=10
#############################################
# LOGS
#############################################
# Dossier des logs backup
BACKUP_LOG_DIR=/var/log/pg_backup
# Dossier logs monitoring apps
APP_LOG_DIR=/var/log/app_health
#############################################
# DISCORD
#############################################
# Webhook Discord pour notifications
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Ping en cas d'erreur
DISCORD_PING=@here
#############################################
# HEALTH CHECK APPS
#############################################
# Timeout connexion HTTP
CHECK_CONNECT_TIMEOUT=3
# Timeout total curl
CHECK_MAX_TIME=8
# Applications à vérifier
APP_URLS="ferme.example.local sirh.example.local inventory.example.local"

121
RecetteScripts/README.md Normal file
View File

@@ -0,0 +1,121 @@
# Scripts Recette
Ce dossier contient les scripts utilisés pour lenvironnement **RECETTE** du projet **Ferme**.
Les scripts permettent principalement :
* la **sauvegarde automatique des bases de données PostgreSQL**
* la **vérification du statut des applications web**
---
# Scripts disponibles
## backup-bdd-recette.sh
Script permettant de réaliser une **sauvegarde des bases de données PostgreSQL**.
Fonctionnement :
* export des bases PostgreSQL définies dans la configuration
* export des utilisateurs PostgreSQL
* création de dumps au format PostgreSQL (`pg_dump -Fc`)
* transfert des sauvegardes vers un serveur distant
* génération de logs locaux
* envoi de notifications Discord en cas de succès ou derreur
---
## check-statut-recette.sh
Script permettant de **vérifier la disponibilité des applications web**.
Le script effectue les vérifications suivantes :
* résolution DNS du site
* connexion HTTP au service
* vérification du code HTTP retourné
Une application est considérée :
* **OK** si le code HTTP est entre **200 et 399**
* **DOWN** si la résolution DNS échoue ou si une erreur HTTP est détectée
Chaque vérification est enregistrée dans un **fichier de log** et une notification peut être envoyée sur **Discord**.
---
# Installation
1. Clonez le dépôt Git :
```bash
git clone https://gitea.malio.fr/MALIO-DEV/Scripts-Serveur.git
```
2. Accédez au dossier des scripts :
```bash
cd Scripts-Serveur/RecetteScripts
```
3. Copiez le fichier denvironnement :
```bash
cp .env.example .env
```
4. Modifiez les variables du fichier `.env` selon votre configuration.
---
# Utilisation
Donnez les permissions dexécution aux scripts :
```bash
chmod +x backup-bdd-recette.sh
chmod +x check-statut-recette.sh
```
Exécution manuelle :
```bash
./backup-bdd-recette.sh
./check-statut-recette.sh
```
---
# Exécution automatique avec Cron
Ouvrez le crontab :
```bash
crontab -e
```
Exemple de planification :
Backup des bases tous les jours à 19h :
```bash
0 19 * * * /chemin/vers/le/script/backup-bdd-recette.sh
```
Vérification des applications tous les jours à 19h :
```bash
0 19 * * * /chemin/vers/le/script/check-statut-recette.sh
```
---
# Avertissement
Assurez-vous que :
* PostgreSQL est accessible depuis la machine exécutant le script
* la clé SSH pour le transfert des sauvegardes est configurée
* les variables du fichier `.env` sont correctement renseignées
* les commandes `curl`, `psql` et `pg_dump` sont installées sur le système

View File

@@ -0,0 +1,347 @@
#!/usr/bin/env bash
set -euo pipefail
###############################################################################
# backup-bdd-recette.sh
#
# Ce script réalise une sauvegarde logique de plusieurs bases PostgreSQL
# définies dans le fichier .env, exporte également la liste des rôles/users,
# puis transfère lensemble vers une machine distante de stockage.
#
# Fonctionnement global :
# 1. charge la configuration depuis le fichier .env ;
# 2. prépare les chemins, logs et variables de connexion ;
# 3. empêche lexécution simultanée grâce à un verrou ;
# 4. crée les dossiers de destination sur la machine distante ;
# 5. exporte les rôles PostgreSQL ;
# 6. dump chaque base au format personnalisé PostgreSQL ;
# 7. transfère chaque fichier vers le serveur distant ;
# 8. envoie un bilan sur Discord :
# - 1 message global si tout est OK ;
# - 1 message USERS si export/transfert des rôles en erreur ;
# - 1 message par base si dump ou transfert en erreur.
###############################################################################
#######################################
# Chargement du .env
#######################################
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env"
if [[ ! -f "$ENV_FILE" ]]; then
echo "ERROR: fichier .env introuvable : $ENV_FILE" >&2
exit 1
fi
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
#######################################
# Vérification des variables requises
#######################################
: "${ENV_NAME:?Variable ENV_NAME manquante}"
: "${PGHOST:?Variable PGHOST manquante}"
: "${PGPORT:?Variable PGPORT manquante}"
: "${PGUSER:?Variable PGUSER manquante}"
: "${PGPASSWORD:?Variable PGPASSWORD manquante}"
: "${DBS:?Variable DBS manquante}"
: "${BACKUP_REMOTE_USER:?Variable BACKUP_REMOTE_USER manquante}"
: "${BACKUP_REMOTE_HOST:?Variable BACKUP_REMOTE_HOST manquante}"
: "${BACKUP_REMOTE_DIR:?Variable BACKUP_REMOTE_DIR manquante}"
: "${SSH_KEY:?Variable SSH_KEY manquante}"
: "${SSH_TIMEOUT:?Variable SSH_TIMEOUT manquante}"
: "${BACKUP_LOG_DIR:?Variable BACKUP_LOG_DIR manquante}"
#######################################
# Configuration principale
#######################################
# Conversion de la liste des bases en tableau Bash
read -r -a DBS_ARRAY <<< "$DBS"
# Paramètres de connexion SSH vers la machine distante
IA_SSH="${BACKUP_REMOTE_USER}@${BACKUP_REMOTE_HOST}"
IA_BASE_DIR="${BACKUP_REMOTE_DIR}"
# Clé SSH et options utilisées pour les connexions SSH/SCP
SSH_OPTS=(-i "$SSH_KEY" -o IdentitiesOnly=yes -o BatchMode=yes -o ConnectTimeout="${SSH_TIMEOUT}")
# Dossier de logs local
LOG_DIR="${BACKUP_LOG_DIR}"
mkdir -p "$LOG_DIR"
# Timestamp unique pour identifier ce jeu de sauvegardes
TS="$(date +'%Y-%m-%d_%H-%M-%S')"
BACKUP_DIR_NAME="backup_${TS}"
LOG_FILE="${LOG_DIR}/${BACKUP_DIR_NAME}.log"
# Dossier temporaire local où seront générés les dumps avant transfert
TMP_DIR="/tmp/pg_dump_${BACKUP_DIR_NAME}"
mkdir -p "$TMP_DIR"
# Redirige stdout/stderr vers le fichier de log tout en gardant l'affichage console
exec > >(tee -a "$LOG_FILE") 2>&1
# Fonction de log horodaté
log() { echo "---- $(date +'%Y-%m-%d %H:%M:%S') ---- $*"; }
# Rend le mot de passe PostgreSQL disponible à psql / pg_dump
export PGPASSWORD
#######################################
# Configuration Discord
#######################################
# URL du webhook Discord.
# Si elle est vide, aucune notification ne sera envoyée.
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-}"
DISCORD_PING="${DISCORD_PING:-@here}"
# Envoie un message texte simple sur Discord via webhook
discord_send() {
local msg="$1"
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return
curl -fsS -H "Content-Type: application/json" \
-d "{\"content\":\"$msg\"}" \
"$DISCORD_WEBHOOK_URL" >/dev/null || true
}
#######################################
# Message global OK
#######################################
# Envoie un message unique quand tout le process sest bien déroulé
discord_msg_global_ok() {
local msg="**BACKUP BDD ${ENV_NAME} 🟢**\n"
msg+="Name: ${BACKUP_DIR_NAME}\n"
msg+="Dumps transfer: ✅\n"
msg+="Users transfer: ✅"
discord_send "$msg"
}
#######################################
# Message USERS
#######################################
# Envoie un message de statut spécifique à lexport/transfert des rôles/users
# Paramètres :
# $1 = export_ok -> non vide si export OK
# $2 = transfer_ok -> non vide si transfert OK
# $3 = details -> détail textuel de lerreur éventuelle
discord_msg_users() {
local export_ok="$1"
local transfer_ok="$2"
local details="$3"
local export_disp transfer_disp
export_disp=$([[ -n "$export_ok" ]] && echo "✅" || echo "❌")
transfer_disp=$([[ -n "$transfer_ok" ]] && echo "✅" || echo "❌")
local color ping
if [[ -n "$export_ok" && -n "$transfer_ok" ]]; then
color="🟢"
ping=""
else
color="🔴"
ping="${DISCORD_PING} "
fi
local msg="**${ping}BACKUP BDD ${ENV_NAME} ${color}**\n"
msg+="Name: ${BACKUP_DIR_NAME}\n"
msg+="Users export: ${export_disp}\n"
msg+="Users transfer: ${transfer_disp}"
[[ -n "$details" ]] && msg+="\nDetails: ${details}"
discord_send "$msg"
}
#######################################
# Message DB
#######################################
# Envoie un message de statut spécifique à une base donnée
# Paramètres :
# $1 = db -> nom de la base
# $2 = dump_ok -> non vide si dump OK
# $3 = transfer_ok -> non vide si transfert OK
# $4 = details -> détail textuel de lerreur éventuelle
discord_msg_db() {
local db="$1"
local dump_ok="$2"
local transfer_ok="$3"
local details="$4"
local dump_disp transfer_disp
dump_disp=$([[ -n "$dump_ok" ]] && echo "✅" || echo "❌")
transfer_disp=$([[ -n "$transfer_ok" ]] && echo "✅" || echo "❌")
local color ping
if [[ -n "$dump_ok" && -n "$transfer_ok" ]]; then
color="🟢"
ping=""
else
color="🔴"
ping="${DISCORD_PING} "
fi
local msg="**${ping}BACKUP BDD ${ENV_NAME} ${color}**\n"
msg+="Name: ${BACKUP_DIR_NAME}\n"
msg+="Database: ${db}\n"
msg+="Dump: ${dump_disp}\n"
msg+="Transfer: ${transfer_disp}"
[[ -n "$details" ]] && msg+="\nDetails: ${details}"
discord_send "$msg"
}
#######################################
# Variables de statut globales
#######################################
DUMPS_OK=true
USERS_OK=true
USERS_EXPORT_OK=true
USERS_TRANSFER_OK=true
USERS_DETAILS=""
declare -A DB_DUMP_OK
declare -A DB_TRANSFER_OK
declare -A DB_DETAILS
#######################################
# Verrou dexécution
#######################################
LOCK_DIR="/tmp/pg_multi_dump_stream.lock.d"
if ! mkdir "$LOCK_DIR" 2>/dev/null; then
log "ERROR: Backup déjà en cours"
discord_msg_users "" "" "Lock already exists"
exit 1
fi
trap 'rm -rf "$LOCK_DIR"' EXIT
#######################################
# Préparation du dossier distant
#######################################
REMOTE_DIR="${IA_BASE_DIR}"
log "Creating remote directories"
if ! ssh "${SSH_OPTS[@]}" "$IA_SSH" "mkdir -p '${REMOTE_DIR}/ferme' '${REMOTE_DIR}/sirh' '${REMOTE_DIR}/inventory' '${REMOTE_DIR}/user'"; then
log "ERROR: remote mkdir failed"
discord_msg_users "" "" "Remote mkdir failed"
exit 1
fi
#######################################
# Export des rôles PostgreSQL
#######################################
ROLES_FILE="${TMP_DIR}/user_${TS}.dump"
set +e
psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d postgres -Atq <<'SQL' > "$ROLES_FILE"
SELECT rolname FROM pg_roles WHERE rolname !~ '^pg_';
SQL
RET=$?
if [[ $RET -ne 0 ]]; then
USERS_OK=
USERS_EXPORT_OK=
USERS_DETAILS="roles export failed"
fi
scp "${SSH_OPTS[@]}" "$ROLES_FILE" "$IA_SSH:${REMOTE_DIR}/user/"
RET=$?
if [[ $RET -ne 0 ]]; then
USERS_OK=
USERS_TRANSFER_OK=
USERS_DETAILS+=" roles transfer failed"
fi
set -e
#######################################
# Dump des bases
#######################################
set +e
for DB in "${DBS_ARRAY[@]}"; do
FILE="${TMP_DIR}/${DB}_${TS}.dump"
DB_DUMP_OK["$DB"]=true
DB_TRANSFER_OK["$DB"]=true
DB_DETAILS["$DB"]="OK"
log "Dump $DB"
pg_dump -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -Fc -d "$DB" -f "$FILE"
RET=$?
if [[ $RET -ne 0 ]]; then
DUMPS_OK=
DB_DUMP_OK["$DB"]=
DB_TRANSFER_OK["$DB"]=
DB_DETAILS["$DB"]="dump failed"
continue
fi
scp "${SSH_OPTS[@]}" "$FILE" "$IA_SSH:${REMOTE_DIR}/${DB}/"
RET=$?
if [[ $RET -ne 0 ]]; then
DUMPS_OK=
DB_TRANSFER_OK["$DB"]=
DB_DETAILS["$DB"]="transfer failed"
fi
done
set -e
#######################################
# Nettoyage local
#######################################
rm -rf "$TMP_DIR"
#######################################
# Bilan final Discord
#######################################
MODE_KO=
[[ -z "${DUMPS_OK:-}" ]] && MODE_KO=true
[[ -z "${USERS_OK:-}" ]] && MODE_KO=true
if [[ -z "${MODE_KO:-}" ]]; then
discord_msg_global_ok
exit 0
fi
discord_msg_users "${USERS_EXPORT_OK:+true}" "${USERS_TRANSFER_OK:+true}" "$USERS_DETAILS"
for DB in "${DBS_ARRAY[@]}"; do
discord_msg_db "$DB" "${DB_DUMP_OK[$DB]:+true}" "${DB_TRANSFER_OK[$DB]:+true}" "${DB_DETAILS[$DB]}"
done
exit 2

View File

@@ -1,30 +1,72 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -u set -u
###############################################################################
# check-statut-recette.sh
#
# Ce script vérifie la disponibilité de plusieurs applications web définies
# dans le fichier .env.
#
# Fonctionnement global :
# 1. charge la configuration depuis le fichier .env ;
# 2. vérifie que le DNS du site est résolu ;
# 3. effectue une requête HTTP avec curl ;
# 4. analyse le code HTTP retourné ;
# 5. écrit le résultat dans un fichier de log local ;
# 6. envoie une notification Discord avec létat du service.
###############################################################################
#######################################
# Chargement du .env
#######################################
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env"
if [[ ! -f "$ENV_FILE" ]]; then
echo "ERROR: fichier .env introuvable : $ENV_FILE" >&2
exit 1
fi
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
#######################################
# Vérification des variables requises
#######################################
: "${ENV_NAME:?Variable ENV_NAME manquante}"
: "${APP_LOG_DIR:?Variable APP_LOG_DIR manquante}"
: "${CHECK_CONNECT_TIMEOUT:?Variable CHECK_CONNECT_TIMEOUT manquante}"
: "${CHECK_MAX_TIME:?Variable CHECK_MAX_TIME manquante}"
: "${APP_URLS:?Variable APP_URLS manquante}"
####################################### #######################################
# Sites à vérifier # Sites à vérifier
####################################### #######################################
SITES=(
"ferme.malio-dev.fr" read -r -a SITES <<< "$APP_URLS"
"sirh.malio-dev.fr"
"inventory.malio-dev.fr"
)
SCHEME="http" SCHEME="http"
CONNECT_TIMEOUT=3 CONNECT_TIMEOUT="${CHECK_CONNECT_TIMEOUT}"
MAX_TIME=8 MAX_TIME="${CHECK_MAX_TIME}"
####################################### #######################################
# Logs # Logs
####################################### #######################################
LOG_DIR="/var/log/app_health"
LOG_DIR="${APP_LOG_DIR}"
mkdir -p "$LOG_DIR" mkdir -p "$LOG_DIR"
LOG_FILE="${LOG_DIR}/app_health_$(date +'%Y-%m-%d').log" LOG_FILE="${LOG_DIR}/app_health_$(date +'%Y-%m-%d').log"
####################################### #######################################
# Discord # Discord
####################################### #######################################
DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/1478379245842600007/tSxi3G6PbCn89pOdeqK34LR7c-GhXfT-lSCPolwBywJXcpa3ihL8rN4QRwsTjF6SS3w0"
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-}"
DISCORD_PING="${DISCORD_PING:-@here}"
discord_ping() { discord_ping() {
local site="$1" local site="$1"
@@ -33,17 +75,17 @@ discord_ping() {
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0 [[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0
local color icon local color icon ping_prefix=""
if [[ "$status" == "OK" ]]; then if [[ "$status" == "OK" ]]; then
color="🟢" color="🟢"
icon="✅" icon="✅"
else else
color="🔴" color="🔴"
icon="❌" icon="❌"
ping_prefix="${DISCORD_PING} "
fi fi
local msg="**CHECK APP RECETTE $color**\n" local msg="**${ping_prefix}CHECK APP ${ENV_NAME} $color**\n"
msg+="Application: ${site}\n" msg+="Application: ${site}\n"
msg+="Status: ${icon}\n" msg+="Status: ${icon}\n"
msg+="Details: ${detail}" msg+="Details: ${detail}"
@@ -56,6 +98,7 @@ discord_ping() {
####################################### #######################################
# Logging # Logging
####################################### #######################################
log_line() { log_line() {
# 2026-03-04 14:12:33 | LEVEL | site | message # 2026-03-04 14:12:33 | LEVEL | site | message
printf "%s | %s | %s | %s\n" \ printf "%s | %s | %s | %s\n" \
@@ -68,6 +111,7 @@ log_line() {
####################################### #######################################
# DNS # DNS
####################################### #######################################
dns_ok() { dns_ok() {
getent hosts "$1" >/dev/null 2>&1 getent hosts "$1" >/dev/null 2>&1
} }
@@ -75,6 +119,7 @@ dns_ok() {
####################################### #######################################
# Check application # Check application
####################################### #######################################
check_site() { check_site() {
local host="$1" local host="$1"
@@ -127,6 +172,7 @@ check_site() {
####################################### #######################################
# Main # Main
####################################### #######################################
main() { main() {
local failures=0 local failures=0
@@ -144,4 +190,4 @@ main() {
exit 0 exit 0
} }
main "$@" main "$@"

View File

@@ -1,210 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
#######################################
# Configuration
#######################################
DBS=("sirh" "inventory" "ferme")
PGHOST="localhost"
PGPORT="5432"
PGUSER="backup_liot"
PGPASSWORD="backup_liot"
IA_SSH="malio-b@192.168.0.179"
IA_BASE_DIR="/home/malio-b/backups"
SSH_KEY="/home/malio/.ssh/id_ed25519_backup"
SSH_OPTS=(-i "$SSH_KEY" -o IdentitiesOnly=yes -o BatchMode=yes -o ConnectTimeout=10)
LOG_DIR="/var/log/pg_backup"
mkdir -p "$LOG_DIR"
TS="$(date +'%Y-%m-%d_%H-%M-%S')"
BACKUP_DIR_NAME="backup_${TS}"
LOG_FILE="${LOG_DIR}/${BACKUP_DIR_NAME}.log"
TMP_DIR="/tmp/pg_dump_${BACKUP_DIR_NAME}"
mkdir -p "$TMP_DIR"
exec > >(tee -a "$LOG_FILE") 2>&1
log() { echo "---- $(date +'%Y-%m-%d %H:%M:%S') ---- $*"; }
export PGPASSWORD
#######################################
# Discord (Webhook)
#######################################
DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/1478503102888935506/YCtJM09QZiKNMiCe5u7vCQb52VcLjHAd9wwEsKNltlJVcy7sKvoMTOJkvEKOOrk-Wpkh"
discord_ping() {
local details="${1:-}"
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0
local color dumps_display users_display
if [[ -n "${DUMPS_OK:-}" && -n "${USERS_OK:-}" ]]; then
color="🟢"
else
color="🔴"
fi
dumps_display=$([[ -n "${DUMPS_OK:-}" ]] && echo "✅" || echo "❌")
users_display=$([[ -n "${USERS_OK:-}" ]] && echo "✅" || echo "❌")
local msg="**@here BACKUP BDD RECETTE ${color}**\n"
msg+="Name: ${BACKUP_DIR_NAME}\n"
msg+="Dumps transfer: ${dumps_display}\n"
msg+="Users transfer: ${users_display}\n"
[[ -n "$details" ]] && msg+="Details: $details"
curl -fsS -H "Content-Type: application/json" \
-d "{\"content\":\"$msg\"}" \
"$DISCORD_WEBHOOK_URL" >/dev/null || true
}
#######################################
# Statuts init
#######################################
DUMPS_OK=true
USERS_OK=true
DUMP_ERRORS=""
USER_ERRORS=""
#######################################
# Lock (évite 2 backups en même temps)
#######################################
LOCK_DIR="/tmp/pg_multi_dump_stream.lock.d"
if ! mkdir "$LOCK_DIR" 2>/dev/null; then
log "ERROR: Backup déjà en cours (lock: $LOCK_DIR)"
DUMPS_OK=
USERS_OK=
discord_ping "Lock exists: $LOCK_DIR"
exit 1
fi
trap 'rm -rf "$LOCK_DIR"' EXIT
#######################################
# Remote dir
#######################################
REMOTE_DIR="${IA_BASE_DIR}/${BACKUP_DIR_NAME}"
log "Starting backup process"
log "Remote directory: ${REMOTE_DIR}"
log "Creating remote directory"
if ! ssh "${SSH_OPTS[@]}" "$IA_SSH" "mkdir -p '${REMOTE_DIR}'"; then
log "ERROR: Création dossier distant impossible: ${REMOTE_DIR}"
DUMPS_OK=
USERS_OK=
discord_ping "Remote mkdir KO: ${REMOTE_DIR}"
exit 1
fi
#######################################
# Export PostgreSQL roles (no passwords)
#######################################
ROLES_FILE="${TMP_DIR}/roles_${TS}.sql"
log "Exporting PostgreSQL roles"
set +e
psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d postgres -Atq <<'SQL' > "$ROLES_FILE"
SELECT
format(
'DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = %L) THEN
CREATE ROLE %I;
END IF;
END $$;',
rolname, rolname
)
FROM pg_roles
WHERE rolname !~ '^pg_'
ORDER BY rolname;
SELECT
format(
'ALTER ROLE %I WITH %s%s%s%s%s%s%s%s;',
rolname,
CASE WHEN rolsuper THEN 'SUPERUSER ' ELSE 'NOSUPERUSER ' END,
CASE WHEN rolinherit THEN 'INHERIT ' ELSE 'NOINHERIT ' END,
CASE WHEN rolcreaterole THEN 'CREATEROLE ' ELSE 'NOCREATEROLE ' END,
CASE WHEN rolcreatedb THEN 'CREATEDB ' ELSE 'NOCREATEDB ' END,
CASE WHEN rolcanlogin THEN 'LOGIN ' ELSE 'NOLOGIN ' END,
CASE WHEN rolreplication THEN 'REPLICATION ' ELSE 'NOREPLICATION ' END,
CASE WHEN rolbypassrls THEN 'BYPASSRLS ' ELSE 'NOBYPASSRLS ' END,
'CONNECTION LIMIT ' || rolconnlimit
)
FROM pg_roles
WHERE rolname !~ '^pg_'
ORDER BY rolname;
SQL
RET=$?
if [[ $RET -ne 0 ]]; then
USERS_OK=
USER_ERRORS+="roles_export "
log "ERROR: Users export failed"
else
log "Roles export completed: $ROLES_FILE"
fi
set -e
log "Sending roles file to IA server"
set +e
scp "${SSH_OPTS[@]}" "$ROLES_FILE" "$IA_SSH:${REMOTE_DIR}/"
RET=$?
if [[ $RET -ne 0 ]]; then
USERS_OK=
USER_ERRORS+="roles_scp "
log "ERROR: Users transfer failed (roles file)"
else
log "Roles transfer completed"
fi
set -e
#######################################
# Dump des bases + transfert (continue même si KO)
#######################################
set +e
for DB in "${DBS[@]}"; do
FILE="${TMP_DIR}/${DB}_${TS}.dump"
log "Dumping database: $DB"
pg_dump -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -Fc --no-owner --no-acl -d "$DB" -f "$FILE"
RET=$?
if [[ $RET -ne 0 ]]; then
DUMPS_OK=
DUMP_ERRORS+="${DB} "
log "ERROR: Dump failed for $DB"
continue
fi
log "Dump completed: $FILE"
log "Sending dump to IA server"
scp "${SSH_OPTS[@]}" "$FILE" "$IA_SSH:${REMOTE_DIR}/"
RET=$?
if [[ $RET -ne 0 ]]; then
DUMPS_OK=
DUMP_ERRORS+="${DB}(scp) "
log "ERROR: Transfer failed for $DB"
continue
fi
log "Transfer completed for $DB"
done
set -e
#######################################
# Nettoyage
#######################################
log "Cleaning temporary files"
rm -rf "$TMP_DIR"
#######################################
# Envoi message Discord (final)
#######################################
DETAILS=""
[[ -z "${DUMPS_OK:-}" ]] && DETAILS+="Dumps KO: ${DUMP_ERRORS} "
[[ -z "${USERS_OK:-}" ]] && DETAILS+="Users KO: ${USER_ERRORS} "
discord_ping "$DETAILS"
log "Backup finished"

View File

@@ -1,3 +0,0 @@
.env
backup.log