-
Notifications
You must be signed in to change notification settings - Fork 6
/
render_cfg.sh
executable file
·106 lines (94 loc) · 2.8 KB
/
render_cfg.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
#!/bin/bash
#
# Renders a foo.cfg.tpl file into foo.cfg
# Uses DNS RR resolution to render a line for each resolved host.
#
# $ render_cfg.sh <hostnames> </path/to/some.cfg.tpl> [ip_address,...]
#
# Multiple hostnames may be given separated by commas, with no spaces
set -e
service=$1
template=$2
# Check for fatal errors
if ! [ -f $template ]; then
echo "Template file $template does not exist."
exit 1
fi
# Third parameter is list of ips
if [[ -n $3 ]]; then
ips=(${3//,/ })
# Otherwise use DNS lookup
else
oldfile=/tmp/cfg.$(<<<$service md5sum - | awk '{print $1}')
tmpfile=$(mktemp -t cfg.XXXXXXX)
# Resolve DNS
for _service in ${service//,/ }; do
nslookup $_service 2>/dev/null | awk '/^Name:/{p=1} p&&/^Address:/{ print $2 }'
done | sort | paste -sd ',' > $tmpfile
if [ $(wc -c $tmpfile | gawk '{print $1}') -eq 0 ]; then
rm $tmpfile
echo "Unable to resolve addresses for $service "
exit 1
fi
# Check if IP addresses for service changed
if test -f $oldfile && cmp -s $oldfile $tmpfile; then
rm $tmpfile
exit 2
fi
# Remove oldfile to prevent tmp file accumulation
if [ -f $oldfile ]; then
rm $oldfile
fi
echo "New service addresses: $(cat $tmpfile)"
IFS=',' read -ra ips < $tmpfile
fi
tmptpl=$(mktemp -t tpl.XXXXXXX)
tmptpl2=$(mktemp -t tpl.XXXXXXX)
cp $template $tmptpl
index=0
while true; do
pattern=$(sed -n '/^\s*{{HOSTS}}$/,/^\s*{{\/HOSTS}}$/{//!p}' $tmptpl | head -n 1)
pattern=$(gawk '/^\s*{{\/HOSTS}}/{exit} p; /^\s*{{HOSTS}}$/{p=1} /^\s*{{\/HOSTS}}/{exit}' $tmptpl)
#pattern='server ${service}${num} ${ip}:3306 check'
[ -n "$pattern" ] || break
gawk "BEGIN{a=0} /^\\s*{{HOSTS}}\$/&&a==0 {f=1} !f; /^\\s*{{\\/HOSTS}}\$/&&a==0 {print \"\${HOSTS$index}\"; f=0; a++}" $tmptpl > $tmptpl2
HOSTS="";SEP=""
for ip in "${ips[@]}"; do
num=${ip##*.}
host=$(eval "echo \"$pattern\"")
HOSTS=$(printf "$HOSTS$SEP$host")
SEP=$'\n'
done
eval "HOSTS$index=\"$(printf "$HOSTS")\""
index=$(($index + 1))
cp $tmptpl2 $tmptpl
done
while true; do
pattern=$(sed -n 's/.*{{HOSTS}}\(.*\){{\/HOSTS}}.*/\1/p' $tmptpl | head -n 1)
[[ -n $pattern ]] || break
gawk "!x{x=sub(/{{HOSTS}}.*{{\\/HOSTS}}/,\"\${HOSTS$index}\");} 1" < $tmptpl > $tmptpl2
_SEP="${pattern: -1}"
pattern="${pattern%?}"
HOSTS="";SEP=""
for ip in "${ips[@]}"; do
num=${ip##*.}
host=$(eval "echo \"$pattern\"")
HOSTS=$(printf "$HOSTS$SEP$host")
SEP=$_SEP
done
eval "HOSTS$index=\"$(printf "$HOSTS")\""
index=$(($index + 1))
cp $tmptpl2 $tmptpl
done
sed -i 's/\$/@@@/g' $tmptpl2
sed -i 's/@@@{HOSTS\([0-9]*\)}/${HOSTS\1}/g' $tmptpl2
eval "echo \"$(cat $tmptpl2)\"" > $tmptpl
sed -i 's/@@@/$/g' $tmptpl
mv $tmptpl ${template%.tpl}
rm $tmptpl2
# Update last DNS resolution result
if [[ -z $3 ]]; then
mv $tmpfile $oldfile
fi
# 0 means config was updated
exit 0