From 895a27c2771dbb497ecc6fe0d212589f012a48d8 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Mon, 13 May 2013 15:12:19 +0530 Subject: [PATCH] - establish model for transferring portable IP association from a network with which it is associated to another network. - enabling static nat api, extended to transfer potrtable IP across the networks if the VM/network is different from the current associate network of the portable ip --- .../command/user/nat/EnableStaticNatCmd.java | 5 +++ .../src/com/cloud/network/NetworkManager.java | 2 ++ .../com/cloud/network/NetworkManagerImpl.java | 27 +++++++++++++++ .../cloud/network/rules/RulesManagerImpl.java | 33 +++++++++++++++++++ .../cloud/network/MockNetworkManagerImpl.java | 5 +++ .../com/cloud/vpc/MockNetworkManagerImpl.java | 5 +++ 6 files changed, 77 insertions(+) diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java b/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java index 902dbae00aa..f78e5447aa0 100644 --- a/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java @@ -91,6 +91,11 @@ public class EnableStaticNatCmd extends BaseCmd{ } else { ntwkId = networkId; } + + if (ip.isPortable() && networkId!= null ) { + ntwkId = networkId; + } + if (ntwkId == null) { throw new InvalidParameterValueException("Unable to enable static nat for the ipAddress id=" + ipAddressId + " as ip is not associated with any network and no networkId is passed in"); diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 2bb40c84321..9a11a3fa622 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -245,6 +245,8 @@ public interface NetworkManager { IPAddressVO disassociatePortableIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException; + boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId); + /** * @param network * @param provider diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index cac6bf20421..aaade3ca76d 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -989,6 +989,33 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } } + @Override + public boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId) { + Network network = _networksDao.findById(networkId); + if (network == null) { + throw new InvalidParameterValueException("Invalid network id is given"); + } + + IPAddressVO ip = _ipAddressDao.findById(ipAddrId); + if (ip == null) { + throw new InvalidParameterValueException("Invalid network id is given"); + } + + // Check if IP has any services (rules) associated in the network + List ipList = new ArrayList(); + PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId())); + ipList.add(publicIp); + Map> ipToServices = _networkModel.getIpToServices(ipList, false, true); + if (ipToServices != null & !ipToServices.isEmpty()) { + Set ipServices = ipToServices.get(publicIp); + if (ipServices != null && !ipServices.isEmpty()) { + return false; + } + } + + return true; + } + @Override @DB public boolean disassociatePublicIpAddress(long addrId, long userId, Account caller) { diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index c9b47b44bab..1c24ee50a78 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -492,6 +492,39 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules } performedIpAssoc = true; } + + if (ipAddress.isPortable()) { + s_logger.info("Portable IP " + ipAddress.getUuid() + " is not associated with the network, so" + + "associated IP with the network " + network.getUuid()); + try { + _networkMgr.associatePortableIPToGuestNetwork(ipId, networkId, false); + } catch (Exception e) { + s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " + + "a part of enable static nat"); + return false; + } + } + } else if (ipAddress.getAssociatedWithNetworkId() != networkId) { + if (ipAddress.isPortable()) { + // check if portable IP can transferred across the network + if (_networkMgr.isPortableIpTransferableFromNetwork(ipId, ipAddress.getAssociatedWithNetworkId() )) { + try { + _networkMgr.disassociatePortableIPToGuestNetwork(ipId, ipAddress.getAssociatedWithNetworkId()); + _networkMgr.associatePortableIPToGuestNetwork(ipId, networkId, false); + } catch (Exception e) { + s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " + + "a part of enable static nat"); + return false; + } + } else { + throw new InvalidParameterValueException("Portable IP: " + ipId + " has associated services" + + "in network " + ipAddress.getAssociatedWithNetworkId() + " so can not be transferred to " + + " network " + networkId); + } + } else { + throw new InvalidParameterValueException("Invalid network Id=" + networkId + " IP is associated with" + + " a different network than passed network id"); + } } else { _networkModel.checkIpForService(ipAddress, Service.StaticNat, null); } diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index c5210580952..29493b0dce4 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -97,6 +97,11 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage return null; // TODO Auto-generated method stub } + @Override + public boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId) { + return false; + } + @Override public boolean releaseIpAddress(long ipAddressId) { // TODO Auto-generated method stub diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index c7700004490..345106c2196 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -213,6 +213,11 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage return false;// TODO Auto-generated method stub } + @Override + public boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId) { + return false; + } + /* (non-Javadoc) * @see com.cloud.network.NetworkService#releaseIpAddress(long) */