@Override public boolean applyLoadBalancerRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException { if (rules == null || rules.isEmpty()) { return true; } if (rules.get(0).getPurpose() != Purpose.LoadBalancing) { s_logger.warn("ELB: Not handling non-LB firewall rules"); return false; } 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 List<LoadBalancerVO> lbs = _lbDao.listByIpAddress(rules.get(0).getSourceIpAddressId()); 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()); LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); 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 finalizeCommandsOnStart( Commands cmds, VirtualMachineProfile<DomainRouterVO> profile) { DomainRouterVO elbVm = profile.getVirtualMachine(); 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.getIp4Address() != null) { controlNic = nic; guestNetworkId = nic.getNetworkId(); } } } else { for (NicProfile nic : profile.getNics()) { if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != 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.getIp4Address(), 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()); LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList); 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 @DB public LoadBalancer handleCreateLoadBalancerRule( CreateLoadBalancerRuleCmd lb, Account account, long networkId) throws InsufficientAddressCapacityException, NetworkRuleConflictException { // this part of code is executed when the LB provider is Elastic Load Balancer vm if (!_networkModel.isProviderSupportServiceInNetwork( lb.getNetworkId(), Service.Lb, Provider.ElasticLoadBalancerVm)) { return null; } Long ipId = lb.getSourceIpAddressId(); if (ipId != null) { return null; } boolean newIp = false; account = _accountDao.acquireInLockTable(account.getId()); if (account == null) { s_logger.warn("ELB: CreateLoadBalancer: Failed to acquire lock on account"); throw new CloudRuntimeException("Failed to acquire lock on account"); } try { List<LoadBalancerVO> existingLbs = findExistingLoadBalancers( lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), lb.getSourcePortStart()); if (existingLbs == null) { existingLbs = findExistingLoadBalancers( lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), null); if (existingLbs == null) { if (lb.getSourceIpAddressId() != null) { existingLbs = findExistingLoadBalancers( lb.getName(), null, lb.getAccountId(), lb.getDomainId(), null); if (existingLbs != null) { throw new InvalidParameterValueException( "Supplied LB name " + lb.getName() + " is not associated with IP " + lb.getSourceIpAddressId()); } } else { s_logger.debug( "Could not find any existing frontend ips for this account for this LB rule, acquiring a new frontent IP for ELB"); PublicIp ip = allocDirectIp(account, networkId); ipId = ip.getId(); newIp = true; } } else { ipId = existingLbs.get(0).getSourceIpAddressId(); s_logger.debug( "ELB: Found existing frontend ip for this account for this LB rule " + ipId); } } else { s_logger.warn("ELB: Found existing load balancers matching requested new LB"); throw new NetworkRuleConflictException( "ELB: Found existing load balancers matching requested new LB"); } Network network = _networkModel.getNetwork(networkId); IPAddressVO ipAddr = _ipAddressDao.findById(ipId); LoadBalancer result = null; try { lb.setSourceIpAddressId(ipId); result = _lbMgr.createLoadBalancer(lb, false); } catch (NetworkRuleConflictException e) { s_logger.warn("Failed to create LB rule, not continuing with ELB deployment"); if (newIp) { releaseIp(ipId, UserContext.current().getCallerUserId(), account); } throw e; } DomainRouterVO elbVm = null; if (existingLbs == null) { elbVm = findELBVmWithCapacity(network, ipAddr); if (elbVm == null) { elbVm = deployLoadBalancerVM(networkId, ipAddr, account.getId()); if (elbVm == null) { s_logger.warn( "Failed to deploy a new ELB vm for ip " + ipAddr + " in network " + network + "lb name=" + lb.getName()); if (newIp) releaseIp(ipId, UserContext.current().getCallerUserId(), account); } } } else { ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(ipId); if (elbVmMap != null) { elbVm = _routerDao.findById(elbVmMap.getElbVmId()); } } if (elbVm == null) { s_logger.warn("No ELB VM can be found or deployed"); s_logger.warn("Deleting LB since we failed to deploy ELB VM"); _lbDao.remove(result.getId()); return null; } ElasticLbVmMapVO mapping = new ElasticLbVmMapVO(ipId, elbVm.getId(), result.getId()); _elbVmMapDao.persist(mapping); return result; } finally { if (account != null) { _accountDao.releaseFromLockTable(account.getId()); } } }