diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index 71280beca..0cb3864ca 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -1,178 +1,179 @@ # Makefile.am for OCF RAs # # Author: Sun Jing Dong # Copyright (C) 2004 IBM # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(ocf_SCRIPTS) $(ocfcommon_DATA) \ $(common_DATA) $(hb_DATA) $(dtd_DATA) \ README AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/linux-ha halibdir = $(libexecdir)/heartbeat ocfdir = $(OCF_RA_DIR_PREFIX)/heartbeat dtddir = $(datadir)/$(PACKAGE_NAME) dtd_DATA = ra-api-1.dtd metadata.rng if USE_IPV6ADDR_AGENT ocf_PROGRAMS = IPv6addr else ocf_PROGRAMS = endif if IPV6ADDR_COMPATIBLE halib_PROGRAMS = send_ua else halib_PROGRAMS = endif IPv6addr_SOURCES = IPv6addr.c IPv6addr_utils.c send_ua_SOURCES = send_ua.c IPv6addr_utils.c IPv6addr_LDADD = -lplumb $(LIBNETLIBS) send_ua_LDADD = $(LIBNETLIBS) ocf_SCRIPTS = AoEtarget \ AudibleAlarm \ ClusterMon \ CTDB \ Delay \ Dummy \ EvmsSCC \ Evmsd \ Filesystem \ ICP \ IPaddr \ IPaddr2 \ IPsrcaddr \ LVM \ LinuxSCSI \ lvmlockd \ MailTo \ ManageRAID \ ManageVE \ NodeUtilization \ Pure-FTPd \ Raid1 \ Route \ SAPDatabase \ SAPInstance \ SendArp \ ServeRAID \ SphinxSearchDaemon \ Squid \ Stateful \ SysInfo \ VIPArip \ VirtualDomain \ WAS \ WAS6 \ WinPopup \ Xen \ Xinetd \ ZFS \ anything \ apache \ asterisk \ + aws-vpc-move-ip \ aws-vpc-route53 \ awseip \ awsvip \ clvm \ conntrackd \ db2 \ dhcpd \ dnsupdate \ docker \ eDir88 \ ethmonitor \ exportfs \ fio \ galera \ garbd \ iSCSILogicalUnit \ iSCSITarget \ ids \ iface-bridge \ iface-vlan \ iscsi \ jboss \ kamailio \ lxc \ minio \ mysql \ mysql-proxy \ nagios \ named \ nfsnotify \ nfsserver \ nginx \ oraasm \ oracle \ oralsnr \ ovsmonitor \ pgagent \ pgsql \ pingd \ portblock \ postfix \ pound \ proftpd \ rabbitmq-cluster \ redis \ rkt \ rsyncd \ rsyslog \ scsi2reservation \ sfex \ sg_persist \ slapd \ symlink \ syslog-ng \ tomcat \ varnish \ vmware \ vsftpd \ zabbixserver ocfcommondir = $(OCF_LIB_DIR_PREFIX)/heartbeat ocfcommon_DATA = ocf-shellfuncs \ ocf-binaries \ ocf-directories \ ocf-returncodes \ ocf-rarun \ ocf-distro \ apache-conf.sh \ http-mon.sh \ sapdb-nosha.sh \ sapdb.sh \ ora-common.sh \ mysql-common.sh \ nfsserver-redhat.sh \ findif.sh # Legacy locations hbdir = $(sysconfdir)/ha.d hb_DATA = shellfuncs check: $(ocf_SCRIPTS:=.check) %.check: % OCF_ROOT=$(abs_srcdir) OCF_FUNCTIONS_DIR=$(abs_srcdir) ./$< meta-data | xmllint --path $(abs_srcdir) --noout --relaxng $(abs_srcdir)/metadata.rng - diff --git a/heartbeat/aws-vpc-move-ip b/heartbeat/aws-vpc-move-ip new file mode 100755 index 000000000..30ea106e6 --- /dev/null +++ b/heartbeat/aws-vpc-move-ip @@ -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 < + + +2.0 + +Resource Agent to move IP addresses within a VPC of the Amazon Webservices EC2 +by changing an entry in an specific routing table + +Move IP within a APC of the AWS EC2 + + + + +Path to command line tools for AWS + +Path to AWS CLI tools + + + + + +Valid AWS CLI profile name (see ~/.aws/config and 'aws configure') + +profile name + + + + + +VPC private IP address + +VPC private IP + + + + + +Name of the routing table, where the route for the IP address should be changed, i.e. rtb-... + +routing table name + + + + + +Name of the network interface, i.e. eth0 + +network interface name + + + + + +Enable enhanced monitoring using AWS API calls to check route table entry + +Enhanced Monitoring + + + + + + + + + + + + +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="" + 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