--- a/heartbeat/aliyun-vpc-move-ip 2020-06-09 13:41:35.308379032 +0200 +++ b/heartbeat/aliyun-vpc-move-ip 2020-06-05 10:48:45.555132686 +0200 @@ -9,12 +9,46 @@ # Initialization: : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +# Parameter defaults + +OCF_RESKEY_address_default="" +OCF_RESKEY_routing_table_default="" +OCF_RESKEY_interface_default="eth0" +OCF_RESKEY_profile_default="default" +OCF_RESKEY_endpoint_default="vpc.aliyuncs.com" +OCF_RESKEY_aliyuncli_default="detect" + + +: ${OCF_RESKEY_address=${OCF_RESKEY_address_default}} +: ${OCF_RESKEY_routing_table=${OCF_RESKEY_routing_table_default}} +: ${OCF_RESKEY_interface=${OCF_RESKEY_interface_default}} +: ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}} +: ${OCF_RESKEY_endpoint=${OCF_RESKEY_endpoint_default}} +: ${OCF_RESKEY_aliyuncli=${OCF_RESKEY_aliyuncli_default}} + ####################################################################### -# aliyuncli doesnt work without HOME parameter +# aliyun cli doesnt work without HOME parameter export HOME="/root" USAGE="usage: $0 {start|stop|status|meta-data}"; + +if [ "${OCF_RESKEY_aliyuncli}" = "detect" ]; then + OCF_RESKEY_aliyuncli="$(which aliyuncli 2> /dev/null || which aliyun 2> /dev/null)" +fi + +if [[ "${OCF_RESKEY_aliyuncli##*/}" == 'aliyuncli' ]]; then + OUTPUT="text" + EXECUTING='{ print $3 }' + IFS_=" " + ENDPOINT="" +elif [[ "${OCF_RESKEY_aliyuncli##*/}" == 'aliyun' ]]; then + OUTPUT="table cols=InstanceId,DestinationCidrBlock rows=RouteTables.RouteTable[].RouteEntrys.RouteEntry[]" + EXECUTING='{ gsub (" ", "", $0); print $1 }' + IFS_="|" + ENDPOINT="--endpoint $OCF_RESKEY_endpoint" +fi ############################################################################### @@ -24,27 +58,61 @@ # ############################################################################### +request_create_route_entry() { + cmd="${OCF_RESKEY_aliyuncli} vpc CreateRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ECS_INSTANCE_ID --NextHopType Instance ${ENDPOINT}" + ocf_log debug "executing command: $cmd" + res=$($cmd 2>&1) + rc=$? + if [[ $rc -eq 0 ]] + then + ocf_log debug "result: $res; rc: $rc" + else + ocf_log err "result: $res; cmd: $cmd; rc: $rc" + fi + return $rc +} + +request_delete_route_entry() { + cmd="${OCF_RESKEY_aliyuncli} vpc DeleteRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ROUTE_TO_INSTANCE ${ENDPOINT}" + ocf_log debug "executing command: $cmd" + res=$($cmd) + rc=$? + if [[ $rc -eq 0 ]] + then + ocf_log debug "result: $res; rc: $rc" + else + ocf_log err "result: $res; cmd: $cmd; rc: $rc" + fi + return $rc +} +request_describe_route_tables() { + cmd="${OCF_RESKEY_aliyuncli} vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output ${OUTPUT} ${ENDPOINT}" + ocf_log debug "executing command: $cmd" + res=$($cmd) + rc=$? + if [[ $rc -eq 0 ]] + then + ROUTE_TO_INSTANCE=$(echo "$res" |grep "\s${OCF_RESKEY_address}/" | awk -F "${IFS_}" "${EXECUTING}") + ocf_log debug "ROUTE_TO_INSTANCE: $ROUTE_TO_INSTANCE" + else + ocf_log err "result: $res; cmd: $cmd; rc: $rc" + fi +} ip_get_and_configure() { ocf_log debug "function: ip_get_and_configure" - ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" - + request_describe_route_tables if [ "$ECS_INSTANCE_ID" != "$ROUTE_TO_INSTANCE" ]; then if [ -n "$ROUTE_TO_INSTANCE" ]; then ip_drop fi - - cmd="aliyuncli vpc CreateRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ECS_INSTANCE_ID --NextHopType Instance --output text" - ocf_log debug "executing command: $cmd" - $cmd + request_create_route_entry rc=$? while [ $rc -ne 0 ]; do sleep 1 - cmd="aliyuncli vpc CreateRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ECS_INSTANCE_ID --NextHopType Instance --output text" - ocf_log debug "executing command: $cmd" - $cmd + request_create_route_entry rc=$? done wait_for_started @@ -68,17 +136,15 @@ ocf_log debug "function: ip_drop" cmd="ip addr delete ${OCF_RESKEY_address}/32 dev $OCF_RESKEY_interface" ocf_log debug "executing command: $cmd" - $cmd + res=$($cmd) rc=$? if [ $rc -ne 0 ] && [ $rc -ne 2 ]; then - ocf_log err "command failed, rc $rc" + ocf_log err "command failed, rc: $rc; cmd: $cmd; result: $res" return $OCF_ERR_GENERIC fi - - cmd="aliyuncli vpc DeleteRouteEntry --RouteTableId $OCF_RESKEY_routing_table --DestinationCidrBlock ${OCF_RESKEY_address}/32 --NextHopId $ROUTE_TO_INSTANCE --output text" - ocf_log debug "executing command: $cmd" - $cmd - if [ $? -ne 0 ]; then + request_delete_route_entry + rc=$? + if [ $rc -ne 0 ]; then ocf_log err "command failed, rc: $rc" return $OCF_ERR_GENERIC fi @@ -90,26 +156,18 @@ } wait_for_started() { - cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" - ocf_log debug "executing command: $cmd" - ROUTE_TO_INSTANCE="$($cmd | grep $OCF_RESKEY_address | awk '{ print $3 }')" - + request_describe_route_tables while [ "$ECS_INSTANCE_ID" != "$ROUTE_TO_INSTANCE" ]; do sleep 3 - cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" - ocf_log debug "executing command: $cmd" - ROUTE_TO_INSTANCE="$($cmd | grep $OCF_RESKEY_address | awk '{ print $3 }')" + request_describe_route_tables done } wait_for_deleted() { - ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" - + request_describe_route_tables while [ ! -z "$ROUTE_TO_INSTANCE" ]; do sleep 1 - cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" - ocf_log debug "executing command: $cmd" - ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" + request_describe_route_tables done } @@ -124,38 +182,58 @@ by changing an entry in an specific routing table Move IP within a VPC of the Aliyun ECS + + + +Path to command line tools for Aliyun + +Path to Aliyun CLI tools + + + VPC private IP address vpc ip - + + Name of the routing table, where the route for the IP address should be changed, i.e. vtb-... routing table name - + + Name of the network interface, i.e. eth0 network interface name - + - + + -Valid Aliyun CLI profile name (see 'aliyuncli-ra configure'). +An endpoint is the service entry of an Alibaba Cloud service, i.e. vpc.cn-beijing.aliyuncs.com + +service endpoint + + -See https://www.alibabacloud.com/help/doc-detail/43039.htm?spm=a2c63.p38356.b99.16.38a914abRZtOU3 for more information about aliyuncli-ra. + + +Valid Aliyun CLI profile name (see 'aliyun cli configure'). +See https://www.alibabacloud.com/help/zh/product/29991.htm for more information about aliyun cli. profile name - + + @@ -170,6 +248,11 @@ ecs_ip_validate() { ocf_log debug "function: validate" + if [ -z "${OCF_RESKEY_aliyuncli}" ]; then + ocf_exit_reason "unable to detect aliyuncli binary" + exit $OCF_ERR_INSTALLED + fi + # IP address if [ -z "$OCF_RESKEY_address" ]; then ocf_log err "IP address parameter not set $OCF_RESKEY_ADDRESS!" @@ -250,10 +333,7 @@ ecs_ip_monitor() { ocf_log debug "function: ecsip_monitor: check routing table" - cmd="aliyuncli vpc DescribeRouteTables --RouteTableId $OCF_RESKEY_routing_table --output text" - ocf_log debug "executing command: $cmd" - - ROUTE_TO_INSTANCE="$($cmd |grep $OCF_RESKEY_address | awk '{ print $3 }')" + request_describe_route_tables if [ "$ECS_INSTANCE_ID" != "$ROUTE_TO_INSTANCE" ]; then ocf_log debug "not routed to this instance ($ECS_INSTANCE_ID) but to instance $ROUTE_TO_INSTANCE"