mirror of https://github.com/apache/cloudstack.git
parent
f5f07ca0fd
commit
99e46e4c2f
|
|
@ -12,13 +12,15 @@
|
|||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.agent.api.routing.SetSourceNatCommand;
|
||||
|
||||
/**
|
||||
* @author Alena Prokharchyk
|
||||
*/
|
||||
public class SetSourceNatAnswer extends Answer{
|
||||
public SetSourceNatAnswer() {}
|
||||
|
||||
public SetSourceNatAnswer(PlugNicCommand cmd, boolean success, String result) {
|
||||
public SetSourceNatAnswer(SetSourceNatCommand cmd, boolean success, String result) {
|
||||
super(cmd, success, result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1812,6 +1812,67 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
|
||||
protected void assignVPCPublicIpAddress(Connection conn, String vmName, String privateIpAddress, String publicIpAddress, boolean add,
|
||||
String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp,TrafficType trafficType, String name) throws InternalErrorException {
|
||||
|
||||
try {
|
||||
VM router = getVM(conn, vmName);
|
||||
|
||||
NicTO nic = new NicTO();
|
||||
nic.setMac(vifMacAddress);
|
||||
nic.setType(trafficType);
|
||||
if (vlanId == null) {
|
||||
nic.setBroadcastType(BroadcastDomainType.Native);
|
||||
} else {
|
||||
nic.setBroadcastType(BroadcastDomainType.Vlan);
|
||||
nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanId));
|
||||
}
|
||||
nic.setName(name);
|
||||
Network network = getNetwork(conn, nic);
|
||||
// Determine the correct VIF on DomR to associate/disassociate the
|
||||
// IP address with
|
||||
VIF correctVif = getCorrectVif(conn, router, network);
|
||||
|
||||
|
||||
if (correctVif == null) {
|
||||
throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
|
||||
}
|
||||
|
||||
String args = "vpc_ipassoc.sh " + privateIpAddress;
|
||||
|
||||
if (add) {
|
||||
args += " -A ";
|
||||
} else {
|
||||
args += " -D ";
|
||||
}
|
||||
|
||||
args += " -l ";
|
||||
args += publicIpAddress;
|
||||
|
||||
args += " -c ";
|
||||
args += "eth" + correctVif.getDevice(conn);
|
||||
|
||||
args += " -g ";
|
||||
args += vlanGateway;
|
||||
|
||||
args += " -m ";
|
||||
args += Long.toString(NetUtils.getCidrSize(vlanNetmask));
|
||||
|
||||
|
||||
args += " -n ";
|
||||
args += NetUtils.getSubNet(publicIpAddress, vlanNetmask);
|
||||
|
||||
String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
|
||||
if (result == null || result.isEmpty()) {
|
||||
throw new InternalErrorException("Xen plugin \"ipassoc\" failed.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Unable to assign public IP address due to " + e.toString();
|
||||
s_logger.warn(msg, e);
|
||||
throw new InternalErrorException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) {
|
||||
|
||||
if (option.equals("get")) {
|
||||
|
|
@ -7124,14 +7185,72 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
|
||||
protected IpAssocAnswer execute(IpAssocVpcCommand cmd) {
|
||||
//FIXME - add implementation here
|
||||
return null;
|
||||
Connection conn = getConnection();
|
||||
String[] results = new String[cmd.getIpAddresses().length];
|
||||
int i = 0;
|
||||
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||
try {
|
||||
IpAddressTO[] ips = cmd.getIpAddresses();
|
||||
for (IpAddressTO ip : ips) {
|
||||
|
||||
assignVPCPublicIpAddress(conn, routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.getVlanId(),
|
||||
ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), ip.getGuestIp(), ip.getTrafficType(), ip.getNetworkName());
|
||||
results[i++] = ip.getPublicIp() + " - success";
|
||||
}
|
||||
} catch (InternalErrorException e) {
|
||||
s_logger.error(
|
||||
"Ip Assoc failure on applying one ip due to exception: ", e);
|
||||
results[i++] = IpAssocAnswer.errorResult;
|
||||
}
|
||||
|
||||
return new IpAssocAnswer(cmd, results);
|
||||
}
|
||||
|
||||
|
||||
protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) {
|
||||
//FIXME - add implementation here
|
||||
return null;
|
||||
Connection conn = getConnection();
|
||||
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
|
||||
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||
IpAddressTO pubIp = cmd.getIpAddress();
|
||||
try {
|
||||
VM router = getVM(conn, routerName);
|
||||
|
||||
NicTO nic = new NicTO();
|
||||
nic.setMac(pubIp.getVifMacAddress());
|
||||
nic.setType(pubIp.getTrafficType());
|
||||
String vlanId = pubIp.getVlanId();
|
||||
if (vlanId == null) {
|
||||
nic.setBroadcastType(BroadcastDomainType.Native);
|
||||
} else {
|
||||
nic.setBroadcastType(BroadcastDomainType.Vlan);
|
||||
nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanId));
|
||||
}
|
||||
nic.setName(pubIp.getNetworkName());
|
||||
Network network = getNetwork(conn, nic);
|
||||
// Determine the correct VIF on DomR to SNAT the
|
||||
// IP address with
|
||||
VIF correctVif = getCorrectVif(conn, router, network);
|
||||
|
||||
String args = "vpc_snat.sh " + routerIp;
|
||||
|
||||
args += " -A ";
|
||||
args += " -l ";
|
||||
args += pubIp;
|
||||
|
||||
args += " -c ";
|
||||
args += "eth" + correctVif.getDevice(conn);
|
||||
|
||||
String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
|
||||
if (result == null || result.isEmpty()) {
|
||||
throw new InternalErrorException("Xen plugin \"vpc_snat\" failed.");
|
||||
}
|
||||
return new SetSourceNatAnswer(cmd, true, "success");
|
||||
} catch (Exception e) {
|
||||
String msg = "Ip SNAT failure due to " + e.toString();
|
||||
s_logger.error(msg, e);
|
||||
return new SetSourceNatAnswer(cmd, false, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ lock="biglock"
|
|||
locked=$(getLockFile $lock)
|
||||
if [ "$locked" != "1" ]
|
||||
then
|
||||
exit 1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
usage() {
|
||||
|
|
@ -35,94 +35,27 @@ usage() {
|
|||
}
|
||||
|
||||
remove_routing() {
|
||||
local pubIp=$1
|
||||
logger -t cloud "$(basename $0):Remove routing $pubIp on interface $ethDev"
|
||||
local ipNoMask=$(echo $pubIp | awk -F'/' '{print $1}')
|
||||
local mask=$(echo $pubIp | awk -F'/' '{print $2}')
|
||||
local tableNo=$(echo $ethDev | awk -F'eth' '{print $2}')
|
||||
|
||||
local tableName="Table_$ethDev"
|
||||
local ethMask=$(ip route list scope link dev $ethDev | awk '{print $1}')
|
||||
if [ "$ethMask" == "" ]
|
||||
then
|
||||
# rules and routes will be deleted for the last ip of the interface.
|
||||
sudo ip rule delete fwmark $tableNo table $tableName
|
||||
sudo ip rule delete table $tableName
|
||||
sudo ip route flush table $tableName
|
||||
sudo ip route flush cache
|
||||
logger -t cloud "$(basename $0):Remove routing $pubIp - routes and rules deleted"
|
||||
fi
|
||||
}
|
||||
|
||||
# copy eth0,eth1 and the current public interface
|
||||
copy_routes_from_main() {
|
||||
local tableName=$1
|
||||
|
||||
#get the network masks from the main table
|
||||
local eth0Mask=$(ip route list scope link dev eth0 | awk '{print $1}')
|
||||
local eth1Mask=$(ip route list scope link dev eth1 | awk '{print $1}')
|
||||
local ethMask=$(ip route list scope link dev $ethDev | awk '{print $1}')
|
||||
|
||||
# eth0,eth1 and other know routes will be skipped, so as main routing table will decide the route. This will be useful if the interface is down and up.
|
||||
sudo ip route add throw $eth0Mask table $tableName proto static
|
||||
sudo ip route add throw $eth1Mask table $tableName proto static
|
||||
sudo ip route add throw $ethMask table $tableName proto static
|
||||
return 0;
|
||||
}
|
||||
|
||||
ip_addr_add() {
|
||||
local dev="$1"
|
||||
local ip="$2"
|
||||
}
|
||||
|
||||
add_routing() {
|
||||
local pubIp=$1
|
||||
logger -t cloud "$(basename $0):Add routing $pubIp on interface $ethDev"
|
||||
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
|
||||
local mask=$(echo $1 | awk -F'/' '{print $2}')
|
||||
|
||||
local tableName="Table_$ethDev"
|
||||
local tablePresent=$(grep $tableName /etc/iproute2/rt_tables)
|
||||
local tableNo=$(echo $ethDev | awk -F'eth' '{print $2}')
|
||||
if [ "$tablePresent" == "" ]
|
||||
then
|
||||
if [ "$tableNo" == ""]
|
||||
then
|
||||
return 0;
|
||||
fi
|
||||
sudo echo "$tableNo $tableName" >> /etc/iproute2/rt_tables
|
||||
fi
|
||||
|
||||
copy_routes_from_main $tableName
|
||||
# NOTE: this entry will be deleted if the interface is down without knowing to Management server, in that case all the outside traffic will be send through main routing table or it will be the first public NIC.
|
||||
sudo ip route add $subnet/$mask dev $ethDev table $tableName proto static
|
||||
sudo ip route add default via $defaultGwIP table $tableName proto static
|
||||
sudo ip route flush cache
|
||||
|
||||
local ethMask=$(ip route list scope link dev $ethDev | awk '{print $1}')
|
||||
local rulePresent=$(ip rule show | grep $ethMask)
|
||||
if [ "$rulePresent" == "" ]
|
||||
then
|
||||
# rules will be added while adding the first ip of the interface
|
||||
sudo ip rule add from $ethMask table $tableName
|
||||
sudo ip rule add fwmark $tableNo table $tableName
|
||||
logger -t cloud "$(basename $0):Add routing $pubIp rules added"
|
||||
fi
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
add_an_ip () {
|
||||
local pubIp=$1
|
||||
logger -t cloud "$(basename $0):Adding ip $pubIp on interface $ethDev"
|
||||
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
|
||||
sudo ip link show $ethDev | grep "state DOWN" > /dev/null
|
||||
local old_state=$?
|
||||
|
||||
sudo ip addr add dev $dev $ip
|
||||
sudo ip addr add dev $ethDev $pubIp/$mask
|
||||
if [ $if_keep_state -ne 1 -o $old_state -ne 0 ]
|
||||
then
|
||||
sudo ip link set $ethDev up
|
||||
sudo arping -c 3 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
|
||||
sudo ip link set $ethDev up
|
||||
sudo arping -c 3 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
|
||||
fi
|
||||
add_routing $1
|
||||
return $?
|
||||
|
|
@ -130,48 +63,34 @@ add_an_ip () {
|
|||
}
|
||||
|
||||
remove_an_ip () {
|
||||
local pubIp=$1
|
||||
logger -t cloud "$(basename $0):Removing ip $pubIp on interface $ethDev"
|
||||
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
|
||||
local mask=$(echo $1 | awk -F'/' '{print $2}')
|
||||
local existingIpMask=$(sudo ip addr show dev $ethDev | grep inet | awk '{print $2}' | grep -w $ipNoMask)
|
||||
[ "$existingIpMask" == "" ] && return 0
|
||||
remove_snat $1
|
||||
local existingMask=$(echo $existingIpMask | awk -F'/' '{print $2}')
|
||||
if [ "$existingMask" == "32" ]
|
||||
then
|
||||
sudo ip addr del dev $ethDev $existingIpMask
|
||||
result=$?
|
||||
fi
|
||||
local existingIpMask=$(sudo ip addr show dev $ethDev | grep "inet " | awk '{print $2}')
|
||||
|
||||
if [ "$existingMask" != "32" ]
|
||||
then
|
||||
replaceIpMask=`sudo ip addr show dev $ethDev | grep inet | grep -v $existingIpMask | awk '{print $2}' | sort -t/ -k2 -n|tail -1`
|
||||
sudo ip addr del dev $ethDev $existingIpMask;
|
||||
if [ -n "$replaceIpMask" ]; then
|
||||
sudo ip addr del dev $ethDev $replaceIpMask;
|
||||
replaceIp=`echo $replaceIpMask | awk -F/ '{print $1}'`;
|
||||
ip_addr_add $ethDev $replaceIp/$existingMask
|
||||
fi
|
||||
result=$?
|
||||
fi
|
||||
sudo ip addr del dev $ethDev $pubIp/$mask
|
||||
# reapply IPs in this interface
|
||||
for ipMask in $existingIpMask
|
||||
do
|
||||
if [ "$ipMask" == "$pubIp/$mask" ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
sudo ip addr add dev $ethDev $ipMask
|
||||
done
|
||||
|
||||
if [ $result -gt 0 -a $result -ne 2 ]
|
||||
then
|
||||
remove_routing $1
|
||||
return 1
|
||||
fi
|
||||
remove_routing $1
|
||||
return 0
|
||||
}
|
||||
|
||||
#set -x
|
||||
lflag=
|
||||
cflag=
|
||||
lflag=0
|
||||
cflag=0
|
||||
gflag=0
|
||||
mflag=0
|
||||
nflag=0
|
||||
op=""
|
||||
|
||||
|
||||
while getopts 'sfADa:l:c:g:' OPTION
|
||||
while getopts 'ADl:c:g:' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
A) Aflag=1
|
||||
|
|
@ -181,7 +100,7 @@ do
|
|||
op="-D"
|
||||
;;
|
||||
l) lflag=1
|
||||
publicIp="$OPTARG"
|
||||
pubIp="$OPTARG"
|
||||
;;
|
||||
c) cflag=1
|
||||
ethDev="$OPTARG"
|
||||
|
|
@ -189,6 +108,12 @@ do
|
|||
g) gflag=1
|
||||
defaultGwIP="$OPTARG"
|
||||
;;
|
||||
m) mflag=1
|
||||
mask="$OPTARG"
|
||||
;;
|
||||
n) nflag=1
|
||||
subnet="$OPTARG"
|
||||
;;
|
||||
?) usage
|
||||
unlock_exit 2 $lock $locked
|
||||
;;
|
||||
|
|
@ -198,14 +123,14 @@ done
|
|||
|
||||
if [ "$Aflag$Dflag" != "1" ]
|
||||
then
|
||||
usage
|
||||
unlock_exit 2 $lock $locked
|
||||
usage
|
||||
unlock_exit 2 $lock $locked
|
||||
fi
|
||||
|
||||
if [ "$lflag$cflag" != "11" ]
|
||||
if [ "$lflag$cflag$gflag$mflag$nflag" != "11111" ]
|
||||
then
|
||||
usage
|
||||
unlock_exit 2 $lock $locked
|
||||
usage
|
||||
unlock_exit 2 $lock $locked
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
|
||||
# @VERSION@
|
||||
|
||||
source /root/func.sh
|
||||
|
||||
lock="biglock"
|
||||
locked=$(getLockFile $lock)
|
||||
if [ "$locked" != "1" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
usage() {
|
||||
printf "Usage:\n %s -A -l <public-ip-address>\n" $(basename $0) >&2
|
||||
printf " %s -D -l <public-ip-address>\n" $(basename $0) >&2
|
||||
}
|
||||
|
||||
|
||||
add_snat() {
|
||||
logger -t cloud "$(basename $0):Added SourceNAT $pubIp on interface $ethDev"
|
||||
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $pubIp ;
|
||||
sudo iptables -t nat -A POSTROUTING -j SNAT -o $ethDev --to-source $pubIp ;
|
||||
return $?
|
||||
}
|
||||
remove_snat() {
|
||||
logger -t cloud "$(basename $0):Removing SourceNAT $pubIp on interface $ethDev"
|
||||
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $pubIp;
|
||||
return $?
|
||||
}
|
||||
|
||||
#set -x
|
||||
lflag=0
|
||||
cflag=0
|
||||
op=""
|
||||
|
||||
while getopts 'ADl:c' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
A) Aflag=1
|
||||
op="-A"
|
||||
;;
|
||||
D) Dflag=1
|
||||
op="-D"
|
||||
;;
|
||||
l) lflag=1
|
||||
pubIp="$OPTARG"
|
||||
;;
|
||||
c) cflag=1
|
||||
ethDev="$OPTARG"
|
||||
;;
|
||||
?) usage
|
||||
unlock_exit 2 $lock $locked
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$Aflag$Dflag" != "1" ]
|
||||
then
|
||||
usage
|
||||
unlock_exit 2 $lock $locked
|
||||
fi
|
||||
|
||||
if [ "$lflag$cflag" != "11" ]
|
||||
then
|
||||
usage
|
||||
unlock_exit 2 $lock $locked
|
||||
fi
|
||||
|
||||
if [ "$Aflag" == "1" ]
|
||||
then
|
||||
add_snat $publicIp &&
|
||||
unlock_exit $? $lock $locked
|
||||
fi
|
||||
|
||||
if [ "$Dflag" == "1" ]
|
||||
then
|
||||
remove_sat $publicIp &&
|
||||
unlock_exit $? $lock $locked
|
||||
fi
|
||||
Loading…
Reference in New Issue