You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

868 lines
25 KiB

diff -uNr a/doc/man/Makefile.am b/doc/man/Makefile.am
--- a/doc/man/Makefile.am 2018-02-21 13:07:56.172091057 +0100
+++ b/doc/man/Makefile.am 2018-02-21 13:05:37.589245986 +0100
@@ -99,6 +99,9 @@
ocf_heartbeat_anything.7 \
ocf_heartbeat_apache.7 \
ocf_heartbeat_asterisk.7 \
+ ocf_heartbeat_aws-vpc-move-ip.7 \
+ ocf_heartbeat_awseip.7 \
+ ocf_heartbeat_awsvip.7 \
ocf_heartbeat_clvm.7 \
ocf_heartbeat_conntrackd.7 \
ocf_heartbeat_db2.7 \
diff -uNr a/heartbeat/awseip b/heartbeat/awseip
--- a/heartbeat/awseip 1970-01-01 01:00:00.000000000 +0100
+++ b/heartbeat/awseip 2018-02-21 13:08:21.112887254 +0100
@@ -0,0 +1,278 @@
+#!/bin/sh
+#
+#
+# Manage Elastic IP with Pacemaker
+#
+#
+# Copyright 2016 guessi <guessi@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+#
+# Prerequisites:
+#
+# - preconfigured AWS CLI running environment (AccessKey, SecretAccessKey, etc.)
+# - a reserved secondary private IP address for EC2 instances high availablity
+# - IAM user role with the following permissions:
+# * DescribeInstances
+# * AssociateAddress
+# * DisassociateAddress
+#
+
+#######################################################################
+# Initialization:
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+
+#######################################################################
+
+#
+# Defaults
+#
+OCF_RESKEY_awscli_default="/usr/bin/aws"
+OCF_RESKEY_profile_default="default"
+OCF_RESKEY_api_delay_default="3"
+
+: ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}}
+: ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}}
+: ${OCF_RESKEY_api_delay=${OCF_RESKEY_api_delay_default}}
+
+meta_data() {
+ cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="awseip">
+<version>1.0</version>
+
+<longdesc lang="en">
+Resource Agent for Amazon AWS Elastic IP Addresses.
+
+It manages AWS Elastic IP Addresses with awscli.
+
+Credentials needs to be setup by running "aws configure".
+
+See https://aws.amazon.com/cli/ for more information about awscli.
+</longdesc>
+<shortdesc lang="en">Amazon AWS Elastic IP Address Resource Agent</shortdesc>
+
+<parameters>
+
+<parameter name="awscli" unique="0">
+<longdesc lang="en">
+command line tools for aws services
+</longdesc>
+<shortdesc lang="en">aws cli tools</shortdesc>
+<content type="string" default="${OCF_RESKEY_awscli_default}" />
+</parameter>
+
+<parameter name="profile">
+<longdesc lang="en">
+Valid AWS CLI profile name (see ~/.aws/config and 'aws configure')
+</longdesc>
+<shortdesc lang="en">profile name</shortdesc>
+<content type="string" default="${OCF_RESKEY_profile_default}" />
+</parameter>
+
+<parameter name="elastic_ip" unique="1" required="1">
+<longdesc lang="en">
+reserved elastic ip for ec2 instance
+</longdesc>
+<shortdesc lang="en">reserved elastic ip for ec2 instance</shortdesc>
+<content type="string" default="" />
+</parameter>
+
+<parameter name="allocation_id" unique="1" required="1">
+<longdesc lang="en">
+reserved allocation id for ec2 instance
+</longdesc>
+<shortdesc lang="en">reserved allocation id for ec2 instance</shortdesc>
+<content type="string" default="" />
+</parameter>
+
+<parameter name="private_ip_address" unique="1" required="0">
+<longdesc lang="en">
+predefined private ip address for ec2 instance
+</longdesc>
+<shortdesc lang="en">predefined private ip address for ec2 instance</shortdesc>
+<content type="string" default="" />
+</parameter>
+
+<parameter name="api_delay" unique="0">
+<longdesc lang="en">
+a short delay between API calls, to avoid sending API too quick
+</longdesc>
+<shortdesc lang="en">a short delay between API calls</shortdesc>
+<content type="integer" default="${OCF_RESKEY_api_delay_default}" />
+</parameter>
+
+</parameters>
+
+<actions>
+<action name="start" timeout="30" />
+<action name="stop" timeout="30" />
+<action name="monitor" timeout="30" interval="20" depth="0" />
+<action name="migrate_to" timeout="30" />
+<action name="migrate_from" timeout="30" />
+<action name="meta-data" timeout="5" />
+<action name="validate" timeout="10" />
+<action name="validate-all" timeout="10" />
+</actions>
+</resource-agent>
+END
+}
+
+#######################################################################
+
+awseip_usage() {
+ cat <<END
+usage: $0 {start|stop|monitor|migrate_to|migrate_from|validate|validate-all|meta-data}
+
+Expects to have a fully populated OCF RA-compliant environment set.
+END
+}
+
+awseip_start() {
+ awseip_monitor && return $OCF_SUCCESS
+
+ if [ -n "${PRIVATE_IP_ADDRESS}" ]; then
+ NETWORK_INTERFACES_MACS="$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/)"
+ for MAC in ${NETWORK_INTERFACES_MACS}; do
+ curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC}/local-ipv4s |
+ grep -q "^${PRIVATE_IP_ADDRESS}$"
+ if [ $? -eq 0 ]; then
+ NETWORK_ID="$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC}/interface-id)"
+ fi
+ done
+ $AWSCLI --profile $OCF_RESKEY_profile ec2 associate-address \
+ --network-interface-id ${NETWORK_ID} \
+ --allocation-id ${ALLOCATION_ID} \
+ --private-ip-address ${PRIVATE_IP_ADDRESS}
+ RET=$?
+ else
+ $AWSCLI --profile $OCF_RESKEY_profile ec2 associate-address \
+ --instance-id ${INSTANCE_ID} \
+ --allocation-id ${ALLOCATION_ID}
+ RET=$?
+ fi
+
+ # delay to avoid sending request too fast
+ sleep ${OCF_RESKEY_api_delay}
+
+ if [ $RET -ne 0 ]; then
+ return $OCF_NOT_RUNNING
+ fi
+
+ ocf_log info "elastic_ip has been successfully brought up (${ELASTIC_IP})"
+ return $OCF_SUCCESS
+}
+
+awseip_stop() {
+ awseip_monitor || return $OCF_SUCCESS
+
+ ASSOCIATION_ID=$($AWSCLI --profile $OCF_RESKEY_profile --output json ec2 describe-addresses \
+ --allocation-id ${ALLOCATION_ID} | grep -m 1 "AssociationId" | awk -F'"' '{print$4}')
+ $AWSCLI --profile $OCF_RESKEY_profile ec2 disassociate-address \
+ --association-id ${ASSOCIATION_ID}
+ RET=$?
+
+ # delay to avoid sending request too fast
+ sleep ${OCF_RESKEY_api_delay}
+
+ if [ $RET -ne 0 ]; then
+ return $OCF_NOT_RUNNING
+ fi
+
+ ocf_log info "elastic_ip has been successfully brought down (${ELASTIC_IP})"
+ return $OCF_SUCCESS
+}
+
+awseip_monitor() {
+ $AWSCLI --profile $OCF_RESKEY_profile ec2 describe-instances --instance-id "${INSTANCE_ID}" | grep -q "${ELASTIC_IP}"
+ RET=$?
+
+ if [ $RET -ne 0 ]; then
+ return $OCF_NOT_RUNNING
+ fi
+ return $OCF_SUCCESS
+}
+
+awseip_validate() {
+ check_binary ${AWSCLI}
+
+ if [ -z "$OCF_RESKEY_profile" ]; then
+ ocf_exit_reason "profile parameter not set"
+ return $OCF_ERR_CONFIGURED
+ fi
+
+ if [ -z "${INSTANCE_ID}" ]; then
+ ocf_exit_reason "instance_id not found. Is this a EC2 instance?"
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+case $__OCF_ACTION in
+ meta-data)
+ meta_data
+ exit $OCF_SUCCESS
+ ;;
+esac
+
+AWSCLI="${OCF_RESKEY_awscli}"
+ELASTIC_IP="${OCF_RESKEY_elastic_ip}"
+ALLOCATION_ID="${OCF_RESKEY_allocation_id}"
+PRIVATE_IP_ADDRESS="${OCF_RESKEY_private_ip_address}"
+INSTANCE_ID="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
+
+case $__OCF_ACTION in
+ start)
+ awseip_validate
+ awseip_start
+ ;;
+ stop)
+ awseip_stop
+ ;;
+ monitor)
+ awseip_monitor
+ ;;
+ migrate_to)
+ ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} to ${OCF_RESKEY_CRM_meta_migrate_target}."
+ awseip_stop
+ ;;
+ migrate_from)
+ ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} from ${OCF_RESKEY_CRM_meta_migrate_source}."
+ awseip_start
+ ;;
+ reload)
+ ocf_log info "Reloading ${OCF_RESOURCE_INSTANCE} ..."
+ ;;
+ validate|validate-all)
+ awseip_validate
+ ;;
+ usage|help)
+ awseip_usage
+ exit $OCF_SUCCESS
+ ;;
+ *)
+ awseip_usage
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+esac
+
+rc=$?
+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
+exit $rc
diff -uNr a/heartbeat/awsvip b/heartbeat/awsvip
--- a/heartbeat/awsvip 1970-01-01 01:00:00.000000000 +0100
+++ b/heartbeat/awsvip 2018-02-21 13:08:21.112887254 +0100
@@ -0,0 +1,245 @@
+#!/bin/sh
+#
+#
+# Manage Secondary Private IP with Pacemaker
+#
+#
+# Copyright 2016 guessi <guessi@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+#
+# Prerequisites:
+#
+# - preconfigured AWS CLI running environment (AccessKey, SecretAccessKey, etc.)
+# - a reserved secondary private IP address for EC2 instances high availablity
+# - IAM user role with the following permissions:
+# * DescribeInstances
+# * AssignPrivateIpAddresses
+# * UnassignPrivateIpAddresses
+#
+
+#######################################################################
+# Initialization:
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+
+#######################################################################
+
+#
+# Defaults
+#
+OCF_RESKEY_awscli_default="/usr/bin/aws"
+OCF_RESKEY_profile_default="default"
+OCF_RESKEY_api_delay_default="3"
+
+: ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}}
+: ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}}
+: ${OCF_RESKEY_api_delay=${OCF_RESKEY_api_delay_default}}
+
+meta_data() {
+ cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="awsvip">
+<version>1.0</version>
+
+<longdesc lang="en">
+Resource Agent for Amazon AWS Secondary Private IP Addresses.
+
+It manages AWS Secondary Private IP Addresses with awscli.
+
+Credentials needs to be setup by running "aws configure".
+
+See https://aws.amazon.com/cli/ for more information about awscli.
+</longdesc>
+<shortdesc lang="en">Amazon AWS Secondary Private IP Address Resource Agent</shortdesc>
+
+<parameters>
+
+<parameter name="awscli" unique="0">
+<longdesc lang="en">
+command line tools for aws services
+</longdesc>
+<shortdesc lang="en">aws cli tools</shortdesc>
+<content type="string" default="${OCF_RESKEY_awscli_default}" />
+</parameter>
+
+<parameter name="profile">
+<longdesc lang="en">
+Valid AWS CLI profile name (see ~/.aws/config and 'aws configure')
+</longdesc>
+<shortdesc lang="en">profile name</shortdesc>
+<content type="string" default="${OCF_RESKEY_profile_default}" />
+</parameter>
+
+<parameter name="secondary_private_ip" unique="1" required="1">
+<longdesc lang="en">
+reserved secondary private ip for ec2 instance
+</longdesc>
+<shortdesc lang="en">reserved secondary private ip for ec2 instance</shortdesc>
+<content type="string" default="" />
+</parameter>
+
+<parameter name="api_delay" unique="0">
+<longdesc lang="en">
+a short delay between API calls, to avoid sending API too quick
+</longdesc>
+<shortdesc lang="en">a short delay between API calls</shortdesc>
+<content type="integer" default="${OCF_RESKEY_api_delay_default}" />
+</parameter>
+
+</parameters>
+
+<actions>
+<action name="start" timeout="30" />
+<action name="stop" timeout="30" />
+<action name="monitor" timeout="30" interval="20" depth="0" />
+<action name="migrate_to" timeout="30" />
+<action name="migrate_from" timeout="30" />
+<action name="meta-data" timeout="5" />
+<action name="validate" timeout="10" />
+<action name="validate-all" timeout="10" />
+</actions>
+</resource-agent>
+END
+}
+
+#######################################################################
+
+awsvip_usage() {
+ cat <<END
+usage: $0 {start|stop|monitor|migrate_to|migrate_from|validate|validate-all|meta-data}
+
+Expects to have a fully populated OCF RA-compliant environment set.
+END
+}
+
+awsvip_start() {
+ awsvip_monitor && return $OCF_SUCCESS
+
+ $AWSCLI --profile $OCF_RESKEY_profile ec2 assign-private-ip-addresses \
+ --network-interface-id ${NETWORK_ID} \
+ --private-ip-addresses ${SECONDARY_PRIVATE_IP} \
+ --allow-reassignment
+ RET=$?
+
+ # delay to avoid sending request too fast
+ sleep ${OCF_RESKEY_api_delay}
+
+ if [ $RET -ne 0 ]; then
+ return $OCF_NOT_RUNNING
+ fi
+
+ ocf_log info "secondary_private_ip has been successfully brought up (${SECONDARY_PRIVATE_IP})"
+ return $OCF_SUCCESS
+}
+
+awsvip_stop() {
+ awsvip_monitor || return $OCF_SUCCESS
+
+ $AWSCLI --profile $OCF_RESKEY_profile ec2 unassign-private-ip-addresses \
+ --network-interface-id ${NETWORK_ID} \
+ --private-ip-addresses ${SECONDARY_PRIVATE_IP}
+ RET=$?
+
+ # delay to avoid sending request too fast
+ sleep ${OCF_RESKEY_api_delay}
+
+ if [ $RET -ne 0 ]; then
+ return $OCF_NOT_RUNNING
+ fi
+
+ ocf_log info "secondary_private_ip has been successfully brought down (${SECONDARY_PRIVATE_IP})"
+ return $OCF_SUCCESS
+}
+
+awsvip_monitor() {
+ $AWSCLI --profile $OCF_RESKEY_profile ec2 describe-instances --instance-id "${INSTANCE_ID}" | grep -q "${SECONDARY_PRIVATE_IP}"
+ RET=$?
+
+ if [ $RET -ne 0 ]; then
+ return $OCF_NOT_RUNNING
+ fi
+ return $OCF_SUCCESS
+}
+
+awsvip_validate() {
+ check_binary ${AWSCLI}
+
+ if [ -z "$OCF_RESKEY_profile" ]; then
+ ocf_exit_reason "profile parameter not set"
+ return $OCF_ERR_CONFIGURED
+ fi
+
+ if [ -z "${INSTANCE_ID}" ]; then
+ ocf_exit_reason "instance_id not found. Is this a EC2 instance?"
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+case $__OCF_ACTION in
+ meta-data)
+ meta_data
+ exit $OCF_SUCCESS
+ ;;
+esac
+
+AWSCLI="${OCF_RESKEY_awscli}"
+SECONDARY_PRIVATE_IP="${OCF_RESKEY_secondary_private_ip}"
+INSTANCE_ID="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
+NETWORK_ID="$($AWSCLI --profile $OCF_RESKEY_profile --output json ec2 describe-instances --instance-id ${INSTANCE_ID} | grep -m 1 'eni' | awk -F'"' '{print$4}')"
+
+case $__OCF_ACTION in
+ start)
+ awsvip_validate
+ awsvip_start
+ ;;
+ stop)
+ awsvip_stop
+ ;;
+ monitor)
+ awsvip_monitor
+ ;;
+ migrate_to)
+ ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} to ${OCF_RESKEY_CRM_meta_migrate_target}."
+ awsvip_stop
+ ;;
+ migrate_from)
+ ocf_log info "Migrating ${OCF_RESOURCE_INSTANCE} from ${OCF_RESKEY_CRM_meta_migrate_source}."
+ awsvip_start
+ ;;
+ reload)
+ ocf_log info "Reloading ${OCF_RESOURCE_INSTANCE} ..."
+ ;;
+ validate|validate-all)
+ awsvip_validate
+ ;;
+ usage|help)
+ awsvip_usage
+ exit $OCF_SUCCESS
+ ;;
+ *)
+ awsvip_usage
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+esac
+
+rc=$?
+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
+exit $rc
diff -uNr a/heartbeat/aws-vpc-move-ip b/heartbeat/aws-vpc-move-ip
--- a/heartbeat/aws-vpc-move-ip 1970-01-01 01:00:00.000000000 +0100
+++ b/heartbeat/aws-vpc-move-ip 2018-02-21 13:05:37.580246065 +0100
@@ -0,0 +1,306 @@
+#!/bin/sh
+#
+#
+# OCF resource agent to move an IP address within a VPC in the AWS
+#
+# Copyright (c) 2017 Markus Guertler (SUSE)
+# Based on code of Adam Gandelman (GitHub ec2-resource-agents/elasticip)
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+
+
+#######################################################################
+# Initialization:
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+
+# Defaults
+OCF_RESKEY_awscli_default="/usr/bin/aws"
+OCF_RESKEY_profile_default="default"
+OCF_RESKEY_monapi_default="false"
+
+: ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}}
+: ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}}
+: ${OCF_RESKEY_monapi=${OCF_RESKEY_monapi_default}}
+#######################################################################
+
+
+USAGE="usage: $0 {start|stop|status|meta-data}";
+###############################################################################
+
+
+###############################################################################
+#
+# Functions
+#
+###############################################################################
+
+
+metadata() {
+cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="aws-vpc-move-ip">
+<version>2.0</version>
+<longdesc lang="en">
+Resource Agent to move IP addresses within a VPC of the Amazon Webservices EC2
+by changing an entry in an specific routing table
+</longdesc>
+<shortdesc lang="en">Move IP within a APC of the AWS EC2</shortdesc>
+
+<parameters>
+<parameter name="awscli">
+<longdesc lang="en">
+Path to command line tools for AWS
+</longdesc>
+<shortdesc lang="en">Path to AWS CLI tools</shortdesc>
+<content type="string" default="${OCF_RESKEY_awscli_default}" />
+</parameter>
+
+<parameter name="profile">
+<longdesc lang="en">
+Valid AWS CLI profile name (see ~/.aws/config and 'aws configure')
+</longdesc>
+<shortdesc lang="en">profile name</shortdesc>
+<content type="string" default="${OCF_RESKEY_profile_default}" />
+</parameter>
+
+<parameter name="ip" required="1">
+<longdesc lang="en">
+VPC private IP address
+</longdesc>
+<shortdesc lang="en">VPC private IP</shortdesc>
+<content type="string" default="" />
+</parameter>
+
+<parameter name="routing_table" required="1">
+<longdesc lang="en">
+Name of the routing table, where the route for the IP address should be changed, i.e. rtb-...
+</longdesc>
+<shortdesc lang="en">routing table name</shortdesc>
+<content type="string" default="" />
+</parameter>
+
+<parameter name="interface" required="1">
+<longdesc lang="en">
+Name of the network interface, i.e. eth0
+</longdesc>
+<shortdesc lang="en">network interface name</shortdesc>
+<content type="string" default="eth0" />
+</parameter>
+
+<parameter name="monapi">
+<longdesc lang="en">
+Enable enhanced monitoring using AWS API calls to check route table entry
+</longdesc>
+<shortdesc lang="en">Enhanced Monitoring</shortdesc>
+<content type="boolean" default="${OCF_RESKEY_monapi_default}" />
+</parameter>
+</parameters>
+
+<actions>
+<action name="start" timeout="180" />
+<action name="stop" timeout="180" />
+<action name="monitor" depth="0" timeout="30" interval="60" />
+<action name="validate-all" timeout="5" />
+<action name="meta-data" timeout="5" />
+</actions>
+</resource-agent>
+END
+}
+
+ec2ip_validate() {
+ for cmd in aws ip curl; do
+ check_binary "$cmd"
+ done
+
+ if [ -z "$OCF_RESKEY_profile" ]; then
+ ocf_exit_reason "profile parameter not set"
+ return $OCF_ERR_CONFIGURED
+ fi
+
+ EC2_INSTANCE_ID="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
+
+ if [ -z "${EC2_INSTANCE_ID}" ]; then
+ ocf_exit_reason "Instance ID not found. Is this a EC2 instance?"
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+ec2ip_monitor() {
+ if ocf_is_true ${OCF_RESKEY_monapi} || [ "$__OCF_ACTION" = "start" ]; then
+ ocf_log info "monitor: check routing table (API call)"
+ cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile --output text ec2 describe-route-tables --route-table-ids $OCF_RESKEY_routing_table"
+ ocf_log debug "executing command: $cmd"
+ ROUTE_TO_INSTANCE="$($cmd | grep $OCF_RESKEY_ip | awk '{ print $3 }')"
+ if [ -z "$ROUTE_TO_INSTANCE" ]; then
+ ROUTE_TO_INSTANCE="<unknown>"
+ fi
+
+ if [ "$EC2_INSTANCE_ID" != "$ROUTE_TO_INSTANCE" ];then
+ ocf_log warn "not routed to this instance ($EC2_INSTANCE_ID) but to instance $ROUTE_TO_INSTANCE"
+ return $OCF_NOT_RUNNING
+ fi
+ else
+ ocf_log debug "monitor: Enhanced Monitoring disabled - omitting API call"
+ fi
+
+ cmd="ping -W 1 -c 1 $OCF_RESKEY_ip"
+ ocf_log debug "executing command: $cmd"
+ $cmd > /dev/null
+ if [ "$?" -gt 0 ]; then
+ ocf_log warn "IP $OCF_RESKEY_ip not locally reachable via ping on this system"
+ return $OCF_NOT_RUNNING
+ fi
+
+ ocf_log debug "route in VPC and locally reachable"
+ return $OCF_SUCCESS
+}
+
+
+ec2ip_drop() {
+ cmd="ip addr delete ${OCF_RESKEY_ip}/32 dev $OCF_RESKEY_interface"
+ ocf_log debug "executing command: $cmd"
+ $cmd
+ rc=$?
+ if [ "$rc" -gt 0 ]; then
+ ocf_log warn "command failed, rc $rc"
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+ec2ip_get_and_configure() {
+ # Adjusting the routing table
+ cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile ec2 replace-route --route-table-id $OCF_RESKEY_routing_table --destination-cidr-block ${OCF_RESKEY_ip}/32 --instance-id $EC2_INSTANCE_ID"
+ ocf_log debug "executing command: $cmd"
+ $cmd
+ rc=$?
+ if [ "$rc" != 0 ]; then
+ ocf_log warn "command failed, rc: $rc"
+ return $OCF_ERR_GENERIC
+ fi
+
+ # Reconfigure the local ip address
+ ec2ip_drop
+ ip addr add "${OCF_RESKEY_ip}/32" dev $OCF_RESKEY_interface
+ rc=$?
+ if [ $rc != 0 ]; then
+ ocf_log warn "command failed, rc: $rc"
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+ec2ip_stop() {
+ ocf_log info "EC2: Bringing down IP address $OCF_RESKEY_ip"
+
+ ec2ip_monitor
+ if [ $? = $OCF_NOT_RUNNING ]; then
+ ocf_log info "EC2: Address $OCF_RESKEY_ip already down"
+ return $OCF_SUCCESS
+ fi
+
+ ec2ip_drop
+ if [ $? != $OCF_SUCCESS ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ ec2ip_monitor
+ if [ $? != $OCF_NOT_RUNNING ]; then
+ ocf_log error "EC2: Couldn't bring down IP address $OCF_RESKEY_ip on interface $OCF_RESKEY_interface."
+ return $OCF_ERR_GENERIC
+ fi
+
+ ocf_log info "EC2: Successfully brought down $OCF_RESKEY_ip"
+ return $OCF_SUCCESS
+}
+
+ec2ip_start() {
+ ocf_log info "EC2: Moving IP address $OCF_RESKEY_ip to this host by adjusting routing table $OCF_RESKEY_routing_table"
+
+ ec2ip_monitor
+ if [ $? = $OCF_SUCCESS ]; then
+ ocf_log info "EC2: $OCF_RESKEY_ip already started"
+ return $OCF_SUCCESS
+ fi
+
+ ocf_log info "EC2: Adjusting routing table and locally configuring IP address"
+ ec2ip_get_and_configure
+ rc=$?
+ if [ $rc != $OCF_SUCCESS ]; then
+ ocf_log error "Received $rc from 'aws'"
+ return $OCF_ERR_GENERIC
+ fi
+
+ ec2ip_monitor
+ if [ $? != $OCF_SUCCESS ]; then
+ ocf_log error "EC2: IP address couldn't be configured on this host (IP: $OCF_RESKEY_ip, Interface: $OCF_RESKEY_interface)"
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+###############################################################################
+#
+# MAIN
+#
+###############################################################################
+
+case $__OCF_ACTION in
+ meta-data)
+ metadata
+ exit $OCF_SUCCESS
+ ;;
+ usage|help)
+ echo $USAGE
+ exit $OCF_SUCCESS
+ ;;
+esac
+
+if ! ocf_is_root; then
+ ocf_log err "You must be root for $__OCF_ACTION operation."
+ exit $OCF_ERR_PERM
+fi
+
+ec2ip_validate
+
+case $__OCF_ACTION in
+ start)
+ ec2ip_start;;
+ stop)
+ ec2ip_stop;;
+ monitor)
+ ec2ip_monitor;;
+ validate-all)
+ exit $?;;
+ *)
+ echo $USAGE
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+esac
diff -uNr a/heartbeat/Makefile.am b/heartbeat/Makefile.am
--- a/heartbeat/Makefile.am 2018-02-21 13:07:45.862175305 +0100
+++ b/heartbeat/Makefile.am 2018-02-21 13:05:37.589245986 +0100
@@ -64,6 +64,9 @@
AoEtarget \
apache \
asterisk \
+ aws-vpc-move-ip \
+ awseip \
+ awsvip \
nginx \
AudibleAlarm \
clvm \