vlanOwner = null;
}
}
// Verify that network exists
Network network = null;
if (networkId != null) {
network = _networkDao.findById(networkId);
if (network == null) {
throw new InvalidParameterValueException("Unable to find network by id " + networkId);
} else {
zoneId = network.getDataCenterId();
physicalNetworkId = network.getPhysicalNetworkId();
}
} else if (ipv6) {
throw new InvalidParameterValueException("Only support IPv6 on extending existed network");
}
// Verify that zone exists
DataCenterVO zone = _zoneDao.findById(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
}
if (ipv6) {
if (network.getGuestType() != GuestType.Shared || zone.isSecurityGroupEnabled()) {
throw new InvalidParameterValueException(
"Only support IPv6 on extending existed share network without SG");
}
}
// verify that physical network exists
PhysicalNetworkVO pNtwk = null;
if (physicalNetworkId != null) {
pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
if (pNtwk == null) {
throw new InvalidParameterValueException("Unable to find Physical Network with id=" + physicalNetworkId);
}
if (zoneId == null) {
zoneId = pNtwk.getDataCenterId();
}
} else {
if (zoneId == null) {
throw new InvalidParameterValueException("");
}
// deduce physicalNetworkFrom Zone or Network.
if (network != null && network.getPhysicalNetworkId() != null) {
physicalNetworkId = network.getPhysicalNetworkId();
} else {
if (forVirtualNetwork) {
// default physical network with public traffic in the zone
physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId,
TrafficType.Public).getId();
} else {
if (zone.getNetworkType() == DataCenter.NetworkType.Basic) {
// default physical network with guest traffic in the
// zone
physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId,
TrafficType.Guest).getId();
} else if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
if (zone.isSecurityGroupEnabled()) {
physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId,
TrafficType.Guest).getId();
} else {
throw new InvalidParameterValueException(
"Physical Network Id is null, please provide the Network id for Direct vlan creation ");
}
}
}
}
}
// Check if zone is enabled
Account caller = UserContext.current().getCaller();
if (Grouping.AllocationState.Disabled == zone.getAllocationState()
&& !_accountMgr.isRootAdmin(caller.getType())) {
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
}
if (zone.isSecurityGroupEnabled() && zone.getNetworkType() != DataCenter.NetworkType.Basic && forVirtualNetwork) {
throw new InvalidParameterValueException(
"Can't add virtual ip range into a zone with security group enabled");
}
// If networkId is not specified, and vlan is Virtual or Direct
// Untagged, try to locate default networks
if (forVirtualNetwork) {
if (network == null) {
// find default public network in the zone
networkId = _networkModel.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId();
network = _networkModel.getNetwork(networkId);
} else if (network.getGuestType() != null || network.getTrafficType() != TrafficType.Public) {
throw new InvalidParameterValueException("Can't find Public network by id=" + networkId);
}
} else {
if (network == null) {
if (zone.getNetworkType() == DataCenter.NetworkType.Basic) {
networkId = _networkModel.getExclusiveGuestNetwork(zoneId).getId();
network = _networkModel.getNetwork(networkId);
} else {
network = _networkModel.getNetworkWithSecurityGroupEnabled(zoneId);
if (network == null) {
throw new InvalidParameterValueException("Nework id is required for Direct vlan creation ");
}
networkId = network.getId();
zoneId = network.getDataCenterId();
}
} else if (network.getGuestType() == null || network.getGuestType() == Network.GuestType.Isolated) {
throw new InvalidParameterValueException("Can't create direct vlan for network id=" + networkId
+ " with type: " + network.getGuestType());
}
}
Pair<Boolean, Pair<String, String>> sameSubnet = null;
// Can add vlan range only to the network which allows it
if (!network.getSpecifyIpRanges()) {
throw new InvalidParameterValueException("Network " + network + " doesn't support adding ip ranges");
}
if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
if (network.getTrafficType() == TrafficType.Guest) {
if (network.getGuestType() != GuestType.Shared) {
throw new InvalidParameterValueException(
"Can execute createVLANIpRanges on shared guest network, but type of this guest network "
+ network.getId() + " is " + network.getGuestType());
}
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
if (vlans != null && vlans.size() > 0) {
VlanVO vlan = vlans.get(0);
if (vlanId == null) {
vlanId = vlan.getVlanTag();
} else if (!vlan.getVlanTag().equals(vlanId)) {
throw new InvalidParameterValueException("there is already one vlan " + vlan.getVlanTag()
+ " on network :" + +network.getId() + ", only one vlan is allowed on guest network");
}
}
sameSubnet = validateIpRange(startIP, endIP, newVlanGateway, newVlanNetmask, vlans, ipv4, ipv6,
ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
}
} else if (network.getTrafficType() == TrafficType.Management) {
throw new InvalidParameterValueException("Cannot execute createVLANIpRanges on management network");
} else if (zone.getNetworkType() == NetworkType.Basic) {
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
sameSubnet = validateIpRange(startIP, endIP, newVlanGateway, newVlanNetmask, vlans, ipv4, ipv6, ip6Gateway,
ip6Cidr, startIPv6, endIPv6, network);
}
if (zoneId == null || (ipv6 && (ip6Gateway == null || ip6Cidr == null))) {
throw new InvalidParameterValueException(
"Gateway, netmask and zoneId have to be passed in for virtual and direct untagged networks");
}
if (forVirtualNetwork) {
if (vlanOwner != null) {
long accountIpRange = NetUtils.ip2Long(endIP) - NetUtils.ip2Long(startIP) + 1;
// check resource limits
_resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountIpRange);
}
}
// Check if the IP range overlaps with the private ip
if (ipv4) {
checkOverlapPrivateIpRange(zoneId, startIP, endIP);
}
Transaction txn = Transaction.currentTxn();
txn.start();
if ((sameSubnet == null || sameSubnet.first() == false) && (network.getTrafficType()== TrafficType.Guest) && (network.getGuestType() == GuestType.Shared) && (_vlanDao.listVlansByNetworkId(networkId) != null)) {
Map<Capability, String> dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(_networkOfferingDao.findById(network.getNetworkOfferingId()), Service.Dhcp);
String supportsMultipleSubnets = dhcpCapabilities.get(Capability.DhcpAccrossMultipleSubnets);
if (supportsMultipleSubnets == null || !Boolean.valueOf(supportsMultipleSubnets)) {
throw new InvalidParameterValueException("The Dhcp serivice provider for this network dose not support the dhcp across multiple subnets");
}
s_logger.info("adding a new subnet to the network " + network.getId());
} else if (sameSubnet != null) {
// if it is same subnet the user might not send the vlan and the
// netmask details. so we are
// figuring out while validation and setting them here.
newVlanGateway = sameSubnet.second().first();