Skip to content

Commit 061ce9b

Browse files
authored
Fix VM and volume metrics listing regressions (#12284)
1 parent 79ab156 commit 061ce9b

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVolumesUsageHistoryCmd.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
import org.apache.cloudstack.acl.RoleType;
2323
import org.apache.cloudstack.api.response.ListResponse;
24-
import org.apache.cloudstack.api.response.SystemVmResponse;
2524
import org.apache.cloudstack.api.response.VolumeResponse;
2625
import org.apache.cloudstack.response.VolumeMetricsStatsResponse;
2726

@@ -37,7 +36,7 @@ public class ListVolumesUsageHistoryCmd extends BaseResourceUsageHistoryCmd {
3736
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VolumeResponse.class, description = "the ID of the volume.")
3837
private Long id;
3938

40-
@Parameter(name=ApiConstants.IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType= SystemVmResponse.class, description="the IDs of the volumes, mutually exclusive with id.")
39+
@Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = VolumeResponse.class, description = "the IDs of the volumes, mutually exclusive with id.")
4140
private List<Long> ids;
4241

4342
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "name of the volume (a substring match is made against the parameter value returning the data for all matching Volumes).")

plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -244,25 +244,49 @@ public ListResponse<VolumeMetricsStatsResponse> searchForVolumeMetricsStats(List
244244
return createVolumeMetricsStatsResponse(volumeList, volumeStatsList);
245245
}
246246

247+
/**
248+
* Outputs the parameters that should be used for access control in the query of a resource to
249+
* {@code permittedAccounts} and {@code domainIdRecursiveListProject}.
250+
* @param isIdProvided indicates whether any ID was provided to the command
251+
*/
252+
private void buildBaseACLSearchParametersForMetrics(boolean isIdProvided, List<Long> permittedAccounts, Ternary<Long, Boolean,
253+
Project.ListProjectResourcesCriteria> domainIdRecursiveListProject) {
254+
Account caller = CallContext.current().getCallingAccount();
255+
Account.Type callerType = caller.getType();
256+
257+
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(callerType);
258+
domainIdRecursiveListProject.second(recursive);
259+
260+
// If no ID was provided, then the listing will skip project resources (null); otherwise, project resources should
261+
// be listed as well (any long allows this)
262+
Long id = isIdProvided ? 1L : null;
263+
264+
// Allow users to also list metrics of resources owned by projects they belong to (-1L), and admins to list all
265+
// metrics belonging to their domains recursively (null)
266+
Long projectId = isIdProvided && callerType == Account.Type.NORMAL ? -1L : null;
267+
268+
accountMgr.buildACLSearchParameters(caller, id, null, projectId, permittedAccounts, domainIdRecursiveListProject, true, false);
269+
}
270+
247271
/**
248272
* Searches VMs based on {@code ListVMsUsageHistoryCmd} parameters.
249273
*
250274
* @param cmd the {@link ListVMsUsageHistoryCmd} specifying the parameters.
251275
* @return the list of VMs.
252276
*/
253277
protected Pair<List<UserVmVO>, Integer> searchForUserVmsInternal(ListVMsUsageHistoryCmd cmd) {
254-
final Long id = cmd.getId();
255-
Account caller = CallContext.current().getCallingAccount();
278+
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
279+
280+
boolean isIdProvided = CollectionUtils.isNotEmpty(ids);
256281
List<Long> permittedAccounts = new ArrayList<>();
257-
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
258-
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
259-
accountMgr.buildACLSearchParameters(caller, id, null, null, permittedAccounts, domainIdRecursiveListProject, true, false);
282+
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, null, null);
283+
buildBaseACLSearchParametersForMetrics(isIdProvided, permittedAccounts, domainIdRecursiveListProject);
284+
260285
Long domainId = domainIdRecursiveListProject.first();
261286
Boolean isRecursive = domainIdRecursiveListProject.second();
262287
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
263288

264289
Filter searchFilter = new Filter(UserVmVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
265-
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
266290
String name = cmd.getName();
267291
String keyword = cmd.getKeyword();
268292

@@ -357,18 +381,18 @@ protected Map<Long,List<VmStatsVO>> searchForVmMetricsStatsInternal(Date startDa
357381
* @return the list of VMs.
358382
*/
359383
protected Pair<List<VolumeVO>, Integer> searchForVolumesInternal(ListVolumesUsageHistoryCmd cmd) {
360-
final Long id = cmd.getId();
361-
Account caller = CallContext.current().getCallingAccount();
384+
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
385+
386+
boolean isIdProvided = CollectionUtils.isNotEmpty(ids);
362387
List<Long> permittedAccounts = new ArrayList<>();
363-
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
364-
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
365-
accountMgr.buildACLSearchParameters(caller, id, null, null, permittedAccounts, domainIdRecursiveListProject, true, false);
388+
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, null, null);
389+
buildBaseACLSearchParametersForMetrics(isIdProvided, permittedAccounts, domainIdRecursiveListProject);
390+
366391
Long domainId = domainIdRecursiveListProject.first();
367392
Boolean isRecursive = domainIdRecursiveListProject.second();
368393
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
369394

370395
Filter searchFilter = new Filter(VolumeVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
371-
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
372396
String name = cmd.getName();
373397
String keyword = cmd.getKeyword();
374398

0 commit comments

Comments
 (0)