Search in sources :

Example 1 with InsufficientNetworkCapacityException

use of com.cloud.exception.InsufficientNetworkCapacityException in project cloudstack by apache.

the class NetscalerElement method manageGuestNetworkWithNetscalerControlCenter.

public boolean manageGuestNetworkWithNetscalerControlCenter(boolean add, Network guestConfig, NetworkOffering offering) throws ResourceUnavailableException, InsufficientCapacityException, ConfigurationException {
    if (guestConfig.getTrafficType() != TrafficType.Guest) {
        s_logger.trace("External load balancer can only be used for guest networks.");
        return false;
    }
    long zoneId = guestConfig.getDataCenterId();
    DataCenterVO zone = _dcDao.findById(zoneId);
    HostVO netscalerControlCenter = null;
    if (add) {
        HostVO lbDeviceVO = null;
        // on restart network, device could have been allocated already,
        // skip allocation if a device is assigned
        lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig);
        if (lbDeviceVO == null) {
            // allocate a load balancer device for the network
            lbDeviceVO = allocateNCCResourceForNetwork(guestConfig);
            if (lbDeviceVO == null) {
                String msg = "failed to allocate Netscaler ControlCenter Resource for the zone in the network " + guestConfig.getId();
                s_logger.error(msg);
                throw new InsufficientNetworkCapacityException(msg, DataCenter.class, guestConfig.getDataCenterId());
            }
        }
        netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId());
        s_logger.debug("Allocated Netscaler Control Center device:" + lbDeviceVO.getId() + " for the network: " + guestConfig.getId());
    } else {
        // find the load balancer device allocated for the network
        HostVO lbDeviceVO = null;
        // on restart network, device could have been allocated already, skip allocation if a device is assigned
        lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig);
        if (lbDeviceVO == null) {
            s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network." + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
            return true;
        }
        netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId());
        assert (netscalerControlCenter != null) : "There is no device assigned to this network how did shutdown network ended up here??";
    }
    JSONObject networkDetails = new JSONObject();
    JSONObject networkPayload = new JSONObject();
    String selfIp = null;
    try {
        networkDetails.put("id", guestConfig.getId());
        networkDetails.put("vlan", guestConfig.getBroadcastUri());
        networkDetails.put("cidr", guestConfig.getCidr());
        networkDetails.put("gateway", guestConfig.getGateway());
        networkDetails.put("servicepackage_id", offering.getServicePackage());
        networkDetails.put("zone_id", zone.getUuid());
        networkDetails.put("account_id", guestConfig.getAccountId());
        networkDetails.put("add", Boolean.toString(add));
        selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null);
        if (selfIp == null) {
            String msg = "failed to acquire guest IP address so not implementing the network on the NetscalerControlCenter";
            s_logger.error(msg);
            throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId());
        }
        networkDetails.put("snip", selfIp);
        // TODO region is hardcoded make it dynamic
        networkDetails.put("region_id", 1);
        networkDetails.put("name", guestConfig.getName());
        networkPayload.put("network", networkDetails);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zone.getUuid(), netscalerControlCenter.getId(), networkPayload.toString());
    Answer answer = _agentMgr.easySend(netscalerControlCenter.getId(), cmd);
    if (add) {
        // TODO After getting the answer check with the job id and do poll on the job and then save the selfip or acquired guest ip to the Nics table
        if (answer != null) {
            if (answer.getResult() == true) {
                if (add) {
                    // Insert a new NIC for this guest network to reserve the self IP
                    _networkService.savePlaceholderNic(guestConfig, selfIp, null, null);
                }
            } else {
                return false;
            }
        }
    } else {
        if (answer != null) {
            if (answer.getResult() == true) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }
    return true;
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) Answer(com.cloud.agent.api.Answer) SetStaticNatRulesAnswer(com.cloud.agent.api.routing.SetStaticNatRulesAnswer) HealthCheckLBConfigAnswer(com.cloud.agent.api.routing.HealthCheckLBConfigAnswer) JSONObject(org.json.JSONObject) JSONException(org.json.JSONException) NetScalerImplementNetworkCommand(com.cloud.agent.api.NetScalerImplementNetworkCommand) HostVO(com.cloud.host.HostVO)

Example 2 with InsufficientNetworkCapacityException

use of com.cloud.exception.InsufficientNetworkCapacityException in project cloudstack by apache.

the class ExternalLoadBalancerDeviceManagerImpl method manageGuestNetworkWithExternalLoadBalancer.

@Override
public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException {
    if (guestConfig.getTrafficType() != TrafficType.Guest) {
        s_logger.trace("External load balancer can only be used for guest networks.");
        return false;
    }
    long zoneId = guestConfig.getDataCenterId();
    DataCenterVO zone = _dcDao.findById(zoneId);
    HostVO externalLoadBalancer = null;
    if (add) {
        ExternalLoadBalancerDeviceVO lbDeviceVO = null;
        // on restart network, device could have been allocated already, skip allocation if a device is assigned
        lbDeviceVO = getExternalLoadBalancerForNetwork(guestConfig);
        if (lbDeviceVO == null) {
            // allocate a load balancer device for the network
            lbDeviceVO = allocateLoadBalancerForNetwork(guestConfig);
            if (lbDeviceVO == null) {
                String msg = "failed to alloacate a external load balancer for the network " + guestConfig.getId();
                s_logger.error(msg);
                throw new InsufficientNetworkCapacityException(msg, DataCenter.class, guestConfig.getDataCenterId());
            }
        }
        externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
        s_logger.debug("Allocated external load balancer device:" + lbDeviceVO.getId() + " for the network: " + guestConfig.getId());
    } else {
        // find the load balancer device allocated for the network
        ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(guestConfig);
        if (lbDeviceVO == null) {
            s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network." + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
            return true;
        }
        externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
        assert (externalLoadBalancer != null) : "There is no device assigned to this network how did shutdown network ended up here??";
    }
    // Send a command to the external load balancer to implement or shutdown the guest network
    String guestVlanTag = BroadcastDomainType.getValue(guestConfig.getBroadcastUri());
    String selfIp = null;
    String guestVlanNetmask = NetUtils.cidr2Netmask(guestConfig.getCidr());
    Integer networkRate = _networkModel.getNetworkRate(guestConfig.getId(), null);
    if (add) {
        // on restart network, network could have already been implemented. If already implemented then return
        Nic selfipNic = getPlaceholderNic(guestConfig);
        if (selfipNic != null) {
            return true;
        }
        // Acquire a self-ip address from the guest network IP address range
        selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null);
        if (selfIp == null) {
            String msg = "failed to acquire guest IP address so not implementing the network on the external load balancer ";
            s_logger.error(msg);
            throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId());
        }
    } else {
        // get the self-ip used by the load balancer
        Nic selfipNic = getPlaceholderNic(guestConfig);
        if (selfipNic == null) {
            s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network." + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
            return true;
        }
        selfIp = selfipNic.getIPv4Address();
    }
    // It's a hack, using isOneToOneNat field for indicate if it's inline or not
    boolean inline = _networkMgr.isNetworkInlineMode(guestConfig);
    IpAddressTO ip = new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, guestVlanTag, selfIp, guestVlanNetmask, null, networkRate, inline);
    IpAddressTO[] ips = new IpAddressTO[1];
    ips[0] = ip;
    IpAssocCommand cmd = new IpAssocCommand(ips);
    Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
    if (answer == null || !answer.getResult()) {
        String action = add ? "implement" : "shutdown";
        String answerDetails = (answer != null) ? answer.getDetails() : null;
        answerDetails = (answerDetails != null) ? " due to " + answerDetails : "";
        String msg = "External load balancer was unable to " + action + " the guest network on the external load balancer in zone " + zone.getName() + answerDetails;
        s_logger.error(msg);
        throw new ResourceUnavailableException(msg, Network.class, guestConfig.getId());
    }
    if (add) {
        // Insert a new NIC for this guest network to reserve the self IP
        _networkMgr.savePlaceholderNic(guestConfig, selfIp, null, null);
    } else {
        // release the self-ip obtained from guest network
        Nic selfipNic = getPlaceholderNic(guestConfig);
        _nicDao.remove(selfipNic.getId());
        // release the load balancer allocated for the network
        boolean releasedLB = freeLoadBalancerForNetwork(guestConfig);
        if (!releasedLB) {
            String msg = "Failed to release the external load balancer used for the network: " + guestConfig.getId();
            s_logger.error(msg);
        }
    }
    if (s_logger.isDebugEnabled()) {
        Account account = _accountDao.findByIdIncludingRemoved(guestConfig.getAccountId());
        String action = add ? "implemented" : "shut down";
        s_logger.debug("External load balancer has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() + ") with VLAN tag " + guestVlanTag);
    }
    return true;
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) Account(com.cloud.user.Account) IpAddressTO(com.cloud.agent.api.to.IpAddressTO) Nic(com.cloud.vm.Nic) HostVO(com.cloud.host.HostVO) ExternalLoadBalancerDeviceVO(com.cloud.network.dao.ExternalLoadBalancerDeviceVO) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) DestroyLoadBalancerApplianceAnswer(com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer) Answer(com.cloud.agent.api.Answer) CreateLoadBalancerApplianceAnswer(com.cloud.network.resource.CreateLoadBalancerApplianceAnswer) HealthCheckLBConfigAnswer(com.cloud.agent.api.routing.HealthCheckLBConfigAnswer) IpAssocCommand(com.cloud.agent.api.routing.IpAssocCommand) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException)

Example 3 with InsufficientNetworkCapacityException

use of com.cloud.exception.InsufficientNetworkCapacityException in project cloudstack by apache.

the class ExternalFirewallDeviceManagerImpl method findSuitableFirewallForNetwork.

@Override
public ExternalFirewallDeviceVO findSuitableFirewallForNetwork(Network network) throws InsufficientCapacityException {
    long physicalNetworkId = network.getPhysicalNetworkId();
    List<ExternalFirewallDeviceVO> fwDevices = _externalFirewallDeviceDao.listByPhysicalNetwork(physicalNetworkId);
    // loop through the firewall device in the physical network and pick the first-fit
    for (ExternalFirewallDeviceVO fwDevice : fwDevices) {
        // max number of guest networks that can be mapped to this device
        long fullCapacity = fwDevice.getCapacity();
        if (fullCapacity == 0) {
            // if capacity not configured then use the default
            fullCapacity = _defaultFwCapacity;
        }
        // get the list of guest networks that are mapped to this load balancer
        List<NetworkExternalFirewallVO> mappedNetworks = _networkExternalFirewallDao.listByFirewallDeviceId(fwDevice.getId());
        long usedCapacity = (mappedNetworks == null) ? 0 : mappedNetworks.size();
        if ((fullCapacity - usedCapacity) > 0) {
            return fwDevice;
        }
    }
    throw new InsufficientNetworkCapacityException("Unable to find a firewall provider with sufficient capcity " + " to implement the network", DataCenter.class, network.getDataCenterId());
}
Also used : InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) ExternalFirewallDeviceVO(com.cloud.network.dao.ExternalFirewallDeviceVO) NetworkExternalFirewallVO(com.cloud.network.dao.NetworkExternalFirewallVO)

Example 4 with InsufficientNetworkCapacityException

use of com.cloud.exception.InsufficientNetworkCapacityException in project cloudstack by apache.

the class ExternalLoadBalancerDeviceManagerImpl method allocateLoadBalancerForNetwork.

@DB
protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(final Network guestConfig) throws InsufficientCapacityException {
    boolean retry = true;
    boolean tryLbProvisioning = false;
    ExternalLoadBalancerDeviceVO lbDevice = null;
    long physicalNetworkId = guestConfig.getPhysicalNetworkId();
    NetworkOfferingVO offering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
    String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(guestConfig.getId(), Service.Lb);
    while (retry) {
        GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
        try {
            if (deviceMapLock.lock(120)) {
                try {
                    // does network offering supports a dedicated load balancer?
                    final boolean dedicatedLB = offering.isDedicatedLB();
                    try {
                        lbDevice = Transaction.execute(new TransactionCallbackWithException<ExternalLoadBalancerDeviceVO, InsufficientCapacityException>() {

                            @Override
                            public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
                                // FIXME: should the device allocation be done during network implement phase or do a
                                // lazy allocation when first rule for the network is configured??
                                // find a load balancer device for this network as per the network offering
                                ExternalLoadBalancerDeviceVO lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB);
                                long lbDeviceId = lbDevice.getId();
                                // persist the load balancer device id that will be used for this network. Once a network
                                // is implemented on a LB device then later on all rules will be programmed on to same device
                                NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId);
                                _networkExternalLBDao.persist(networkLB);
                                // mark device to be either dedicated or shared use
                                lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared);
                                _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice);
                                return lbDevice;
                            }
                        });
                        // allocated load balancer for the network, so skip retry
                        tryLbProvisioning = false;
                        retry = false;
                    } catch (InsufficientCapacityException exception) {
                        // if already attempted to provision load balancer then throw out of capacity exception,
                        if (tryLbProvisioning) {
                            retry = false;
                            // TODO: throwing warning instead of error for now as its possible another provider can service this network
                            s_logger.warn("There are no load balancer device with the capacity for implementing this network");
                            throw exception;
                        } else {
                            // if possible provision a LB appliance in to the physical network
                            tryLbProvisioning = true;
                        }
                    }
                } finally {
                    deviceMapLock.unlock();
                }
            }
        } finally {
            deviceMapLock.releaseRef();
        }
        // there are no LB devices or there is no free capacity on the devices in the physical network so provision a new LB appliance
        if (tryLbProvisioning) {
            // check if LB appliance can be dynamically provisioned
            List<ExternalLoadBalancerDeviceVO> providerLbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Provider);
            if ((providerLbDevices != null) && (!providerLbDevices.isEmpty())) {
                for (ExternalLoadBalancerDeviceVO lbProviderDevice : providerLbDevices) {
                    if (lbProviderDevice.getState() == LBDeviceState.Enabled) {
                        // acquire a private IP from the data center which will be used as management IP of provisioned LB appliance,
                        DataCenterIpAddressVO dcPrivateIp = _dcDao.allocatePrivateIpAddress(guestConfig.getDataCenterId(), lbProviderDevice.getUuid());
                        if (dcPrivateIp == null) {
                            throw new InsufficientNetworkCapacityException("failed to acquire a priavate IP in the zone " + guestConfig.getDataCenterId() + " needed for management IP of the load balancer appliance", DataCenter.class, guestConfig.getDataCenterId());
                        }
                        Pod pod = _podDao.findById(dcPrivateIp.getPodId());
                        String lbIP = dcPrivateIp.getIpAddress();
                        String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
                        String gateway = pod.getGateway();
                        // send CreateLoadBalancerApplianceCommand to the host capable of provisioning
                        CreateLoadBalancerApplianceCommand lbProvisionCmd = new CreateLoadBalancerApplianceCommand(lbIP, netmask, gateway);
                        CreateLoadBalancerApplianceAnswer createLbAnswer = null;
                        try {
                            createLbAnswer = (CreateLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbProvisionCmd);
                            if (createLbAnswer == null || !createLbAnswer.getResult()) {
                                s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId());
                                continue;
                            }
                        } catch (Exception agentException) {
                            s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId() + " due to " + agentException.getMessage());
                            continue;
                        }
                        String username = createLbAnswer.getUsername();
                        String password = createLbAnswer.getPassword();
                        String publicIf = createLbAnswer.getPublicInterface();
                        String privateIf = createLbAnswer.getPrivateInterface();
                        // we have provisioned load balancer so add the appliance as cloudstack provisioned external load balancer
                        String dedicatedLb = offering.isDedicatedLB() ? "true" : "false";
                        String capacity = Long.toString(lbProviderDevice.getCapacity());
                        // acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network)
                        PublicIp publicIp = _ipAddrMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null, null, false, false);
                        String publicIPNetmask = publicIp.getVlanNetmask();
                        String publicIPgateway = publicIp.getVlanGateway();
                        String publicIP = publicIp.getAddress().toString();
                        String publicIPVlanTag = "";
                        try {
                            publicIPVlanTag = BroadcastDomainType.getValue(publicIp.getVlanTag());
                        } catch (URISyntaxException e) {
                            s_logger.error("Failed to parse public ip vlan tag" + e.getMessage());
                        }
                        String url = "https://" + lbIP + "?publicinterface=" + publicIf + "&privateinterface=" + privateIf + "&lbdevicededicated=" + dedicatedLb + "&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&lbdevicecapacity=" + capacity + "&publicipvlan=" + publicIPVlanTag + "&publicipgateway=" + publicIPgateway;
                        ExternalLoadBalancerDeviceVO lbAppliance = null;
                        try {
                            lbAppliance = addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(), createLbAnswer.getServerResource(), false, false, null, null);
                        } catch (Exception e) {
                            s_logger.error("Failed to add load balancer appliance in to cloudstack due to " + e.getMessage() + ". So provisioned load balancer appliance will be destroyed.");
                        }
                        if (lbAppliance != null) {
                            // mark the load balancer as cloudstack managed and set parent host id on which lb appliance is provisioned
                            ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId());
                            managedLb.setIsManagedDevice(true);
                            managedLb.setParentHostId(lbProviderDevice.getHostId());
                            _externalLoadBalancerDeviceDao.update(lbAppliance.getId(), managedLb);
                        } else {
                            // failed to add the provisioned load balancer into cloudstack so destroy the appliance
                            DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
                            DestroyLoadBalancerApplianceAnswer answer = null;
                            try {
                                answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbProviderDevice.getHostId(), lbDeleteCmd);
                                if (answer == null || !answer.getResult()) {
                                    s_logger.warn("Failed to destroy load balancer appliance created");
                                } else {
                                    // release the public & private IP back to dc pool, as the load balancer appliance is now destroyed
                                    _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null);
                                    _ipAddrMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
                                }
                            } catch (Exception e) {
                                s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage());
                            }
                        }
                    }
                }
            }
        }
    }
    return lbDevice;
}
Also used : CreateLoadBalancerApplianceCommand(com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand) Pod(com.cloud.dc.Pod) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) PublicIp(com.cloud.network.addr.PublicIp) DataCenterIpAddressVO(com.cloud.dc.DataCenterIpAddressVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) URISyntaxException(java.net.URISyntaxException) NetworkExternalLoadBalancerVO(com.cloud.network.dao.NetworkExternalLoadBalancerVO) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) URISyntaxException(java.net.URISyntaxException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) ExternalLoadBalancerDeviceVO(com.cloud.network.dao.ExternalLoadBalancerDeviceVO) GlobalLock(com.cloud.utils.db.GlobalLock) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) DestroyLoadBalancerApplianceCommand(com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand) CreateLoadBalancerApplianceAnswer(com.cloud.network.resource.CreateLoadBalancerApplianceAnswer) NetworkOfferingVO(com.cloud.offerings.NetworkOfferingVO) DestroyLoadBalancerApplianceAnswer(com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) DB(com.cloud.utils.db.DB)

Example 5 with InsufficientNetworkCapacityException

use of com.cloud.exception.InsufficientNetworkCapacityException in project cloudstack by apache.

the class ExternalLoadBalancerDeviceManagerImpl method findSuitableLoadBalancerForNetwork.

@Override
public ExternalLoadBalancerDeviceVO findSuitableLoadBalancerForNetwork(Network network, boolean dedicatedLb) throws InsufficientCapacityException {
    long physicalNetworkId = network.getPhysicalNetworkId();
    List<ExternalLoadBalancerDeviceVO> lbDevices = null;
    String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Lb);
    assert (provider != null);
    if (dedicatedLb) {
        lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
        if (lbDevices != null && !lbDevices.isEmpty()) {
            // return first device that is free, fully configured and meant for dedicated use
            for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
                if (lbdevice.getState() == LBDeviceState.Enabled && lbdevice.getIsDedicatedDevice()) {
                    return lbdevice;
                }
            }
        }
    } else {
        // get the LB devices that are already allocated for shared use
        lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Shared);
        if (lbDevices != null) {
            ExternalLoadBalancerDeviceVO maxFreeCapacityLbdevice = null;
            long maxFreeCapacity = 0;
            // loop through the LB device in the physical network and pick the one with maximum free capacity
            for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
                // skip if device is not enabled
                if (lbdevice.getState() != LBDeviceState.Enabled) {
                    continue;
                }
                // get the used capacity from the list of guest networks that are mapped to this load balancer
                List<NetworkExternalLoadBalancerVO> mappedNetworks = _networkExternalLBDao.listByLoadBalancerDeviceId(lbdevice.getId());
                long usedCapacity = ((mappedNetworks == null) || (mappedNetworks.isEmpty())) ? 0 : mappedNetworks.size();
                // get the configured capacity for this device
                long fullCapacity = lbdevice.getCapacity();
                if (fullCapacity == 0) {
                    // if capacity not configured then use the default
                    fullCapacity = _defaultLbCapacity;
                }
                long freeCapacity = fullCapacity - usedCapacity;
                if (freeCapacity > 0) {
                    if (maxFreeCapacityLbdevice == null) {
                        maxFreeCapacityLbdevice = lbdevice;
                        maxFreeCapacity = freeCapacity;
                    } else if (freeCapacity > maxFreeCapacity) {
                        maxFreeCapacityLbdevice = lbdevice;
                        maxFreeCapacity = freeCapacity;
                    }
                }
            }
            // return the device with maximum free capacity and is meant for shared use
            if (maxFreeCapacityLbdevice != null) {
                return maxFreeCapacityLbdevice;
            }
        }
        // if we are here then there are no existing LB devices in shared use or the devices in shared use has no
        // free capacity left
        // so allocate a new load balancer configured for shared use from the pool of free LB devices
        lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
        if (lbDevices != null && !lbDevices.isEmpty()) {
            for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
                if (lbdevice.getState() == LBDeviceState.Enabled && !lbdevice.getIsDedicatedDevice()) {
                    return lbdevice;
                }
            }
        }
    }
    // there are no devices which capacity
    throw new InsufficientNetworkCapacityException("Unable to find a load balancing provider with sufficient capcity " + " to implement the network", Network.class, network.getId());
}
Also used : ExternalLoadBalancerDeviceVO(com.cloud.network.dao.ExternalLoadBalancerDeviceVO) InsufficientNetworkCapacityException(com.cloud.exception.InsufficientNetworkCapacityException) NetworkExternalLoadBalancerVO(com.cloud.network.dao.NetworkExternalLoadBalancerVO)

Aggregations

InsufficientNetworkCapacityException (com.cloud.exception.InsufficientNetworkCapacityException)5 ExternalLoadBalancerDeviceVO (com.cloud.network.dao.ExternalLoadBalancerDeviceVO)3 Answer (com.cloud.agent.api.Answer)2 HealthCheckLBConfigAnswer (com.cloud.agent.api.routing.HealthCheckLBConfigAnswer)2 DataCenterVO (com.cloud.dc.DataCenterVO)2 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)2 HostVO (com.cloud.host.HostVO)2 NetworkExternalLoadBalancerVO (com.cloud.network.dao.NetworkExternalLoadBalancerVO)2 CreateLoadBalancerApplianceAnswer (com.cloud.network.resource.CreateLoadBalancerApplianceAnswer)2 DestroyLoadBalancerApplianceAnswer (com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer)2 NetScalerImplementNetworkCommand (com.cloud.agent.api.NetScalerImplementNetworkCommand)1 CreateLoadBalancerApplianceCommand (com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand)1 DestroyLoadBalancerApplianceCommand (com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand)1 IpAssocCommand (com.cloud.agent.api.routing.IpAssocCommand)1 SetStaticNatRulesAnswer (com.cloud.agent.api.routing.SetStaticNatRulesAnswer)1 IpAddressTO (com.cloud.agent.api.to.IpAddressTO)1 DataCenterIpAddressVO (com.cloud.dc.DataCenterIpAddressVO)1 Pod (com.cloud.dc.Pod)1 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)1 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)1