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 }}
+ </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
}