From 3588f468482e43181802730ed5a059897eb85458 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 8 Apr 2013 16:23:03 -0700 Subject: [PATCH] Internal LB - added network-element plugin for internal lb service --- api/src/com/cloud/network/Network.java | 1 + .../cloud/network/router/VirtualRouter.java | 2 +- .../internal-loadbalancer/pom.xml | 34 +++ .../element/InternalLoadBalancerElement.java | 203 ++++++++++++++++++ plugins/pom.xml | 1 + .../network/element/VirtualRouterElement.java | 6 +- 6 files changed, 243 insertions(+), 4 deletions(-) create mode 100644 plugins/network-elements/internal-loadbalancer/pom.xml create mode 100644 plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/element/InternalLoadBalancerElement.java diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 159274b8c6a..9f1e579f1c1 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -125,6 +125,7 @@ public interface Network extends ControlledEntity, StateObject, I public static final Provider None = new Provider("None", false); // NiciraNvp is not an "External" provider, otherwise we get in trouble with NetworkServiceImpl.providersConfiguredForExternalNetworking public static final Provider NiciraNvp = new Provider("NiciraNvp", false); + public static final Provider InternalLoadBalancerVm = new Provider("InternalLoadBalancerVm", false); private String name; private boolean isExternal; diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java index d7239dd3452..59410fa0d48 100755 --- a/api/src/com/cloud/network/router/VirtualRouter.java +++ b/api/src/com/cloud/network/router/VirtualRouter.java @@ -23,7 +23,7 @@ import com.cloud.vm.VirtualMachine; */ public interface VirtualRouter extends VirtualMachine { public enum Role { - VIRTUAL_ROUTER, LB + VIRTUAL_ROUTER, LB, InternalLB } Role getRole(); boolean getIsRedundantRouter(); diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml new file mode 100644 index 00000000000..f3c8b372c0a --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + cloud-plugin-network-internallb + Apache CloudStack Plugin - Network Internal Load Balancer + + org.apache.cloudstack + cloudstack-plugins + 4.2.0-SNAPSHOT + ../../pom.xml + + + install + src + test + + diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/element/InternalLoadBalancerElement.java b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/element/InternalLoadBalancerElement.java new file mode 100644 index 00000000000..f55465d60d5 --- /dev/null +++ b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/element/InternalLoadBalancerElement.java @@ -0,0 +1,203 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.element; + +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 javax.inject.Inject; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.element.IpDeployer; +import com.cloud.network.element.LoadBalancingServiceProvider; +import com.cloud.network.element.NetworkElement; +import com.cloud.network.element.VirtualRouterElement; +import com.cloud.network.lb.LoadBalancingRule; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.rules.LoadBalancerContainer; +import com.cloud.offering.NetworkOffering; +import com.cloud.utils.component.AdapterBase; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.DomainRouterDao; + +@Local(value = {NetworkElement.class}) +public class InternalLoadBalancerElement extends AdapterBase implements LoadBalancingServiceProvider{ + private static final Logger s_logger = Logger.getLogger(InternalLoadBalancerElement.class); + protected static final Map> capabilities = setCapabilities(); + + @Inject NetworkModel _ntwkModel; + @Inject NetworkServiceMapDao _ntwkSrvcDao; + @Inject DomainRouterDao _routerDao; + + private boolean canHandle(Network config, List rules) { + if (config.getGuestType() != Network.GuestType.Isolated || config.getTrafficType() != TrafficType.Guest) { + s_logger.trace("Not handling network with Type " + config.getGuestType() + " and traffic type " + config.getTrafficType()); + return false; + } + + Map lbCaps = this.getCapabilities().get(Service.Lb); + if (!lbCaps.isEmpty()) { + String schemeCaps = lbCaps.get(Capability.LbSchemes); + if (schemeCaps != null && rules != null && !rules.isEmpty()) { + for (LoadBalancingRule rule : rules) { + if (!schemeCaps.contains(rule.getScheme().toString())) { + s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider " + this.getName()); + return false; + } + } + } + } + + if (!_ntwkModel.isProviderSupportServiceInNetwork(config.getId(), Service.Lb, getProvider())) { + s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + Service.Lb + + " in the network " + config); + return false; + } + return true; + } + + @Override + public Map> getCapabilities() { + return capabilities; + } + + @Override + public Provider getProvider() { + return Provider.InternalLoadBalancerVm; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + return true; + } + + @Override + public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Shutdown all the internal lb elements + return false; + } + + @Override + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Shutdown all the internal lb elements + return false; + } + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + // TODO Shutdown all the internal lb elements + return false; + } + + @Override + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Shutdown all the internal lb elements + return false; + } + + @Override + public boolean canEnableIndividualServices() { + return false; + } + + @Override + public boolean verifyServicesCombination(Set services) { + return true; + } + + @Override + public IpDeployer getIpDeployer(Network network) { + return null; + } + + @Override + public boolean applyLBRules(Network network, List rules) throws ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean validateLBRule(Network network, LoadBalancingRule rule) { + List rules = new ArrayList(); + rules.add(rule); + if (canHandle(network, rules)) { + List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.InternalLB); + if (routers == null || routers.isEmpty()) { + return true; + } + return VirtualRouterElement.validateHAProxyLBRule(rule); + } + return true; + } + + @Override + public List updateHealthChecks(Network network, List lbrules) { + return null; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + // Set capabilities for LB service + Map lbCapabilities = new HashMap(); + lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,source"); + lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated"); + lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp"); + lbCapabilities.put(Capability.SupportedStickinessMethods, VirtualRouterElement.getHAProxyStickinessCapability()); + lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Internal.toString()); + + capabilities.put(Service.Lb, lbCapabilities); + return capabilities; + } + +} diff --git a/plugins/pom.xml b/plugins/pom.xml index 607c50cff22..763b20b5f59 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -62,6 +62,7 @@ storage/volume/default alert-handlers/snmp-alerts alert-handlers/syslog-alerts + network-elements/internal-loadbalancer diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index ddb35b61f8f..bf9ac49a635 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -244,7 +244,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl * number like 12 2) time or tablesize like 12h, 34m, 45k, 54m , here * last character is non-digit but from known characters . */ - private boolean containsOnlyNumbers(String str, String endChar) { + private static boolean containsOnlyNumbers(String str, String endChar) { if (str == null) return false; @@ -273,7 +273,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } - private boolean validateHAProxyLBRule(LoadBalancingRule rule) { + public static boolean validateHAProxyLBRule(LoadBalancingRule rule) { String timeEndChar = "dhms"; for (LbStickinessPolicy stickinessPolicy : rule.getStickinessPolicies()) { @@ -460,7 +460,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return capabilities; } - private static String getHAProxyStickinessCapability() { + public static String getHAProxyStickinessCapability() { LbStickinessMethod method; List methodList = new ArrayList(1);