Skip to content

Commit 631d6ad

Browse files
authored
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
1 parent 68a231a commit 631d6ad

File tree

11 files changed

+63
-39
lines changed

11 files changed

+63
-39
lines changed

api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.user.vm;
1818

19-
import java.util.ArrayList;
2019
import java.util.EnumSet;
20+
import java.util.HashSet;
2121
import java.util.List;
22+
import java.util.Set;
2223

2324
import org.apache.cloudstack.acl.RoleType;
2425
import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -45,6 +46,7 @@
4546
import org.apache.cloudstack.api.response.VpcResponse;
4647
import org.apache.cloudstack.api.response.ZoneResponse;
4748
import org.apache.commons.lang3.BooleanUtils;
49+
import org.apache.commons.collections.CollectionUtils;
4850
import org.apache.log4j.Logger;
4951

5052
import com.cloud.exception.InvalidParameterValueException;
@@ -58,7 +60,6 @@
5860
public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements UserCmd {
5961
public static final Logger s_logger = Logger.getLogger(ListVMsCmd.class.getName());
6062

61-
private static final String s_name = "listvirtualmachinesresponse";
6263

6364
/////////////////////////////////////////////////////
6465
//////////////// API parameters /////////////////////
@@ -98,7 +99,8 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
9899
collectionType = CommandType.STRING,
99100
description = "comma separated list of vm details requested, "
100101
+ "value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp]."
101-
+ " If no parameter is passed in, the details will be defaulted to all")
102+
+ " If no parameter is passed in, the details will be defaulted to all. When return.vm.stats.on.vm.list is true, the default" +
103+
"details change to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp], thus the stats will not be returned. ")
102104
private List<String> viewDetails;
103105

104106
@Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "list vms by template")
@@ -239,22 +241,32 @@ public Long getAutoScaleVmGroupId() {
239241
return autoScaleVmGroupId;
240242
}
241243

244+
protected boolean isViewDetailsEmpty() {
245+
return CollectionUtils.isEmpty(viewDetails);
246+
}
247+
242248
public EnumSet<VMDetails> getDetails() throws InvalidParameterValueException {
243-
EnumSet<VMDetails> dv;
244-
if (viewDetails == null || viewDetails.size() <= 0) {
245-
dv = EnumSet.of(VMDetails.all);
246-
} else {
247-
try {
248-
ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
249-
for (String detail : viewDetails) {
250-
dc.add(VMDetails.valueOf(detail));
251-
}
252-
dv = EnumSet.copyOf(dc);
253-
} catch (IllegalArgumentException e) {
254-
throw new InvalidParameterValueException("The details parameter contains a non permitted value. The allowed values are " + EnumSet.allOf(VMDetails.class));
249+
if (isViewDetailsEmpty()) {
250+
if (_queryService.ReturnVmStatsOnVmList.value()) {
251+
return EnumSet.of(VMDetails.all);
252+
}
253+
254+
Set<VMDetails> allDetails = new HashSet<>(Set.of(VMDetails.values()));
255+
allDetails.remove(VMDetails.stats);
256+
allDetails.remove(VMDetails.all);
257+
return EnumSet.copyOf(allDetails);
258+
}
259+
260+
try {
261+
Set<VMDetails> dc = new HashSet<>();
262+
for (String detail : viewDetails) {
263+
dc.add(VMDetails.valueOf(detail));
255264
}
265+
266+
return EnumSet.copyOf(dc);
267+
} catch (IllegalArgumentException e) {
268+
throw new InvalidParameterValueException("The details parameter contains a non permitted value. The allowed values are " + EnumSet.allOf(VMDetails.class));
256269
}
257-
return dv;
258270
}
259271

260272
@Override
@@ -277,10 +289,6 @@ public Boolean getVnf() {
277289
/////////////////////////////////////////////////////
278290
/////////////// API Implementation///////////////////
279291
/////////////////////////////////////////////////////
280-
@Override
281-
public String getCommandName() {
282-
return s_name;
283-
}
284292

285293
@Override
286294
public ApiCommandResourceType getApiResourceType() {

api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.cloud.uservm.UserVm;
3838
import com.cloud.vm.VirtualMachine;
3939
import com.google.gson.annotations.SerializedName;
40+
import org.apache.commons.collections.CollectionUtils;
4041

4142
@SuppressWarnings("unused")
4243
@EntityReference(value = {VirtualMachine.class, UserVm.class, VirtualRouter.class})
@@ -273,6 +274,10 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
273274
@Param(description = "the hypervisor on which the template runs")
274275
private String hypervisor;
275276

277+
@SerializedName(ApiConstants.IP_ADDRESS)
278+
@Param(description = "the VM's primary IP address")
279+
private String ipAddress;
280+
276281
@SerializedName(ApiConstants.PUBLIC_IP_ID)
277282
@Param(description = "public IP address id associated with vm via Static nat rule")
278283
private String publicIpId;
@@ -627,6 +632,10 @@ public String getHypervisor() {
627632
return hypervisor;
628633
}
629634

635+
public String getIpAddress() {
636+
return ipAddress;
637+
}
638+
630639
public String getPublicIpId() {
631640
return publicIpId;
632641
}
@@ -863,6 +872,13 @@ public void setForVirtualNetwork(Boolean forVirtualNetwork) {
863872

864873
public void setNics(Set<NicResponse> nics) {
865874
this.nics = nics;
875+
setIpAddress(nics);
876+
}
877+
878+
public void setIpAddress(final Set<NicResponse> nics) {
879+
if (CollectionUtils.isNotEmpty(nics)) {
880+
this.ipAddress = nics.iterator().next().getIpaddress();
881+
}
866882
}
867883

868884
public void addNic(NicResponse nic) {

api/src/main/java/org/apache/cloudstack/query/QueryService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ public interface QueryService {
125125
static final ConfigKey<Boolean> SharePublicTemplatesWithOtherDomains = new ConfigKey<>("Advanced", Boolean.class, "share.public.templates.with.other.domains", "true",
126126
"If false, templates of this domain will not show up in the list templates of other domains.", true, ConfigKey.Scope.Domain);
127127

128+
ConfigKey<Boolean> ReturnVmStatsOnVmList = new ConfigKey<>("Advanced", Boolean.class, "return.vm.stats.on.vm.list", "true",
129+
"If false, changes the listVirtualMachines default details to [group, nics, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp], so that the VMs' stats" +
130+
" are not returned by default when listing VMs; only when the 'stats' or 'all' detail is informed.", true, ConfigKey.Scope.Global);
131+
128132
ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException;
129133

130134
ListResponse<UserResponse> searchForUsers(Long domainId, boolean recursive) throws PermissionDeniedException;

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717

1818
package org.apache.cloudstack.api;
1919

20+
import java.util.EnumSet;
2021
import java.util.List;
2122

2223
import javax.inject.Inject;
2324

25+
import com.cloud.exception.InvalidParameterValueException;
2426
import org.apache.cloudstack.acl.RoleType;
2527
import org.apache.cloudstack.api.command.user.UserCmd;
2628
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
@@ -42,18 +44,21 @@
4244
* although most of it is not suitable/useful for the API purpose.</li>
4345
* </ul>
4446
*/
45-
@APICommand(name = ListVMsMetricsCmd.APINAME, description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
47+
@APICommand(name = "listVirtualMachinesMetrics", description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
4648
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Restricted,
4749
since = "4.9.3", authorized = {RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
4850
public class ListVMsMetricsCmd extends ListVMsCmd implements UserCmd {
49-
public static final String APINAME = "listVirtualMachinesMetrics";
5051

5152
@Inject
5253
private MetricsService metricsService;
5354

5455
@Override
55-
public String getCommandName() {
56-
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
56+
public EnumSet<ApiConstants.VMDetails> getDetails() throws InvalidParameterValueException {
57+
if (isViewDetailsEmpty()) {
58+
return EnumSet.of(ApiConstants.VMDetails.all);
59+
}
60+
61+
return super.getDetails();
5762
}
5863

5964
@Override

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,6 @@ public List<VmMetricsResponse> listVmMetrics(List<UserVmResponse> vmResponses) {
619619
}
620620

621621
metricsResponse.setHasAnnotation(vmResponse.hasAnnotation());
622-
metricsResponse.setIpAddress(vmResponse.getNics());
623622
metricsResponse.setCpuTotal(vmResponse.getCpuNumber(), vmResponse.getCpuSpeed());
624623
metricsResponse.setMemTotal(vmResponse.getMemory());
625624
metricsResponse.setNetworkRead(vmResponse.getNetworkKbsRead());

plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,13 @@
1717

1818
package org.apache.cloudstack.response;
1919

20-
import java.util.Set;
21-
2220
import org.apache.cloudstack.api.ApiConstants;
23-
import org.apache.cloudstack.api.response.NicResponse;
2421
import org.apache.cloudstack.api.response.UserVmResponse;
2522

2623
import com.cloud.serializer.Param;
2724
import com.google.gson.annotations.SerializedName;
2825

2926
public class VmMetricsResponse extends UserVmResponse {
30-
@SerializedName(ApiConstants.IP_ADDRESS)
31-
@Param(description = "the VM's primary IP address")
32-
private String ipAddress;
3327

3428
@SerializedName("cputotal")
3529
@Param(description = "the total cpu capacity in Ghz")
@@ -59,11 +53,6 @@ public class VmMetricsResponse extends UserVmResponse {
5953
@Param(description = "the total disk iops")
6054
private Long diskIopsTotal;
6155

62-
public void setIpAddress(final Set<NicResponse> nics) {
63-
if (nics != null && nics.size() > 0) {
64-
this.ipAddress = nics.iterator().next().getIpaddress();
65-
}
66-
}
6756

6857
public void setCpuTotal(final Integer cpuNumber, final Integer cpuSpeed) {
6958
if (cpuNumber != null && cpuSpeed != null) {

server/src/main/java/com/cloud/api/query/QueryManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5686,6 +5686,6 @@ public String getConfigComponentName() {
56865686
@Override
56875687
public ConfigKey<?>[] getConfigKeys() {
56885688
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, UserVMDeniedDetails, UserVMReadOnlyDetails, SortKeyAscending,
5689-
AllowUserViewAllDomainAccounts, SharePublicTemplatesWithOtherDomains};
5689+
AllowUserViewAllDomainAccounts, SharePublicTemplatesWithOtherDomains, ReturnVmStatsOnVmList};
56905690
}
56915691
}

server/src/main/java/com/cloud/api/query/ViewResponseHelper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ public static List<UserVmResponse> createUserVmResponse(ResponseView view, Strin
166166
// update nics, securitygroups, tags, affinitygroups for 1 to many mapping fields
167167
userVmData = ApiDBUtils.fillVmDetails(view, userVmData, userVm);
168168
}
169+
userVmData.setIpAddress(userVmData.getNics());
169170
vmDataList.put(userVm.getId(), userVmData);
170171
}
171172
return new ArrayList<UserVmResponse>(vmDataList.values());

ui/src/config/router.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ function generateRouterMap (section) {
7575
icon: child.icon,
7676
docHelp: vueProps.$applyDocHelpMappings(child.docHelp),
7777
permission: child.permission,
78+
getApiToCall: child.getApiToCall,
7879
resourceType: child.resourceType,
7980
filters: child.filters,
8081
params: child.params ? child.params : {},

ui/src/config/section/compute.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export default {
2828
title: 'label.instances',
2929
icon: 'cloud-server-outlined',
3030
docHelp: 'adminguide/virtual_machines.html',
31-
permission: ['listVirtualMachinesMetrics'],
31+
permission: ['listVirtualMachines', 'listVirtualMachinesMetrics'],
32+
getApiToCall: () => store.getters.metrics ? 'listVirtualMachinesMetrics' : 'listVirtualMachines',
3233
resourceType: 'UserVm',
3334
params: () => {
3435
var params = { details: 'servoff,tmpl,iso,nics,backoff' }

0 commit comments

Comments
 (0)