mirror of https://github.com/apache/cloudstack.git
Merge a84c486854 into bce3e54a7e
This commit is contained in:
commit
962abd38ce
|
|
@ -932,6 +932,7 @@
|
||||||
"label.endpoint": "Endpoint",
|
"label.endpoint": "Endpoint",
|
||||||
"label.endport": "End port",
|
"label.endport": "End port",
|
||||||
"label.enter.account.name": "Enter the account name",
|
"label.enter.account.name": "Enter the account name",
|
||||||
|
"label.enter.domain.name": "Enter the domain name",
|
||||||
"label.enter.code": "Enter 2FA code to verify",
|
"label.enter.code": "Enter 2FA code to verify",
|
||||||
"label.enter.static.pin": "Enter static PIN to verify",
|
"label.enter.static.pin": "Enter static PIN to verify",
|
||||||
"label.enter.token": "Enter token",
|
"label.enter.token": "Enter token",
|
||||||
|
|
@ -2970,6 +2971,9 @@
|
||||||
"message.delete.account.processing": "Deleting account",
|
"message.delete.account.processing": "Deleting account",
|
||||||
"message.delete.account.success": "Successfully deleted account",
|
"message.delete.account.success": "Successfully deleted account",
|
||||||
"message.delete.account.warning": "Deleting this account will delete all of the instances, volumes and snapshots associated with the account.",
|
"message.delete.account.warning": "Deleting this account will delete all of the instances, volumes and snapshots associated with the account.",
|
||||||
|
"message.delete.domain.confirm": "Please confirm that you want to delete this domain by entering the name of the domain below.",
|
||||||
|
"message.delete.domain.warning": "This domain may contain accounts, users, or sub-domains. All of these must be removed before the domain can be deleted. This action cannot be undone.",
|
||||||
|
"message.delete.domain.failed": "Delete domain failed",
|
||||||
"message.delete.acl.processing": "Removing ACL rule...",
|
"message.delete.acl.processing": "Removing ACL rule...",
|
||||||
"message.delete.acl.rule": "Remove ACL rule",
|
"message.delete.acl.rule": "Remove ACL rule",
|
||||||
"message.delete.acl.rule.failed": "Failed to remove ACL rule.",
|
"message.delete.acl.rule.failed": "Failed to remove ACL rule.",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
// or more contributor license agreements. See the NOTICE file
|
||||||
|
// distributed with this work for additional information
|
||||||
|
// regarding copyright ownership. The ASF licenses this file
|
||||||
|
// to you under the Apache License, Version 2.0 (the
|
||||||
|
// "License"); you may not use this file except in compliance
|
||||||
|
// with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing,
|
||||||
|
// software distributed under the License is distributed on an
|
||||||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
// KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations
|
||||||
|
// under the License.
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="true"
|
||||||
|
:title="$t('label.action.delete.domain') + ': ' + domain.name"
|
||||||
|
:okText="$t('label.delete.domain')"
|
||||||
|
okType="danger"
|
||||||
|
:confirmLoading="loading"
|
||||||
|
:ok-button-props="{ disabled: !canDelete }"
|
||||||
|
@cancel="emitClose"
|
||||||
|
@ok="emitConfirm">
|
||||||
|
|
||||||
|
<a-alert
|
||||||
|
type="warning"
|
||||||
|
show-icon
|
||||||
|
style="margin-bottom: 16px">
|
||||||
|
<template #message>
|
||||||
|
<div v-html="$t('message.delete.domain.warning')"></div>
|
||||||
|
</template>
|
||||||
|
</a-alert>
|
||||||
|
|
||||||
|
<a-spin v-if="loading" />
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
v-else
|
||||||
|
size="small"
|
||||||
|
:columns="columns"
|
||||||
|
:dataSource="accountVmSummary"
|
||||||
|
:pagination="false"
|
||||||
|
rowKey="account" />
|
||||||
|
|
||||||
|
<div style="margin-top: 16px">
|
||||||
|
<a-alert style="margin-bottom: 10px">
|
||||||
|
<template #message>
|
||||||
|
<div v-html="$t('message.delete.domain.confirm')"></div>
|
||||||
|
</template>
|
||||||
|
</a-alert>
|
||||||
|
<a-input
|
||||||
|
v-model:value="confirmText"
|
||||||
|
:placeholder="$t('label.enter.domain.name')" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { api } from '@/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DomainDeleteConfirm',
|
||||||
|
props: {
|
||||||
|
domain: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
confirmText: '',
|
||||||
|
accountVmSummary: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
canDelete () {
|
||||||
|
return this.confirmText.trim() === this.domain.name.trim()
|
||||||
|
},
|
||||||
|
columns () {
|
||||||
|
return [
|
||||||
|
{ title: this.$t('label.account'), dataIndex: 'account' },
|
||||||
|
{ title: this.$t('label.total') + ' VMs', dataIndex: 'total' },
|
||||||
|
{ title: this.$t('label.running') + ' VMs', dataIndex: 'running' },
|
||||||
|
{ title: this.$t('label.stopped') + ' VMs', dataIndex: 'stopped' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.fetchDomainImpact()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
emitClose () {
|
||||||
|
this.$emit('close')
|
||||||
|
},
|
||||||
|
emitConfirm () {
|
||||||
|
if (this.canDelete) {
|
||||||
|
this.$emit('confirm')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async fetchDomainImpact () {
|
||||||
|
this.loading = true
|
||||||
|
try {
|
||||||
|
const accResp = await api('listAccounts', {
|
||||||
|
domainid: this.domain.id,
|
||||||
|
listall: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const accounts =
|
||||||
|
accResp.listaccountsresponse &&
|
||||||
|
accResp.listaccountsresponse.account
|
||||||
|
? accResp.listaccountsresponse.account
|
||||||
|
: []
|
||||||
|
|
||||||
|
const vmResp = await api('listVirtualMachines', {
|
||||||
|
domainid: this.domain.id,
|
||||||
|
listall: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const vms =
|
||||||
|
vmResp.listvirtualmachinesresponse &&
|
||||||
|
vmResp.listvirtualmachinesresponse.virtualmachine
|
||||||
|
? vmResp.listvirtualmachinesresponse.virtualmachine
|
||||||
|
: []
|
||||||
|
|
||||||
|
this.accountVmSummary = accounts.map(account => {
|
||||||
|
const accountVms = vms.filter(vm => vm.account === account.name)
|
||||||
|
const running = accountVms.filter(vm => vm.state === 'Running').length
|
||||||
|
const stopped = accountVms.length - running
|
||||||
|
|
||||||
|
return {
|
||||||
|
account: account.name,
|
||||||
|
total: accountVms.length,
|
||||||
|
running,
|
||||||
|
stopped
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
this.$notification.error({
|
||||||
|
message: this.$t('message.request.failed'),
|
||||||
|
description: e.response?.headers['x-description'] || this.$t('message.request.failed')
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
|
|
@ -74,6 +74,11 @@
|
||||||
:resource="resource"
|
:resource="resource"
|
||||||
:action="action"/>
|
:action="action"/>
|
||||||
</div>
|
</div>
|
||||||
|
<domain-delete-confirm
|
||||||
|
v-if="showDeleteConfirm"
|
||||||
|
:domain="deleteDomainResource"
|
||||||
|
@close="showDeleteConfirm = false"
|
||||||
|
@confirm="confirmDeleteDomain" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -87,6 +92,7 @@ import ActionButton from '@/components/view/ActionButton'
|
||||||
import TreeView from '@/components/view/TreeView'
|
import TreeView from '@/components/view/TreeView'
|
||||||
import DomainActionForm from '@/views/iam/DomainActionForm'
|
import DomainActionForm from '@/views/iam/DomainActionForm'
|
||||||
import ResourceView from '@/components/view/ResourceView'
|
import ResourceView from '@/components/view/ResourceView'
|
||||||
|
import DomainDeleteConfirm from '@/components/view/DomainDeleteConfirm'
|
||||||
import eventBus from '@/config/eventBus'
|
import eventBus from '@/config/eventBus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -96,7 +102,8 @@ export default {
|
||||||
ActionButton,
|
ActionButton,
|
||||||
TreeView,
|
TreeView,
|
||||||
DomainActionForm,
|
DomainActionForm,
|
||||||
ResourceView
|
ResourceView,
|
||||||
|
DomainDeleteConfirm
|
||||||
},
|
},
|
||||||
mixins: [mixinDevice],
|
mixins: [mixinDevice],
|
||||||
data () {
|
data () {
|
||||||
|
|
@ -111,7 +118,9 @@ export default {
|
||||||
action: {},
|
action: {},
|
||||||
dataView: false,
|
dataView: false,
|
||||||
domainStore: {},
|
domainStore: {},
|
||||||
treeDeletedKey: null
|
treeDeletedKey: null,
|
||||||
|
showDeleteConfirm: false,
|
||||||
|
deleteDomainResource: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -205,7 +214,12 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
execAction (action) {
|
execAction (action) {
|
||||||
this.treeDeletedKey = action.api === 'deleteDomain' ? this.resource.key : null
|
if (action.api === 'deleteDomain') {
|
||||||
|
this.deleteDomainResource = this.resource
|
||||||
|
this.showDeleteConfirm = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.treeDeletedKey = null
|
||||||
this.actionData = []
|
this.actionData = []
|
||||||
this.action = action
|
this.action = action
|
||||||
this.action.params = store.getters.apis[this.action.api].params
|
this.action.params = store.getters.apis[this.action.api].params
|
||||||
|
|
@ -319,6 +333,38 @@ export default {
|
||||||
closeAction () {
|
closeAction () {
|
||||||
this.showAction = false
|
this.showAction = false
|
||||||
},
|
},
|
||||||
|
confirmDeleteDomain () {
|
||||||
|
const domain = this.deleteDomainResource
|
||||||
|
const params = { id: domain.id, cleanup: true }
|
||||||
|
|
||||||
|
api('deleteDomain', params).then(json => {
|
||||||
|
const jobId = json.deletedomainresponse.jobid
|
||||||
|
|
||||||
|
this.$pollJob({
|
||||||
|
jobId,
|
||||||
|
title: this.$t('label.action.delete.domain'),
|
||||||
|
description: domain.name,
|
||||||
|
loadingMessage: `${this.$t('label.action.delete.domain')} ${domain.name}`,
|
||||||
|
successMessage: `${this.$t('label.action.delete.domain')} ${domain.name}`,
|
||||||
|
catchMessage: this.$t('error.fetching.async.job.result'),
|
||||||
|
successMethod: () => {
|
||||||
|
if (this.$route.params.id === domain.id) {
|
||||||
|
this.$router.push({ path: '/domain' })
|
||||||
|
}
|
||||||
|
this.fetchData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
this.$notification.error({
|
||||||
|
message: this.$t('message.request.failed'),
|
||||||
|
description: error.response?.headers['x-description'] || this.$t('message.request.failed')
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
this.showDeleteConfirm = false
|
||||||
|
this.deleteDomainResource = null
|
||||||
|
this.treeDeletedKey = null
|
||||||
|
})
|
||||||
|
},
|
||||||
forceRerender () {
|
forceRerender () {
|
||||||
this.treeViewKey += 1
|
this.treeViewKey += 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue