mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
WIP: make creating an ELB bullet proof
This commit is contained in:
parent
b999980ce8
commit
b240c4a645
@ -126,55 +126,17 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCmd /*implements LoadBa
|
||||
return s_name;
|
||||
}
|
||||
|
||||
protected LoadBalancer findExistingLB() {
|
||||
List<? extends LoadBalancer> lbs = _lbService.searchForLoadBalancers(new ListLoadBalancerRulesCmd(getAccountName(), getDomainId(), null, getName(), publicIpId, null, getZoneId()) );
|
||||
if (lbs != null && lbs.size() > 0) {
|
||||
return lbs.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void allocateIp() throws ResourceAllocationException, ResourceUnavailableException {
|
||||
AssociateIPAddrCmd allocIpCmd = new AssociateIPAddrCmd(getAccountName(), getDomainId(), getZoneId(), null);
|
||||
try {
|
||||
IpAddress ip = _networkService.allocateIP(allocIpCmd);
|
||||
if (ip != null) {
|
||||
this.setPublicIpId(ip.getId());
|
||||
allocIpCmd.setEntityId(ip.getId());
|
||||
} else {
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to allocate ip address");
|
||||
}
|
||||
//UserContext.current().setEventDetails("Ip Id: "+ ip.getId());
|
||||
//IpAddress result = _networkService.associateIP(allocIpCmd);
|
||||
} catch (ConcurrentOperationException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
|
||||
} catch (InsufficientAddressCapacityException ex) {
|
||||
s_logger.info(ex);
|
||||
s_logger.trace(ex);
|
||||
throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceAllocationException, ResourceUnavailableException {
|
||||
LoadBalancer result = null;
|
||||
try {
|
||||
if (publicIpId == null) {
|
||||
if (getZoneId() == null ) {
|
||||
throw new InvalidParameterValueException("Either zone id or public ip id needs to be specified");
|
||||
}
|
||||
LoadBalancer existing = findExistingLB();
|
||||
if (existing == null) {
|
||||
allocateIp();
|
||||
} else {
|
||||
this.setPublicIpId(existing.getSourceIpAddressId());
|
||||
}
|
||||
}
|
||||
result = _lbService.createLoadBalancerRule(this);
|
||||
} catch (NetworkRuleConflictException e) {
|
||||
s_logger.warn("Exception: ", e);
|
||||
throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
|
||||
} catch (InsufficientAddressCapacityException e) {
|
||||
s_logger.warn("Exception: ", e);
|
||||
throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, e.getMessage());
|
||||
}
|
||||
LoadBalancerResponse response = _responseGenerator.createLoadBalancerResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -23,6 +23,7 @@ import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
|
||||
import com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd;
|
||||
import com.cloud.api.commands.ListLoadBalancerRulesCmd;
|
||||
import com.cloud.api.commands.UpdateLoadBalancerRuleCmd;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.rules.LoadBalancer;
|
||||
@ -33,8 +34,9 @@ public interface LoadBalancingRulesService {
|
||||
* Create a load balancer rule from the given ipAddress/port to the given private port
|
||||
* @param cmd the command specifying the ip address, public port, protocol, private port, and algorithm
|
||||
* @return the newly created LoadBalancerVO if successful, null otherwise
|
||||
* @throws InsufficientAddressCapacityException
|
||||
*/
|
||||
LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb) throws NetworkRuleConflictException;
|
||||
LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb) throws NetworkRuleConflictException, InsufficientAddressCapacityException;
|
||||
|
||||
LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd);
|
||||
|
||||
|
||||
@ -22,25 +22,37 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.NetworkVO;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.GuestIpType;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
import com.cloud.network.addr.PublicIp;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.lb.ElasticLoadBalancerManager;
|
||||
import com.cloud.network.lb.LoadBalancerElement;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.vm.NicProfile;
|
||||
@ -53,12 +65,16 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
public class ElasticLoadBalancerElement extends AdapterBase implements NetworkElement{
|
||||
private static final Logger s_logger = Logger.getLogger(ElasticLoadBalancerElement.class);
|
||||
private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
|
||||
@Inject ConfigurationManager _configMgr;
|
||||
@Inject NetworkManager _networkManager;
|
||||
@Inject ElasticLoadBalancerManager _lbMgr;
|
||||
@Inject ConfigurationDao _configDao;
|
||||
@Inject NetworkOfferingDao _networkOfferingDao;
|
||||
@Inject NetworkDao _networksDao;
|
||||
|
||||
boolean _enabled;
|
||||
TrafficType _frontEndTrafficType = TrafficType.Guest;
|
||||
|
||||
private boolean canHandle(Network network) {
|
||||
// DataCenter zone = _configMgr.getZone(network.getDataCenterId());
|
||||
if (network.getGuestType() != Network.GuestIpType.Direct || network.getTrafficType() != TrafficType.Guest) {
|
||||
s_logger.debug("Not handling network with guest Type " + network.getGuestType() + " and traffic type " + network.getTrafficType());
|
||||
return false;
|
||||
@ -140,4 +156,23 @@ public class ElasticLoadBalancerElement extends AdapterBase implements NetworkEl
|
||||
|
||||
return _lbMgr.applyLoadBalancerRules(network, rules);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
|
||||
super.configure(name, params);
|
||||
String enabled = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
|
||||
_enabled = (enabled == null) ? false: Boolean.parseBoolean(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("Traffic type for front end of load balancer has to be guest or public; found : " + traffType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
@ -38,6 +39,6 @@ public interface ElasticLoadBalancerManager {
|
||||
List<? extends FirewallRule> rules)
|
||||
throws ResourceUnavailableException;
|
||||
|
||||
public void handleCreateLoadBalancerRule(CreateLoadBalancerRuleCmd lb, Account caller);
|
||||
public LoadBalancer handleCreateLoadBalancerRule(CreateLoadBalancerRuleCmd lb, Account caller) throws InsufficientAddressCapacityException;
|
||||
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.PodVlanMapVO;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
@ -52,8 +53,10 @@ import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
@ -62,6 +65,7 @@ import com.cloud.network.IPAddressVO;
|
||||
import com.cloud.network.LoadBalancerVO;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.GuestIpType;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.NetworkVO;
|
||||
import com.cloud.network.addr.PublicIp;
|
||||
@ -86,11 +90,16 @@ import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicProfile;
|
||||
@ -150,10 +159,17 @@ public class ElasticLoadBalancerManagerImpl implements
|
||||
PodVlanMapDao _podVlanMapDao;
|
||||
@Inject
|
||||
ElasticLbVmMapDao _elbVmMapDao;
|
||||
@Inject
|
||||
NetworkDao _networksDao;
|
||||
@Inject
|
||||
AccountDao _accountDao;
|
||||
|
||||
|
||||
String _name;
|
||||
String _instance;
|
||||
|
||||
boolean _enabled;
|
||||
TrafficType _frontendTrafficType = TrafficType.Guest;
|
||||
|
||||
Account _systemAcct;
|
||||
ServiceOfferingVO _elasticLbVmOffering;
|
||||
@ -340,6 +356,18 @@ public class ElasticLoadBalancerManagerImpl implements
|
||||
_elasticLbVmOffering.setUniqueName("Cloud.Com-ElasticLBVm");
|
||||
_elasticLbVmOffering = _serviceOfferingDao.persistSystemServiceOffering(_elasticLbVmOffering);
|
||||
|
||||
String enabled = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
|
||||
_enabled = (enabled == null) ? false: Boolean.parseBoolean(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("Traffic type for front end of load balancer has to be guest or public; found : " + traffType);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -441,52 +469,153 @@ public class ElasticLoadBalancerManagerImpl implements
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<LoadBalancerVO> findExistingLoadBalancers(String lbName, Long ipId, Long accountId, Long domainId, Integer publicPort) {
|
||||
SearchBuilder<LoadBalancerVO> sb = _lbDao.createSearchBuilder();
|
||||
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
|
||||
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ);
|
||||
if (ipId != null) {
|
||||
sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
if (domainId != null) {
|
||||
sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
if (publicPort != null) {
|
||||
sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
SearchCriteria<LoadBalancerVO> sc = sb.create();
|
||||
sc.setParameters("name", lbName);
|
||||
sc.setParameters("accountId", accountId);
|
||||
if (ipId != null) {
|
||||
sc.setParameters("sourceIpAddress", ipId);
|
||||
}
|
||||
if (domainId != null) {
|
||||
sc.setParameters("domainId",domainId);
|
||||
}
|
||||
if (publicPort != null) {
|
||||
sc.setParameters("publicPort", publicPort);
|
||||
}
|
||||
List<LoadBalancerVO> lbs = _lbDao.search(sc, null);
|
||||
|
||||
return lbs == null || lbs.size()==0 ? null: lbs;
|
||||
}
|
||||
|
||||
@DB
|
||||
public PublicIp allocIp(CreateLoadBalancerRuleCmd lb, Account account) throws InsufficientAddressCapacityException {
|
||||
//TODO: this only works in the guest network. Handle the public network case also.
|
||||
List<NetworkOfferingVO> offerings = _networkOfferingDao.listByTrafficTypeAndGuestType(true, _frontendTrafficType, GuestIpType.Direct);
|
||||
if (offerings == null || offerings.size() == 0) {
|
||||
s_logger.warn("Could not find system offering for direct networks of type " + _frontendTrafficType);
|
||||
return null;
|
||||
}
|
||||
NetworkOffering frontEndOffering = offerings.get(0);
|
||||
List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, frontEndOffering.getId(), lb.getZoneId());
|
||||
if (networks == null || networks.size() == 0) {
|
||||
s_logger.warn("Could not find network of offering type " + frontEndOffering + " in zone " + lb.getZoneId());
|
||||
return null;
|
||||
}
|
||||
Network frontEndNetwork = networks.get(0);
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
PublicIp ip = _networkMgr.assignPublicIpAddress(lb.getZoneId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null);
|
||||
IPAddressVO ipvo = _ipAddressDao.findById(ip.getId());
|
||||
ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId());
|
||||
_ipAddressDao.update(ipvo.getId(), ipvo);
|
||||
txn.commit();
|
||||
s_logger.info("Acquired public IP for loadbalancing " + ip);
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void releaseIp(long ipId, long userId, Account caller) {
|
||||
s_logger.info("Release public IP for loadbalancing " + ipId);
|
||||
_networkMgr.releasePublicIpAddress(ipId, userId, caller);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public void handleCreateLoadBalancerRule( CreateLoadBalancerRuleCmd lb, Account account) {
|
||||
|
||||
long ipId = lb.getSourceIpAddressId();
|
||||
IPAddressVO ipAddr = _ipAddressDao.findById(ipId);
|
||||
Long networkId= ipAddr.getSourceNetworkId();
|
||||
NetworkVO network=_networkDao.findById(networkId);
|
||||
|
||||
if (network.getGuestType() != GuestIpType.Direct) {
|
||||
s_logger.info("Elastic LB Manager: not handling guest traffic of type " + network.getGuestType());
|
||||
return;
|
||||
public LoadBalancer handleCreateLoadBalancerRule( CreateLoadBalancerRuleCmd lb, Account account) throws InsufficientAddressCapacityException {
|
||||
Long ipId = lb.getSourceIpAddressId();
|
||||
boolean newIp = false;
|
||||
account = _accountDao.acquireInLockTable(account.getId());
|
||||
if (account == null) {
|
||||
s_logger.warn("CreateLoadBalancer: Failed to acquire lock on account");
|
||||
}
|
||||
DomainRouterVO elbVm = null;
|
||||
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 {
|
||||
PublicIp ip = allocIp(lb, account);
|
||||
ipId = ip.getId();
|
||||
newIp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadBalancerVO lbvo;
|
||||
lbvo = _lbDao.findByAccountAndName(account.getId(), lb.getName());
|
||||
if (lbvo == null) {
|
||||
elbVm = findELBVmWithCapacity(network, ipAddr);
|
||||
if (elbVm == null) {
|
||||
elbVm = deployLoadBalancerVM(networkId, ipAddr, account.getId());
|
||||
IPAddressVO ipAddr = _ipAddressDao.findById(ipId);
|
||||
Long networkId= ipAddr.getSourceNetworkId();
|
||||
NetworkVO network=_networkDao.findById(networkId);
|
||||
|
||||
|
||||
if (network.getGuestType() != GuestIpType.Direct) {
|
||||
s_logger.info("Elastic LB Manager: not handling guest traffic of type " + network.getGuestType());
|
||||
return null;
|
||||
}
|
||||
LoadBalancer result = null;
|
||||
try {
|
||||
result = _lbMgr.createLoadBalancer(lb);
|
||||
} catch (NetworkRuleConflictException e) {
|
||||
s_logger.warn("Failed to create LB rule, not continuing with ELB deployment");
|
||||
if (newIp) {
|
||||
releaseIp(ipId, UserContext.current().getCallerUserId(), account);
|
||||
}
|
||||
}
|
||||
|
||||
DomainRouterVO elbVm = null;
|
||||
|
||||
|
||||
if (existingLbs == null) {
|
||||
elbVm = findELBVmWithCapacity(network, ipAddr);
|
||||
if (elbVm == null) {
|
||||
s_logger.warn("Failed to deploy a new ELB vm for ip " + ipAddr + " in network " + network + "lb name=" + lb.getName());
|
||||
return; //TODO: throw exception
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(lb.getSourceIpAddressId());
|
||||
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());
|
||||
_elbVmMapDao.persist(mapping);
|
||||
return result;
|
||||
|
||||
} finally {
|
||||
if (account != null) {
|
||||
_accountDao.releaseFromLockTable(account.getId());
|
||||
}
|
||||
}
|
||||
if (elbVm == null) {
|
||||
s_logger.warn("No ELB VM can be found or deployed");
|
||||
return;
|
||||
}
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
IPAddressVO ipvo = _ipAddressDao.findById(ipId);
|
||||
ipvo.setAssociatedWithNetworkId(networkId);
|
||||
_ipAddressDao.update(ipvo.getId(), ipvo);
|
||||
ElasticLbVmMapVO mapping = new ElasticLbVmMapVO(ipId, elbVm.getId());
|
||||
_elbVmMapDao.persist(mapping);
|
||||
txn.commit();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -19,11 +19,17 @@ package com.cloud.network.lb;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
|
||||
import com.cloud.network.rules.LoadBalancer;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
public interface LoadBalancingRulesManager extends LoadBalancingRulesService {
|
||||
|
||||
LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb) throws NetworkRuleConflictException;
|
||||
|
||||
boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId);
|
||||
boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId);
|
||||
List<LbDestination> getExistingDestinations(long lbId);
|
||||
|
||||
@ -43,6 +43,7 @@ import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.UsageEventVO;
|
||||
import com.cloud.event.dao.EventDao;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
@ -60,6 +61,7 @@ import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.LoadBalancerDao;
|
||||
import com.cloud.network.dao.LoadBalancerVMMapDao;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
@ -72,6 +74,7 @@ import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Adapters;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.db.DB;
|
||||
@ -126,7 +129,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
ElasticLoadBalancerManager _elbMgr;
|
||||
@Inject
|
||||
NetworkDao _networkDao;
|
||||
|
||||
@Inject(adapter = LoadBalancerElement.class)
|
||||
Adapters<LoadBalancerElement> _lbElements;
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true)
|
||||
@ -347,26 +352,11 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer")
|
||||
public LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb) throws NetworkRuleConflictException {
|
||||
public LoadBalancer createLoadBalancerRule(CreateLoadBalancerRuleCmd lb) throws NetworkRuleConflictException, InsufficientAddressCapacityException {
|
||||
UserContext caller = UserContext.current();
|
||||
|
||||
long ipId = lb.getSourceIpAddressId();
|
||||
|
||||
|
||||
_elbMgr.handleCreateLoadBalancerRule(lb, caller.getCaller());
|
||||
|
||||
|
||||
IPAddressVO ipAddr = _ipAddressDao.findById(ipId);
|
||||
Long networkId= ipAddr.getSourceNetworkId();
|
||||
NetworkVO network=_networkDao.findById(networkId);
|
||||
// make sure ip address exists
|
||||
if (ipAddr == null || !ipAddr.readyToUse()) {
|
||||
throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id" + ipId);
|
||||
}
|
||||
|
||||
int srcPortStart = lb.getSourcePortStart();
|
||||
int srcPortEnd = lb.getSourcePortEnd();
|
||||
int defPortStart = lb.getDefaultPortStart();
|
||||
@ -394,6 +384,31 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager,
|
||||
throw new InvalidParameterValueException("Invalid algorithm: " + lb.getAlgorithm());
|
||||
}
|
||||
|
||||
Long ipId = lb.getSourceIpAddressId();
|
||||
|
||||
if (ipId == null) {
|
||||
return _elbMgr.handleCreateLoadBalancerRule(lb, caller.getCaller());
|
||||
|
||||
} else {
|
||||
return createLoadBalancer(lb);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public LoadBalancer createLoadBalancer(CreateLoadBalancerRuleCmd lb) throws NetworkRuleConflictException {
|
||||
long ipId = lb.getSourceIpAddressId();
|
||||
UserContext caller = UserContext.current();
|
||||
int srcPortStart = lb.getSourcePortStart();
|
||||
int defPortStart = lb.getDefaultPortStart();
|
||||
|
||||
IPAddressVO ipAddr = _ipAddressDao.findById(lb.getSourceIpAddressId());
|
||||
Long networkId = ipAddr.getSourceNetworkId();
|
||||
NetworkVO network = _networkDao.findById(networkId);
|
||||
// make sure ip address exists
|
||||
if (ipAddr == null || !ipAddr.readyToUse()) {
|
||||
throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id" + ipId);
|
||||
}
|
||||
|
||||
networkId = ipAddr.getAssociatedWithNetworkId();
|
||||
if (networkId == null) {
|
||||
throw new InvalidParameterValueException("Unable to create load balancer rule ; ip id=" + ipId + " is not associated with any network");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user