From 177e157cbfa40af82de628cb00876678d7646d2d Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Fri, 4 Jan 2013 18:56:47 -0800 Subject: [PATCH] CLOUDSTACK-306: Move inline mode parameter from device to network offering One F5 device can be used as inline and side-by-side at the same time(for different networks). So we can define inline or not on network base. --- .../cloud/agent/api/to/LoadBalancerTO.java | 12 ++- api/src/com/cloud/network/Network.java | 1 + .../com/cloud/offering/NetworkOffering.java | 1 + .../lb/ElasticLoadBalancerManagerImpl.java | 2 +- .../api/response/F5LoadBalancerResponse.java | 7 -- .../F5ExternalLoadBalancerElement.java | 4 +- .../network/resource/F5BigIpResource.java | 87 +++++++++---------- .../NetscalerLoadBalancerResponse.java | 7 -- .../network/element/NetscalerElement.java | 25 +----- .../src/com/cloud/api/ApiResponseHelper.java | 5 ++ .../ConfigurationManagerImpl.java | 23 ++++- ...ExternalLoadBalancerDeviceManagerImpl.java | 17 ++-- .../network/ExternalLoadBalancerDeviceVO.java | 18 +--- .../src/com/cloud/network/NetworkManager.java | 1 + .../com/cloud/network/NetworkManagerImpl.java | 5 ++ .../VirtualNetworkApplianceManagerImpl.java | 4 +- .../cloud/offerings/NetworkOfferingVO.java | 11 ++- .../cloud/server/ConfigurationServerImpl.java | 2 +- .../cloud/network/MockNetworkManagerImpl.java | 6 ++ .../com/cloud/vpc/MockNetworkManagerImpl.java | 5 ++ setup/db/create-schema.sql | 2 +- setup/db/db/schema-40to410.sql | 3 + 22 files changed, 131 insertions(+), 117 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java index 2e19af05569..2d166ea1e1e 100644 --- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java +++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java @@ -43,12 +43,13 @@ public class LoadBalancerTO { String algorithm; boolean revoked; boolean alreadyAdded; + boolean inline; DestinationTO[] destinations; private StickinessPolicyTO[] stickinessPolicies; private AutoScaleVmGroupTO autoScaleVmGroupTO; final static int MAX_STICKINESS_POLICIES = 1; - public LoadBalancerTO(String uuid, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List destinations) { + public LoadBalancerTO(String uuid, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, boolean inline, List destinations) { if (destinations == null) { // for autoscaleconfig destinations will be null; destinations = new ArrayList(); } @@ -59,6 +60,7 @@ public class LoadBalancerTO { this.algorithm = algorithm; this.revoked = revoked; this.alreadyAdded = alreadyAdded; + this.inline = inline; this.destinations = new DestinationTO[destinations.size()]; this.stickinessPolicies = null; int i = 0; @@ -67,8 +69,8 @@ public class LoadBalancerTO { } } - public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List arg_destinations, List stickinessPolicies) { - this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, arg_destinations); + public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, boolean inline, List arg_destinations, List stickinessPolicies) { + this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, inline, arg_destinations); this.stickinessPolicies = null; if (stickinessPolicies != null && stickinessPolicies.size() > 0) { this.stickinessPolicies = new StickinessPolicyTO[MAX_STICKINESS_POLICIES]; @@ -116,6 +118,10 @@ public class LoadBalancerTO { return alreadyAdded; } + public boolean isInline() { + return inline; + } + public StickinessPolicyTO[] getStickinessPolicies() { return stickinessPolicies; } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 188ef92e57b..a6cbdd80f0e 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -171,6 +171,7 @@ public interface Network extends ControlledEntity { public static final Capability AssociatePublicIP = new Capability("AssociatePublicIP"); public static final Capability ElasticLb = new Capability("ElasticLb"); public static final Capability AutoScaleCounters = new Capability("AutoScaleCounters"); + public static final Capability InlineMode = new Capability("InlineMode"); private String name; diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 29828ab6172..8de1d13e372 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -111,4 +111,5 @@ public interface NetworkOffering { boolean getSpecifyIpRanges(); + boolean isInline(); } diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index 366070af21f..0043cac778a 100644 --- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -296,7 +296,7 @@ ElasticLoadBalancerManager, Manager, VirtualMachineGuru { int srcPort = rule.getSourcePortStart(); String uuid = rule.getUuid(); List destinations = rule.getDestinations(); - LoadBalancerTO lb = new LoadBalancerTO(uuid, elbIp, srcPort, protocol, algorithm, revoked, false, destinations); + LoadBalancerTO lb = new LoadBalancerTO(uuid, elbIp, srcPort, protocol, algorithm, revoked, false, false, destinations); lbs[i++] = lb; } diff --git a/plugins/network-elements/f5/src/com/cloud/api/response/F5LoadBalancerResponse.java b/plugins/network-elements/f5/src/com/cloud/api/response/F5LoadBalancerResponse.java index dbb962fff03..275fca687ba 100644 --- a/plugins/network-elements/f5/src/com/cloud/api/response/F5LoadBalancerResponse.java +++ b/plugins/network-elements/f5/src/com/cloud/api/response/F5LoadBalancerResponse.java @@ -43,9 +43,6 @@ public class F5LoadBalancerResponse extends BaseResponse { @SerializedName(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) @Param(description="true if device is dedicated for an account") private Boolean dedicatedLoadBalancer; - @SerializedName(ApiConstants.INLINE) @Param(description="true if device is inline with firewall device") - private Boolean inlineLoadBalancer; - @SerializedName(ApiConstants.PUBLIC_INTERFACE) @Param(description="the public interface of the load balancer") private String publicInterface; @@ -83,10 +80,6 @@ public class F5LoadBalancerResponse extends BaseResponse { this.dedicatedLoadBalancer = isDedicated; } - public void setInlineMode(boolean inline) { - this.inlineLoadBalancer = inline; - } - public void setPublicInterface(String publicInterface) { this.publicInterface = publicInterface; } diff --git a/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java b/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java index 579a4628c74..63e82751b4d 100644 --- a/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java +++ b/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java @@ -206,6 +206,9 @@ public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceMan // Specifies that load balancing rules can only be made with public IPs that aren't source NAT IPs lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional"); + // Support inline mode with firewall + lbCapabilities.put(Capability.InlineMode, "true"); + LbStickinessMethod method; List methodList = new ArrayList(); method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is cookie based sticky method, can be used only for http"); @@ -448,7 +451,6 @@ public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceMan } else { response.setDeviceCapacity(lbDeviceVO.getCapacity()); } - response.setInlineMode(lbDeviceVO.getIsInLineMode()); response.setDedicatedLoadBalancer(lbDeviceVO.getIsDedicatedDevice()); response.setProvider(lbDeviceVO.getProviderName()); response.setDeviceState(lbDeviceVO.getState().name()); diff --git a/plugins/network-elements/f5/src/com/cloud/network/resource/F5BigIpResource.java b/plugins/network-elements/f5/src/com/cloud/network/resource/F5BigIpResource.java index a45dd92ca98..618cd912e91 100644 --- a/plugins/network-elements/f5/src/com/cloud/network/resource/F5BigIpResource.java +++ b/plugins/network-elements/f5/src/com/cloud/network/resource/F5BigIpResource.java @@ -119,7 +119,6 @@ public class F5BigIpResource implements ServerResource { private String _privateInterface; private Integer _numRetries; private String _guid; - private boolean _inline; private Interfaces _interfaces; private LocalLBVirtualServerBindingStub _virtualServerApi; @@ -180,8 +179,6 @@ public class F5BigIpResource implements ServerResource { throw new ConfigurationException("Unable to find the guid"); } - _inline = Boolean.parseBoolean((String) params.get("inline")); - login(); return true; @@ -292,45 +289,49 @@ public class F5BigIpResource implements ServerResource { } private synchronized Answer execute(IpAssocCommand cmd, int numRetries) { - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; - try { - IpAddressTO[] ips = cmd.getIpAddresses(); - for (IpAddressTO ip : ips) { - long guestVlanTag = Long.valueOf(ip.getVlanId()); - String vlanSelfIp = _inline ? tagAddressWithRouteDomain(ip.getVlanGateway(), guestVlanTag) : ip.getVlanGateway(); - String vlanNetmask = ip.getVlanNetmask(); - - // Delete any existing guest VLAN with this tag, self IP, and netmask - deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask); - - if (ip.isAdd()) { - // Add a new guest VLAN - addGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask); + String[] results = new String[cmd.getIpAddresses().length]; + int i = 0; + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + long guestVlanTag = Long.valueOf(ip.getVlanId()); + // It's a hack, using isOneToOneNat field for indicate if it's inline or not + // We'd better have an separate SetupGuestNetwork command later + boolean inline = ip.isOneToOneNat(); + String vlanSelfIp = inline ? tagAddressWithRouteDomain(ip.getVlanGateway(), guestVlanTag) : ip.getVlanGateway(); + String vlanNetmask = ip.getVlanNetmask(); + + // Delete any existing guest VLAN with this tag, self IP, and netmask + deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask, inline); + + if (ip.isAdd()) { + // Add a new guest VLAN + addGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask, inline); + } + + saveConfiguration(); + results[i++] = ip.getPublicIp() + " - success"; } - - saveConfiguration(); - results[i++] = ip.getPublicIp() + " - success"; - } - - } catch (ExecutionException e) { - s_logger.error("Failed to execute IPAssocCommand due to " + e); - - if (shouldRetry(numRetries)) { - return retry(cmd, numRetries); - } else { - results[i++] = IpAssocAnswer.errorResult; - } - } - - return new IpAssocAnswer(cmd, results); - } + + } catch (ExecutionException e) { + s_logger.error("Failed to execute IPAssocCommand due to " + e); + + if (shouldRetry(numRetries)) { + return retry(cmd, numRetries); + } else { + results[i++] = IpAssocAnswer.errorResult; + } + } + + return new IpAssocAnswer(cmd, results); + } private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) { try { long guestVlanTag = Long.parseLong(cmd.getAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG)); LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers(); for (LoadBalancerTO loadBalancer : loadBalancers) { + boolean inline = loadBalancer.isInline(); LbProtocol lbProtocol; try { if (loadBalancer.getProtocol() == null) { @@ -351,7 +352,7 @@ public class F5BigIpResource implements ServerResource { throw new ExecutionException("Got invalid algorithm: " + loadBalancer.getAlgorithm()); } - String srcIp = _inline ? tagAddressWithRouteDomain(loadBalancer.getSrcIp(), guestVlanTag) : loadBalancer.getSrcIp(); + String srcIp = inline ? tagAddressWithRouteDomain(loadBalancer.getSrcIp(), guestVlanTag) : loadBalancer.getSrcIp(); int srcPort = loadBalancer.getSrcPort(); String virtualServerName = genVirtualServerName(lbProtocol, srcIp, srcPort); @@ -371,7 +372,7 @@ public class F5BigIpResource implements ServerResource { List activePoolMembers = new ArrayList(); for (DestinationTO destination : loadBalancer.getDestinations()) { if (!destination.isRevoked()) { - String destIp = _inline ? tagAddressWithRouteDomain(destination.getDestIp(), guestVlanTag) : destination.getDestIp(); + String destIp = inline ? tagAddressWithRouteDomain(destination.getDestIp(), guestVlanTag) : destination.getDestIp(); addPoolMember(virtualServerName, destIp, destination.getDestPort()); activePoolMembers.add(destIp + "-" + destination.getDestPort()); } @@ -421,7 +422,7 @@ public class F5BigIpResource implements ServerResource { } } - private void addGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException { + private void addGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask, boolean inline) throws ExecutionException { try { String vlanName = genVlanName(vlanTag); List allVlans = getVlans(); @@ -444,7 +445,7 @@ public class F5BigIpResource implements ServerResource { } } - if (_inline) { + if (inline) { List allRouteDomains = getRouteDomains(); if (!allRouteDomains.contains(vlanTag)) { long[] routeDomainIds = genLongArray(vlanTag); @@ -481,7 +482,7 @@ public class F5BigIpResource implements ServerResource { } - private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException { + private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask, boolean inline) throws ExecutionException { try { // Delete all virtual servers and pools that use this guest VLAN deleteVirtualServersInGuestVlan(vlanSelfIp, vlanNetmask); @@ -496,7 +497,7 @@ public class F5BigIpResource implements ServerResource { } } - if (_inline) { + if (inline) { List allRouteDomains = getRouteDomains(); if (allRouteDomains.contains(vlanTag)) { s_logger.debug("Deleting route domain " + vlanTag); @@ -969,9 +970,7 @@ public class F5BigIpResource implements ServerResource { for (LocalLBVirtualServerVirtualServerStatisticEntry entry : stats.getStatistics()) { String virtualServerIp = entry.getVirtual_server().getAddress(); - if (_inline) { - virtualServerIp = stripRouteDomainFromAddress(virtualServerIp); - } + virtualServerIp = stripRouteDomainFromAddress(virtualServerIp); long[] bytesSentAndReceived = answer.ipBytes.get(virtualServerIp); diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java index bbbfca515a1..7bc70dc786f 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java +++ b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java @@ -49,9 +49,6 @@ public class NetscalerLoadBalancerResponse extends BaseResponse { @SerializedName(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) @Param(description="true if device is dedicated for an account") private Boolean dedicatedLoadBalancer; - @SerializedName(ApiConstants.INLINE) @Param(description="true if device is inline with firewall device") - private Boolean inlineLoadBalancer; - @SerializedName(ApiConstants.PUBLIC_INTERFACE) @Param(description="the public interface of the load balancer") private String publicInterface; @@ -94,10 +91,6 @@ public class NetscalerLoadBalancerResponse extends BaseResponse { this.deviceState = deviceState; } - public void setInlineMode(boolean inline) { - this.inlineLoadBalancer = inline; - } - public void setPublicInterface(String publicInterface) { this.publicInterface = publicInterface; } diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index 987e937952d..c4f0ef392ef 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -353,18 +353,17 @@ StaticNatServiceProvider { public ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(ConfigureNetscalerLoadBalancerCmd cmd) { Long lbDeviceId = cmd.getLoadBalancerDeviceId(); Boolean dedicatedUse = cmd.getLoadBalancerDedicated(); - Boolean inline = cmd.getLoadBalancerInline(); Long capacity = cmd.getLoadBalancerCapacity(); List podIds = cmd.getPodIds(); try { - return configureNetscalerLoadBalancer(lbDeviceId, capacity, inline, dedicatedUse, podIds); + return configureNetscalerLoadBalancer(lbDeviceId, capacity, dedicatedUse, podIds); } catch (Exception e) { throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage()); } } @DB - private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(long lbDeviceId, Long capacity, Boolean inline, Boolean dedicatedUse, List newPodsConfig) { + private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(long lbDeviceId, Long capacity, Boolean dedicatedUse, List newPodsConfig) { ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); Map lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId()); @@ -404,7 +403,7 @@ StaticNatServiceProvider { } String deviceName = lbDeviceVo.getDeviceName(); - if (dedicatedUse != null || capacity != null || inline != null) { + if (dedicatedUse != null || capacity != null) { if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) || NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) { if (dedicatedUse != null && dedicatedUse == true) { @@ -422,13 +421,6 @@ StaticNatServiceProvider { if (dedicatedUse != null && dedicatedUse == true) { throw new CloudRuntimeException("There are networks already using this netscaler device to make device dedicated"); } - - if (inline != null) { - boolean _setInline = Boolean.parseBoolean(lbDetails.get("inline")); - if (inline != _setInline) { - throw new CloudRuntimeException("There are networks already using this netscaler device to change the device inline or side-by-side configuration"); - } - } } } @@ -444,14 +436,6 @@ StaticNatServiceProvider { lbDeviceVo.setIsDedicatedDevice(dedicatedUse); } - if (inline != null && inline == true) { - lbDeviceVo.setIsInlineMode(true); - lbDetails.put("inline", "true"); - } else { - lbDeviceVo.setIsInlineMode(false); - lbDetails.put("inline", "false"); - } - Transaction txn = Transaction.currentTxn(); txn.start(); @@ -552,7 +536,6 @@ StaticNatServiceProvider { } else { response.setDeviceCapacity(lbDeviceVO.getCapacity()); } - response.setInlineMode(lbDeviceVO.getIsInLineMode()); response.setDedicatedLoadBalancer(lbDeviceVO.getIsDedicatedDevice()); response.setProvider(lbDeviceVO.getProviderName()); response.setDeviceState(lbDeviceVO.getState().name()); @@ -690,7 +673,7 @@ StaticNatServiceProvider { List destinations = rule.getDestinations(); if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { - LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); + LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, rule.getStickinessPolicies()); if (rule.isAutoScaleConfig()) { loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 8f9837f54a5..e3450e95629 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3006,6 +3006,11 @@ public class ApiResponseHelper implements ResponseGenerator { eLb.setValue(offering.getElasticLb() ? "true" : "false"); lbCapResponse.add(eLb); + CapabilityResponse inline = new CapabilityResponse(); + inline.setName(Capability.InlineMode.getName()); + inline.setValue(offering.isInline() ? "true" : "false"); + lbCapResponse.add(inline); + svcRsp.setCapabilities(lbCapResponse); } else if (Service.SourceNat == service) { List capabilities = new ArrayList(); diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index c7a5d64ac7e..de0931f4728 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -3099,8 +3099,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura void validateLoadBalancerServiceCapabilities(Map lbServiceCapabilityMap) { if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) { - if (lbServiceCapabilityMap.keySet().size() > 2 || !lbServiceCapabilityMap.containsKey(Capability.SupportedLBIsolation)) { - throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + " and " + Capability.ElasticLb + " capabilities can be sepcified for LB service"); + if (lbServiceCapabilityMap.keySet().size() > 3 || !lbServiceCapabilityMap.containsKey(Capability.SupportedLBIsolation)) { + throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + ", " + Capability.ElasticLb.getName() + ", " + Capability.InlineMode.getName() + " capabilities can be sepcified for LB service"); } for (Capability cap : lbServiceCapabilityMap.keySet()) { @@ -3117,8 +3117,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (!enabled && !disabled) { throw new InvalidParameterValueException("Unknown specified value for " + Capability.ElasticLb.getName()); } + } else if (cap == Capability.InlineMode) { + boolean enabled = value.contains("true"); + boolean disabled = value.contains("false"); + if (!enabled && !disabled) { + throw new InvalidParameterValueException("Unknown specified value for " + Capability.InlineMode.getName()); + } } else { - throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + " and " + Capability.ElasticLb + " capabilities can be sepcified for LB service"); + throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + ", " + Capability.ElasticLb.getName() + ", " + Capability.InlineMode.getName() + " capabilities can be sepcified for LB service"); } } } @@ -3234,6 +3240,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura boolean redundantRouter = false; boolean elasticIp = false; boolean associatePublicIp = false; + boolean inline = false; if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) { Map lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb); @@ -3250,6 +3257,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (param != null) { elasticLb = param.contains("true"); } + + String inlineMode = lbServiceCapabilityMap.get(Capability.InlineMode); + if (inlineMode != null) { + _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.InlineMode, inlineMode); + inline = inlineMode.contains("true"); + } else { + inline = false; + } } Map sourceNatServiceCapabilityMap = serviceCapabilityMap.get(Service.SourceNat); @@ -3284,7 +3299,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, - sharedSourceNat, redundantRouter, elasticIp, elasticLb, associatePublicIp, specifyIpRanges); + sharedSourceNat, redundantRouter, elasticIp, elasticLb, associatePublicIp, specifyIpRanges, inline); if (serviceOfferingId != null) { offering.setServiceOfferingId(serviceOfferingId); diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 8c69bf6d852..839f8023220 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -239,7 +239,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (host != null) { boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false; - boolean inline = (configParams.get(ApiConstants.INLINE) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.INLINE)) : false; long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_CAPACITY), 0); if (capacity == 0) { capacity = _defaultLbCapacity; @@ -247,7 +246,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase txn.start(); ExternalLoadBalancerDeviceVO lbDeviceVO = new ExternalLoadBalancerDeviceVO(host.getId(), pNetwork.getId(), ntwkSvcProvider.getProviderName(), - deviceName, capacity, dedicatedUse, inline); + deviceName, capacity, dedicatedUse); _externalLoadBalancerDeviceDao.persist(lbDeviceVO); DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.LOAD_BALANCER_DEVICE_ID, String.valueOf(lbDeviceVO.getId())); @@ -708,11 +707,6 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase return fwHost; } - private boolean externalLoadBalancerIsInline(HostVO externalLoadBalancer) { - DetailVO detail = _hostDetailDao.findDetail(externalLoadBalancer.getId(), "inline"); - return (detail != null && detail.getValue().equals("true")); - } - private NicVO savePlaceholderNic(Network network, String ipAddress) { NicVO nic = new NicVO(null, null, network.getId(), null); nic.setIp4Address(ipAddress); @@ -786,7 +780,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); - boolean externalLoadBalancerIsInline = externalLoadBalancerIsInline(externalLoadBalancer); + boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network); if (network.getState() == Network.State.Allocated) { s_logger.debug("External load balancer was asked to apply LB rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands."); @@ -867,7 +861,8 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { - LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, destinations, rule.getStickinessPolicies()); + boolean inline = _networkMgr.isNetworkInlineMode(network); + LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies()); if(rule.isAutoScaleConfig()) { loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); } @@ -951,7 +946,9 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase selfIp = selfipNic.getIp4Address(); } - IpAddressTO ip = new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, networkRate, false); + // It's a hack, using isOneToOneNat field for indicate if it's inline or not + boolean inline = _networkMgr.isNetworkInlineMode(guestConfig); + IpAddressTO ip = new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, networkRate, inline); IpAddressTO[] ips = new IpAddressTO[1]; ips[0] = ip; IpAssocCommand cmd = new IpAssocCommand(ips); diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java index 190067b653b..e9414dc3bfb 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceVO.java @@ -66,9 +66,6 @@ public class ExternalLoadBalancerDeviceVO { @Column(name="is_managed") private boolean isManagedDevice; - @Column(name="is_inline") - private boolean isInlineMode; - @Column(name="is_dedicated") private boolean isDedicatedDevice; @@ -92,7 +89,7 @@ public class ExternalLoadBalancerDeviceVO { } public ExternalLoadBalancerDeviceVO(long hostId, long physicalNetworkId, String provider_name, String device_name, - long capacity, boolean dedicated, boolean inline) { + long capacity, boolean dedicated) { this.physicalNetworkId = physicalNetworkId; this.providerName = provider_name; this.deviceName = device_name; @@ -101,7 +98,6 @@ public class ExternalLoadBalancerDeviceVO { this.allocationState = LBDeviceAllocationState.Free; this.capacity = capacity; this.isDedicatedDevice = dedicated; - this.isInlineMode = inline; this.isManagedDevice = false; this.state = LBDeviceState.Enabled; this.uuid = UUID.randomUUID().toString(); @@ -112,8 +108,8 @@ public class ExternalLoadBalancerDeviceVO { } public ExternalLoadBalancerDeviceVO(long hostId, long physicalNetworkId, String provider_name, String device_name, - long capacity, boolean dedicated, boolean inline, boolean managed, long parentHostId) { - this(hostId, physicalNetworkId, provider_name, device_name, capacity, dedicated, inline); + long capacity, boolean dedicated, boolean managed, long parentHostId) { + this(hostId, physicalNetworkId, provider_name, device_name, capacity, dedicated); this.isManagedDevice = managed; this.parentHostId = parentHostId; } @@ -182,14 +178,6 @@ public class ExternalLoadBalancerDeviceVO { this.isManagedDevice = managed; } - public boolean getIsInLineMode () { - return isInlineMode; - } - - public void setIsInlineMode(boolean inline) { - this.isInlineMode = inline; - } - public boolean getIsDedicatedDevice() { return isDedicatedDevice; } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 057f473e732..d52e88a45bd 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -483,4 +483,5 @@ public interface NetworkManager extends NetworkService { */ int getNetworkLockTimeout(); + boolean isNetworkInlineMode(Network network); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 3f8b08519ad..f993b2b9b72 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -7484,4 +7484,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return _networkLockTimeout; } + @Override + public boolean isNetworkInlineMode(Network network) { + NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + return offering.isInline(); + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 966c32de6c2..c61e97965f1 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2835,6 +2835,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; int i = 0; + // We don't support VR to be inline currently + boolean inline = false; for (LoadBalancingRule rule : rules) { boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); String protocol = rule.getProtocol(); @@ -2845,7 +2847,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); List stickinessPolicies = rule.getStickinessPolicies(); - LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, destinations, stickinessPolicies); + LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, stickinessPolicies); lbs[i++] = lb; } String routerPublicIp = null; diff --git a/server/src/com/cloud/offerings/NetworkOfferingVO.java b/server/src/com/cloud/offerings/NetworkOfferingVO.java index 2570b70f630..100a52935b8 100755 --- a/server/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/server/src/com/cloud/offerings/NetworkOfferingVO.java @@ -117,6 +117,9 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { @Column(name = "eip_associate_public_ip") boolean eipAssociatePublicIp; + @Column(name = "inline") + boolean inline; + @Override public String getDisplayText() { return displayText; @@ -278,12 +281,13 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { this.elasticIp = false; this.elasticLb = false; this.eipAssociatePublicIp = true; + this.inline = false; this.specifyIpRanges = specifyIpRanges; } public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb, boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, - boolean associatePublicIP, boolean specifyIpRanges) { + boolean associatePublicIP, boolean specifyIpRanges, boolean inline) { this(name, displayText, trafficType, systemOnly, specifyVlan, rateMbps, multicastRateMbps, isDefault, availability, tags, guestType, conserveMode, specifyIpRanges); this.dedicatedLB = dedicatedLb; this.sharedSourceNat = sharedSourceNat; @@ -291,6 +295,7 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { this.elasticIp = elasticIp; this.elasticLb = elasticLb; this.eipAssociatePublicIp = associatePublicIP; + this.inline = inline; } public NetworkOfferingVO() { @@ -367,4 +372,8 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { return specifyIpRanges; } + @Override + public boolean isInline() { + return inline; + } } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index c0c29ed8eb8..43a1d99c888 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -971,7 +971,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, false, false, false, true, true, true, true); + null, Network.GuestType.Shared, true, false, false, false, true, true, true, true, false); defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index 76b911a722e..d8ef9e4cfbe 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -1135,4 +1135,10 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS // TODO Auto-generated method stub return 0; } + + @Override + public boolean isNetworkInlineMode(Network network) { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 3536d66ea4f..2141c1b0e09 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -1480,4 +1480,9 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager{ return 0; } + @Override + public boolean isNetworkInlineMode(Network network) { + // TODO Auto-generated method stub + return false; + } } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 1b6ee5df112..fb00ed4cd37 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -308,6 +308,7 @@ CREATE TABLE `cloud`.`network_offerings` ( `eip_associate_public_ip` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if public IP is associated with user VM creation by default when EIP service is enabled.', `elastic_lb_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides elastic lb service', `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides an ability to define ip ranges', + `inline` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this network offering LB provider is in inline mode', PRIMARY KEY (`id`), INDEX `i_network_offerings__system_only`(`system_only`), INDEX `i_network_offerings__removed`(`removed`), @@ -2075,7 +2076,6 @@ CREATE TABLE `cloud`.`external_load_balancer_devices` ( `device_state` varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'state (enabled/disabled/shutdown) of the device', `allocation_state` varchar(32) NOT NULL DEFAULT 'Free' COMMENT 'Allocation state (Free/Shared/Dedicated/Provider) of the device', `is_dedicated` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if device/appliance is provisioned for dedicated use only', - `is_inline` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if load balancer will be used in in-line configuration with firewall', `is_managed` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if load balancer appliance is provisioned and its life cycle is managed by by cloudstack', `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external load balancer device', `parent_host_id` bigint unsigned COMMENT 'if the load balancer appliance is cloudstack managed, then host id on which this appliance is provisioned', diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql index b09ebb94fea..2ce86e0b894 100644 --- a/setup/db/db/schema-40to410.sql +++ b/setup/db/db/schema-40to410.sql @@ -57,6 +57,9 @@ ALTER TABLE `cloud`.`snapshots` ADD COLUMN `s3_id` bigint unsigned COMMENT 'S3 t ALTER TABLE `cloud`.`snapshots` ADD CONSTRAINT `fk_snapshots__s3_id` FOREIGN KEY `fk_snapshots__s3_id` (`s3_id`) REFERENCES `s3` (`id`); ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `eip_associate_public_ip` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if public IP is associated with user VM creation by default when EIP service is enabled.' AFTER `elastic_ip_service`; +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `inline` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this network offering LB provider is in inline mode'; + +ALTER TABLE `cloud`.`external_load_balancer_devices` DROP COLUMN `is_inline`; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network','DEFAULT','NetworkManager','network.dhcp.nondefaultnetwork.setgateway.guestos','Windows','The guest OS\'s name start with this fields would result in DHCP server response gateway information even when the network it\'s on is not default network. Names are separated by comma.');