-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhaproxy.sh
507 lines (506 loc) · 20.4 KB
/
haproxy.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
#!/bin/bash
check_haproxy_availability() {
if command -v haproxy &>/dev/null; then
return 0 # HAProxy is installed
else
return 1 # HAProxy is not installed
fi
}
install_haproxy() {
clear
if check_haproxy_availability; then
echo "HAProxy is already installed."
read -n 1 -s -r -p "Press any key to continue"
echo
else
# Install HAProxy
echo "Installing HAProxy..."
if [ -x "$(command -v apt-get)" ]; then
sudo apt-get update
sudo apt-get install -y haproxy
apt install curl socat -y
elif [ -x "$(command -v yum)" ]; then
sudo yum install -y haproxy
else
echo "Unsupported package manager. Cannot install HAProxy."
exit 1
fi
# Check installation status
if [ $? -eq 0 ]; then
# Backup the original configuration file (optional)
cp "/etc/haproxy/haproxy.cfg" "/etc/haproxy/haproxy.cfg.bak"
# Replace the original configuration file with the new one
# Download the haproxy.cfg from GitHub and overwrite the original file
wget -O /etc/haproxy/haproxy.cfg https://raw.githubusercontent.com/Argo160/HaProxy_LoadBalancer/main/haproxy.cfg
echo "HAProxy configuration file replaced successfully."
echo "HAProxy installed successfully."
read -n 1 -s -r -p "Press any key to continue"
echo
else
echo "Failed to install HAProxy."
exit 1
fi
fi
}
uninstall_haproxy() {
if check_haproxy_availability; then
clear
# Prompt the user for confirmation with default value 'n'
read -p "Are you sure to uninstall the loadBalancer? (y/n) [n]: " -r answer
# Use default value if user input is empty
answer=${answer:-n}
# Check the user's response
if [[ $answer == [Yy] ]]; then
# Uninstall HAProxy
echo "Uninstalling HAProxy..."
if [ -x "$(command -v apt-get)" ]; then
sudo apt-get remove --purge -y haproxy
elif [ -x "$(command -v yum)" ]; then
sudo yum remove -y haproxy
else
echo "Unsupported package manager. Cannot uninstall HAProxy."
exit 1
fi
# Check uninstallation status
if [ $? -eq 0 ]; then
echo "HAProxy uninstalled successfully."
read -n 1 -s -r -p "Press any key to continue"
echo
else
echo "Failed to uninstall HAProxy."
exit 1
fi
# Add commands to uninstall the loadBalancer here
else
echo "Operation canceled. LoadBalancer will not be uninstalled."
read -n 1 -s -r -p "Press any key to continue"
echo
return
fi
else
echo "HAProxy is not installed."
exit 1
fi
}
add_ip() {
clear
# Check if at least one port is specified in both backend and frontend sections
config_file="/etc/haproxy/haproxy.cfg"
# Check if the configuration file exists
if [ ! -f "$config_file" ]; then
echo "Error: HAProxy configuration file not found: $config_file"
read -n 1 -s -r -p "Press any key to continue"
echo
exit 1
fi
# Extract frontend port numbers from the configuration file
frontend_ports=$(grep -E "^\s*frontend\s+port[0-9]+" "$config_file" | awk '{print $2}')
# Check if any frontend ports are defined
if [ -z "$frontend_ports" ]; then
echo "Please specify at least one port in the HAProxy configuration file before adding IP addresses."
read -n 1 -s -r -p "Press any key to continue"
echo
return
fi
# Extract backend IP addresses from the configuration file
backend_ips=$(grep -Eo '\b([0-9]+\.){3}[0-9]+|([0-9a-fA-F]+:){2,7}[0-9a-fA-F]+(::1)?\b' "$config_file" | sort -u)
# Check if any backend IPs are defined
clear
if [ -z "$backend_ips" ]; then
echo "No IPs defined in the configuration file yet."
read -n 1 -s -r -p "Press any key to continue"
echo
else
echo -e "\e[1mThe current IPs defined in the configuration file:\e[0m"
echo -e "\e[1m\e[33m$backend_ips\e[0m"
fi
# Prompt the user for the new IP address
read -p "Enter the new IP address: " new_ip
# Check if the entered IP address is valid
if [[ $new_ip =~ ^[0-9.]+$ ]]; then
# IPv4 address
ip_format="%s"
elif [[ $new_ip =~ ^[0-9a-fA-F:.]+$ ]]; then
# IPv6 address
ip_format="[%s]"
else
echo "Error: Invalid IP address format."
read -n 1 -s -r -p "Press any key to continue"
echo
return
fi
# Extract backend names from the configuration file
backend_names=$(awk '/^\s*backend\s+/{print $2}' "$config_file")
#check if backend is empty or not
if [ -z "$backend_names" ]; then
for port in $frontend_ports; do
front_ports=$(echo "$port" | sed 's/port//g')
backend_name="backend$front_ports"
echo "backend $backend_name" >> "$config_file"
echo " balance roundrobin" >> "$config_file"
echo " server server"$new_ip" $(printf "$ip_format" "$new_ip"):$front_ports check" >> "$config_file"
done
systemctl restart haproxy
else
if grep -qE "(^| )($new_ip:|\[$new_ip\]|$new_ip)( |$|\]|:)" "$config_file"; then
echo "IP $new_ip is already present in the configuration file."
read -n 1 -s -r -p "Press any key to continue"
echo
return
else
# Add the new IP address to the backend sections after the line containing "balance roundrobin"
for backend_name in $backend_names; do
sed -i "/^\s*backend\s\+$backend_name\s*$/,/balance roundrobin/ s/\(balance roundrobin\)/\1\n server server"$new_ip" $(printf "$ip_format" "$new_ip"):${backend_name#backend} check/" "$config_file"
done
fi
echo "New IP address added to the HAProxy configuration file."
systemctl restart haproxy
read -n 1 -s -r -p "Press any key to continue"
echo
fi
}
remove_ip() {
config_file="/etc/haproxy/haproxy.cfg"
backend_ips=$(grep -Eo '\b([0-9]+\.){3}[0-9]+|([0-9a-fA-F]+:){2,7}[0-9a-fA-F]+(::1)?\b' "$config_file" | sort -u)
num_ips=$(echo "$backend_ips" | wc -l)
# Check if any backend IPs are defined
clear
if [ -z "$backend_ips" ]; then
echo "No IPs defined in the configuration file yet."
read -n 1 -s -r -p "Press any key to continue"
echo
return
else
echo -e "\e[1mThe current IPs defined in the configuration file:\e[0m"
echo -e "\e[1m\e[33m$backend_ips\e[0m"
fi
read -p "Enter IP address to delete: " old_ip
#check if there are more than 1 unique ip and the one is already there
if grep -qE "(^| )($old_ip:|\[$old_ip\]|$old_ip)( |$|\]|:)" "$config_file"; then
if [ "$num_ips" -gt 1 ]; then
# Delete only the given IP from the backends
sed -i "/server.*$old_ip.*check/d" "$config_file"
echo "Deleted IP $old_ip from the backends."
systemctl restart haproxy
read -n 1 -s -r -p "Press any key to continue"
echo
elif [ "$num_ips" -eq 1 ]; then
# Delete the entire backend
last_default_backend_line=$(grep -n "default_backend" "$config_file" | tail -n1 | cut -d: -f1)
sed -i "${last_default_backend_line}q" "$config_file"
#sed -i "${last_default_backend_line},$ d" "$config_file"
echo "Deleted the entire backend where IP $old_ip was the only one."
systemctl restart haproxy
read -n 1 -s -r -p "Press any key to continue"
echo
fi
else
echo "IP $old_ip is not present in the configuration file."
read -n 1 -s -r -p "Press any key to continue"
echo
fi
}
add_port() {
clear
# Check if at least one port is specified in both backend and frontend sections
config_file="/etc/haproxy/haproxy.cfg"
# Check if the configuration file exists
if [ ! -f "$config_file" ]; then
echo "Error: HAProxy configuration file not found: $config_file"
read -n 1 -s -r -p "Press any key to continue"
echo
exit 1
fi
# Extract frontend port numbers from the configuration file
frontend_ports=$(grep -E "^\s*frontend\s+port[0-9]+" "$config_file" | awk '{print $2}')
# Check if any frontend ports are defined
if [ -z "$frontend_ports" ]; then
read -p "Enter the port to add: " port_to_add
# Create the configuration snippet
config_snippet="frontend port${port_to_add}
bind *:${port_to_add}
default_backend backend${port_to_add}"
# Append the snippet to the end of the file
echo "$config_snippet" >> "$config_file"
echo "Successfully added the configuration snippet for port ${port_to_add}."
read -n 1 -s -r -p "Press any key to continue"
echo
else
echo -e "\e[1mCurrent Ports::\e[0m"
echo -e "\e[33m$frontend_ports\e[0m"
read -p "Enter the port to add: " port_to_add
if [ -n "$(grep -E "frontend port${port_to_add}\\b" "$config_file")" ]; then
echo "The Port is already available"
read -n 1 -s -r -p "Press any key to continue"
echo
return
fi
# Find the last line containing "default_backend"
last_default_backend_line=$(grep -n "default_backend" "$config_file" | tail -n1 | cut -d: -f1)
# Append the new frontend configuration after the last line containing "default_backend"
new_frontend_config="frontend port${port_to_add}\\
bind *:${port_to_add}\\
default_backend backend${port_to_add}"
sed -i "${last_default_backend_line} a\\
${new_frontend_config}" "$config_file"
echo "Successfully added the new frontend configuration for port ${port_to_add}."
# Extract backend IP addresses from the configuration file
backend_ips=$(grep -Eo '\b([0-9]+\.){3}[0-9]+|([0-9a-fA-F]+:){2,7}[0-9a-fA-F]+(::1)?\b' "$config_file" | sort -u)
# Check if any backend IPs are defined
clear
if [ -z "$backend_ips" ]; then
echo "No IPs defined in the configuration file yet."
read -n 1 -s -r -p "Press any key to continue"
echo
else
echo "backend backend$port_to_add" >> "$config_file"
echo " balance roundrobin" >> "$config_file"
for ip in $backend_ips; do
# Check if the entered IP address is valid
if [[ $ip =~ ^[0-9.]+$ ]]; then
# IPv4 address
ip_format="%s"
elif [[ $ip =~ ^[0-9a-fA-F:.]+$ ]]; then
# IPv6 address
ip_format="[%s]"
fi
echo " server server"$ip" $(printf "$ip_format" "$ip"):$port_to_add check" >> "$config_file"
done
systemctl restart haproxy
echo "Successfully added the backend(s) configuration for port ${port_to_add}."
read -n 1 -s -r -p "Press any key to continue"
echo
fi
fi
}
remove_port() {
clear
config_file="/etc/haproxy/haproxy.cfg"
# Extract frontend port numbers from the configuration file
frontend_ports=$(grep -E "^\s*frontend\s+port[0-9]+" "$config_file" | awk '{print $2}')
# Check if any frontend ports are defined
if [ -z "$frontend_ports" ]; then
echo "No ports defined to delete"
read -n 1 -s -r -p "Press any key to continue"
echo
return
else
echo -e "\e[1mCurrent Ports::\e[0m"
echo -e "\e[33m$frontend_ports\e[0m"
read -p "Enter the port to delete: " port_to_delete
existing_frontend=$(grep -E "frontend port${port_to_delete}\\b" "$config_file")
if [ -n "$existing_frontend" ]; then
# Delete the frontend configuration for the given port
sed -i "/^frontend port${port_to_delete}/,+2 d" "$config_file"
sed -i "/^backend backend${port_to_delete}$/,/^backend/ {/^backend backend${port_to_delete}$/b; /^backend/!d}" "$config_file"
sed -i "/^backend backend${port_to_delete}$/d" "$config_file"
echo "Successfully deleted for port ${port_to_delete}."
systemctl restart haproxy
read -n 1 -s -r -p "Press any key to continue"
echo
else
echo "Frontend configuration for port ${port_to_delete} does not exist."
read -n 1 -s -r -p "Press any key to continue"
echo
fi
fi
}
health_check() {
clear
config_file="/etc/haproxy/haproxy.cfg"
# Extract backend names from the configuration file
backend_names=$(awk '/^\s*backend\s+/{print $2}' "$config_file")
for backend_name in $backend_names; do
server_info=$(echo "show stat" | socat stdio /run/haproxy/admin.sock | awk -F',' "/^$backend_name,/ && !/BACKEND/{print \$74,\$18}")
echo "$server_info" | while read -r server_ip status; do
if [[ "$status" == "UP" ]]; then
echo -e "\e[32mServer at $server_ip is up.\e[0m" # Green color for UP
else
echo -e "\e[31mServer at $server_ip is down.\e[0m" # Red color for DOWN
fi
done
done
read -n 1 -s -r -p "Press any key to continue"
echo
}
proxy_protocol() {
clear
config_file="/etc/haproxy/haproxy.cfg"
if ! grep -qE '^\s*server ' "$config_file"; then
echo "Atleast one ip address is required in configuration file"
else
if grep -qE '^\s*server .* check send-proxy-v2$' "$config_file"; then
echo -e "\e[32mProxy Protocol is Enabled.\e[0m" # Green color for Enabled
read -p "Do you want to Disable it? (y/n): " pp
# Convert input to lowercase
pp_lowercase=$(echo "$pp" | tr '[:upper:]' '[:lower:]')
# Check if the input is "y"
if [ "$pp_lowercase" = "y" ]; then
# Tasks to be performed if input is "y"
sed -i 's/send-proxy-v2//g' "$config_file"
systemctl restart haproxy
echo "Disabled Successfuly"
read -n 1 -s -r -p "Press any key to continue"
echo
fi
else
echo -e "\e[33mProxy Protocol is Disabled.\e[0m"
read -p "Do you want to Enable it? (y/n): " pp
# Convert input to lowercase
pp_lowercase=$(echo "$pp" | tr '[:upper:]' '[:lower:]')
# Check if the input is "y"
if [ "$pp_lowercase" = "y" ]; then
# Tasks to be performed if input is "y"
sed -i 's/\(server.*check\)/\1 send-proxy-v2/g' "$config_file"
systemctl restart haproxy
echo "Enabled Successfuly"
read -n 1 -s -r -p "Press any key to continue"
echo
fi
fi
fi
}
create_backup() {
config_file="/etc/haproxy/haproxy.cfg"
backup_file="/etc/haproxy/haproxy.cfg.back"
clear
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.back
echo -e "\e[32mBackup Successfuly created\e[0m"
read -n 1 -s -r -p "Press any key to continue"
echo
}
restore_backup() {
config_file="/etc/haproxy/haproxy.cfg"
backup_file="/etc/haproxy/haproxy.cfg.back"
clear
cp /etc/haproxy/haproxy.cfg.back /etc/haproxy/haproxy.cfg
systemctl restart haproxy
echo -e "\e[32mBackup Successfuly Restored\e[0m"
read -n 1 -s -r -p "Press any key to continue"
echo
}
Reset_Config() {
clear
# Download the haproxy.cfg from GitHub and overwrite the original file
wget -O /etc/haproxy/haproxy.cfg https://raw.githubusercontent.com/Argo160/HaProxy_LoadBalancer/main/haproxy.cfg
echo -e "\e[32mThe Setting Restored to default\e[0m"
echo "You need to specify ports and ip addresses"
read -n 1 -s -r -p "Press any key to continue"
echo
}
balance_algo() {
clear
config_file="/etc/haproxy/haproxy.cfg"
backend_names=$(awk '/^\s*backend\s+/{print $2}' "$config_file")
# Function to extract the balance algorithm for a given backend
get_balance_algorithm() {
local backend_name="$1"
grep -A 2 -E "backend $backend_name$" "$config_file" | grep -oE "balance\s+\w+" | awk '{print $2}'
}
# Function to check if the balance algorithm is roundrobin
is_roundrobin() {
local algorithm="$1"
[[ "$algorithm" == "roundrobin" ]]
}
# Function to check if the balance algorithm is leastconn
is_leastconn() {
local algorithm="$1"
[[ "$algorithm" == "leastconn" ]]
}
# Main script
first_backend=$(grep -m 1 -E "^backend " "$config_file" | awk '{print $2}')
balance_algorithm=$(get_balance_algorithm "$first_backend")
if is_roundrobin "$balance_algorithm"; then
echo -e "\e[32mCurrent Balance Algorithm is: ROUNDROBIN\e[0m"
read -p "Do you want to change it to Leastconn? (y/n): " pp
# Convert input to lowercase
pp_lowercase=$(echo "$pp" | tr '[:upper:]' '[:lower:]')
# Check if the input is "y"
if [ "$pp_lowercase" = "y" ]; then
# Tasks to be performed if input is "y"
for backend_name in $backend_names; do
sed -i "/^backend $backend_name$/,/^$/ s/^ balance .*/ balance leastconn/" "$config_file"
done
systemctl restart haproxy
echo -e "\e[32mChanged successfuly\e[0m"
read -n 1 -s -r -p "Press any key to continue"
echo
fi
elif is_leastconn "$balance_algorithm"; then
echo -e "\e[32mCurrent Balance Algorithm is: LEASTCONN\e[0m"
read -p "Do you want to change it to Roundrobin? (y/n): " pp
# Convert input to lowercase
pp_lowercase=$(echo "$pp" | tr '[:upper:]' '[:lower:]')
# Check if the input is "y"
if [ "$pp_lowercase" = "y" ]; then
for backend_name in $backend_names; do
sed -i "/^backend $backend_name$/,/^$/ s/^ balance .*/ balance roundrobin/" "$config_file"
done
systemctl restart haproxy
echo -e "\e[32mChanged successfuly\e[0m"
read -n 1 -s -r -p "Press any key to continue"
echo
fi
else
echo "No Balance Algorithm Found"
fi
}
# Main menu
while true; do
clear
echo "Menu:"
echo "1 - Install HAProxy"
echo "2 - IP & Port Management"
echo "3 - Health Check"
echo "4 - Proxy Protocol"
echo "5 - Balance Algorithm"
echo "6 - Backup"
echo "7 - Reset Config"
echo "8 - Uninstall"
echo "0 - Exit"
read -p "Enter your choice: " choice
case $choice in
1) install_haproxy;;
2) # IP Management menu
while true; do
clear
echo " IP Management Menu:"
echo " 1 - Add IP"
echo " 2 - Remove IP"
echo " 3 - Add Port"
echo " 4 - Remove Port"
echo " 9 - Back to Main Menu"
read -p "Enter your choice: " ip_choice
case $ip_choice in
1) add_ip;;
2) remove_ip;;
3) add_port;;
4) remove_port;;
9) break;; # Return to the main menu
*) echo "Invalid choice. Please enter a valid option.";;
esac
done;;
3) health_check;;
4) proxy_protocol;;
5) balance_algo;;
6) # Backup
while true; do
clear
echo " Backup Management Menu:"
echo " 1 - Create Backup"
echo " 2 - Restore Backup"
echo " 9 - Back to Main Menu"
read -p "Enter your choice: " backup_choice
case $backup_choice in
1) create_backup;;
2) restore_backup;;
9) break;;
*) echo "Invalid choice. Please enter a valid option.";;
esac
done;;
7) Reset_Config;;
8) uninstall_haproxy;;
0) echo "Exiting..."; exit;;
*) echo "Invalid choice. Please enter a valid option.";;
esac
done