Last active
August 29, 2015 14:12
-
-
Save pozgo/b05bd578ef51b55469f6 to your computer and use it in GitHub Desktop.
haproxy-marathon-bridge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -o errexit -o nounset -o pipefail | |
function -h { | |
cat <<USAGE | |
USAGE: $name <marathon host:port>+ | |
$name install_haproxy_system <marathon host:port>+ | |
Generates a new configuration file for HAProxy from the specified Marathon | |
servers, replaces the file in /etc/haproxy and restarts the service. | |
In the second form, installs the script itself, HAProxy and a cronjob that | |
once a minute pings one of the Marathon servers specified and refreshes | |
HAProxy if anything has changed. The list of Marathons to ping is stored, | |
one per line, in: | |
$cronjob_conf_file | |
The script is installed as: | |
$script_path | |
The cronjob is installed as: | |
$cronjob | |
and run as root. | |
USAGE | |
}; function --help { -h ;} | |
export LC_ALL=en_US.UTF-8 | |
name=haproxy-marathon-bridge | |
cronjob_conf_file=/etc/"$name"/marathons | |
cronjob=/etc/cron.d/"$name" | |
script_path=/usr/local/bin/"$name" | |
conf_file=haproxy.cfg | |
function main { | |
config "$@" | |
} | |
function refresh_system_haproxy { | |
config "$@" > /tmp/"$conf_file" | |
if ! diff -q /tmp/"$conf_file" /etc/haproxy/"$conf_file" >&2 | |
then | |
msg "Found changes. Sending reload request to HAProxy..." | |
cat /tmp/"$conf_file" > /etc/haproxy/"$conf_file" | |
if [[ -f /etc/init/haproxy.conf ]] | |
then reload haproxy ## Upstart | |
elif [[ -f /usr/lib/systemd/system/haproxy.service ]] | |
then systemctl reload haproxy ## systemd | |
else /etc/init.d/haproxy reload | |
fi | |
fi | |
} | |
function install_haproxy_system { | |
os=$(lsb_release -si) | |
if [[ $os == "CentOS" ]] || [[ $os == "RHEL" ]] | |
then | |
yum install -y haproxy | |
chkconfig haproxy on | |
elif [[ $os == "Ubuntu" ]] || [[ $os == "Debian" ]] | |
then | |
env DEBIAN_FRONTEND=noninteractive aptitude install -y haproxy | |
sed -i 's/^ENABLED=0/ENABLED=1/' /etc/default/haproxy | |
else | |
echo "$os is not a supported OS for this feature." | |
exit 1 | |
fi | |
install_cronjob "$@" | |
} | |
function install_cronjob { | |
mkdir -p "$(dirname "$cronjob_conf_file")" | |
[[ -f $cronjob_conf_file ]] || touch "$cronjob_conf_file" | |
if [[ $# -gt 0 ]] | |
then printf '%s\n' "$@" | dd of="$cronjob_conf_file" | |
fi | |
cat "$0" | dd of="$script_path" | |
chmod ug+rx "$script_path" | |
cronjob | dd of="$cronjob" | |
header | dd of=/etc/haproxy/"$conf_file" | |
} | |
function cronjob { | |
cat <<EOF | |
* * * * * root $script_path logged refresh_system_haproxy \$(cat $cronjob_conf_file) | |
EOF | |
} | |
function config { | |
header | |
apps "$@" | |
} | |
function header { | |
cat <<\EOF | |
global | |
log 127.0.0.1 local0 | |
log 127.0.0.1 local1 notice | |
maxconn 4096 | |
defaults | |
log global | |
retries 3 | |
maxconn 2000 | |
timeout connect 5000 | |
timeout client 50000 | |
timeout server 50000 | |
listen stats | |
bind 0.0.0.0:80 | |
balance | |
mode http | |
stats enable | |
stats hide-version | |
stats refresh 30s | |
stats realm Strictly\ Private | |
stats auth admin:admin | |
stats uri / | |
EOF | |
} | |
function apps { | |
(until curl -sSfLk -m 10 -H 'Accept: text/plain' "${1%/}"/v2/tasks; do [ $# -lt 2 ] && return 1 || shift; done) | while read -r txt | |
do | |
set -- $txt | |
local app_name="$1" | |
local app_port="$2" | |
shift 2 | |
if [ "${app_port//[0-9]*}" = "" ] | |
then | |
cat <<EOF | |
frontend $app_name-$app_port | |
bind 0.0.0.0:$app_port | |
default_backend $app_name-$app_port | |
backend $app_name-$app_port | |
mode tcp | |
balance roundrobin | |
EOF | |
while [[ $# -ne 0 ]] | |
do | |
out " server ${app_name}-$# $1 check" | |
shift | |
done | |
fi | |
done | |
} | |
function logged { | |
exec 1> >(logger -p user.info -t "$name[$$]") | |
exec 2> >(logger -p user.notice -t "$name[$$]") | |
"$@" | |
} | |
function msg { out "$*" >&2 ;} | |
function err { local x=$? ; msg "$*" ; return $(( $x == 0 ? 1 : $x )) ;} | |
function out { printf '%s\n' "$*" ;} | |
# If less than 1 argument is provided, print usage and exit. At least one | |
# argument is required as described in the `USAGE` message. | |
[ $# -lt 1 ] && { -h; exit 1; } | |
if [[ ${1:-} ]] && declare -F | cut -d' ' -f3 | fgrep -qx -- "${1:-}" | |
then "$@" | |
else main "$@" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment