Skip to content

Commit caf0dd2

Browse files
author
Likitha Shetty
committed
Dedicate Public IP range - If every public ip range in the system is dedicated when an account with no dedicate ranges
acquires a new public ip the request should fail
1 parent 973c43a commit caf0dd2

1 file changed

Lines changed: 58 additions & 56 deletions

File tree

server/src/com/cloud/network/NetworkManagerImpl.java

Lines changed: 58 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ public PublicIp fetchNewPublicIp(long dcId, Long podId, List<Long> vlanDbIds, Ac
284284
Long guestNetworkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem, Long vpcId)
285285
throws InsufficientAddressCapacityException {
286286
StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
287+
boolean fetchFromDedicatedRange = false;
288+
List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
289+
List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
290+
287291
Transaction txn = Transaction.currentTxn();
288292
txn.start();
289293
SearchCriteria<IPAddressVO> sc = null;
@@ -296,9 +300,37 @@ public PublicIp fetchNewPublicIp(long dcId, Long podId, List<Long> vlanDbIds, Ac
296300
errorMessage.append(" zone id=" + dcId);
297301
}
298302

299-
if ( vlanDbIds != null && !vlanDbIds.isEmpty() ) {
300-
sc.setParameters("vlanId", vlanDbIds.toArray());
301-
errorMessage.append(", vlanId id=" + vlanDbIds.toArray());
303+
// If owner has dedicated Public IP ranges, fetch IP from the dedicated range
304+
// Otherwise fetch IP from the system pool
305+
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
306+
for (AccountVlanMapVO map : maps) {
307+
if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
308+
dedicatedVlanDbIds.add(map.getVlanDbId());
309+
}
310+
List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
311+
for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
312+
if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
313+
nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
314+
}
315+
if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
316+
fetchFromDedicatedRange = true;
317+
sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
318+
errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray());
319+
} else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
320+
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
321+
errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
322+
} else {
323+
if (podId != null) {
324+
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException
325+
("Insufficient address capacity", Pod.class, podId);
326+
ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
327+
throw ex;
328+
}
329+
s_logger.warn(errorMessage.toString());
330+
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException
331+
("Insufficient address capacity", DataCenter.class, dcId);
332+
ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
333+
throw ex;
302334
}
303335

304336
sc.setParameters("dc", dcId);
@@ -321,6 +353,16 @@ public PublicIp fetchNewPublicIp(long dcId, Long podId, List<Long> vlanDbIds, Ac
321353

322354
List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
323355

356+
// If all the dedicated IPs of the owner are in use fetch an IP from the system pool
357+
if (addrs.size() == 0 && fetchFromDedicatedRange) {
358+
if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
359+
fetchFromDedicatedRange = false;
360+
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
361+
errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
362+
addrs = _ipAddressDao.lockRows(sc, filter, true);
363+
}
364+
}
365+
324366
if (addrs.size() == 0) {
325367
if (podId != null) {
326368
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException
@@ -338,6 +380,16 @@ public PublicIp fetchNewPublicIp(long dcId, Long podId, List<Long> vlanDbIds, Ac
338380

339381
assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
340382

383+
if (!fetchFromDedicatedRange) {
384+
// Check that the maximum number of public IPs for the given accountId will not be exceeded
385+
try {
386+
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
387+
} catch (ResourceAllocationException ex) {
388+
s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
389+
throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
390+
}
391+
}
392+
341393
IPAddressVO addr = addrs.get(0);
342394
addr.setSourceNat(sourceNat);
343395
addr.setAllocatedTime(new Date());
@@ -442,14 +494,6 @@ public PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vp
442494

443495
long ownerId = owner.getId();
444496

445-
// Check that the maximum number of public IPs for the given accountId will not be exceeded
446-
try {
447-
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
448-
} catch (ResourceAllocationException ex) {
449-
s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
450-
throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
451-
}
452-
453497
PublicIp ip = null;
454498
Transaction txn = Transaction.currentTxn();
455499
try {
@@ -466,15 +510,7 @@ public PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vp
466510
s_logger.debug("lock account " + ownerId + " is acquired");
467511
}
468512

469-
// If account has Account specific ip ranges, try to allocate ip from there
470-
List<Long> vlanIds = new ArrayList<Long>();
471-
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ownerId);
472-
if (maps != null && !maps.isEmpty()) {
473-
vlanIds.add(maps.get(0).getVlanDbId());
474-
}
475-
476-
477-
ip = fetchNewPublicIp(dcId, null, vlanIds, owner, VlanType.VirtualNetwork, guestNtwkId,
513+
ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId,
478514
isSourceNat, false, null, false, vpcId);
479515
IPAddressVO publicIp = ip.ip();
480516

@@ -610,9 +646,6 @@ public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, l
610646

611647
VlanType vlanType = VlanType.VirtualNetwork;
612648
boolean assign = false;
613-
boolean allocateFromDedicatedRange = false;
614-
List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
615-
List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
616649

617650
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
618651
// zone is of type DataCenter. See DataCenterVO.java.
@@ -642,39 +675,8 @@ public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, l
642675

643676
txn.start();
644677

645-
// If account has dedicated Public IP ranges, allocate IP from the dedicated range
646-
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ipOwner.getId());
647-
for (AccountVlanMapVO map : maps) {
648-
dedicatedVlanDbIds.add(map.getVlanDbId());
649-
}
650-
if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
651-
allocateFromDedicatedRange = true;
652-
}
653-
654-
try {
655-
if (allocateFromDedicatedRange) {
656-
ip = fetchNewPublicIp(zone.getId(), null, dedicatedVlanDbIds, ipOwner, vlanType, null,
657-
false, assign, null, isSystem, null);
658-
}
659-
} catch(InsufficientAddressCapacityException e) {
660-
s_logger.warn("All IPs dedicated to account " + ipOwner.getId() + " has been acquired." +
661-
" Now acquiring from the system pool");
662-
txn.close();
663-
allocateFromDedicatedRange = false;
664-
}
665-
666-
if (!allocateFromDedicatedRange) {
667-
// Check that the maximum number of public IPs for the given
668-
// accountId will not be exceeded
669-
_resourceLimitMgr.checkResourceLimit(accountToLock, ResourceType.public_ip);
670-
671-
List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(zone.getId());
672-
for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
673-
nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
674-
}
675-
ip = fetchNewPublicIp(zone.getId(), null, nonDedicatedVlanDbIds, ipOwner, vlanType, null, false, assign, null,
676-
isSystem, null);
677-
}
678+
ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null,
679+
isSystem, null);
678680

679681
if (ip == null) {
680682
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException

0 commit comments

Comments
 (0)