Skip to content

Commit 1644338

Browse files
committed
prevent domain deletion in case any vm is deletion protected under it
1 parent 4557b07 commit 1644338

4 files changed

Lines changed: 50 additions & 12 deletions

File tree

engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,6 @@ List<VMInstanceVO> searchRemovedByRemoveDate(final Date startDate, final Date en
194194
List<VMInstanceVO> listByIdsIncludingRemoved(List<Long> ids);
195195

196196
List<VMInstanceVO> listDeleteProtectedVmsByAccountId(long accountId);
197+
198+
List<VMInstanceVO> listDeleteProtectedVmsByDomainIds(List<Long> domainIds);
197199
}

engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
107107
protected SearchBuilder<VMInstanceVO> IdsPowerStateSelectSearch;
108108
GenericSearchBuilder<VMInstanceVO, Integer> CountByOfferingId;
109109
GenericSearchBuilder<VMInstanceVO, Integer> CountUserVmNotInDomain;
110-
SearchBuilder<VMInstanceVO> DeleteProtectedVmSearch;
110+
SearchBuilder<VMInstanceVO> DeleteProtectedVmSearchByAccount;
111+
SearchBuilder<VMInstanceVO> DeleteProtectedVmSearchByDomainIds;
111112

112113
@Inject
113114
ResourceTagDao tagsDao;
@@ -370,12 +371,19 @@ protected void init() {
370371
CountUserVmNotInDomain.and("domainIdsNotIn", CountUserVmNotInDomain.entity().getDomainId(), Op.NIN);
371372
CountUserVmNotInDomain.done();
372373

373-
DeleteProtectedVmSearch = createSearchBuilder();
374-
DeleteProtectedVmSearch.selectFields(DeleteProtectedVmSearch.entity().getUuid());
375-
DeleteProtectedVmSearch.and(ApiConstants.ACCOUNT_ID, DeleteProtectedVmSearch.entity().getAccountId(), Op.EQ);
376-
DeleteProtectedVmSearch.and(ApiConstants.DELETE_PROTECTION, DeleteProtectedVmSearch.entity().isDeleteProtection(), Op.EQ);
377-
DeleteProtectedVmSearch.and(ApiConstants.REMOVED, DeleteProtectedVmSearch.entity().getRemoved(), Op.NULL);
378-
DeleteProtectedVmSearch.done();
374+
DeleteProtectedVmSearchByAccount = createSearchBuilder();
375+
DeleteProtectedVmSearchByAccount.selectFields(DeleteProtectedVmSearchByAccount.entity().getUuid());
376+
DeleteProtectedVmSearchByAccount.and(ApiConstants.ACCOUNT_ID, DeleteProtectedVmSearchByAccount.entity().getAccountId(), Op.EQ);
377+
DeleteProtectedVmSearchByAccount.and(ApiConstants.DELETE_PROTECTION, DeleteProtectedVmSearchByAccount.entity().isDeleteProtection(), Op.EQ);
378+
DeleteProtectedVmSearchByAccount.and(ApiConstants.REMOVED, DeleteProtectedVmSearchByAccount.entity().getRemoved(), Op.NULL);
379+
DeleteProtectedVmSearchByAccount.done();
380+
381+
DeleteProtectedVmSearchByDomainIds = createSearchBuilder();
382+
DeleteProtectedVmSearchByDomainIds.selectFields(DeleteProtectedVmSearchByDomainIds.entity().getUuid());
383+
DeleteProtectedVmSearchByDomainIds.and(ApiConstants.DOMAIN_IDS, DeleteProtectedVmSearchByDomainIds.entity().getDomainId(), Op.IN);
384+
DeleteProtectedVmSearchByDomainIds.and(ApiConstants.DELETE_PROTECTION, DeleteProtectedVmSearchByDomainIds.entity().isDeleteProtection(), Op.EQ);
385+
DeleteProtectedVmSearchByDomainIds.and(ApiConstants.REMOVED, DeleteProtectedVmSearchByDomainIds.entity().getRemoved(), Op.NULL);
386+
DeleteProtectedVmSearchByDomainIds.done();
379387
}
380388

381389
@Override
@@ -1307,9 +1315,17 @@ public List<VMInstanceVO> listByIdsIncludingRemoved(List<Long> ids) {
13071315

13081316
@Override
13091317
public List<VMInstanceVO> listDeleteProtectedVmsByAccountId(long accountId) {
1310-
SearchCriteria<VMInstanceVO> sc = DeleteProtectedVmSearch.create();
1318+
SearchCriteria<VMInstanceVO> sc = DeleteProtectedVmSearchByAccount.create();
13111319
sc.setParameters(ApiConstants.ACCOUNT_ID, accountId);
13121320
sc.setParameters(ApiConstants.DELETE_PROTECTION, true);
13131321
return listBy(sc);
13141322
}
1323+
1324+
@Override
1325+
public List<VMInstanceVO> listDeleteProtectedVmsByDomainIds(List<Long> domainIds) {
1326+
SearchCriteria<VMInstanceVO> sc = DeleteProtectedVmSearchByDomainIds.create();
1327+
sc.setParameters(ApiConstants.DOMAIN_IDS, domainIds);
1328+
sc.setParameters(ApiConstants.DELETE_PROTECTION, true);
1329+
return listBy(sc);
1330+
}
13151331
}

server/src/main/java/com/cloud/user/AccountManagerImpl.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,7 +2097,7 @@ public boolean deleteUserAccount(long accountId) {
20972097
return true;
20982098
}
20992099

2100-
validateNoDeleteProtectedVms(account);
2100+
validateNoDeleteProtectedVmsForAccount(account);
21012101
checkIfAccountManagesProjects(accountId);
21022102
verifyCallerPrivilegeForUserOrAccountOperations(account);
21032103

@@ -2139,7 +2139,7 @@ protected boolean isDeleteNeeded(AccountVO account, long accountId, Account call
21392139
return true;
21402140
}
21412141

2142-
private void validateNoDeleteProtectedVms(Account account) {
2142+
private void validateNoDeleteProtectedVmsForAccount(Account account) {
21432143
long accountId = account.getId();
21442144
List<VMInstanceVO> deleteProtectedVms = _vmDao.listDeleteProtectedVmsByAccountId(accountId);
21452145
if (deleteProtectedVms.isEmpty()) {
@@ -2148,8 +2148,7 @@ private void validateNoDeleteProtectedVms(Account account) {
21482148

21492149
if (logger.isDebugEnabled()) {
21502150
List<String> vmUuids = deleteProtectedVms.stream().map(VMInstanceVO::getUuid).collect(Collectors.toList());
2151-
logger.debug("Cannot delete Account {} (id={}), delete protection enabled for Instances: {}",
2152-
account.getAccountName(), accountId, vmUuids);
2151+
logger.debug("Cannot delete Account {}, delete protection enabled for Instances: {}", account, vmUuids);
21532152
}
21542153

21552154
throw new InvalidParameterValueException(

server/src/main/java/com/cloud/user/DomainManagerImpl.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.UUID;
2626
import java.util.regex.Matcher;
2727
import java.util.regex.Pattern;
28+
import java.util.stream.Collectors;
2829

2930
import javax.inject.Inject;
3031

@@ -104,6 +105,7 @@
104105
import com.cloud.utils.net.NetUtils;
105106
import com.cloud.vm.ReservationContext;
106107
import com.cloud.vm.ReservationContextImpl;
108+
import com.cloud.vm.VMInstanceVO;
107109
import com.cloud.vm.dao.VMInstanceDao;
108110

109111
import org.apache.commons.lang3.StringUtils;
@@ -629,6 +631,9 @@ protected boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOp
629631
sc.addAnd("parent", SearchCriteria.Op.EQ, domainId);
630632
List<DomainVO> domains = _domainDao.search(sc, null);
631633

634+
List<Long> domainIds = domains.stream().map(Domain::getId).collect(Collectors.toList());
635+
validateNoDeleteProtectedVmsForDomainIds(domainHandle, domainIds);
636+
632637
SearchCriteria<DomainVO> sc1 = _domainDao.createSearchCriteria();
633638
sc1.addAnd("path", SearchCriteria.Op.LIKE, "%" + "replace(" + domainHandle.getPath() + ", '%', '[%]')" + "%");
634639
List<DomainVO> domainsToBeInactivated = _domainDao.search(sc1, null);
@@ -724,6 +729,22 @@ protected boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOp
724729
return success && deleteDomainSuccess;
725730
}
726731

732+
private void validateNoDeleteProtectedVmsForDomainIds(Domain domainHandle, List<Long> domainIds) {
733+
List<VMInstanceVO> deleteProtectedVms = vmInstanceDao.listDeleteProtectedVmsByDomainIds(domainIds);
734+
if (deleteProtectedVms.isEmpty()) {
735+
return;
736+
}
737+
738+
if (logger.isDebugEnabled()) {
739+
List<String> vmUuids = deleteProtectedVms.stream().map(VMInstanceVO::getUuid).collect(Collectors.toList());
740+
logger.debug("Cannot delete Domain {}, it has delete protection enabled for Instances: {}", domainHandle, vmUuids);
741+
}
742+
743+
throw new InvalidParameterValueException(
744+
String.format("Cannot delete Domain '%s'. One or more Instances have delete protection enabled.",
745+
domainHandle.getName()));
746+
}
747+
727748
@Override
728749
public Pair<List<? extends Domain>, Integer> searchForDomains(ListDomainsCmd cmd) {
729750
Account caller = getCaller();

0 commit comments

Comments
 (0)