3636import javax .mail .MessagingException ;
3737import javax .naming .ConfigurationException ;
3838
39+ import com .cloud .resourcelimit .CheckedReservation ;
3940import org .apache .cloudstack .acl .ControlledEntity ;
4041import org .apache .cloudstack .acl .ProjectRole ;
4142import org .apache .cloudstack .acl .SecurityChecker .AccessType ;
4748import org .apache .cloudstack .framework .messagebus .MessageBus ;
4849import org .apache .cloudstack .framework .messagebus .PublishScope ;
4950import org .apache .cloudstack .managed .context .ManagedContextRunnable ;
51+ import org .apache .cloudstack .reservation .dao .ReservationDao ;
5052import org .apache .cloudstack .utils .mailing .MailAddress ;
5153import org .apache .cloudstack .utils .mailing .SMTPMailProperties ;
5254import org .apache .cloudstack .utils .mailing .SMTPMailSender ;
@@ -159,6 +161,8 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
159161 private VpcManager _vpcMgr ;
160162 @ Inject
161163 MessageBus messageBus ;
164+ @ Inject
165+ private ReservationDao reservationDao ;
162166
163167 protected boolean _invitationRequired = false ;
164168 protected long _invitationTimeOut = 86400000 ;
@@ -272,8 +276,7 @@ public Project createProject(final String name, final String displayText, String
272276 owner = _accountDao .findById (user .getAccountId ());
273277 }
274278
275- //do resource limit check
276- _resourceLimitMgr .checkResourceLimit (owner , ResourceType .project );
279+ try (CheckedReservation projectReservation = new CheckedReservation (owner , ResourceType .project , null , null , 1L , reservationDao , _resourceLimitMgr )) {
277280
278281 final Account ownerFinal = owner ;
279282 User finalUser = user ;
@@ -308,6 +311,7 @@ public Project doInTransaction(TransactionStatus status) {
308311 messageBus .publish (_name , ProjectManager .MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT , PublishScope .LOCAL , project );
309312
310313 return project ;
314+ }
311315 }
312316
313317 @ Override
@@ -491,6 +495,9 @@ public Boolean doInTransaction(TransactionStatus status) {
491495 //remove account
492496 ProjectAccountVO projectAccount = _projectAccountDao .findByProjectIdAccountId (projectId , account .getId ());
493497 success = _projectAccountDao .remove (projectAccount .getId ());
498+ if (projectAccount .getAccountRole () == Role .Admin ) {
499+ _resourceLimitMgr .decrementResourceCount (account .getId (), ResourceType .project );
500+ }
494501
495502 //remove all invitations for account
496503 if (success ) {
@@ -594,12 +601,22 @@ public boolean addUserToProject(Long projectId, String username, String email, L
594601 if (username == null ) {
595602 throw new InvalidParameterValueException ("User information (ID) is required to add user to the project" );
596603 }
604+
605+ boolean shouldIncrementResourceCount = projectRole != null && Role .Admin == projectRole ;
606+ try (CheckedReservation cr = new CheckedReservation (userAccount , ResourceType .project , shouldIncrementResourceCount ? 1L : 0L , reservationDao , _resourceLimitMgr )) {
597607 if (assignUserToProject (project , user .getId (), user .getAccountId (), projectRole ,
598608 Optional .ofNullable (role ).map (ProjectRole ::getId ).orElse (null )) != null ) {
609+ if (shouldIncrementResourceCount ) {
610+ _resourceLimitMgr .incrementResourceCount (userAccount .getId (), ResourceType .project );
611+ }
599612 return true ;
613+ } else {
614+ logger .warn ("Failed to add user to project: {}" , project );
615+ return false ;
616+ }
617+ } catch (ResourceAllocationException e ) {
618+ throw new RuntimeException (e );
600619 }
601- logger .warn ("Failed to add user to project: {}" , project );
602- return false ;
603620 }
604621 }
605622
@@ -652,14 +669,18 @@ public boolean canModifyProjectAccount(Account caller, long accountId) {
652669 }
653670
654671 private void updateProjectAccount (ProjectAccountVO futureOwner , Role newAccRole , Long accountId ) throws ResourceAllocationException {
655- _resourceLimitMgr .checkResourceLimit (_accountMgr .getAccount (accountId ), ResourceType .project );
672+ Account account = _accountMgr .getAccount (accountId );
673+ boolean shouldIncrementResourceCount = Role .Admin == newAccRole ;
674+
675+ try (CheckedReservation checkedReservation = new CheckedReservation (account , ResourceType .project , shouldIncrementResourceCount ? 1L : 0L , reservationDao , _resourceLimitMgr )) {
656676 futureOwner .setAccountRole (newAccRole );
657677 _projectAccountDao .update (futureOwner .getId (), futureOwner );
658- if (newAccRole != null && Role . Admin == newAccRole ) {
678+ if (shouldIncrementResourceCount ) {
659679 _resourceLimitMgr .incrementResourceCount (accountId , ResourceType .project );
660680 } else {
661681 _resourceLimitMgr .decrementResourceCount (accountId , ResourceType .project );
662682 }
683+ }
663684 }
664685
665686 @ Override
@@ -701,7 +722,8 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Resour
701722 " doesn't belong to the project. Add it to the project first and then change the project's ownership" );
702723 }
703724
704- //do resource limit check
725+ try (CheckedReservation checkedReservation = new CheckedReservation (futureOwnerAccount , ResourceType .project , null , null , 1L , reservationDao , _resourceLimitMgr )) {
726+
705727 _resourceLimitMgr .checkResourceLimit (_accountMgr .getAccount (futureOwnerAccount .getId ()), ResourceType .project );
706728
707729 //unset the role for the old owner
@@ -714,7 +736,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Resour
714736 futureOwner .setAccountRole (Role .Admin );
715737 _projectAccountDao .update (futureOwner .getId (), futureOwner );
716738 _resourceLimitMgr .incrementResourceCount (futureOwnerAccount .getId (), ResourceType .project );
717-
739+ }
718740 } else {
719741 logger .trace ("Future owner {}is already the owner of the project {}" , newOwnerName , project );
720742 }
@@ -857,13 +879,22 @@ public boolean addAccountToProject(long projectId, String accountName, String em
857879 if (account == null ) {
858880 throw new InvalidParameterValueException ("Account information is required for assigning account to the project" );
859881 }
882+
883+ boolean shouldIncrementResourceCount = projectRoleType != null && Role .Admin == projectRoleType ;
884+ try (CheckedReservation cr = new CheckedReservation (account , ResourceType .project , shouldIncrementResourceCount ? 1L : 0L , reservationDao , _resourceLimitMgr )) {
860885 if (assignAccountToProject (project , account .getId (), projectRoleType , null ,
861886 Optional .ofNullable (projectRole ).map (ProjectRole ::getId ).orElse (null )) != null ) {
887+ if (shouldIncrementResourceCount ) {
888+ _resourceLimitMgr .incrementResourceCount (account .getId (), ResourceType .project );
889+ }
862890 return true ;
863891 } else {
864892 logger .warn ("Failed to add account {} to project {}" , accountName , project );
865893 return false ;
866894 }
895+ } catch (ResourceAllocationException e ) {
896+ throw new RuntimeException (e );
897+ }
867898 }
868899 }
869900
@@ -1042,7 +1073,9 @@ public Boolean doInTransaction(TransactionStatus status) {
10421073 boolean success = true ;
10431074 ProjectAccountVO projectAccount = _projectAccountDao .findByProjectIdUserId (projectId , user .getAccountId (), user .getId ());
10441075 success = _projectAccountDao .remove (projectAccount .getId ());
1045-
1076+ if (projectAccount .getAccountRole () == Role .Admin ) {
1077+ _resourceLimitMgr .decrementResourceCount (user .getAccountId (), ResourceType .project );
1078+ }
10461079 if (success ) {
10471080 logger .debug ("Removed user {} from project. Removing any invite sent to the user" , user );
10481081 ProjectInvitation invite = _projectInvitationDao .findByUserIdProjectId (user .getId (), user .getAccountId (), projectId );
0 commit comments