This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.20 by this push:
new 061ce9b39bc Fix VM and volume metrics listing regressions (#12284)
061ce9b39bc is described below
commit 061ce9b39bc1ec63f311b34e4246a6150ade9f22
Author: Fabricio Duarte <[email protected]>
AuthorDate: Sat Dec 20 06:40:26 2025 -0300
Fix VM and volume metrics listing regressions (#12284)
---
.../cloudstack/api/ListVolumesUsageHistoryCmd.java | 3 +-
.../cloudstack/metrics/MetricsServiceImpl.java | 48 ++++++++++++++++------
2 files changed, 37 insertions(+), 14 deletions(-)
diff --git
a/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVolumesUsageHistoryCmd.java
b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVolumesUsageHistoryCmd.java
index 4e9191a16f8..e5d6a2429d2 100644
---
a/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVolumesUsageHistoryCmd.java
+++
b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVolumesUsageHistoryCmd.java
@@ -21,7 +21,6 @@ import java.util.List;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.SystemVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.response.VolumeMetricsStatsResponse;
@@ -37,7 +36,7 @@ public class ListVolumesUsageHistoryCmd extends
BaseResourceUsageHistoryCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType =
VolumeResponse.class, description = "the ID of the volume.")
private Long id;
- @Parameter(name=ApiConstants.IDS, type=CommandType.LIST,
collectionType=CommandType.UUID, entityType= SystemVmResponse.class,
description="the IDs of the volumes, mutually exclusive with id.")
+ @Parameter(name = ApiConstants.IDS, type = CommandType.LIST,
collectionType = CommandType.UUID, entityType = VolumeResponse.class,
description = "the IDs of the volumes, mutually exclusive with id.")
private List<Long> ids;
@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).")
diff --git
a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
index c305d9312ba..77785133428 100644
---
a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
+++
b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
@@ -244,6 +244,30 @@ public class MetricsServiceImpl extends
MutualExclusiveIdsManagerBase implements
return createVolumeMetricsStatsResponse(volumeList, volumeStatsList);
}
+ /**
+ * Outputs the parameters that should be used for access control in the
query of a resource to
+ * {@code permittedAccounts} and {@code domainIdRecursiveListProject}.
+ * @param isIdProvided indicates whether any ID was provided to the command
+ */
+ private void buildBaseACLSearchParametersForMetrics(boolean isIdProvided,
List<Long> permittedAccounts, Ternary<Long, Boolean,
+ Project.ListProjectResourcesCriteria>
domainIdRecursiveListProject) {
+ Account caller = CallContext.current().getCallingAccount();
+ Account.Type callerType = caller.getType();
+
+ boolean recursive =
AccountTypesWithRecursiveUsageAccess.contains(callerType);
+ domainIdRecursiveListProject.second(recursive);
+
+ // If no ID was provided, then the listing will skip project resources
(null); otherwise, project resources should
+ // be listed as well (any long allows this)
+ Long id = isIdProvided ? 1L : null;
+
+ // Allow users to also list metrics of resources owned by projects
they belong to (-1L), and admins to list all
+ // metrics belonging to their domains recursively (null)
+ Long projectId = isIdProvided && callerType == Account.Type.NORMAL ?
-1L : null;
+
+ accountMgr.buildACLSearchParameters(caller, id, null, projectId,
permittedAccounts, domainIdRecursiveListProject, true, false);
+ }
+
/**
* Searches VMs based on {@code ListVMsUsageHistoryCmd} parameters.
*
@@ -251,18 +275,18 @@ public class MetricsServiceImpl extends
MutualExclusiveIdsManagerBase implements
* @return the list of VMs.
*/
protected Pair<List<UserVmVO>, Integer>
searchForUserVmsInternal(ListVMsUsageHistoryCmd cmd) {
- final Long id = cmd.getId();
- Account caller = CallContext.current().getCallingAccount();
+ List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
+
+ boolean isIdProvided = CollectionUtils.isNotEmpty(ids);
List<Long> permittedAccounts = new ArrayList<>();
- boolean recursive =
AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
- Ternary<Long, Boolean, Project.ListProjectResourcesCriteria>
domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
- accountMgr.buildACLSearchParameters(caller, id, null, null,
permittedAccounts, domainIdRecursiveListProject, true, false);
+ Ternary<Long, Boolean, Project.ListProjectResourcesCriteria>
domainIdRecursiveListProject = new Ternary<>(null, null, null);
+ buildBaseACLSearchParametersForMetrics(isIdProvided,
permittedAccounts, domainIdRecursiveListProject);
+
Long domainId = domainIdRecursiveListProject.first();
Boolean isRecursive = domainIdRecursiveListProject.second();
Project.ListProjectResourcesCriteria listProjectResourcesCriteria =
domainIdRecursiveListProject.third();
Filter searchFilter = new Filter(UserVmVO.class, "id", true,
cmd.getStartIndex(), cmd.getPageSizeVal());
- List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
String name = cmd.getName();
String keyword = cmd.getKeyword();
@@ -357,18 +381,18 @@ public class MetricsServiceImpl extends
MutualExclusiveIdsManagerBase implements
* @return the list of VMs.
*/
protected Pair<List<VolumeVO>, Integer>
searchForVolumesInternal(ListVolumesUsageHistoryCmd cmd) {
- final Long id = cmd.getId();
- Account caller = CallContext.current().getCallingAccount();
+ List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
+
+ boolean isIdProvided = CollectionUtils.isNotEmpty(ids);
List<Long> permittedAccounts = new ArrayList<>();
- boolean recursive =
AccountTypesWithRecursiveUsageAccess.contains(caller.getType());
- Ternary<Long, Boolean, Project.ListProjectResourcesCriteria>
domainIdRecursiveListProject = new Ternary<>(null, recursive, null);
- accountMgr.buildACLSearchParameters(caller, id, null, null,
permittedAccounts, domainIdRecursiveListProject, true, false);
+ Ternary<Long, Boolean, Project.ListProjectResourcesCriteria>
domainIdRecursiveListProject = new Ternary<>(null, null, null);
+ buildBaseACLSearchParametersForMetrics(isIdProvided,
permittedAccounts, domainIdRecursiveListProject);
+
Long domainId = domainIdRecursiveListProject.first();
Boolean isRecursive = domainIdRecursiveListProject.second();
Project.ListProjectResourcesCriteria listProjectResourcesCriteria =
domainIdRecursiveListProject.third();
Filter searchFilter = new Filter(VolumeVO.class, "id", true,
cmd.getStartIndex(), cmd.getPageSizeVal());
- List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
String name = cmd.getName();
String keyword = cmd.getKeyword();