diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index e9bbc8edbd6..cad5a503d9f 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -382,4 +382,11 @@ public class MockAccountManager extends ManagerBase implements AccountManager { } + @Override + public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedAccounts, + Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) { + // TODO Auto-generated method stub + + } + } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index dcb32a940fc..41b134fc051 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2806,7 +2806,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { return response; } - private Pair, Integer> searchForTemplatesInternal(ListTemplatesCmd cmd) { + // Temporarily disable this method which used IAM model to do template list + private Pair, Integer> searchForTemplatesInternalIAM(ListTemplatesCmd cmd) { TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter()); Long id = cmd.getId(); Map tags = cmd.getTags(); @@ -2838,12 +2839,13 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured)); HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); - return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, + return searchForTemplatesInternalIAM(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedDomains, permittedAccounts, permittedResources, isRecursive, caller, listProjectResourcesCriteria, tags, showRemovedTmpl); } - private Pair, Integer> searchForTemplatesInternal(Long templateId, String name, + // Temporarily disable this method which used IAM model to do template list + private Pair, Integer> searchForTemplatesInternalIAM(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List permittedDomains, List permittedAccounts, List permittedResources, boolean isRecursive, Account caller, @@ -3079,6 +3081,302 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } + private Pair, Integer> searchForTemplatesInternal(ListTemplatesCmd cmd) { + TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter()); + Long id = cmd.getId(); + Map tags = cmd.getTags(); + boolean showRemovedTmpl = cmd.getShowRemoved(); + Account caller = CallContext.current().getCallingAccount(); + + boolean listAll = false; + if (templateFilter != null && templateFilter == TemplateFilter.all) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + throw new InvalidParameterValueException("Filter " + TemplateFilter.all + + " can be specified by admin only"); + } + listAll = true; + } + + List permittedAccountIds = new ArrayList(); + Ternary domainIdRecursiveListProject = new Ternary( + cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, + domainIdRecursiveListProject, listAll, false); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + List permittedAccounts = new ArrayList(); + for (Long accountId : permittedAccountIds) { + permittedAccounts.add(_accountMgr.getAccount(accountId)); + } + + boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured)); + HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); + + return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, + cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, showDomr, + cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl); + } + + private Pair, Integer> searchForTemplatesInternal(Long templateId, String name, + String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize, + Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, + List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, + Map tags, boolean showRemovedTmpl) { + + // check if zone is configured, if not, just return empty list + List hypers = null; + if (!isIso) { + hypers = _resourceMgr.listAvailHypervisorInZone(null, null); + if (hypers == null || hypers.isEmpty()) { + return new Pair, Integer>(new ArrayList(), 0); + } + } + + VMTemplateVO template = null; + + Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); + isAscending = (isAscending == null ? true : isAscending); + Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, startIndex, pageSize); + + SearchBuilder sb = _templateJoinDao.createSearchBuilder(); + sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair + SearchCriteria sc = sb.create(); + + // verify templateId parameter and specially handle it + if (templateId != null) { + template = _templateDao.findByIdIncludingRemoved(templateId); // Done for backward compatibility - Bug-5221 + if (template == null) { + throw new InvalidParameterValueException("Please specify a valid template ID."); + }// If ISO requested then it should be ISO. + if (isIso && template.getFormat() != ImageFormat.ISO) { + s_logger.error("Template Id " + templateId + " is not an ISO"); + InvalidParameterValueException ex = new InvalidParameterValueException( + "Specified Template Id is not an ISO"); + ex.addProxyObject(template.getUuid(), "templateId"); + throw ex; + }// If ISO not requested then it shouldn't be an ISO. + if (!isIso && template.getFormat() == ImageFormat.ISO) { + s_logger.error("Incorrect format of the template id " + templateId); + InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + + template.getFormat() + " of the specified template id"); + ex.addProxyObject(template.getUuid(), "templateId"); + throw ex; + } + + // if template is not public, perform permission check here + if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + Account owner = _accountMgr.getAccount(template.getAccountId()); + _accountMgr.checkAccess(caller, null, true, owner); + } + + // if templateId is specified, then we will just use the id to + // search and ignore other query parameters + sc.addAnd("id", SearchCriteria.Op.EQ, templateId); + } else { + + DomainVO domain = null; + if (!permittedAccounts.isEmpty()) { + domain = _domainDao.findById(permittedAccounts.get(0).getDomainId()); + } else { + domain = _domainDao.findById(DomainVO.ROOT_DOMAIN); + } + + // List hypers = null; + // if (!isIso) { + // hypers = _resourceMgr.listAvailHypervisorInZone(null, null); + // } + + // add criteria for project or not + if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { + sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) { + sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); + } + + // add criteria for domain path in case of domain admin + if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) + && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); + } + + List relatedDomainIds = new ArrayList(); + List permittedAccountIds = new ArrayList(); + if (!permittedAccounts.isEmpty()) { + for (Account account : permittedAccounts) { + permittedAccountIds.add(account.getId()); + boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community); + + // get all parent domain ID's all the way till root domain + DomainVO domainTreeNode = null; + //if template filter is featured, or community, all child domains should be included in search + if (publicTemplates) { + domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN); + + } else { + domainTreeNode = _domainDao.findById(account.getDomainId()); + } + relatedDomainIds.add(domainTreeNode.getId()); + while (domainTreeNode.getParent() != null) { + domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); + relatedDomainIds.add(domainTreeNode.getId()); + } + + // get all child domain ID's + if (_accountMgr.isAdmin(account.getId()) || publicTemplates) { + List allChildDomains = _domainDao.findAllChildren(domainTreeNode.getPath(), domainTreeNode.getId()); + for (DomainVO childDomain : allChildDomains) { + relatedDomainIds.add(childDomain.getId()); + } + } + } + } + + if (!isIso) { + // add hypervisor criteria for template case + if (hypers != null && !hypers.isEmpty()) { + String[] relatedHypers = new String[hypers.size()]; + for (int i = 0; i < hypers.size(); i++) { + relatedHypers[i] = hypers.get(i).toString(); + } + sc.addAnd("hypervisorType", SearchCriteria.Op.IN, relatedHypers); + } + } + + // control different template filters + if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) { + sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true); + if (templateFilter == TemplateFilter.featured) { + sc.addAnd("featured", SearchCriteria.Op.EQ, true); + } else { + sc.addAnd("featured", SearchCriteria.Op.EQ, false); + } + if (!permittedAccounts.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray()); + scc.addOr("domainId", SearchCriteria.Op.NULL); + sc.addAnd("domainId", SearchCriteria.Op.SC, scc); + } + } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { + if (!permittedAccounts.isEmpty()) { + sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + } + } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + sc.addAnd("accountId", SearchCriteria.Op.SC, scc); + } else if (templateFilter == TemplateFilter.executable) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true); + if (!permittedAccounts.isEmpty()) { + scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + } + sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc); + } + + // add tags criteria + if (tags != null && !tags.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + for (String key : tags.keySet()) { + SearchCriteria scTag = _templateJoinDao.createSearchCriteria(); + scTag.addAnd("tagKey", SearchCriteria.Op.EQ, key); + scTag.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key)); + if (isIso) { + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.ISO); + } else { + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.Template); + } + scc.addOr("tagKey", SearchCriteria.Op.SC, scTag); + } + sc.addAnd("tagKey", SearchCriteria.Op.SC, scc); + } + + // other criteria + + if (keyword != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + } else if (name != null) { + sc.addAnd("name", SearchCriteria.Op.EQ, name); + } + + if (isIso) { + sc.addAnd("format", SearchCriteria.Op.EQ, "ISO"); + + } else { + sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO"); + } + + if (!hyperType.equals(HypervisorType.None)) { + sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType); + } + + if (bootable != null) { + sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable); + } + + if (onlyReady) { + SearchCriteria readySc = _templateJoinDao.createSearchCriteria(); + readySc.addOr("state", SearchCriteria.Op.EQ, TemplateState.Ready); + readySc.addOr("format", SearchCriteria.Op.EQ, ImageFormat.BAREMETAL); + SearchCriteria isoPerhostSc = _templateJoinDao.createSearchCriteria(); + isoPerhostSc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO); + isoPerhostSc.addAnd("templateType", SearchCriteria.Op.EQ, TemplateType.PERHOST); + readySc.addOr("templateType", SearchCriteria.Op.SC, isoPerhostSc); + sc.addAnd("state", SearchCriteria.Op.SC, readySc); + } + + if (!showDomr) { + // excluding system template + sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); + } + } + + if (zoneId != null) { + SearchCriteria zoneSc = _templateJoinDao.createSearchCriteria(); + zoneSc.addOr("dataCenterId", SearchCriteria.Op.EQ, zoneId); + zoneSc.addOr("dataStoreScope", SearchCriteria.Op.EQ, ScopeType.REGION); + // handle the case where xs-tools.iso and vmware-tools.iso do not + // have data_center information in template_view + SearchCriteria isoPerhostSc = _templateJoinDao.createSearchCriteria(); + isoPerhostSc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO); + isoPerhostSc.addAnd("templateType", SearchCriteria.Op.EQ, TemplateType.PERHOST); + zoneSc.addOr("templateType", SearchCriteria.Op.SC, isoPerhostSc); + sc.addAnd("dataCenterId", SearchCriteria.Op.SC, zoneSc); + } + + // don't return removed template, this should not be needed since we + // changed annotation for removed field in TemplateJoinVO. + // sc.addAnd("removed", SearchCriteria.Op.NULL); + + // search unique templates and find details by Ids + Pair, Integer> uniqueTmplPair = null; + if (showRemovedTmpl) { + uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter); + } else { + sc.addAnd("templateState", SearchCriteria.Op.EQ, State.Active); + uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); + } + + Integer count = uniqueTmplPair.second(); + if (count.intValue() == 0) { + // empty result + return uniqueTmplPair; + } + List uniqueTmpls = uniqueTmplPair.first(); + String[] tzIds = new String[uniqueTmpls.size()]; + int i = 0; + for (TemplateJoinVO v : uniqueTmpls) { + tzIds[i++] = v.getTempZonePair(); + } + List vrs = _templateJoinDao.searchByTemplateZonePair(showRemovedTmpl, tzIds); + return new Pair, Integer>(vrs, count); + + // TODO: revisit the special logic for iso search in + // VMTemplateDaoImpl.searchForTemplates and understand why we need to + // specially handle ISO. The original logic is very twisted and no idea + // about what the code was doing. + + } + @Override public ListResponse listIsos(ListIsosCmd cmd) { Pair, Integer> result = searchForIsosInternal(cmd); @@ -3102,6 +3400,40 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { boolean showRemovedISO = cmd.getShowRemoved(); Account caller = CallContext.current().getCallingAccount(); + boolean listAll = false; + if (isoFilter != null && isoFilter == TemplateFilter.all) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + throw new InvalidParameterValueException("Filter " + TemplateFilter.all + + " can be specified by admin only"); + } + listAll = true; + } + + List permittedAccountIds = new ArrayList(); + Ternary domainIdRecursiveListProject = new Ternary( + cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, + domainIdRecursiveListProject, listAll, false); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + List permittedAccounts = new ArrayList(); + for (Long accountId : permittedAccountIds) { + permittedAccounts.add(_accountMgr.getAccount(accountId)); + } + + HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); + + return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, + cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, + cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO); + } + + private Pair, Integer> searchForIsosInternalIAM(ListIsosCmd cmd) { + TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter()); + Long id = cmd.getId(); + Map tags = cmd.getTags(); + boolean showRemovedISO = cmd.getShowRemoved(); + Account caller = CallContext.current().getCallingAccount(); + boolean listAll = false; if (isoFilter != null && isoFilter == TemplateFilter.all) { if (_accountMgr.isNormalUser(caller.getId())) { @@ -3128,7 +3460,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); - return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, + return searchForTemplatesInternalIAM(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedDomains, permittedAccounts, permittedResources, isRecursive, caller, listProjectResourcesCriteria, tags, showRemovedISO); } diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index 03bf8421a30..748be2b2c70 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -102,6 +102,11 @@ public interface AccountManager extends AccountService { List permittedResources, ListProjectResourcesCriteria listProjectResourcesCriteria); + // deprecated methods that should only be used in listTemplates due to backwards compatibility of templateFilter. + void buildACLSearchParameters(Account caller, Long id, + String accountName, Long projectId, List permittedAccounts, Ternary domainIdRecursiveListProject, boolean listAll, + boolean forProjectInvitation); + /** * Deletes a user by userId * diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index d7db6c2e9e7..06c55aa1533 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -2176,6 +2176,94 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M return _userAccountDao.getUserByApiKey(apiKey); } + // NOTE: This method should only be used in listTemplates call, all other list calls should use the new buildACLSearchParameters which takes + // "action" as extra parameter and uses new IAM model. + @Override + public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List + permittedAccounts, Ternary domainIdRecursiveListProject, + boolean listAll, boolean forProjectInvitation) { + Long domainId = domainIdRecursiveListProject.first(); + if (domainId != null) { + Domain domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Unable to find domain by id " + domainId); + } + // check permissions + checkAccess(caller, domain); + } + + if (accountName != null) { + if (projectId != null) { + throw new InvalidParameterValueException("Account and projectId can't be specified together"); + } + + Account userAccount = null; + Domain domain = null; + if (domainId != null) { + userAccount = _accountDao.findActiveAccount(accountName, domainId); + domain = _domainDao.findById(domainId); + } else { + userAccount = _accountDao.findActiveAccount(accountName, caller.getDomainId()); + domain = _domainDao.findById(caller.getDomainId()); + } + + if (userAccount != null) { + checkAccess(caller, null, false, userAccount); + // check permissions + permittedAccounts.add(userAccount.getId()); + } else { + throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid()); + } + } + + // set project information + if (projectId != null) { + if (!forProjectInvitation) { + if (projectId.longValue() == -1) { + if (isNormalUser(caller.getId())) { + permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId())); + } else { + domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly); + } + } else { + Project project = _projectMgr.getProject(projectId); + if (project == null) { + throw new InvalidParameterValueException("Unable to find project by id " + projectId); + } + if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) { + throw new PermissionDeniedException("Account " + caller + " can't access project id=" + projectId); + } + permittedAccounts.add(project.getProjectAccountId()); + } + } + } else { + if (id == null) { + domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources); + } + if (permittedAccounts.isEmpty() && domainId == null) { + if (isNormalUser(caller.getId())) { + permittedAccounts.add(caller.getId()); + } else if (!listAll) { + if (id == null) { + permittedAccounts.add(caller.getId()); + } else if (!isRootAdmin(caller.getId())) { + domainIdRecursiveListProject.first(caller.getDomainId()); + domainIdRecursiveListProject.second(true); + } + } else if (domainId == null) { + if (isDomainAdmin(caller.getId())) { + domainIdRecursiveListProject.first(caller.getDomainId()); + domainIdRecursiveListProject.second(true); + } + } + } else if (domainId != null) { + if (isNormalUser(caller.getId())) { + permittedAccounts.add(caller.getId()); + } + } + } + } + @Override public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedDomains, List permittedAccounts, List permittedResources, Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation, diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index e53974a664d..2f57abcefe4 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -358,5 +358,11 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco } + @Override + public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedAccounts, + Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) { + // TODO Auto-generated method stub + + } }