From e45d0ca9ccc3d5fbe94372f40bedb7559dc9530a Mon Sep 17 00:00:00 2001 From: "feng.changf1" Date: Tue, 24 Jul 2018 15:08:45 +0800 Subject: [PATCH] Add Aliyun vpc-move-ip agent. --- heartbeat/aliyun-vpc-move-ip | 258 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 heartbeat/aliyun-vpc-move-ip diff --git a/heartbeat/aliyun-vpc-move-ip b/heartbeat/aliyun-vpc-move-ip new file mode 100644 index 000000000..bc97822a8 --- /dev/null +++ b/heartbeat/aliyun-vpc-move-ip @@ -0,0 +1,258 @@ +#!/bin/bash +# +# OCF resource agent to move an IP address within a VPC in the Aliyun +# Based on code of Markus Guertler (GitHub AWS-VPC-move-IP) +# Based on code of Adam Gandelman (GitHub ec2-resource-agents/elasticip) +# + +############################################################################### +# 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 + +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} +. ${OCF_FUNCTIONS} +: ${__OCF_ACTION=$1} +export HOME=/root +####################################################################### + + +USAGE="usage: $0 {start|stop|status|meta-data}"; +############################################################################### + + +############################################################################### +# +# Functions +# +############################################################################### + + +metadata() { +cat < + + +2.0 + +Resource Agent to move IP addresses within a VPC of the Aliyun Webservices ECS +by changing an entry in an specific routing table + +Move IP within a APC of the Aliyun ECS + + + +VPC private IP address + +vpc 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 interfacen, i.e. eth0 + +network interface name + + + + +Valid Aliyun CLI profile name + +profile name + + + + + + + + + + + +END +} + +debugger() { + ocf_log info "DEBUG: $1" +} + +ecs_ip_validate() { + debugger "function: validate" + + # IP address + [[ -z "$OCF_RESKEY_address" ]] && ocf_log error "IP address parameter not set $OCF_RESKEY_ADDRESS!" && exit $OCF_ERR_CONFIGURED + + # Network Interface + [[ -z "$OCF_RESKEY_interface" ]] && ocf_log error "Network interface parameter not set $OCF_RESKEY_INTERFACE!" && exit $OCF_ERR_CONFIGURED + + # Routing Table + [[ -z "$OCF_RESKEY_routing_table" ]] && ocf_log error "Routing table parameter not set $OCF_RESKEY_ROUTING_TABLE!" && exit $OCF_ERR_CONFIGURED + + ECS_INSTANCE_ID="$(curl -s http://100.100.100.200/latest/meta-data/instance-id)" + + if [ -z "${ECS_INSTANCE_ID}" ]; then + ocf_exit_reason "Instance ID not found. Is this a ECS instance?" + return $OCF_ERR_GENERIC + fi + + return $OCF_SUCCESS +} + +ecs_ip_monitor() { + ecs_ip_validate + debugger "function: ecsip_monitor: check routing table" + cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" + debugger "executing command: $cmd" + ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" + if [ -z "$ROUTE_TO_INSTANCE" ]; then + ROUTE_TO_INSTANCE="" + fi + + [[ "$ECS_INSTANCE_ID" != "$ROUTE_TO_INSTANCE" ]] && debugger "not routed to this instance ($ECS_INSTANCE_ID) but to instance $ROUTE_TO_INSTANCE" && return $OCF_NOT_RUNNING + cmd="ping -W 1 -c 1 $OCF_RESKEY_address" + debugger "executing command: $cmd" + $cmd > /dev/null + [[ $? -gt 0 ]] && debugger "IP $OCF_RESKEY_address not locally reachable via ping on this system" && return $OCF_NOT_RUNNING + debugger "routed in VPC and locally reachable" + return $OCF_SUCCESS +} + + +ecs_ip_drop() { + debugger "function: ecsip_drop" + cmd="ip addr delete ${OCF_RESKEY_address}/32 dev $OCF_RESKEY_interface" + debugger "executing command: $cmd" + $cmd + rc=$? + [[ $rc -gt 2 ]] && debugger "command failed, rc $rc" && return $OCF_ERR_GENERIC + debugger "command succeeded" + return $OCF_SUCCESS +} + +wait_for_deleted() { + while [ ! -z "$ROUTE_TO_INSTANCE" ]; do + sleep 1 + cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" + debugger "executing command: $cmd" + ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" + done + sleep 5 +} + +wait_for_started() { + cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" + debugger "executing command: $cmd" + ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" + + while [ "$ECS_INSTANCE_ID" != "$ROUTE_TO_INSTANCE" ]; do + sleep 1 + cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" + debugger "executing command: $cmd" + ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" + done + sleep 5 +} + +ecs_ip_get_and_configure() { + debugger "function: ecsip_get_and_configure" + + if [ "$ECS_INSTANCE_ID" != "$ROUTE_TO_INSTANCE" ]; then + + if [ $ROUTE_TO_INSTANCE != "" ]; then + # Adjusting the routing table + cmd="aliyuncli vpc DeleteRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ROUTE_TO_INSTANCE --output text" + debugger "executing command: $cmd" + $cmd + rc=$? + [[ $rc != 0 ]] && debugger "command failed, rc: $rc" && return $OCF_ERR_GENERIC + #wait_for_deleted + sleep 3 + fi + + cmd="aliyuncli vpc CreateRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ECS_INSTANCE_ID --NextHopType Instance --output text" + debugger "executing command: $cmd" + $cmd + rc=$? + #[[ $rc != 0 ]] && debugger "command failed, rc: $rc" && return $OCF_ERR_GENERIC + while [ $rc != 0 ]; do + sleep 2 + cmd="aliyuncli vpc CreateRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ECS_INSTANCE_ID --NextHopType Instance --output text" + debugger "executing command: $cmd" + $cmd + rc=$? + done + wait_for_started + fi + + + # Reconfigure the local ip address + ecs_ip_drop + ip addr add "${OCF_RESKEY_address}/32" dev $OCF_RESKEY_interface + rc=$? + [[ $rc != 0 ]] && debugger "command failed, rc: $rc" && return $OCF_ERR_GENERIC + debugger "-success" + return $OCF_SUCCESS +} + +ecs_ip_stop() { + ocf_log info "ECS: Bringing down IP address $OCF_RESKEY_address" + ecs_ip_validate + ecs_ip_monitor + [[ $? == $OCF_NOT_RUNNING ]] && ocf_log info "ECS: Address $OCF_RESKEY_address already down" && return $OCF_SUCCESS + ecs_ip_drop + [[ $? != $OCF_SUCCESS ]] && return $OCF_ERR_GENERIC + ecs_ip_monitor + [[ $? == $OCF_NOT_RUNNING ]] && ocf_log info "ECS: Successfully brought down $OCF_RESKEY_address" && return $OCF_SUCCESS + ocf_log error "ECS: Couldn't bring down IP address $OCF_RESKEY_address on interface $OCF_RESKEY_interface." + return $OCF_ERR_GENERIC +} + +ecs_ip_start() { + ocf_log info "ECS: Moving IP address $OCF_RESKEY_address to this host by adjusting routing table $OCF_RESKEY_routing_table" + ecs_ip_validate + ecs_ip_monitor + [[ $? == $OCF_SUCCESS ]] && ocf_log info "ECS: $OCF_RESKEY_address already started" && return $OCF_SUCCESS + ocf_log info "ECS: Adjusting routing table and locally configuring IP address" + ecs_ip_get_and_configure + [[ $? != 0 ]] && ocf_log error "Received $? from 'aliyun cli'" && return $OCF_ERR_GENERIC + return $OCF_SUCCESS + ecs_ip_monitor + [[ $? == $OCF_SUCCESS ]] && return $? + ocf_log error "ECS: IP address couldn't be configured on this host (IP: $OCF_RESKEY_address, Interface: $OCF_RESKEY_interface)" + return $OCF_ERR_GENERIC +} + +############################################################################### +# +# MAIN +# +############################################################################### + +case $__OCF_ACTION in + meta-data) metadata + exit $OCF_SUCCESS;; + monitor) + ecs_ip_monitor;; + stop) + ecs_ip_stop;; + validate-all) ecs_ip_validate;; + start) + ecs_ip_start;; + *) exit $OCF_ERR_UNIMPLEMENTED;; +esac \ No newline at end of file