Skip to content

Instantly share code, notes, and snippets.

@tomwalsh
Forked from therobot/elastic-ip
Last active August 29, 2015 14:26
Show Gist options
  • Save tomwalsh/bc36fe8f819a51d8d8b2 to your computer and use it in GitHub Desktop.
Save tomwalsh/bc36fe8f819a51d8d8b2 to your computer and use it in GitHub Desktop.
Elastic IP corosync resource agent
#!/bin/bash
###############################################################################
# CONFIG
# AWS config
# OCF Parameters:
# OCF_RESKEY_aws_secret_key - The AWS secret key for the account with the elastic IP address.
# OCF_RESKEY_aws_access_key - The AWS access key for the account with the elastic IP address.
# OCF_RESKEY_java_home - The base directory for the Java JRE Default: /usr/lib/jvm/java-7-openjdk-amd64/
# OCF_RESKEY_ec2_url - The API endpoint for the AWS calls. Default: https://us-east-1.ec2.amazon.com/
# OCF_RESKEY_aws_instance_id - The current AWS instance ID.
# OCF_RESKEY_elastic_ip - The Elastic IP address that we are monitoring as a resource
###############################################################################
###############################################################################
# For testing purposes delete OCF_ROOT after testing
OCF_ROOT=/usr/lib/ocf/
#
# INIT
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
if [ -f ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs ]; then
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
fi
OCF_RESKEY_aws_secret_key_default=""
OCF_RESKEY_aws_access_key_default=""
OCF_RESKEY_java_home_default="/usr/lib/jvm/java-7-openjdk-amd64/"
OCF_RESKEY_ec2_url_default="https://us-east-1.ec2.amazonaws.com"
OCF_RESKEY_aws_instance_id_default="$(ec2metadata --instance-id)"
OCF_RESKEY_elastic_ip_default=""
: ${OCF_RESKEY_aws_secret_key=${OCF_RESKEY_aws_secret_key_default}}
: ${OCF_RESKEY_aws_access_key=${OCF_RESKEY_aws_access_key_default}}
: ${OCF_RESKEY_java_home=${OCF_RESKEY_java_home_default}}
: ${OCF_RESKEY_ec2_url=${OCF_RESKEY_ec2_url_default}}
: ${OCF_RESKEY_aws_instance_id=${OCF_RESKEY_aws_instance_id_default}}
: ${OCF_RESKEY_elastic_ip=${OCF_RESKEY_elastic_ip_default}}
export AWS_SECRET_KEY="${OCF_RESKEY_aws_secret_key}"
export AWS_ACCESS_KEY="${OCF_RESKEY_aws_access_key}"
export JAVA_HOME="${OCF_RESKEY_java_home}"
export EC2_URL="${OCF_RESKEY_ec2_url}"
export AWS_INSTANCE_ID="${OCF_RESKEY_aws_instance_id}"
export ELASTIC_IP="${OCF_RESKEY_elastic_ip}"
USAGE="usage: $0 {start|stop|status|meta-data}";
###############################################################################
meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="ElasticIP">
<version>2.0</version>
<longdesc lang="en">
This script manages Amazon EC2 Elastic IP addresses.
</longdesc>
<shortdesc lang="en">Manages Amazon EC2 Elastic IP addresses</shortdesc>
<parameters>
<parameter name="aws_secret_key" unique="0" required="1">
<longdesc lang="en">
This is the secret key for your AWS account. This is used
to access your AWS account to check on the ElasticIP and
perform resource operations on the ElasticIP.
</longdesc>
<shortdesc>The AWS secret key</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="aws_access_key" unique="0" required="1">
<longdesc lang="en">
This is the access key for your AWS account. This is used
to access your AWS account to check on the ElasticIP and
perform resource operations on the ElasticIP.
</longdesc>
<shortdesc>The AWS access key</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="java_home" unique="1">
<longdesc lang="en">
This is the path to the Java JRE.
</longdesc>
<shortdesc>This is the path to the Java JRE.</shortdesc>
<content type="string" default="/usr/lib/jvm/java-7-openjdk-amd64/" />
</parameter>
<parameter name="ec2_url" unique="0">
<longdesc lang="en">
This is the URL that we use to access the AWS API. This must be pointed
at your region.
</longdesc>
<shortdesc>URL that is used to access the AWS API</shortdesc>
<content type="string" default="https://eu-east-1.ec2.amazonaws.com" />
</parameter>
<parameter name="aws_instance_id" unique="1">
<longdesc lang="en">
This is the AWS instance ID. This must be set for each node in your
AWS cluster.
</longdesc>
<shortdesc>AWS instance ID</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="elastic_ip" unique="0" required="1">
<longdesc lang="en">
This is the Elastic IP address that is monitored and
moved around in the AWS cluster.
</longdesc>
<shortdesc>Elastic IP address</shortdesc>
<content type="string" default="" />
</parameter>
</parameters>
<actions>
<action name="start" timeout="20s" />
<action name="stop" timeout="20s" />
<action name="monitor" timeout="20s" />
<action name="meta-data" timeout="5s" />
</actions>
</resource-agent>
END
}
ip_already_associated() {
if [ `ec2-describe-addresses | grep "$ELASTIC_IP" | awk '{print $3}'` = "$AWS_INSTANCE_ID" ]; then
ocf_log info "Elastic IP address already associated to the node"
return $OCF_SUCCESS
else
ocf_log err "Elastic IP address not associated to the node"
return $OCF_ERR_GENERIC
fi
}
ip_start() {
ip_validate_all || exit $?
if ip_monitor; then
ocf_log info "Resource is already running"
return $OCF_SUCCESS
fi
ec2-associate-address "$ELASTIC_IP" -i "$AWS_INSTANCE_ID" > /dev/null
if [ $? -eq 1 ]; then
ocf_log info "An error occurred when starting the resource"
return $OCF_ERR_GENERIC
fi
while ! ip_monitor; do
ocf_log debug "Resource has not started yet, waiting"
sleep 1
done
ocf_log info "Elastic IP sucessfully associated with the node"
return $OCF_SUCCESS
}
ip_stop() {
ip_validate_all || exit $?
if ip_monitor; then
ocf_log debug "Resource is currently running"
else
ocf_log info "Resource is already stopped"
return $OCF_SUCCESS
fi
ec2-disassociate-address "$ELASTIC_IP" > /dev/null
if [ $? -eq 0 ]; then
while ip_monitor; do
ocf_log debug "Resource has not stopped yet, waiting"
sleep 1
done
ocf_log info "Resource is stopped"
else
ocf_log info "An error occurred when stopping the resource"
exit $OCF_ERR_GENERIC
fi
return $OCF_SUCCESS
}
# FIRST approach to monitoring
ip_monitor() {
ip_validate_all || exit $?
if ip_already_associated; then
ping -c 1 $ELASTIC_IP > /dev/null
if [ $? -eq 0 ]; then
ocf_log info "Elastic IP responding to ping test, resource test sucessful"
return $OCF_SUCCESS
else
ocf_log err "Elastic IP not responding to ping test, resource test failed"
return $OCF_ERR_GENERIC
fi
else
ocf_log debug "Resource not running"
return $OCF_NOT_RUNNING
fi
return $OCF_SUCCESS
}
ip_validate_all() {
which ec2-describe-addresses > /dev/null
if [ $? -eq 1 ]; then
ocf_log info "AWS command line tools unavailable"
return $OCF_ERR_INSTALLED
elif [ -z "$AWS_SECRET_KEY" ]; then
ocf_log info "AWS_SECRET_KEY env variable not set"
return $OCF_ERR_CONFIGURED
elif [ -z "$AWS_ACCESS_KEY" ]; then
ocf_log info "AWS_ACCESS_KEY env variable not set"
return $OCF_ERR_CONFIGURED
elif [ -z "$JAVA_HOME" ]; then
ocf_log info "JAVA_HOME env variable not set"
return $OCF_ERR_CONFIGURED
elif [ -z "$EC2_URL" ]; then
ocf_log info "EC2_URL env variable not set"
return $OCF_ERR_CONFIGURED
elif [ -z "$AWS_INSTANCE_ID" ]; then
ocf_log info "AWS_INSTANCE_ID env variable not set"
return $OCF_ERR_CONFIGURED
elif [ -z $ELASTIC_IP ]; then
ocf_log info "ELASTIC_IP env variable not set"
return $OCF_ERR_CONFIGURED
fi
return $OCF_SUCCESS
}
usage() {
echo $USAGE >&2
return $1
}
if [ $# -ne 1 ]; then
usage $OCF_ERR_ARGS
fi
case $1 in
meta-data) meta_data;;
start) ip_start;;
stop) ip_stop;;
status) ip_monitor;; # Status is deprecated, monitor replaces it.
monitor) ip_monitor;;
validate-all) ip_validate_all;;
usage) usage $OCF_SUCCESS;;
*) usage $OCF_ERR_UNIMPLEMENTED;;
esac
exit $?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment