Skip to content
This repository has been archived by the owner on Jul 10, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' of github.com:monobilisim/mono.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
LobbyLobster committed Jun 12, 2024
2 parents 0b40f49 + 1bc13b5 commit a205a23
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 33 deletions.
51 changes: 40 additions & 11 deletions .bin/caddy-lb-policy-switch.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,38 @@
# Caddy LB-Policy Switcher configuration
#

# Send alarm
SEND_ALARM=1

# Send bot alarm
SEND_BOT_ALARM=0


#
# Alarm Bot configuration
#
ALARM_BOT_API_URL=https://example.com
[email protected]
ALARM_BOT_API_KEY=testkey
ALARM_BOT_USER_EMAILS=("[email protected]")

#
# Alarm Webhook URL
# Format: url
# Example: "https://zulip.example.com/api/v1/external/slack_incoming?api_key=example"
ALARM_WEBHOOK_URL=""

# Alarm Webhook URLs
# Format: "url"
# Example: "https://zulip.example.com/api/v1/external/slack_incoming?api_key=example"
ALARM_WEBHOOK_URLS=()

# Caddy API URLs
# Format: "username:password@host:port"
# Example: "testusername:testpassword@localhost:2019"
# Format: "username:password@host:port;identifier"
# Example: "testusername:testpassword@localhost:2019;identifier"
CADDY_API_URLS=(
"testusername:testpassword@localhost:2019"
"testusername:testpassword@localhost:2019"
"testusername:testpassword@localhost:2019;identifier1"
"testusername:testpassword@localhost:2019;identifier2"
)

# Caddy server/vHost names
Expand Down Expand Up @@ -36,18 +61,22 @@ CADDY_LB_URLS=(
"whoami.test2.com"
)

# Threshold to exit after a certain number of no changes.
NO_CHANGES_EXIT_THRESHOLD=1

# Override config even if it is the same
SERVER_OVERRIDE_CONFIG=1
SERVER_OVERRIDE_CONFIG=0


# Threshold to exit after a certain number of no changes.
# Only matters if SERVER_OVERRIDE_CONFIG is set to 0
# Default: 3
SERVER_NOCHANGE_EXIT_THRESHOLD=1

# Loop order
# SERVERS: Prioritize servers
# API_URLS: Prioritize API URLs
# Default: "API_URLS"
LOOP_ORDER="API_URLS"

# Disables dynamic API URLs
# If set to 1, the script will not use the CADDY_LB_URLS to adjust the priority of the CADDY_API_URLS
NO_DYNAMIC_API_URLS=0
# Enable/Disable dynamic API URLs
# If set to 0, the script will not use the CADDY_LB_URLS to adjust the priority of the CADDY_API_URLS
# Default: 1
DYNAMIC_API_URLS=0
83 changes: 61 additions & 22 deletions caddy/caddy-lb-policy-switch.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
###~ description: Switch the load balancing policy of a Caddy server
start=`date +%s`

if [[ "$1" == "--version" ]] || [[ "$1" == "-v" ]]; then
echo "v0.4.0"
Expand All @@ -18,6 +19,25 @@ function verbose() {
fi
}

function verbose_alarm() {
if [[ "$VERBOSE" -eq 1 ]]; then
echo "$1"
alarm "$1"
fi
}

function remove_password() {
CENSORED_CADDY_API_URLS=()
local url=("$@")

for i in "${url[@]}"; do

CENSORED_CADDY_API_URLS+=("${i#*;}")
done

export CENSORED_CADDY_API_URLS
}

function hostname_to_url() {
local hostname="$1"

Expand Down Expand Up @@ -64,12 +84,15 @@ function alarm() {


function identify_request() {
debug "Checking $URL"

read IDENTIFIER < <(awk -F '[@;]' '{print $2}' <<< "$URL")
read ACTUAL_URL < <(awk -F '[@;]' '{print $1}' <<< "$URL")

debug "Checking $ACTUAL_URL for $IDENTIFIER"
debug "Username-Password: $USERNAME_PASSWORD"


# Not to be confused with CADDY_SERVERS
SERVERS="$(curl -s -u "$USERNAME_PASSWORD" "$URL"/config/apps/http/servers | jq -r 'keys | join(" ")')"
SERVERS="$(curl -s -u "$USERNAME_PASSWORD" "$ACTUAL_URL"/config/apps/http/servers | jq -r 'keys | join(" ")')"

debug "Servers: $SERVERS"

Expand All @@ -78,19 +101,19 @@ function identify_request() {
debug "checking server: $SERVER"

# Identify the routes
LENGTH="$(curl -s -u "$USERNAME_PASSWORD" "$URL"/config/apps/http/servers/"${SERVER:?}"/routes | jq length)"
LENGTH="$(curl -s -u "$USERNAME_PASSWORD" "$ACTUAL_URL"/config/apps/http/servers/"${SERVER:?}"/routes | jq length)"

debug "Routes: $LENGTH"

for route in $(seq 0 $((LENGTH-1))); do
REQ_URL="$URL/config/apps/http/servers/${SERVER:?}/routes/$route"
REQ_URL="$ACTUAL_URL/config/apps/http/servers/${SERVER:?}/routes/$route"
REQ="$(curl -u "$USERNAME_PASSWORD" -s "$REQ_URL")"
export REQ
export REQ_URL

if (echo "$REQ" | jq -r '.match[].host | join(" ")' 2> /dev/null | grep -qw "$URL_TO_FIND"); then
echo "Match found, route: $route, server: $SERVER"
change_upstreams "$1" "$2"
change_upstreams "$1" "$2" "$IDENTIFIER"
fi
done
done
Expand All @@ -99,11 +122,15 @@ function identify_request() {
function change_upstreams() {
echo "Changing upstreams"

if [[ "$NO_CHANGES_COUNTER" -ge "${NO_CHANGES_EXIT_THRESHOLD:-3}" ]]; then
echo "No changes needed for $NO_CHANGES_EXIT_THRESHOLD times, exiting"
if [[ "$NO_CHANGES_COUNTER" -ge "${SERVER_NOCHANGE_EXIT_THRESHOLD:-3}" ]]; then
echo "No changes needed for $SERVER_NOCHANGE_EXIT_THRESHOLD times, exiting"
exit 0
fi

if [[ -z "$IDENTIFIER" ]]; then
IDENTIFIER="$URL"
fi

case $1 in
first)
REQ_TO_SEND="$(echo "$REQ" | jq --arg SRVNAME "$2" -cMr '
Expand All @@ -130,16 +157,16 @@ function change_upstreams() {
NO_CHANGES_COUNTER=$((NO_CHANGES_COUNTER+1))
export NO_CHANGES_COUNTER
if [[ "$VERBOSE" -eq 1 ]]; then
alarm "[Caddy lb-policy Switch] [$URL] [$URL_TO_FIND] [:check:] No changes needed as the upstreams are already in the first_$2 order"
alarm "[Caddy lb-policy Switch] [$IDENTIFIER] [$URL_TO_FIND] [:check:] No changes needed as the upstreams are already in the first_$2 order"
fi
return
else
echo "Sending request to change upstreams"

if curl -u "$USERNAME_PASSWORD" -X PATCH -H "Content-Type: application/json" -d "$REQ_TO_SEND" "$REQ_URL" 2> /tmp/caddy-lb-policy-switch-error.log; then
alarm "[Caddy lb-policy Switch] [$URL] [$URL_TO_FIND] [:check:] Switched upstreams to first_$2"
alarm "[Caddy lb-policy Switch] [$IDENTIFIER] [$URL_TO_FIND] [:check:] Switched upstreams to first_$2"
else
alarm "[Caddy lb-policy Switch] [$URL] [$URL_TO_FIND] [:red_circle:] Failed to switch upstreams to first_$2\nError log: \`\`\`\n$(cat /tmp/caddy-lb-policy-switch-error.log)\n\`\`\`"
alarm "[Caddy lb-policy Switch] [$IDENTIFIER] [$URL_TO_FIND] [:red_circle:] Failed to switch upstreams to first_$2\nError log: \`\`\`\n$(cat /tmp/caddy-lb-policy-switch-error.log)\n\`\`\`"
fi

fi
Expand All @@ -162,15 +189,15 @@ function change_upstreams() {
NO_CHANGES_COUNTER=$((NO_CHANGES_COUNTER+1))
export NO_CHANGES_COUNTER
if [[ "$VERBOSE" -eq 1 ]]; then
alarm "[Caddy lb-policy Switch] [$URL] [$URL_TO_FIND] [:check:] No changes needed as the upstreams are already in the $1 order"
alarm "[Caddy lb-policy Switch] [$IDENTIFIER] [$URL_TO_FIND] [:check:] No changes needed as the upstreams are already in the $1 order"
fi
return
else
echo "Sending request to change lb_policy to $1"
if curl -u "$USERNAME_PASSWORD" -X PATCH -H "Content-Type: application/json" -d "$REQ_TO_SEND" "$REQ_URL" 2> /tmp/caddy-lb-policy-switch-error.log; then
alarm "[Caddy lb-policy Switch] [$URL] [$URL_TO_FIND] [:check:] Switched lb_policy to $1"
alarm "[Caddy lb-policy Switch] [$IDENTIFIER] [$URL_TO_FIND] [:check:] Switched lb_policy to $1"
else
alarm "[Caddy lb-policy Switch] [$URL] [$URL_TO_FIND] [:red_circle:] Failed to switch lb_policy to $1\nError log: \`\`\`\n$(cat /tmp/caddy-lb-policy-switch-error.log)\n\`\`\`"
alarm "[Caddy lb-policy Switch] [$IDENTIFIER] [$URL_TO_FIND] [:red_circle:] Failed to switch lb_policy to $1\nError log: \`\`\`\n$(cat /tmp/caddy-lb-policy-switch-error.log)\n\`\`\`"
fi
fi
;;
Expand All @@ -187,15 +214,18 @@ function adjust_api_urls() {
for i in "${CADDY_LB_URLS[@]}"; do
for URL_UP in "${CADDY_API_URLS[@]}"; do

if [[ "${#CADDY_API_URLS_NEW[@]}" -eq $((${#CADDY_LB_URLS[@]} - 1)) ]]; then
break
fi

URL="${URL_UP#*@}"
USERNAME_PASSWORD="${URL_UP%%@*}"

verbose "LB $i"
debug "LB $i"
url_new="$(hostname_to_url "$(curl -s "$i" | grep "Hostname:" | awk '{print $2}')")"
if [[ "$url_new" == "$URL" ]]; then
debug "$url_new is the same as URL, adding to CADDY_API_URLS_NEW"
CADDY_API_URLS_NEW+=("$URL_UP") # Make sure the ones that respond first are added first
verbose "CADDY_API_URLS_NEW: ${CADDY_API_URLS_NEW[*]}"
fi
done

Expand All @@ -205,8 +235,8 @@ function adjust_api_urls() {
CADDY_API_URLS_NEW+=("$URL_UP")
done

mapfile -t CADDY_API_URLS < <(printf "%s\n" "${CADDY_API_URLS_NEW[@]}" | sort -u)
export CADDY_API_URLS
readarray -t CADDY_API_URLS_NEW < <(printf '%s\n' "${CADDY_API_URLS_NEW[@]}" | sort -u)
export CADDY_API_URLS_NEW

}

Expand Down Expand Up @@ -236,10 +266,15 @@ for conf in /etc/glb/*.conf; do
exit 1
fi

if [[ "$NO_DYNAMIC_API_URLS" -ne 1 ]]; then
debug "CADDY_API_URLS: ${CADDY_API_URLS[*]}"
if [[ "$DYNAMIC_API_URLS" -ne 0 ]]; then
remove_password "${CADDY_API_URLS[@]}"
verbose_alarm "CADDY_API_URLS: ${CENSORED_CADDY_API_URLS[*]}"

adjust_api_urls
debug "CADDY_API_URLS_NEW: ${CADDY_API_URLS_NEW[*]}"
unset CENSORED_CADDY_API_URLS

remove_password "${CADDY_API_URLS_NEW[@]}"
verbose_alarm "CADDY_API_URLS_NEW: ${CENSORED_CADDY_API_URLS[*]}"
fi

if [[ "$LOOP_ORDER" == "SERVERS" ]]; then
Expand Down Expand Up @@ -267,10 +302,14 @@ for conf in /etc/glb/*.conf; do
fi


for i in CADDY_API_URLS CADDY_API_URLS_NEW CADDY_SERVERS ALARM_BOT_USER_EMAILS ALARM_WEBHOOK_URLS ALARM_BOT_EMAIL ALARM_BOT_API_KEY ALARM_BOT_API_URL ALARM_WEBHOOK_URL SEND_ALARM SEND_DM_ALARM NO_CHANGES_EXIT_THRESHOLD CADDY_LB_URLS NO_DYNAMIC_API_URLS SERVER_OVERRIDE_CONFIG LOOP_ORDER VERBOSE DEBUG; do
for i in CADDY_API_URLS CADDY_API_URLS_NEW CADDY_SERVERS ALARM_BOT_USER_EMAILS ALARM_WEBHOOK_URLS ALARM_BOT_EMAIL ALARM_BOT_API_KEY ALARM_BOT_API_URL ALARM_WEBHOOK_URL SEND_ALARM SEND_DM_ALARM SERVER_NOCHANGE_EXIT_THRESHOLD CADDY_LB_URLS DYNAMIC_API_URLS SERVER_OVERRIDE_CONFIG LOOP_ORDER VERBOSE DEBUG CENSORED_CADDY_API_URLS; do
unset $i
done

echo "Done with $conf"
echo "---------------------------------"
done

end=`date +%s`
runtime=$((end-start))
echo "Script runtime: $runtime seconds"

0 comments on commit a205a23

Please sign in to comment.