mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
bug 12983: resource limits for projects
This commit is contained in:
parent
5d266b3b4b
commit
ad1076f21d
@ -30,6 +30,7 @@ import com.cloud.api.ServerApiException;
|
|||||||
import com.cloud.api.response.ProjectResponse;
|
import com.cloud.api.response.ProjectResponse;
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.projects.Project;
|
import com.cloud.projects.Project;
|
||||||
import com.cloud.user.UserContext;
|
import com.cloud.user.UserContext;
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
|
|||||||
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of the project to be modified")
|
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of the project to be modified")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="new Admin account for the project, should be specified with domainId")
|
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="new Admin account for the project")
|
||||||
private String accountName;
|
private String accountName;
|
||||||
|
|
||||||
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="display text of the project")
|
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="display text of the project")
|
||||||
@ -91,7 +92,7 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
|
|||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(){
|
public void execute() throws ResourceAllocationException{
|
||||||
UserContext.current().setEventDetails("Project id: "+ getId());
|
UserContext.current().setEventDetails("Project id: "+ getId());
|
||||||
Project project = _projectService.updateProject(getId(), getDisplayText(), getAccountName());
|
Project project = _projectService.updateProject(getId(), getDisplayText(), getAccountName());
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public interface Resource {
|
|||||||
volume ("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
volume ("volume", 2, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||||
snapshot ("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
snapshot ("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||||
template ("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
template ("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||||
project ("project", 5, ResourceOwnerType.Domain);
|
project ("project", 5, ResourceOwnerType.Account, ResourceOwnerType.Domain);
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private ResourceOwnerType[] supportedOwners;
|
private ResourceOwnerType[] supportedOwners;
|
||||||
|
|||||||
@ -50,7 +50,7 @@ public interface ProjectService {
|
|||||||
|
|
||||||
Project findByNameAndDomainId(String name, long domainId);
|
Project findByNameAndDomainId(String name, long domainId);
|
||||||
|
|
||||||
Project updateProject(long id, String displayText, String newOwnerName);
|
Project updateProject(long id, String displayText, String newOwnerName) throws ResourceAllocationException;
|
||||||
|
|
||||||
boolean addAccountToProject(long projectId, String accountName, String email);
|
boolean addAccountToProject(long projectId, String accountName, String email);
|
||||||
|
|
||||||
|
|||||||
@ -214,8 +214,8 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||||||
UserContext.current().setEventDetails("Project id=" + project.getId());
|
UserContext.current().setEventDetails("Project id=" + project.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Increment resource count for the Owner's domain
|
//Increment resource count
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.project);
|
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project);
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||||||
s_logger.debug("Marking project id=" + projectId + " with state " + State.Disabled + " as a part of project delete...");
|
s_logger.debug("Marking project id=" + projectId + " with state " + State.Disabled + " as a part of project delete...");
|
||||||
project.setState(State.Disabled);
|
project.setState(State.Disabled);
|
||||||
boolean updateResult = _projectDao.update(projectId, project);
|
boolean updateResult = _projectDao.update(projectId, project);
|
||||||
_resourceLimitMgr.decrementResourceCount(project.getProjectAccountId(), ResourceType.project);
|
_resourceLimitMgr.decrementResourceCount(getProjectOwner(projectId).getId(), ResourceType.project);
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
if (updateResult) {
|
if (updateResult) {
|
||||||
@ -494,7 +494,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||||||
|
|
||||||
@Override @DB
|
@Override @DB
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true)
|
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true)
|
||||||
public Project updateProject(long projectId, String displayText, String newOwnerName) {
|
public Project updateProject(long projectId, String displayText, String newOwnerName) throws ResourceAllocationException{
|
||||||
Account caller = UserContext.current().getCaller();
|
Account caller = UserContext.current().getCaller();
|
||||||
|
|
||||||
//check that the project exists
|
//check that the project exists
|
||||||
@ -527,14 +527,20 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||||||
throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
|
throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//do resource limit check
|
||||||
|
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
|
||||||
|
|
||||||
//unset the role for the old owner
|
//unset the role for the old owner
|
||||||
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
|
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
|
||||||
currentOwner.setAccountRole(Role.Regular);
|
currentOwner.setAccountRole(Role.Regular);
|
||||||
_projectAccountDao.update(currentOwner.getId(), currentOwner);
|
_projectAccountDao.update(currentOwner.getId(), currentOwner);
|
||||||
|
_resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
|
||||||
|
|
||||||
//set new owner
|
//set new owner
|
||||||
futureOwner.setAccountRole(Role.Admin);
|
futureOwner.setAccountRole(Role.Admin);
|
||||||
_projectAccountDao.update(futureOwner.getId(), futureOwner);
|
_projectAccountDao.update(futureOwner.getId(), futureOwner);
|
||||||
|
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
|
s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package com.cloud.projects.dao;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.cloud.projects.ProjectAccount;
|
||||||
import com.cloud.projects.ProjectAccountVO;
|
import com.cloud.projects.ProjectAccountVO;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
@ -34,4 +35,6 @@ public interface ProjectAccountDao extends GenericDao<ProjectAccountVO, Long>{
|
|||||||
List<Long> listPermittedAccountIds(long accountId);
|
List<Long> listPermittedAccountIds(long accountId);
|
||||||
|
|
||||||
List<Long> listAdministratedProjects(long adminAccountId);
|
List<Long> listAdministratedProjects(long adminAccountId);
|
||||||
|
|
||||||
|
Long countByAccountIdAndRole(long accountId, ProjectAccount.Role role);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import com.cloud.utils.db.GenericDaoBase;
|
|||||||
import com.cloud.utils.db.GenericSearchBuilder;
|
import com.cloud.utils.db.GenericSearchBuilder;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import com.cloud.utils.db.SearchCriteria.Func;
|
||||||
import com.cloud.utils.db.SearchCriteria.Op;
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
|
|
||||||
@Local(value={ProjectAccountDao.class})
|
@Local(value={ProjectAccountDao.class})
|
||||||
@ -34,6 +35,7 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
|||||||
protected final SearchBuilder<ProjectAccountVO> AllFieldsSearch;
|
protected final SearchBuilder<ProjectAccountVO> AllFieldsSearch;
|
||||||
final GenericSearchBuilder<ProjectAccountVO, Long> AdminSearch;
|
final GenericSearchBuilder<ProjectAccountVO, Long> AdminSearch;
|
||||||
final GenericSearchBuilder<ProjectAccountVO, Long> ProjectAccountSearch;
|
final GenericSearchBuilder<ProjectAccountVO, Long> ProjectAccountSearch;
|
||||||
|
final GenericSearchBuilder<ProjectAccountVO, Long> CountByRoleSearch;
|
||||||
|
|
||||||
protected ProjectAccountDaoImpl() {
|
protected ProjectAccountDaoImpl() {
|
||||||
AllFieldsSearch = createSearchBuilder();
|
AllFieldsSearch = createSearchBuilder();
|
||||||
@ -53,6 +55,12 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
|||||||
ProjectAccountSearch.selectField(ProjectAccountSearch.entity().getProjectAccountId());
|
ProjectAccountSearch.selectField(ProjectAccountSearch.entity().getProjectAccountId());
|
||||||
ProjectAccountSearch.and("accountId", ProjectAccountSearch.entity().getAccountId(), Op.EQ);
|
ProjectAccountSearch.and("accountId", ProjectAccountSearch.entity().getAccountId(), Op.EQ);
|
||||||
ProjectAccountSearch.done();
|
ProjectAccountSearch.done();
|
||||||
|
|
||||||
|
CountByRoleSearch = createSearchBuilder(Long.class);
|
||||||
|
CountByRoleSearch.select(null, Func.COUNT, CountByRoleSearch.entity().getId());
|
||||||
|
CountByRoleSearch.and("accountId", CountByRoleSearch.entity().getAccountId(), Op.EQ);
|
||||||
|
CountByRoleSearch.and("role", CountByRoleSearch.entity().getAccountRole(), Op.EQ);
|
||||||
|
CountByRoleSearch.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -122,4 +130,12 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
|||||||
sc.setParameters("accountId", adminAccountId);
|
sc.setParameters("accountId", adminAccountId);
|
||||||
return customSearch(sc, null);
|
return customSearch(sc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long countByAccountIdAndRole(long accountId, ProjectAccount.Role role) {
|
||||||
|
SearchCriteria<Long> sc = CountByRoleSearch.create();
|
||||||
|
sc.setParameters("accountId", accountId);
|
||||||
|
sc.setParameters("role", role);
|
||||||
|
return customSearch(sc, null).get(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,8 @@ import com.cloud.exception.PermissionDeniedException;
|
|||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.network.dao.IPAddressDao;
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
import com.cloud.projects.Project;
|
import com.cloud.projects.Project;
|
||||||
|
import com.cloud.projects.ProjectAccount.Role;
|
||||||
|
import com.cloud.projects.dao.ProjectAccountDao;
|
||||||
import com.cloud.projects.dao.ProjectDao;
|
import com.cloud.projects.dao.ProjectDao;
|
||||||
import com.cloud.storage.dao.SnapshotDao;
|
import com.cloud.storage.dao.SnapshotDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
@ -112,6 +114,9 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager{
|
|||||||
private EntityManager _entityMgr;
|
private EntityManager _entityMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectDao _projectDao;
|
private ProjectDao _projectDao;
|
||||||
|
@Inject
|
||||||
|
private ProjectAccountDao _projectAccountDao;
|
||||||
|
|
||||||
|
|
||||||
protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
|
protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
|
||||||
ScheduledExecutorService _rcExecutor;
|
ScheduledExecutorService _rcExecutor;
|
||||||
@ -690,6 +695,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager{
|
|||||||
newCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
|
newCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
|
||||||
} else if (type == Resource.ResourceType.template) {
|
} else if (type == Resource.ResourceType.template) {
|
||||||
newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
|
newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
|
||||||
|
} else if (type == Resource.ResourceType.project) {
|
||||||
|
newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidParameterValueException("Unsupported resource type " + type);
|
throw new InvalidParameterValueException("Unsupported resource type " + type);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user