diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 41b134fc051..16c68b16324 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -3486,6 +3486,161 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { caller.getAccountId(); + if (vmId != null) { + UserVmVO userVM = _userVmDao.findById(vmId); + if (userVM == null) { + throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance " + + vmId + "; instance not found."); + } + _accountMgr.checkAccess(caller, null, true, userVM); + return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize); + } + + List permittedAccounts = new ArrayList(); + Ternary domainIdRecursiveListProject = new Ternary( + domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, null, permittedAccounts, + domainIdRecursiveListProject, listAll, true); + domainId = domainIdRecursiveListProject.first(); + isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + + Filter searchFilter = new Filter(AffinityGroupJoinVO.class, "id", true, startIndex, pageSize); + SearchCriteria sc = buildAffinityGroupSearchCriteria(domainId, isRecursive, + permittedAccounts, listProjectResourcesCriteria, affinityGroupId, affinityGroupName, affinityGroupType, keyword); + + Pair, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, + searchFilter); + // search group details by ids + List vrs = new ArrayList(); + Integer count = uniqueGroupsPair.second(); + if (count.intValue() != 0) { + List uniqueGroups = uniqueGroupsPair.first(); + Long[] vrIds = new Long[uniqueGroups.size()]; + int i = 0; + for (AffinityGroupJoinVO v : uniqueGroups) { + vrIds[i++] = v.getId(); + } + vrs = _affinityGroupJoinDao.searchByIds(vrIds); + } + + if (!permittedAccounts.isEmpty()) { + // add domain level affinity groups + if (domainId != null) { + SearchCriteria scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, + new ArrayList(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName, + affinityGroupType, keyword); + vrs.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId)); + } else { + + for (Long permAcctId : permittedAccounts) { + Account permittedAcct = _accountDao.findById(permAcctId); + SearchCriteria scDomain = buildAffinityGroupSearchCriteria( + null, isRecursive, new ArrayList(), + listProjectResourcesCriteria, affinityGroupId, affinityGroupName, affinityGroupType, keyword); + + vrs.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, permittedAcct.getDomainId())); + } + } + } else if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) { + // list all domain level affinity groups for the domain admin case + SearchCriteria scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, + new ArrayList(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName, + affinityGroupType, keyword); + vrs.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId)); + } + + return new Pair, Integer>(vrs, vrs.size()); + + } + + private void buildAffinityGroupViewSearchBuilder(SearchBuilder sb, Long domainId, + boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + + sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN); + sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); + + if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) { + // if accountId isn't specified, we can do a domain match for the + // admin case if isRecursive is true + sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE); + } + + if (listProjectResourcesCriteria != null) { + if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) { + sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ); + } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) { + sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ); + } + } + + } + + private void buildAffinityGroupViewSearchCriteria(SearchCriteria sc, + Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { + + if (listProjectResourcesCriteria != null) { + sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT); + } + + if (!permittedAccounts.isEmpty()) { + sc.setParameters("accountIdIN", permittedAccounts.toArray()); + } else if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + if (isRecursive) { + sc.setParameters("domainPath", domain.getPath() + "%"); + } else { + sc.setParameters("domainId", domainId); + } + } + } + + private SearchCriteria buildAffinityGroupSearchCriteria(Long domainId, boolean isRecursive, + List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria, + Long affinityGroupId, String affinityGroupName, String affinityGroupType, String keyword) { + + SearchBuilder groupSearch = _affinityGroupJoinDao.createSearchBuilder(); + buildAffinityGroupViewSearchBuilder(groupSearch, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); + + groupSearch.select(null, Func.DISTINCT, groupSearch.entity().getId()); // select + // distinct + + SearchCriteria sc = groupSearch.create(); + buildAffinityGroupViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, + listProjectResourcesCriteria); + + if (affinityGroupId != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId); + } + + if (affinityGroupName != null) { + sc.addAnd("name", SearchCriteria.Op.EQ, affinityGroupName); + } + + if (affinityGroupType != null) { + sc.addAnd("type", SearchCriteria.Op.EQ, affinityGroupType); + } + + if (keyword != null) { + SearchCriteria ssc = _affinityGroupJoinDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + return sc; + } + + public Pair, Integer> listAffinityGroupsInternalIAM(Long affinityGroupId, + String affinityGroupName, String affinityGroupType, Long vmId, String accountName, Long domainId, + boolean isRecursive, boolean listAll, Long startIndex, Long pageSize, String keyword) { + + Account caller = CallContext.current().getCallingAccount(); + + caller.getAccountId(); + if (vmId != null) { UserVmVO userVM = _userVmDao.findById(vmId); if (userVM == null) { @@ -3507,7 +3662,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); Filter searchFilter = new Filter(AffinityGroupJoinVO.class, "id", true, startIndex, pageSize); - SearchCriteria sc = buildAffinityGroupSearchCriteria(isRecursive, + SearchCriteria sc = buildAffinityGroupSearchCriteriaIAM(isRecursive, permittedDomains, permittedAccounts, permittedResources, listProjectResourcesCriteria, affinityGroupId, affinityGroupName, affinityGroupType, keyword); Pair, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter); @@ -3556,7 +3711,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } - private SearchCriteria buildAffinityGroupSearchCriteria(boolean isRecursive, + private SearchCriteria buildAffinityGroupSearchCriteriaIAM(boolean isRecursive, List permittedDomains, List permittedAccounts, List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria, Long affinityGroupId, String affinityGroupName, String affinityGroupType, String keyword) {