@@ -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