From a53c51d9bfd18d2736be54514e96cd3b0adbe7cb Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 18:05:01 +0530 Subject: [PATCH 01/20] Show site to site VPN connections in UI --- ui/src/config/section/network.js | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js index 3d5241feb590..093cd057e1bf 100644 --- a/ui/src/config/section/network.js +++ b/ui/src/config/section/network.js @@ -921,7 +921,6 @@ export default { name: 's2svpn', title: 'label.site.to.site.vpn', icon: 'lock-outlined', - hidden: true, permission: ['listVpnGateways'], columns: ['publicip', 'account', 'domain'], details: ['publicip', 'account', 'domain'], From 677682604ad631ef48967071403a06b8f6861f4f Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 22:48:54 +0530 Subject: [PATCH 02/20] Add search filter for Kubernetes --- ui/public/locales/en.json | 4 ++ ui/src/components/view/SearchView.vue | 84 ++++++++++++++++++++++++++- ui/src/config/section/compute.js | 1 + 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 1f6a2057c49b..1c3bd7883846 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -708,6 +708,7 @@ "label.destnetworkuuid": "Network", "label.destport": "Destination Ports", "label.destroy": "Destroy", +"label.destroying": "Destroying", "label.destroyed": "Destroyed", "label.destroy.router": "Destroy router", "label.deststartport": "Destination Start Port", @@ -1682,6 +1683,7 @@ "label.reboot": "Reboot", "label.receivedbytes": "Bytes received", "label.recover.vm": "Recover Instance", +"label.recovering": "Recovering", "label.redirect": "Redirect to:", "label.redirecturi": "Redirect URI", "label.redundantrouter": "Redundant router", @@ -1824,6 +1826,7 @@ "label.scaledown.policy": "ScaleDown policy", "label.scaleup.policies": "ScaleUp policies", "label.scaleup.policy": "ScaleUp policy", +"label.scaling": "Scaling", "label.schedule": "Schedule", "label.schedule.add": "Add schedule", "label.scheduled.backups": "Scheduled backups", @@ -2188,6 +2191,7 @@ "label.update.vmware.datacenter": "Update VMWare datacenter", "label.updating": "Updating", "label.upgrade.router.newer.template": "Upgrade router to use newer Template", +"label.upgrading": "Upgrading", "label.upload": "Upload", "label.upload.description": "Path to upload objects at", "label.upload.path": "Upload path", diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 7a2154ad4263..b6df0826f226 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -79,7 +79,7 @@ - + @@ -268,6 +268,9 @@ export default { if (item === 'domainid' && !('listDomains' in this.$store.getters.apis)) { return true } + if (item === 'account' && !('listAccounts' in this.$store.getters.apis)) { + return true + } if (item === 'account' && !('addAccountToProject' in this.$store.getters.apis || 'createAccount' in this.$store.getters.apis)) { return true } @@ -280,7 +283,7 @@ export default { if (item === 'groupid' && !('listInstanceGroups' in this.$store.getters.apis)) { return true } - if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'type'].includes(item)) { + if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'type'].includes(item)) { type = 'list' } else if (item === 'tags') { type = 'tag' @@ -351,6 +354,7 @@ export default { let typeIndex = -1 let zoneIndex = -1 let domainIndex = -1 + let accountIndex = -1 let imageStoreIndex = -1 let storageIndex = -1 let podIndex = -1 @@ -377,6 +381,12 @@ export default { promises.push(await this.fetchDomains(searchKeyword)) } + if (arrayField.includes('account')) { + accountIndex = this.fields.findIndex(item => item.name === 'account') + this.fields[accountIndex].loading = true + promises.push(await this.fetchAccounts(searchKeyword)) + } + if (arrayField.includes('imagestoreid')) { imageStoreIndex = this.fields.findIndex(item => item.name === 'imagestoreid') this.fields[imageStoreIndex].loading = true @@ -426,6 +436,12 @@ export default { this.fields[domainIndex].opts = this.sortArray(domain[0].data, 'path') } } + if (accountIndex > -1) { + const account = response.filter(item => item.type === 'account') + if (account && account.length > 0) { + this.fields[accountIndex].opts = this.sortArray(account[0].data, 'name') + } + } if (imageStoreIndex > -1) { const imageStore = response.filter(item => item.type === 'imagestoreid') if (imageStore && imageStore.length > 0) { @@ -539,6 +555,19 @@ export default { }) }) }, + fetchAccounts (searchKeyword) { + return new Promise((resolve, reject) => { + api('listAccounts', { listAll: true, showicon: true, keyword: searchKeyword }).then(json => { + const account = json.listaccountsresponse.account + resolve({ + type: 'account', + data: account + }) + }).catch(error => { + reject(error.response.headers['x-description']) + }) + }) + }, fetchImageStores (searchKeyword) { return new Promise((resolve, reject) => { api('listImageStores', { listAll: true, showicon: true, keyword: searchKeyword }).then(json => { @@ -673,6 +702,57 @@ export default { name: 'label.migrating' } ] + } else if (this.apiName.includes('listKubernetesClusters')) { + return [ + { + id: 'Created', + name: 'label.created' + }, + { + id: 'Starting', + name: 'label.starting' + }, + { + id: 'Running', + name: 'label.running' + }, + { + id: 'Stopping', + name: 'label.stopping' + }, + { + id: 'Stopped', + name: 'label.stopped' + }, + { + id: 'Scaling', + name: 'label.scaling' + }, + { + id: 'Upgrading', + name: 'label.upgrading' + }, + { + id: 'Alert', + name: 'label.alert' + }, + { + id: 'Recovering', + name: 'label.recovering' + }, + { + id: 'Destroyed', + name: 'label.destroyed' + }, + { + id: 'Destroying', + name: 'label.destroying' + }, + { + id: 'Error', + name: 'label.error' + } + ] } return [] }, diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index ba3a21e15397..5d0e1a6e557b 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -520,6 +520,7 @@ export default { title: 'label.kubernetes', icon: ['fa-solid', 'fa-dharmachakra'], docHelp: 'plugins/cloudstack-kubernetes-service.html', + searchFilters: ['name', 'domainid', 'account', 'state'], permission: ['listKubernetesClusters'], columns: (store) => { var fields = ['name', 'state', 'clustertype', 'size', 'cpunumber', 'memory', 'kubernetesversionname'] From bab4e7381c4f341d3dfa5c67c003ba0abbe4e5f9 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 22:58:46 +0530 Subject: [PATCH 03/20] Add search filter for Autoscale Instance Groups --- ui/src/config/section/compute.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index 5d0e1a6e557b..b282f4f8241e 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -630,6 +630,7 @@ export default { docHelp: 'adminguide/autoscale_with_virtual_router.html', resourceType: 'AutoScaleVmGroup', permission: ['listAutoScaleVmGroups'], + searchFilters: ['name', 'domainid', 'account', 'zoneid'], columns: (store) => { var fields = ['name', 'state', 'associatednetworkname', 'publicip', 'publicport', 'privateport', 'minmembers', 'maxmembers', 'availablevirtualmachinecount', 'account'] if (store.listAllProjects) { From 59a66db3771b384b5f90417d4e0988dc2223226f Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 22:59:28 +0530 Subject: [PATCH 04/20] Add search filter for Instance Groups --- ui/src/config/section/compute.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index b282f4f8241e..c8503f77a74d 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -741,7 +741,7 @@ export default { docHelp: 'adminguide/virtual_machines.html#changing-the-vm-name-os-or-group', resourceType: 'VMInstanceGroup', permission: ['listInstanceGroups'], - + searchFilters: ['name', 'domainid', 'account', 'zoneid'], columns: (store) => { var fields = ['name', 'account'] if (store.listAllProjects) { From 2a6401369aabcdd67f878feef697b7747838037b Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:01:04 +0530 Subject: [PATCH 05/20] Add search filter for SSH Key Pairs --- ui/src/config/section/compute.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index c8503f77a74d..951fcfbab3ee 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -799,6 +799,7 @@ export default { icon: 'key-outlined', docHelp: 'adminguide/virtual_machines.html#using-ssh-keys-for-authentication', permission: ['listSSHKeyPairs'], + searchFilters: ['name', 'domainid', 'account', 'fingerprint'], columns: () => { var fields = ['name', 'fingerprint'] if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) { From d478562d6fb303c863051868436ef357516ae5f7 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:19:52 +0530 Subject: [PATCH 06/20] Add search filter for Affinity Groups --- ui/src/components/view/SearchView.vue | 39 +++++++++++++++++++++++++++ ui/src/config/section/compute.js | 1 + 2 files changed, 40 insertions(+) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index b6df0826f226..4fd616686cc2 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -366,6 +366,10 @@ export default { typeIndex = this.fields.findIndex(item => item.name === 'type') this.fields[typeIndex].loading = true promises.push(await this.fetchAlertTypes()) + } else if (this.$route.path === '/affinitygroup') { + typeIndex = this.fields.findIndex(item => item.name === 'type') + this.fields[typeIndex].loading = true + promises.push(await this.fetchAffinityGroupTypes()) } } @@ -656,6 +660,41 @@ export default { }) } }, + fetchAffinityGroupTypes () { + if (this.alertTypes.length > 0) { + return new Promise((resolve, reject) => { + resolve({ + type: 'type', + data: this.alertTypes + }) + }) + } else { + return new Promise((resolve, reject) => { + api('listAffinityGroupTypes').then(json => { + const alerttypes = json.listaffinitygrouptypesresponse.affinityGroupType.map(a => { + let name = a.type + if (a.type === 'host anti-affinity') { + name = 'host anti-affinity (Strict)' + } else if (a.type === 'host affinity') { + name = 'host affinity (Strict)' + } else if (a.type === 'non-strict host anti-affinity') { + name = 'host anti-affinity (Non-Strict)' + } else if (a.type === 'non-strict host affinity') { + name = 'host affinity (Non-Strict)' + } + return { id: a.type, name: name } + }) + this.alertTypes = alerttypes + resolve({ + type: 'type', + data: alerttypes + }) + }).catch(error => { + reject(error.response.headers['x-description']) + }) + }) + } + }, fetchGuestNetworkTypes () { const types = [] if (this.apiName.indexOf('listNetworks') > -1) { diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index 951fcfbab3ee..b1bcdc866d57 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -960,6 +960,7 @@ export default { icon: 'swap-outlined', docHelp: 'adminguide/virtual_machines.html#affinity-groups', permission: ['listAffinityGroups'], + searchFilters: ['name', 'domainid', 'account', 'zoneid', 'type'], columns: () => { var fields = ['name', 'type', 'description'] if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) { From 68e659f28393e3bb27544e1822c9a66bcc3e8270 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:26:51 +0530 Subject: [PATCH 07/20] Add search filter for Public IP addresses --- ui/src/config/section/compute.js | 6 +++--- ui/src/config/section/network.js | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index b1bcdc866d57..969402a694cd 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -630,7 +630,7 @@ export default { docHelp: 'adminguide/autoscale_with_virtual_router.html', resourceType: 'AutoScaleVmGroup', permission: ['listAutoScaleVmGroups'], - searchFilters: ['name', 'domainid', 'account', 'zoneid'], + searchFilters: ['name', 'zoneid', 'domainid', 'account'], columns: (store) => { var fields = ['name', 'state', 'associatednetworkname', 'publicip', 'publicport', 'privateport', 'minmembers', 'maxmembers', 'availablevirtualmachinecount', 'account'] if (store.listAllProjects) { @@ -741,7 +741,7 @@ export default { docHelp: 'adminguide/virtual_machines.html#changing-the-vm-name-os-or-group', resourceType: 'VMInstanceGroup', permission: ['listInstanceGroups'], - searchFilters: ['name', 'domainid', 'account', 'zoneid'], + searchFilters: ['name', 'zoneid', 'domainid', 'account'], columns: (store) => { var fields = ['name', 'account'] if (store.listAllProjects) { @@ -960,7 +960,7 @@ export default { icon: 'swap-outlined', docHelp: 'adminguide/virtual_machines.html#affinity-groups', permission: ['listAffinityGroups'], - searchFilters: ['name', 'domainid', 'account', 'zoneid', 'type'], + searchFilters: ['name', 'zoneid', 'domainid', 'account', 'type'], columns: () => { var fields = ['name', 'type', 'description'] if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) { diff --git a/ui/src/config/section/network.js b/ui/src/config/section/network.js index 093cd057e1bf..65abdd6bec84 100644 --- a/ui/src/config/section/network.js +++ b/ui/src/config/section/network.js @@ -748,6 +748,7 @@ export default { icon: 'environment-outlined', docHelp: 'adminguide/networking_and_traffic.html#reserving-public-ip-addresses-and-vlans-for-accounts', permission: ['listPublicIpAddresses'], + searchFilters: ['ipaddress', 'zoneid', 'account', 'domainid', 'vlanid', 'tags'], resourceType: 'PublicIpAddress', columns: () => { var fields = ['ipaddress', 'state', 'associatednetworkname', 'vpcname', 'virtualmachinename', 'allocated', 'account'] From b764d4aeaa282833560f36273bf9b4626de86f88 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:29:42 +0530 Subject: [PATCH 08/20] Add search filter for Kubernetes ISOs --- ui/public/locales/en.json | 1 + ui/src/config/section/image.js | 1 + 2 files changed, 2 insertions(+) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 1c3bd7883846..0f9a066f6cee 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1344,6 +1344,7 @@ "label.min_balance": "Min balance", "label.mincpunumber": "Min CPU cores", "label.minimum": "Minimum", +"label.minimumsemanticversion": "Minimum semantic version", "label.miniops": "Min IOPS", "label.minmaxiops": "Min IOPS / Max IOPS", "label.minmembers": "Min members", diff --git a/ui/src/config/section/image.js b/ui/src/config/section/image.js index 7a5d52d1b898..3efcfff4a565 100644 --- a/ui/src/config/section/image.js +++ b/ui/src/config/section/image.js @@ -367,6 +367,7 @@ export default { icon: ['fa-solid', 'fa-dharmachakra'], docHelp: 'plugins/cloudstack-kubernetes-service.html#kubernetes-supported-versions', permission: ['listKubernetesSupportedVersions'], + searchFilters: ['zoneid', 'minimumsemanticversion'], columns: ['name', 'state', 'semanticversion', 'isostate', 'mincpunumber', 'minmemory', 'zonename'], details: ['name', 'semanticversion', 'supportsautoscaling', 'zoneid', 'zonename', 'isoid', 'isoname', 'isostate', 'mincpunumber', 'minmemory', 'supportsha', 'state', 'created'], actions: [ From 58ac037154debae87481a0b8ab7fab8bd48d25a0 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:35:03 +0530 Subject: [PATCH 09/20] Add search filter for Roles --- ui/src/components/view/SearchView.vue | 27 +++++++++++++++++++++++++++ ui/src/config/section/role.js | 1 + 2 files changed, 28 insertions(+) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 4fd616686cc2..36478b01711e 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -308,6 +308,11 @@ export default { this.fields[typeIndex].loading = true this.fields[typeIndex].opts = this.fetchGuestNetworkTypes() this.fields[typeIndex].loading = false + } else if (this.$route.path === '/role' || this.$route.path.includes('/role/')) { + const typeIndex = this.fields.findIndex(item => item.name === 'type') + this.fields[typeIndex].loading = true + this.fields[typeIndex].opts = this.fetchRoleTypes() + this.fields[typeIndex].loading = false } } @@ -713,6 +718,28 @@ export default { } return types }, + fetchRoleTypes () { + const types = [] + if (this.apiName.indexOf('listRoles') > -1) { + types.push({ + id: 'Admin', + name: 'Admin' + }) + types.push({ + id: 'ResourceAdmin', + name: 'ResourceAdmin' + }) + types.push({ + id: 'DomainAdmin', + name: 'DomainAdmin' + }) + types.push({ + id: 'User', + name: 'User' + }) + } + return types + }, fetchState () { if (this.apiName.includes('listVolumes')) { return [ diff --git a/ui/src/config/section/role.js b/ui/src/config/section/role.js index 3823d633b186..c842b2f68f16 100644 --- a/ui/src/config/section/role.js +++ b/ui/src/config/section/role.js @@ -24,6 +24,7 @@ export default { icon: 'idcard-outlined', docHelp: 'adminguide/accounts.html#roles', permission: ['listRoles', 'listRolePermissions'], + searchFilters: ['name', 'type'], columns: ['name', 'type', 'description'], details: ['name', 'id', 'type', 'description', 'ispublic'], tabs: [{ From 9a2e6e820623403bf4a6888e1aacabb93aa93254 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:47:57 +0530 Subject: [PATCH 10/20] Add search filter for Accounts --- ui/src/components/view/SearchView.vue | 29 +++++++++++++++++++++++++-- ui/src/config/section/account.js | 1 + 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 36478b01711e..b42c4c947dc7 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -79,7 +79,7 @@ - + @@ -283,7 +283,7 @@ export default { if (item === 'groupid' && !('listInstanceGroups' in this.$store.getters.apis)) { return true } - if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'type'].includes(item)) { + if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'type'].includes(item)) { type = 'list' } else if (item === 'tags') { type = 'tag' @@ -337,6 +337,13 @@ export default { this.fields[entityTypeIndex].loading = false } + if (arrayField.includes('accounttype')) { + const accountTypeIndex = this.fields.findIndex(item => item.name === 'accounttype') + this.fields[accountTypeIndex].loading = true + this.fields[accountTypeIndex].opts = this.fetchAccountTypes() + this.fields[accountTypeIndex].loading = false + } + if (arrayField.includes('resourcetype')) { const resourceTypeIndex = this.fields.findIndex(item => item.name === 'resourcetype') this.fields[resourceTypeIndex].loading = true @@ -718,6 +725,24 @@ export default { } return types }, + fetchAccountTypes () { + const types = [] + if (this.apiName.indexOf('listAccounts') > -1) { + types.push({ + id: '1', + name: 'Admin' + }) + types.push({ + id: '2', + name: 'DomainAdmin' + }) + types.push({ + id: '3', + name: 'User' + }) + } + return types + }, fetchRoleTypes () { const types = [] if (this.apiName.indexOf('listRoles') > -1) { diff --git a/ui/src/config/section/account.js b/ui/src/config/section/account.js index 92897a33b126..a35b2b9d5f0d 100644 --- a/ui/src/config/section/account.js +++ b/ui/src/config/section/account.js @@ -24,6 +24,7 @@ export default { icon: 'team-outlined', docHelp: 'adminguide/accounts.html', permission: ['listAccounts'], + searchFilters: ['name', 'accounttype', 'domainid'], columns: ['name', 'state', 'rolename', 'roletype', 'domainpath'], details: ['name', 'id', 'rolename', 'roletype', 'domainpath', 'networkdomain', 'iptotal', 'vmtotal', 'volumetotal', 'receivedbytes', 'sentbytes', 'created'], related: [{ From c2bdc34b17d61a26c18481a639773921276a6ff6 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:50:16 +0530 Subject: [PATCH 11/20] Add search filter for Zone --- ui/src/config/section/infra/zones.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/config/section/infra/zones.js b/ui/src/config/section/infra/zones.js index b2768f773432..929add5210d0 100644 --- a/ui/src/config/section/infra/zones.js +++ b/ui/src/config/section/infra/zones.js @@ -24,6 +24,7 @@ export default { icon: 'global-outlined', docHelp: 'conceptsandterminology/concepts.html#about-zones', permission: ['listZonesMetrics'], + searchFilters: ['name', 'domainid', 'tags'], columns: () => { const fields = ['name', 'allocationstate', 'type', 'networktype', 'clusters'] const metricsFields = ['cpuused', 'cpumaxdeviation', 'cpuallocated', 'cputotal', 'memoryused', 'memorymaxdeviation', 'memoryallocated', 'memorytotal'] From e03e9cf1e06ca2ba73d7b13db12d0a5d7fe34e62 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Thu, 9 May 2024 23:54:44 +0530 Subject: [PATCH 12/20] Add search filter for Pods --- ui/src/config/section/infra/pods.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/config/section/infra/pods.js b/ui/src/config/section/infra/pods.js index eff62e0a4a28..a405ad1bffe0 100644 --- a/ui/src/config/section/infra/pods.js +++ b/ui/src/config/section/infra/pods.js @@ -24,6 +24,7 @@ export default { icon: 'appstore-outlined', docHelp: 'conceptsandterminology/concepts.html#about-pods', permission: ['listPods'], + searchFilters: ['name', 'zoneid', 'tags'], columns: ['name', 'allocationstate', 'gateway', 'netmask', 'zonename'], details: ['name', 'id', 'allocationstate', 'netmask', 'gateway', 'zonename'], related: [{ From df57864a60aa71e6a46d3a945ff0ba7f51c21b47 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 00:04:38 +0530 Subject: [PATCH 13/20] Add search filter for Clusters --- ui/src/components/view/SearchView.vue | 28 ++++++++++++++++++++++++- ui/src/config/section/infra/clusters.js | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index b42c4c947dc7..acac1b76e366 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -283,7 +283,7 @@ export default { if (item === 'groupid' && !('listInstanceGroups' in this.$store.getters.apis)) { return true } - if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'type'].includes(item)) { + if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'type'].includes(item)) { type = 'list' } else if (item === 'tags') { type = 'tag' @@ -367,6 +367,7 @@ export default { let zoneIndex = -1 let domainIndex = -1 let accountIndex = -1 + let hypervisorIndex = -1 let imageStoreIndex = -1 let storageIndex = -1 let podIndex = -1 @@ -403,6 +404,12 @@ export default { promises.push(await this.fetchAccounts(searchKeyword)) } + if (arrayField.includes('hypervisor')) { + hypervisorIndex = this.fields.findIndex(item => item.name === 'hypervisor') + this.fields[hypervisorIndex].loading = true + promises.push(await this.fetchHypervisors()) + } + if (arrayField.includes('imagestoreid')) { imageStoreIndex = this.fields.findIndex(item => item.name === 'imagestoreid') this.fields[imageStoreIndex].loading = true @@ -458,6 +465,12 @@ export default { this.fields[accountIndex].opts = this.sortArray(account[0].data, 'name') } } + if (hypervisorIndex > -1) { + const hypervisor = response.filter(item => item.type === 'hypervisor') + if (hypervisor && hypervisor.length > 0) { + this.fields[hypervisorIndex].opts = this.sortArray(hypervisor[0].data, 'name') + } + } if (imageStoreIndex > -1) { const imageStore = response.filter(item => item.type === 'imagestoreid') if (imageStore && imageStore.length > 0) { @@ -584,6 +597,19 @@ export default { }) }) }, + fetchHypervisors () { + return new Promise((resolve, reject) => { + api('listHypervisors').then(json => { + const hypervisor = json.listhypervisorsresponse.hypervisor.map(a => { return { id: a.name, name: a.name } }) + resolve({ + type: 'hypervisor', + data: hypervisor + }) + }).catch(error => { + reject(error.response.headers['x-description']) + }) + }) + }, fetchImageStores (searchKeyword) { return new Promise((resolve, reject) => { api('listImageStores', { listAll: true, showicon: true, keyword: searchKeyword }).then(json => { diff --git a/ui/src/config/section/infra/clusters.js b/ui/src/config/section/infra/clusters.js index ab8bea6b79d4..15c9f31ab8d5 100644 --- a/ui/src/config/section/infra/clusters.js +++ b/ui/src/config/section/infra/clusters.js @@ -24,6 +24,7 @@ export default { icon: 'cluster-outlined', docHelp: 'conceptsandterminology/concepts.html#about-clusters', permission: ['listClustersMetrics'], + searchFilters: ['name', 'zoneid', 'podid', 'hypervisor', 'tags'], columns: () => { const fields = ['name', 'state', 'allocationstate', 'clustertype', 'hypervisortype', 'hosts'] const metricsFields = ['cpuused', 'cpumaxdeviation', 'cpuallocated', 'cputotal', 'memoryused', 'memorymaxdeviation', 'memoryallocated', 'memorytotal', 'drsimbalance'] From b787ec5dacafe6af2707b009053fc55d0603c0d4 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 00:08:13 +0530 Subject: [PATCH 14/20] Add search filter for Hosts --- ui/src/config/section/infra/clusters.js | 2 +- ui/src/config/section/infra/hosts.js | 1 + ui/src/config/section/infra/pods.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/src/config/section/infra/clusters.js b/ui/src/config/section/infra/clusters.js index 15c9f31ab8d5..8b2f37d5b7bb 100644 --- a/ui/src/config/section/infra/clusters.js +++ b/ui/src/config/section/infra/clusters.js @@ -24,7 +24,7 @@ export default { icon: 'cluster-outlined', docHelp: 'conceptsandterminology/concepts.html#about-clusters', permission: ['listClustersMetrics'], - searchFilters: ['name', 'zoneid', 'podid', 'hypervisor', 'tags'], + searchFilters: ['name', 'zoneid', 'podid', 'hypervisor'], columns: () => { const fields = ['name', 'state', 'allocationstate', 'clustertype', 'hypervisortype', 'hosts'] const metricsFields = ['cpuused', 'cpumaxdeviation', 'cpuallocated', 'cputotal', 'memoryused', 'memorymaxdeviation', 'memoryallocated', 'memorytotal', 'drsimbalance'] diff --git a/ui/src/config/section/infra/hosts.js b/ui/src/config/section/infra/hosts.js index d92f4af21e6e..329b77fe2d7f 100644 --- a/ui/src/config/section/infra/hosts.js +++ b/ui/src/config/section/infra/hosts.js @@ -24,6 +24,7 @@ export default { icon: 'database-outlined', docHelp: 'conceptsandterminology/concepts.html#about-hosts', permission: ['listHostsMetrics'], + searchFilters: ['name', 'zoneid', 'podid', 'clusterid', 'hypervisor'], resourceType: 'Host', filters: () => { const filters = ['enabled', 'disabled', 'maintenance', 'up', 'down', 'alert'] diff --git a/ui/src/config/section/infra/pods.js b/ui/src/config/section/infra/pods.js index a405ad1bffe0..595b35f4fb99 100644 --- a/ui/src/config/section/infra/pods.js +++ b/ui/src/config/section/infra/pods.js @@ -24,7 +24,7 @@ export default { icon: 'appstore-outlined', docHelp: 'conceptsandterminology/concepts.html#about-pods', permission: ['listPods'], - searchFilters: ['name', 'zoneid', 'tags'], + searchFilters: ['name', 'zoneid'], columns: ['name', 'allocationstate', 'gateway', 'netmask', 'zonename'], details: ['name', 'id', 'allocationstate', 'netmask', 'gateway', 'zonename'], related: [{ From 56387b7b3bc00d065e2385004e89b65821351c01 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 00:19:56 +0530 Subject: [PATCH 15/20] Add search filter for Storage Pools --- ui/public/locales/en.json | 1 + ui/src/components/view/SearchView.vue | 35 ++++++++++++++++++- .../config/section/infra/primaryStorages.js | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 0f9a066f6cee..89abfe5981fa 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -932,6 +932,7 @@ "label.fwdeviceid": "ID", "label.fwdevicestate": "Status", "label.gateway": "Gateway", +"label.global": "Global", "label.global.settings": "Global Settings", "label.globo.dns": "GloboDNS", "label.globo.dns.configuration": "GloboDNS configuration", diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index acac1b76e366..2ae616c7929c 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -283,7 +283,7 @@ export default { if (item === 'groupid' && !('listInstanceGroups' in this.$store.getters.apis)) { return true } - if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'type'].includes(item)) { + if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'scope', 'type'].includes(item)) { type = 'list' } else if (item === 'tags') { type = 'tag' @@ -344,6 +344,13 @@ export default { this.fields[accountTypeIndex].loading = false } + if (arrayField.includes('scope')) { + const scopeIndex = this.fields.findIndex(item => item.name === 'scope') + this.fields[scopeIndex].loading = true + this.fields[scopeIndex].opts = this.fetchStoragePoolScope() + this.fields[scopeIndex].loading = false + } + if (arrayField.includes('resourcetype')) { const resourceTypeIndex = this.fields.findIndex(item => item.name === 'resourcetype') this.fields[resourceTypeIndex].loading = true @@ -769,6 +776,32 @@ export default { } return types }, + fetchStoragePoolScope () { + const types = [] + if (this.apiName.indexOf('listStoragePools') > -1) { + types.push({ + id: 'HOST', + name: 'label.hostname' + }) + types.push({ + id: 'CLUSTER', + name: 'label.cluster' + }) + types.push({ + id: 'ZONE', + name: 'label.zone' + }) + types.push({ + id: 'REGION', + name: 'label.region' + }) + types.push({ + id: 'GLOBAL', + name: 'label.global' + }) + } + return types + }, fetchRoleTypes () { const types = [] if (this.apiName.indexOf('listRoles') > -1) { diff --git a/ui/src/config/section/infra/primaryStorages.js b/ui/src/config/section/infra/primaryStorages.js index f222edeaf70b..74624b3e8887 100644 --- a/ui/src/config/section/infra/primaryStorages.js +++ b/ui/src/config/section/infra/primaryStorages.js @@ -24,6 +24,7 @@ export default { icon: 'hdd-outlined', docHelp: 'adminguide/storage.html#primary-storage', permission: ['listStoragePoolsMetrics'], + searchFilters: ['name', 'zoneid', 'podid', 'clusterid', 'ipaddress', 'path', 'scope'], columns: () => { const fields = ['name', 'state', 'ipaddress', 'scope', 'type', 'path'] const metricsFields = ['disksizeusedgb', 'disksizetotalgb', 'disksizeallocatedgb', 'disksizeunallocatedgb'] From d5cd710cea756cc482dad0dd1cb398fab4bb41e9 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 00:30:12 +0530 Subject: [PATCH 16/20] Add search filter for Image Stores --- ui/src/components/view/SearchView.vue | 31 ++++++++++++++++++- .../config/section/infra/secondaryStorages.js | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 2ae616c7929c..45705512e11e 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -283,7 +283,7 @@ export default { if (item === 'groupid' && !('listInstanceGroups' in this.$store.getters.apis)) { return true } - if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'scope', 'type'].includes(item)) { + if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'scope', 'provider', 'type'].includes(item)) { type = 'list' } else if (item === 'tags') { type = 'tag' @@ -351,6 +351,13 @@ export default { this.fields[scopeIndex].loading = false } + if (arrayField.includes('provider')) { + const providerIndex = this.fields.findIndex(item => item.name === 'provider') + this.fields[providerIndex].loading = true + this.fields[providerIndex].opts = this.fetchImageStoreProviders() + this.fields[providerIndex].loading = false + } + if (arrayField.includes('resourcetype')) { const resourceTypeIndex = this.fields.findIndex(item => item.name === 'resourcetype') this.fields[resourceTypeIndex].loading = true @@ -802,6 +809,28 @@ export default { } return types }, + fetchImageStoreProviders () { + const types = [] + if (this.apiName.indexOf('listImageStores') > -1) { + types.push({ + id: 'NFS', + name: 'NFS' + }) + types.push({ + id: 'SMB/CIFS', + name: 'SMB/CIFS' + }) + types.push({ + id: 'S3', + name: 'S3' + }) + types.push({ + id: 'Swift', + name: 'Swift' + }) + } + return types + }, fetchRoleTypes () { const types = [] if (this.apiName.indexOf('listRoles') > -1) { diff --git a/ui/src/config/section/infra/secondaryStorages.js b/ui/src/config/section/infra/secondaryStorages.js index 774c233c4461..53fa546d9348 100644 --- a/ui/src/config/section/infra/secondaryStorages.js +++ b/ui/src/config/section/infra/secondaryStorages.js @@ -24,6 +24,7 @@ export default { icon: 'picture-outlined', docHelp: 'adminguide/storage.html#secondary-storage', permission: ['listImageStores'], + searchFilters: ['name', 'zoneid', 'provider'], columns: () => { var fields = ['name', 'url', 'protocol', 'scope', 'zonename'] if (store.getters.apis.listImageStores.params.filter(x => x.name === 'readonly').length > 0) { From e12748cd9bf01515d504de86cd93dbd5f83cf113 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 00:38:07 +0530 Subject: [PATCH 17/20] Add search filter for System VMs --- ui/src/components/view/SearchView.vue | 23 ++++++++++++++++++++++- ui/src/config/section/infra/systemVms.js | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 45705512e11e..9d307b67439f 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -283,7 +283,7 @@ export default { if (item === 'groupid' && !('listInstanceGroups' in this.$store.getters.apis)) { return true } - if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'scope', 'provider', 'type'].includes(item)) { + if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'systemvmtype', 'scope', 'provider', 'type'].includes(item)) { type = 'list' } else if (item === 'tags') { type = 'tag' @@ -344,6 +344,13 @@ export default { this.fields[accountTypeIndex].loading = false } + if (arrayField.includes('systemvmtype')) { + const systemVmTypeIndex = this.fields.findIndex(item => item.name === 'systemvmtype') + this.fields[systemVmTypeIndex].loading = true + this.fields[systemVmTypeIndex].opts = this.fetchSystemVmTypes() + this.fields[systemVmTypeIndex].loading = false + } + if (arrayField.includes('scope')) { const scopeIndex = this.fields.findIndex(item => item.name === 'scope') this.fields[scopeIndex].loading = true @@ -783,6 +790,20 @@ export default { } return types }, + fetchSystemVmTypes () { + const types = [] + if (this.apiName.indexOf('listSystemVms') > -1) { + types.push({ + id: 'consoleproxy', + name: 'label.console.proxy.vm' + }) + types.push({ + id: 'secondarystoragevm', + name: 'label.secondary.storage.vm' + }) + } + return types + }, fetchStoragePoolScope () { const types = [] if (this.apiName.indexOf('listStoragePools') > -1) { diff --git a/ui/src/config/section/infra/systemVms.js b/ui/src/config/section/infra/systemVms.js index 68a27f73a520..3ecd17f95caf 100644 --- a/ui/src/config/section/infra/systemVms.js +++ b/ui/src/config/section/infra/systemVms.js @@ -24,6 +24,7 @@ export default { icon: 'thunderbolt-outlined', docHelp: 'adminguide/systemvm.html', permission: ['listSystemVms'], + searchFilters: ['name', 'zoneid', 'podid', 'hostid', 'systemvmtype', 'storageid'], columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'version', 'hostname', 'zonename'], details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'version', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable', 'hostcontrolstate'], resourceType: 'SystemVm', From 5d98eab3d82c13933891474db084410fb5976a0c Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 00:41:57 +0530 Subject: [PATCH 18/20] Add search filter for Alerts --- ui/src/config/section/infra.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/config/section/infra.js b/ui/src/config/section/infra.js index 5b3b38a68e57..cb91d4d7b04f 100644 --- a/ui/src/config/section/infra.js +++ b/ui/src/config/section/infra.js @@ -79,7 +79,7 @@ export default { permission: ['listAlerts'], columns: ['name', 'description', 'type', 'sent'], details: ['name', 'id', 'type', 'sent', 'description'], - searchFilters: ['type'], + searchFilters: ['name', 'type'], actions: [ { api: 'archiveAlerts', From a2ef96c2c7da242683a46d4af25036db7ba12c1c Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 01:00:28 +0530 Subject: [PATCH 19/20] Add search filter for Service Offerings --- ui/src/components/view/SearchView.vue | 5 ++++- ui/src/config/section/offering.js | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 9d307b67439f..43f07c7456b5 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -283,7 +283,10 @@ export default { if (item === 'groupid' && !('listInstanceGroups' in this.$store.getters.apis)) { return true } - if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'systemvmtype', 'scope', 'provider', 'type'].includes(item)) { + if (['zoneid', 'domainid', 'imagestoreid', 'storageid', 'state', 'account', 'hypervisor', 'level', + 'clusterid', 'podid', 'groupid', 'entitytype', 'accounttype', 'systemvmtype', 'scope', 'provider', + 'type'].includes(item) + ) { type = 'list' } else if (item === 'tags') { type = 'tag' diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js index 3e99f602d919..b97b1a0cb2c9 100644 --- a/ui/src/config/section/offering.js +++ b/ui/src/config/section/offering.js @@ -29,6 +29,7 @@ export default { docHelp: 'adminguide/service_offerings.html#compute-and-disk-service-offerings', icon: 'cloud-outlined', permission: ['listServiceOfferings'], + searchFilters: ['name', 'zoneid', 'domainid', 'cpunumber', 'cpuspeed', 'memory'], params: () => { var params = {} if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) { @@ -132,6 +133,7 @@ export default { icon: 'setting-outlined', docHelp: 'adminguide/service_offerings.html#system-service-offerings', permission: ['listServiceOfferings', 'listInfrastructure'], + searchFilters: ['name', 'zoneid', 'domainid', 'cpunumber', 'cpuspeed', 'memory'], params: { issystem: 'true', isrecursive: 'true' }, columns: ['name', 'state', 'systemvmtype', 'cpunumber', 'cpuspeed', 'memory', 'storagetype', 'order'], filters: ['active', 'inactive'], @@ -208,6 +210,7 @@ export default { icon: 'hdd-outlined', docHelp: 'adminguide/service_offerings.html#compute-and-disk-service-offerings', permission: ['listDiskOfferings'], + searchFilters: ['name', 'zoneid', 'domainid', 'storageid'], params: () => { var params = {} if (['Admin', 'DomainAdmin'].includes(store.getters.userInfo.roletype)) { @@ -307,6 +310,7 @@ export default { icon: 'cloud-upload-outlined', docHelp: 'adminguide/virtual_machines.html#backup-offerings', permission: ['listBackupOfferings'], + searchFilters: ['zoneid'], columns: ['name', 'description', 'zonename'], details: ['name', 'id', 'description', 'externalid', 'zone', 'allowuserdrivenbackups', 'created'], related: [{ @@ -360,6 +364,7 @@ export default { icon: 'wifi-outlined', docHelp: 'adminguide/networking.html#network-offerings', permission: ['listNetworkOfferings'], + searchFilters: ['name', 'zoneid', 'domainid', 'tags'], columns: ['name', 'state', 'guestiptype', 'traffictype', 'networkrate', 'domain', 'zone', 'order'], details: ['name', 'id', 'displaytext', 'guestiptype', 'traffictype', 'internetprotocol', 'networkrate', 'ispersistent', 'egressdefaultpolicy', 'availability', 'conservemode', 'specifyvlan', 'specifyipranges', 'supportspublicaccess', 'supportsstrechedl2subnet', 'service', 'tags', 'domain', 'zone'], resourceType: 'NetworkOffering', @@ -458,6 +463,7 @@ export default { icon: 'deployment-unit-outlined', docHelp: 'plugins/nuage-plugin.html?#vpc-offerings', permission: ['listVPCOfferings'], + searchFilters: ['name', 'zoneid', 'domainid'], resourceType: 'VpcOffering', columns: ['name', 'state', 'displaytext', 'domain', 'zone', 'order'], details: ['name', 'id', 'displaytext', 'internetprotocol', 'distributedvpcrouter', 'tags', 'service', 'domain', 'zone', 'created'], From d5092d07a4a77869cbd8a47747b401188e128da7 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 10 May 2024 01:06:33 +0530 Subject: [PATCH 20/20] Add search filter for ldap configuration & hypervisor capabilities --- ui/src/config/section/config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/src/config/section/config.js b/ui/src/config/section/config.js index 6fa33e3ed31b..aa108b5b1fa8 100644 --- a/ui/src/config/section/config.js +++ b/ui/src/config/section/config.js @@ -37,6 +37,7 @@ export default { icon: 'team-outlined', docHelp: 'adminguide/accounts.html#using-an-ldap-server-for-user-authentication', permission: ['listLdapConfigurations'], + searchFilters: ['domainid', 'hostname', 'port'], columns: ['hostname', 'port', 'domainid'], details: ['hostname', 'port', 'domainid'], actions: [ @@ -118,6 +119,7 @@ export default { icon: 'database-outlined', docHelp: 'adminguide/hosts.html?highlight=Hypervisor%20capabilities#hypervisor-capabilities', permission: ['listHypervisorCapabilities'], + searchFilters: ['hypervisor'], columns: ['hypervisor', 'hypervisorversion', 'maxguestslimit', 'maxhostspercluster'], details: ['hypervisor', 'hypervisorversion', 'maxguestslimit', 'maxdatavolumeslimit', 'maxhostspercluster', 'securitygroupenabled', 'storagemotionenabled'], actions: [