mirror of https://github.com/apache/cloudstack.git
[20.3] Implement/fix limit validation for projects
This commit is contained in:
parent
4dd91feb27
commit
1593944553
|
|
@ -36,6 +36,7 @@ import javax.inject.Inject;
|
|||
import javax.mail.MessagingException;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.resourcelimit.CheckedReservation;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
|
|
@ -47,6 +48,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.reservation.dao.ReservationDao;
|
||||
import org.apache.cloudstack.utils.mailing.MailAddress;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
|
||||
|
|
@ -159,6 +161,8 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
private VpcManager _vpcMgr;
|
||||
@Inject
|
||||
MessageBus messageBus;
|
||||
@Inject
|
||||
private ReservationDao reservationDao;
|
||||
|
||||
protected boolean _invitationRequired = false;
|
||||
protected long _invitationTimeOut = 86400000;
|
||||
|
|
@ -272,8 +276,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
owner = _accountDao.findById(user.getAccountId());
|
||||
}
|
||||
|
||||
//do resource limit check
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.project);
|
||||
try (CheckedReservation projectReservation = new CheckedReservation(owner, ResourceType.project, null, null, 1L, reservationDao, _resourceLimitMgr)) {
|
||||
|
||||
final Account ownerFinal = owner;
|
||||
User finalUser = user;
|
||||
|
|
@ -308,6 +311,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
messageBus.publish(_name, ProjectManager.MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project);
|
||||
|
||||
return project;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -491,6 +495,9 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
//remove account
|
||||
ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
|
||||
success = _projectAccountDao.remove(projectAccount.getId());
|
||||
if (projectAccount.getAccountRole() == Role.Admin) {
|
||||
_resourceLimitMgr.decrementResourceCount(account.getId(), ResourceType.project);
|
||||
}
|
||||
|
||||
//remove all invitations for account
|
||||
if (success) {
|
||||
|
|
@ -594,12 +601,22 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
if (username == null) {
|
||||
throw new InvalidParameterValueException("User information (ID) is required to add user to the project");
|
||||
}
|
||||
|
||||
boolean shouldIncrementResourceCount = projectRole != null && Role.Admin == projectRole;
|
||||
try (CheckedReservation cr = new CheckedReservation(userAccount, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
|
||||
if (assignUserToProject(project, user.getId(), user.getAccountId(), projectRole,
|
||||
Optional.ofNullable(role).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
if (shouldIncrementResourceCount) {
|
||||
_resourceLimitMgr.incrementResourceCount(userAccount.getId(), ResourceType.project);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
logger.warn("Failed to add user to project: {}", project);
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceAllocationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
logger.warn("Failed to add user to project: {}", project);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -652,14 +669,18 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
}
|
||||
|
||||
private void updateProjectAccount(ProjectAccountVO futureOwner, Role newAccRole, Long accountId) throws ResourceAllocationException {
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), ResourceType.project);
|
||||
Account account = _accountMgr.getAccount(accountId);
|
||||
boolean shouldIncrementResourceCount = Role.Admin == newAccRole;
|
||||
|
||||
try (CheckedReservation checkedReservation = new CheckedReservation(account, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
|
||||
futureOwner.setAccountRole(newAccRole);
|
||||
_projectAccountDao.update(futureOwner.getId(), futureOwner);
|
||||
if (newAccRole != null && Role.Admin == newAccRole) {
|
||||
if (shouldIncrementResourceCount) {
|
||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.project);
|
||||
} else {
|
||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -701,7 +722,8 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
" doesn't belong to the project. Add it to the project first and then change the project's ownership");
|
||||
}
|
||||
|
||||
//do resource limit check
|
||||
try (CheckedReservation checkedReservation = new CheckedReservation(futureOwnerAccount, ResourceType.project, null, null, 1L, reservationDao, _resourceLimitMgr)) {
|
||||
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
|
||||
|
||||
//unset the role for the old owner
|
||||
|
|
@ -714,7 +736,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
futureOwner.setAccountRole(Role.Admin);
|
||||
_projectAccountDao.update(futureOwner.getId(), futureOwner);
|
||||
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
|
||||
|
||||
}
|
||||
} else {
|
||||
logger.trace("Future owner {}is already the owner of the project {}", newOwnerName, project);
|
||||
}
|
||||
|
|
@ -857,13 +879,22 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
if (account == null) {
|
||||
throw new InvalidParameterValueException("Account information is required for assigning account to the project");
|
||||
}
|
||||
|
||||
boolean shouldIncrementResourceCount = projectRoleType != null && Role.Admin == projectRoleType;
|
||||
try (CheckedReservation cr = new CheckedReservation(account, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
|
||||
if (assignAccountToProject(project, account.getId(), projectRoleType, null,
|
||||
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
if (shouldIncrementResourceCount) {
|
||||
_resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.project);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
logger.warn("Failed to add account {} to project {}", accountName, project);
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceAllocationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1042,7 +1073,9 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager, C
|
|||
boolean success = true;
|
||||
ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdUserId(projectId, user.getAccountId(), user.getId());
|
||||
success = _projectAccountDao.remove(projectAccount.getId());
|
||||
|
||||
if (projectAccount.getAccountRole() == Role.Admin) {
|
||||
_resourceLimitMgr.decrementResourceCount(user.getAccountId(), ResourceType.project);
|
||||
}
|
||||
if (success) {
|
||||
logger.debug("Removed user {} from project. Removing any invite sent to the user", user);
|
||||
ProjectInvitation invite = _projectInvitationDao.findByUserIdProjectId(user.getId(), user.getAccountId(), projectId);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import com.cloud.utils.db.GlobalLock;
|
|||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
|
||||
public class CheckedReservation implements AutoCloseable {
|
||||
public class CheckedReservation implements Reserver {
|
||||
protected Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
private static final int TRY_TO_GET_LOCK_TIME = 120;
|
||||
|
|
@ -174,7 +174,7 @@ public class CheckedReservation implements AutoCloseable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
public void close() {
|
||||
removeAllReservations();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.resourcelimit;
|
||||
|
||||
public interface Reserver extends AutoCloseable {
|
||||
|
||||
void close();
|
||||
|
||||
}
|
||||
|
|
@ -1199,11 +1199,6 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
long newResourceCount = 0L;
|
||||
ResourceCountVO domainRC = null;
|
||||
|
||||
// calculate project count here
|
||||
if (type == ResourceType.project) {
|
||||
newResourceCount += _projectDao.countProjectsForDomain(domainId);
|
||||
}
|
||||
|
||||
if (type == ResourceType.network) {
|
||||
newResourceCount += networkDomainDao.listDomainNetworkMapByDomain(domainId).size();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue