Search in sources :

Example 31 with PublicIp

use of com.cloud.network.addr.PublicIp in project cloudstack by apache.

the class IpAddressManagerImpl method allocateIp.

@DB
@Override
public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, Account caller, long callerUserId, final DataCenter zone, final Boolean displayIp) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException {
    final VlanType vlanType = VlanType.VirtualNetwork;
    final boolean assign = false;
    if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
        // zone is of type DataCenter. See DataCenterVO.java.
        PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, " + "Zone is currently disabled");
        ex.addProxyObject(zone.getUuid(), "zoneId");
        throw ex;
    }
    PublicIp ip = null;
    Account accountToLock = null;
    try {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
        }
        accountToLock = _accountDao.acquireInLockTable(ipOwner.getId());
        if (accountToLock == null) {
            s_logger.warn("Unable to lock account: " + ipOwner.getId());
            throw new ConcurrentOperationException("Unable to acquire account lock");
        }
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Associate IP address lock acquired");
        }
        ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {

            @Override
            public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
                PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null, displayIp);
                if (ip == null) {
                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId());
                    ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid());
                    throw ex;
                }
                CallContext.current().setEventDetails("Ip Id: " + ip.getId());
                Ip ipAddress = ip.getAddress();
                s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId());
                return ip;
            }
        });
    } finally {
        if (accountToLock != null) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Releasing lock account " + ipOwner);
            }
            _accountDao.releaseFromLockTable(ipOwner.getId());
            s_logger.debug("Associate IP address lock released");
        }
    }
    return ip;
}
Also used : Account(com.cloud.user.Account) PublicIp(com.cloud.network.addr.PublicIp) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) InsufficientAddressCapacityException(com.cloud.exception.InsufficientAddressCapacityException) PortableIp(org.apache.cloudstack.region.PortableIp) Ip(com.cloud.utils.net.Ip) PublicIp(com.cloud.network.addr.PublicIp) TransactionStatus(com.cloud.utils.db.TransactionStatus) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VlanType(com.cloud.dc.Vlan.VlanType) DB(com.cloud.utils.db.DB)

Example 32 with PublicIp

use of com.cloud.network.addr.PublicIp in project cloudstack by apache.

the class IpAddressManagerImpl method applyRules.

@Override
public boolean applyRules(List<? extends FirewallRule> rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError) throws ResourceUnavailableException {
    if (rules == null || rules.size() == 0) {
        s_logger.debug("There are no rules to forward to the network elements");
        return true;
    }
    boolean success = true;
    Network network = _networksDao.findById(rules.get(0).getNetworkId());
    FirewallRuleVO.TrafficType trafficType = rules.get(0).getTrafficType();
    List<PublicIp> publicIps = new ArrayList<PublicIp>();
    if (!(rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) {
        // get the list of public ip's owned by the network
        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
        if (userIps != null && !userIps.isEmpty()) {
            for (IPAddressVO userIp : userIps) {
                PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
                publicIps.add(publicIp);
            }
        }
    }
    // the network so as to ensure IP is associated before applying rules (in add state)
    if (checkIfIpAssocRequired(network, false, publicIps)) {
        applyIpAssociations(network, false, continueOnError, publicIps);
    }
    try {
        applier.applyRules(network, purpose, rules);
    } catch (ResourceUnavailableException e) {
        if (!continueOnError) {
            throw e;
        }
        s_logger.warn("Problems with applying " + purpose + " rules but pushing on", e);
        success = false;
    }
    // This IPAssoc ensures, public IP is dis-associated after last active rule is revoked.
    if (checkIfIpAssocRequired(network, true, publicIps)) {
        applyIpAssociations(network, true, continueOnError, publicIps);
    }
    return success;
}
Also used : PublicIp(com.cloud.network.addr.PublicIp) ArrayList(java.util.ArrayList) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) IPAddressVO(com.cloud.network.dao.IPAddressVO) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO)

Example 33 with PublicIp

use of com.cloud.network.addr.PublicIp in project cloudstack by apache.

the class IpAddressManagerImpl method applyStaticNats.

@Override
public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException {
    if (staticNats == null || staticNats.size() == 0) {
        s_logger.debug("There are no static nat rules for the network elements");
        return true;
    }
    Network network = _networksDao.findById(staticNats.get(0).getNetworkId());
    boolean success = true;
    // Check if the StaticNat service is supported
    if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
        s_logger.debug("StaticNat service is not supported in specified network id");
        return true;
    }
    List<IPAddressVO> userIps = getStaticNatSourceIps(staticNats);
    List<PublicIp> publicIps = new ArrayList<PublicIp>();
    if (userIps != null && !userIps.isEmpty()) {
        for (IPAddressVO userIp : userIps) {
            PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
            publicIps.add(publicIp);
        }
    }
    // association for the network so as to ensure IP is associated before applying rules
    if (checkStaticNatIPAssocRequired(network, false, forRevoke, publicIps)) {
        applyIpAssociations(network, false, continueOnError, publicIps);
    }
    // get provider
    StaticNatServiceProvider element = _networkMgr.getStaticNatProviderForNetwork(network);
    try {
        success = element.applyStaticNats(network, staticNats);
    } catch (ResourceUnavailableException e) {
        if (!continueOnError) {
            throw e;
        }
        s_logger.warn("Problems with " + element.getName() + " but pushing on", e);
        success = false;
    }
    // For revoked static nat IP, set the vm_id to null, indicate it should be revoked
    for (StaticNat staticNat : staticNats) {
        if (staticNat.isForRevoke()) {
            for (PublicIp publicIp : publicIps) {
                if (publicIp.getId() == staticNat.getSourceIpAddressId()) {
                    publicIps.remove(publicIp);
                    IPAddressVO ip = _ipAddressDao.findByIdIncludingRemoved(staticNat.getSourceIpAddressId());
                    // ip can't be null, otherwise something wrong happened
                    ip.setAssociatedWithVmId(null);
                    publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId()));
                    publicIps.add(publicIp);
                    break;
                }
            }
        }
    }
    // if the static NAT rules configured on public IP is revoked then, dis-associate IP with static NAT service provider
    if (checkStaticNatIPAssocRequired(network, true, forRevoke, publicIps)) {
        applyIpAssociations(network, true, continueOnError, publicIps);
    }
    return success;
}
Also used : PublicIp(com.cloud.network.addr.PublicIp) StaticNatServiceProvider(com.cloud.network.element.StaticNatServiceProvider) ArrayList(java.util.ArrayList) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) IPAddressVO(com.cloud.network.dao.IPAddressVO) StaticNat(com.cloud.network.rules.StaticNat)

Example 34 with PublicIp

use of com.cloud.network.addr.PublicIp in project cloudstack by apache.

the class IpAddressManagerImpl method allocatePublicIpForGuestNic.

@Override
public String allocatePublicIpForGuestNic(Network network, Long podId, Account owner, String requestedIp) throws InsufficientAddressCapacityException {
    PublicIp ip = assignPublicIpAddress(network.getDataCenterId(), podId, owner, VlanType.DirectAttached, network.getId(), requestedIp, false);
    if (ip == null) {
        s_logger.debug("There is no free public ip address");
        return null;
    }
    Ip ipAddr = ip.getAddress();
    return ipAddr.addr();
}
Also used : PublicIp(com.cloud.network.addr.PublicIp) PortableIp(org.apache.cloudstack.region.PortableIp) Ip(com.cloud.utils.net.Ip) PublicIp(com.cloud.network.addr.PublicIp)

Example 35 with PublicIp

use of com.cloud.network.addr.PublicIp 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

PublicIp (com.cloud.network.addr.PublicIp)38 IPAddressVO (com.cloud.network.dao.IPAddressVO)20 ArrayList (java.util.ArrayList)16 Network (com.cloud.network.Network)9 Account (com.cloud.user.Account)9 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)9 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)8 DataCenter (com.cloud.dc.DataCenter)7 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)6 Test (org.junit.Test)6 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)5 InsufficientAddressCapacityException (com.cloud.exception.InsufficientAddressCapacityException)5 Service (com.cloud.network.Network.Service)5 DB (com.cloud.utils.db.DB)5 TransactionStatus (com.cloud.utils.db.TransactionStatus)5 HashSet (java.util.HashSet)5 Set (java.util.Set)5 VlanVO (com.cloud.dc.VlanVO)4 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)4 Provider (com.cloud.network.Network.Provider)4