blob: 6975f76e96816450e8ea6595cf2185a28f7a05b2 [file] [log] [blame]
// 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 com.cloud.network.lb;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd;
import org.apache.cloudstack.config.ApiServiceConfiguration;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.to.LoadBalancerTO;
import com.cloud.agent.manager.Commands;
import com.cloud.configuration.Config;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.ElasticLbVmMapVO;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.LoadBalancerVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.dao.ElasticLbVmMapDao;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.Storage;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
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;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineGuru;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
@Component
public class ElasticLoadBalancerManagerImpl extends ManagerBase implements ElasticLoadBalancerManager, VirtualMachineGuru {
private static final Logger s_logger = Logger.getLogger(ElasticLoadBalancerManagerImpl.class);
@Inject
private AgentManager _agentMgr;
@Inject
private NetworkModel _networkModel;
@Inject
private LoadBalancingRulesManager _lbMgr;
@Inject
private final DomainRouterDao _routerDao = null;
@Inject
protected HostPodDao _podDao = null;
@Inject
protected ClusterDao _clusterDao;
@Inject
private final DataCenterDao _dcDao = null;
@Inject
protected NetworkDao _networkDao;
@Inject
protected NetworkOfferingDao _networkOfferingDao;
@Inject
private VirtualMachineManager _itMgr;
@Inject
private ConfigurationDao _configDao;
@Inject
private final ServiceOfferingDao _serviceOfferingDao = null;
@Inject
private AccountService _accountService;
@Inject
private LoadBalancerDao _lbDao;
@Inject
private ElasticLbVmMapDao _elbVmMapDao;
@Inject
private NicDao _nicDao;
String _instance;
static final private String SystemVmType = "elbvm";
boolean _enabled;
TrafficType _frontendTrafficType = TrafficType.Guest;
Account _systemAcct;
ScheduledExecutorService _gcThreadPool;
String _mgmtCidr;
Set<Long> _gcCandidateElbVmIds = Collections.newSetFromMap(new ConcurrentHashMap<Long, Boolean>());
int _elasticLbVmRamSize;
int _elasticLbvmCpuMHz;
int _elasticLbvmNumCpu;
private LoadBalanceRuleHandler loadBalanceRuleHandler;
private boolean sendCommandsToRouter(final DomainRouterVO elbVm, Commands cmds) throws AgentUnavailableException {
Answer[] answers = null;
try {
answers = _agentMgr.send(elbVm.getHostId(), cmds);
} catch (OperationTimedoutException e) {
s_logger.warn("ELB: Timed Out", e);
throw new AgentUnavailableException("Unable to send commands to virtual elbVm ", elbVm.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
if (answers.length > 0) {
Answer ans = answers[0];
return ans.getResult();
}
return true;
}
private void createApplyLoadBalancingRulesCommands(List<LoadBalancingRule> rules, DomainRouterVO elbVm, Commands cmds, long guestNetworkId) {
/* XXX: cert */
LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()];
int i = 0;
for (LoadBalancingRule rule : rules) {
boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
String protocol = rule.getProtocol();
String algorithm = rule.getAlgorithm();
String elbIp = rule.getSourceIp().addr();
int srcPort = rule.getSourcePortStart();
String uuid = rule.getUuid();
List<LbDestination> destinations = rule.getDestinations();
LoadBalancerTO lb = new LoadBalancerTO(uuid, elbIp, srcPort, protocol, algorithm, revoked, false, false, destinations);
lbs[i++] = lb;
}
NetworkOffering offering = _networkOfferingDao.findById(guestNetworkId);
String maxconn = null;
if (offering.getConcurrentConnections() == null) {
maxconn = _configDao.getValue(Config.NetworkLBHaproxyMaxConn.key());
} else {
maxconn = offering.getConcurrentConnections().toString();
}
LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs, elbVm.getPublicIpAddress(), _nicDao.getIpAddress(guestNetworkId, elbVm.getId()),
elbVm.getPrivateIpAddress(), null, null, maxconn, offering.isKeepAliveEnabled());
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, elbVm.getPrivateIpAddress());
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, elbVm.getInstanceName());
//FIXME: why are we setting attributes directly? Ick!! There should be accessors and
//the constructor should set defaults.
cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key());
cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key());
cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key());
cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key());
cmds.addCommand(cmd);
}
protected boolean applyLBRules(DomainRouterVO elbVm, List<LoadBalancingRule> rules, long guestNetworkId) throws ResourceUnavailableException {
Commands cmds = new Commands(Command.OnError.Continue);
createApplyLoadBalancingRulesCommands(rules, elbVm, cmds, guestNetworkId);
// Send commands to elbVm
return sendCommandsToRouter(elbVm, cmds);
}
protected DomainRouterVO findElbVmForLb(LoadBalancingRule lb) {//TODO: use a table to lookup
Network ntwk = _networkModel.getNetwork(lb.getNetworkId());
long sourceIpId = _networkModel.getPublicIpAddress(lb.getSourceIp().addr(), ntwk.getDataCenterId()).getId();
ElasticLbVmMapVO map = _elbVmMapDao.findOneByIp(sourceIpId);
if (map == null) {
return null;
}
DomainRouterVO elbVm = _routerDao.findById(map.getElbVmId());
return elbVm;
}
@Override
public boolean applyLoadBalancerRules(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
if (rules == null || rules.isEmpty()) {
return true;
}
DomainRouterVO elbVm = findElbVmForLb(rules.get(0));
if (elbVm == null) {
s_logger.warn("Unable to apply lb rules, ELB vm doesn't exist in the network " + network.getId());
throw new ResourceUnavailableException("Unable to apply lb rules", DataCenter.class, network.getDataCenterId());
}
if (elbVm.getState() == State.Running) {
//resend all rules for the public ip
long sourceIpId = _networkModel.getPublicIpAddress(rules.get(0).getSourceIp().addr(), network.getDataCenterId()).getId();
List<LoadBalancerVO> lbs = _lbDao.listByIpAddress(sourceIpId);
List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
for (LoadBalancerVO lb : lbs) {
List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId());
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol());
lbRules.add(loadBalancing);
}
return applyLBRules(elbVm, lbRules, network.getId());
} else if (elbVm.getState() == State.Stopped || elbVm.getState() == State.Stopping) {
s_logger.debug("ELB VM is in " + elbVm.getState() + ", so not sending apply LoadBalancing rules commands to the backend");
return true;
} else {
s_logger.warn("Unable to apply loadbalancing rules, ELB VM is not in the right state " + elbVm.getState());
throw new ResourceUnavailableException("Unable to apply loadbalancing rules, ELB VM is not in the right state", VirtualRouter.class, elbVm.getId());
}
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
final Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
_systemAcct = _accountService.getSystemAccount();
_instance = configs.get("instance.name");
if (_instance == null) {
_instance = "VM";
}
_mgmtCidr = _configDao.getValue(Config.ManagementNetwork.key());
_elasticLbVmRamSize = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmMemory.key()), DEFAULT_ELB_VM_RAMSIZE);
_elasticLbvmCpuMHz = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmCpuMhz.key()), DEFAULT_ELB_VM_CPU_MHZ);
_elasticLbvmNumCpu = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmNumVcpu.key()), 1);
List<ServiceOfferingVO> offerings = _serviceOfferingDao.createSystemServiceOfferings("System Offering For Elastic LB VM",
ServiceOffering.elbVmDefaultOffUniqueName, _elasticLbvmNumCpu, _elasticLbVmRamSize, _elasticLbvmCpuMHz, 0, 0, true, null,
Storage.ProvisioningType.THIN, true, null, true, VirtualMachine.Type.ElasticLoadBalancerVm, true);
// this can sometimes happen, if DB is manually or programmatically manipulated
if (offerings == null || offerings.size() < 2) {
String msg = "Data integrity problem : System Offering For Elastic LB VM has been removed?";
s_logger.error(msg);
throw new ConfigurationException(msg);
}
String enabled = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
_enabled = (enabled == null) ? false : Boolean.parseBoolean(enabled);
s_logger.info("Elastic Load balancer enabled: " + _enabled);
if (_enabled) {
String traffType = _configDao.getValue(Config.ElasticLoadBalancerNetwork.key());
if ("guest".equalsIgnoreCase(traffType)) {
_frontendTrafficType = TrafficType.Guest;
} else if ("public".equalsIgnoreCase(traffType)) {
_frontendTrafficType = TrafficType.Public;
} else
throw new ConfigurationException("ELB: Traffic type for front end of load balancer has to be guest or public; found : " + traffType);
s_logger.info("ELB: Elastic Load Balancer: will balance on " + traffType);
int gcIntervalMinutes = NumbersUtil.parseInt(configs.get(Config.ElasticLoadBalancerVmGcInterval.key()), 5);
if (gcIntervalMinutes < 5)
gcIntervalMinutes = 5;
s_logger.info("ELB: Elastic Load Balancer: scheduling GC to run every " + gcIntervalMinutes + " minutes");
_gcThreadPool = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ELBVM-GC"));
_gcThreadPool.scheduleAtFixedRate(new CleanupThread(), gcIntervalMinutes, gcIntervalMinutes, TimeUnit.MINUTES);
_itMgr.registerGuru(VirtualMachine.Type.ElasticLoadBalancerVm, this);
}
loadBalanceRuleHandler = new LoadBalanceRuleHandler(_instance, _systemAcct);
return true;
}
private DomainRouterVO stop(DomainRouterVO elbVm, boolean forced) throws ConcurrentOperationException, ResourceUnavailableException {
s_logger.debug("Stopping ELB vm " + elbVm);
try {
_itMgr.advanceStop(elbVm.getUuid(), forced);
return _routerDao.findById(elbVm.getId());
} catch (OperationTimedoutException e) {
throw new CloudRuntimeException("Unable to stop " + elbVm, e);
}
}
@Override
public LoadBalancer handleCreateLoadBalancerRule(CreateLoadBalancerRuleCmd lb, Account account, long networkId) throws InsufficientAddressCapacityException,
NetworkRuleConflictException {
return loadBalanceRuleHandler.handleCreateLoadBalancerRule(lb, account, networkId);
}
void garbageCollectUnusedElbVms() {
List<DomainRouterVO> unusedElbVms = _elbVmMapDao.listUnusedElbVms();
if (unusedElbVms != null) {
if (unusedElbVms.size() > 0) {
s_logger.info("Found " + unusedElbVms.size() + " unused ELB vms");
}
Set<Long> currentGcCandidates = new HashSet<Long>();
for (DomainRouterVO elbVm : unusedElbVms) {
currentGcCandidates.add(elbVm.getId());
}
_gcCandidateElbVmIds.retainAll(currentGcCandidates);
currentGcCandidates.removeAll(_gcCandidateElbVmIds);
for (Long elbVmId : _gcCandidateElbVmIds) {
DomainRouterVO elbVm = _routerDao.findById(elbVmId);
boolean gceed = false;
try {
s_logger.info("Attempting to stop ELB VM: " + elbVm);
stop(elbVm, true);
gceed = true;
} catch (ConcurrentOperationException e) {
s_logger.warn("Unable to stop unused ELB vm " + elbVm + " due to ", e);
} catch (ResourceUnavailableException e) {
s_logger.warn("Unable to stop unused ELB vm " + elbVm + " due to ", e);
continue;
}
if (gceed) {
try {
s_logger.info("Attempting to destroy ELB VM: " + elbVm);
_itMgr.expunge(elbVm.getUuid());
_routerDao.remove(elbVm.getId());
} catch (ResourceUnavailableException e) {
s_logger.warn("Unable to destroy unused ELB vm " + elbVm + " due to ", e);
gceed = false;
}
}
if (!gceed) {
currentGcCandidates.add(elbVm.getId());
}
}
_gcCandidateElbVmIds = currentGcCandidates;
}
}
public class CleanupThread extends ManagedContextRunnable {
@Override
protected void runInContext() {
garbageCollectUnusedElbVms();
}
CleanupThread() {
}
}
@Override
public void handleDeleteLoadBalancerRule(LoadBalancer lb, long userId, Account caller) {
if (!_enabled) {
return;
}
loadBalanceRuleHandler.handleDeleteLoadBalancerRule(lb, userId, caller);
}
@Override
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
List<NicProfile> elbNics = profile.getNics();
Long guestNtwkId = null;
for (NicProfile routerNic : elbNics) {
if (routerNic.getTrafficType() == TrafficType.Guest) {
guestNtwkId = routerNic.getNetworkId();
break;
}
}
NetworkVO guestNetwork = _networkDao.findById(guestNtwkId);
DataCenter dc = dest.getDataCenter();
StringBuilder buf = profile.getBootArgsBuilder();
buf.append(" template=domP type=" + SystemVmType);
buf.append(" name=").append(profile.getHostName());
NicProfile controlNic = null;
String defaultDns1 = null;
String defaultDns2 = null;
for (NicProfile nic : profile.getNics()) {
int deviceId = nic.getDeviceId();
buf.append(" eth").append(deviceId).append("ip=").append(nic.getIPv4Address());
buf.append(" eth").append(deviceId).append("mask=").append(nic.getIPv4Netmask());
if (nic.isDefaultNic()) {
buf.append(" gateway=").append(nic.getIPv4Gateway());
defaultDns1 = nic.getIPv4Dns1();
defaultDns2 = nic.getIPv4Dns2();
}
if (nic.getTrafficType() == TrafficType.Management) {
buf.append(" localgw=").append(dest.getPod().getGateway());
} else if (nic.getTrafficType() == TrafficType.Control) {
// control command is sent over management network in VMware
if (dest.getHost().getHypervisorType() == HypervisorType.VMware) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Check if we need to add management server explicit route to ELB vm. pod cidr: " + dest.getPod().getCidrAddress() + "/"
+ dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: "
+ ApiServiceConfiguration.ManagementServerAddresses.value());
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Added management server explicit route to ELB vm.");
}
// always add management explicit route, for basic networking setup
buf.append(" mgmtcidr=").append(_mgmtCidr);
buf.append(" localgw=").append(dest.getPod().getGateway());
if (dc.getNetworkType() == NetworkType.Basic) {
// ask elb vm to setup SSH on guest network
buf.append(" sshonguest=true");
}
}
controlNic = nic;
}
}
String domain = guestNetwork.getNetworkDomain();
if (domain != null) {
buf.append(" domain=" + domain);
}
buf.append(" dns1=").append(defaultDns1);
if (defaultDns2 != null) {
buf.append(" dns2=").append(defaultDns2);
}
String msPublicKey = _configDao.getValue("ssh.publickey");
buf.append(" authorized_key=").append(VirtualMachineGuru.getEncodedMsPublicKey(msPublicKey));
if (s_logger.isDebugEnabled()) {
s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
}
if (controlNic == null) {
throw new CloudRuntimeException("Didn't start a control port");
}
return true;
}
@Override
public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException {
DomainRouterVO elbVm = _routerDao.findById(profile.getVirtualMachine().getId());
List<NicProfile> nics = profile.getNics();
for (NicProfile nic : nics) {
if (nic.getTrafficType() == TrafficType.Public) {
elbVm.setPublicIpAddress(nic.getIPv4Address());
elbVm.setPublicNetmask(nic.getIPv4Netmask());
elbVm.setPublicMacAddress(nic.getMacAddress());
} else if (nic.getTrafficType() == TrafficType.Control) {
elbVm.setPrivateIpAddress(nic.getIPv4Address());
elbVm.setPrivateMacAddress(nic.getMacAddress());
}
}
_routerDao.update(elbVm.getId(), elbVm);
finalizeCommandsOnStart(cmds, profile);
return true;
}
@Override
public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
if (answer == null || !answer.getResult()) {
s_logger.warn("Unable to ssh to the ELB VM: " + (answer != null ? answer.getDetails() : "No answer (answer for \"checkSsh\" was null)"));
return false;
}
return true;
}
@Override
public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
DomainRouterVO elbVm = _routerDao.findById(profile.getVirtualMachine().getId());
DataCenterVO dcVo = _dcDao.findById(elbVm.getDataCenterId());
NicProfile controlNic = null;
Long guestNetworkId = null;
if (profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) {
// TODO this is a ugly to test hypervisor type here
// for basic network mode, we will use the guest NIC for control NIC
for (NicProfile nic : profile.getNics()) {
if (nic.getTrafficType() == TrafficType.Guest && nic.getIPv4Address() != null) {
controlNic = nic;
guestNetworkId = nic.getNetworkId();
}
}
} else {
for (NicProfile nic : profile.getNics()) {
if (nic.getTrafficType() == TrafficType.Control && nic.getIPv4Address() != null) {
controlNic = nic;
} else if (nic.getTrafficType() == TrafficType.Guest) {
guestNetworkId = nic.getNetworkId();
}
}
}
if (controlNic == null) {
s_logger.error("Control network doesn't exist for the ELB vm " + elbVm);
return false;
}
cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIPv4Address(), 3922));
// Re-apply load balancing rules
List<LoadBalancerVO> lbs = _elbVmMapDao.listLbsForElbVm(elbVm.getId());
List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
for (LoadBalancerVO lb : lbs) {
List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp);
lbRules.add(loadBalancing);
}
s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of ELB vm " + elbVm + " start.");
if (!lbRules.isEmpty()) {
createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds, guestNetworkId);
}
return true;
}
@Override
public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
if (answer != null) {
DomainRouterVO elbVm = _routerDao.findById(profile.getVirtualMachine().getId());
processStopOrRebootAnswer(elbVm, answer);
}
}
@SuppressWarnings("unused")
public void processStopOrRebootAnswer(final DomainRouterVO elbVm, Answer answer) {
//TODO: process network usage stats
}
@Override
public void finalizeExpunge(VirtualMachine vm) {
// no-op
}
@Override
public void prepareStop(VirtualMachineProfile profile) {
}
@Override
public void finalizeUnmanage(VirtualMachine vm) {
}
}