From fcbcddbcb96f18a5f4dc2d464ec1d91cb53360ea Mon Sep 17 00:00:00 2001 From: kishankavala Date: Wed, 19 Apr 2023 12:12:29 +0530 Subject: [PATCH 1/4] ui: Allow admin/user to filter by state for Pods, Clusters and Hosts (#7373) This PR allows admin/user to filter by state for Pods, Clusters and Hosts. This is part of #7366 . --- ui/public/locales/en.json | 4 ++++ ui/src/config/section/infra/clusters.js | 4 ++++ ui/src/config/section/infra/hosts.js | 4 ++++ ui/src/config/section/infra/pods.js | 4 ++++ ui/src/views/AutogenView.vue | 23 +++++++++++++++++++++-- 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 5bc585fa3f2..dd94644c6f8 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -722,6 +722,7 @@ "label.domainrouter": "Virtual Router", "label.domains": "Domains", "label.done": "Done", +"label.down": "Down", "label.download": "Download", "label.download.kubeconfig.cluster": "Download kubeconfig for the cluster

The kubectl command-line tool uses kubeconfig files to find the information it needs to choose a cluster and communicate with the API server of a cluster.", "label.download.kubectl": "Download kubectl tool for cluster's Kubernetes version", @@ -762,6 +763,7 @@ "label.egressdefaultpolicy": "Default egress policy", "label.elastic": "Elastic", "label.email": "Email", +"label.enabled": "Enabled", "label.enable.autoscale.vmgroup": "Enable AutoScale VM Group", "label.enable.host": "Enable Host", "label.enable.network.offering": "Enable network offering", @@ -1158,6 +1160,7 @@ "label.macaddresschanges": "MAC address changes", "label.maclearning": "MAC learning", "label.macos": "MacOS", +"label.maintenance": "Maintenance", "label.majorsequence": "Major Sequence", "label.make": "Make", "label.make.project.owner": "Make account project owner", @@ -2002,6 +2005,7 @@ "label.unmanaged.instance": "Unmanaged instance", "label.unmanaged.instances": "Unmanaged instances", "label.untagged": "Untagged", +"label.up": "Up", "label.updateinsequence": "Update in sequence", "label.update.autoscale.vmgroup": "Update AutoScale VM group", "label.update.condition": "Update condition", diff --git a/ui/src/config/section/infra/clusters.js b/ui/src/config/section/infra/clusters.js index 743c782a7a0..904938ca528 100644 --- a/ui/src/config/section/infra/clusters.js +++ b/ui/src/config/section/infra/clusters.js @@ -40,6 +40,10 @@ export default { param: 'clusterid' }], resourceType: 'Cluster', + filters: () => { + const filters = ['enabled', 'disabled'] + return filters + }, tabs: [{ name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) diff --git a/ui/src/config/section/infra/hosts.js b/ui/src/config/section/infra/hosts.js index 1ca0a99e617..9f2c6292052 100644 --- a/ui/src/config/section/infra/hosts.js +++ b/ui/src/config/section/infra/hosts.js @@ -24,6 +24,10 @@ export default { icon: 'desktop-outlined', permission: ['listHostsMetrics'], resourceType: 'Host', + filters: () => { + const filters = ['enabled', 'disabled', 'maintenance', 'up', 'down', 'alert'] + return filters + }, params: { type: 'routing' }, columns: () => { const fields = ['name', 'state', 'resourcestate', 'ipaddress', 'hypervisor', 'instances', 'powerstate'] diff --git a/ui/src/config/section/infra/pods.js b/ui/src/config/section/infra/pods.js index 70674ac7fbb..a462478f979 100644 --- a/ui/src/config/section/infra/pods.js +++ b/ui/src/config/section/infra/pods.js @@ -35,6 +35,10 @@ export default { param: 'podid' }], resourceType: 'Pod', + filters: () => { + const filters = ['enabled', 'disabled'] + return filters + }, tabs: [{ name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index 16cf14e04cb..4a8a909e794 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -54,7 +54,8 @@ v-if="!dataView && filters && filters.length > 0" :placeholder="$t('label.filterby')" :value="$route.query.filter || (projectView && $route.name === 'vm' || - ['Admin', 'DomainAdmin'].includes($store.getters.userInfo.roletype) && ['vm', 'iso', 'template'].includes($route.name) + ['Admin', 'DomainAdmin'].includes($store.getters.userInfo.roletype) && + ['vm', 'iso', 'template', 'pod', 'cluster', 'host'].includes($route.name) ? 'all' : ['publicip'].includes($route.name) ? 'allocated' : ['guestnetwork', 'guestvlans'].includes($route.name) ? 'all' : ['volume'].includes($route.name) @@ -68,7 +69,8 @@ }" > {{ $t('label.all') }} @@ -1573,6 +1575,23 @@ export default { } } else if (this.$route.name === 'publicip') { query.state = filter + } else if (['pod', 'cluster'].includes(this.$route.name)) { + if (filter === 'all') { + delete query.allocationstate + } else { + query.allocationstate = filter + } + } else if (['host'].includes(this.$route.name)) { + if (filter === 'all') { + delete query.resourcestate + delete query.state + } else if (['up', 'down', 'alert'].includes(filter)) { + delete query.resourcestate + query.state = filter + } else { + delete query.state + query.resourcestate = filter + } } else if (this.$route.name === 'vm') { if (filter === 'self') { query.account = this.$store.getters.userInfo.account From fb51504dff0ba6545b1bde722554924c3455d6ff Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 19 Apr 2023 08:44:53 +0200 Subject: [PATCH 2/4] server: dedicate vxlan range to account (#7215) This fixes #6871 --- .../main/java/com/cloud/network/NetworkServiceImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 2aca1f7c649..8f2d250f056 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -4048,12 +4048,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } vlanOwnerId = vlanOwner.getAccountId(); - // Verify physical network isolation type is VLAN + // Verify physical network isolation methods contain VLAN or VXLAN PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); if (physicalNetwork == null) { throw new InvalidParameterValueException("Unable to find physical network by id " + physicalNetworkId); - } else if (!physicalNetwork.getIsolationMethods().isEmpty() && !physicalNetwork.getIsolationMethods().contains("VLAN")) { - throw new InvalidParameterValueException("Cannot dedicate guest vlan range. " + "Physical isolation type of network " + physicalNetworkId + " is not VLAN"); + } else if (!physicalNetwork.getIsolationMethods().isEmpty() && + !physicalNetwork.getIsolationMethods().contains("VLAN") && + !physicalNetwork.getIsolationMethods().contains("VXLAN")) { + throw new InvalidParameterValueException("Cannot dedicate guest vlan range. " + "Physical isolation type of network " + physicalNetworkId + " is not VLAN nor VXLAN"); } // Get the start and end vlan From 79eae89a87e212a347e68e20678a95ecded0ed41 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Wed, 19 Apr 2023 12:22:24 +0530 Subject: [PATCH 3/4] ui: Add filtering by state in account, systemvms, router and storagepool (#7368) This PR allows admin to filter resources by state for systemvms, router & storagepool. This is part of #7366 . Co-authored-by: Abhishek Kumar Co-authored-by: Rohit Yadav --- .../java/com/cloud/storage/ScopeType.java | 15 ++++ .../com/cloud/storage/StoragePoolStatus.java | 15 ++++ .../admin/storage/ListStoragePoolsCmd.java | 9 +- .../com/cloud/api/query/QueryManagerImpl.java | 88 +++---------------- .../api/query/dao/StoragePoolJoinDao.java | 6 ++ .../api/query/dao/StoragePoolJoinDaoImpl.java | 75 ++++++++++++++++ ui/public/locales/en.json | 21 ++++- ui/src/config/section/account.js | 4 + .../config/section/infra/primaryStorages.js | 4 + ui/src/config/section/infra/routers.js | 4 + ui/src/config/section/infra/systemVms.js | 4 + ui/src/views/AutogenView.vue | 18 ++-- ui/src/views/dashboard/UsageDashboard.vue | 4 +- 13 files changed, 181 insertions(+), 86 deletions(-) diff --git a/api/src/main/java/com/cloud/storage/ScopeType.java b/api/src/main/java/com/cloud/storage/ScopeType.java index e20f525c5f8..a944ebae10c 100644 --- a/api/src/main/java/com/cloud/storage/ScopeType.java +++ b/api/src/main/java/com/cloud/storage/ScopeType.java @@ -18,6 +18,21 @@ */ package com.cloud.storage; +import com.cloud.exception.InvalidParameterValueException; +import org.apache.commons.lang3.EnumUtils; + public enum ScopeType { HOST, CLUSTER, ZONE, REGION, GLOBAL; + + public static ScopeType validateAndGetScopeType(String value) { + if (value == null) { + return null; + } else { + ScopeType scopeType = EnumUtils.getEnumIgnoreCase(ScopeType.class, value); + if (scopeType == null) { + throw new InvalidParameterValueException("Invalid scope type: " + value); + } + return scopeType; + } + } } diff --git a/api/src/main/java/com/cloud/storage/StoragePoolStatus.java b/api/src/main/java/com/cloud/storage/StoragePoolStatus.java index 778d3881e3e..3bfd829d2f7 100644 --- a/api/src/main/java/com/cloud/storage/StoragePoolStatus.java +++ b/api/src/main/java/com/cloud/storage/StoragePoolStatus.java @@ -16,6 +16,21 @@ // under the License. package com.cloud.storage; +import com.cloud.exception.InvalidParameterValueException; +import org.apache.commons.lang3.EnumUtils; + public enum StoragePoolStatus { Initial, Initialized, Creating, Attaching, Up, PrepareForMaintenance, ErrorInMaintenance, CancelMaintenance, Maintenance, Disabled, Removed; + + public static StoragePoolStatus validateAndGetStatus(String value) { + if (value == null) { + return null; + } else { + StoragePoolStatus status = EnumUtils.getEnumIgnoreCase(StoragePoolStatus.class, value); + if (status == null) { + throw new InvalidParameterValueException("Invalid status: " + value); + } + return status; + } + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java index ce1164000fc..209aaac279c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java @@ -66,6 +66,9 @@ public class ListStoragePoolsCmd extends BaseListCmd { @Parameter(name = ApiConstants.SCOPE, type = CommandType.STRING, entityType = StoragePoolResponse.class, description = "the ID of the storage pool") private String scope; + @Parameter(name = ApiConstants.STATUS, type = CommandType.STRING, description = "the status of the storage pool") + private String status; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -94,6 +97,10 @@ public class ListStoragePoolsCmd extends BaseListCmd { return zoneId; } + public String getStatus() { + return status; + } + public Long getId() { return id; } @@ -101,7 +108,7 @@ public class ListStoragePoolsCmd extends BaseListCmd { public void setId(Long id) { this.id = id; } -///////////////////////////////////////////////////// + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// 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 6fecd2c3c6d..0968af0e7c0 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -229,6 +229,7 @@ import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolTagVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; @@ -2603,89 +2604,26 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q } private Pair, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) { - ScopeType scopeType = null; - if (cmd.getScope() != null) { - try { - scopeType = Enum.valueOf(ScopeType.class, cmd.getScope().toUpperCase()); - } catch (Exception e) { - throw new InvalidParameterValueException("Invalid scope type: " + cmd.getScope()); - } - } + ScopeType scopeType = ScopeType.validateAndGetScopeType(cmd.getScope()); + StoragePoolStatus status = StoragePoolStatus.validateAndGetStatus(cmd.getStatus()); Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId()); - Object id = cmd.getId(); - Object name = cmd.getStoragePoolName(); - Object path = cmd.getPath(); - Object pod = cmd.getPodId(); - Object cluster = cmd.getClusterId(); - Object address = cmd.getIpAddress(); - Object keyword = cmd.getKeyword(); + Long id = cmd.getId(); + String name = cmd.getStoragePoolName(); + String path = cmd.getPath(); + Long pod = cmd.getPodId(); + Long cluster = cmd.getClusterId(); + String address = cmd.getIpAddress(); + String keyword = cmd.getKeyword(); Long startIndex = cmd.getStartIndex(); Long pageSize = cmd.getPageSizeVal(); Filter searchFilter = new Filter(StoragePoolJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize); - SearchBuilder sb = _poolJoinDao.createSearchBuilder(); - sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct - // ids - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); - sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); - sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ); - sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ); - sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ); - sb.and("parent", sb.entity().getParent(), Op.EQ); + // search & count Pool details by ids + Pair, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(id, name, zoneId, path, pod, + cluster, address, scopeType, status, keyword, searchFilter); - SearchCriteria sc = sb.create(); - - if (keyword != null) { - SearchCriteria ssc = _poolJoinDao.createSearchCriteria(); - ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - - sc.addAnd("name", SearchCriteria.Op.SC, ssc); - } - - if (id != null) { - sc.setParameters("id", id); - } - - if (name != null) { - sc.setParameters("name", name); - } - - if (path != null) { - sc.setParameters("path", path); - } - if (zoneId != null) { - sc.setParameters("dataCenterId", zoneId); - } - if (pod != null) { - SearchCriteria ssc = _poolJoinDao.createSearchCriteria(); - ssc.addOr("podId", Op.EQ, pod); - ssc.addOr("podId", Op.NULL); - - sc.addAnd("podId", SearchCriteria.Op.SC, ssc); - } - if (address != null) { - sc.setParameters("hostAddress", address); - } - if (cluster != null) { - SearchCriteria ssc = _poolJoinDao.createSearchCriteria(); - ssc.addOr("clusterId", Op.EQ, cluster); - ssc.addOr("clusterId", Op.NULL); - - sc.addAnd("clusterId", SearchCriteria.Op.SC, ssc); - } - if (scopeType != null) { - sc.setParameters("scope", scopeType.toString()); - } - sc.setParameters("parent", 0); - - // search Pool details by ids - Pair, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(sc, searchFilter); Integer count = uniquePoolPair.second(); if (count.intValue() == 0) { // empty result diff --git a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java index 55c028044f7..87659210ad7 100644 --- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java +++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java @@ -18,6 +18,10 @@ package com.cloud.api.query.dao; import java.util.List; +import com.cloud.storage.ScopeType; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Filter; import org.apache.cloudstack.api.response.StoragePoolResponse; import com.cloud.api.query.vo.StoragePoolJoinVO; @@ -38,4 +42,6 @@ public interface StoragePoolJoinDao extends GenericDao List searchByIds(Long... spIds); + Pair, Integer> searchAndCount(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword, Filter searchFilter); + } diff --git a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java index 28ba1f63fc6..527cc949ed1 100644 --- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java @@ -20,11 +20,15 @@ import com.cloud.api.ApiDBUtils; import com.cloud.api.query.vo.StoragePoolJoinVO; import com.cloud.capacity.CapacityManager; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StorageStats; import com.cloud.user.AccountManager; +import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -291,4 +295,75 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase, Integer> searchAndCount(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword, Filter searchFilter) { + SearchCriteria sc = createStoragePoolSearchCriteria(storagePoolId, storagePoolName, zoneId, path, podId, clusterId, address, scopeType, status, keyword); + return searchAndCount(sc, searchFilter); + } + + private SearchCriteria createStoragePoolSearchCriteria(Long storagePoolId, String storagePoolName, Long zoneId, String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status, String keyword) { + SearchBuilder sb = createSearchBuilder(); + sb.select(null, SearchCriteria.Func.DISTINCT, sb.entity().getId()); // select distinct + // ids + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); + sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ); + sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ); + sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ); + sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); + sb.and("parent", sb.entity().getParent(), SearchCriteria.Op.EQ); + + SearchCriteria sc = sb.create(); + + if (keyword != null) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (storagePoolId != null) { + sc.setParameters("id", storagePoolId); + } + + if (storagePoolName != null) { + sc.setParameters("name", storagePoolName); + } + + if (path != null) { + sc.setParameters("path", path); + } + if (zoneId != null) { + sc.setParameters("dataCenterId", zoneId); + } + if (podId != null) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addOr("podId", SearchCriteria.Op.EQ, podId); + ssc.addOr("podId", SearchCriteria.Op.NULL); + + sc.addAnd("podId", SearchCriteria.Op.SC, ssc); + } + if (address != null) { + sc.setParameters("hostAddress", address); + } + if (clusterId != null) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addOr("clusterId", SearchCriteria.Op.EQ, clusterId); + ssc.addOr("clusterId", SearchCriteria.Op.NULL); + + sc.addAnd("clusterId", SearchCriteria.Op.SC, ssc); + } + if (scopeType != null) { + sc.setParameters("scope", scopeType.toString()); + } + if (status != null) { + sc.setParameters("status", status.toString()); + } + sc.setParameters("parent", 0); + return sc; + } } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index dd94644c6f8..c026e5bb7f0 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -340,9 +340,9 @@ "label.associatednetworkid": "Associated network ID", "label.associatednetworkname": "Network name", "label.asyncbackup": "Async backup", +"label.attaching": "Attaching", "label.authentication.method": "Authentication Method", "label.authentication.sshkey": "System SSH Key", -"label.automigrate.volume": "Auto migrate volume to another storage pool if required", "label.autoscale": "AutoScale", "label.autoscalevmgroupname": "AutoScale VM Group", "label.author.email": "Author e-mail", @@ -402,6 +402,7 @@ "label.bypassvlanoverlapcheck": "Bypass VLAN id/range overlap", "label.cachemode": "Write-cache type", "label.cancel": "Cancel", +"label.cancelmaintenance": "Cancel maintenance", "label.capacity": "Capacity", "label.capacitybytes": "Capacity bytes", "label.capacityiops": "IOPS total", @@ -545,6 +546,7 @@ "label.create.user": "Create user", "label.create.vpn.connection": "Create VPN connection", "label.created": "Created", +"label.creating": "Creating", "label.creating.iprange": "Creating IP ranges", "label.credit": "Credit", "label.crosszones": "Cross zones", @@ -653,6 +655,7 @@ "label.destnetworkuuid": "Network", "label.destport": "Destination Ports", "label.destroy": "Destroy", +"label.destroyed": "Destroyed", "label.destroy.router": "Destroy router", "label.deststartport": "Destination Start Port", "label.desttaguuid": "Destination Tag", @@ -771,6 +774,7 @@ "label.enable.storage": "Enable storage pool", "label.enable.vpc.offering": "Enable VPC offering", "label.enable.vpn": "Enable remote access VPN", +"label.enabled": "Enabled", "label.encrypt": "Encrypt", "label.encryptroot": "Encrypt Root Disk", "label.end": "End", @@ -798,6 +802,7 @@ "label.error.setting": "Error setting", "label.error.something.went.wrong.please.correct.the.following": "Something went wrong; please correct the following", "label.error.upper": "ERROR", +"label.errorinmaintenance": "Error in maintenance", "label.espencryption": "ESP encryption", "label.esphash": "ESP hash", "label.esplifetime": "ESP lifetime (second)", @@ -957,6 +962,8 @@ "label.infrastructure": "Infrastructure", "label.ingress": "Ingress", "label.ingress.rule": "Ingress Rule", +"label.initial": "Inital", +"label.initialized": "Initalized", "label.insideportprofile": "Inside port profile", "label.installwizard.addzoneintro.title": "Let's add a zone", "label.installwizard.subtitle": "This guide will aid you in setting up your CloudStack™ installation", @@ -1147,6 +1154,7 @@ "label.local.storage.enabled.system.vms": "Enable local storage for system VMs", "label.localstorageenabled": "Enable local storage for user VMs", "label.localstorageenabledforsystemvm": "Enable local storage for system VMs", +"label.locked": "Locked", "label.login": "Login", "label.loginfo": "Log file information", "label.login.portal": "Portal login", @@ -1446,6 +1454,7 @@ "label.preferred": "Preferred", "label.prefix": "Prefix", "label.prefix.type": "Prefix type", +"label.prepareformaintenance": "Prepare for Maintenance", "label.presetup": "PreSetup", "label.prev": "Prev", "label.previous": "Previous", @@ -1591,6 +1600,7 @@ "label.remove.vmware.datacenter": "Remove VMware Datacenter", "label.remove.vpc": "Remove VPC", "label.remove.vpc.offering": "Remove VPC offering", +"label.removed": "Removed", "label.removing": "Removing", "label.replace.acl": "Replace ACL", "label.replace.acl.list": "Replace ACL list", @@ -1658,7 +1668,8 @@ "label.rules.file.import.description": "Click or drag rule definitions CSV file to import.", "label.rules.file.to.import": "Rule definitions CSV file to import", "label.run.proxy.locally": "Run proxy locally", -"label.running": "Running VMs", +"label.running": "Running", +"label.running.vms": "Running VMs", "label.s2scustomergatewayid": "Site to site customer gateway ID", "label.s2svpngatewayid": "Site to site VPN gateway ID", "label.s3.access.key": "Access key", @@ -1754,6 +1765,7 @@ "label.sharewith": "Share with", "label.showing": "Showing", "label.shrinkok": "Shrink OK", +"label.shutdown": "Shutdown", "label.shutdown.provider": "Shutdown provider", "label.simplified.chinese.keyboard": "Simplified Chinese keyboard", "label.site.to.site.vpn": "Site-to-site VPN", @@ -1822,6 +1834,7 @@ "label.start.rolling.maintenance": "Start rolling maintenance", "label.start.vm": "Start VM", "label.startdate": "By date (start)", +"label.starting": "Starting", "label.startip": "Start IP", "label.startipv4": "IPv4 start IP", "label.startipv6": "IPv6 start IP", @@ -1849,7 +1862,9 @@ "label.sticky.request-learn": "Request learn", "label.sticky.tablesize": "Table size", "label.stop": "Stop", -"label.stopped": "Stopped VMs", +"label.stopped": "Stopped", +"label.stopped.vms": "Stopped VMs", +"label.stopping": "Stopping", "label.storage": "Storage", "label.storage.migration.required": "Storage migration required", "label.storage.tags": "Storage tags", diff --git a/ui/src/config/section/account.js b/ui/src/config/section/account.js index 4de0cc6f5a4..21878c1fe36 100644 --- a/ui/src/config/section/account.js +++ b/ui/src/config/section/account.js @@ -31,6 +31,10 @@ export default { title: 'label.users', param: 'account' }], + filters: () => { + const filters = ['enabled', 'disabled', 'locked'] + return filters + }, tabs: [ { name: 'details', diff --git a/ui/src/config/section/infra/primaryStorages.js b/ui/src/config/section/infra/primaryStorages.js index ff5bb41be65..4537b993a06 100644 --- a/ui/src/config/section/infra/primaryStorages.js +++ b/ui/src/config/section/infra/primaryStorages.js @@ -41,6 +41,10 @@ export default { param: 'storageid' }], resourceType: 'PrimaryStorage', + filters: () => { + const filters = ['initial', 'initialized', 'creating', 'attaching', 'up', 'prepareformaintenance', 'errorinmaintenance', 'cancelmaintenance', 'maintenance', 'disabled', 'removed'] + return filters + }, tabs: [{ name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) diff --git a/ui/src/config/section/infra/routers.js b/ui/src/config/section/infra/routers.js index 6f24d6b7d82..9e45cb73246 100644 --- a/ui/src/config/section/infra/routers.js +++ b/ui/src/config/section/infra/routers.js @@ -33,6 +33,10 @@ export default { searchFilters: ['name', 'zoneid', 'podid', 'clusterid'], details: ['name', 'id', 'version', 'softwareversion', 'requiresupgrade', 'guestnetworkname', 'vpcname', 'publicip', 'guestipaddress', 'linklocalip', 'serviceofferingname', 'networkdomain', 'isredundantrouter', 'redundantstate', 'hostname', 'account', 'zonename', 'created', 'hostcontrolstate'], resourceType: 'VirtualRouter', + filters: () => { + const filters = ['starting', 'running', 'stopping', 'stopped', 'destroyed', 'expunging', 'migrating', 'error', 'unknown', 'shutdown'] + return filters + }, tabs: [{ name: 'details', component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue'))) diff --git a/ui/src/config/section/infra/systemVms.js b/ui/src/config/section/infra/systemVms.js index a649ef1c11a..e48b19cb5d4 100644 --- a/ui/src/config/section/infra/systemVms.js +++ b/ui/src/config/section/infra/systemVms.js @@ -27,6 +27,10 @@ export default { columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'hostname', 'zonename'], details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable', 'hostcontrolstate'], resourceType: 'SystemVm', + filters: () => { + const filters = ['starting', 'running', 'stopping', 'stopped', 'destroyed', 'expunging', 'migrating', 'error', 'unknown', 'shutdown'] + return filters + }, tabs: [ { name: 'details', diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index 4a8a909e794..3c49309bc02 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -55,9 +55,9 @@ :placeholder="$t('label.filterby')" :value="$route.query.filter || (projectView && $route.name === 'vm' || ['Admin', 'DomainAdmin'].includes($store.getters.userInfo.roletype) && - ['vm', 'iso', 'template', 'pod', 'cluster', 'host'].includes($route.name) + ['vm', 'iso', 'template', 'pod', 'cluster', 'host', 'systemvm', 'router', 'storagepool'].includes($route.name) ? 'all' : ['publicip'].includes($route.name) - ? 'allocated' : ['guestnetwork', 'guestvlans'].includes($route.name) + ? 'allocated' : ['account', 'guestnetwork', 'guestvlans'].includes($route.name) ? 'all' : ['volume'].includes($route.name) ? 'user' : 'self')" style="min-width: 120px; margin-left: 10px" @@ -70,7 +70,8 @@ {{ $t('label.all') }} @@ -1573,8 +1574,15 @@ export default { } else { query.networkfilter = filter } - } else if (this.$route.name === 'publicip') { - query.state = filter + } else if (['account', 'publicip', 'systemvm', 'router'].includes(this.$route.name)) { + if (filter !== 'all') { + query.state = filter + } + } else if (this.$route.name === 'storagepool') { + if (filter === 'all') { + delete query.status + } else { + query.status = filter } else if (['pod', 'cluster'].includes(this.$route.name)) { if (filter === 'all') { delete query.allocationstate diff --git a/ui/src/views/dashboard/UsageDashboard.vue b/ui/src/views/dashboard/UsageDashboard.vue index 77eb16ef496..4264a90f925 100644 --- a/ui/src/views/dashboard/UsageDashboard.vue +++ b/ui/src/views/dashboard/UsageDashboard.vue @@ -175,7 +175,7 @@ export default { count = json.listvirtualmachinesresponse.count } var tileColor = this.$config.theme['@dashboard-tile-runningvms-bg'] || '#dfe9cc' - this.stats.splice(0, 1, { name: this.$t('label.running'), count: count, icon: 'desktop-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'running', filter: 'running' } }) + this.stats.splice(0, 1, { name: this.$t('label.running.vms'), count: count, icon: 'desktop-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'running', filter: 'running' } }) }) api('listVirtualMachines', { state: 'Stopped', listall: true }).then(json => { var count = 0 @@ -183,7 +183,7 @@ export default { count = json.listvirtualmachinesresponse.count } var tileColor = this.$config.theme['@dashboard-tile-stoppedvms-bg'] || '#edcbce' - this.stats.splice(1, 1, { name: this.$t('label.stopped'), count: count, icon: 'poweroff-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'stopped', filter: 'stopped' } }) + this.stats.splice(1, 1, { name: this.$t('label.stopped.vms'), count: count, icon: 'poweroff-outlined', bgcolor: tileColor, path: '/vm', query: { state: 'stopped', filter: 'stopped' } }) }) api('listVirtualMachines', { listall: true }).then(json => { var count = 0 From a5676b0d01340b797c581ebea37929e86e130770 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 19 Apr 2023 12:47:20 +0530 Subject: [PATCH 4/4] ui: syntax fix for build failure Signed-off-by: Abhishek Kumar --- ui/src/views/AutogenView.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index 3c49309bc02..cf552e2ede4 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -1583,6 +1583,7 @@ export default { delete query.status } else { query.status = filter + } } else if (['pod', 'cluster'].includes(this.$route.name)) { if (filter === 'all') { delete query.allocationstate