Search in sources :

Example 16 with DataCenterVnetVO

use of com.cloud.dc.DataCenterVnetVO in project cosmic by MissionCriticalCloud.

the class NetworkServiceImpl method dedicateGuestVlanRange.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_GUEST_VLAN_RANGE_DEDICATE, eventDescription = "dedicating guest vlan range", async = false)
public GuestVlan dedicateGuestVlanRange(final DedicateGuestVlanRangeCmd cmd) {
    final String vlan = cmd.getVlan();
    final String accountName = cmd.getAccountName();
    final Long domainId = cmd.getDomainId();
    final Long physicalNetworkId = cmd.getPhysicalNetworkId();
    final Long projectId = cmd.getProjectId();
    final int startVlan;
    final int endVlan;
    String updatedVlanRange = null;
    long guestVlanMapId = 0;
    long guestVlanMapAccountId = 0;
    long vlanOwnerId = 0;
    // Verify account is valid
    Account vlanOwner = null;
    if (projectId != null) {
        if (accountName != null) {
            throw new InvalidParameterValueException("accountName and projectId are mutually exclusive");
        }
        final Project project = _projectMgr.getProject(projectId);
        if (project == null) {
            throw new InvalidParameterValueException("Unable to find project by id " + projectId);
        }
        vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
    }
    if (accountName != null && domainId != null) {
        vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
    }
    if (vlanOwner == null) {
        throw new InvalidParameterValueException("Unable to find account by name " + accountName);
    }
    vlanOwnerId = vlanOwner.getAccountId();
    // Verify physical network isolation type is VLAN
    final PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
    if (physicalNetwork == null) {
        throw new InvalidParameterValueException("Unable to find physical network by id " + physicalNetworkId);
    } else if (!physicalNetwork.getIsolationMethods().isEmpty() && !physicalNetwork.getIsolationMethods().contains("VLAN")) {
        throw new InvalidParameterValueException("Cannot dedicate guest vlan range. " + "Physical isolation type of network " + physicalNetworkId + " is not VLAN");
    }
    // Get the start and end vlan
    final String[] vlanRange = vlan.split("-");
    if (vlanRange.length != 2) {
        throw new InvalidParameterValueException("Invalid format for parameter value vlan " + vlan + " .Vlan should be specified as 'startvlan-endvlan'");
    }
    try {
        startVlan = Integer.parseInt(vlanRange[0]);
        endVlan = Integer.parseInt(vlanRange[1]);
    } catch (final NumberFormatException e) {
        s_logger.warn("Unable to parse guest vlan range:", e);
        throw new InvalidParameterValueException("Please provide valid guest vlan range");
    }
    // Verify guest vlan range exists in the system
    final List<Pair<Integer, Integer>> existingRanges = physicalNetwork.getVnet();
    Boolean exists = false;
    if (!existingRanges.isEmpty()) {
        for (int i = 0; i < existingRanges.size(); i++) {
            final int existingStartVlan = existingRanges.get(i).first();
            final int existingEndVlan = existingRanges.get(i).second();
            if (startVlan <= endVlan && startVlan >= existingStartVlan && endVlan <= existingEndVlan) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            throw new InvalidParameterValueException("Unable to find guest vlan by range " + vlan);
        }
    }
    // Verify guest vlans in the range don't belong to a network of a different account
    for (int i = startVlan; i <= endVlan; i++) {
        final List<DataCenterVnetVO> allocatedVlans = _datacneterVnet.listAllocatedVnetsInRange(physicalNetwork.getDataCenterId(), physicalNetwork.getId(), startVlan, endVlan);
        if (allocatedVlans != null && !allocatedVlans.isEmpty()) {
            for (final DataCenterVnetVO allocatedVlan : allocatedVlans) {
                if (allocatedVlan.getAccountId() != vlanOwner.getAccountId()) {
                    throw new InvalidParameterValueException("Guest vlan from this range " + allocatedVlan.getVnet() + " is allocated to a different account." + " Can only dedicate a range which has no allocated vlans or has vlans allocated to the same account ");
                }
            }
        }
    }
    final List<AccountGuestVlanMapVO> guestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(physicalNetworkId);
    // Verify if vlan range is already dedicated
    for (final AccountGuestVlanMapVO guestVlanMap : guestVlanMaps) {
        final List<Integer> vlanTokens = getVlanFromRange(guestVlanMap.getGuestVlanRange());
        final int dedicatedStartVlan = vlanTokens.get(0).intValue();
        final int dedicatedEndVlan = vlanTokens.get(1).intValue();
        if (startVlan < dedicatedStartVlan & endVlan >= dedicatedStartVlan || startVlan >= dedicatedStartVlan & startVlan <= dedicatedEndVlan) {
            throw new InvalidParameterValueException("Vlan range is already dedicated. Cannot" + " dedicate guest vlan range " + vlan);
        }
    }
    // Sort the existing dedicated vlan ranges
    Collections.sort(guestVlanMaps, new Comparator<AccountGuestVlanMapVO>() {

        @Override
        public int compare(final AccountGuestVlanMapVO obj1, final AccountGuestVlanMapVO obj2) {
            final List<Integer> vlanTokens1 = getVlanFromRange(obj1.getGuestVlanRange());
            final List<Integer> vlanTokens2 = getVlanFromRange(obj2.getGuestVlanRange());
            return vlanTokens1.get(0).compareTo(vlanTokens2.get(0));
        }
    });
    // Verify if vlan range extends an already dedicated range
    for (int i = 0; i < guestVlanMaps.size(); i++) {
        guestVlanMapId = guestVlanMaps.get(i).getId();
        guestVlanMapAccountId = guestVlanMaps.get(i).getAccountId();
        final List<Integer> vlanTokens1 = getVlanFromRange(guestVlanMaps.get(i).getGuestVlanRange());
        // Range extends a dedicated vlan range to the left
        if (endVlan == vlanTokens1.get(0).intValue() - 1) {
            if (guestVlanMapAccountId == vlanOwnerId) {
                updatedVlanRange = startVlan + "-" + vlanTokens1.get(1).intValue();
            }
            break;
        }
        // Range extends a dedicated vlan range to the right
        if (startVlan == vlanTokens1.get(1).intValue() + 1 & guestVlanMapAccountId == vlanOwnerId) {
            if (i != guestVlanMaps.size() - 1) {
                final List<Integer> vlanTokens2 = getVlanFromRange(guestVlanMaps.get(i + 1).getGuestVlanRange());
                // Range extends 2 vlan ranges, both to the right and left
                if (endVlan == vlanTokens2.get(0).intValue() - 1 && guestVlanMaps.get(i + 1).getAccountId() == vlanOwnerId) {
                    _datacneterVnet.releaseDedicatedGuestVlans(guestVlanMaps.get(i + 1).getId());
                    _accountGuestVlanMapDao.remove(guestVlanMaps.get(i + 1).getId());
                    updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + vlanTokens2.get(1).intValue();
                    break;
                }
            }
            updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + endVlan;
            break;
        }
    }
    // Dedicate vlan range
    final AccountGuestVlanMapVO accountGuestVlanMapVO;
    if (updatedVlanRange != null) {
        accountGuestVlanMapVO = _accountGuestVlanMapDao.findById(guestVlanMapId);
        accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange);
        _accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO);
    } else {
        accountGuestVlanMapVO = new AccountGuestVlanMapVO(vlanOwner.getAccountId(), physicalNetworkId);
        accountGuestVlanMapVO.setGuestVlanRange(startVlan + "-" + endVlan);
        _accountGuestVlanMapDao.persist(accountGuestVlanMapVO);
    }
    // For every guest vlan set the corresponding account guest vlan map id
    final List<Integer> finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange());
    for (int i = finaVlanTokens.get(0).intValue(); i <= finaVlanTokens.get(1).intValue(); i++) {
        final List<DataCenterVnetVO> dataCenterVnet = _datacneterVnet.findVnet(physicalNetwork.getDataCenterId(), physicalNetworkId, Integer.toString(i));
        dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId());
        _datacneterVnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0));
    }
    return accountGuestVlanMapVO;
}
Also used : Account(com.cloud.user.Account) AccountGuestVlanMapVO(com.cloud.network.dao.AccountGuestVlanMapVO) Project(com.cloud.projects.Project) DataCenterVnetVO(com.cloud.dc.DataCenterVnetVO) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) PhysicalNetworkVO(com.cloud.network.dao.PhysicalNetworkVO) ArrayList(java.util.ArrayList) List(java.util.List) Pair(com.cloud.utils.Pair) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 17 with DataCenterVnetVO

use of com.cloud.dc.DataCenterVnetVO in project cosmic by MissionCriticalCloud.

the class NetworkOrchestrator method createGuestNetwork.

@Override
@DB
public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr, final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, final String dns1, final String dns2, final String ipExclusionList) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
    final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
    // this method supports only guest network creation
    if (ntwkOff.getTrafficType() != TrafficType.Guest) {
        s_logger.warn("Only guest networks can be created using this method");
        return null;
    }
    final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType);
    // check resource limits
    if (updateResourceCount) {
        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.network, isDisplayNetworkEnabled);
    }
    // Validate network offering
    if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
        // see NetworkOfferingVO
        final InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled);
        ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
        throw ex;
    }
    // Validate physical network
    if (pNtwk.getState() != PhysicalNetwork.State.Enabled) {
        // see PhysicalNetworkVO.java
        final InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is" + " in incorrect state:" + pNtwk.getState());
        ex.addProxyObject(pNtwk.getUuid(), "physicalNetworkId");
        throw ex;
    }
    boolean ipv6 = false;
    if (ip6Gateway != null && ip6Cidr != null) {
        ipv6 = true;
    }
    // Validate zone
    final Zone zone = _zoneRepository.findOne(zoneId);
    if (zone.getNetworkType() == com.cloud.model.enumeration.NetworkType.Basic) {
        if (ipv6) {
            throw new InvalidParameterValueException("IPv6 is not supported in Basic zone");
        }
        // In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
        if (aclType == null || aclType != ACLType.Domain) {
            throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
        }
        // Only one guest network is supported in Basic zone
        final List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
        if (!guestNetworks.isEmpty()) {
            throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic);
        }
        // if zone is basic, only Shared network offerings w/o source nat service are allowed
        if (!(ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
            throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + "guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName() + " service are allowed");
        }
        if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
            throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
        }
        if (subdomainAccess == null) {
            subdomainAccess = true;
        } else if (!subdomainAccess) {
            throw new InvalidParameterValueException("Subdomain access should be set to true for the" + " guest network in the Basic zone");
        }
        if (vlanId == null) {
            vlanId = Vlan.UNTAGGED;
        } else {
            if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
                throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + "the zone of type " + NetworkType.Basic);
            }
        }
    } else if (zone.getNetworkType() == com.cloud.model.enumeration.NetworkType.Advanced) {
        // don't allow eip/elb networks in Advance zone
        if (ntwkOff.getElasticIp() || ntwkOff.getElasticLb()) {
            throw new InvalidParameterValueException("Elastic IP and Elastic LB services are supported in zone of type " + NetworkType.Basic);
        }
    }
    // TODO(VXLAN): Support VNI specified
    // VlanId can be specified only when network offering supports it
    final boolean vlanSpecified = vlanId != null;
    if (vlanSpecified != ntwkOff.getSpecifyVlan()) {
        if (vlanSpecified) {
            throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
        } else {
            throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
        }
    }
    if (vlanSpecified) {
        // don't allow to specify vlan tag used by physical network for dynamic vlan allocation
        if (_dcVnetDao.findVnet(zoneId, pNtwk.getId(), 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());
        }
        final String uri = BroadcastDomainType.fromString(vlanId).toString();
        // For Isolated networks, don't allow to create network with vlan that already exists in the zone
        if (ntwkOff.getGuestType() == GuestType.Isolated) {
            if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) {
                throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
            } else {
                final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId);
                // the vnet is not coming from the data center vnet table, so the list can be empty
                if (!dcVnets.isEmpty()) {
                    final DataCenterVnetVO dcVnet = dcVnets.get(0);
                    // Fail network creation if specified vlan is dedicated to a different account
                    if (dcVnet.getAccountGuestVlanMapId() != null) {
                        final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
                        final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
                        if (map.getAccountId() != owner.getAccountId()) {
                            throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
                        }
                    // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
                    } else {
                        final List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
                        if (maps != null && !maps.isEmpty()) {
                            final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
                            final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
                            if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
                                throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner " + owner.getAccountName());
                            }
                        }
                    }
                }
            }
        } else {
            // shared network with same Vlan ID in the zone
            if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0) {
                throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId);
            }
        }
    }
    // If networkDomain is not specified, take it from the global configuration
    if (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
        final Map<Network.Capability, String> dnsCapabilities = _networkModel.getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, networkOfferingId), Service.Dns);
        final String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
        if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
            if (networkDomain != null) {
                // TBD: NetworkOfferingId and zoneId. Send uuids instead.
                throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + networkOfferingId + " in zone id=" + zoneId);
            }
        } else {
            if (networkDomain == null) {
                // 1) Get networkDomain from the corresponding account/domain/zone
                if (aclType == ACLType.Domain) {
                    networkDomain = _networkModel.getDomainNetworkDomain(domainId, zoneId);
                } else if (aclType == ACLType.Account) {
                    networkDomain = _networkModel.getAccountNetworkDomain(owner.getId(), zoneId);
                }
                // 2) If null, generate networkDomain using domain suffix from the global config variables
                if (networkDomain == null) {
                    networkDomain = "cs" + Long.toHexString(owner.getId()) + GuestDomainSuffix.valueIn(zoneId);
                }
            } else {
                // validate network domain
                if (!NetUtils.verifyDomainName(networkDomain)) {
                    throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain " + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "and the hyphen ('-'); can't start or end with \"-\"");
                }
            }
        }
    }
    // In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x
    // limitation, remove after we introduce support for multiple ip ranges
    // with different Cidrs for the same Shared network
    final boolean cidrRequired = zone.getNetworkType() == com.cloud.model.enumeration.NetworkType.Advanced && ntwkOff.getTrafficType() == TrafficType.Guest && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)));
    if (cidr == null && ip6Cidr == null && cidrRequired) {
        throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of" + " type " + GuestType.Shared + " and network of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled");
    }
    // No cidr can be specified in Basic zone
    if (zone.getNetworkType() == com.cloud.model.enumeration.NetworkType.Basic && cidr != null) {
        throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask can't be specified for zone of type " + NetworkType.Basic);
    }
    // Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4
    if (cidr != null && ntwkOff.getGuestType() != GuestType.Shared && ntwkOff.getTrafficType() == TrafficType.Guest) {
        if (!NetUtils.validateGuestCidr(cidr)) {
            throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC1918 compliant");
        }
    }
    final String networkDomainFinal = networkDomain;
    final String vlanIdFinal = vlanId;
    final Boolean subdomainAccessFinal = subdomainAccess;
    final Network network = Transaction.execute(new TransactionCallback<Network>() {

        @Override
        public Network doInTransaction(final TransactionStatus status) {
            Long physicalNetworkId = null;
            if (pNtwk != null) {
                physicalNetworkId = pNtwk.getId();
            }
            final DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null, null, physicalNetworkId);
            final NetworkVO userNetwork = new NetworkVO();
            userNetwork.setNetworkDomain(networkDomainFinal);
            userNetwork.setCidr(cidr);
            userNetwork.setGateway(gateway);
            if (dns1 != null) {
                userNetwork.setDns1(dns1);
            }
            if (dns2 != null) {
                userNetwork.setDns2(dns2);
            }
            if (ipExclusionList != null) {
                userNetwork.setIpExclusionList(ipExclusionList);
            }
            if (ip6Cidr != null && ip6Gateway != null) {
                userNetwork.setIp6Cidr(ip6Cidr);
                userNetwork.setIp6Gateway(ip6Gateway);
            }
            if (vlanIdFinal != null) {
                if (isolatedPvlan == null) {
                    final URI uri = BroadcastDomainType.fromString(vlanIdFinal);
                    userNetwork.setBroadcastUri(uri);
                    if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
                        userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
                    } else {
                        userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
                    }
                } else {
                    if (vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
                        throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!");
                    }
                    userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanIdFinal, isolatedPvlan));
                    userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan);
                }
            }
            final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId, null, isDisplayNetworkEnabled, dns1, dns2, ipExclusionList);
            Network network = null;
            if (networks == null || networks.isEmpty()) {
                throw new CloudRuntimeException("Fail to create a network");
            } else {
                if (networks.size() > 0 && networks.get(0).getGuestType() == GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) {
                    Network defaultGuestNetwork = networks.get(0);
                    for (final Network nw : networks) {
                        if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) {
                            defaultGuestNetwork = nw;
                        }
                    }
                    network = defaultGuestNetwork;
                } else {
                    // For shared network
                    network = networks.get(0);
                }
            }
            if (updateResourceCount) {
                _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
            }
            return network;
        }
    });
    CallContext.current().setEventDetails("Network Id: " + network.getId());
    CallContext.current().putContextParameter(Network.class, network.getUuid());
    return network;
}
Also used : AccountGuestVlanMapVO(com.cloud.network.dao.AccountGuestVlanMapVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) URI(java.net.URI) DataCenterVnetVO(com.cloud.dc.DataCenterVnetVO) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) Network(com.cloud.network.Network) PhysicalNetwork(com.cloud.network.PhysicalNetwork) ArrayList(java.util.ArrayList) List(java.util.List) PhysicalNetworkVO(com.cloud.network.dao.PhysicalNetworkVO) NetworkVO(com.cloud.network.dao.NetworkVO) DataCenterDeployment(com.cloud.deploy.DataCenterDeployment) Capability(com.cloud.network.Network.Capability) NetworkOffering(com.cloud.offering.NetworkOffering) Zone(com.cloud.db.model.Zone) NetworkOfferingVO(com.cloud.offerings.NetworkOfferingVO) DB(com.cloud.utils.db.DB)

Example 18 with DataCenterVnetVO

use of com.cloud.dc.DataCenterVnetVO in project cloudstack by apache.

the class NetworkOrchestrator method createGuestNetwork.

@DB
private Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr, final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
    final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
    final DataCenterVO zone = _dcDao.findById(zoneId);
    // this method supports only guest network creation
    if (ntwkOff.getTrafficType() != TrafficType.Guest) {
        s_logger.warn("Only guest networks can be created using this method");
        return null;
    }
    final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType);
    // check resource limits
    if (updateResourceCount) {
        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.network, isDisplayNetworkEnabled);
    }
    // Validate network offering
    if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
        // see NetworkOfferingVO
        final InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its state is not " + NetworkOffering.State.Enabled);
        ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
        throw ex;
    }
    // Validate physical network
    if (pNtwk.getState() != PhysicalNetwork.State.Enabled) {
        // see PhysicalNetworkVO.java
        final InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is" + " in incorrect state:" + pNtwk.getState());
        ex.addProxyObject(pNtwk.getUuid(), "physicalNetworkId");
        throw ex;
    }
    boolean ipv6 = false;
    if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
        ipv6 = true;
    }
    // Validate zone
    if (zone.getNetworkType() == NetworkType.Basic) {
        // In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
        if (aclType == null || aclType != ACLType.Domain) {
            throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
        }
        // Only one guest network is supported in Basic zone
        final List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
        if (!guestNetworks.isEmpty()) {
            throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic);
        }
        // if zone is basic, only Shared network offerings w/o source nat service are allowed
        if (!(ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
            throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + "guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName() + " service are allowed");
        }
        if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
            throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
        }
        if (subdomainAccess == null) {
            subdomainAccess = true;
        } else if (!subdomainAccess) {
            throw new InvalidParameterValueException("Subdomain access should be set to true for the" + " guest network in the Basic zone");
        }
        if (vlanId == null) {
            vlanId = Vlan.UNTAGGED;
        } else {
            if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
                throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + "the zone of type " + NetworkType.Basic);
            }
        }
    } else if (zone.getNetworkType() == NetworkType.Advanced) {
        if (zone.isSecurityGroupEnabled()) {
            if (isolatedPvlan != null) {
                throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
            }
            // enabled zone
            if (ntwkOff.getGuestType() != GuestType.Shared) {
                throw new InvalidParameterValueException("Only shared guest network can be created in security group enabled zone");
            }
            if (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)) {
                throw new InvalidParameterValueException("Service SourceNat is not allowed in security group enabled zone");
            }
        }
        // don't allow eip/elb networks in Advance zone
        if (ntwkOff.isElasticIp() || ntwkOff.isElasticLb()) {
            throw new InvalidParameterValueException("Elastic IP and Elastic LB services are supported in zone of type " + NetworkType.Basic);
        }
    }
    if (ipv6 && NetUtils.getIp6CidrSize(ip6Cidr) != 64) {
        throw new InvalidParameterValueException("IPv6 subnet should be exactly 64-bits in size");
    }
    // TODO(VXLAN): Support VNI specified
    // VlanId can be specified only when network offering supports it
    final boolean vlanSpecified = vlanId != null;
    if (vlanSpecified != ntwkOff.isSpecifyVlan()) {
        if (vlanSpecified) {
            throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
        } else {
            throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
        }
    }
    if (vlanSpecified) {
        URI uri = encodeVlanIdIntoBroadcastUri(vlanId, pNtwk);
        // Aux: generate secondary URI for secondary VLAN ID (if provided) for performing checks
        URI secondaryUri = StringUtils.isNotBlank(isolatedPvlan) ? BroadcastDomainType.fromString(isolatedPvlan) : null;
        // don't allow to specify vlan tag used by physical network for dynamic vlan allocation
        if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
            throw new InvalidParameterValueException("The VLAN tag to use for new guest network, " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone " + zone.getName());
        }
        if (secondaryUri != null && !(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(secondaryUri)).size() > 0) {
            throw new InvalidParameterValueException("The VLAN tag for isolated PVLAN " + isolatedPvlan + " is already being used for dynamic vlan allocation for the guest network in zone " + zone.getName());
        }
        if (!UuidUtils.validateUUID(vlanId)) {
            // For Isolated and L2 networks, don't allow to create network with vlan that already exists in the zone
            if (!hasGuestBypassVlanOverlapCheck(bypassVlanOverlapCheck, ntwkOff, isPrivateNetwork)) {
                if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) {
                    throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists or overlaps with other network vlans in zone " + zoneId);
                } else if (secondaryUri != null && _networksDao.listByZoneAndUriAndGuestType(zoneId, secondaryUri.toString(), null).size() > 0) {
                    throw new InvalidParameterValueException("Network with vlan " + isolatedPvlan + " already exists or overlaps with other network vlans in zone " + zoneId);
                } else {
                    final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, BroadcastDomainType.getValue(uri));
                    // the vnet is not coming from the data center vnet table, so the list can be empty
                    if (!dcVnets.isEmpty()) {
                        final DataCenterVnetVO dcVnet = dcVnets.get(0);
                        // Fail network creation if specified vlan is dedicated to a different account
                        if (dcVnet.getAccountGuestVlanMapId() != null) {
                            final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
                            final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
                            if (map.getAccountId() != owner.getAccountId()) {
                                throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
                            }
                        // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
                        } else {
                            final List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
                            if (maps != null && !maps.isEmpty()) {
                                final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
                                final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
                                if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
                                    throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner " + owner.getAccountName());
                                }
                            }
                        }
                    }
                }
            } else {
                // shared network with same Vlan ID in the zone
                if (!bypassVlanOverlapCheck && _networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), GuestType.Isolated).size() > 0) {
                    throw new InvalidParameterValueException("There is an existing isolated/shared network that overlaps with vlan id:" + vlanId + " in zone " + zoneId);
                }
            }
        }
    }
    // If networkDomain is not specified, take it from the global configuration
    if (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
        final Map<Network.Capability, String> dnsCapabilities = _networkModel.getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, networkOfferingId), Service.Dns);
        final String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
        if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
            if (networkDomain != null) {
                // TBD: NetworkOfferingId and zoneId. Send uuids instead.
                throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + networkOfferingId + " in zone id=" + zoneId);
            }
        } else {
            if (networkDomain == null) {
                // 1) Get networkDomain from the corresponding account/domain/zone
                if (aclType == ACLType.Domain) {
                    networkDomain = _networkModel.getDomainNetworkDomain(domainId, zoneId);
                } else if (aclType == ACLType.Account) {
                    networkDomain = _networkModel.getAccountNetworkDomain(owner.getId(), zoneId);
                }
                // 2) If null, generate networkDomain using domain suffix from the global config variables
                if (networkDomain == null) {
                    networkDomain = "cs" + Long.toHexString(owner.getId()) + GuestDomainSuffix.valueIn(zoneId);
                }
            } else {
                // validate network domain
                if (!NetUtils.verifyDomainName(networkDomain)) {
                    throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain " + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "and the hyphen ('-'); can't start or end with \"-\"");
                }
            }
        }
    }
    // In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x
    // limitation, remove after we introduce support for multiple ip ranges
    // with different Cidrs for the same Shared network
    final boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced && ntwkOff.getTrafficType() == TrafficType.Guest && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)));
    if (cidr == null && ip6Cidr == null && cidrRequired) {
        if (ntwkOff.getGuestType() == GuestType.Shared) {
            throw new InvalidParameterValueException(String.format("Gateway/netmask are required when creating %s networks.", Network.GuestType.Shared));
        } else {
            throw new InvalidParameterValueException("gateway/netmask are required when create network of" + " type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled");
        }
    }
    checkL2OfferingServices(ntwkOff);
    // No cidr can be specified in Basic zone
    if (zone.getNetworkType() == NetworkType.Basic && cidr != null) {
        throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask can't be specified for zone of type " + NetworkType.Basic);
    }
    // Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4
    if (cidr != null && ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) {
        if (!NetUtils.validateGuestCidr(cidr)) {
            throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC 1918 or 6598 compliant");
        }
    }
    final String networkDomainFinal = networkDomain;
    final String vlanIdFinal = vlanId;
    final Boolean subdomainAccessFinal = subdomainAccess;
    final Network network = Transaction.execute(new TransactionCallback<Network>() {

        @Override
        public Network doInTransaction(final TransactionStatus status) {
            Long physicalNetworkId = null;
            if (pNtwk != null) {
                physicalNetworkId = pNtwk.getId();
            }
            final DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null, null, physicalNetworkId);
            final NetworkVO userNetwork = new NetworkVO();
            userNetwork.setNetworkDomain(networkDomainFinal);
            if (cidr != null && gateway != null) {
                userNetwork.setCidr(cidr);
                userNetwork.setGateway(gateway);
            }
            if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
                userNetwork.setIp6Cidr(ip6Cidr);
                userNetwork.setIp6Gateway(ip6Gateway);
            }
            if (externalId != null) {
                userNetwork.setExternalId(externalId);
            }
            if (StringUtils.isNotBlank(routerIp)) {
                userNetwork.setRouterIp(routerIp);
            }
            if (StringUtils.isNotBlank(routerIpv6)) {
                userNetwork.setRouterIpv6(routerIpv6);
            }
            if (vlanIdFinal != null) {
                if (isolatedPvlan == null) {
                    URI uri = null;
                    if (UuidUtils.validateUUID(vlanIdFinal)) {
                        // Logical router's UUID provided as VLAN_ID
                        // Set transient field
                        userNetwork.setVlanIdAsUUID(vlanIdFinal);
                    } else {
                        uri = encodeVlanIdIntoBroadcastUri(vlanIdFinal, pNtwk);
                    }
                    if (_networksDao.listByPhysicalNetworkPvlan(physicalNetworkId, uri.toString()).size() > 0) {
                        throw new InvalidParameterValueException("Network with vlan " + vlanIdFinal + " already exists or overlaps with other network pvlans in zone " + zoneId);
                    }
                    userNetwork.setBroadcastUri(uri);
                    if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
                        userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
                    } else {
                        userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
                    }
                } else {
                    if (vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
                        throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!");
                    }
                    URI uri = NetUtils.generateUriForPvlan(vlanIdFinal, isolatedPvlan, isolatedPvlanType.toString());
                    if (_networksDao.listByPhysicalNetworkPvlan(physicalNetworkId, uri.toString(), isolatedPvlanType).size() > 0) {
                        throw new InvalidParameterValueException("Network with primary vlan " + vlanIdFinal + " and secondary vlan " + isolatedPvlan + " type " + isolatedPvlanType + " already exists or overlaps with other network pvlans in zone " + zoneId);
                    }
                    userNetwork.setBroadcastUri(uri);
                    userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan);
                    userNetwork.setPvlanType(isolatedPvlanType);
                }
            }
            final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId, isDisplayNetworkEnabled);
            Network network = null;
            if (networks == null || networks.isEmpty()) {
                throw new CloudRuntimeException("Fail to create a network");
            } else {
                if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) {
                    Network defaultGuestNetwork = networks.get(0);
                    for (final Network nw : networks) {
                        if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) {
                            defaultGuestNetwork = nw;
                        }
                    }
                    network = defaultGuestNetwork;
                } else {
                    // For shared network
                    network = networks.get(0);
                }
            }
            if (updateResourceCount) {
                _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
            }
            return network;
        }
    });
    CallContext.current().setEventDetails("Network Id: " + network.getId());
    CallContext.current().putContextParameter(Network.class, network.getUuid());
    return network;
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) PhysicalNetworkVO(com.cloud.network.dao.PhysicalNetworkVO) NetworkVO(com.cloud.network.dao.NetworkVO) AccountGuestVlanMapVO(com.cloud.network.dao.AccountGuestVlanMapVO) DataCenterDeployment(com.cloud.deploy.DataCenterDeployment) Capability(com.cloud.network.Network.Capability) NetworkOffering(com.cloud.offering.NetworkOffering) TransactionStatus(com.cloud.utils.db.TransactionStatus) URI(java.net.URI) DataCenterVnetVO(com.cloud.dc.DataCenterVnetVO) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) Network(com.cloud.network.Network) PhysicalNetwork(com.cloud.network.PhysicalNetwork) NetworkOfferingVO(com.cloud.offerings.NetworkOfferingVO) LinkedList(java.util.LinkedList) ArrayList(java.util.ArrayList) List(java.util.List) DB(com.cloud.utils.db.DB)

Example 19 with DataCenterVnetVO

use of com.cloud.dc.DataCenterVnetVO in project cloudstack by apache.

the class DataCenterVnetDaoImpl method take.

@Override
@DB
public DataCenterVnetVO take(long physicalNetworkId, long accountId, String reservationId, List<Long> vlanDbIds) {
    SearchCriteria<DataCenterVnetVO> sc;
    if (vlanDbIds != null) {
        sc = FreeDedicatedVnetSearch.create();
        sc.setParameters("accountGuestVlanMapId", vlanDbIds.toArray());
    } else {
        sc = FreeVnetSearch.create();
    }
    sc.setParameters("physicalNetworkId", physicalNetworkId);
    Date now = new Date();
    TransactionLegacy txn = TransactionLegacy.currentTxn();
    txn.start();
    DataCenterVnetVO vo = lockOneRandomRow(sc, true);
    if (vo == null) {
        return null;
    }
    vo.setTakenAt(now);
    vo.setAccountId(accountId);
    vo.setReservationId(reservationId);
    update(vo.getId(), vo);
    txn.commit();
    return vo;
}
Also used : TransactionLegacy(com.cloud.utils.db.TransactionLegacy) DataCenterVnetVO(com.cloud.dc.DataCenterVnetVO) Date(java.util.Date) DB(com.cloud.utils.db.DB)

Example 20 with DataCenterVnetVO

use of com.cloud.dc.DataCenterVnetVO in project cloudstack by apache.

the class DataCenterVnetDaoImpl method findOverlappingVnets.

private List<DataCenterVnetVO> findOverlappingVnets(final long dcId, final Long physicalNetworkId, final String vnet) {
    final List<Integer> searchVnets = UriUtils.expandVlanUri(vnet);
    final List<DataCenterVnetVO> overlappingVnets = new ArrayList<>();
    if (searchVnets == null || searchVnets.isEmpty()) {
        return overlappingVnets;
    }
    SearchCriteria<DataCenterVnetVO> sc = VnetDcSearch.create();
    sc.setParameters("dc", dcId);
    if (physicalNetworkId != null) {
        sc.setParameters("physicalNetworkId", physicalNetworkId);
    }
    for (final DataCenterVnetVO dcVNet : listBy(sc)) {
        if (dcVNet == null || dcVNet.getVnet() == null) {
            continue;
        }
        final Integer vnetValue = NumbersUtil.parseInt(dcVNet.getVnet(), -1);
        if (vnetValue != -1 && searchVnets.contains(vnetValue)) {
            overlappingVnets.add(dcVNet);
        }
    }
    return overlappingVnets;
}
Also used : DataCenterVnetVO(com.cloud.dc.DataCenterVnetVO) ArrayList(java.util.ArrayList)

Aggregations

DataCenterVnetVO (com.cloud.dc.DataCenterVnetVO)22 ArrayList (java.util.ArrayList)16 AccountGuestVlanMapVO (com.cloud.network.dao.AccountGuestVlanMapVO)11 PhysicalNetworkVO (com.cloud.network.dao.PhysicalNetworkVO)9 DB (com.cloud.utils.db.DB)7 List (java.util.List)7 TransactionLegacy (com.cloud.utils.db.TransactionLegacy)6 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)5 Pair (com.cloud.utils.Pair)4 InvalidParameterValueException (com.cloud.utils.exception.InvalidParameterValueException)4 Field (java.lang.reflect.Field)4 DataCenterDeployment (com.cloud.deploy.DataCenterDeployment)3 Network (com.cloud.network.Network)3 Capability (com.cloud.network.Network.Capability)3 PhysicalNetwork (com.cloud.network.PhysicalNetwork)3 NetworkVO (com.cloud.network.dao.NetworkVO)3 NetworkOffering (com.cloud.offering.NetworkOffering)3 NetworkOfferingVO (com.cloud.offerings.NetworkOfferingVO)3 TransactionStatus (com.cloud.utils.db.TransactionStatus)3 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)3