mirror of https://github.com/apache/cloudstack.git
bug 6807: split associateIp into single ip and ip list cases since it is impossible to assure correct operation with previous approach
status 6807: resolved fixed
This commit is contained in:
parent
5b4b25e5d2
commit
a907c1d09f
|
|
@ -42,7 +42,7 @@ public interface IPAddressDao extends GenericDao<IPAddressVO, String> {
|
|||
|
||||
public int countIPs(long dcId, long vlanDbId, boolean onlyCountAllocated);
|
||||
|
||||
public int countIPs(long dcId, String vlanId, String vlanGateway, String vlanNetmask, boolean onlyCountAllocated);
|
||||
public int countIPs(long dcId, Long accountId, String vlanId, String vlanGateway, String vlanNetmask);
|
||||
|
||||
public boolean mark(long dcId, String ip);
|
||||
|
||||
|
|
|
|||
|
|
@ -214,21 +214,19 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, String> implem
|
|||
}
|
||||
|
||||
@Override @DB
|
||||
public int countIPs(long dcId, String vlanId, String vlanGateway, String vlanNetmask, boolean onlyCountAllocated) {
|
||||
public int countIPs(long dcId, Long accountId, String vlanId, String vlanGateway, String vlanNetmask) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
int ipCount = 0;
|
||||
try {
|
||||
String sql = "SELECT count(*) FROM user_ip_address u INNER JOIN vlan v on (u.vlan_db_id = v.id AND v.data_center_id = ? AND v.vlan_id = ? AND v.vlan_gateway = ? AND v.vlan_netmask = ?)";
|
||||
String sql = "SELECT count(*) FROM user_ip_address u INNER JOIN vlan v on (u.vlan_db_id = v.id AND v.data_center_id = ? AND v.vlan_id = ? AND v.vlan_gateway = ? AND v.vlan_netmask = ? AND u.account_id = ?)";
|
||||
|
||||
if (onlyCountAllocated) {
|
||||
sql += " WHERE allocated IS NOT NULL";
|
||||
}
|
||||
|
||||
PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
pstmt.setLong(1, dcId);
|
||||
pstmt.setString(2, vlanId);
|
||||
pstmt.setString(3, vlanGateway);
|
||||
pstmt.setString(4, vlanNetmask);
|
||||
pstmt.setLong(5, accountId);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
|
||||
if (rs.next()) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# ipassoc.sh -- associate/disassociate a public ip with an instance
|
||||
#
|
||||
#
|
||||
# @VERSION@
|
||||
# 2.1.4
|
||||
usage() {
|
||||
printf "Usage:\n %s -A -i <domR eth1 ip> -l <public-ip-address> -r <domr name> [-f] \n" $(basename $0) >&2
|
||||
printf " %s -D -i <domR eth1 ip> -l <public-ip-address> -r <domr name> [-f] \n" $(basename $0) >&2
|
||||
|
|
@ -54,10 +54,11 @@ check_gw() {
|
|||
add_nat_entry() {
|
||||
local dRIp=$1
|
||||
local pubIp=$2
|
||||
local ipNoMask=$(echo $2 | awk -F'/' '{print $1}')
|
||||
ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$dRIp "\
|
||||
ip addr add dev $correctVif $pubIp
|
||||
iptables -t nat -I POSTROUTING -j SNAT -o $correctVif --to-source $pubIp ;
|
||||
/sbin/arping -c 3 -I $correctVif -A -U -s $pubIp $pubIp;
|
||||
iptables -t nat -I POSTROUTING -j SNAT -o $correctVif --to-source $ipNoMask ;
|
||||
/sbin/arping -c 3 -I $correctVif -A -U -s $ipNoMask $ipNoMask;
|
||||
"
|
||||
if [ $? -gt 0 -a $? -ne 2 ]
|
||||
then
|
||||
|
|
@ -71,9 +72,12 @@ add_nat_entry() {
|
|||
del_nat_entry() {
|
||||
local dRIp=$1
|
||||
local pubIp=$2
|
||||
local ipNoMask=$(echo $2 | awk -F'/' '{print $1}')
|
||||
local mask=$(echo $2 | awk -F'/' '{print $2}')
|
||||
[ "$mask" == "" ] && mask="32"
|
||||
ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$dRIp "\
|
||||
iptables -t nat -D POSTROUTING -j SNAT -o $correctVif --to-source $pubIp;
|
||||
ip addr del dev $correctVif $pubIp/32
|
||||
iptables -t nat -D POSTROUTING -j SNAT -o $correctVif --to-source $ipNoMask;
|
||||
ip addr del dev $correctVif "$ipNoMask/$mask"
|
||||
"
|
||||
|
||||
if [ $? -gt 0 -a $? -ne 2 ]
|
||||
|
|
@ -88,10 +92,11 @@ del_nat_entry() {
|
|||
add_an_ip () {
|
||||
local dRIp=$1
|
||||
local pubIp=$2
|
||||
local ipNoMask=$(echo $2 | awk -F'/' '{print $1}')
|
||||
ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$dRIp "\
|
||||
ifconfig $correctVif up;
|
||||
ip addr add dev $correctVif $pubIp ;
|
||||
/sbin/arping -c 3 -I $correctVif -A -U -s $pubIp $pubIp;
|
||||
/sbin/arping -c 3 -I $correctVif -A -U -s $ipNoMask $ipNoMask;
|
||||
"
|
||||
return $?
|
||||
}
|
||||
|
|
@ -99,8 +104,11 @@ add_an_ip () {
|
|||
remove_an_ip () {
|
||||
local dRIp=$1
|
||||
local pubIp=$2
|
||||
local ipNoMask=$(echo $2 | awk -F'/' '{print $1}')
|
||||
local mask=$(echo $2 | awk -F'/' '{print $2}')
|
||||
[ "$mask" == "" ] && mask="32"
|
||||
ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$dRIp "\
|
||||
ip addr del dev $correctVif $pubIp/32
|
||||
ip addr del dev $correctVif "$ipNoMask/$mask"
|
||||
"
|
||||
if [ $? -gt 0 -a $? -ne 2 ]
|
||||
then
|
||||
|
|
|
|||
|
|
@ -174,6 +174,15 @@ public interface NetworkManager extends Manager {
|
|||
*/
|
||||
boolean associateIP(DomainRouterVO router, List<String> ipAddrList, boolean add) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* Associates or disassociates a single IP address for a router.
|
||||
* @param router router object to send the association to
|
||||
* @param ipAddress public IP addresses
|
||||
* @param add true if associate, false if disassociate
|
||||
* @return
|
||||
*/
|
||||
boolean associateIP(DomainRouterVO router, String ipAddress, boolean add) throws ResourceAllocationException;
|
||||
|
||||
boolean updateFirewallRule(FirewallRuleVO fwRule, String oldPrivateIP, String oldPrivatePort);
|
||||
boolean executeAssignToLoadBalancer(AssignToLoadBalancerExecutor executor, LoadBalancerParam param);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
package com.cloud.network;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -97,6 +100,7 @@ import com.cloud.host.Host;
|
|||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.IpAddrAllocator.networkInfo;
|
||||
import com.cloud.network.dao.FirewallRulesDao;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.LoadBalancerDao;
|
||||
|
|
@ -1286,26 +1290,44 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
|
|||
final Command [] cmds = new Command[ipAddrList.size()];
|
||||
int i=0;
|
||||
boolean sourceNat = false;
|
||||
Map<VlanVO, ArrayList<IPAddressVO>> vlanIpMap = new HashMap<VlanVO, ArrayList<IPAddressVO>>();
|
||||
for (final String ipAddress: ipAddrList) {
|
||||
if (ipAddress.equalsIgnoreCase(router.getPublicIpAddress()))
|
||||
sourceNat=true;
|
||||
|
||||
IPAddressVO ip = _ipAddressDao.findById(ipAddress);
|
||||
|
||||
VlanVO vlan = _vlanDao.findById(ip.getVlanDbId());
|
||||
String vlanId = vlan.getVlanId();
|
||||
String vlanGateway = vlan.getVlanGateway();
|
||||
String vlanNetmask = vlan.getVlanNetmask();
|
||||
boolean firstIP = (!sourceNat && (_ipAddressDao.countIPs(vlan.getDataCenterId(), vlan.getVlanId(), vlan.getVlanGateway(), vlan.getVlanNetmask(), true) == 1));
|
||||
|
||||
String vifMacAddress = null;
|
||||
if (firstIP) {
|
||||
String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId());
|
||||
vifMacAddress = macAddresses[1];
|
||||
}
|
||||
ArrayList<IPAddressVO> ipList = vlanIpMap.get(vlan.getId());
|
||||
if (ipList == null) {
|
||||
ipList = new ArrayList<IPAddressVO>();
|
||||
}
|
||||
ipList.add(ip);
|
||||
vlanIpMap.put(vlan, ipList);
|
||||
}
|
||||
for (Map.Entry<VlanVO, ArrayList<IPAddressVO>> vlanAndIp: vlanIpMap.entrySet()) {
|
||||
boolean firstIP = true;
|
||||
ArrayList<IPAddressVO> ipList = vlanAndIp.getValue();
|
||||
Collections.sort(ipList, new Comparator<IPAddressVO>() {
|
||||
@Override
|
||||
public int compare(IPAddressVO o1, IPAddressVO o2) {
|
||||
return o1.getAddress().compareTo(o2.getAddress());
|
||||
} });
|
||||
|
||||
cmds[i++] = new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ipAddress, add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress);
|
||||
|
||||
sourceNat = false;
|
||||
for (final IPAddressVO ip: ipList) {
|
||||
sourceNat = ip.getSourceNat();
|
||||
VlanVO vlan = vlanAndIp.getKey();
|
||||
String vlanId = vlan.getVlanId();
|
||||
String vlanGateway = vlan.getVlanGateway();
|
||||
String vlanNetmask = vlan.getVlanNetmask();
|
||||
|
||||
String vifMacAddress = null;
|
||||
if (firstIP && add) {
|
||||
String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId());
|
||||
vifMacAddress = macAddresses[1];
|
||||
}
|
||||
|
||||
cmds[i++] = new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress);
|
||||
|
||||
firstIP = false;
|
||||
}
|
||||
}
|
||||
|
||||
Answer[] answers = null;
|
||||
|
|
@ -1326,13 +1348,49 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
|
|||
if (answers.length != ipAddrList.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = true;
|
||||
for (int i1=0; i1 < answers.length; i1++) {
|
||||
Answer ans = answers[i1];
|
||||
return ans.getResult();
|
||||
result = result && ans.getResult();
|
||||
}
|
||||
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean associateIP(final DomainRouterVO router, final String ipAddress, final boolean add) {
|
||||
IPAddressVO ip = _ipAddressDao.findById(ipAddress);
|
||||
VlanVO vlan = _vlanDao.findById(ip.getVlanDbId());
|
||||
boolean sourceNat = ip.isSourceNat();
|
||||
boolean firstIP = (!sourceNat && (_ipAddressDao.countIPs(vlan.getDataCenterId(), router.getAccountId(), vlan.getVlanId(), vlan.getVlanGateway(), vlan.getVlanNetmask()) == 1));
|
||||
String vlanId = vlan.getVlanId();
|
||||
String vlanGateway = vlan.getVlanGateway();
|
||||
String vlanNetmask = vlan.getVlanNetmask();
|
||||
String vifMacAddress = null;
|
||||
if (firstIP && add) {
|
||||
String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId());
|
||||
vifMacAddress = macAddresses[1];
|
||||
}
|
||||
IPAssocCommand cmd = new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress);
|
||||
Answer[] answers = null;
|
||||
try {
|
||||
answers = _agentMgr.send(router.getHostId(), new Command[]{cmd}, false);
|
||||
} catch (final AgentUnavailableException e) {
|
||||
s_logger.warn("Agent unavailable", e);
|
||||
return false;
|
||||
} catch (final OperationTimedoutException e) {
|
||||
s_logger.warn("Timed Out", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (answers == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (answers.length != 1) {
|
||||
return false;
|
||||
}
|
||||
return answers[0].getResult();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1645,7 +1703,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager
|
|||
s_logger.debug("Disassociate ip " + router.getName());
|
||||
}
|
||||
|
||||
if (associateIP(router, ipAddrs, false)) {
|
||||
if (associateIP(router, ip.getAddress(), false)) {
|
||||
_ipAddressDao.unassignIpAddress(ipAddress);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
|
|
|||
|
|
@ -1473,7 +1473,6 @@ public class ManagementServerImpl implements ManagementServer {
|
|||
// Associate the IP's to DomR
|
||||
boolean success = true;
|
||||
String params = "\nsourceNat=" + false + "\ndcId=" + zoneId;
|
||||
ArrayList<String> dummyipAddrList = new ArrayList<String>();
|
||||
success = _networkMgr.associateIP(router,ipAddrsList, true);
|
||||
String errorMsg = "Unable to assign public IP address pool";
|
||||
if (!success) {
|
||||
|
|
@ -1557,7 +1556,7 @@ public class ManagementServerImpl implements ManagementServer {
|
|||
ipAddrs.add(ipAddress);
|
||||
|
||||
if (router.getState() == State.Running) {
|
||||
success = _networkMgr.associateIP(router, ipAddrs, true);
|
||||
success = _networkMgr.associateIP(router, ipAddress, true);
|
||||
if (!success) {
|
||||
errorMsg = "Unable to assign public IP address.";
|
||||
}
|
||||
|
|
@ -2415,7 +2414,6 @@ public class ManagementServerImpl implements ManagementServer {
|
|||
_vmInstanceDao.update(started.getId(), updatedInstance);
|
||||
started = _userVmDao.findById(started.getId());
|
||||
}
|
||||
String params = "\nsourceNat=" + false + "\ndcId=" + dc.getId();
|
||||
try {
|
||||
associateIpAddressListToAccount(userId, accountId, dc.getId(),null);
|
||||
} catch (InsufficientAddressCapacityException e) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue