Table des matières

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.

Prérequis

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 "<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

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 :

0 5 1 * * root /usr/local/batch/set-ha-maintenance.sh -a -m "Maintenance de 5h00 à 7h00" -n "nekan@shyrkasystem.com"

0 7 1 * * root /usr/local/batch/set-ha-maintenance.sh -d -n "nekan@shyrkasystem.com"