Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ui/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3968,6 +3968,9 @@
"message.remove.sticky.policy.failed": "Failed to remove sticky policy.",
"message.remove.sticky.policy.processing": "Removing sticky policy...",
"message.remove.vpc": "Please confirm that you want to remove the VPC",
"message.replace.acl.failed": "Failed to replace the Network ACL list",
"message.replace.acl.processing": "Replacing the Network ACL list...",
"message.replace.acl.success": "Successfully replaced the Network ACL list",
"message.request.failed": "Request failed.",
"message.request.no.data": "There is no data to show.",
"message.required.add.least.ip": "Please add at least 1 IP Range",
Expand Down
173 changes: 173 additions & 0 deletions ui/src/views/network/VpcTiersTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
<router-link :to="{ path: '/acllist/' + network.aclid }">
{{ network.aclname }}
</router-link>
<tooltip-button
:tooltip="$t('label.replace.acl')"
icon="swap-outlined"
size="small"
:disabled="!('replaceNetworkACLList' in $store.getters.apis)"
@onClick="() => handleOpenReplaceAclModal(network)" />
</div>
</div>
</div>
Expand Down Expand Up @@ -302,6 +308,56 @@
</a-spin>
</a-modal>

<a-modal
:visible="showReplaceAclModal"
:title="$t('label.replace.acl')"
:maskClosable="false"
:closable="true"
:footer="null"
:destroyOnClose="true"
@cancel="handleCloseReplaceAclModal">
<a-spin :spinning="replaceAclLoading || replaceAclFetchLoading" v-ctrl-enter="handleReplaceAclSubmit">
<a-form
layout="vertical"
:ref="replaceAclFormRef"
:model="replaceAclForm"
:rules="replaceAclRules"
@finish="handleReplaceAclSubmit"
>
<p>{{ $t('message.confirm.replace.acl.new.one') }}</p>
<a-form-item ref="replaceAcl" name="acl" :colon="false">
<template #label>
<tooltip-label :title="$t('label.aclid')" :tooltip="$t('label.create.tier.aclid.description')"/>
</template>
<a-select
:placeholder="$t('label.create.tier.aclid.description')"
v-model:value="replaceAclForm.acl"
v-focus="true"
@change="val => { handleReplaceAclChange(val) }"
showSearch
optionFilterProp="label"
:filterOption="(input, option) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}" >
<a-select-option v-for="item in replaceAclList" :key="item.id" :value="item.id" :label="`${item.name}(${item.description})`">
<strong>{{ item.name }}</strong> ({{ item.description }})
</a-select-option>
</a-select>
</a-form-item>
<a-alert v-if="replaceAclSelected.name==='default_allow'" type="warning" show-icon>
<template #message><div v-html="$t('message.network.acl.default.allow')"/></template>
</a-alert>
<a-alert v-else-if="replaceAclSelected.name==='default_deny'" type="warning" show-icon>
<template #message><div v-html="$t('message.network.acl.default.deny')"/></template>
</a-alert>
<div :span="24" class="action-button">
<a-button @click="handleCloseReplaceAclModal">{{ $t('label.cancel') }}</a-button>
<a-button type="primary" ref="submit" @click="handleReplaceAclSubmit">{{ $t('label.ok') }}</a-button>
</div>
</a-form>
</a-spin>
</a-modal>

<a-modal
:visible="showAddInternalLB"
:title="$t('label.add.internal.lb')"
Expand Down Expand Up @@ -368,6 +424,7 @@ import { ref, reactive, toRaw } from 'vue'
import { postAPI, getAPI } from '@/api'
import { mixinForm } from '@/utils/mixin'
import Status from '@/components/widgets/Status'
import TooltipButton from '@/components/widgets/TooltipButton'
import TooltipLabel from '@/components/widgets/TooltipLabel'
import { getNetmaskFromCidr } from '@/utils/network'

Expand All @@ -376,6 +433,7 @@ export default {
mixins: [mixinForm],
components: {
Status,
TooltipButton,
TooltipLabel
},
props: {
Expand All @@ -395,10 +453,19 @@ export default {
networkid: '',
fetchLoading: false,
showCreateNetworkModal: false,
showReplaceAclModal: false,
showAddInternalLB: false,
networkOfferings: [],
networkAclList: [],
selectedNetworkAcl: {},
replaceAclForm: {},
replaceAclRules: {},
replaceAclList: [],
replaceAclSelected: {},
replaceAclNetworkId: '',
replaceAclLoading: false,
replaceAclFetchLoading: false,
replaceAclInteractionGeneration: 0,
modalLoading: false,
internalLB: {},
LBPublicIPs: {},
Expand Down Expand Up @@ -476,13 +543,19 @@ export default {
},
created () {
this.initForm()
this.replaceAclFormRef = ref()
this.fetchData()
},
watch: {
loading (newData, oldData) {
if (!newData && this.resource.id) {
this.fetchData()
}
},
'resource.id' (newId, oldId) {
if (oldId && newId !== oldId) {
this.handleCloseReplaceAclModal()
}
}
},
methods: {
Expand Down Expand Up @@ -559,6 +632,25 @@ export default {
this.modalLoading = false
})
},
fetchReplaceAclList (interactionGeneration, vpcId, selectedAclId) {
this.replaceAclFetchLoading = true
return getAPI('listNetworkACLLists', { vpcid: vpcId }).then(json => {
if (interactionGeneration !== this.replaceAclInteractionGeneration || vpcId !== this.resource.id) {
return
}
this.replaceAclList = json.listnetworkacllistsresponse.networkacllist || []
this.replaceAclForm.acl = selectedAclId
this.handleReplaceAclChange(selectedAclId)
}).catch(error => {
if (interactionGeneration === this.replaceAclInteractionGeneration && vpcId === this.resource.id) {
this.$notifyError(error)
}
}).finally(() => {
if (interactionGeneration === this.replaceAclInteractionGeneration && vpcId === this.resource.id) {
this.replaceAclFetchLoading = false
}
})
},
getNetworkOffering (networkId) {
return new Promise((resolve, reject) => {
getAPI('listNetworkOfferings', {
Expand Down Expand Up @@ -700,6 +792,13 @@ export default {
this.selectedNetworkAcl = {}
}
},
handleReplaceAclChange (aclId) {
if (aclId) {
this.replaceAclSelected = this.replaceAclList.filter(acl => acl.id === aclId)[0] || {}
} else {
this.replaceAclSelected = {}
}
},
closeModal () {
this.$emit('close-action')
},
Expand All @@ -724,6 +823,80 @@ export default {
vlan: [{ required: true, message: this.$t('message.please.enter.value') }]
}
},
handleOpenReplaceAclModal (network) {
const interactionGeneration = ++this.replaceAclInteractionGeneration
const vpcId = this.resource.id
this.replaceAclFormRef = ref()
this.replaceAclForm = reactive({ acl: network.aclid })
this.replaceAclRules = reactive({
acl: [{ required: true, message: this.$t('label.required') }]
})
this.replaceAclList = []
this.replaceAclSelected = {}
this.replaceAclNetworkId = network.id
this.replaceAclLoading = false
this.replaceAclFetchLoading = false
this.showReplaceAclModal = true
return this.fetchReplaceAclList(interactionGeneration, vpcId, network.aclid)
},
handleCloseReplaceAclModal () {
this.showReplaceAclModal = false
this.replaceAclInteractionGeneration += 1
this.replaceAclList = []
this.replaceAclSelected = {}
this.replaceAclNetworkId = ''
this.replaceAclLoading = false
this.replaceAclFetchLoading = false
},
handleReplaceAclSubmit () {
if (this.replaceAclLoading || this.replaceAclFetchLoading) return

const interactionGeneration = this.replaceAclInteractionGeneration
const vpcId = this.resource.id
const networkId = this.replaceAclNetworkId
const aclId = this.replaceAclForm.acl
const formRef = this.replaceAclFormRef
this.replaceAclLoading = true

return formRef.value.validate().then(() => {
if (interactionGeneration !== this.replaceAclInteractionGeneration || vpcId !== this.resource.id) {
return
}
this.showReplaceAclModal = false

return postAPI('replaceNetworkACLList', {
aclid: aclId,
networkid: networkId
}).then(response => {
this.$pollJob({
jobId: response.replacenetworkacllistresponse.jobid,
title: this.$t('label.replace.acl'),
description: networkId,
successMessage: this.$t('message.replace.acl.success'),
successMethod: () => {
this.parentFetchData()
},
errorMessage: this.$t('message.replace.acl.failed'),
loadingMessage: this.$t('message.replace.acl.processing'),
catchMessage: this.$t('error.fetching.async.job.result')
})
}).catch(error => {
this.$notifyError(error)
}).finally(() => {
if (interactionGeneration === this.replaceAclInteractionGeneration && vpcId === this.resource.id) {
this.replaceAclLoading = false
}
})
}).catch((error) => {
if (interactionGeneration !== this.replaceAclInteractionGeneration || vpcId !== this.resource.id) {
return
}
this.replaceAclLoading = false
if (error?.errorFields?.length > 0) {
formRef.value.scrollToField(error.errorFields[0].name)
}
})
},
handleAddInternalLB (id) {
this.initForm()
this.showAddInternalLB = true
Expand Down
Loading