Skip to content

Commit 2a0815b

Browse files
winterhazelLocharla, Sandeep
authored andcommitted
Fix VM and volume metrics listing regressions (apache#12284)
1 parent fb7df08 commit 2a0815b

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
@@ -248,25 +248,49 @@ public ListResponse<VolumeMetricsStatsResponse> searchForVolumeMetricsStats(List
248248
return createVolumeMetricsStatsResponse(volumeList, volumeStatsList);
249249
}
250250

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

268293
Filter searchFilter = new Filter(UserVmVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
269-
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
270294
String name = cmd.getName();
271295
String keyword = cmd.getKeyword();
272296

@@ -361,18 +385,18 @@ protected Map<Long,List<VmStatsVO>> searchForVmMetricsStatsInternal(Date startDa
361385
* @return the list of VMs.
362386
*/
363387
protected Pair<List<VolumeVO>, Integer> searchForVolumesInternal(ListVolumesUsageHistoryCmd cmd) {
364-
final Long id = cmd.getId();
365-
Account caller = CallContext.current().getCallingAccount();
388+
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
389+
390+
boolean isIdProvided = CollectionUtils.isNotEmpty(ids);
366391
List<Long> permittedAccounts = new ArrayList<>();
367-
boolean recursive = AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
368-
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
369-
accountMgr.buildACLSearchParameters(caller, id, null, null, permittedAccounts, domainIdRecursiveListProject, true, false);
392+
Ternary<Long, Boolean, Project.ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(null, null, null);
393+
buildBaseACLSearchParametersForMetrics(isIdProvided, permittedAccounts, domainIdRecursiveListProject);
394+
370395
Long domainId = domainIdRecursiveListProject.first();
371396
Boolean isRecursive = domainIdRecursiveListProject.second();
372397
Project.ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
373398

374399
Filter searchFilter = new Filter(VolumeVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
375-
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
376400
String name = cmd.getName();
377401
String keyword = cmd.getKeyword();
378402

0 commit comments

Comments
 (0)