forked from HariSekhon/HAProxy-configs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
check_haproxy_syntax.sh
executable file
·137 lines (126 loc) · 4.47 KB
/
check_haproxy_syntax.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env bash
# vim:ts=4:sts=4:sw=4:et
#
# Author: Hari Sekhon
# Date: 2018-01-15 17:56:39 +0000 (Mon, 15 Jan 2018)
#
# https://github.com/HariSekhon/HAProxy-configs
#
# License: see accompanying Hari Sekhon LICENSE file
#
# If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback to help steer this or other code I publish
#
# https://www.linkedin.com/in/HariSekhon
#
set -euo pipefail
[ -n "${DEBUG:-}" ] && set -x
srcdir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
haproxy_srcdir="$srcdir"
# shellcheck disable=SC1090
. "$srcdir/bash-tools/lib/utils.sh"
section "HAProxy Configs"
echo "Testing all HAProxy configs under $haproxy_srcdir for correctness:"
echo
echo "(requires HAProxy 1.7+ to be able to skip any unresolvable DNS entries)"
echo
# shellcheck disable=SC2086
trap 'pkill -9 -P $$; exit 1' $TRAP_SIGNALS
configs_without_acls="
http.cfg
"
ppid=$$
test_haproxy_conf(){
local cfg="$1"
local str
str="$(printf "%-${maxwidth}s " "$cfg:")"
if haproxy -c -f 10-global.cfg -f 20-stats.cfg -f "$cfg" &>/dev/null; then
echo "$str OK"
if ! grep -q "^$cfg$" <<< "$configs_without_acls"; then
if ! grep -q -e '^[[:space:]]*acl internal_networks src 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 127.0.0.1$' "$cfg"; then
echo "ERROR: No internal networks ACL defined in config $cfg"
kill $ppid
exit 1
fi
# leave unanchored at end to allow elasticsearch-auth.cfg to append auth_ok ACLs
if ! grep -q -e '^[[:space:]]*http-request deny if ! internal_networks' \
-e '^[[:space:]]*tcp-request content reject if ! internal_networks$' "$cfg"; then
echo "ERROR: No ACL defined in config $cfg"
kill $ppid
exit 1
fi
fi
#for mode in tcp http; do
# backends don't respect the advanced logging options any more so have been removed from backends so it's no longer 1 to 1
#num_mode=$(grep -Ec "^[[:space:]]*mode[[:space:]]+$mode" "$cfg" || :)
#num_option_log=$(grep -Ec "^[[:space:]]*option[[:space:]]+${mode}log" "$cfg" || :)
#if [ "$num_mode" != "$num_option_log" ]; then
# echo "ERROR: missing advanced logging options in $cfg"
# kill $ppid
# exit 1
#fi
#done
if grep -E "^[[:space:]]*mode[[:space:]]+tcp" && ! grep -Ec "^[[:space:]]*option[[:space:]]+tcplog" "$cfg"; then
echo "ERROR: missing advanced logging options in $cfg"
kill $ppid
exit 1
fi
else
echo "$str FAILED"
echo
echo "Error:"
echo
haproxy -c -f 10-global.cfg -f 20-stats.cfg -f "$cfg" || :
kill $ppid
fi
}
if [ $# -gt 0 ]; then
configs="$*"
else
configs="$(echo [a-z]*.cfg ./*/*.cfg)"
fi
if command -v haproxy &>/dev/null; then
set +o pipefail
haproxy 2>/dev/null | head -n1
haproxy_version="$(haproxy 2>/dev/null | head -n1 | awk '{print $3}' | awk -F. '{print $1"."$2}')"
if ! type -P bc >/dev/null; then
echo "bc command not found, cannot test HAProxy version, skipping tests..."
exit 0
fi
if [ "$(bc <<< "$haproxy_version < 1.7")" = 1 ]; then
echo
echo 'WARNING: HAProxy version too old to test these configs!!'
untrap
exit 0
fi
set -o pipefail
echo
cd "$haproxy_srcdir"
echo
maxwidth=0
for cfg in $configs; do
if [ "${#cfg}" -gt $maxwidth ]; then
maxwidth="${#cfg}"
fi
done
((maxwidth+=1))
for cfg in $configs; do
# slow due to all the DNS lookup failures for alternative haproxy services DNS names so aggressively parallelizing
test_haproxy_conf "$cfg" &
done
# this waits for all children but returns zero if even one of the children returns non-zero so we kill our own process from the child as a workaround
wait
# race condition as first child finishes before this loop starts and can't test for their existence as there would be a race condition between the check and wait command
#for num in `seq ${#configs}`; do
# wait $num
#done
echo
echo "All HAProxy Configurations Passed Checks"
elif is_CI; then
echo "FAILED: haproxy is not installed"
exit 1
else
echo
echo "WARNING: HAProxy configurations NOT TESTED (haproxy not found in path, please install first)"
fi
echo
untrap