From 2af007a739c98b9cc4351927dfe45f8b589dc596 Mon Sep 17 00:00:00 2001 From: anthony Date: Mon, 2 Jul 2012 17:28:30 -0700 Subject: [PATCH] VPC : add static route --- .../api/routing/SetStaticRouteCommand.java | 19 +++ .../xen/resource/CitrixResourceBase.java | 32 ++++- .../config/opt/cloud/bin/vpc_staticroute.sh | 119 +++++++++++------- 3 files changed, 122 insertions(+), 48 deletions(-) diff --git a/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java b/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java index 1ab59d7174e..4f335af7fdd 100644 --- a/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java +++ b/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java @@ -12,8 +12,12 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.agent.api.routing; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import com.cloud.agent.api.to.NetworkACLTO; +import com.cloud.network.vpc.StaticRoute; import com.cloud.network.vpc.StaticRouteProfile; /** @@ -32,4 +36,19 @@ public class SetStaticRouteCommand extends NetworkElementCommand{ public StaticRouteProfile[] getStaticRoutes() { return staticRoutes; } + + public String[][] generateSRouteRules() { + String [][] result = new String [2][]; + Set toAdd = new HashSet(); + for (StaticRouteProfile route: staticRoutes) { + /* example : ip:gateway:cidr, + */ + if( route.getState() == StaticRoute.State.Active || route.getState() == StaticRoute.State.Add ) { + String entry = route.getIp4Address()+ ":" + route.getGateway() + ":" + route.getCidr(); + toAdd.add(entry); + } + } + result[0] = toAdd.toArray(new String[toAdd.size()]); + return result; + } } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4a700cd9177..17e8a5cef00 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -7413,9 +7413,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String [][] rules = cmd.generateFwRules(); StringBuilder sb = new StringBuilder(); String[] aclRules = rules[0]; - if (aclRules.length == 0) { - return new SetNetworkACLAnswer(cmd, true, results); - } for (int i = 0; i < aclRules.length; i++) { sb.append(aclRules[i]).append(','); @@ -7475,7 +7472,32 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - // TODO Auto-generated method stub - return new SetStaticRouteAnswer(cmd, true, null); + String[] results = new String[cmd.getStaticRoutes().length]; + String callResult; + Connection conn = getConnection(); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + try { + String [][] rules = cmd.generateSRouteRules(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < rules.length; i++) { + sb.append(rules[i]).append(','); + } + + String args = "vpc_staticroute.sh " + routerIp; + args += " -a " + sb.toString(); + callResult = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (callResult == null || callResult.isEmpty()) { + //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails + for (int i=0; i < results.length; i++) { + results[i] = "Failed"; + } + return new SetStaticRouteAnswer(cmd, false, results); + } + return new SetStaticRouteAnswer(cmd, true, results); + } catch (Exception e) { + String msg = "SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new SetStaticRouteAnswer(cmd, false, results); + } } } diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticroute.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticroute.sh index 2a4593c7603..2c3f3ee9810 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticroute.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticroute.sh @@ -23,56 +23,68 @@ then fi usage() { - printf "Usage: %s: (-A|-D) -c < cidr > -l -g < gateway> \n" $(basename $0) >&2 + printf "Usage: %s: -a < routes > \n" $(basename $0) >&2 } #set -x +flush_table_backup() { + flush_table "static_route_back" +} + +flush_table() { + local tab=$1 + sudo ip route flush table $tab +} + +copy_table() { + local from=$1 + local to=$2 + sudo ip route show table $from | while read route + do + sudo ip route add table $to $route + done +} + +backup_table() { + flush_table "static_route_back" + copy_table "static_route" "static_route_back" + flush table "static_route" +} + +restore_table() { + flush_table "static_route" + copy_table "static_route_back" "static_route" + flush table "static_route_back" +} + static_route() { - local op=$1 - local publicIp=$2 - local gateway=$3 - local cidr=$4 - + local rule=$1 + local ip=$(echo $rule | cut -d: -f1) + local gateway=$(echo $rule | cut -d: -f2) + local cidr=$(echo $rule | cut -d: -f3) logger -t cloud "$(basename $0): static route: public ip=$publicIp \ - gateway=$gateway cidr=$cidr op=$op" - #if adding, this might be a duplicate, so delete the old one first - [ "$op" == "add" ] && static_routet "del" $publicIp $gateway $cidr - - sudo ip route $op $cidr dev $ethDev via $gateway &>> $OUTFILE + gateway=$gateway cidr=$cidr" + local dev=$(getDevByIp $ip) + if [ $? -gt 0 ] + then + return 1 + fi + sudo ip route table static_route add $cidr dev $dev via $gateway &>> $OUTFILE result=$? logger -t cloud "$(basename $0): done static route: public ip=$publicIp \ - gateway=$gateway cidr=$cidr op=$op" - - if [ "$op" == "del" ] - then - return 0 - fi + gateway=$gateway cidr=$cidr" return $result } - - gflag= -lflag= -cflag= -op="" -while getopts 'ADg:l:c:' OPTION +aflag= +while getopts 'a:' OPTION do case $OPTION in - A) op="add" - ;; - D) op="del" - ;; - g) gflag=1 - gateway="$OPTARG" - ;; - l) lflag=1 - publicIp="$OPTARG" - ;; - c) cflag=1 - cidr="$OPTARG" + a) aflag=1 + rules="$OPTARG" ;; ?) usage unlock_exit 2 $lock $locked @@ -80,14 +92,35 @@ do esac done -ethDev=$(getEthByIp $publicIp) -result=$? -if [ $result -gt 0 ] +if [ -n "$rules" ] then - unlock_exit $result $lock $locked + rules_list=$(echo $rules | cut -d, --output-delimiter=" ") fi -OUTFILE=$(mktemp) -static_route $op $publicIp $gateway $cidr -result=$? -unlock_exit $result $lock $locked +success=0 + +backup_table + +for r in $rules_list +do + static_route $r + success=$? + if [ $success -gt 0 ] + then + logger -t cloud "$(basename $0): failure to apply fw rules for guest network: $gcidr" + break + else + logger -t cloud "$(basename $0): successful in applying fw rules for guest network: $gcidr" + fi +done + +if [ $success -gt 0 ] +then + logger -t cloud "$(basename $0): restoring from backup for guest network: $gcidr" + restore_table +else + logger -t cloud "$(basename $0): deleting backup for guest network: $gcidr" + flush_table_backup +fi +unlock_exit $success $lock $locked +