throw ex;
}
sc.setParameters("dc", dcId);
DataCenter zone = _configMgr.getZone(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");
}
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
boolean useSystemIps = Boolean.parseBoolean(_configServer.getConfigValue(Config.UseSystemPublicIps.key(),
Config.ConfigurationParameterScope.account.toString(), owner.getId()));
if(useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
fetchFromDedicatedRange = false;
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
addrs = _ipAddressDao.lockRows(sc, filter, true);
}
}
if (addrs.size() == 0) {
if (podId != null) {
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());
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) {
// Check that the maximum number of public IPs for the given accountId will not be exceeded
try {
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
} catch (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.");
}
}
IPAddressVO addr = addrs.get(0);
addr.setSourceNat(sourceNat);
addr.setAllocatedTime(new Date());
addr.setAllocatedInDomainId(owner.getDomainId());
addr.setAllocatedToAccountId(owner.getId());
addr.setSystem(isSystem);
if (assign) {
markPublicIpAsAllocated(addr);
} else {
addr.setState(IpAddress.State.Allocating);
}
addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating);
if (vlanUse != VlanType.DirectAttached || zone.getNetworkType() == NetworkType.Basic) {
addr.setAssociatedWithNetworkId(guestNetworkId);
addr.setVpcId(vpcId);
}
_ipAddressDao.update(addr.getId(), addr);