Skip to content

Instantly share code, notes, and snippets.

@pgporada
Last active May 2, 2018 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pgporada/116c7d792150d11ee4b269a3632a705d to your computer and use it in GitHub Desktop.
Save pgporada/116c7d792150d11ee4b269a3632a705d to your computer and use it in GitHub Desktop.
Packet.net Elastic IP Failover Script
#!/bin/bash
function usage() {
echo "USAGE: ./$(basename ${0})"
echo
}
# if ((${EUID:-0} || "$(id -u)")); then
# usage
# exit 1
# fi
PACKET_ELASTIC_IP="1.1.1.1" # Script assumes a /32 cidr
PACKET_KEY="XYZaintNeverGonnaFindMe123"
PACKET_ORG="My Organization"
PACKET_DC="ord1"
HOSTAME_IDENTIFIER="-loadbalancer-"
PACKET_ORG_ID=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/organizations | jq -r ".organizations[].id")
PACKET_PROJECT_ID=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/organizations/${PACKET_ORG_ID}/projects | jq -r ".projects[] | select(\".name == ${PACKET_ORG}\") | .id")
function detach() {
# Get fresh data
local TEMP_DATA=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/projects/${PACKET_PROJECT_ID}/ips?ipv4=true&public=true&facility=${PACKET_DC}&include=assignments,assignments.assigned_to)
local EIP_ID=$(echo "${TEMP_DATA}" | jq -r ".ip_addresses[] | select(.address == \"${PACKET_ELASTIC_IP}\") | .id")
local AVAILABILITY=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/ips/${EIP_ID}/available?cidr=32 | jq -r ".available[] | contains(\"${PACKET_ELASTIC_IP}\")" > /dev/null 2>&1)
local NODE_DATA=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/projects/${PACKET_PROJECT_ID}/devices?per_page=100)
local LOADBALANCER_NODES=( $(echo "${NODE_DATA}" | jq -r ".devices[] | select(.hostname | contains(\"${HOSTNAME_IDENTIFIER}\")) | .hostname") )
if [ "${AVAILABILITY}" == "true" ]; then
echo "$(date) EIP ${PACKET_ELASTIC_IP} is not assigned to any nodes and therefor cannot be detached."
else
# Search for the node with the EIP attached
for i in ${LOADBALANCER_NODES[@]}; do
local NODE_ID=$(echo "${NODE_DATA}" | jq -r ".devices[] | select(.hostname == \"${i}\") | .id")
local EIP_ID=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" --data '' https://api.packet.net/devices/${NODE_ID}/ips?address=${PACKET_ELASTIC_IP}/32 | jq -r ".ip_addresses[] | select(.address == \"${PACKET_ELASTIC_IP}\") | .id")
if [ ! -z ${EIP_ID} ]; then
echo "$(date) Detaching EIP ${EIP_ID} from node ${i} with node ID of ${NODE_ID}"
export BAD_NODE_ID=${NODE_ID}
curl -sL -X DELETE --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/ips/${EIP_ID}
break
fi
done
fi
}
function attach() {
# Get fresh data
local TEMP_DATA=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/projects/${PACKET_PROJECT_ID}/ips?ipv4=true&public=true&facility=${PACKET_DC}&include=assignments,assignments.assigned_to)
local EIP_ID=$(echo "${TEMP_DATA}" | jq -r ".ip_addresses[] | select(.address == \"${PACKET_ELASTIC_IP}\") | .id")
local AVAILABILITY=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/ips/${EIP_ID}/available?cidr=32 | jq -r ".available[] | contains(\"${PACKET_ELASTIC_IP}\")")
local NODE_DATA=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/projects/${PACKET_PROJECT_ID}/devices?per_page=100)
local LOADBALANCER_NODES=( $(echo "${NODE_DATA}" | jq -r ".devices[] | select(.hostname | contains(\"${HOSTNAME_IDENTIFIER}\")) | .hostname") )
if [ "${AVAILABILITY}" == "true" ]; then
for i in ${LOADBALANCER_NODES[@]}; do
local NODE_ID=$(echo "${NODE_DATA}" | jq -r ".devices[] | select(.hostname == \"${i}\") | .id")
if [ "${NODE_ID}" != "${BAD_NODE_ID}" ]; then
# An error looks like: {"errors":["Not found"]}
echo "$(date) Attaching EIP ${EIP_ID} to node ${i} with node ID of ${NODE_ID}"
curl -sL -X POST --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" --data '' https://api.packet.net/devices/${NODE_ID}/ips?address=${PACKET_ELASTIC_IP}/32 > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$(date) Something is broken in the attachment step"
fi
fi
done
else
echo "$(date) EIP is not available. This is a problem and shouldn't happen."
fi
}
function get_status() {
# Get fresh data
local NODE_DATA=$(curl -sL -X GET --header 'Accept: application/json' --header "X-Auth-Token: ${PACKET_KEY}" https://api.packet.net/projects/${PACKET_PROJECT_ID}/devices?per_page=100)
local LOADBALANCER_NODES=( $(echo "${NODE_DATA}" | jq -r ".devices[] | select(.hostname | contains(\"${HOSTNAME_IDENTIFIER}\")) | .hostname") )
# Determine node that EIP is attached to
local ATTACHED_NODE_HOSTNAME=$(echo "${NODE_DATA}" | jq -r ".devices[] | .hostname + \" \" + (.ip_addresses[] | select(.address == \"${PACKET_ELASTIC_IP}\") | .id)" | awk '{print $1}')
local ATTACHED_NODE_ID=$(echo "${NODE_DATA}" | jq -r ".devices[] | select(.hostname == \"${ATTACHED_NODE_HOSTNAME}\") | .id")
for i in ${LOADBALANCER_NODES[@]}; do
if [ "${i}" != "${ATTACHED_NODE_HOSTNAME}" ]; then
UNATTACHED_NODE_HOSTNAME=${i}
UNATTACHED_NODE_ID=$(echo "${NODE_DATA}" | jq -r ".devices[] | select(.hostname == \"${UNATTACHED_NODE_HOSTNAME}\") | .id")
fi
done
if [ "${#LOADBALANCER_NODES[@]}" -gt 1 ]; then
echo "$(date) Node hostname with EIP: ${ATTACHED_NODE_HOSTNAME}"
echo "$(date) Node hostname without EIP: ${UNATTACHED_NODE_HOSTNAME}"
echo "$(date) Node ID with EIP: ${ATTACHED_NODE_ID}"
echo "$(date) Node ID without EIP: ${UNATTACHED_NODE_ID}"
else
echo "$(date) Node hostname with EIP: ${ATTACHED_NODE_HOSTNAME}"
echo "$(date) Node ID with EIP: ${ATTACHED_NODE_ID}"
fi
}
detach
attach
get_status
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment