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/03 02:44:32 UTC

[6/7] git commit: VPC: set networkId to be null for IP address when the last PF/LB rule is removed for it and the IP belongs to VPC

VPC: set networkId to be null for IP address when the last PF/LB rule is removed for it and the IP belongs to VPC

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/2dc1a286
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/2dc1a286
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/2dc1a286

Branch: refs/heads/vpc
Commit: 2dc1a286f6b1dcbe22e88a41780691ef96fda455
Parents: 8d16d7f
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Fri Jun 29 13:35:44 2012 -0700
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Mon Jul 2 17:44:27 2012 -0700

----------------------------------------------------------------------
 .../network/firewall/FirewallManagerImpl.java      |    5 +-
 .../network/lb/LoadBalancingRulesManagerImpl.java  |   37 +++-
 .../VpcVirtualNetworkApplianceManagerImpl.java     |    9 +
 .../com/cloud/network/rules/FirewallManager.java   |    5 +
 .../com/cloud/network/rules/RulesManagerImpl.java  |  163 +++++++++------
 .../rules/dao/PortForwardingRulesDaoImpl.java      |    3 -
 6 files changed, 148 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2dc1a286/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
index 1c1c882..c414968 100644
--- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
+++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
@@ -425,7 +425,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
     }
 
     @DB
-    protected void removeRule(FirewallRule rule) {
+    @Override
+    public void removeRule(FirewallRule rule) {
         
         Transaction txn = Transaction.currentTxn();
         txn.start();
@@ -527,7 +528,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule);
             }
-            _firewallDao.remove(rule.getId());
+            removeRule(rule);
             generateUsageEvent = true;
         } else if (rule.getState() == State.Add || rule.getState() == State.Active) {
             rule.setState(State.Revoke);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2dc1a286/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index a777d9a..83e79c2 100755
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -675,7 +675,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
             s_logger.warn("Unable to remove firewall rule id=" + lb.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state");
             success = false;
         } else {
-            _firewallDao.remove(lb.getId());
+            _firewallMgr.removeRule(lb);
         }
 
         _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller);
@@ -720,6 +720,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
         }
 
         LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, lbOwner, lb.getNetworkId());
+        boolean performedIpAssoc = false;
         if (result == null) {
             IpAddress ip = null;
             Network guestNetwork = _networkMgr.getNetwork(lb.getNetworkId());
@@ -732,8 +733,13 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
             try {
                 if (ipAddressVO != null) {
                     if (ipAddressVO.getAssociatedWithNetworkId() == null) {
+                      //set networkId just for verification purposes
+                        ipAddressVO.setAssociatedWithNetworkId(lb.getNetworkId());
+                        _networkMgr.checkIpForService(ipAddressVO, Service.Lb);
+                        
                         s_logger.debug("The ip is not associated with the network id="+ lb.getNetworkId() + " so assigning");
                         ipAddressVO = _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId());
+                        boolean perfomedIpAssoc = true;
                     }
                     _networkMgr.checkIpForService(ipAddressVO, Service.Lb);
                 }   
@@ -752,6 +758,15 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
                     s_logger.debug("Releasing system IP address " + ip + " as corresponding lb rule failed to create");
                     _networkMgr.handleSystemIpRelease(ip);
                 }
+                // release ip address if ipassoc was perfored
+                if (performedIpAssoc) {
+                    //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
+                    ip = _ipAddressDao.findById(ip.getId());
+                    if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) {
+                        s_logger.debug("Releasing VPC ip address " + ip + " as LB rule failed to create");
+                        _networkMgr.unassignIPFromVpcNetwork(ip.getId());
+                    }
+                }
             }
         }
 
@@ -771,7 +786,6 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
         long sourceIpId = lb.getSourceIpAddressId();
 
         IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId);
-        Long networkId = ipAddr.getSourceNetworkId();
         // make sure ip address exists
         if (ipAddr == null || !ipAddr.readyToUse()) {
         	InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id specified");
@@ -786,7 +800,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
         _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), 
                 Purpose.LoadBalancing, FirewallRuleType.User);
 
-        networkId = ipAddr.getAssociatedWithNetworkId();
+        Long networkId = ipAddr.getAssociatedWithNetworkId();
         if (networkId == null) {
         	InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network");
         	ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId");            
@@ -842,7 +856,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
 
                 txn.start();
                 _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
-                _lbDao.remove(newRule.getId());
+                removeLBRule(newRule);
 
                 txn.commit();
             }
@@ -897,7 +911,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
                 boolean checkForReleaseElasticIp = false;
                 txn.start();
                 if (lb.getState() == FirewallRule.State.Revoke) {
-                    _lbDao.remove(lb.getId());
+                    removeLBRule(lb);
                     s_logger.debug("LB " + lb.getId() + " is successfully removed");
                     checkForReleaseElasticIp = true;
                 } else if (lb.getState() == FirewallRule.State.Add) {
@@ -1290,4 +1304,17 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
         return _lbDao.findById(lbId);
     }
 
+    @DB
+    protected void removeLBRule(LoadBalancerVO rule) {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        _lbDao.remove(rule.getId());
+        //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
+        IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
+        if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) {
+            _networkMgr.unassignIPFromVpcNetwork(ip.getId());
+        }
+        
+        txn.commit();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2dc1a286/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
index f53ae24..c9ccc41 100644
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@ -310,6 +310,15 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
             NicProfile publicNic = _itMgr.addVmToNetwork(router, publicNetwork, defaultNic);
             //setup public network
             if (publicNic != null) {
+                if (ipAddress.isSourceNat()) {
+                    if (router.getPublicIpAddress() == null) {
+                        DomainRouterVO routerVO = _routerDao.findById(router.getId());
+                        routerVO.setPublicIpAddress(ipAddress.getAddress().toString());
+                        routerVO.setPublicNetmask(ipAddress.getNetmask());
+                        routerVO.setPublicMacAddress(ipAddress.getMacAddress());
+                        _routerDao.update(routerVO.getId(), routerVO);
+                    }
+                }
                 publicNic.setDefaultNic(true);
                 if (ipAddress != null) {
                     IPAddressVO ipVO = _ipAddressDao.findById(ipAddress.getId());

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2dc1a286/server/src/com/cloud/network/rules/FirewallManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/FirewallManager.java b/server/src/com/cloud/network/rules/FirewallManager.java
index abf4403..1f9e0e8 100644
--- a/server/src/com/cloud/network/rules/FirewallManager.java
+++ b/server/src/com/cloud/network/rules/FirewallManager.java
@@ -76,4 +76,9 @@ public interface FirewallManager extends FirewallService {
 
     boolean addSystemFirewallRules(IPAddressVO ip, Account acct);
 
+    /**
+     * @param rule
+     */
+    void removeRule(FirewallRule rule);
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2dc1a286/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 3ce19c7..2e0d14e 100755
--- a/server/src/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java
@@ -173,92 +173,113 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
         
         Long networkId = rule.getNetworkId();
         //associate ip address to network (if needed)
+        boolean performedIpAssoc = false;
         if (ipAddress.getAssociatedWithNetworkId() == null) {
+            //set networkId just for verification purposes
+            ipAddress.setAssociatedWithNetworkId(networkId);
+            _networkMgr.checkIpForService(ipAddress, Service.PortForwarding);
+            
             s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning");
             try {
                 ipAddress = _networkMgr.associateIPToGuestNetwork(ipAddrId, networkId);
+                performedIpAssoc = true;
             } catch (Exception ex) {
                 throw new CloudRuntimeException("Failed to associate ip to network as " +
                         "a part of port forwarding rule creation");
             }
+        } else {
+            _networkMgr.checkIpForService(ipAddress, Service.PortForwarding);
         }
         
-        _networkMgr.checkIpForService(ipAddress, Service.PortForwarding);
-
-        _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), 
-                rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User);
-        
-        Long accountId = ipAddress.getAllocatedToAccountId();
-        Long domainId = ipAddress.getAllocatedInDomainId();
+        try {
+            _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), 
+                    rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User);
 
-        // start port can't be bigger than end port
-        if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) {
-            throw new InvalidParameterValueException("Start port can't be bigger than end port");
-        }
+            Long accountId = ipAddress.getAllocatedToAccountId();
+            Long domainId = ipAddress.getAllocatedInDomainId();
 
-        // check that the port ranges are of equal size
-        if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) {
-            throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes.");
-        }
+            // start port can't be bigger than end port
+            if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) {
+                throw new InvalidParameterValueException("Start port can't be bigger than end port");
+            }
 
-        // validate user VM exists
-        UserVm vm = _vmDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + 
-                    ", invalid virtual machine id specified (" + vmId + ").");
-        } else {
-            checkRuleAndUserVm(rule, vm, caller);
-        }
+            // check that the port ranges are of equal size
+            if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) {
+                throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes.");
+            }
 
+            // validate user VM exists
+            UserVm vm = _vmDao.findById(vmId);
+            if (vm == null) {
+                throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + 
+                        ", invalid virtual machine id specified (" + vmId + ").");
+            } else {
+                checkRuleAndUserVm(rule, vm, caller);
+            }
 
-        // Verify that vm has nic in the network
-        Ip dstIp = rule.getDestinationIpAddress();
-        Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId);
-        if (guestNic == null || guestNic.getIp4Address() == null) {
-            throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
-        } else {
-            dstIp = new Ip(guestNic.getIp4Address());
-        }
 
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
+            // Verify that vm has nic in the network
+            Ip dstIp = rule.getDestinationIpAddress();
+            Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId);
+            if (guestNic == null || guestNic.getIp4Address() == null) {
+                throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
+            } else {
+                dstIp = new Ip(guestNic.getIp4Address());
+            }
 
-        PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), 
-                rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(),
-                rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId);
-        newRule = _portForwardingDao.persist(newRule);
+            Transaction txn = Transaction.currentTxn();
+            txn.start();
 
-        // create firewallRule for 0.0.0.0/0 cidr
-        if (openFirewall) {
-            _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(),
-                    rule.getProtocol(), null, null, newRule.getId(), networkId);
-        }
+            PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), 
+                    rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(),
+                    rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId);
+            newRule = _portForwardingDao.persist(newRule);
 
-        try {
-            _firewallMgr.detectRulesConflict(newRule);
-            if (!_firewallDao.setStateToAdd(newRule)) {
-                throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
+            // create firewallRule for 0.0.0.0/0 cidr
+            if (openFirewall) {
+                _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(),
+                        rule.getProtocol(), null, null, newRule.getId(), networkId);
             }
-            UserContext.current().setEventDetails("Rule Id: " + newRule.getId());
-            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 
-                    ipAddress.getDataCenterId(), newRule.getId(), null);
-            _usageEventDao.persist(usageEvent);
-            txn.commit();
-            return newRule;
-        } catch (Exception e) {
-            if (newRule != null) {
-                txn.start();
-                // no need to apply the rule as it wasn't programmed on the backend yet
-                _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
-                _portForwardingDao.remove(newRule.getId());
+
+            try {
+                _firewallMgr.detectRulesConflict(newRule);
+                if (!_firewallDao.setStateToAdd(newRule)) {
+                    throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
+                }
+                UserContext.current().setEventDetails("Rule Id: " + newRule.getId());
+                UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 
+                        ipAddress.getDataCenterId(), newRule.getId(), null);
+                _usageEventDao.persist(usageEvent);
                 txn.commit();
-            }
+                return newRule;
+            } catch (Exception e) {
+                if (newRule != null) {
+                    txn.start();
+                    // no need to apply the rule as it wasn't programmed on the backend yet
+                    _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
+                    removePFRule(newRule);
+                    txn.commit();
+                }
 
-            if (e instanceof NetworkRuleConflictException) {
-                throw (NetworkRuleConflictException) e;
+                if (e instanceof NetworkRuleConflictException) {
+                    throw (NetworkRuleConflictException) e;
+                }
+                
+                throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e);
+            }
+        } finally {
+            // release ip address if ipassoc was perfored
+            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());
+                }
             }
-            throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e);
         }
+        
+        
     }
 
     @Override
@@ -326,7 +347,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
                 txn.start();
                 // no need to apply the rule as it wasn't programmed on the backend yet
                 _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
-                _portForwardingDao.remove(newRule.getId());
+                _firewallMgr.removeRule(newRule);
                 txn.commit();
             }
 
@@ -1017,7 +1038,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
                 txn.start();
 
                 for (FirewallRuleVO newRule : rules) {
-                    _portForwardingDao.remove(newRule.getId());
+                    _firewallMgr.removeRule(newRule);
                 }
                 txn.commit();
             }
@@ -1271,4 +1292,18 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
             }
         }
     }
+    
+    @DB
+    protected void removePFRule(PortForwardingRuleVO rule) {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        _portForwardingDao.remove(rule.getId());
+        //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
+        IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
+        if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) {
+            _networkMgr.unassignIPFromVpcNetwork(ip.getId());
+        }
+        
+        txn.commit();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2dc1a286/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java
index 2bdaea5..e4fbbb0 100644
--- a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java
+++ b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java
@@ -16,8 +16,6 @@ import java.util.List;
 
 import javax.ejb.Local;
 
-import org.apache.log4j.Logger;
-
 import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
 import com.cloud.network.rules.FirewallRule.Purpose;
 import com.cloud.network.rules.FirewallRule.State;
@@ -30,7 +28,6 @@ import com.cloud.utils.db.SearchCriteria.Op;
 
 @Local(value=PortForwardingRulesDao.class)
 public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRuleVO, Long> implements PortForwardingRulesDao {
-    private static final Logger s_logger = Logger.getLogger(PortForwardingRulesDaoImpl.class);
 
     protected final SearchBuilder<PortForwardingRuleVO> AllFieldsSearch;
     protected final SearchBuilder<PortForwardingRuleVO> ApplicationSearch;