server: fix listing vm metrics for infra resources (#6851)

Fixes #6786 

listVirtualMachinesMetrics does not support some of the params that are supported by admin API call for listVirtualMachines.
These parameters are used in UI.

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
Co-authored-by: Rohit Yadav <rohityadav89@gmail.com>
Co-authored-by: Daan Hoogland <daan@onecht.net>
This commit is contained in:
Abhishek Kumar 2022-12-12 11:22:07 +05:30 committed by GitHub
parent 335e26bb1d
commit 4de66f9855
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 117 additions and 29 deletions

View File

@ -17,16 +17,18 @@
package org.apache.cloudstack.api;
import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.user.UserCmd;
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.VmMetricsResponse;
import javax.inject.Inject;
import java.util.List;
/**
* API supported for backward compatibility. Use the {@link ListVMsUsageHistoryCmd} API instead. <br>
* The reasons for this are: <br>
@ -42,9 +44,8 @@ import java.util.List;
*/
@APICommand(name = ListVMsMetricsCmd.APINAME, description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
@Deprecated(since = "4.17.0")
public class ListVMsMetricsCmd extends ListVMsCmd {
since = "4.9.3", authorized = {RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class ListVMsMetricsCmd extends ListVMsCmd implements UserCmd {
public static final String APINAME = "listVirtualMachinesMetrics";
@Inject

View File

@ -0,0 +1,73 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.admin.AdminCmd;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.response.VmMetricsResponse;
@APICommand(name = ListVMsMetricsCmd.APINAME, description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
authorized = {RoleType.Admin})
public class ListVMsMetricsCmdByAdmin extends ListVMsMetricsCmd implements AdminCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.HOST_ID, type= BaseCmd.CommandType.UUID, entityType= HostResponse.class,
description="the host ID")
private Long hostId;
@Parameter(name=ApiConstants.POD_ID, type= BaseCmd.CommandType.UUID, entityType= PodResponse.class,
description="the pod ID")
private Long podId;
@Parameter(name=ApiConstants.STORAGE_ID, type= BaseCmd.CommandType.UUID, entityType= StoragePoolResponse.class,
description="the storage ID where vm's volumes belong to")
private Long storageId;
@Parameter(name = ApiConstants.CLUSTER_ID, type = BaseCmd.CommandType.UUID, entityType = ClusterResponse.class,
description = "the cluster ID")
private Long clusterId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getHostId() {
return hostId;
}
public Long getPodId() {
return podId;
}
public Long getStorageId() {
return storageId;
}
public Long getClusterId() {
return clusterId;
}
}

View File

@ -17,6 +17,8 @@
package org.apache.cloudstack.metrics;
import static com.cloud.utils.NumbersUtil.toReadableSize;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.util.ArrayList;
@ -28,14 +30,6 @@ import java.util.Properties;
import javax.inject.Inject;
import com.cloud.server.DbStatsCollection;
import com.cloud.server.StatsCollector;
import com.cloud.usage.UsageJobVO;
import com.cloud.usage.dao.UsageJobDao;
import com.cloud.utils.db.DbProperties;
import com.cloud.utils.db.DbUtil;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.script.Script;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.ListClustersMetricsCmd;
import org.apache.cloudstack.api.ListDbMetricsCmd;
@ -45,6 +39,7 @@ import org.apache.cloudstack.api.ListMgmtsMetricsCmd;
import org.apache.cloudstack.api.ListStoragePoolsMetricsCmd;
import org.apache.cloudstack.api.ListUsageServerMetricsCmd;
import org.apache.cloudstack.api.ListVMsMetricsCmd;
import org.apache.cloudstack.api.ListVMsMetricsCmdByAdmin;
import org.apache.cloudstack.api.ListVMsUsageHistoryCmd;
import org.apache.cloudstack.api.ListVolumesMetricsCmd;
import org.apache.cloudstack.api.ListZonesMetricsCmd;
@ -52,8 +47,8 @@ import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.StatsResponse;
import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.StatsResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
@ -76,6 +71,10 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.log4j.Logger;
import com.cloud.agent.api.VmStatsEntryBase;
import com.cloud.alert.AlertManager;
@ -103,13 +102,21 @@ import com.cloud.network.router.VirtualRouter;
import com.cloud.org.Cluster;
import com.cloud.org.Grouping;
import com.cloud.org.Managed;
import com.cloud.server.DbStatsCollection;
import com.cloud.server.ManagementServerHostStats;
import com.cloud.server.StatsCollector;
import com.cloud.usage.UsageJobVO;
import com.cloud.usage.dao.UsageJobDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DbProperties;
import com.cloud.utils.db.DbUtil;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.script.Script;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
@ -119,12 +126,6 @@ import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.dao.VmStatsDao;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.log4j.Logger;
import static com.cloud.utils.NumbersUtil.toReadableSize;
public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements MetricsService {
private static final Logger LOGGER = Logger.getLogger(MetricsServiceImpl.class);
@ -878,6 +879,9 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
cmdList.add(ListVolumesMetricsCmd.class);
cmdList.add(ListZonesMetricsCmd.class);
cmdList.add(ListVMsUsageHistoryCmd.class);
// separate Admin commands
cmdList.add(ListVMsMetricsCmdByAdmin.class);
return cmdList;
}

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.api.query;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -65,7 +67,6 @@ import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
import org.apache.cloudstack.api.command.admin.template.ListTemplatesCmdByAdmin;
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
@ -971,6 +972,17 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
return response;
}
private Object getObjectPossibleMethodValue(Object obj, String methodName) {
Object result = null;
try {
Method m = obj.getClass().getMethod(methodName);
result = m.invoke(obj);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {}
return result;
}
private Pair<List<UserVmJoinVO>, Integer> searchForUserVMsInternal(ListVMsCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedAccounts = new ArrayList<Long>();
@ -1035,16 +1047,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
Object backupOfferingId = cmd.getBackupOfferingId();
Object isHaEnabled = cmd.getHaEnabled();
Object pod = null;
Long clusterId = null;
Object clusterId = null;
Object hostId = null;
Object storageId = null;
if (_accountMgr.isRootAdmin(caller.getId())) {
if (cmd instanceof ListVMsCmdByAdmin) {
pod = ((ListVMsCmdByAdmin) cmd).getPodId();
clusterId = ((ListVMsCmdByAdmin) cmd).getClusterId();
hostId = ((ListVMsCmdByAdmin) cmd).getHostId();
storageId = ((ListVMsCmdByAdmin) cmd).getStorageId();
}
pod = getObjectPossibleMethodValue(cmd, "getPodId");
clusterId = getObjectPossibleMethodValue(cmd, "getClusterId");
hostId = getObjectPossibleMethodValue(cmd, "getHostId");
storageId = getObjectPossibleMethodValue(cmd, "getStorageId");
}
sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE);