Skip to content

Commit 38a0ded

Browse files
authored
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
1 parent 13efa59 commit 38a0ded

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

ui/src/components/view/DetailsTab.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@
4949
<div v-else-if="$route.meta.name === 'guestnetwork' && item === 'egressdefaultpolicy'">
5050
{{ dataResource[item]? $t('message.egress.rules.allow') : $t('message.egress.rules.deny') }}
5151
</div>
52+
<div v-else-if="item === 'securitygroup'">
53+
<div v-if="dataResource[item] && dataResource[item].length > 0">
54+
<span v-for="(securityGroup, idx) in dataResource[item]" :key="idx">
55+
{{ securityGroup.name }} &nbsp;
56+
</span>
57+
</div>
58+
</div>
5259
<div v-else>{{ dataResource[item] }}</div>
5360
</div>
5461
</a-list-item>

ui/src/config/section/compute.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,15 @@ export default {
6767
return fields
6868
},
6969
searchFilters: ['name', 'zoneid', 'domainid', 'account', 'tags'],
70-
details: ['displayname', 'name', 'id', 'state', 'ipaddress', 'ip6address', 'templatename', 'ostypename', 'serviceofferingname', 'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 'account', 'domain', 'zonename'],
70+
details: () => {
71+
var fields = ['displayname', 'name', 'id', 'state', 'ipaddress', 'ip6address', 'templatename', 'ostypename', 'serviceofferingname', 'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 'account', 'domain', 'zonename']
72+
const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true)
73+
if (!listZoneHaveSGEnabled || listZoneHaveSGEnabled.length === 0) {
74+
return fields
75+
}
76+
fields.push('securitygroup')
77+
return fields
78+
},
7179
tabs: [{
7280
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/InstanceTab.vue')))
7381
}],

ui/src/views/compute/EditVM.vue

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,25 @@
9191
<a-textarea v-model:value="form.userdata">
9292
</a-textarea>
9393
</a-form-item>
94+
<a-form-item ref="securitygroupids" name="securitygroupids" :label="$t('label.security.groups')" v-if="securityGroupsEnabled">
95+
<a-select
96+
mode="multiple"
97+
:placeholder="$t('label.select.security.groups')"
98+
v-model:value="form.securitygroupids"
99+
showSearch
100+
optionFilterProp="label"
101+
:filterOption="(input, option) => {
102+
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
103+
}"
104+
:loading="securitygroups.loading"
105+
v-focus="true">
106+
<a-select-option v-for="securitygroup in securitygroups.opts" :key="securitygroup.id" :label="securitygroup.name">
107+
<div>
108+
{{ securitygroup.name || securitygroup.id }}
109+
</div>
110+
</a-select-option>
111+
</a-select>
112+
</a-form-item>
94113

95114
<div :span="24" class="action-button">
96115
<a-button :loading="loading" @click="onCloseAction">{{ $t('label.cancel') }}</a-button>
@@ -124,8 +143,13 @@ export default {
124143
return {
125144
serviceOffering: {},
126145
template: {},
146+
securityGroupsEnabled: false,
127147
dynamicScalingVmConfig: false,
128148
loading: false,
149+
securitygroups: {
150+
loading: false,
151+
opts: []
152+
},
129153
osTypes: {
130154
loading: false,
131155
opts: []
@@ -151,17 +175,48 @@ export default {
151175
displayname: this.resource.displayname,
152176
ostypeid: this.resource.ostypeid,
153177
isdynamicallyscalable: this.resource.isdynamicallyscalable,
154-
group: this.resource.group
178+
group: this.resource.group,
179+
securitygroupids: this.resource.securitygroup.map(x => x.id)
155180
})
156181
this.rules = reactive({})
157182
},
158183
fetchData () {
184+
this.fetchZoneDetails()
185+
this.fetchSecurityGroups()
159186
this.fetchOsTypes()
160187
this.fetchInstaceGroups()
161188
this.fetchServiceOfferingData()
162189
this.fetchTemplateData()
163190
this.fetchDynamicScalingVmConfig()
164191
},
192+
fetchZoneDetails () {
193+
api('listZones', {
194+
zoneid: this.resource.zoneid
195+
}).then(response => {
196+
const zone = response?.listzonesresponse?.zone || []
197+
this.securityGroupsEnabled = zone?.[0]?.securitygroupsenabled
198+
})
199+
},
200+
fetchSecurityGroups () {
201+
this.securitygroups.loading = true
202+
api('listSecurityGroups', {
203+
zoneid: this.resource.zoneid
204+
}).then(json => {
205+
const items = json.listsecuritygroupsresponse.securitygroup || []
206+
if (items && items.length > 0) {
207+
for (let i = 0; i < items.length; i++) {
208+
this.securitygroups.opts.push(items[i])
209+
}
210+
this.securitygroups.opts.sort((a, b) => {
211+
if (a.name < b.name) return -1
212+
if (a.name > b.name) return 1
213+
return 0
214+
})
215+
}
216+
}).finally(() => {
217+
this.securitygroups.loading = false
218+
})
219+
},
165220
fetchServiceOfferingData () {
166221
const params = {}
167222
params.id = this.resource.serviceofferingid
@@ -242,6 +297,11 @@ export default {
242297
params.name = values.name
243298
params.displayname = values.displayname
244299
params.ostypeid = values.ostypeid
300+
if (this.securityGroupsEnabled) {
301+
if (values.securitygroupids) {
302+
params.securitygroupids = values.securitygroupids
303+
}
304+
}
245305
if (values.isdynamicallyscalable !== undefined) {
246306
params.isdynamicallyscalable = values.isdynamicallyscalable
247307
}

0 commit comments

Comments
 (0)