5252
5353import com .cloud .exception .UnsupportedServiceException ;
5454import com .cloud .network .as .AutoScaleManager ;
55+ import com .cloud .resourcelimit .CheckedReservation ;
5556import com .cloud .user .AccountManagerImpl ;
5657import org .apache .cloudstack .acl .RoleType ;
5758import org .apache .cloudstack .acl .SecurityChecker ;
128129import org .apache .cloudstack .region .Region ;
129130import org .apache .cloudstack .region .RegionVO ;
130131import org .apache .cloudstack .region .dao .RegionDao ;
132+ import org .apache .cloudstack .reservation .dao .ReservationDao ;
131133import org .apache .cloudstack .resourcedetail .DiskOfferingDetailVO ;
132134import org .apache .cloudstack .resourcedetail .dao .DiskOfferingDetailsDao ;
133135import org .apache .cloudstack .storage .datastore .db .ImageStoreDao ;
@@ -395,6 +397,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
395397 @ Inject
396398 ResourceLimitService _resourceLimitMgr ;
397399 @ Inject
400+ ReservationDao reservationDao ;
401+ @ Inject
398402 ProjectManager _projectMgr ;
399403 @ Inject
400404 DataStoreManager _dataStoreMgr ;
@@ -4833,22 +4837,20 @@ public Vlan createVlanAndPublicIpRange(final CreateVlanIpRangeCmd cmd) throws In
48334837 throw new InvalidParameterValueException ("Gateway, netmask and zoneId have to be passed in for virtual and direct untagged networks" );
48344838 }
48354839
4836- if (forVirtualNetwork ) {
4837- if (vlanOwner != null ) {
4838-
4839- final long accountIpRange = NetUtils .ip2Long (endIP ) - NetUtils .ip2Long (startIP ) + 1 ;
4840-
4841- // check resource limits
4842- _resourceLimitMgr .checkResourceLimit (vlanOwner , ResourceType .public_ip , accountIpRange );
4843- }
4844- }
48454840 // Check if the IP range overlaps with the private ip
48464841 if (ipv4 ) {
48474842 checkOverlapPrivateIpRange (zoneId , startIP , endIP );
48484843 }
48494844
4850- return commitVlan (zoneId , podId , startIP , endIP , newVlanGateway , newVlanNetmask , vlanId , forVirtualNetwork , forSystemVms , networkId , physicalNetworkId , startIPv6 , endIPv6 , ip6Gateway ,
4851- ip6Cidr , domain , vlanOwner , network , sameSubnet , cmd .isForNsx ());
4845+ long reservedIpAddressesAmount = 0L ;
4846+ if (forVirtualNetwork && vlanOwner != null ) {
4847+ reservedIpAddressesAmount = NetUtils .ip2Long (endIP ) - NetUtils .ip2Long (startIP ) + 1 ;
4848+ }
4849+
4850+ try (CheckedReservation publicIpReservation = new CheckedReservation (vlanOwner , ResourceType .public_ip , null , null , null , reservedIpAddressesAmount , null , reservationDao , _resourceLimitMgr )) {
4851+ return commitVlan (zoneId , podId , startIP , endIP , newVlanGateway , newVlanNetmask , vlanId , forVirtualNetwork , forSystemVms , networkId , physicalNetworkId , startIPv6 , endIPv6 , ip6Gateway ,
4852+ ip6Cidr , domain , vlanOwner , network , sameSubnet , cmd .isForNsx ());
4853+ }
48524854 }
48534855
48544856 private Network getNetwork (Long networkId ) {
@@ -5377,7 +5379,7 @@ public Vlan updateVlanAndPublicIpRange(final long id, String startIp,
53775379 String endIpv6 ,
53785380 String ip6Gateway ,
53795381 String ip6Cidr ,
5380- Boolean forSystemVms ) throws ConcurrentOperationException {
5382+ Boolean forSystemVms ) throws ConcurrentOperationException , ResourceAllocationException {
53815383
53825384 VlanVO vlanRange = _vlanDao .findById (id );
53835385 if (vlanRange == null ) {
@@ -5397,24 +5399,50 @@ public Vlan updateVlanAndPublicIpRange(final long id, String startIp,
53975399 }
53985400 }
53995401
5402+ AccountVlanMapVO accountMap = _accountVlanMapDao .findAccountVlanMap (null , id );
5403+ Account account = accountMap != null ? _accountDao .findById (accountMap .getAccountId ()) : null ;
5404+
5405+ DomainVlanMapVO domainMap = _domainVlanMapDao .findDomainVlanMap (null , id );
5406+ Long domainId = domainMap != null ? domainMap .getDomainId () : null ;
5407+
54005408 final Boolean isRangeForSystemVM = checkIfVlanRangeIsForSystemVM (id );
54015409 if (forSystemVms != null && isRangeForSystemVM != forSystemVms ) {
54025410 if (VlanType .DirectAttached .equals (vlanRange .getVlanType ())) {
54035411 throw new InvalidParameterValueException ("forSystemVms is not available for this IP range with vlan type: " + VlanType .DirectAttached );
54045412 }
54055413 // Check if range has already been dedicated
5406- final List <AccountVlanMapVO > maps = _accountVlanMapDao .listAccountVlanMapsByVlan (id );
5407- if (maps != null && !maps .isEmpty ()) {
5414+ if (account != null ) {
54085415 throw new InvalidParameterValueException ("Specified Public IP range has already been dedicated to an account" );
54095416 }
5410-
5411- List <DomainVlanMapVO > domainmaps = _domainVlanMapDao .listDomainVlanMapsByVlan (id );
5412- if (domainmaps != null && !domainmaps .isEmpty ()) {
5417+ if (domainId != null ) {
54135418 throw new InvalidParameterValueException ("Specified Public IP range has already been dedicated to a domain" );
54145419 }
54155420 }
54165421 if (ipv4 ) {
5422+ long existingIpAddressAmount = 0L ;
5423+ long newIpAddressAmount = 0L ;
5424+
5425+ if (account != null ) {
5426+ // IPv4 public range is dedicated to an account (IPv6 cannot be dedicated at the moment).
5427+ // We need to update the resource count.
5428+ existingIpAddressAmount = _publicIpAddressDao .countIPs (vlanRange .getDataCenterId (), id , false );
5429+ newIpAddressAmount = NetUtils .ip2Long (endIp ) - NetUtils .ip2Long (startIp ) + 1 ;
5430+ }
5431+
5432+ try (CheckedReservation publicIpReservation = new CheckedReservation (account , ResourceType .public_ip , null , null , null , newIpAddressAmount , existingIpAddressAmount , reservationDao , _resourceLimitMgr )) {
5433+
54175434 updateVlanAndIpv4Range (id , vlanRange , startIp , endIp , gateway , netmask , isRangeForSystemVM , forSystemVms );
5435+
5436+ if (account != null ) {
5437+ long countDiff = newIpAddressAmount - existingIpAddressAmount ;
5438+ if (countDiff > 0 ) {
5439+ _resourceLimitMgr .incrementResourceCount (account .getId (), ResourceType .public_ip , countDiff );
5440+ } else if (countDiff < 0 ) {
5441+ _resourceLimitMgr .decrementResourceCount (account .getId (), ResourceType .public_ip , Math .abs (countDiff ));
5442+ }
5443+ }
5444+
5445+ }
54185446 }
54195447 if (ipv6 ) {
54205448 updateVlanAndIpv6Range (id , vlanRange , startIpv6 , endIpv6 , ip6Gateway , ip6Cidr , isRangeForSystemVM , forSystemVms );
@@ -5801,12 +5829,6 @@ public Vlan dedicatePublicIpRange(final DedicatePublicIpRangeCmd cmd) throws Res
58015829 throw new InvalidParameterValueException ("Public IP range can be dedicated to an account only in the zone of type " + NetworkType .Advanced );
58025830 }
58035831
5804- // Check Public IP resource limits
5805- if (vlanOwner != null ) {
5806- final int accountPublicIpRange = _publicIpAddressDao .countIPs (zoneId , vlanDbId , false );
5807- _resourceLimitMgr .checkResourceLimit (vlanOwner , ResourceType .public_ip , accountPublicIpRange );
5808- }
5809-
58105832 // Check if any of the Public IP addresses is allocated to another
58115833 // account
58125834 final List <IPAddressVO > ips = _publicIpAddressDao .listByVlanId (vlanDbId );
@@ -5827,6 +5849,10 @@ public Vlan dedicatePublicIpRange(final DedicatePublicIpRangeCmd cmd) throws Res
58275849 }
58285850 }
58295851
5852+ // Check Public IP resource limits
5853+ long reservedIpAddressesAmount = vlanOwner != null ? _publicIpAddressDao .countIPs (zoneId , vlanDbId , false ) : 0L ;
5854+ try (CheckedReservation publicIpReservation = new CheckedReservation (vlanOwner , ResourceType .public_ip , null , null , null , reservedIpAddressesAmount , null , reservationDao , _resourceLimitMgr )) {
5855+
58305856 if (vlanOwner != null ) {
58315857 // Create an AccountVlanMapVO entry
58325858 final AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO (vlanOwner .getId (), vlan .getId ());
@@ -5850,6 +5876,8 @@ public Vlan dedicatePublicIpRange(final DedicatePublicIpRangeCmd cmd) throws Res
58505876 }
58515877
58525878 return vlan ;
5879+
5880+ }
58535881 }
58545882
58555883 @ Override
0 commit comments