#!/bin/bash # ====================================================================== # # haproxy functions # parse haproxy.cfg - as good I can do with bash # # ---------------------------------------------------------------------- # 2021-12-14 v1.0 <axel.hahn@iml.unibe.ch> init # ====================================================================== # full path to haproxy.cfg HAPROXYcfgfile=/etc/haproxy/haproxy.cfg # rewritten config as tmp file to parse data HAPROXYdumpfile=/tmp/haproxy.config # enable caching; value 0 = off - it recreates tmp file on each run HAPROXYdoCache=0 # TESTING ONLY # HAPROXYcfgfile=./haproxy-01.cfg # /TESTING # ---------------------------------------------------------------------- # # functions # # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- # CONFIG REWRITER # ---------------------------------------------------------------------- # rewrite the ha proxy config file to parse it by section # it creates output with # # section + ":" + variable + "=" + value # i.e.: # # new section: global # global:chroot=/var/lib/haproxy # global:daemon= # global:user=haproxy # global:group=haproxy # global:maxconn=4000 # global:pidfile=/var/run/haproxy.pid # ... function cfgrewriter(){ local _section= IFS='' while read line do echo $line | grep "^[a-z]" >/dev/null if [ $? -eq 0 ]; then _section=$line echo "# new section: $_section" fi echo $line | grep "^\ \ [a-z]*" >/dev/null if [ $? -eq 0 ]; then echo -n "$_section:" echo $line | sed -e "s#^\ *\([a-z\-]*\)\ *#\1=#g" fi done < $HAPROXYcfgfile } # ------------------------------------------------------------ # dump Cfg data # ------------------------------------------------------------ # dump rewritten config function _dumpCfg(){ cat $HAPROXYdumpfile } # dump rewritten config and filter by a given section # param string name of section function _dumpSection(){ local _section=$1 _dumpCfg | grep "^${_section}:" } # ------------------------------------------------------------ # parsing functions # ------------------------------------------------------------ # get a value from a given section # param string name of variable # param string name of section function _getCfgVarFromSection(){ local _var=$1 local _section=$2 _dumpSection "${_section}" | grep ":${_var}=" | cut -f 2 -d "=" } # get sections where a given var exists # param string name of variable function getCfgSectionsOfVar(){ local _var="$1" _dumpCfg | grep ":${_var}=" | cut -f 1 -d ":" | sort -u } # get a value from config - with autoscan of sections defaults and globals # param string name of variable # param string name of section function getCfgVar(){ local _var=$1 local _section=$2 test -z "$_section" && _section='.*' _getCfgVarFromSection "${_var}" "${_section}" \ || _getCfgVarFromSection "${_var}" "defaults" \ || _getCfgVarFromSection "${_var}" "global" } # ---------------------------------------------------------------------- # High level functions # ---------------------------------------------------------------------- # detect the section where variables named "stats" are defined # to generate urls for health check and status # WARNING: this function is UNSAFE ... it is heavy to parse # haproxy.cfg with a bash script :-/ function detectStatsSection(){ getCfgSectionsOfVar "stats" | tail -1 } # get a string with base url for stats and health check function getStatsBaseUrl(){ # default url parts local proto=http local auth= local host=localhost local port=80 local mysection=$( detectStatsSection ) # read config port=$( getCfgVar "bind" "${mysection}" | cut -f 2 -d ":") auth=$( getCfgVar "stats" "${mysection}" | grep "^auth" | cut -f 2- -d " " ) # build url url="$proto://" test -z "$auth" || url="${url}${auth}@" url="${url}${host}:${port}" echo $url } # get a string with a health url function getHealthUri(){ local uri=$( getCfgVar "monitor-uri" ) test -z "$uri" || echo $( getStatsBaseUrl )${uri} } # get a string with a status page function getStatusUri(){ local mysection=$( detectStatsSection ) local uri=$( getCfgVar "stats" "${mysection}" | grep "^uri " | cut -f 2- -d " " ) test -z "$uri" || echo $( getStatsBaseUrl )${uri} } # ---------------------------------------------------------------------- # INIT if [ $HAPROXYdoCache = 0 -o $HAPROXYcfgfile -nt $HAPROXYdumpfile ]; then cfgrewriter >$HAPROXYdumpfile fi