CLOUDSTACK-2700:on network/vpc delete, portable IP should be still
associated with account

Unlike public ip which gets dis-associated (released) with the account
on network/VPC delete, portable IP should continue to be associated with
the account even when the network/VPC with which it is currently
associated in deleted. This fix ensures portable IP are associated to
account even after network/vpc is deleted.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/883333c2
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/883333c2
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/883333c2

Branch: refs/heads/vmware-storage-motion
Commit: 883333c2143e9f3b14a3bc91f8e486e3574dfa37
Parents: ad48c83
Author: Murali Reddy <muralimmre...@gmail.com>
Authored: Mon May 27 18:42:33 2013 +0530
Committer: Murali Reddy <muralimmre...@gmail.com>
Committed: Mon May 27 18:44:41 2013 +0530

----------------------------------------------------------------------
 api/src/com/cloud/network/NetworkService.java      |    2 +-
 server/src/com/cloud/network/NetworkManager.java   |    9 +++---
 .../src/com/cloud/network/NetworkManagerImpl.java  |   20 +++++++++++---
 .../src/com/cloud/network/NetworkServiceImpl.java  |   10 +++++--
 .../com/cloud/network/rules/RulesManagerImpl.java  |   12 ++++----
 .../src/com/cloud/network/vpc/VpcManagerImpl.java  |   15 +++++++++--
 server/src/com/cloud/user/AccountManagerImpl.java  |    8 ++++++
 .../com/cloud/network/MockNetworkManagerImpl.java  |    2 +-
 .../test/com/cloud/vpc/MockNetworkManagerImpl.java |    2 +-
 9 files changed, 56 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/api/src/com/cloud/network/NetworkService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/NetworkService.java 
b/api/src/com/cloud/network/NetworkService.java
index 59702a2..405cecd 100755
--- a/api/src/com/cloud/network/NetworkService.java
+++ b/api/src/com/cloud/network/NetworkService.java
@@ -55,7 +55,7 @@ public interface NetworkService {
     IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, 
Long networkId, Long vpcId) throws ResourceAllocationException,
             InsufficientAddressCapacityException, ConcurrentOperationException;
 
-    boolean releasePortableIpAddress(long ipAddressId) throws 
InsufficientAddressCapacityException;
+    boolean releasePortableIpAddress(long ipAddressId);
 
     Network createGuestNetwork(CreateNetworkCmd cmd) throws 
InsufficientCapacityException, ConcurrentOperationException,
     ResourceAllocationException;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/src/com/cloud/network/NetworkManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManager.java 
b/server/src/com/cloud/network/NetworkManager.java
index 05bc26e..19f396a 100755
--- a/server/src/com/cloud/network/NetworkManager.java
+++ b/server/src/com/cloud/network/NetworkManager.java
@@ -268,6 +268,11 @@ public interface NetworkManager  {
     IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId, 
boolean releaseOnFailure) throws ResourceAllocationException, 
ResourceUnavailableException, 
         InsufficientAddressCapacityException, ConcurrentOperationException;
 
+    IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, 
Long networkId, Long vpcID)
+            throws ConcurrentOperationException, ResourceAllocationException, 
InsufficientAddressCapacityException;
+
+    boolean releasePortableIpAddress(long addrId);
+
     IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long 
networkId, boolean releaseOnFailure) throws ResourceAllocationException, 
ResourceUnavailableException,
             InsufficientAddressCapacityException, ConcurrentOperationException;
 
@@ -362,10 +367,6 @@ public interface NetworkManager  {
        IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, 
long callerId,
                        DataCenter zone) throws ConcurrentOperationException, 
ResourceAllocationException, InsufficientAddressCapacityException;
 
-
-    IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, 
Long networkId, Long vpcID)
-            throws ConcurrentOperationException, ResourceAllocationException, 
InsufficientAddressCapacityException;
-
        Map<String, String> 
finalizeServicesAndProvidersForNetwork(NetworkOffering offering,
                        Long physicalNetworkId);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java 
b/server/src/com/cloud/network/NetworkManagerImpl.java
index d699b2e..b443dca 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -1118,7 +1118,8 @@ public class NetworkManagerImpl extends ManagerBase 
implements NetworkManager, L
     }
 
     @DB
-    private void releasePortableIpAddress(long addrId) {
+    @Override
+    public boolean releasePortableIpAddress(long addrId) {
         Transaction txn = Transaction.currentTxn();
         GlobalLock portableIpLock = 
GlobalLock.getInternLock("PortablePublicIpRange");
 
@@ -1133,12 +1134,13 @@ public class NetworkManagerImpl extends ManagerBase 
implements NetworkManager, L
 
             // removed the provisioned vlan
             VlanVO vlan = _vlanDao.findById(ip.getVlanId());
-            _vlanDao.expunge(vlan.getId());
+            _vlanDao.remove(vlan.getId());
 
             // remove the provisioned public ip address
-            _ipAddressDao.expunge(ip.getId());
+            _ipAddressDao.remove(ip.getId());
 
             txn.commit();
+            return true;
         } finally {
             portableIpLock.releaseRef();
         }
@@ -3537,8 +3539,16 @@ public class NetworkManagerImpl extends ManagerBase 
implements NetworkManager, L
         List<IPAddressVO> ipsToRelease = 
_ipAddressDao.listByAssociatedNetwork(networkId, null);
         for (IPAddressVO ipToRelease : ipsToRelease) {
             if (ipToRelease.getVpcId() == null) {
-                IPAddressVO ip = markIpAsUnavailable(ipToRelease.getId());
-                assert (ip != null) : "Unable to mark the ip address id=" + 
ipToRelease.getId() + " as unavailable.";
+                if (!ipToRelease.isPortable()) {
+                    IPAddressVO ip = markIpAsUnavailable(ipToRelease.getId());
+                    assert (ip != null) : "Unable to mark the ip address id=" 
+ ipToRelease.getId() + " as unavailable.";
+                } else {
+                    // portable IP address are associated with owner, until 
explicitly requested to be disassociated
+                    // so as part of network clean up just break IP 
association with guest network
+                    ipToRelease.setAssociatedWithNetworkId(null);
+                    _ipAddressDao.update(ipToRelease.getId(), ipToRelease);
+                    s_logger.debug("Portable IP address " + ipToRelease + " is 
no longer associated with any network");
+                }
             } else {
                 _vpcMgr.unassignIPFromVpcNetwork(ipToRelease.getId(), 
network.getId());
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java 
b/server/src/com/cloud/network/NetworkServiceImpl.java
index 1533ca9..f880bcc 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -591,8 +591,12 @@ public class NetworkServiceImpl extends ManagerBase 
implements  NetworkService {
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RELEASE, 
eventDescription = "disassociating portable Ip", async = true)
-    public boolean releasePortableIpAddress(long ipAddressId) throws 
InsufficientAddressCapacityException {
-        return releaseIpAddressInternal(ipAddressId);
+    public boolean releasePortableIpAddress(long ipAddressId) {
+        try {
+            return releaseIpAddressInternal(ipAddressId);
+        } catch (Exception e) {
+           return false;
+        }
     }
 
     @Override
@@ -880,7 +884,7 @@ public class NetworkServiceImpl extends ManagerBase 
implements  NetworkService {
         boolean success = _networkMgr.disassociatePublicIpAddress(ipAddressId, 
userId, caller);
 
         if (success) {
-            if (!ipVO.isPortable()) {
+            if (ipVO.isPortable()) {
                 return success;
             }
             Long networkId = ipVO.getAssociatedWithNetworkId();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/src/com/cloud/network/rules/RulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java 
b/server/src/com/cloud/network/rules/RulesManagerImpl.java
index 8834553..3c95cef 100755
--- a/server/src/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java
@@ -490,10 +490,9 @@ public class RulesManagerImpl extends ManagerBase 
implements RulesManager, Rules
                                     "a part of enable static nat");
                             return false;
                         }
-                        performedIpAssoc = true;
                     }  else if (ipAddress.isPortable()) {
-                        s_logger.info("Portable IP " + ipAddress.getUuid() + " 
is not associated with the network, so" +
-                                "associate IP with the network " + networkId);
+                        s_logger.info("Portable IP " + ipAddress.getUuid() + " 
is not associated with the network yet "
+                                + " so associate IP with the network " + 
networkId);
                         try {
                             // check if StaticNat service is enabled in the 
network
                             _networkModel.checkIpForService(ipAddress, 
Service.StaticNat, networkId);
@@ -504,13 +503,12 @@ public class RulesManagerImpl extends ManagerBase 
implements RulesManager, Rules
                             }
 
                             // associate portable IP with guest network
-                            
_networkMgr.associatePortableIPToGuestNetwork(ipId, networkId, false);
+                            ipAddress = 
_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;
                         }
-                        performedIpAssoc = true;
                     }
                 } else  if (ipAddress.getAssociatedWithNetworkId() != 
networkId) {
                     if (ipAddress.isPortable()) {
@@ -520,14 +518,16 @@ public class RulesManagerImpl extends ManagerBase 
implements RulesManager, Rules
                         // check if portable IP can be transferred across the 
networks
                         if 
(_networkMgr.isPortableIpTransferableFromNetwork(ipId, 
ipAddress.getAssociatedWithNetworkId() )) {
                             try {
+                                // transfer the portable IP and refresh IP 
details
                                 _networkMgr.transferPortableIP(ipId, 
ipAddress.getAssociatedWithNetworkId(), networkId);
+                                ipAddress = _ipAddressDao.findById(ipId);
                             } 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" +
+                            throw new InvalidParameterValueException("Portable 
IP: " + ipId + " has associated services " +
                                     "in network " + 
ipAddress.getAssociatedWithNetworkId() + " so can not be transferred to " +
                                     " network " + networkId);
                         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java 
b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 1aab732..15e1539 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -1217,9 +1217,18 @@ public class VpcManagerImpl extends ManagerBase 
implements VpcManager, VpcProvis
         List<IPAddressVO> ipsToRelease = 
_ipAddressDao.listByAssociatedVpc(vpcId, null);
         s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of 
vpc cleanup");
         for (IPAddressVO ipToRelease : ipsToRelease) {
-            success = success && 
_ntwkMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller);
-            if (!success) {
-                s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a 
part of vpc id=" + vpcId + " cleanup");
+            if (ipToRelease.isPortable()) {
+                // portable IP address are associated with owner, until 
explicitly requested to be disassociated.
+                // so as part of VPC clean up just break IP association with 
VPC
+                ipToRelease.setVpcId(null);
+                ipToRelease.setAssociatedWithNetworkId(null);
+                _ipAddressDao.update(ipToRelease.getId(), ipToRelease);
+                s_logger.debug("Portable IP address " + ipToRelease + " is no 
longer associated with any VPC");
+            } else {
+                success = success && 
_ntwkMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller);
+                if (!success) {
+                    s_logger.warn("Failed to cleanup ip " + ipToRelease + " as 
a part of vpc id=" + vpcId + " cleanup");
+                }
             }
         } 
         

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java 
b/server/src/com/cloud/user/AccountManagerImpl.java
index 7421422..e72005e 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -731,6 +731,14 @@ public class AccountManagerImpl extends ManagerBase 
implements AccountManager, M
             _resourceCountDao.removeEntriesByOwner(accountId, 
ResourceOwnerType.Account);
             _resourceLimitDao.removeEntriesByOwner(accountId, 
ResourceOwnerType.Account);
 
+            // release account specific acquired portable IP's. Since all the 
portable IP's must have been already
+            // disassociated with VPC/guest network (due to deletion), so just 
mark portable IP as free.
+            List<? extends IpAddress> portableIpsToRelease = 
_ipAddressDao.listByAccount(accountId);
+            for (IpAddress ip : portableIpsToRelease) {
+                s_logger.debug("Releasing portable ip " + ip + " as a part of 
account id=" + accountId + " cleanup");
+                _networkMgr.releasePortableIpAddress(ip.getId());
+            }
+
             return true;
         } catch (Exception ex) {
             s_logger.warn("Failed to cleanup account " + account + " due to ", 
ex);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/test/com/cloud/network/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java 
b/server/test/com/cloud/network/MockNetworkManagerImpl.java
index e5d34fb..53c0fa8 100755
--- a/server/test/com/cloud/network/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java
@@ -887,7 +887,7 @@ public class MockNetworkManagerImpl extends ManagerBase 
implements NetworkManage
     }
 
     @Override
-    public boolean releasePortableIpAddress(long ipAddressId) throws 
InsufficientAddressCapacityException {
+    public boolean releasePortableIpAddress(long ipAddressId)  {
         return false;// TODO Auto-generated method stub
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/883333c2/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java 
b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index 7129273..a1ece44 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -210,7 +210,7 @@ public class MockNetworkManagerImpl extends ManagerBase 
implements NetworkManage
     }
 
     @Override
-    public boolean releasePortableIpAddress(long ipAddressId) throws 
InsufficientAddressCapacityException {
+    public boolean releasePortableIpAddress(long ipAddressId) {
         return false;// TODO Auto-generated method stub
     }
 

Reply via email to