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

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


The following commit(s) were added to refs/heads/main by this push:
     new 38a0ded  ui: Support to specify security groups when updating/editing 
a VM (adv zone + SG) (#6138)
38a0ded is described below

commit 38a0ded053d01989c055fc8c46053968de6e1a74
Author: Pearl Dsilva <[email protected]>
AuthorDate: Mon Mar 21 19:02:15 2022 +0530

    ui: Support to specify security groups when updating/editing a VM (adv zone 
+ SG) (#6138)
    
    * ui: Support to specify security groups when updating/editing a VM (adv 
zone + SG)
    
    * cleanup
---
 ui/src/components/view/DetailsTab.vue |  7 ++++
 ui/src/config/section/compute.js      | 10 +++++-
 ui/src/views/compute/EditVM.vue       | 62 ++++++++++++++++++++++++++++++++++-
 3 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/ui/src/components/view/DetailsTab.vue 
b/ui/src/components/view/DetailsTab.vue
index 9800448..2554ad2 100644
--- a/ui/src/components/view/DetailsTab.vue
+++ b/ui/src/components/view/DetailsTab.vue
@@ -49,6 +49,13 @@
           <div v-else-if="$route.meta.name === 'guestnetwork' && item === 
'egressdefaultpolicy'">
             {{ dataResource[item]? $t('message.egress.rules.allow') : 
$t('message.egress.rules.deny') }}
           </div>
+          <div v-else-if="item === 'securitygroup'">
+            <div v-if="dataResource[item] && dataResource[item].length > 0">
+              <span v-for="(securityGroup, idx) in dataResource[item]" 
:key="idx">
+                {{ securityGroup.name }} &nbsp;
+              </span>
+            </div>
+          </div>
           <div v-else>{{ dataResource[item] }}</div>
         </div>
       </a-list-item>
diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js
index 955383b..350c00d 100644
--- a/ui/src/config/section/compute.js
+++ b/ui/src/config/section/compute.js
@@ -67,7 +67,15 @@ export default {
         return fields
       },
       searchFilters: ['name', 'zoneid', 'domainid', 'account', 'tags'],
-      details: ['displayname', 'name', 'id', 'state', 'ipaddress', 
'ip6address', 'templatename', 'ostypename', 'serviceofferingname', 
'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 
'account', 'domain', 'zonename'],
+      details: () => {
+        var fields = ['displayname', 'name', 'id', 'state', 'ipaddress', 
'ip6address', 'templatename', 'ostypename', 'serviceofferingname', 
'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 
'account', 'domain', 'zonename']
+        const listZoneHaveSGEnabled = store.getters.zones.filter(zone => 
zone.securitygroupsenabled === true)
+        if (!listZoneHaveSGEnabled || listZoneHaveSGEnabled.length === 0) {
+          return fields
+        }
+        fields.push('securitygroup')
+        return fields
+      },
       tabs: [{
         component: shallowRef(defineAsyncComponent(() => 
import('@/views/compute/InstanceTab.vue')))
       }],
diff --git a/ui/src/views/compute/EditVM.vue b/ui/src/views/compute/EditVM.vue
index ffd13e2..87545c7 100644
--- a/ui/src/views/compute/EditVM.vue
+++ b/ui/src/views/compute/EditVM.vue
@@ -91,6 +91,25 @@
         <a-textarea v-model:value="form.userdata">
         </a-textarea>
       </a-form-item>
+      <a-form-item ref="securitygroupids" name="securitygroupids" 
:label="$t('label.security.groups')" v-if="securityGroupsEnabled">
+        <a-select
+          mode="multiple"
+          :placeholder="$t('label.select.security.groups')"
+          v-model:value="form.securitygroupids"
+          showSearch
+          optionFilterProp="label"
+          :filterOption="(input, option) => {
+            return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
+          }"
+          :loading="securitygroups.loading"
+          v-focus="true">
+          <a-select-option v-for="securitygroup in securitygroups.opts" 
:key="securitygroup.id" :label="securitygroup.name">
+            <div>
+              {{ securitygroup.name ||  securitygroup.id }}
+            </div>
+          </a-select-option>
+        </a-select>
+      </a-form-item>
 
       <div :span="24" class="action-button">
         <a-button :loading="loading" @click="onCloseAction">{{ 
$t('label.cancel') }}</a-button>
@@ -124,8 +143,13 @@ export default {
     return {
       serviceOffering: {},
       template: {},
+      securityGroupsEnabled: false,
       dynamicScalingVmConfig: false,
       loading: false,
+      securitygroups: {
+        loading: false,
+        opts: []
+      },
       osTypes: {
         loading: false,
         opts: []
@@ -151,17 +175,48 @@ export default {
         displayname: this.resource.displayname,
         ostypeid: this.resource.ostypeid,
         isdynamicallyscalable: this.resource.isdynamicallyscalable,
-        group: this.resource.group
+        group: this.resource.group,
+        securitygroupids: this.resource.securitygroup.map(x => x.id)
       })
       this.rules = reactive({})
     },
     fetchData () {
+      this.fetchZoneDetails()
+      this.fetchSecurityGroups()
       this.fetchOsTypes()
       this.fetchInstaceGroups()
       this.fetchServiceOfferingData()
       this.fetchTemplateData()
       this.fetchDynamicScalingVmConfig()
     },
+    fetchZoneDetails () {
+      api('listZones', {
+        zoneid: this.resource.zoneid
+      }).then(response => {
+        const zone = response?.listzonesresponse?.zone || []
+        this.securityGroupsEnabled = zone?.[0]?.securitygroupsenabled
+      })
+    },
+    fetchSecurityGroups () {
+      this.securitygroups.loading = true
+      api('listSecurityGroups', {
+        zoneid: this.resource.zoneid
+      }).then(json => {
+        const items = json.listsecuritygroupsresponse.securitygroup || []
+        if (items && items.length > 0) {
+          for (let i = 0; i < items.length; i++) {
+            this.securitygroups.opts.push(items[i])
+          }
+          this.securitygroups.opts.sort((a, b) => {
+            if (a.name < b.name) return -1
+            if (a.name > b.name) return 1
+            return 0
+          })
+        }
+      }).finally(() => {
+        this.securitygroups.loading = false
+      })
+    },
     fetchServiceOfferingData () {
       const params = {}
       params.id = this.resource.serviceofferingid
@@ -242,6 +297,11 @@ export default {
         params.name = values.name
         params.displayname = values.displayname
         params.ostypeid = values.ostypeid
+        if (this.securityGroupsEnabled) {
+          if (values.securitygroupids) {
+            params.securitygroupids = values.securitygroupids
+          }
+        }
         if (values.isdynamicallyscalable !== undefined) {
           params.isdynamicallyscalable = values.isdynamicallyscalable
         }

Reply via email to