mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
bug 12656: Refactor IP associate process
Introduce the concept of Ip Deployer. The IP deployer would be responible for apply IP to the element. Most element's IP deployer is itself, but it can be someone else if we want to implement inline mode in the future.
This commit is contained in:
parent
5e60228d2b
commit
ba23973d53
@ -4,7 +4,6 @@ import java.util.List;
|
||||
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
|
||||
public interface FirewallServiceProvider extends NetworkElement {
|
||||
@ -16,13 +15,4 @@ public interface FirewallServiceProvider extends NetworkElement {
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyFWRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* Apply ip addresses to this network
|
||||
* @param network
|
||||
* @param ipAddress
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException;
|
||||
}
|
||||
|
||||
20
api/src/com/cloud/network/element/IpDeployer.java
Normal file
20
api/src/com/cloud/network/element/IpDeployer.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.cloud.network.element;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
|
||||
public interface IpDeployer {
|
||||
/**
|
||||
* Apply ip addresses to this network
|
||||
* @param network
|
||||
* @param ipAddress
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> services) throws ResourceUnavailableException;
|
||||
}
|
||||
@ -4,7 +4,6 @@ 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 {
|
||||
@ -17,12 +16,5 @@ public interface LoadBalancingServiceProvider extends NetworkElement {
|
||||
*/
|
||||
boolean applyLBRules(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* Apply ip addresses to this network service provider
|
||||
* @param network
|
||||
* @param ipAddress
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyLoadBalancerIp(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException;
|
||||
IpDeployer getIpDeployer(Network network);
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ 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 {
|
||||
@ -17,12 +16,5 @@ public interface PortForwardingServiceProvider extends NetworkElement {
|
||||
*/
|
||||
boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* Apply ip addresses to this network service provider
|
||||
* @param network
|
||||
* @param ipAddress
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException;
|
||||
IpDeployer getIpDeployer(Network network);
|
||||
}
|
||||
|
||||
@ -13,4 +13,6 @@ public interface RemoteAccessVPNServiceProvider extends NetworkElement {
|
||||
boolean startVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
|
||||
|
||||
boolean stopVpn(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException;
|
||||
|
||||
IpDeployer getIpDeployer(Network network);
|
||||
}
|
||||
|
||||
@ -1,19 +1,7 @@
|
||||
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<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException;
|
||||
IpDeployer getIpDeployer(Network network);
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ 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 {
|
||||
@ -17,12 +16,5 @@ public interface StaticNatServiceProvider extends NetworkElement {
|
||||
*/
|
||||
boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* Apply ip addresses to this network service provider
|
||||
* @param network
|
||||
* @param ipAddress
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException;
|
||||
IpDeployer getIpDeployer(Network network);
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
*/
|
||||
package com.cloud.network;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -264,4 +265,8 @@ public interface NetworkManager extends NetworkService {
|
||||
List<Service> listNetworkOfferingServices(long networkOfferingId);
|
||||
|
||||
boolean areServicesEnabledInZone(long zoneId, long networkOfferingId, String tags, List<Service> services);
|
||||
|
||||
public Map<PublicIp, Set<Service>> getIpToServices(Network network, List<PublicIp> publicIps, boolean rulesRevoked);
|
||||
|
||||
public Map<Provider, ArrayList<PublicIp>> getProviderToIpList(Network network, Map<PublicIp, Set<Service>> ipToServices);
|
||||
}
|
||||
|
||||
@ -126,10 +126,12 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
|
||||
import com.cloud.network.element.DhcpServiceProvider;
|
||||
import com.cloud.network.element.FirewallServiceProvider;
|
||||
import com.cloud.network.element.IpDeployer;
|
||||
import com.cloud.network.element.LoadBalancingServiceProvider;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.PortForwardingServiceProvider;
|
||||
import com.cloud.network.element.RemoteAccessVPNServiceProvider;
|
||||
import com.cloud.network.element.SourceNatServiceProvider;
|
||||
import com.cloud.network.element.StaticNatServiceProvider;
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.network.element.VirtualRouterElement;
|
||||
@ -310,7 +312,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
private static HashMap<Service, List<Provider>> s_serviceToImplementedProvidersMap = new HashMap<Service, List<Provider>>();
|
||||
private static HashMap<String, String> s_providerToNetworkElementMap = new HashMap<String, String>();
|
||||
|
||||
private NetworkElement getElementImplementingProvider(String providerName){
|
||||
public NetworkElement getElementImplementingProvider(String providerName){
|
||||
String elementName = s_providerToNetworkElementMap.get(providerName);
|
||||
NetworkElement element = _networkElements.get(elementName);
|
||||
return element;
|
||||
@ -603,104 +605,218 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
return success;
|
||||
}
|
||||
|
||||
protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List<PublicIp> publicIps) throws ResourceUnavailableException {
|
||||
boolean success = true;
|
||||
List<PublicIp> firewallPublicIps = new ArrayList<PublicIp>();
|
||||
List<PublicIp> loadbalncerPublicIps = new ArrayList<PublicIp>();
|
||||
private Map<Provider, Set<Service>> getProviderServiceMap(long networkId) {
|
||||
Map<Provider, Set<Service>> map = new HashMap<Provider, Set<Service>>();
|
||||
List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
|
||||
for (NetworkServiceMapVO nsm : nsms) {
|
||||
Set<Service> services = map.get(Provider.getProvider(nsm.getProvider()));
|
||||
if (services == null) {
|
||||
services = new HashSet<Service>();
|
||||
}
|
||||
services.add(Service.getService(nsm.getService()));
|
||||
map.put(Provider.getProvider(nsm.getProvider()), services);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map<Service, Set<Provider>> getServiceProviderMap(long networkId) {
|
||||
Map<Service, Set<Provider>> map = new HashMap<Service, Set<Provider>>();
|
||||
List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
|
||||
for (NetworkServiceMapVO nsm : nsms) {
|
||||
Set<Provider> providers = map.get(Service.getService(nsm.getService()));
|
||||
if (providers == null) {
|
||||
providers = new HashSet<Provider>();
|
||||
}
|
||||
providers.add(Provider.getProvider(nsm.getProvider()));
|
||||
map.put(Service.getService(nsm.getService()), providers);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/* Get a list of IPs, classify them by service */
|
||||
@Override
|
||||
public Map<PublicIp, Set<Service>> getIpToServices(Network network, List<PublicIp> publicIps, boolean rulesRevoked) {
|
||||
Map<PublicIp, Set<Service>> ipToServices = new HashMap<PublicIp, Set<Service>>();
|
||||
|
||||
if (publicIps != null && !publicIps.isEmpty()) {
|
||||
boolean gotSNAT = false;
|
||||
for (PublicIp ip : publicIps) {
|
||||
Set<Service> services = ipToServices.get(ip);
|
||||
if (services == null) {
|
||||
services = new HashSet<Service>();
|
||||
}
|
||||
if (ip.isSourceNat()) {
|
||||
// Source nat ip address should always be sent first
|
||||
firewallPublicIps.add(0, ip);
|
||||
} else if (ip.isOneToOneNat()) {
|
||||
firewallPublicIps.add(ip);
|
||||
} else {
|
||||
//if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service provider
|
||||
if (ip.getState() == State.Allocating) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if any active rules are applied on the public IP
|
||||
Purpose purpose = getPublicIpPurpose(ip, false);
|
||||
if (purpose == null) {
|
||||
// since no active rules are there check if any rules are applied on the public IP but are in revoking state
|
||||
purpose = getPublicIpPurpose(ip, true);
|
||||
if (purpose == null) {
|
||||
// IP is not being used for any purpose so skip IPAssoc to network service provider
|
||||
continue;
|
||||
} else {
|
||||
if (rulesRevoked) {
|
||||
// no active rules/revoked rules are associated with this public IP, so remove the association with the provider
|
||||
ip.setState(State.Releasing);
|
||||
} else {
|
||||
if (ip.getState() == State.Releasing) {
|
||||
// rules are not revoked yet, so don't let the network service provider revoke the IP association
|
||||
// mark IP is allocated so that IP association will not be removed from the provider
|
||||
ip.setState(State.Allocated);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!gotSNAT) {
|
||||
services.add(Service.SourceNat);
|
||||
gotSNAT = true;
|
||||
} else {
|
||||
//TODO throw proper exception
|
||||
throw new CloudRuntimeException("Multiply generic source NAT IPs in network " + network.getId() + "!");
|
||||
}
|
||||
}
|
||||
ipToServices.put(ip, services);
|
||||
|
||||
//if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service provider
|
||||
if (ip.getState() == State.Allocating) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(purpose) {
|
||||
case LoadBalancing:
|
||||
loadbalncerPublicIps.add(ip);
|
||||
break;
|
||||
|
||||
case PortForwarding:
|
||||
case StaticNat:
|
||||
case Firewall:
|
||||
firewallPublicIps.add(ip);
|
||||
break;
|
||||
default:
|
||||
// check if any active rules are applied on the public IP
|
||||
Set<Purpose> purposes = getPublicIpPurposeInRules(ip, false);
|
||||
if (purposes == null || purposes.isEmpty()) {
|
||||
// since no active rules are there check if any rules are applied on the public IP but are in revoking state
|
||||
purposes = getPublicIpPurposeInRules(ip, true);
|
||||
if (purposes == null || purposes.isEmpty()) {
|
||||
// IP is not being used for any purpose so skip IPAssoc to network service provider
|
||||
continue;
|
||||
} else {
|
||||
if (rulesRevoked) {
|
||||
// no active rules/revoked rules are associated with this public IP, so remove the association with the provider
|
||||
ip.setState(State.Releasing);
|
||||
} else {
|
||||
if (ip.getState() == State.Releasing) {
|
||||
// rules are not revoked yet, so don't let the network service provider revoke the IP association
|
||||
// mark IP is allocated so that IP association will not be removed from the provider
|
||||
ip.setState(State.Allocated);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (purposes.contains(Purpose.StaticNat)) {
|
||||
services.add(Service.StaticNat);
|
||||
}
|
||||
if (purposes.contains(Purpose.LoadBalancing)) {
|
||||
services.add(Service.Lb);
|
||||
}
|
||||
if (purposes.contains(Purpose.PortForwarding)) {
|
||||
services.add(Service.PortForwarding);
|
||||
}
|
||||
if (purposes.contains(Purpose.Vpn)) {
|
||||
services.add(Service.Vpn);
|
||||
}
|
||||
if (services.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
ipToServices.put(ip, services);
|
||||
}
|
||||
}
|
||||
return ipToServices;
|
||||
}
|
||||
|
||||
public boolean canIpUsedForService(Network network, PublicIp ip, Service service) {
|
||||
// We need to check if it's non-conserve mode, then the new ip should not be used by any other services
|
||||
NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
if (offering.isConserveMode()) {
|
||||
List<PublicIp> ipList = new ArrayList<PublicIp>();
|
||||
ipList.add(ip);
|
||||
Map<PublicIp, Set<Service>> ipToServices = getIpToServices(network, ipList, false);
|
||||
Set<Service> currentServices = ipToServices.get(ip);
|
||||
// Not used currently, safe
|
||||
if (currentServices == null || currentServices.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Map<Service, Set<Provider>> serviceToProviders = getServiceProviderMap(network.getId());
|
||||
Set<Provider> currentProviders = serviceToProviders.get(service);
|
||||
if (currentProviders.size() > 1) {
|
||||
throw new CloudRuntimeException("Can't support multiply providers for same service now!");
|
||||
}
|
||||
Provider currentProvider = (Provider)currentProviders.toArray()[0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return a mapping between NetworkElement in the network and the IP they should applied */
|
||||
@Override
|
||||
public Map<Provider, ArrayList<PublicIp>> getProviderToIpList(Network network, Map<PublicIp, Set<Service>> ipToServices) {
|
||||
NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
if (!offering.isConserveMode()) {
|
||||
for (PublicIp ip : ipToServices.keySet()) {
|
||||
Set<Service> services = ipToServices.get(ip);
|
||||
if (services != null && services.size() > 1) {
|
||||
//TODO throw proper exception
|
||||
throw new CloudRuntimeException("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String lbProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Lb);
|
||||
String fwProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Firewall);
|
||||
|
||||
for (NetworkElement element : _networkElements) {
|
||||
try {
|
||||
if (element instanceof FirewallServiceProvider && element instanceof LoadBalancingServiceProvider) {
|
||||
List<PublicIp> allIps = new ArrayList<PublicIp>();
|
||||
|
||||
if (lbProvider.equalsIgnoreCase(element.getProvider().getName()) && fwProvider.equalsIgnoreCase(element.getProvider().getName())) {
|
||||
allIps.addAll(firewallPublicIps);
|
||||
allIps.addAll(loadbalncerPublicIps);
|
||||
} else if (fwProvider.equalsIgnoreCase(element.getProvider().getName())) {
|
||||
allIps.addAll(firewallPublicIps);
|
||||
} else if (lbProvider.equalsIgnoreCase(element.getProvider().getName())) {
|
||||
allIps.addAll(loadbalncerPublicIps);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
FirewallServiceProvider fwElement = (FirewallServiceProvider)element;
|
||||
fwElement.applyIps(network, allIps);
|
||||
} else if (element instanceof FirewallServiceProvider) {
|
||||
FirewallServiceProvider fwElement = (FirewallServiceProvider)element;
|
||||
if (fwProvider.equalsIgnoreCase(element.getProvider().getName())) {
|
||||
fwElement.applyIps(network, firewallPublicIps);
|
||||
}
|
||||
} else if (element instanceof LoadBalancingServiceProvider) {
|
||||
LoadBalancingServiceProvider lbElement = (LoadBalancingServiceProvider) element;
|
||||
if (lbProvider.equalsIgnoreCase(element.getProvider().getName())) {
|
||||
if (loadbalncerPublicIps != null && !loadbalncerPublicIps.isEmpty()) {
|
||||
lbElement.applyLoadBalancerIp(network, publicIps);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Map<Service, Set<PublicIp>> serviceToIps = new HashMap<Service, Set<PublicIp>>();
|
||||
for (PublicIp ip : ipToServices.keySet()) {
|
||||
for (Service service : ipToServices.get(ip)) {
|
||||
Set<PublicIp> ips = serviceToIps.get(service);
|
||||
if (ips == null) {
|
||||
ips = new HashSet<PublicIp>();
|
||||
}
|
||||
ips.add(ip);
|
||||
serviceToIps.put(service, ips);
|
||||
}
|
||||
}
|
||||
//TODO Check different provider for same IP
|
||||
Map<Provider, Set<Service>> providerToServices = getProviderServiceMap(network.getId());
|
||||
Map<Provider, ArrayList<PublicIp>> providerToIpList = new HashMap<Provider, ArrayList<PublicIp>>();
|
||||
for (Provider provider: providerToServices.keySet()) {
|
||||
Set<Service> services = providerToServices.get(provider);
|
||||
//TODO add checking for services, multiply services may bind to one provider, which is invalid in non-conserved mode
|
||||
ArrayList<PublicIp> ipList = new ArrayList<PublicIp>();
|
||||
Set<PublicIp> ipSet = new HashSet<PublicIp>();
|
||||
for (Service service: services) {
|
||||
Set<PublicIp> serviceIps = serviceToIps.get(service);
|
||||
if (serviceIps == null || serviceIps.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
ipSet.addAll(serviceIps);
|
||||
}
|
||||
Set<PublicIp> sourceNatIps = serviceToIps.get(Service.SourceNat);
|
||||
if (sourceNatIps != null && !sourceNatIps.isEmpty()) {
|
||||
ipList.addAll(0, sourceNatIps);
|
||||
ipSet.removeAll(sourceNatIps);
|
||||
}
|
||||
ipList.addAll(ipSet);
|
||||
providerToIpList.put(provider, ipList);
|
||||
}
|
||||
return providerToIpList;
|
||||
}
|
||||
|
||||
protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List<PublicIp> publicIps) throws ResourceUnavailableException {
|
||||
boolean success = true;
|
||||
|
||||
Map<PublicIp, Set<Service>> ipToServices = getIpToServices(network, publicIps, rulesRevoked);
|
||||
Map<Provider, ArrayList<PublicIp>> providerToIpList = getProviderToIpList(network, ipToServices);
|
||||
|
||||
for (Provider provider : providerToIpList.keySet()) {
|
||||
try {
|
||||
ArrayList<PublicIp> ips = providerToIpList.get(provider);
|
||||
if (ips == null || ips.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
IpDeployer deployer = null;
|
||||
NetworkElement element = getElementImplementingProvider(provider.getName());
|
||||
if (element instanceof SourceNatServiceProvider) {
|
||||
deployer = ((SourceNatServiceProvider)element).getIpDeployer(network);
|
||||
} else if (element instanceof StaticNatServiceProvider) {
|
||||
deployer = ((StaticNatServiceProvider)element).getIpDeployer(network);
|
||||
} else if (element instanceof LoadBalancingServiceProvider) {
|
||||
deployer = ((LoadBalancingServiceProvider)element).getIpDeployer(network);
|
||||
} else if (element instanceof PortForwardingServiceProvider) {
|
||||
deployer = ((PortForwardingServiceProvider)element).getIpDeployer(network);
|
||||
} else if (element instanceof RemoteAccessVPNServiceProvider) {
|
||||
deployer = ((RemoteAccessVPNServiceProvider)element).getIpDeployer(network);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Fail to get ip deployer for element: " + element);
|
||||
}
|
||||
Set<Service> services = new HashSet<Service>();
|
||||
for (PublicIp ip : ips) {
|
||||
if (!ipToServices.containsKey(ip)) {
|
||||
continue;
|
||||
}
|
||||
services.addAll(ipToServices.get(ip));
|
||||
}
|
||||
deployer.applyIps(network, ips, services);
|
||||
} catch (ResourceUnavailableException e) {
|
||||
success = false;
|
||||
if (!continueOnError) {
|
||||
throw e;
|
||||
} else {
|
||||
s_logger.debug("Resource is not available: " + element.getName(), e);
|
||||
s_logger.debug("Resource is not available: " + provider.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -708,51 +824,35 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
||||
return success;
|
||||
}
|
||||
|
||||
Purpose getPublicIpPurpose(PublicIp ip, boolean includeRevoked) {
|
||||
Set<Purpose> getPublicIpPurposeInRules(PublicIp ip, boolean includeRevoked) {
|
||||
Set<Purpose> result = new HashSet<Purpose>();
|
||||
if (includeRevoked) {
|
||||
List<FirewallRuleVO> loadBalancingRules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.LoadBalancing);
|
||||
if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) {
|
||||
return Purpose.LoadBalancing;
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIp(ip.getId());
|
||||
if (rules == null || rules.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> firewall_rules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall);
|
||||
if (firewall_rules != null && !firewall_rules.isEmpty()) {
|
||||
return Purpose.Firewall;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> staticNatRules = _firewallDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat);
|
||||
if (staticNatRules != null && !staticNatRules.isEmpty()) {
|
||||
return Purpose.StaticNat;
|
||||
}
|
||||
|
||||
List<PortForwardingRuleVO> pfRules = _portForwardingDao.listByIp(ip.getId());
|
||||
if (pfRules != null && !pfRules.isEmpty()) {
|
||||
return Purpose.PortForwarding;
|
||||
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
// Firewall should attach to others, firewall rule alone make no sense
|
||||
if (rule.getPurpose() != Purpose.Firewall) {
|
||||
result.add(rule.getPurpose());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<FirewallRuleVO> loadBalancingRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.LoadBalancing);
|
||||
if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) {
|
||||
return Purpose.LoadBalancing;
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndNotRevoked(ip.getId());
|
||||
if (rules == null || rules.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> firewall_rules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.Firewall);
|
||||
if (firewall_rules != null && !firewall_rules.isEmpty()) {
|
||||
return Purpose.Firewall;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> staticNatRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ip.getId(), Purpose.StaticNat);
|
||||
if (staticNatRules != null && !staticNatRules.isEmpty()) {
|
||||
return Purpose.StaticNat;
|
||||
}
|
||||
|
||||
List<PortForwardingRuleVO> pfRules = _portForwardingDao.listByIpAndNotRevoked(ip.getId());
|
||||
if (pfRules != null && !pfRules.isEmpty()) {
|
||||
return Purpose.PortForwarding;
|
||||
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
// Firewall is attached to others, firewall rule alone make no sense
|
||||
if (rule.getPurpose() != Purpose.Firewall) {
|
||||
result.add(rule.getPurpose());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we are here means, public IP has no active/revoked rules to know the purpose
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -50,4 +50,8 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
|
||||
FirewallRuleVO findByRelatedId(long ruleId);
|
||||
|
||||
List<FirewallRuleVO> listSystemRules();
|
||||
|
||||
List<FirewallRuleVO> listByIp(long ipAddressId);
|
||||
|
||||
List<FirewallRuleVO> listByIpAndNotRevoked(long ipAddressId);
|
||||
}
|
||||
|
||||
@ -241,5 +241,21 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByIp(long ipId) {
|
||||
SearchCriteria<FirewallRuleVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("ipId", ipId);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByIpAndNotRevoked(long ipId) {
|
||||
SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
|
||||
sc.setParameters("ipId", ipId);
|
||||
sc.setParameters("state", State.Revoke);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ package com.cloud.network.element;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
@ -54,7 +55,7 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
|
||||
@Local(value=NetworkElement.class)
|
||||
public class ElasticLoadBalancerElement extends AdapterBase implements LoadBalancingServiceProvider {
|
||||
public class ElasticLoadBalancerElement extends AdapterBase implements LoadBalancingServiceProvider, IpDeployer {
|
||||
private static final Logger s_logger = Logger.getLogger(ElasticLoadBalancerElement.class);
|
||||
private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
|
||||
@Inject NetworkManager _networkManager;
|
||||
@ -181,9 +182,14 @@ public class ElasticLoadBalancerElement extends AdapterBase implements LoadBalan
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyLoadBalancerIp(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> services) throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpDeployer getIpDeployer(Network network) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
@ -88,7 +89,7 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@Local(value=NetworkElement.class)
|
||||
public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, F5ExternalLoadBalancerElementService, ExternalLoadBalancerDeviceManager {
|
||||
public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, IpDeployer, F5ExternalLoadBalancerElementService, ExternalLoadBalancerDeviceManager {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(F5ExternalLoadBalancerElement.class);
|
||||
|
||||
@ -442,9 +443,14 @@ public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceMan
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyLoadBalancerIp(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
|
||||
@Override
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service) throws ResourceUnavailableException {
|
||||
// return true, as IP will be associated as part of LB rule configuration
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpDeployer getIpDeployer(Network network) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,8 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -87,7 +89,7 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Local(value=NetworkElement.class)
|
||||
public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceManagerImpl implements SourceNatServiceProvider, FirewallServiceProvider,
|
||||
PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, JuniperSRXFirewallElementService{
|
||||
PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, JuniperSRXFirewallElementService{
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(JuniperSRXExternalFirewallElement.class);
|
||||
|
||||
@ -496,8 +498,13 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpDeployer getIpDeployer(Network network) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service) throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
@ -88,7 +89,7 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@Local(value=NetworkElement.class)
|
||||
public class NetscalerExternalLoadBalancerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager {
|
||||
public class NetscalerExternalLoadBalancerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager, IpDeployer {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(NetscalerExternalLoadBalancerElement.class);
|
||||
|
||||
@ -467,9 +468,14 @@ public class NetscalerExternalLoadBalancerElement extends ExternalLoadBalancerDe
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyLoadBalancerIp(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
|
||||
@Override
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service) throws ResourceUnavailableException {
|
||||
// return true, as IP will be associated as part of LB rule configuration
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpDeployer getIpDeployer(Network network) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
@ -84,9 +85,8 @@ import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
|
||||
@Local(value=NetworkElement.class)
|
||||
public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider {
|
||||
public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer {
|
||||
private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
|
||||
|
||||
private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
|
||||
@ -256,8 +256,15 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
|
||||
if (canHandle(network, Service.Firewall)) {
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> services) throws ResourceUnavailableException {
|
||||
boolean canHandle = true;
|
||||
for (Service service : services) {
|
||||
if (!canHandle(network, service)) {
|
||||
canHandle = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (canHandle) {
|
||||
List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
|
||||
if (routers == null || routers.isEmpty()) {
|
||||
s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual router doesn't exist in the network " + network.getId());
|
||||
@ -270,21 +277,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyLoadBalancerIp(Network network, List<? extends PublicIpAddress> ipAddress) throws ResourceUnavailableException {
|
||||
if (canHandle(network, Service.Lb)) {
|
||||
List<DomainRouterVO> 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;
|
||||
@ -660,4 +652,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpDeployer getIpDeployer(Network network) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,6 +146,7 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
|
||||
import com.cloud.network.dao.RemoteAccessVpnDao;
|
||||
import com.cloud.network.dao.VirtualRouterProviderDao;
|
||||
import com.cloud.network.dao.VpnUserDao;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.lb.LoadBalancingRule;
|
||||
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
|
||||
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
|
||||
@ -1781,13 +1782,20 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
long zoneId = router.getDataCenterIdToDeployIn();
|
||||
|
||||
final List<IPAddressVO> userIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(ownerId, zoneId, null, null);
|
||||
List<PublicIpAddress> publicIps = new ArrayList<PublicIpAddress>();
|
||||
List<PublicIp> allPublicIps = new ArrayList<PublicIp>();
|
||||
if (userIps != null && !userIps.isEmpty()) {
|
||||
for (IPAddressVO userIp : userIps) {
|
||||
PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
|
||||
publicIps.add(publicIp);
|
||||
allPublicIps.add(publicIp);
|
||||
}
|
||||
}
|
||||
|
||||
//Get public Ips that should be handled by router
|
||||
Network network = _networkDao.findById(networkId);
|
||||
Map<PublicIp, Set<Service>> ipToServices = _networkMgr.getIpToServices(network, allPublicIps, false);
|
||||
Map<Provider, ArrayList<PublicIp>> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices);
|
||||
// Only cover virtual router for now, if ELB use it this need to be modified
|
||||
ArrayList<PublicIp> publicIps = providerToIpList.get(Provider.VirtualRouter);
|
||||
|
||||
s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start.");
|
||||
|
||||
@ -1799,8 +1807,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
List<FirewallRule> firewallRules = new ArrayList<FirewallRule>();
|
||||
|
||||
// Re-apply public ip addresses - should come before PF/LB/VPN
|
||||
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) {
|
||||
createAssociateIPCommands(router, publicIps, cmds, 0);
|
||||
}
|
||||
|
||||
//Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start)
|
||||
for (PublicIpAddress ip : publicIps) {
|
||||
for (PublicIp ip : publicIps) {
|
||||
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.PortForwarding, provider)) {
|
||||
pfRules.addAll(_pfRulesDao.listForApplication(ip.getId()));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user