This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.19 by this push:
     new 631d6ad09bc Do not retrieve VM's stats on normal VM listing (#8782)
631d6ad09bc is described below

commit 631d6ad09bc5e175492973de9f2958456db4488e
Author: João Jandre <48719461+joaojan...@users.noreply.github.com>
AuthorDate: Wed Jun 5 09:15:28 2024 -0300

    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
---
 .../cloudstack/api/command/user/vm/ListVMsCmd.java | 48 +++++++++++++---------
 .../cloudstack/api/response/UserVmResponse.java    | 16 ++++++++
 .../org/apache/cloudstack/query/QueryService.java  |  4 ++
 .../apache/cloudstack/api/ListVMsMetricsCmd.java   | 13 ++++--
 .../cloudstack/metrics/MetricsServiceImpl.java     |  1 -
 .../cloudstack/response/VmMetricsResponse.java     | 11 -----
 .../java/com/cloud/api/query/QueryManagerImpl.java |  2 +-
 .../com/cloud/api/query/ViewResponseHelper.java    |  1 +
 ui/src/config/router.js                            |  1 +
 ui/src/config/section/compute.js                   |  3 +-
 ui/src/views/AutogenView.vue                       |  2 +-
 11 files changed, 63 insertions(+), 39 deletions(-)

diff --git 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
index 6a5ec28d1ba..4abccfd1da8 100644
--- 
a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
+++ 
b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
@@ -16,9 +16,10 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vm;
 
-import java.util.ArrayList;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.cloudstack.acl.RoleType;
 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.ZoneResponse;
 import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
 
 import com.cloud.exception.InvalidParameterValueException;
@@ -58,7 +60,6 @@ import com.cloud.vm.VirtualMachine;
 public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd 
implements UserCmd {
     public static final Logger s_logger = 
Logger.getLogger(ListVMsCmd.class.getName());
 
-    private static final String s_name = "listvirtualmachinesresponse";
 
     /////////////////////////////////////////////////////
     //////////////// API parameters /////////////////////
@@ -98,7 +99,8 @@ public class ListVMsCmd extends 
BaseListRetrieveOnlyResourceCountCmd implements
                collectionType = CommandType.STRING,
                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]."
-                   + " 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;
 
     @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;
     }
 
+    protected boolean isViewDetailsEmpty() {
+        return CollectionUtils.isEmpty(viewDetails);
+    }
+
     public EnumSet<VMDetails> getDetails() throws 
InvalidParameterValueException {
-        EnumSet<VMDetails> dv;
-        if (viewDetails == null || viewDetails.size() <= 0) {
-            dv = 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));
+        if (isViewDetailsEmpty()) {
+            if (_queryService.ReturnVmStatsOnVmList.value()) {
+                return EnumSet.of(VMDetails.all);
+            }
+
+            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
@@ -277,10 +289,6 @@ public class ListVMsCmd extends 
BaseListRetrieveOnlyResourceCountCmd implements
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
 
     @Override
     public ApiCommandResourceType getApiResourceType() {
diff --git 
a/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java 
b/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
index 5a0ea77a4e7..8deae7d80d3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
@@ -37,6 +37,7 @@ import com.cloud.serializer.Param;
 import com.cloud.uservm.UserVm;
 import com.cloud.vm.VirtualMachine;
 import com.google.gson.annotations.SerializedName;
+import org.apache.commons.collections.CollectionUtils;
 
 @SuppressWarnings("unused")
 @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")
     private String hypervisor;
 
+    @SerializedName(ApiConstants.IP_ADDRESS)
+    @Param(description = "the VM's primary IP address")
+    private String ipAddress;
+
     @SerializedName(ApiConstants.PUBLIC_IP_ID)
     @Param(description = "public IP address id associated with vm via Static 
nat rule")
     private String publicIpId;
@@ -627,6 +632,10 @@ public class UserVmResponse extends 
BaseResponseWithTagInformation implements Co
         return hypervisor;
     }
 
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
     public String getPublicIpId() {
         return publicIpId;
     }
@@ -863,6 +872,13 @@ public class UserVmResponse extends 
BaseResponseWithTagInformation implements Co
 
     public void setNics(Set<NicResponse> 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) {
diff --git a/api/src/main/java/org/apache/cloudstack/query/QueryService.java 
b/api/src/main/java/org/apache/cloudstack/query/QueryService.java
index 3299e7537a2..dd5aaf4e6d7 100644
--- a/api/src/main/java/org/apache/cloudstack/query/QueryService.java
+++ b/api/src/main/java/org/apache/cloudstack/query/QueryService.java
@@ -125,6 +125,10 @@ public interface QueryService {
     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);
 
+    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(Long domainId, boolean 
recursive) throws PermissionDeniedException;
diff --git 
a/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVMsMetricsCmd.java
 
b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVMsMetricsCmd.java
index 55af69e623c..f5b2ee5bda7 100644
--- 
a/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVMsMetricsCmd.java
+++ 
b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVMsMetricsCmd.java
@@ -17,10 +17,12 @@
 
 package org.apache.cloudstack.api;
 
+import java.util.EnumSet;
 import java.util.List;
 
 import javax.inject.Inject;
 
+import com.cloud.exception.InvalidParameterValueException;
 import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.command.user.UserCmd;
 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>
  * </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,
         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
     private MetricsService metricsService;
 
     @Override
-    public String getCommandName() {
-        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    public EnumSet<ApiConstants.VMDetails> getDetails() throws 
InvalidParameterValueException {
+        if (isViewDetailsEmpty()) {
+            return EnumSet.of(ApiConstants.VMDetails.all);
+        }
+
+        return super.getDetails();
     }
 
     @Override
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 136976cafc2..86bf2e3e351 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
@@ -619,7 +619,6 @@ public class MetricsServiceImpl extends 
MutualExclusiveIdsManagerBase implements
             }
 
             metricsResponse.setHasAnnotation(vmResponse.hasAnnotation());
-            metricsResponse.setIpAddress(vmResponse.getNics());
             metricsResponse.setCpuTotal(vmResponse.getCpuNumber(), 
vmResponse.getCpuSpeed());
             metricsResponse.setMemTotal(vmResponse.getMemory());
             metricsResponse.setNetworkRead(vmResponse.getNetworkKbsRead());
diff --git 
a/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java
 
b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java
index fb5e8e5e104..7e5db7939db 100644
--- 
a/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java
+++ 
b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java
@@ -17,19 +17,13 @@
 
 package org.apache.cloudstack.response;
 
-import java.util.Set;
-
 import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.response.NicResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 
 import com.cloud.serializer.Param;
 import com.google.gson.annotations.SerializedName;
 
 public class VmMetricsResponse extends UserVmResponse {
-    @SerializedName(ApiConstants.IP_ADDRESS)
-    @Param(description = "the VM's primary IP address")
-    private String ipAddress;
 
     @SerializedName("cputotal")
     @Param(description = "the total cpu capacity in Ghz")
@@ -59,11 +53,6 @@ public class VmMetricsResponse extends UserVmResponse {
     @Param(description = "the total disk iops")
     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) {
         if (cpuNumber != null && cpuSpeed != null) {
diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java 
b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
index 5248a5535a5..dc591e8f30c 100644
--- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
@@ -5686,6 +5686,6 @@ public class QueryManagerImpl extends 
MutualExclusiveIdsManagerBase implements Q
     @Override
     public ConfigKey<?>[] getConfigKeys() {
         return new ConfigKey<?>[] {AllowUserViewDestroyedVM, 
UserVMDeniedDetails, UserVMReadOnlyDetails, SortKeyAscending,
-                AllowUserViewAllDomainAccounts, 
SharePublicTemplatesWithOtherDomains};
+                AllowUserViewAllDomainAccounts, 
SharePublicTemplatesWithOtherDomains, ReturnVmStatsOnVmList};
     }
 }
diff --git a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java 
b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
index 623ba436d0e..934de8a2558 100644
--- a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
@@ -166,6 +166,7 @@ public class ViewResponseHelper {
                 // update nics, securitygroups, tags, affinitygroups for 1 to 
many mapping fields
                 userVmData = ApiDBUtils.fillVmDetails(view, userVmData, 
userVm);
             }
+            userVmData.setIpAddress(userVmData.getNics());
             vmDataList.put(userVm.getId(), userVmData);
         }
         return new ArrayList<UserVmResponse>(vmDataList.values());
diff --git a/ui/src/config/router.js b/ui/src/config/router.js
index c3b69bde23a..ef9ae6c1130 100644
--- a/ui/src/config/router.js
+++ b/ui/src/config/router.js
@@ -75,6 +75,7 @@ function generateRouterMap (section) {
           icon: child.icon,
           docHelp: vueProps.$applyDocHelpMappings(child.docHelp),
           permission: child.permission,
+          getApiToCall: child.getApiToCall,
           resourceType: child.resourceType,
           filters: child.filters,
           params: child.params ? child.params : {},
diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js
index 969402a694c..4893cfc1053 100644
--- a/ui/src/config/section/compute.js
+++ b/ui/src/config/section/compute.js
@@ -28,7 +28,8 @@ export default {
       title: 'label.instances',
       icon: 'cloud-server-outlined',
       docHelp: 'adminguide/virtual_machines.html',
-      permission: ['listVirtualMachinesMetrics'],
+      permission: ['listVirtualMachines', 'listVirtualMachinesMetrics'],
+      getApiToCall: () => store.getters.metrics ? 'listVirtualMachinesMetrics' 
: 'listVirtualMachines',
       resourceType: 'UserVm',
       params: () => {
         var params = { details: 'servoff,tmpl,iso,nics,backoff' }
diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue
index 6fa8a3e0848..f9c4edd36b0 100644
--- a/ui/src/views/AutogenView.vue
+++ b/ui/src/views/AutogenView.vue
@@ -819,7 +819,7 @@ export default {
       }
 
       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) {
           const columns = this.$route.meta.columns
           if (columns && typeof columns === 'function') {

Reply via email to