Search in sources :

Example 1 with Pod

use of com.cloud.legacymodel.dc.Pod in project cosmic by MissionCriticalCloud.

the class VolumeOrchestrator method createVolumeFromSnapshot.

@DB
@Override
public VolumeInfo createVolumeFromSnapshot(final Volume volume, final Snapshot snapshot, final UserVm vm) throws StorageUnavailableException {
    final Account account = this._entityMgr.findById(Account.class, volume.getAccountId());
    final HashSet<StoragePool> poolsToAvoid = new HashSet<>();
    StoragePool pool = null;
    final Set<Long> podsToAvoid = new HashSet<>();
    Pair<Pod, Long> pod = null;
    final DiskOffering diskOffering = this._entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
    final DataCenter dc = this._entityMgr.findById(DataCenter.class, volume.getDataCenterId());
    final DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
    String msg = "There are no available storage pools to store the volume in";
    if (vm != null) {
        final Pod podofVM = this._entityMgr.findById(Pod.class, vm.getPodIdToDeployIn());
        if (podofVM != null) {
            pod = new Pair<>(podofVM, podofVM.getId());
        }
    }
    if (vm != null && pod != null) {
        // if VM is running use the hostId to find the clusterID. If it is stopped, refer the cluster where the ROOT volume of the VM exists.
        Long hostId = null;
        Long clusterId = null;
        if (vm.getState() == State.Running) {
            hostId = vm.getHostId();
            if (hostId != null) {
                final Host vmHost = this._entityMgr.findById(Host.class, hostId);
                clusterId = vmHost.getClusterId();
            }
        } else {
            final List<VolumeVO> rootVolumesOfVm = this._volsDao.findByInstanceAndType(vm.getId(), VolumeType.ROOT);
            if (rootVolumesOfVm.size() != 1) {
                throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state. Please contact Cloud Support.");
            } else {
                final VolumeVO rootVolumeOfVm = rootVolumesOfVm.get(0);
                final StoragePoolVO rootDiskPool = this._storagePoolDao.findById(rootVolumeOfVm.getPoolId());
                clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
            }
        }
        // Determine what storage pool to store the volume in
        while ((pool = findStoragePool(dskCh, dc, pod.first(), clusterId, hostId, vm, poolsToAvoid)) != null) {
            break;
        }
        if (pool == null) {
            // pool could not be found in the VM's pod/cluster.
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Could not find any storage pool to create Volume in the pod/cluster of the provided VM " + vm.getUuid());
            }
            final StringBuilder addDetails = new StringBuilder(msg);
            addDetails.append(", Could not find any storage pool to create Volume in the pod/cluster of the VM ");
            addDetails.append(vm.getUuid());
            msg = addDetails.toString();
        }
    } else {
        // Determine what pod to store the volume in
        while ((pod = findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
            podsToAvoid.add(pod.first().getId());
            // Determine what storage pool to store the volume in
            while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) {
                break;
            }
            if (pool != null) {
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Found a suitable pool for create volume: " + pool.getId());
                }
                break;
            }
        }
    }
    if (pool == null) {
        s_logger.info(msg);
        throw new StorageUnavailableException(msg, -1);
    }
    final VolumeInfo vol = this.volFactory.getVolume(volume.getId());
    final DataStore store = this.dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
    final DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
    SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
    if (snapInfo == null && dataStoreRole == DataStoreRole.Image) {
        // snapshot is not backed up to secondary, let's do that now.
        snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
        if (snapInfo == null) {
            throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId());
        }
        // We need to copy the snapshot onto secondary.
        final SnapshotStrategy snapshotStrategy = this._storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
        snapshotStrategy.backupSnapshot(snapInfo);
        // Attempt to grab it again.
        snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
        if (snapInfo == null) {
            throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId() + " on secondary and could not create backup");
        }
    }
    // don't try to perform a sync if the DataStoreRole of the snapshot is equal to DataStoreRole.Primary
    if (!DataStoreRole.Primary.equals(dataStoreRole)) {
        try {
            // sync snapshot to region store if necessary
            final DataStore snapStore = snapInfo.getDataStore();
            final long snapVolId = snapInfo.getVolumeId();
            this._snapshotSrv.syncVolumeSnapshotsToRegionStore(snapVolId, snapStore);
        } catch (final Exception ex) {
            // log but ignore the sync error to avoid any potential S3 down issue, it should be sync next time
            s_logger.warn(ex.getMessage(), ex);
        }
    }
    // create volume on primary from snapshot
    final AsyncCallFuture<VolumeService.VolumeApiResult> future = this.volService.createVolumeFromSnapshot(vol, store, snapInfo);
    try {
        final VolumeService.VolumeApiResult result = future.get();
        if (result.isFailed()) {
            s_logger.debug("Failed to create volume from snapshot:" + result.getResult());
            throw new CloudRuntimeException("Failed to create volume from snapshot:" + result.getResult());
        }
        return result.getVolume();
    } catch (final InterruptedException e) {
        s_logger.debug("Failed to create volume from snapshot", e);
        throw new CloudRuntimeException("Failed to create volume from snapshot", e);
    } catch (final ExecutionException e) {
        s_logger.debug("Failed to create volume from snapshot", e);
        throw new CloudRuntimeException("Failed to create volume from snapshot", e);
    }
}
Also used : Account(com.cloud.legacymodel.user.Account) StoragePool(com.cloud.legacymodel.storage.StoragePool) DiskOffering(com.cloud.legacymodel.storage.DiskOffering) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) DataStoreRole(com.cloud.model.enumeration.DataStoreRole) VolumeVO(com.cloud.storage.VolumeVO) StorageUnavailableException(com.cloud.legacymodel.exceptions.StorageUnavailableException) CloudRuntimeException(com.cloud.legacymodel.exceptions.CloudRuntimeException) VolumeService(com.cloud.engine.subsystem.api.storage.VolumeService) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) PrimaryDataStore(com.cloud.engine.subsystem.api.storage.PrimaryDataStore) StoragePoolVO(com.cloud.storage.datastore.db.StoragePoolVO) ExecutionException(java.util.concurrent.ExecutionException) SnapshotStrategy(com.cloud.engine.subsystem.api.storage.SnapshotStrategy) HashSet(java.util.HashSet) Pod(com.cloud.legacymodel.dc.Pod) Host(com.cloud.legacymodel.dc.Host) DiskProfile(com.cloud.legacymodel.storage.DiskProfile) InvalidParameterValueException(com.cloud.legacymodel.exceptions.InvalidParameterValueException) ConcurrentOperationException(com.cloud.legacymodel.exceptions.ConcurrentOperationException) NoTransitionException(com.cloud.legacymodel.exceptions.NoTransitionException) ExecutionException(java.util.concurrent.ExecutionException) ConfigurationException(javax.naming.ConfigurationException) StorageUnavailableException(com.cloud.legacymodel.exceptions.StorageUnavailableException) CloudRuntimeException(com.cloud.legacymodel.exceptions.CloudRuntimeException) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) DataCenter(com.cloud.legacymodel.dc.DataCenter) DB(com.cloud.utils.db.DB)

Example 2 with Pod

use of com.cloud.legacymodel.dc.Pod in project cosmic by MissionCriticalCloud.

the class VolumeOrchestrator method createVolumeOnPrimaryStorage.

@Override
public VolumeInfo createVolumeOnPrimaryStorage(final VirtualMachine vm, final VolumeInfo volume, final HypervisorType rootDiskHyperType, final StoragePool storagePool) {
    final VirtualMachineTemplate rootDiskTmplt = this._entityMgr.findById(VirtualMachineTemplate.class, vm.getTemplateId());
    final DataCenter dcVO = this._entityMgr.findById(DataCenter.class, vm.getDataCenterId());
    final Pod pod = this._entityMgr.findById(Pod.class, storagePool.getPodId());
    final ServiceOffering svo = this._entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId());
    final DiskOffering diskVO = this._entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
    VolumeInfo vol = null;
    if (volume.getState() == Volume.State.Allocated) {
        vol = createVolume(storagePool, volume, rootDiskTmplt, dcVO, svo, diskVO, volume.getSize(), rootDiskHyperType);
    } else if (volume.getState() == Volume.State.Uploaded) {
        vol = copyVolume(storagePool, volume, vm, rootDiskTmplt, dcVO, pod, diskVO, rootDiskHyperType);
        if (vol != null) {
            // Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
            this._resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, volume.getSize());
            this._resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.getSize());
        }
    }
    if (vol == null) {
        throw new CloudRuntimeException("Volume shouldn't be null " + volume.getId());
    }
    final VolumeVO volVO = this._volsDao.findById(vol.getId());
    if (volVO.getFormat() == null) {
        volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType));
    }
    this._volsDao.update(volVO.getId(), volVO);
    return this.volFactory.getVolume(volVO.getId());
}
Also used : DataCenter(com.cloud.legacymodel.dc.DataCenter) DiskOffering(com.cloud.legacymodel.storage.DiskOffering) VirtualMachineTemplate(com.cloud.legacymodel.storage.VirtualMachineTemplate) Pod(com.cloud.legacymodel.dc.Pod) VolumeVO(com.cloud.storage.VolumeVO) ServiceOffering(com.cloud.offering.ServiceOffering) CloudRuntimeException(com.cloud.legacymodel.exceptions.CloudRuntimeException) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo)

Example 3 with Pod

use of com.cloud.legacymodel.dc.Pod in project cosmic by MissionCriticalCloud.

the class ConfigurationManagerImpl method createVlanAndPublicIpRange.

@Override
@DB
public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final boolean forVirtualNetwork, final Long podId, final String startIP, final String endIP, final String vlanGateway, final String vlanNetmask, String vlanId, final Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
    final Network network = _networkModel.getNetwork(networkId);
    boolean ipv4 = false, ipv6 = false;
    if (startIP != null) {
        ipv4 = true;
    }
    if (startIPv6 != null) {
        ipv6 = true;
    }
    if (!ipv4 && !ipv6) {
        throw new InvalidParameterValueException("Please specify IPv4 or IPv6 address.");
    }
    // Validate the zone
    final Zone zone = zoneRepository.findById(zoneId).orElse(null);
    if (zone == null) {
        throw new InvalidParameterValueException("Please specify a valid zone.");
    }
    // ACL check
    checkZoneAccess(CallContext.current().getCallingAccount(), zone);
    // Validate the physical network
    if (_physicalNetworkDao.findById(physicalNetworkId) == null) {
        throw new InvalidParameterValueException("Please specify a valid physical network id");
    }
    // Validate the pod
    if (podId != null) {
        final Pod pod = _podDao.findById(podId);
        if (pod == null) {
            throw new InvalidParameterValueException("Please specify a valid pod.");
        }
        if (pod.getDataCenterId() != zoneId) {
            throw new InvalidParameterValueException("Pod id=" + podId + " doesn't belong to zone id=" + zoneId);
        }
        // pod vlans can be created in basic zone only
        if (zone.getNetworkType() != NetworkType.Basic || network.getTrafficType() != TrafficType.Guest) {
            throw new InvalidParameterValueException("Pod id can be specified only for the networks of type " + TrafficType.Guest + " in zone of type " + NetworkType.Basic);
        }
    }
    // 2) if vlan is missing, default it to the guest network's vlan
    if (network.getTrafficType() == TrafficType.Guest) {
        String networkVlanId = null;
        final URI uri = network.getBroadcastUri();
        if (uri != null) {
            final String[] vlan = uri.toString().split("vlan:\\/\\/");
            networkVlanId = vlan[1];
            // For pvlan
            networkVlanId = networkVlanId.split("-")[0];
        }
        if (vlanId != null) {
            // network's vlanId
            if (networkVlanId != null && !NetUtils.isSameIsolationId(networkVlanId, vlanId)) {
                throw new InvalidParameterValueException("Vlan doesn't match vlan of the network");
            }
        } else {
            vlanId = networkVlanId;
        }
    } else if (network.getTrafficType() == TrafficType.Public && vlanId == null) {
        throw new InvalidParameterValueException("Unable to determine vlan id or untagged vlan for public network");
    }
    if (vlanId == null) {
        vlanId = Vlan.UNTAGGED;
    }
    final VlanType vlanType = forVirtualNetwork ? VlanType.VirtualNetwork : VlanType.DirectAttached;
    if ((domain != null || vlanOwner != null) && zone.getNetworkType() != NetworkType.Advanced) {
        throw new InvalidParameterValueException("Vlan owner can be defined only in the zone of type " + NetworkType.Advanced);
    }
    if (ipv4) {
        // Make sure the gateway is valid
        if (!NetUtils.isValidIp4(vlanGateway)) {
            throw new InvalidParameterValueException("Please specify a valid gateway");
        }
        // Make sure the netmask is valid
        if (!NetUtils.isValidIp4Netmask(vlanNetmask)) {
            throw new InvalidParameterValueException("Please specify a valid netmask");
        }
    }
    if (ipv6) {
        if (!NetUtils.isValidIp6(vlanIp6Gateway)) {
            throw new InvalidParameterValueException("Please specify a valid IPv6 gateway");
        }
        if (!NetUtils.isValidIp6Cidr(vlanIp6Cidr)) {
            throw new InvalidParameterValueException("Please specify a valid IPv6 CIDR");
        }
    }
    if (ipv4) {
        final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
        // Make sure start and end ips are with in the range of cidr calculated for this gateway and netmask {
        if (!NetUtils.isIpWithtInCidrRange(vlanGateway, newCidr) || !NetUtils.isIpWithtInCidrRange(startIP, newCidr) || !NetUtils.isIpWithtInCidrRange(endIP, newCidr)) {
            throw new InvalidParameterValueException("Please specify a valid IP range or valid netmask or valid gateway");
        }
        // Check if the new VLAN's subnet conflicts with the guest network
        // in
        // the specified zone (guestCidr is null for basic zone)
        final String guestNetworkCidr = zone.getGuestNetworkCidr();
        if (guestNetworkCidr != null) {
            if (NetUtils.isNetworksOverlap(newCidr, guestNetworkCidr)) {
                throw new InvalidParameterValueException("The new IP range you have specified has  overlapped with the guest network in zone: " + zone.getName() + ". Please specify a different gateway/netmask.");
            }
        }
        // Check if there are any errors with the IP range
        checkPublicIpRangeErrors(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP);
        // Throw an exception if this subnet overlaps with subnet on other VLAN,
        // if this is ip range extension, gateway, network mask should be same and ip range should not overlap
        final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
        for (final VlanVO vlan : vlans) {
            final String otherVlanGateway = vlan.getVlanGateway();
            final String otherVlanNetmask = vlan.getVlanNetmask();
            // Continue if it's not IPv4
            if (otherVlanGateway == null || otherVlanNetmask == null) {
                continue;
            }
            if (vlan.getNetworkId() == null) {
                continue;
            }
            final String otherCidr = NetUtils.getCidrFromGatewayAndNetmask(otherVlanGateway, otherVlanNetmask);
            if (!NetUtils.isNetworksOverlap(newCidr, otherCidr)) {
                continue;
            }
            // from here, subnet overlaps
            if (!vlanId.equals(vlan.getVlanTag())) {
                boolean overlapped = false;
                if (network.getTrafficType() == TrafficType.Public) {
                    overlapped = true;
                } else {
                    final Long nwId = vlan.getNetworkId();
                    if (nwId != null) {
                        final Network nw = _networkModel.getNetwork(nwId);
                        if (nw != null && nw.getTrafficType() == TrafficType.Public) {
                            overlapped = true;
                        }
                    }
                }
                if (overlapped) {
                    throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag() + " in zone " + zone.getName() + " has overlapped with the subnet. Please specify a different gateway/netmask.");
                }
            } else {
                final String[] otherVlanIpRange = vlan.getIpRange().split("\\-");
                final String otherVlanStartIP = otherVlanIpRange[0];
                String otherVlanEndIP = null;
                if (otherVlanIpRange.length > 1) {
                    otherVlanEndIP = otherVlanIpRange[1];
                }
                // extend IP range
                if (!vlanGateway.equals(otherVlanGateway) || !vlanNetmask.equals(vlan.getVlanNetmask())) {
                    throw new InvalidParameterValueException("The IP range has already been added with gateway " + otherVlanGateway + " ,and netmask " + otherVlanNetmask + ", Please specify the gateway/netmask if you want to extend ip range");
                }
                if (!NetUtils.is31PrefixCidr(newCidr)) {
                    if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) {
                        throw new InvalidParameterValueException("The IP range already has IPs that overlap with the new range." + " Please specify a different start IP/end IP.");
                    }
                }
            }
        }
    }
    String ipv6Range = null;
    if (ipv6) {
        ipv6Range = startIPv6;
        if (endIPv6 != null) {
            ipv6Range += "-" + endIPv6;
        }
        final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
        for (final VlanVO vlan : vlans) {
            if (vlan.getIp6Gateway() == null) {
                continue;
            }
            if (NetUtils.isSameIsolationId(vlanId, vlan.getVlanTag())) {
                if (NetUtils.isIp6RangeOverlap(ipv6Range, vlan.getIp6Range())) {
                    throw new InvalidParameterValueException("The IPv6 range with tag: " + vlan.getVlanTag() + " already has IPs that overlap with the new range. Please specify a different start IP/end IP.");
                }
                if (!vlanIp6Gateway.equals(vlan.getIp6Gateway())) {
                    throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag() + " has already been added with gateway " + vlan.getIp6Gateway() + ". Please specify a different tag.");
                }
            }
        }
    }
    // Check if the vlan is being used
    if (_zoneDao.findVnet(zoneId, physicalNetworkId, vlanId).size() > 0) {
        throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone " + zone.getName());
    }
    String ipRange = null;
    if (ipv4) {
        ipRange = startIP;
        if (endIP != null) {
            ipRange += "-" + endIP;
        }
    }
    // Everything was fine, so persist the VLAN
    final VlanVO vlan = commitVlanAndIpRange(zoneId, networkId, physicalNetworkId, podId, startIP, endIP, vlanGateway, vlanNetmask, vlanId, domain, vlanOwner, vlanIp6Gateway, vlanIp6Cidr, ipv4, zone, vlanType, ipv6Range, ipRange);
    return vlan;
}
Also used : Pod(com.cloud.legacymodel.dc.Pod) InvalidParameterValueException(com.cloud.legacymodel.exceptions.InvalidParameterValueException) Zone(com.cloud.db.model.Zone) PhysicalNetwork(com.cloud.network.PhysicalNetwork) Network(com.cloud.legacymodel.network.Network) VlanVO(com.cloud.dc.VlanVO) URI(java.net.URI) VlanType(com.cloud.legacymodel.dc.Vlan.VlanType) DB(com.cloud.utils.db.DB)

Example 4 with Pod

use of com.cloud.legacymodel.dc.Pod in project cosmic by MissionCriticalCloud.

the class DeploymentPlanningManagerImpl method isEnabledForAllocation.

private boolean isEnabledForAllocation(final long zoneId, final Long podId, final Long clusterId) {
    // Check if the zone exists in the system
    final Zone zone = zoneRepository.findById(zoneId).orElse(null);
    if (zone != null && AllocationState.Disabled == zone.getAllocationState()) {
        s_logger.info("Zone is currently disabled, cannot allocate to this zone: " + zoneId);
        return false;
    }
    final Pod pod = _podDao.findById(podId);
    if (pod != null && AllocationState.Disabled == pod.getAllocationState()) {
        s_logger.info("Pod is currently disabled, cannot allocate to this pod: " + podId);
        return false;
    }
    final Cluster cluster = _clusterDao.findById(clusterId);
    if (cluster != null && AllocationState.Disabled == cluster.getAllocationState()) {
        s_logger.info("Cluster is currently disabled, cannot allocate to this cluster: " + clusterId);
        return false;
    }
    return true;
}
Also used : Pod(com.cloud.legacymodel.dc.Pod) Zone(com.cloud.db.model.Zone) Cluster(com.cloud.legacymodel.dc.Cluster)

Example 5 with Pod

use of com.cloud.legacymodel.dc.Pod in project cosmic by MissionCriticalCloud.

the class IpAddressManagerImpl method fetchNewPublicIp.

@DB
public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List<Long> vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, final boolean sourceNat, final boolean assign, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp) throws InsufficientAddressCapacityException {
    final IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {

        @Override
        public IPAddressVO doInTransaction(final TransactionStatus status) throws InsufficientAddressCapacityException {
            final StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
            boolean fetchFromDedicatedRange = false;
            final List<Long> dedicatedVlanDbIds = new ArrayList<>();
            final List<Long> nonDedicatedVlanDbIds = new ArrayList<>();
            SearchCriteria<IPAddressVO> sc = null;
            if (podId != null) {
                sc = AssignIpAddressFromPodVlanSearch.create();
                sc.setJoinParameters("podVlanMapSB", "podId", podId);
                errorMessage.append(" pod id=" + podId);
            } else {
                sc = AssignIpAddressSearch.create();
                errorMessage.append(" zone id=" + dcId);
            }
            // If owner has dedicated Public IP ranges, fetch IP from the dedicated range
            // Otherwise fetch IP from the system pool
            final List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
            for (final AccountVlanMapVO map : maps) {
                if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId())) {
                    dedicatedVlanDbIds.add(map.getVlanDbId());
                }
            }
            final List<DomainVlanMapVO> domainMaps = _domainVlanMapDao.listDomainVlanMapsByDomain(owner.getDomainId());
            for (final DomainVlanMapVO map : domainMaps) {
                if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId())) {
                    dedicatedVlanDbIds.add(map.getVlanDbId());
                }
            }
            final List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
            for (final VlanVO nonDedicatedVlan : nonDedicatedVlans) {
                if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId())) {
                    nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
                }
            }
            if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
                fetchFromDedicatedRange = true;
                sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
                errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
            } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
                sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
                errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
            } else {
                if (podId != null) {
                    final InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
                    ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
                    throw ex;
                }
                s_logger.warn(errorMessage.toString());
                final InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
                ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
                throw ex;
            }
            sc.setParameters("dc", dcId);
            final DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
            // for direct network take ip addresses only from the vlans belonging to the network
            if (vlanUse == VlanType.DirectAttached) {
                sc.setJoinParameters("vlan", "networkId", guestNetworkId);
                errorMessage.append(", network id=" + guestNetworkId);
            }
            sc.setJoinParameters("vlan", "type", vlanUse);
            if (requestedIp != null) {
                sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
                errorMessage.append(": requested ip " + requestedIp + " is not available");
            }
            final Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
            List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
            // If all the dedicated IPs of the owner are in use fetch an IP from the system pool
            if (addrs.size() == 0 && fetchFromDedicatedRange) {
                // Verify if account is allowed to acquire IPs from the system
                final boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
                if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
                    fetchFromDedicatedRange = false;
                    sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
                    errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
                    addrs = _ipAddressDao.lockRows(sc, filter, true);
                }
            }
            if (addrs.size() == 0) {
                if (podId != null) {
                    final InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
                    // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
                    ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
                    throw ex;
                }
                s_logger.warn(errorMessage.toString());
                final InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
                ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
                throw ex;
            }
            assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
            if (!fetchFromDedicatedRange && VlanType.VirtualNetwork.equals(vlanUse)) {
                // Check that the maximum number of public IPs for the given accountId will not be exceeded
                try {
                    _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
                } catch (final ResourceAllocationException ex) {
                    s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
                    throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
                }
            }
            final IPAddressVO addr = addrs.get(0);
            addr.setSourceNat(sourceNat);
            addr.setAllocatedTime(new Date());
            addr.setAllocatedInDomainId(owner.getDomainId());
            addr.setAllocatedToAccountId(owner.getId());
            addr.setSystem(isSystem);
            addr.setIpACLId(NetworkACL.DEFAULT_ALLOW);
            if (displayIp != null) {
                addr.setDisplay(displayIp);
            }
            if (assign) {
                markPublicIpAsAllocated(addr);
            } else {
                addr.setState(IpAddress.State.Allocating);
            }
            addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating);
            if (vlanUse != VlanType.DirectAttached) {
                addr.setAssociatedWithNetworkId(guestNetworkId);
                addr.setVpcId(vpcId);
            }
            _ipAddressDao.update(addr.getId(), addr);
            return addr;
        }
    });
    if (vlanUse == VlanType.VirtualNetwork) {
        _firewallMgr.addSystemFirewallRules(addr, owner);
    }
    return PublicIp.createFromAddrAndVlan(addr, _vlanDao.findById(addr.getVlanId()));
}
Also used : Pod(com.cloud.legacymodel.dc.Pod) InsufficientAddressCapacityException(com.cloud.legacymodel.exceptions.InsufficientAddressCapacityException) AccountVlanMapVO(com.cloud.dc.AccountVlanMapVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) SearchCriteria(com.cloud.utils.db.SearchCriteria) DomainVlanMapVO(com.cloud.dc.DomainVlanMapVO) Date(java.util.Date) DataCenter(com.cloud.legacymodel.dc.DataCenter) Filter(com.cloud.utils.db.Filter) IPAddressVO(com.cloud.network.dao.IPAddressVO) ArrayList(java.util.ArrayList) List(java.util.List) VlanVO(com.cloud.dc.VlanVO) ResourceAllocationException(com.cloud.legacymodel.exceptions.ResourceAllocationException) AccountLimitException(com.cloud.legacymodel.exceptions.AccountLimitException) DB(com.cloud.utils.db.DB)

Aggregations

Pod (com.cloud.legacymodel.dc.Pod)15 Zone (com.cloud.db.model.Zone)5 StoragePool (com.cloud.legacymodel.storage.StoragePool)5 Cluster (com.cloud.legacymodel.dc.Cluster)4 DataCenter (com.cloud.legacymodel.dc.DataCenter)4 Host (com.cloud.legacymodel.dc.Host)4 CloudRuntimeException (com.cloud.legacymodel.exceptions.CloudRuntimeException)4 Volume (com.cloud.legacymodel.storage.Volume)4 ArrayList (java.util.ArrayList)4 List (java.util.List)4 PodResponse (com.cloud.api.response.PodResponse)3 InsufficientAddressCapacityException (com.cloud.legacymodel.exceptions.InsufficientAddressCapacityException)3 DiskOffering (com.cloud.legacymodel.storage.DiskOffering)3 DB (com.cloud.utils.db.DB)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ServerApiException (com.cloud.api.ServerApiException)2 VlanVO (com.cloud.dc.VlanVO)2 DeployDestination (com.cloud.deploy.DeployDestination)2 ExcludeList (com.cloud.deploy.DeploymentPlanner.ExcludeList)2