From 4f058feef231f2dfdedf67fe058936cead05db43 Mon Sep 17 00:00:00 2001 From: Murali reddy Date: Mon, 19 Dec 2011 23:47:11 +0530 Subject: [PATCH] bug 12276: public IP's should be associated with a network service provider depending on the network rules for which IP is used for --- .../element/LoadBalancingServiceProvider.java | 10 +++ .../PortForwardingServiceProvider.java | 10 +++ .../element/SourceNatServiceProvider.java | 15 ++++ .../element/StaticNatServiceProvider.java | 10 +++ .../com/cloud/network/NetworkManagerImpl.java | 77 ++++++++++++++++++- .../element/ElasticLoadBalancerElement.java | 7 ++ .../F5ExternalLoadBalancerElement.java | 7 ++ .../JuniperSRXExternalFirewallElement.java | 16 ++-- .../NetscalerExternalLoadBalancerElement.java | 7 ++ .../network/element/VirtualRouterElement.java | 16 ++++ 10 files changed, 164 insertions(+), 11 deletions(-) diff --git a/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java b/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java index 32b9b4776e9..7d31f3cd7fe 100644 --- a/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java +++ b/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java @@ -4,6 +4,7 @@ import java.util.List; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.PublicIpAddress; import com.cloud.network.lb.LoadBalancingRule; public interface LoadBalancingServiceProvider extends NetworkElement { @@ -15,4 +16,13 @@ public interface LoadBalancingServiceProvider extends NetworkElement { * @throws ResourceUnavailableException */ boolean applyLBRules(Network network, List rules) throws ResourceUnavailableException; + + /** + * Apply ip addresses to this network service provider + * @param network + * @param ipAddress + * @return + * @throws ResourceUnavailableException + */ + boolean applyLoadBalancerIp(Network network, List ipAddress) throws ResourceUnavailableException; } diff --git a/api/src/com/cloud/network/element/PortForwardingServiceProvider.java b/api/src/com/cloud/network/element/PortForwardingServiceProvider.java index bdd6bc01da4..2bcdc8c7fa0 100644 --- a/api/src/com/cloud/network/element/PortForwardingServiceProvider.java +++ b/api/src/com/cloud/network/element/PortForwardingServiceProvider.java @@ -4,6 +4,7 @@ import java.util.List; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.PublicIpAddress; import com.cloud.network.rules.PortForwardingRule; public interface PortForwardingServiceProvider extends NetworkElement { @@ -15,4 +16,13 @@ public interface PortForwardingServiceProvider extends NetworkElement { * @throws ResourceUnavailableException */ boolean applyPFRules(Network network, List rules) throws ResourceUnavailableException; + + /** + * Apply ip addresses to this network service provider + * @param network + * @param ipAddress + * @return + * @throws ResourceUnavailableException + */ + boolean applyIps(Network network, List ipAddress) throws ResourceUnavailableException; } diff --git a/api/src/com/cloud/network/element/SourceNatServiceProvider.java b/api/src/com/cloud/network/element/SourceNatServiceProvider.java index d21e0b660a1..f42c445997c 100644 --- a/api/src/com/cloud/network/element/SourceNatServiceProvider.java +++ b/api/src/com/cloud/network/element/SourceNatServiceProvider.java @@ -1,4 +1,19 @@ package com.cloud.network.element; +import java.util.List; + +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.PublicIpAddress; + public interface SourceNatServiceProvider extends NetworkElement { + + /** + * Apply ip addresses to this network + * @param network + * @param ipAddress + * @return + * @throws ResourceUnavailableException + */ + boolean applyIps(Network network, List ipAddress) throws ResourceUnavailableException; } diff --git a/api/src/com/cloud/network/element/StaticNatServiceProvider.java b/api/src/com/cloud/network/element/StaticNatServiceProvider.java index c73ce2b77c5..c5c0608fe76 100644 --- a/api/src/com/cloud/network/element/StaticNatServiceProvider.java +++ b/api/src/com/cloud/network/element/StaticNatServiceProvider.java @@ -4,6 +4,7 @@ import java.util.List; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.PublicIpAddress; import com.cloud.network.rules.StaticNat; public interface StaticNatServiceProvider extends NetworkElement { @@ -15,4 +16,13 @@ public interface StaticNatServiceProvider extends NetworkElement { * @throws ResourceUnavailableException */ boolean applyStaticNats(Network config, List rules) throws ResourceUnavailableException; + + /** + * Apply ip addresses to this network service provider + * @param network + * @param ipAddress + * @return + * @throws ResourceUnavailableException + */ + boolean applyIps(Network network, List ipAddress) throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 92ea5c8fc39..57bd3cb5768 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -601,8 +601,79 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return success; } + protected boolean applyProviderIpAssociations(Network network, Purpose purpose, boolean continueOnError, List rules) throws ResourceUnavailableException { + boolean success = true; + + List publicIps = new ArrayList(); + for (FirewallRule rule : rules) { + IPAddressVO lbIp = _ipAddressDao.findById(rule.getSourceIpAddressId()); + PublicIp publicIp = new PublicIp(lbIp, _vlanDao.findById(lbIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(lbIp.getMacAddress())); + publicIps.add(publicIp); + } + + for (NetworkElement ne : _networkElements) { + try { + boolean handled; + switch (purpose) { + case LoadBalancing: + if (!(ne instanceof LoadBalancingServiceProvider)) { + continue; + } + LoadBalancingServiceProvider lbProvider = (LoadBalancingServiceProvider) ne; + s_logger.trace("Asking " + ne + " to apply ip associations for " + purpose.toString() + " purpose"); + handled = lbProvider.applyLoadBalancerIp(network, publicIps); + break; + + case PortForwarding: + if (!(ne instanceof PortForwardingServiceProvider)) { + continue; + } + PortForwardingServiceProvider pfProvider = (PortForwardingServiceProvider) ne; + s_logger.trace("Asking " + ne + " to apply ip associations for " + purpose.toString() + " purpose"); + handled = pfProvider.applyIps(network, publicIps); + break; + + case StaticNat: + case Firewall: + if (!(ne instanceof FirewallServiceProvider)) { + continue; + } + s_logger.trace("Asking " + ne + " to apply ip associations for " + purpose.toString() + " purpose"); + FirewallServiceProvider fwProvider = (FirewallServiceProvider) ne; + handled = fwProvider.applyIps(network, publicIps); + break; + + default: + s_logger.debug("Unable to handle IP association for purpose: " + purpose.toString()); + handled = false; + } + s_logger.debug("Network Rules for network " + network.getId() + " were " + (handled ? "" : " not") + " handled by " + ne.getName()); + } catch (ResourceUnavailableException e) { + success = false; + if (!continueOnError) { + throw e; + } else { + s_logger.debug("Resource is not available: " + ne.getName(), e); + } + } + } + return success; + } + protected boolean applyIpAssociations(Network network, boolean continueOnError, List publicIps) throws ResourceUnavailableException { boolean success = true; + List srcNatpublicIps = new ArrayList(); + + // apply IP only for source NAT public IP at this point. Depending on the network service for which + // public IP will be used do IP Association to respective network service provider before apply rules + if (publicIps != null && !publicIps.isEmpty()) { + for (PublicIp ip : publicIps) { + if (ip.isSourceNat()) { + srcNatpublicIps.add(ip); + } + } + } + for (NetworkElement element : _networkElements) { try { if (!(element instanceof FirewallServiceProvider)) { @@ -610,7 +681,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } FirewallServiceProvider e = (FirewallServiceProvider)element; s_logger.trace("Asking " + element + " to apply ip associations"); - e.applyIps(network, publicIps); + e.applyIps(network, srcNatpublicIps); } catch (ResourceUnavailableException e) { success = false; if (!continueOnError) { @@ -2583,6 +2654,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean success = true; Network network = _networksDao.findById(rules.get(0).getNetworkId()); Purpose purpose = rules.get(0).getPurpose(); + + // associate the IP with corresponding network service provider + applyProviderIpAssociations(network, purpose, continueOnError, rules); + for (NetworkElement ne : _networkElements) { try { boolean handled; diff --git a/server/src/com/cloud/network/element/ElasticLoadBalancerElement.java b/server/src/com/cloud/network/element/ElasticLoadBalancerElement.java index cbb429a4465..3fc8f11bbb4 100644 --- a/server/src/com/cloud/network/element/ElasticLoadBalancerElement.java +++ b/server/src/com/cloud/network/element/ElasticLoadBalancerElement.java @@ -39,6 +39,7 @@ import com.cloud.network.Network.Service; import com.cloud.network.NetworkManager; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.NetworkDao; import com.cloud.network.lb.ElasticLoadBalancerManager; import com.cloud.network.lb.LoadBalancingRule; @@ -179,4 +180,10 @@ public class ElasticLoadBalancerElement extends AdapterBase implements LoadBalan public boolean verifyServicesCombination(List services) { return true; } + + @Override + public boolean applyLoadBalancerIp(Network network, List ipAddress) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java b/server/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java index 6f58a9a3b4b..68567f88dbc 100644 --- a/server/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java +++ b/server/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java @@ -66,6 +66,7 @@ import com.cloud.network.NetworkManager; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkVO; +import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkExternalLoadBalancerDao; @@ -440,4 +441,10 @@ public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceMan public boolean verifyServicesCombination(List services) { return true; } + + @Override + public boolean applyLoadBalancerIp(Network network, List ipAddress) throws ResourceUnavailableException { + // return true, as IP will be associated as part of LB rule configuration + return true; + } } diff --git a/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java b/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java index c70f2280b85..17daa651b69 100644 --- a/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java +++ b/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java @@ -175,16 +175,6 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan return true; } - @Override - public boolean applyIps(Network network, List ipAddresses) throws ResourceUnavailableException { - if (!canHandle(network)) { - return false; - } - - return applyIps(network, ipAddresses); - } - - @Override public boolean applyFWRules(Network config, List rules) throws ResourceUnavailableException { if (!canHandle(config)) { @@ -505,4 +495,10 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan public boolean verifyServicesCombination(List services) { return true; } + + @Override + public boolean applyIps(Network network, List ipAddress) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } } \ No newline at end of file diff --git a/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java b/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java index 06c638461d4..a87e9a98327 100644 --- a/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java +++ b/server/src/com/cloud/network/element/NetscalerExternalLoadBalancerElement.java @@ -64,6 +64,7 @@ import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkVO; +import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkExternalLoadBalancerDao; @@ -465,4 +466,10 @@ public class NetscalerExternalLoadBalancerElement extends ExternalLoadBalancerDe public boolean verifyServicesCombination(List services) { return true; } + + @Override + public boolean applyLoadBalancerIp(Network network, List ipAddress) throws ResourceUnavailableException { + // return true, as IP will be associated as part of LB rule configuration + return true; + } } \ No newline at end of file diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 024a8097fc4..57a3ce0f2d4 100644 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -270,6 +270,21 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } } + @Override + public boolean applyLoadBalancerIp(Network network, List ipAddress) throws ResourceUnavailableException { + if (canHandle(network, Service.Lb)) { + List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); + if (routers == null || routers.isEmpty()) { + s_logger.debug("Virtual router element doesn't need to associate load balancer ip addresses on the backend; virtual router doesn't exist in the network " + network.getId()); + return true; + } + + return _routerMgr.associateIP(network, ipAddress, routers); + } else { + return false; + } + } + @Override public Provider getProvider() { return Provider.VirtualRouter; @@ -644,4 +659,5 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } return true; } + }