protected DomainRouterVO findElbVmForLb(FirewallRule lb) { // TODO: use a table to lookup ElasticLbVmMapVO map = _elbVmMapDao.findOneByIp(lb.getSourceIpAddressId()); if (map == null) { return null; } DomainRouterVO elbVm = _routerDao.findById(map.getElbVmId()); return elbVm; }
private DomainRouterVO findELBVmWithCapacity(Network guestNetwork, IPAddressVO ipAddr) { List<DomainRouterVO> unusedElbVms = _elbVmMapDao.listUnusedElbVms(); if (unusedElbVms.size() > 0) { List<DomainRouterVO> candidateVms = new ArrayList<DomainRouterVO>(); for (DomainRouterVO candidateVm : unusedElbVms) { if (candidateVm.getPodIdToDeployIn() == getPodIdForDirectIp(ipAddr)) candidateVms.add(candidateVm); } return candidateVms.size() == 0 ? null : candidateVms.get(new Random().nextInt(candidateVms.size())); } return null; }
void garbageCollectUnusedElbVms() { List<DomainRouterVO> unusedElbVms = _elbVmMapDao.listUnusedElbVms(); if (unusedElbVms != null && 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); User user = _accountService.getSystemUser(); 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, user, _systemAcct); 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, user, _systemAcct); } 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; }
@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()); } } }