Search in sources :

Example 1 with InlineLoadBalancerNicMapVO

use of com.cloud.network.dao.InlineLoadBalancerNicMapVO in project cloudstack by apache.

the class ExternalLoadBalancerDeviceManagerImpl method getLoadBalancingIpNic.

private MappingNic getLoadBalancingIpNic(DataCenterVO zone, Network network, long sourceIpId, boolean revoked, String existedGuestIp) throws ResourceUnavailableException {
    String srcIp = _networkModel.getIp(sourceIpId).getAddress().addr();
    InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(srcIp);
    Nic loadBalancingIpNic = null;
    MappingNic nic = new MappingNic();
    nic.setState(MappingState.Unchanged);
    if (!revoked) {
        if (mapping == null) {
            // Acquire a new guest IP address and save it as the load balancing IP address
            String loadBalancingIpAddress = existedGuestIp;
            if (loadBalancingIpAddress == null) {
                if (network.getGuestType() == Network.GuestType.Isolated) {
                    loadBalancingIpAddress = _ipAddrMgr.acquireGuestIpAddress(network, null);
                } else if (network.getGuestType() == Network.GuestType.Shared) {
                    try {
                        PublicIp directIp = _ipAddrMgr.assignPublicIpAddress(network.getDataCenterId(), null, _accountDao.findById(network.getAccountId()), VlanType.DirectAttached, network.getId(), null, true, false);
                        loadBalancingIpAddress = directIp.getAddress().addr();
                    } catch (InsufficientCapacityException capException) {
                        String msg = "Ran out of guest IP addresses from the shared network.";
                        s_logger.error(msg);
                        throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
                    }
                }
            }
            if (loadBalancingIpAddress == null) {
                String msg = "Ran out of guest IP addresses.";
                s_logger.error(msg);
                throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
            }
            // If a NIC doesn't exist for the load balancing IP address, create one
            loadBalancingIpNic = _nicDao.findByIp4AddressAndNetworkId(loadBalancingIpAddress, network.getId());
            if (loadBalancingIpNic == null) {
                loadBalancingIpNic = _networkMgr.savePlaceholderNic(network, loadBalancingIpAddress, null, null);
            }
            // Save a mapping between the source IP address and the load balancing IP address NIC
            mapping = new InlineLoadBalancerNicMapVO(srcIp, loadBalancingIpNic.getId());
            _inlineLoadBalancerNicMapDao.persist(mapping);
            // address and the load balancing IP address
            try {
                applyStaticNatRuleForInlineLBRule(zone, network, revoked, srcIp, loadBalancingIpNic.getIPv4Address());
            } catch (ResourceUnavailableException ex) {
                // Rollback db operation
                _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
                _nicDao.expunge(loadBalancingIpNic.getId());
                throw ex;
            }
            s_logger.debug("Created static nat rule for inline load balancer");
            nic.setState(MappingState.Create);
        } else {
            loadBalancingIpNic = _nicDao.findById(mapping.getNicId());
        }
    } else {
        if (mapping != null) {
            // Find the NIC that the mapping refers to
            loadBalancingIpNic = _nicDao.findById(mapping.getNicId());
            int count = _ipAddrMgr.getRuleCountForIp(sourceIpId, Purpose.LoadBalancing, FirewallRule.State.Active);
            if (count == 0) {
                // On the firewall provider for the network, delete the static NAT rule between the source IP
                // address and the load balancing IP address
                applyStaticNatRuleForInlineLBRule(zone, network, revoked, srcIp, loadBalancingIpNic.getIPv4Address());
                // Delete the mapping between the source IP address and the load balancing IP address
                _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
                // Delete the NIC
                _nicDao.expunge(loadBalancingIpNic.getId());
                s_logger.debug("Revoked static nat rule for inline load balancer");
                nic.setState(MappingState.Remove);
            }
        } else {
            s_logger.debug("Revoking a rule for an inline load balancer that has not been programmed yet.");
            nic.setNic(null);
            return nic;
        }
    }
    nic.setNic(loadBalancingIpNic);
    return nic;
}
Also used : PublicIp(com.cloud.network.addr.PublicIp) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) Nic(com.cloud.vm.Nic) InlineLoadBalancerNicMapVO(com.cloud.network.dao.InlineLoadBalancerNicMapVO) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException)

Example 2 with InlineLoadBalancerNicMapVO

use of com.cloud.network.dao.InlineLoadBalancerNicMapVO in project cloudstack by apache.

the class ExternalFirewallDeviceManagerImpl method manageGuestNetworkWithExternalFirewall.

@Override
public boolean manageGuestNetworkWithExternalFirewall(boolean add, Network network) throws ResourceUnavailableException, InsufficientCapacityException {
    if (network.getTrafficType() != TrafficType.Guest) {
        s_logger.trace("External firewall can only be used for add/remove guest networks.");
        return false;
    }
    long zoneId = network.getDataCenterId();
    DataCenterVO zone = _dcDao.findById(zoneId);
    HostVO externalFirewall = null;
    if (add) {
        GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkFirewallDeviceMap");
        try {
            if (deviceMapLock.lock(120)) {
                try {
                    ExternalFirewallDeviceVO device = findSuitableFirewallForNetwork(network);
                    long externalFirewallId = device.getId();
                    NetworkExternalFirewallVO networkFW = new NetworkExternalFirewallVO(network.getId(), externalFirewallId);
                    _networkExternalFirewallDao.persist(networkFW);
                    externalFirewall = _hostDao.findById(device.getHostId());
                } finally {
                    deviceMapLock.unlock();
                }
            }
        } finally {
            deviceMapLock.releaseRef();
        }
    } else {
        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
        if (fwDeviceVO == null) {
            s_logger.warn("Network shutdown requested on external firewall element, which did not implement the network." + " Either network implement failed half way through or already network shutdown is completed.");
            return true;
        }
        externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
    }
    Account account = _accountDao.findByIdIncludingRemoved(network.getAccountId());
    NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
    boolean sharedSourceNat = offering.isSharedSourceNat();
    IPAddressVO sourceNatIp = null;
    if (!sharedSourceNat) {
        // Get the source NAT IP address for this network
        List<? extends IpAddress> sourceNatIps = _networkModel.listPublicIpsAssignedToAccount(network.getAccountId(), zoneId, true);
        for (IpAddress ipAddress : sourceNatIps) {
            if (ipAddress.getAssociatedWithNetworkId().longValue() == network.getId()) {
                sourceNatIp = _ipAddressDao.findById(ipAddress.getId());
                break;
            }
        }
        if (sourceNatIp == null) {
            String errorMsg = "External firewall was unable to find the source NAT IP address for network " + network.getName();
            s_logger.error(errorMsg);
            return true;
        }
    }
    // Send a command to the external firewall to implement or shutdown the guest network
    long guestVlanTag = Long.parseLong(BroadcastDomainType.getValue(network.getBroadcastUri()));
    String guestVlanGateway = network.getGateway();
    String guestVlanCidr = network.getCidr();
    String sourceNatIpAddress = null;
    String publicVlanTag = null;
    if (sourceNatIp != null) {
        sourceNatIpAddress = sourceNatIp.getAddress().addr();
        VlanVO publicVlan = _vlanDao.findById(sourceNatIp.getVlanId());
        publicVlanTag = publicVlan.getVlanTag();
    }
    // Get network rate
    Integer networkRate = _networkModel.getNetworkRate(network.getId(), null);
    IpAddressTO ip = new IpAddressTO(account.getAccountId(), sourceNatIpAddress, add, false, !sharedSourceNat, publicVlanTag, null, null, null, networkRate, false);
    IpAddressTO[] ips = new IpAddressTO[1];
    ips[0] = ip;
    IpAssocCommand cmd = new IpAssocCommand(ips);
    cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, guestVlanGateway);
    cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, guestVlanCidr);
    cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
    Answer answer = _agentMgr.easySend(externalFirewall.getId(), cmd);
    List<String> reservedIpAddressesForGuestNetwork = _nicDao.listIpAddressInNetwork(network.getId());
    if (answer == null || !answer.getResult()) {
        String action = add ? "implement" : "shutdown";
        String answerDetails = (answer != null) ? answer.getDetails() : "answer was null";
        String msg = "External firewall was unable to " + action + " the guest network on the external firewall in zone " + zone.getName() + " due to " + answerDetails;
        s_logger.error(msg);
        if (!add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
            // If we failed the implementation as well, then just return, no complain
            s_logger.error("Skip the shutdown of guest network on SRX because it seems we didn't implement it as well");
            return true;
        }
        throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
    }
    if (add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
        // Insert a new NIC for this guest network to reserve the gateway address
        _networkMgr.savePlaceholderNic(network, network.getGateway(), null, null);
    }
    // Delete any mappings used for inline external load balancers in this network
    List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(network.getId());
    for (NicVO nic : nicsInNetwork) {
        InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByNicId(nic.getId());
        if (mapping != null) {
            _nicDao.expunge(mapping.getNicId());
            _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
        }
    }
    // on network shutdown, delete placeHolder nics used for the firewall device
    if (!add) {
        List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
        for (NicVO nic : nics) {
            if (nic.getVmType() == null && nic.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && nic.getIPv4Address().equals(network.getGateway())) {
                s_logger.debug("Removing placeholder nic " + nic + " for the network " + network);
                _nicDao.remove(nic.getId());
            }
        }
        freeFirewallForNetwork(network);
    }
    String action = add ? "implemented" : "shut down";
    s_logger.debug("External firewall 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) ExternalFirewallDeviceVO(com.cloud.network.dao.ExternalFirewallDeviceVO) IpAddressTO(com.cloud.agent.api.to.IpAddressTO) NetworkOffering(com.cloud.offering.NetworkOffering) InlineLoadBalancerNicMapVO(com.cloud.network.dao.InlineLoadBalancerNicMapVO) HostVO(com.cloud.host.HostVO) GlobalLock(com.cloud.utils.db.GlobalLock) Answer(com.cloud.agent.api.Answer) NetworkExternalFirewallVO(com.cloud.network.dao.NetworkExternalFirewallVO) IpAssocCommand(com.cloud.agent.api.routing.IpAssocCommand) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) IPAddressVO(com.cloud.network.dao.IPAddressVO) VlanVO(com.cloud.dc.VlanVO) NicVO(com.cloud.vm.NicVO)

Example 3 with InlineLoadBalancerNicMapVO

use of com.cloud.network.dao.InlineLoadBalancerNicMapVO in project cloudstack by apache.

the class ExternalDeviceUsageManagerImpl method updateExternalLoadBalancerNetworkUsageStats.

@Override
public void updateExternalLoadBalancerNetworkUsageStats(long loadBalancerRuleId) {
    LoadBalancerVO lb = _loadBalancerDao.findById(loadBalancerRuleId);
    if (lb == null) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Cannot update usage stats, LB rule is not found");
        }
        return;
    }
    long networkId = lb.getNetworkId();
    Network network = _networkDao.findById(networkId);
    if (network == null) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Cannot update usage stats, Network is not found");
        }
        return;
    }
    ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
    if (lbDeviceVO == null) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Cannot update usage stats,  No external LB device found");
        }
        return;
    }
    // Get network stats from the external load balancer
    ExternalNetworkResourceUsageAnswer lbAnswer = null;
    HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
    if (externalLoadBalancer != null) {
        ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
        lbAnswer = (ExternalNetworkResourceUsageAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
        if (lbAnswer == null || !lbAnswer.getResult()) {
            String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
            String msg = "Unable to get external load balancer stats for network" + networkId + " due to: " + details + ".";
            s_logger.error(msg);
            return;
        }
    }
    long accountId = lb.getAccountId();
    AccountVO account = _accountDao.findById(accountId);
    if (account == null) {
        s_logger.debug("Skipping stats update for external LB for account with ID " + accountId);
        return;
    }
    String publicIp = _networkModel.getIp(lb.getSourceIpAddressId()).getAddress().addr();
    DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
    String statsEntryIdentifier = "account " + account.getAccountName() + ", zone " + zone.getName() + ", network ID " + networkId + ", host ID " + externalLoadBalancer.getName();
    long newCurrentBytesSent = 0;
    long newCurrentBytesReceived = 0;
    if (publicIp != null) {
        long[] bytesSentAndReceived = null;
        statsEntryIdentifier += ", public IP: " + publicIp;
        boolean inline = _networkModel.isNetworkInlineMode(network);
        if (externalLoadBalancer.getType().equals(Host.Type.ExternalLoadBalancer) && inline) {
            // Look up stats for the guest IP address that's mapped to the public IP address
            InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(publicIp);
            if (mapping != null) {
                NicVO nic = _nicDao.findById(mapping.getNicId());
                String loadBalancingIpAddress = nic.getIPv4Address();
                bytesSentAndReceived = lbAnswer.ipBytes.get(loadBalancingIpAddress);
                if (bytesSentAndReceived != null) {
                    bytesSentAndReceived[0] = 0;
                }
            }
        } else {
            bytesSentAndReceived = lbAnswer.ipBytes.get(publicIp);
        }
        if (bytesSentAndReceived == null) {
            s_logger.debug("Didn't get an external network usage answer for public IP " + publicIp);
        } else {
            newCurrentBytesSent += bytesSentAndReceived[0];
            newCurrentBytesReceived += bytesSentAndReceived[1];
        }
        commitStats(networkId, externalLoadBalancer, accountId, publicIp, zone, statsEntryIdentifier, newCurrentBytesSent, newCurrentBytesReceived);
    }
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) LoadBalancerVO(com.cloud.network.dao.LoadBalancerVO) NetworkExternalLoadBalancerVO(com.cloud.network.dao.NetworkExternalLoadBalancerVO) ExternalNetworkResourceUsageCommand(com.cloud.agent.api.ExternalNetworkResourceUsageCommand) InlineLoadBalancerNicMapVO(com.cloud.network.dao.InlineLoadBalancerNicMapVO) AccountVO(com.cloud.user.AccountVO) HostVO(com.cloud.host.HostVO) ExternalLoadBalancerDeviceVO(com.cloud.network.dao.ExternalLoadBalancerDeviceVO) ExternalNetworkResourceUsageAnswer(com.cloud.agent.api.ExternalNetworkResourceUsageAnswer) NicVO(com.cloud.vm.NicVO)

Aggregations

InlineLoadBalancerNicMapVO (com.cloud.network.dao.InlineLoadBalancerNicMapVO)3 DataCenterVO (com.cloud.dc.DataCenterVO)2 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)2 HostVO (com.cloud.host.HostVO)2 NicVO (com.cloud.vm.NicVO)2 Answer (com.cloud.agent.api.Answer)1 ExternalNetworkResourceUsageAnswer (com.cloud.agent.api.ExternalNetworkResourceUsageAnswer)1 ExternalNetworkResourceUsageCommand (com.cloud.agent.api.ExternalNetworkResourceUsageCommand)1 IpAssocCommand (com.cloud.agent.api.routing.IpAssocCommand)1 IpAddressTO (com.cloud.agent.api.to.IpAddressTO)1 VlanVO (com.cloud.dc.VlanVO)1 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)1 PublicIp (com.cloud.network.addr.PublicIp)1 ExternalFirewallDeviceVO (com.cloud.network.dao.ExternalFirewallDeviceVO)1 ExternalLoadBalancerDeviceVO (com.cloud.network.dao.ExternalLoadBalancerDeviceVO)1 IPAddressVO (com.cloud.network.dao.IPAddressVO)1 LoadBalancerVO (com.cloud.network.dao.LoadBalancerVO)1 NetworkExternalFirewallVO (com.cloud.network.dao.NetworkExternalFirewallVO)1 NetworkExternalLoadBalancerVO (com.cloud.network.dao.NetworkExternalLoadBalancerVO)1 NetworkOffering (com.cloud.offering.NetworkOffering)1