mirror of https://github.com/apache/cloudstack.git
InternalLB: modified InternalLbElement to start the Internal Lb vm for each ip address (if not already started)
This commit is contained in:
parent
76a4b1cf81
commit
f4c2b53c21
|
|
@ -31,6 +31,7 @@ import org.apache.log4j.Logger;
|
|||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
|
|
@ -234,6 +235,9 @@ public class CreateApplicationLoadBalancerCmd extends BaseAsyncCreateCmd {
|
|||
} catch (InsufficientAddressCapacityException e) {
|
||||
s_logger.warn("Exception: ", e);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, e.getMessage());
|
||||
} catch (InsufficientVirtualNetworkCapcityException e) {
|
||||
s_logger.warn("Exception: ", e);
|
||||
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ import com.cloud.network.element.VirtualRouterElement;
|
|||
import com.cloud.network.element.VirtualRouterProviderVO;
|
||||
import com.cloud.network.lb.LoadBalancingRule;
|
||||
import com.cloud.network.router.VirtualRouter.Role;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.LoadBalancerContainer;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.user.AccountManager;
|
||||
|
|
@ -68,6 +69,8 @@ import com.cloud.utils.component.AdapterBase;
|
|||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.SearchCriteria2;
|
||||
import com.cloud.utils.db.SearchCriteriaService;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.Ip;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
|
|
@ -235,27 +238,82 @@ public class InternalLoadBalancerElement extends AdapterBase implements LoadBala
|
|||
|
||||
@Override
|
||||
public boolean applyLBRules(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
|
||||
List<DomainRouterVO> routers;
|
||||
try {
|
||||
DeployDestination dest = new DeployDestination(_configMgr.getZone(network.getDataCenterId()), null, null, null);
|
||||
routers = _internalLbMgr.deployInternalLbVm(network, null, dest, _accountMgr.getAccount(network.getAccountId()), null);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
s_logger.warn("Failed to apply lb rule(s) on the element " + this.getName() + " due to:", e);
|
||||
return false;
|
||||
} catch (ConcurrentOperationException e) {
|
||||
s_logger.warn("Failed to apply lb rule(s) on the element " + this.getName() + " due to:", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((routers == null) || (routers.size() == 0)) {
|
||||
throw new ResourceUnavailableException("Can't find/deploy internal lb vm to handle LB rules",
|
||||
DataCenter.class, network.getDataCenterId());
|
||||
}
|
||||
Map<Ip, List<LoadBalancingRule>> rulesToApply = getLbRulesToApply(rules);
|
||||
|
||||
//TODO - apply the rules
|
||||
for (Ip sourceIp : rulesToApply.keySet()) {
|
||||
//2.1 Start Internal LB vm per IP address
|
||||
List<DomainRouterVO> internalLbVms;
|
||||
try {
|
||||
DeployDestination dest = new DeployDestination(_configMgr.getZone(network.getDataCenterId()), null, null, null);
|
||||
internalLbVms = _internalLbMgr.deployInternalLbVm(network, sourceIp, dest, _accountMgr.getAccount(network.getAccountId()), null);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
s_logger.warn("Failed to apply lb rule(s) on the element " + this.getName() + " due to:", e);
|
||||
return false;
|
||||
} catch (ConcurrentOperationException e) {
|
||||
s_logger.warn("Failed to apply lb rule(s) on the element " + this.getName() + " due to:", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((internalLbVms == null) || (internalLbVms.size() == 0)) {
|
||||
throw new ResourceUnavailableException("Can't find/deploy internal lb vm to handle LB rules",
|
||||
DataCenter.class, network.getDataCenterId());
|
||||
}
|
||||
|
||||
//2.2 Apply Internal LB rules on the VM
|
||||
if (!_internalLbMgr.applyLoadBalancingRules(network, rules, internalLbVms)) {
|
||||
throw new CloudRuntimeException("Failed to apply load balancing rules in network " + network.getId() + " on element " + this.getName());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Map<Ip, List<LoadBalancingRule>> getLbRulesToApply(List<LoadBalancingRule> rules) {
|
||||
//1) Group rules by the source ip address as NetworkManager always passes the entire network lb config to the element
|
||||
Map<Ip, List<LoadBalancingRule>> groupedRules = groupBySourceIp(rules);
|
||||
|
||||
//2) Apply only set containing LB rules in transition state (Add/Revoke)
|
||||
Map<Ip, List<LoadBalancingRule>> rulesToApply = new HashMap<Ip, List<LoadBalancingRule>>();
|
||||
|
||||
for (Ip sourceIp : groupedRules.keySet()) {
|
||||
boolean apply = false;
|
||||
List<LoadBalancingRule> rulesToCheck = groupedRules.get(sourceIp);
|
||||
for (LoadBalancingRule ruleToCheck : rulesToCheck) {
|
||||
if (ruleToCheck.getState() == FirewallRule.State.Revoke || ruleToCheck.getState() == FirewallRule.State.Add){
|
||||
apply = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (apply) {
|
||||
rulesToApply.put(sourceIp, rulesToCheck);
|
||||
} else {
|
||||
s_logger.debug("Not applying the lb rules for soure ip " + sourceIp + " on element " + this.getName() + " as there are no rules in transition state");
|
||||
}
|
||||
}
|
||||
return rulesToApply;
|
||||
}
|
||||
|
||||
protected Map<Ip, List<LoadBalancingRule>> groupBySourceIp(List<LoadBalancingRule> rules) {
|
||||
Map<Ip, List<LoadBalancingRule>> groupedRules = new HashMap<Ip, List<LoadBalancingRule>>();
|
||||
for (LoadBalancingRule rule : rules) {
|
||||
Ip sourceIp = rule.getSourceIp();
|
||||
if (!groupedRules.containsKey(sourceIp)) {
|
||||
groupedRules.put(sourceIp, null);
|
||||
}
|
||||
|
||||
List<LoadBalancingRule> rulesToApply = groupedRules.get(sourceIp);
|
||||
if (rulesToApply == null) {
|
||||
rulesToApply = new ArrayList<LoadBalancingRule>();
|
||||
}
|
||||
rulesToApply.add(rule);
|
||||
groupedRules.put(sourceIp, rulesToApply);
|
||||
}
|
||||
return groupedRules;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateLBRule(Network network, LoadBalancingRule rule) {
|
||||
List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.cloud.exception.InsufficientCapacityException;
|
|||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.lb.LoadBalancingRule;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
|
|
@ -94,4 +95,16 @@ public interface InternalLoadBalancerManager extends Manager{
|
|||
throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException,
|
||||
ResourceUnavailableException;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param network
|
||||
* @param rules
|
||||
* @param internalLbVms
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
boolean applyLoadBalancingRules(Network network, List<LoadBalancingRule> rules, List<? extends VirtualRouter> internalLbVms)
|
||||
throws ResourceUnavailableException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.apache.log4j.Logger;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.AgentManager.OnError;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.GetDomRVersionAnswer;
|
||||
import com.cloud.agent.api.GetDomRVersionCmd;
|
||||
|
|
@ -50,6 +51,7 @@ import com.cloud.dc.dao.DataCenterDao;
|
|||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
|
|
@ -567,26 +569,26 @@ InternalLoadBalancerManager, VirtualMachineGuru<DomainRouterVO> {
|
|||
|
||||
List<DomainRouterVO> internalLbVms = findOrDeployInternalLbVm(guestNetwork, requestedGuestIp, dest, owner, params);
|
||||
|
||||
return startRouters(params, internalLbVms);
|
||||
return startInternalLbVms(params, internalLbVms);
|
||||
}
|
||||
|
||||
protected List<DomainRouterVO> startRouters(Map<Param, Object> params, List<DomainRouterVO> routers)
|
||||
protected List<DomainRouterVO> startInternalLbVms(Map<Param, Object> params, List<DomainRouterVO> internalLbVms)
|
||||
throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
|
||||
List<DomainRouterVO> runningRouters = null;
|
||||
List<DomainRouterVO> runningInternalLbVms = null;
|
||||
|
||||
if (routers != null) {
|
||||
runningRouters = new ArrayList<DomainRouterVO>();
|
||||
if (internalLbVms != null) {
|
||||
runningInternalLbVms = new ArrayList<DomainRouterVO>();
|
||||
}
|
||||
|
||||
for (DomainRouterVO router : routers) {
|
||||
router = startInternalLbVm(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params);
|
||||
for (DomainRouterVO internalLbVm : internalLbVms) {
|
||||
internalLbVm = startInternalLbVm(internalLbVm, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params);
|
||||
|
||||
if (router != null) {
|
||||
runningRouters.add(router);
|
||||
if (internalLbVm != null) {
|
||||
runningInternalLbVms.add(internalLbVm);
|
||||
}
|
||||
|
||||
}
|
||||
return runningRouters;
|
||||
return runningInternalLbVms;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -630,22 +632,22 @@ InternalLoadBalancerManager, VirtualMachineGuru<DomainRouterVO> {
|
|||
}
|
||||
|
||||
// 3) deploy internal lb vm
|
||||
Pair<DeploymentPlan, List<DomainRouterVO>> planAndRouters = getDeploymentPlanAndInternalLbVms(dest, guestNetwork.getId(), requestedGuestIp);
|
||||
internalLbs = planAndRouters.second();
|
||||
DeploymentPlan plan = planAndRouters.first();
|
||||
Pair<DeploymentPlan, List<DomainRouterVO>> planAndInternalLbVms = getDeploymentPlanAndInternalLbVms(dest, guestNetwork.getId(), requestedGuestIp);
|
||||
internalLbs = planAndInternalLbVms.second();
|
||||
DeploymentPlan plan = planAndInternalLbVms.first();
|
||||
|
||||
List<Pair<NetworkVO, NicProfile>> networks = createInternalLbVmNetworks(guestNetwork, plan, null);
|
||||
//don't start the internal lb as we are holding the network lock that needs to be released at the end of router allocation
|
||||
DomainRouterVO internalLb = deployInternalLbVm(owner, dest, plan, params, internalLbProvider, offeringId, guestNetwork.getVpcId(),
|
||||
DomainRouterVO internalLbVm = deployInternalLbVm(owner, dest, plan, params, internalLbProvider, offeringId, guestNetwork.getVpcId(),
|
||||
networks, false);
|
||||
if (internalLb != null) {
|
||||
internalLbs.add(internalLb);
|
||||
if (internalLbVm != null) {
|
||||
internalLbs.add(internalLbVm);
|
||||
}
|
||||
} finally {
|
||||
if (lock != null) {
|
||||
_networkDao.releaseFromLockTable(lock.getId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Lock is released for network id " + lock.getId() + " as a part of router startup in " + dest);
|
||||
s_logger.debug("Lock is released for network id " + lock.getId() + " as a part of internal lb vm startup in " + dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -827,4 +829,52 @@ InternalLoadBalancerManager, VirtualMachineGuru<DomainRouterVO> {
|
|||
}
|
||||
return hypervisors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyLoadBalancingRules(Network network, final List<LoadBalancingRule> rules, List<? extends VirtualRouter> internalLbVms) throws ResourceUnavailableException {
|
||||
if (rules == null || rules.isEmpty()) {
|
||||
s_logger.debug("No lb rules to be applied for network " + network);
|
||||
return true;
|
||||
}
|
||||
|
||||
//FIXME - add validation for the internal lb vm state here
|
||||
return sendLBRules(internalLbVms.get(0), rules, network.getId());
|
||||
}
|
||||
|
||||
protected boolean sendLBRules(VirtualRouter internalLbVm, List<LoadBalancingRule> rules, long guestNetworkId) throws ResourceUnavailableException {
|
||||
Commands cmds = new Commands(OnError.Continue);
|
||||
createApplyLoadBalancingRulesCommands(rules, internalLbVm, cmds, guestNetworkId);
|
||||
return sendCommandsToInternalLbVm(internalLbVm, cmds);
|
||||
}
|
||||
|
||||
|
||||
protected boolean sendCommandsToInternalLbVm(final VirtualRouter internalLbVm, Commands cmds) throws AgentUnavailableException {
|
||||
Answer[] answers = null;
|
||||
try {
|
||||
answers = _agentMgr.send(internalLbVm.getHostId(), cmds);
|
||||
} catch (OperationTimedoutException e) {
|
||||
s_logger.warn("Timed Out", e);
|
||||
throw new AgentUnavailableException("Unable to send commands to virtual router ", internalLbVm.getHostId(), e);
|
||||
}
|
||||
|
||||
if (answers == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (answers.length != cmds.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Have to return state for individual command in the future
|
||||
boolean result = true;
|
||||
if (answers.length > 0) {
|
||||
for (Answer answer : answers) {
|
||||
if (!answer.getResult()) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
|||
throw new CloudRuntimeException("Failed to apply load balancing rules in network " + network.getId());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A
|
|||
}
|
||||
|
||||
//1) Validate LB rule's parameters
|
||||
validateLbRuleParameters(sourcePort, instancePort, algorithm, guestNtwk);
|
||||
validateLbRule(sourcePort, instancePort, algorithm, guestNtwk, scheme);
|
||||
|
||||
//2) Get source ip address
|
||||
sourceIp = getSourceIp(scheme, sourceIpNtwk, sourceIp);
|
||||
|
|
@ -188,10 +188,11 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A
|
|||
* @param sourcePort
|
||||
* @param instancePort
|
||||
* @param algorithm
|
||||
* @param networkId
|
||||
* @param network
|
||||
* @param scheme TODO
|
||||
* @param networkId
|
||||
*/
|
||||
protected void validateLbRuleParameters(int sourcePort, int instancePort, String algorithm, Network network) {
|
||||
protected void validateLbRule(int sourcePort, int instancePort, String algorithm, Network network, Scheme scheme) {
|
||||
// verify that lb service is supported by the network
|
||||
if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException(
|
||||
|
|
@ -200,6 +201,8 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements A
|
|||
throw ex;
|
||||
}
|
||||
|
||||
//FIXME - check if the schema is supported by the network
|
||||
|
||||
Map<Network.Capability, String> caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb);
|
||||
String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
|
||||
if (!supportedProtocols.contains(NetUtils.TCP_PROTO.toLowerCase())) {
|
||||
|
|
|
|||
|
|
@ -856,4 +856,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUsedIpsInNetwork(Network network) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -869,4 +869,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUsedIpsInNetwork(Network network) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue