You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by al...@apache.org on 2012/07/13 22:34:34 UTC

[3/11] git commit: VPC: CS-15569/CS-15568 - release ip address from VPC when fail to enable static nat

VPC: CS-15569/CS-15568 - release ip address from VPC when fail to enable static nat

Conflicts:

	server/src/com/cloud/network/rules/RulesManagerImpl.java


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

Branch: refs/heads/vpc
Commit: d48d4c24e7d6d781c1d478072bc9ebd5c578ae3a
Parents: ad80f42
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Fri Jul 13 10:32:02 2012 -0700
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Fri Jul 13 13:34:19 2012 -0700

----------------------------------------------------------------------
 .../com/cloud/network/rules/RulesManagerImpl.java  |  154 ++++++++-------
 1 files changed, 86 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/d48d4c24/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 5f3d58a..da312fc 100755
--- a/server/src/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java
@@ -376,7 +376,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
     }
 
     @Override
-    public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException {
+    @DB
+    public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm) 
+            throws NetworkRuleConflictException, ResourceUnavailableException {
         UserContext ctx = UserContext.current();
         Account caller = ctx.getCaller();
 
@@ -386,84 +388,100 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
         if (ipAddress == null) {
             throw new InvalidParameterValueException("Unable to find ip address by id " + ipId);
         }
-        
-        boolean setNetworkId = false;
-        Network network = _networkMgr.getNetwork(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Unable to find network by id");
-        }
-        
-        if (!isSystemVm) {
-            UserVmVO vm = _vmDao.findById(vmId);
-            if (vm == null) {
-                throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + 
-                        ", invalid virtual machine id specified (" + vmId + ").");
-            }
-            //associate ip address to network (if needed)
-            if (ipAddress.getAssociatedWithNetworkId() == null) {
-                boolean assignToVpcNtwk = network.getVpcId() != null 
-                        && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
-                if (assignToVpcNtwk) {
-                    _networkMgr.checkIpForService(ipAddress, Service.StaticNat, networkId);
-                    
-                    s_logger.debug("The ip is not associated with the VPC network id="+ networkId + ", so assigning");
-                    try {
-                        ipAddress = _networkMgr.associateIPToGuestNetwork(ipId, networkId);
-                    } catch (Exception ex) {
-                        s_logger.warn("Failed to associate ip id=" + ipId + " to VPC network id=" + networkId + " as " +
-                                "a part of enable static nat");
-                        return false;
-                    }
-                    setNetworkId = true;
-                }
-            } else {
-                _networkMgr.checkIpForService(ipAddress, Service.StaticNat, null);
+
+        // Verify input parameters
+        boolean performedIpAssoc = false;
+        boolean result = false;
+        try {
+            Network network = _networkMgr.getNetwork(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Unable to find network by id");
             }
             
-            
-            if (ipAddress.getAssociatedWithNetworkId() == null) { 
-                throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
+            // Check that vm has a nic in the network
+            Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId);
+            if (guestNic == null) {
+                throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
             }
 
-            // Check permissions
-            checkIpAndUserVm(ipAddress, vm, caller);
-        }
-
-        // Check that vm has a nic in the network
-        Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId);
-        if (guestNic == null) {
-            throw new InvalidParameterValueException("Vm doesn't belong to the network " + networkId);
-        }
-
-        if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
-            throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " +
-            		"supported in network id=" + networkId);
-        }
-
-        // Verify ip address parameter
-        isIpReadyForStaticNat(vmId, ipAddress, caller, ctx.getCallerUserId());
-        ipAddress.setOneToOneNat(true);
-        ipAddress.setAssociatedWithVmId(vmId);
+            
+            if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
+                throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " +
+                        "supported in network with specified id");
+            }
+ 
+            if (!isSystemVm) {
+                UserVmVO vm = _vmDao.findById(vmId);
+                if (vm == null) {
+                    throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + 
+                            ", invalid virtual machine id specified (" + vmId + ").");
+                }
+                //associate ip address to network (if needed)
+                if (ipAddress.getAssociatedWithNetworkId() == null) {
+                    boolean assignToVpcNtwk = network.getVpcId() != null 
+                            && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
+                    if (assignToVpcNtwk) {
+                        _networkMgr.checkIpForService(ipAddress, Service.StaticNat, networkId);
+                        
+                        s_logger.debug("The ip is not associated with the VPC network id="+ networkId + ", so assigning");
+                        try {
+                            ipAddress = _networkMgr.associateIPToGuestNetwork(ipId, networkId);
+                        } catch (Exception ex) {
+                            s_logger.warn("Failed to associate ip id=" + ipId + " to VPC network id=" + networkId + " as " +
+                                    "a part of enable static nat");
+                            return false;
+                        }
+                        performedIpAssoc = true;
+                    }
+                } else {
+                    _networkMgr.checkIpForService(ipAddress, Service.StaticNat, null);
+                }
+                
+                if (ipAddress.getAssociatedWithNetworkId() == null) { 
+                    throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
+                }
 
-        if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
-            // enable static nat on the backend
-            s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
-            if (applyStaticNatForIp(ipId, false, caller, false)) {
-                return true;
+                // Check permissions
+                checkIpAndUserVm(ipAddress, vm, caller);
+                
+                // Verify ip address parameter
+                isIpReadyForStaticNat(vmId, ipAddress, caller, ctx.getCallerUserId());
+            }
+            
+            ipAddress.setOneToOneNat(true);
+            ipAddress.setAssociatedWithVmId(vmId);
+
+            if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
+                // enable static nat on the backend
+                s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
+                if (applyStaticNatForIp(ipId, false, caller, false)) {
+                    result = true;
+                } else {
+                    s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
+                }
             } else {
+                s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
+                
+            }
+        } finally {
+            if (!result) {
+                Transaction txn = Transaction.currentTxn();
+                txn.start();
                 ipAddress.setOneToOneNat(false);
                 ipAddress.setAssociatedWithVmId(null);
-                if (setNetworkId) {
-                    ipAddress.setAssociatedWithNetworkId(null);
-                }
                 _ipAddressDao.update(ipAddress.getId(), ipAddress);
-                s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
-                return false;
+                if (performedIpAssoc) {
+                    //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
+                    IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
+                    if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) {
+                        s_logger.debug("Releasing VPC ip address " + ip + " as PF rule failed to create");
+                        _networkMgr.unassignIPFromVpcNetwork(ip.getId());
+                    }
+                } 
+                txn.commit();
             }
-        } else {
-            s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
-            return false;
         }
+        return result;
     }
 
     protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId)