haproxy_maintenance

HAProxy - Activation automatique de la page de maintenance

CréationNicolas 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.

  • 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

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 "<html><body>" >> $WEB
	echo "<br>" >> $WEB
	echo "<br>" >> $WEB
	echo "<center>$MESSAGE</center>" >> $WEB
	echo "<center>Veuillez nous excuser pour la g&ecirc;ne occasionn&eacute;e.</center>" >> $WEB
	echo "</body></html>" >> $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

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"

Entrer votre commentaire. La syntaxe wiki est autorisée:
 
  • haproxy_maintenance.txt
  • Dernière modification : 2021/03/05 16:20
  • de nekan