====== 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~~