====== HAProxy - Activation automatique de la page de maintenance ====== --- //[[nekan@shyrkasystem.com|Nicolas THOREZ]] 2020/02/18 17:25// Dans une configuration de cluster avec ''haproxy'', on peut être amené à désactiver les ''backends'' et les remplacer par une page de maintenance selon les besoins de la production. Le but du script suivant est d'activer ou désactiver la maintenance sur ''haproxy''. ===== Prérequis ===== * Sur un ''haproxy'' correctement paramétré, dupliquer le fichier ''/etc/haproxy/haproxy.cfg'' en ''/etc/haproxy/haproxy.maintenance''. * Modifier ''/etc/haproxy/haproxy.maintenance'' pour que chaque ''frontend'' renvoie vers un ''backend'' de maintenance. * Modifier le ''backend'' de maintenance pour qu'il renvoie la page web ''/etc/haproxy/errors/maintenance.http'' ===== Script ===== Le script est généralement placé dans ''/usr/local/batch'' sous le nom ''set-ha-maintenance.sh''. #!/bin/bash ################################################################################## # # Script d'activation/désactivation de la maintenance sur le HAProxy # # Par Nicolas THOREZ # # Date de création : 18/02/2020 # ################################################################################## ##### Déclaration des fonctions # Fonction d'aide display-help() { # Affichage de l'aide echo "" echo "Aide pour set-ha-maintenance.sh" echo "" echo "Script d'activation/désactivation de la maintenance sur le HAProxy." echo "" echo "Activation : ./set-ha-maintenance.sh [-a|--activation] [-m|--message] message [-n|--notification] adresse_mail" echo "Désactivation : ./set-ha-maintenance.sh [-d|--desactivation] [-n|--notification] adresse_mail" echo "Aide : ./set-ha-maintenance.sh [-h|--help]" echo "" echo "Paramètres et arguments :" echo "" echo "-h, --help Affiche cette aide." echo "" echo "-a, --activation Active la maintenance." echo " Ne peut être utilisé en même temps que -d." echo "" echo "-d, --desactivation Désactive la maintenance." echo " Ne peut être utilisé en même temps que -a." echo "" echo " Il faut obligatoirement utiliser soit -a soit -d." echo "" echo "-m, --message Indique le message qui sera affiché sur la page de maintenance." echo " Obligatoire avec le paramètre -a." echo "" echo "-n, --notification Envoi un email de notification à l'adresse indiquée." echo " Facultatif." echo "" exit 2 } # Fonction d'affichage des messages dans la console write-host() { # Variables pour la coloration syntaxique GOOD="\e[92m" CRIT="\e[91m" WARN="\e[93m" INFO="\e[96m" UNKN="\e[95m" OFF="\e[39m" # Gestion des arguments pour la fonction while [[ $# -gt 0 ]] do WRITE_PARAM="$1" case $WRITE_PARAM in # Coloration -l|--level) LEVEL="$2" shift shift ;; # Message -o|--output) OUTPUT="$2" shift shift ;; # Autres *) echo -e "$CRIT[CRIT]$OFF Erreur d'arguments pour la fonction$CRIT write-host$OFF. Merci de vérifier votre code." ;; esac done # Affichage console case $LEVEL in "GOOD") echo -e "$GOOD[GOOD]$OFF $OUTPUT" ;; "WARN") echo -e "$WARN[WARN]$OFF $OUTPUT" ;; "CRIT") echo -e "$CRIT[CRIT]$OFF $OUTPUT" ;; "INFO") echo -e "$INFO[INFO]$OFF $OUTPUT" ;; *) echo -e "$UNKN[UNKN]$OFF $OUTPUT" ;; esac } ##### Traitement des arguments en entrée while [[ $# -gt 0 ]] do PARAM="$1" case $PARAM in # Aide "-h"|"--help") display-help shift ;; # Activation "-a"|"--activation") ACTIVATION="TRUE" shift ;; # Désactivation "-d"|"--desactivation") DESACTIVATION="TRUE" shift ;; # Message "-m"|"--message") MESSAGE="$2" shift shift ;; # Mail "-n"|"--notification") MAIL="$2" shift shift ;; # Autres *) display-help shift ;; esac done ##### Déclarations des variables # Dossier du haproxy HADIR=/etc/haproxy # Fichier de configuration actif ACTIF=$HADIR/haproxy.cfg # Fichier de configuration prod PROD=$HADIR/haproxy.prod # Fichier de configuration maintenance MAINTENANCE=$HADIR/haproxy.maintenance # Page web de maintenance WEB=$HADIR/errors/maintenance.http # Hôte sur lequel est exécuté le script HOSTNAME=$(hostname) # Date d'exécution DATE=$(date '+%Y/%m/%d %H:%M:%S') ##### Validation des paramètres d'entrée # Vérification de l'action et du message (si activation) if [ "$ACTIVATION" == "TRUE" ] then if [ "$DESACTIVATION" == "TRUE" ] then write-host -l "CRIT" -o "On ne peut pas activer et désactiver en même temps." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. On ne peut pas activer et désactiver en même temps. Aucune modification apportée." | mail -s "CRIT - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi display-help else write-host -l "INFO" -o "Mode activation de la maintenance." ACTION="ACTIVATION" if [ -z "$MESSAGE" ] then write-host -l "CRIT" -o "En cas d'activation, un message est obligatoire." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. En cas d'activation, un message est obligatoire. Aucune modification apportée." | mail -s "CRIT - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi display-help else write-host -l "INFO" -o "Message renseigné." fi fi else if [ "$DESACTIVATION" == "TRUE" ] then write-host -l "INFO" -o "Mode désactivation de la maintenance." ACTION="DESACTIVATION" else write-host -l "CRIT" -o "Il faut obligatoirement indiquer une action." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. Il faut obligatoirement indiquer une action. Aucune modification apportée." | mail -s "CRIT - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi display-help fi fi # Test du status de haproxy TEST=$(/etc/init.d/haproxy status | grep '(running)' | wc -l) if [[ $TEST -ne 1 ]] then write-host -l "WARN" -o "Haproxy inactif. Veuillez l'activer avant de lancer ce script." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. Haproxy inactif. Veuillez l'activer avant de lancer ce script. Aucune modification apportée." | mail -s "WARN - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi exit 1 fi # Traitement selon l'action désirée case $ACTION in "ACTIVATION") # Vérification de la présence du fichier de maintenance if [ -r $MAINTENANCE ] then write-host -l "GOOD" -o "Fichier de maintenance trouvé." else write-host -l "WARN" -o "Fichier de maintenance introuvable." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. Fichier de maintenance introuvable. Aucune modification apportée." | mail -s "WARN - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi exit 1 fi # Transfert du fichier actif vers fichier de prod mv -f $ACTIF $PROD write-host -l "GOOD" -o "Désactivation du fichier de production." # Activation du fichier de maintenance mv -f $MAINTENANCE $ACTIF write-host -l "GOOD" -o "Activation du fichier de maintenance." # Modification de la page web de maintenance echo "HTTP/1.0 503 Service Unavailable" > $WEB echo "Cache-Control: no-cache" >> $WEB echo "Connection: close" >> $WEB echo "Content-Type: text/html" >> $WEB echo "" >> $WEB echo "" >> $WEB echo "
" >> $WEB echo "
" >> $WEB echo "
$MESSAGE
" >> $WEB echo "
Veuillez nous excuser pour la gêne occasionnée.
" >> $WEB echo "" >> $WEB write-host -l "GOOD" -o "Modification de la page de maintenance." # Fin de l'option ;; "DESACTIVATION") # Vérification de la présence du fichier de prod if [ -r $PROD ] then write-host -l "GOOD" -o "Fichier de production trouvé." else write-host -l "WARN" -o "Fichier de production introuvable." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. Fichier de maintenance introuvable. Aucune modification apportée." | mail -s "WARN - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi exit 1 fi # Transfert du fichier actif vers fichier de maintenance mv -f $ACTIF $MAINTENANCE write-host -l "GOOD" -o "Désactivation du fichier de maintenance." # Activation du fichier de prod mv -f $PROD $ACTIF write-host -l "GOOD" -o "Activation du fichier de production." # Fin de l'option ;; *) write-host -l "UNKN" -o "Erreur inconnue 1." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. Erreur inconnue 1. A priori, le HAPROXY est toujours actif sur l'ancienne configuration." | mail -s "UNKN - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi exit 3 ;; esac # Rechargement du haproxy /etc/init.d/haproxy reload # Vérification du status du haproxy TEST=$(/etc/init.d/haproxy status | grep '(running)' | wc -l) if [[ $TEST -ne 1 ]] then write-host -l "CRIT" -o "Erreur de rechargement de la configuration. HAPROXY inactif." if [ -n "$MAIL" ] then echo "$DATE Erreur lors de l'activation de la maintenance sur $HOSTNAME. HAPROXY inactif." | mail -s "CRIT - $HOSTNAME - Echec de l'activation de la maintenance" $MAIL fi exit 2 else write-host -l "GOOD" -o "Configuration chargée. HAPROXY actif." if [ -n "$MAIL" ] then echo "$DATE Activation de la maintenance sur $HOSTNAME avec le message : $MESSAGE" | mail -s "GOOD - $HOSTNAME - Activation de la maintenance" $MAIL fi exit 0 fi # Si on toujours pas sortie alors erreur inconnue write-host -l "UNKN" -o "Erreur inconnue 2." if [ -n "$MAIL" ] then echo "$DATE Erreur sur $HOSTNAME. Erreur inconnue 2. Etat du HAPROXY inconnu." | mail -s "UNKN - $HOSTNAME - Echec de la modification de la maintenance" $MAIL fi exit 3
===== Planification ===== Pour planifier une maintenance, il suffit de mettre en place un ''cron'' pour l'activation et un autre pour la désactivation. Par exemple : * Activation tous les 1ers du mois à 5h00 : ''/etc/cron.d/maintenance-on'' 0 5 1 * * root /usr/local/batch/set-ha-maintenance.sh -a -m "Maintenance de 5h00 à 7h00" -n "nekan@shyrkasystem.com" * Désactivation 2 heures plus tard : ''/etc/cron.d/maintenance-off'' 0 7 1 * * root /usr/local/batch/set-ha-maintenance.sh -d -n "nekan@shyrkasystem.com" ~~DISCUSSION~~