mirror of https://github.com/apache/cloudstack.git
bug 13700: delete projects as a part of domain cleanup
status 13700: resolved fixed Reviewed-by: Frank
This commit is contained in:
parent
e34cd2ca4e
commit
5aaf15f0a7
|
|
@ -32,6 +32,7 @@ import com.cloud.utils.db.GenericDao;
|
|||
|
||||
@Entity
|
||||
@Table(name="project_account")
|
||||
@SuppressWarnings("unused")
|
||||
public class ProjectAccountVO implements ProjectAccount{
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
|
|
|
|||
|
|
@ -17,4 +17,6 @@ public interface ProjectManager extends ProjectService {
|
|||
|
||||
boolean allowUserToCreateProject();
|
||||
|
||||
boolean deleteProject(Account caller, long callerUserId, ProjectVO project);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,11 +246,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
|
||||
@DB
|
||||
public boolean deleteProject (long projectId) {
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
|
||||
public boolean deleteProject(long projectId) {
|
||||
UserContext ctx = UserContext.current();
|
||||
Account caller = ctx.getCaller();
|
||||
|
||||
ProjectVO project= getProject(projectId);
|
||||
//verify input parameters
|
||||
|
|
@ -258,28 +256,39 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
_accountMgr.checkAccess(ctx.getCaller(),AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
return deleteProject(ctx.getCaller(), ctx.getCallerUserId(), project);
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public boolean deleteProject(Account caller, long callerUserId, ProjectVO project) {
|
||||
//mark project as inactive first, so you can't add resources to it
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
s_logger.debug("Marking project id=" + projectId + " with state " + State.Disabled + " as a part of project delete...");
|
||||
s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
|
||||
project.setState(State.Disabled);
|
||||
boolean updateResult = _projectDao.update(projectId, project);
|
||||
_resourceLimitMgr.decrementResourceCount(getProjectOwner(projectId).getId(), ResourceType.project);
|
||||
boolean updateResult = _projectDao.update(project.getId(), project);
|
||||
//owner can be already removed at this point, so adding the conditional check
|
||||
Account projectOwner = getProjectOwner(project.getId());
|
||||
if (projectOwner != null) {
|
||||
_resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
|
||||
if (updateResult) {
|
||||
if (!cleanupProject(project, _accountDao.findById(caller.getId()), ctx.getCallerUserId())) {
|
||||
s_logger.warn("Failed to cleanup project's id=" + projectId + " resources, not removing the project yet");
|
||||
if (!cleanupProject(project, _accountDao.findById(caller.getId()), callerUserId)) {
|
||||
s_logger.warn("Failed to cleanup project's id=" + project.getId() + " resources, not removing the project yet");
|
||||
return false;
|
||||
} else {
|
||||
return _projectDao.remove(projectId);
|
||||
return _projectDao.remove(project.getId());
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Failed to mark the project id=" + projectId + " with state " + State.Disabled);
|
||||
s_logger.warn("Failed to mark the project id=" + project.getId() + " with state " + State.Disabled);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
|
|
@ -376,16 +385,14 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||
accountId = caller.getId();
|
||||
}
|
||||
|
||||
if (!listAll) {
|
||||
if (domainId == null && accountId == null) {
|
||||
accountId = caller.getId();
|
||||
} else {
|
||||
if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || !isRecursive) {
|
||||
DomainVO domain = _domainDao.findById(caller.getDomainId());
|
||||
path = domain.getPath();
|
||||
}
|
||||
}
|
||||
|
||||
if (domainId == null && accountId == null) {
|
||||
accountId = caller.getId();
|
||||
} else if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || (!isRecursive && !listAll)) {
|
||||
DomainVO domain = _domainDao.findById(caller.getDomainId());
|
||||
path = domain.getPath();
|
||||
}
|
||||
|
||||
|
||||
if (path != null) {
|
||||
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
|
||||
|
|
@ -469,8 +476,12 @@ public class ProjectManagerImpl implements ProjectManager, Manager{
|
|||
|
||||
@Override
|
||||
public Account getProjectOwner(long projectId) {
|
||||
long accountId = _projectAccountDao.getProjectOwner(projectId).getAccountId();
|
||||
return _accountMgr.getAccount(accountId);
|
||||
ProjectAccount prAcct = _projectAccountDao.getProjectOwner(projectId);
|
||||
if (prAcct != null) {
|
||||
return _accountMgr.getAccount(prAcct.getAccountId());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ import com.cloud.projects.Project;
|
|||
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||
import com.cloud.projects.ProjectInvitationVO;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.server.auth.UserAuthenticator;
|
||||
|
|
@ -1299,14 +1300,14 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
|
|||
}
|
||||
|
||||
// cleanup inactive projects
|
||||
List<? extends Project> inactiveProjects = _projectDao.listByState(Project.State.Disabled);
|
||||
List<ProjectVO> inactiveProjects = _projectDao.listByState(Project.State.Disabled);
|
||||
s_logger.info("Found " + inactiveProjects.size() + " disabled projects to cleanup");
|
||||
for (Project project : inactiveProjects) {
|
||||
for (ProjectVO project : inactiveProjects) {
|
||||
try {
|
||||
Account projectAccount = getAccount(project.getProjectAccountId());
|
||||
if (projectAccount == null) {
|
||||
s_logger.debug("Removing inactive project id=" + project.getId());
|
||||
_projectMgr.deleteProject(project.getId());
|
||||
_projectMgr.deleteProject(UserContext.current().getCaller(), UserContext.current().getCallerUserId(), project);
|
||||
} else {
|
||||
s_logger.debug("Can't remove disabled project " + project + " as it has non removed account id=" + project.getId());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ import com.cloud.exception.ConcurrentOperationException;
|
|||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
|
|
@ -73,6 +76,10 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
|
|||
private DiskOfferingDao _diskOfferingDao;
|
||||
@Inject
|
||||
private ServiceOfferingDao _offeringsDao;
|
||||
@Inject
|
||||
private ProjectDao _projectDao;
|
||||
@Inject
|
||||
private ProjectManager _projectMgr;
|
||||
|
||||
@Override
|
||||
public Domain getDomain(long domainId) {
|
||||
|
|
@ -275,6 +282,7 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
|
|||
}
|
||||
|
||||
private boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
s_logger.debug("Cleaning up domain id=" + domainId);
|
||||
boolean success = true;
|
||||
{
|
||||
DomainVO domainHandle = _domainDao.findById(domainId);
|
||||
|
|
@ -309,9 +317,19 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
|
|||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
List<AccountVO> accounts = _accountDao.search(sc, null);
|
||||
for (AccountVO account : accounts) {
|
||||
success = (success && _accountMgr.deleteAccount(account, UserContext.current().getCallerUserId(), UserContext.current().getCaller()));
|
||||
if (!success) {
|
||||
s_logger.warn("Failed to cleanup account id=" + account.getId() + " as a part of domain cleanup");
|
||||
if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
|
||||
s_logger.debug("Deleting account " + account + " as a part of domain id=" + domainId + " cleanup");
|
||||
success = (success && _accountMgr.deleteAccount(account, UserContext.current().getCallerUserId(), UserContext.current().getCaller()));
|
||||
if (!success) {
|
||||
s_logger.warn("Failed to cleanup account id=" + account.getId() + " as a part of domain cleanup");
|
||||
}
|
||||
} else {
|
||||
ProjectVO project = _projectDao.findByProjectAccountId(account.getId());
|
||||
s_logger.debug("Deleting project " + project + " as a part of domain id=" + domainId + " cleanup");
|
||||
success = (success && _projectMgr.deleteProject(UserContext.current().getCaller(), UserContext.current().getCallerUserId(), project));
|
||||
if (!success) {
|
||||
s_logger.warn("Failed to cleanup project " + project + " as a part of domain cleanup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue