Search in sources :

Example 1 with DestroyLoadBalancerApplianceAnswer

use of com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer in project cloudstack by apache.

the class ExternalLoadBalancerDeviceManagerImpl method freeLoadBalancerForNetwork.

@DB
protected boolean freeLoadBalancerForNetwork(final Network guestConfig) {
    GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
    try {
        if (deviceMapLock.lock(120)) {
            ExternalLoadBalancerDeviceVO lbDevice = Transaction.execute(new TransactionCallback<ExternalLoadBalancerDeviceVO>() {

                @Override
                public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) {
                    // since network is shutdown remove the network mapping to the load balancer device
                    NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId());
                    long lbDeviceId = networkLBDevice.getExternalLBDeviceId();
                    _networkExternalLBDao.remove(networkLBDevice.getId());
                    List<NetworkExternalLoadBalancerVO> ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId());
                    ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
                    boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty());
                    boolean lbCloudManaged = lbDevice.getIsManagedDevice();
                    if (!lbInUse && !lbCloudManaged) {
                        // this is the last network mapped to the load balancer device so set device allocation state to be free
                        lbDevice.setAllocationState(LBDeviceAllocationState.Free);
                        _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice);
                    }
                    // commit the changes before sending agent command to destroy cloudstack managed LB
                    if (!lbInUse && lbCloudManaged) {
                        return lbDevice;
                    } else {
                        return null;
                    }
                }
            });
            if (lbDevice != null) {
                // send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned
                Host lbHost = _hostDao.findById(lbDevice.getHostId());
                String lbIP = lbHost.getPrivateIpAddress();
                DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
                DestroyLoadBalancerApplianceAnswer answer = null;
                try {
                    answer = (DestroyLoadBalancerApplianceAnswer) _agentMgr.easySend(lbDevice.getParentHostId(), lbDeleteCmd);
                    if (answer == null || !answer.getResult()) {
                        s_logger.warn("Failed to destoy load balancer appliance used by the network" + guestConfig.getId() + " due to " + answer == null ? "communication error with agent" : answer.getDetails());
                    }
                } catch (Exception e) {
                    s_logger.warn("Failed to destroy load balancer appliance used by the network" + guestConfig.getId() + " due to " + e.getMessage());
                }
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Successfully destroyed load balancer appliance used for the network" + guestConfig.getId());
                }
                deviceMapLock.unlock();
                // remove the provisioned load balancer appliance from cloudstack
                deleteExternalLoadBalancer(lbHost.getId());
                // release the private IP back to dc pool, as the load balancer appliance is now destroyed
                _dcDao.releasePrivateIpAddress(lbHost.getPrivateIpAddress(), guestConfig.getDataCenterId(), null);
                // release the public IP allocated for this LB appliance
                DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip");
                IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString());
                _ipAddrMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
            } else {
                deviceMapLock.unlock();
            }
            return true;
        } else {
            s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + "as failed to acquire lock ");
            return false;
        }
    } catch (Exception exception) {
        s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + " due to " + exception.getMessage());
    } finally {
        deviceMapLock.releaseRef();
    }
    return false;
}
Also used : TransactionStatus(com.cloud.utils.db.TransactionStatus) Host(com.cloud.host.Host) 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) GlobalLock(com.cloud.utils.db.GlobalLock) ExternalLoadBalancerDeviceVO(com.cloud.network.dao.ExternalLoadBalancerDeviceVO) DestroyLoadBalancerApplianceCommand(com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand) DetailVO(com.cloud.host.DetailVO) DestroyLoadBalancerApplianceAnswer(com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer) ArrayList(java.util.ArrayList) List(java.util.List) IPAddressVO(com.cloud.network.dao.IPAddressVO) DB(com.cloud.utils.db.DB)

Example 2 with DestroyLoadBalancerApplianceAnswer

use of com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer 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.getDedicatedLB();
                    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.getDedicatedLB() ? "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);
                        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)

Aggregations

DestroyLoadBalancerApplianceCommand (com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand)2 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)2 InsufficientNetworkCapacityException (com.cloud.exception.InsufficientNetworkCapacityException)2 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)2 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)2 ExternalLoadBalancerDeviceVO (com.cloud.network.dao.ExternalLoadBalancerDeviceVO)2 NetworkExternalLoadBalancerVO (com.cloud.network.dao.NetworkExternalLoadBalancerVO)2 DestroyLoadBalancerApplianceAnswer (com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer)2 UnableDeleteHostException (com.cloud.resource.UnableDeleteHostException)2 DB (com.cloud.utils.db.DB)2 GlobalLock (com.cloud.utils.db.GlobalLock)2 TransactionCallbackWithException (com.cloud.utils.db.TransactionCallbackWithException)2 TransactionStatus (com.cloud.utils.db.TransactionStatus)2 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)2 URISyntaxException (java.net.URISyntaxException)2 ConfigurationException (javax.naming.ConfigurationException)2 CreateLoadBalancerApplianceCommand (com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand)1 DataCenterIpAddressVO (com.cloud.dc.DataCenterIpAddressVO)1 Pod (com.cloud.dc.Pod)1 DetailVO (com.cloud.host.DetailVO)1