mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Do not retrieve VM's stats on normal VM listing (#8782)
* Do not retrieve VM's stats on normal VM listing * Add config to control the behavior * address reviews
This commit is contained in:
parent
68a231aaee
commit
631d6ad09b
@ -16,9 +16,10 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.user.vm;
|
package org.apache.cloudstack.api.command.user.vm;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.RoleType;
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||||
@ -45,6 +46,7 @@ import org.apache.cloudstack.api.response.UserVmResponse;
|
|||||||
import org.apache.cloudstack.api.response.VpcResponse;
|
import org.apache.cloudstack.api.response.VpcResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
@ -58,7 +60,6 @@ import com.cloud.vm.VirtualMachine;
|
|||||||
public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements UserCmd {
|
public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements UserCmd {
|
||||||
public static final Logger s_logger = Logger.getLogger(ListVMsCmd.class.getName());
|
public static final Logger s_logger = Logger.getLogger(ListVMsCmd.class.getName());
|
||||||
|
|
||||||
private static final String s_name = "listvirtualmachinesresponse";
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
//////////////// API parameters /////////////////////
|
//////////////// API parameters /////////////////////
|
||||||
@ -98,7 +99,8 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
|
|||||||
collectionType = CommandType.STRING,
|
collectionType = CommandType.STRING,
|
||||||
description = "comma separated list of vm details requested, "
|
description = "comma separated list of vm details requested, "
|
||||||
+ "value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp]."
|
+ "value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp]."
|
||||||
+ " If no parameter is passed in, the details will be defaulted to all")
|
+ " If no parameter is passed in, the details will be defaulted to all. When return.vm.stats.on.vm.list is true, the default" +
|
||||||
|
"details change to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp], thus the stats will not be returned. ")
|
||||||
private List<String> viewDetails;
|
private List<String> viewDetails;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "list vms by template")
|
@Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "list vms by template")
|
||||||
@ -239,22 +241,32 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
|
|||||||
return autoScaleVmGroupId;
|
return autoScaleVmGroupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isViewDetailsEmpty() {
|
||||||
|
return CollectionUtils.isEmpty(viewDetails);
|
||||||
|
}
|
||||||
|
|
||||||
public EnumSet<VMDetails> getDetails() throws InvalidParameterValueException {
|
public EnumSet<VMDetails> getDetails() throws InvalidParameterValueException {
|
||||||
EnumSet<VMDetails> dv;
|
if (isViewDetailsEmpty()) {
|
||||||
if (viewDetails == null || viewDetails.size() <= 0) {
|
if (_queryService.ReturnVmStatsOnVmList.value()) {
|
||||||
dv = EnumSet.of(VMDetails.all);
|
return EnumSet.of(VMDetails.all);
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
|
|
||||||
for (String detail : viewDetails) {
|
|
||||||
dc.add(VMDetails.valueOf(detail));
|
|
||||||
}
|
|
||||||
dv = EnumSet.copyOf(dc);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
throw new InvalidParameterValueException("The details parameter contains a non permitted value. The allowed values are " + EnumSet.allOf(VMDetails.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<VMDetails> allDetails = new HashSet<>(Set.of(VMDetails.values()));
|
||||||
|
allDetails.remove(VMDetails.stats);
|
||||||
|
allDetails.remove(VMDetails.all);
|
||||||
|
return EnumSet.copyOf(allDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Set<VMDetails> dc = new HashSet<>();
|
||||||
|
for (String detail : viewDetails) {
|
||||||
|
dc.add(VMDetails.valueOf(detail));
|
||||||
|
}
|
||||||
|
|
||||||
|
return EnumSet.copyOf(dc);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new InvalidParameterValueException("The details parameter contains a non permitted value. The allowed values are " + EnumSet.allOf(VMDetails.class));
|
||||||
}
|
}
|
||||||
return dv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -277,10 +289,6 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
|
|||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@Override
|
|
||||||
public String getCommandName() {
|
|
||||||
return s_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiCommandResourceType getApiResourceType() {
|
public ApiCommandResourceType getApiResourceType() {
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import com.cloud.serializer.Param;
|
|||||||
import com.cloud.uservm.UserVm;
|
import com.cloud.uservm.UserVm;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class})
|
@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class})
|
||||||
@ -273,6 +274,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||||||
@Param(description = "the hypervisor on which the template runs")
|
@Param(description = "the hypervisor on which the template runs")
|
||||||
private String hypervisor;
|
private String hypervisor;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.IP_ADDRESS)
|
||||||
|
@Param(description = "the VM's primary IP address")
|
||||||
|
private String ipAddress;
|
||||||
|
|
||||||
@SerializedName(ApiConstants.PUBLIC_IP_ID)
|
@SerializedName(ApiConstants.PUBLIC_IP_ID)
|
||||||
@Param(description = "public IP address id associated with vm via Static nat rule")
|
@Param(description = "public IP address id associated with vm via Static nat rule")
|
||||||
private String publicIpId;
|
private String publicIpId;
|
||||||
@ -627,6 +632,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||||||
return hypervisor;
|
return hypervisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getIpAddress() {
|
||||||
|
return ipAddress;
|
||||||
|
}
|
||||||
|
|
||||||
public String getPublicIpId() {
|
public String getPublicIpId() {
|
||||||
return publicIpId;
|
return publicIpId;
|
||||||
}
|
}
|
||||||
@ -863,6 +872,13 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
|||||||
|
|
||||||
public void setNics(Set<NicResponse> nics) {
|
public void setNics(Set<NicResponse> nics) {
|
||||||
this.nics = nics;
|
this.nics = nics;
|
||||||
|
setIpAddress(nics);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIpAddress(final Set<NicResponse> nics) {
|
||||||
|
if (CollectionUtils.isNotEmpty(nics)) {
|
||||||
|
this.ipAddress = nics.iterator().next().getIpaddress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNic(NicResponse nic) {
|
public void addNic(NicResponse nic) {
|
||||||
|
|||||||
@ -125,6 +125,10 @@ public interface QueryService {
|
|||||||
static final ConfigKey<Boolean> SharePublicTemplatesWithOtherDomains = new ConfigKey<>("Advanced", Boolean.class, "share.public.templates.with.other.domains", "true",
|
static final ConfigKey<Boolean> SharePublicTemplatesWithOtherDomains = new ConfigKey<>("Advanced", Boolean.class, "share.public.templates.with.other.domains", "true",
|
||||||
"If false, templates of this domain will not show up in the list templates of other domains.", true, ConfigKey.Scope.Domain);
|
"If false, templates of this domain will not show up in the list templates of other domains.", true, ConfigKey.Scope.Domain);
|
||||||
|
|
||||||
|
ConfigKey<Boolean> ReturnVmStatsOnVmList = new ConfigKey<>("Advanced", Boolean.class, "return.vm.stats.on.vm.list", "true",
|
||||||
|
"If false, changes the listVirtualMachines default details to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp], so that the VMs' stats" +
|
||||||
|
" are not returned by default when listing VMs; only when the 'stats' or 'all' detail is informed.", true, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException;
|
ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException;
|
||||||
|
|
||||||
ListResponse<UserResponse> searchForUsers(Long domainId, boolean recursive) throws PermissionDeniedException;
|
ListResponse<UserResponse> searchForUsers(Long domainId, boolean recursive) throws PermissionDeniedException;
|
||||||
|
|||||||
@ -17,10 +17,12 @@
|
|||||||
|
|
||||||
package org.apache.cloudstack.api;
|
package org.apache.cloudstack.api;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import org.apache.cloudstack.acl.RoleType;
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
|
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
|
||||||
@ -42,18 +44,21 @@ import org.apache.cloudstack.response.VmMetricsResponse;
|
|||||||
* although most of it is not suitable/useful for the API purpose.</li>
|
* although most of it is not suitable/useful for the API purpose.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@APICommand(name = ListVMsMetricsCmd.APINAME, description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
|
@APICommand(name = "listVirtualMachinesMetrics", description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Restricted,
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Restricted,
|
||||||
since = "4.9.3", authorized = {RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
since = "4.9.3", authorized = {RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||||
public class ListVMsMetricsCmd extends ListVMsCmd implements UserCmd {
|
public class ListVMsMetricsCmd extends ListVMsCmd implements UserCmd {
|
||||||
public static final String APINAME = "listVirtualMachinesMetrics";
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private MetricsService metricsService;
|
private MetricsService metricsService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCommandName() {
|
public EnumSet<ApiConstants.VMDetails> getDetails() throws InvalidParameterValueException {
|
||||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
if (isViewDetailsEmpty()) {
|
||||||
|
return EnumSet.of(ApiConstants.VMDetails.all);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -619,7 +619,6 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
metricsResponse.setHasAnnotation(vmResponse.hasAnnotation());
|
metricsResponse.setHasAnnotation(vmResponse.hasAnnotation());
|
||||||
metricsResponse.setIpAddress(vmResponse.getNics());
|
|
||||||
metricsResponse.setCpuTotal(vmResponse.getCpuNumber(), vmResponse.getCpuSpeed());
|
metricsResponse.setCpuTotal(vmResponse.getCpuNumber(), vmResponse.getCpuSpeed());
|
||||||
metricsResponse.setMemTotal(vmResponse.getMemory());
|
metricsResponse.setMemTotal(vmResponse.getMemory());
|
||||||
metricsResponse.setNetworkRead(vmResponse.getNetworkKbsRead());
|
metricsResponse.setNetworkRead(vmResponse.getNetworkKbsRead());
|
||||||
|
|||||||
@ -17,19 +17,13 @@
|
|||||||
|
|
||||||
package org.apache.cloudstack.response;
|
package org.apache.cloudstack.response;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.response.NicResponse;
|
|
||||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||||
|
|
||||||
import com.cloud.serializer.Param;
|
import com.cloud.serializer.Param;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class VmMetricsResponse extends UserVmResponse {
|
public class VmMetricsResponse extends UserVmResponse {
|
||||||
@SerializedName(ApiConstants.IP_ADDRESS)
|
|
||||||
@Param(description = "the VM's primary IP address")
|
|
||||||
private String ipAddress;
|
|
||||||
|
|
||||||
@SerializedName("cputotal")
|
@SerializedName("cputotal")
|
||||||
@Param(description = "the total cpu capacity in Ghz")
|
@Param(description = "the total cpu capacity in Ghz")
|
||||||
@ -59,11 +53,6 @@ public class VmMetricsResponse extends UserVmResponse {
|
|||||||
@Param(description = "the total disk iops")
|
@Param(description = "the total disk iops")
|
||||||
private Long diskIopsTotal;
|
private Long diskIopsTotal;
|
||||||
|
|
||||||
public void setIpAddress(final Set<NicResponse> nics) {
|
|
||||||
if (nics != null && nics.size() > 0) {
|
|
||||||
this.ipAddress = nics.iterator().next().getIpaddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCpuTotal(final Integer cpuNumber, final Integer cpuSpeed) {
|
public void setCpuTotal(final Integer cpuNumber, final Integer cpuSpeed) {
|
||||||
if (cpuNumber != null && cpuSpeed != null) {
|
if (cpuNumber != null && cpuSpeed != null) {
|
||||||
|
|||||||
@ -5686,6 +5686,6 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, UserVMDeniedDetails, UserVMReadOnlyDetails, SortKeyAscending,
|
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, UserVMDeniedDetails, UserVMReadOnlyDetails, SortKeyAscending,
|
||||||
AllowUserViewAllDomainAccounts, SharePublicTemplatesWithOtherDomains};
|
AllowUserViewAllDomainAccounts, SharePublicTemplatesWithOtherDomains, ReturnVmStatsOnVmList};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -166,6 +166,7 @@ public class ViewResponseHelper {
|
|||||||
// update nics, securitygroups, tags, affinitygroups for 1 to many mapping fields
|
// update nics, securitygroups, tags, affinitygroups for 1 to many mapping fields
|
||||||
userVmData = ApiDBUtils.fillVmDetails(view, userVmData, userVm);
|
userVmData = ApiDBUtils.fillVmDetails(view, userVmData, userVm);
|
||||||
}
|
}
|
||||||
|
userVmData.setIpAddress(userVmData.getNics());
|
||||||
vmDataList.put(userVm.getId(), userVmData);
|
vmDataList.put(userVm.getId(), userVmData);
|
||||||
}
|
}
|
||||||
return new ArrayList<UserVmResponse>(vmDataList.values());
|
return new ArrayList<UserVmResponse>(vmDataList.values());
|
||||||
|
|||||||
@ -75,6 +75,7 @@ function generateRouterMap (section) {
|
|||||||
icon: child.icon,
|
icon: child.icon,
|
||||||
docHelp: vueProps.$applyDocHelpMappings(child.docHelp),
|
docHelp: vueProps.$applyDocHelpMappings(child.docHelp),
|
||||||
permission: child.permission,
|
permission: child.permission,
|
||||||
|
getApiToCall: child.getApiToCall,
|
||||||
resourceType: child.resourceType,
|
resourceType: child.resourceType,
|
||||||
filters: child.filters,
|
filters: child.filters,
|
||||||
params: child.params ? child.params : {},
|
params: child.params ? child.params : {},
|
||||||
|
|||||||
@ -28,7 +28,8 @@ export default {
|
|||||||
title: 'label.instances',
|
title: 'label.instances',
|
||||||
icon: 'cloud-server-outlined',
|
icon: 'cloud-server-outlined',
|
||||||
docHelp: 'adminguide/virtual_machines.html',
|
docHelp: 'adminguide/virtual_machines.html',
|
||||||
permission: ['listVirtualMachinesMetrics'],
|
permission: ['listVirtualMachines', 'listVirtualMachinesMetrics'],
|
||||||
|
getApiToCall: () => store.getters.metrics ? 'listVirtualMachinesMetrics' : 'listVirtualMachines',
|
||||||
resourceType: 'UserVm',
|
resourceType: 'UserVm',
|
||||||
params: () => {
|
params: () => {
|
||||||
var params = { details: 'servoff,tmpl,iso,nics,backoff' }
|
var params = { details: 'servoff,tmpl,iso,nics,backoff' }
|
||||||
|
|||||||
@ -819,7 +819,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.$route && this.$route.meta && this.$route.meta.permission) {
|
if (this.$route && this.$route.meta && this.$route.meta.permission) {
|
||||||
this.apiName = this.$route.meta.permission[0]
|
this.apiName = (this.$route.meta.getApiToCall && this.$route.meta.getApiToCall()) || this.$route.meta.permission[0]
|
||||||
if (this.$route.meta.columns) {
|
if (this.$route.meta.columns) {
|
||||||
const columns = this.$route.meta.columns
|
const columns = this.$route.meta.columns
|
||||||
if (columns && typeof columns === 'function') {
|
if (columns && typeof columns === 'function') {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user