mirror of https://github.com/apache/cloudstack.git
infra: add cluster form (#114)
This adds the add cluster form with domain/account dedication option. Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com> Co-authored-by: Rohit Yadav <rohit@apache.org>
This commit is contained in:
parent
46d73a01d2
commit
41a2297dd4
|
|
@ -116,7 +116,7 @@ export default {
|
|||
zoneid: this.resource.id
|
||||
}).then(response => {
|
||||
if (response.listdedicatedzonesresponse.dedicatedzone &&
|
||||
response.listdedicatedzonesresponse.dedicatedzone.length > 0) {
|
||||
response.listdedicatedzonesresponse.dedicatedzone.length > 0) {
|
||||
this.dedicatedDomainId = response.listdedicatedzonesresponse.dedicatedzone[0].domainid
|
||||
this.dedicatedAccountId = response.listdedicatedzonesresponse.dedicatedzone[0].accountid
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ export default {
|
|||
podid: this.resource.id
|
||||
}).then(response => {
|
||||
if (response.listdedicatedpodsresponse.dedicatedpod &&
|
||||
response.listdedicatedpodsresponse.dedicatedpod.length > 0) {
|
||||
response.listdedicatedpodsresponse.dedicatedpod.length > 0) {
|
||||
this.dedicatedDomainId = response.listdedicatedpodsresponse.dedicatedpod[0].domainid
|
||||
this.dedicatedAccountId = response.listdedicatedpodsresponse.dedicatedpod[0].accountid
|
||||
}
|
||||
|
|
@ -148,7 +148,7 @@ export default {
|
|||
clusterid: this.resource.id
|
||||
}).then(response => {
|
||||
if (response.listdedicatedclustersresponse.dedicatedcluster &&
|
||||
response.listdedicatedclustersresponse.dedicatedcluster.length > 0) {
|
||||
response.listdedicatedclustersresponse.dedicatedcluster.length > 0) {
|
||||
this.dedicatedDomainId = response.listdedicatedclustersresponse.dedicatedcluster[0].domainid
|
||||
this.dedicatedAccountId = response.listdedicatedclustersresponse.dedicatedcluster[0].accountid
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ export default {
|
|||
hostid: this.resource.id
|
||||
}).then(response => {
|
||||
if (response.listdedicatedhostsresponse.dedicatedhost &&
|
||||
response.listdedicatedhostsresponse.dedicatedhost.length > 0) {
|
||||
response.listdedicatedhostsresponse.dedicatedhost.length > 0) {
|
||||
this.dedicatedDomainId = response.listdedicatedhostsresponse.dedicatedhost[0].domainid
|
||||
this.dedicatedAccountId = response.listdedicatedhostsresponse.dedicatedhost[0].accountid
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,15 +55,19 @@ export default {
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
dedicatedRoutes: ['zone', 'pod', 'cluster', 'host'],
|
||||
dedicatedSectionActive: false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.dedicatedSectionActive = this.dedicatedRoutes.includes(this.$route.meta.name)
|
||||
},
|
||||
created () {
|
||||
this.dedicatedSectionActive = ['zone', 'pod', 'cluster', 'host'].includes(this.$route.meta.name)
|
||||
this.dedicatedSectionActive = this.dedicatedRoutes.includes(this.$route.meta.name)
|
||||
},
|
||||
watch: {
|
||||
$route () {
|
||||
this.dedicatedSectionActive = ['zone', 'pod', 'cluster', 'host'].includes(this.$route.meta.name)
|
||||
this.dedicatedSectionActive = this.dedicatedRoutes.includes(this.$route.meta.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ export default {
|
|||
icon: 'plus',
|
||||
label: 'label.add.cluster',
|
||||
listView: true,
|
||||
args: ['zoneid', 'hypervisor', 'podid', 'clustername']
|
||||
popup: true,
|
||||
component: () => import('@/views/infra/ClusterAdd.vue')
|
||||
},
|
||||
{
|
||||
api: 'updateCluster',
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
"Virtual Routers": "Virtual Routers",
|
||||
"Volumes": "Volumes",
|
||||
"Zones": "Zones",
|
||||
"add": "Add",
|
||||
"accesskey": "Access Key",
|
||||
"account": "Account",
|
||||
"accountId": "Account",
|
||||
|
|
@ -120,6 +119,7 @@
|
|||
"clusterId": "Cluster",
|
||||
"clusterid": "Cluster",
|
||||
"clustername": "Cluster",
|
||||
"clusternamelabel": "Cluster Name",
|
||||
"clusters": "Clusters",
|
||||
"clustertype": "Cluster Type",
|
||||
"connectiontimeout": "Connection Timeout",
|
||||
|
|
@ -1066,6 +1066,8 @@
|
|||
"newInstance": "New instance",
|
||||
"defaultNetwork": "Default network",
|
||||
"cpu": "CPU",
|
||||
"ram": "RAM",
|
||||
"ok": "OK",
|
||||
"minMaxIops": "Min IOPS / Max IOPS",
|
||||
"isSelf": "Self",
|
||||
"isShared": "Shared",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,365 @@
|
|||
// 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-spin :spinning="loading">
|
||||
<div class="form">
|
||||
<div class="form__item">
|
||||
<div class="form__label"><span class="required">* </span>{{ $t('zonenamelabel') }}</div>
|
||||
<a-select v-model="zoneId" @change="fetchPods">
|
||||
<a-select-option
|
||||
v-for="zone in zonesList"
|
||||
:value="zone.id"
|
||||
:key="zone.id">
|
||||
{{ zone.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
|
||||
<div class="form__item">
|
||||
<div class="form__label">{{ $t('hypervisor') }}</div>
|
||||
<a-select v-model="hypervisor" @change="resetAllFields">
|
||||
<a-select-option
|
||||
v-for="hv in hypervisorsList"
|
||||
:value="hv.name"
|
||||
:key="hv.name">
|
||||
{{ hv.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
|
||||
<div class="form__item">
|
||||
<div class="form__label">{{ $t('podname') }}</div>
|
||||
<a-select v-model="podId">
|
||||
<a-select-option
|
||||
v-for="pod in podsList"
|
||||
:value="pod.id"
|
||||
:key="pod.id">
|
||||
{{ pod.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
|
||||
<div class="form__item">
|
||||
<div class="form__label"><span class="required">* </span>{{ $t('clusternamelabel') }}</div>
|
||||
<span class="required required-label" ref="requiredCluster">Required</span>
|
||||
<a-input :placeholder="placeholder.clustername" v-model="clustername"></a-input>
|
||||
</div>
|
||||
|
||||
<template v-if="hypervisor === 'VMware'">
|
||||
<div class="form__item">
|
||||
<div class="form__label">{{ $t('vCenterHost') }}</div>
|
||||
<a-input v-model="host"></a-input>
|
||||
</div>
|
||||
|
||||
<div class="form__item">
|
||||
<div class="form__label">{{ $t('vCenterUsername') }}</div>
|
||||
<a-input v-model="username"></a-input>
|
||||
</div>
|
||||
|
||||
<div class="form__item">
|
||||
<div class="form__label">{{ $t('vCenterPassword') }}</div>
|
||||
<a-input v-model="password"></a-input>
|
||||
</div>
|
||||
|
||||
<div class="form__item">
|
||||
<div class="form__label">{{ $t('vCenterDataCenter') }}</div>
|
||||
<a-input v-model="dataCenter"></a-input>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="form__item">
|
||||
<div class="form__label">{{ $t('isDedicated') }}</div>
|
||||
<a-checkbox @change="toggleDedicated" />
|
||||
</div>
|
||||
|
||||
<template v-if="showDedicated">
|
||||
<DedicateDomain
|
||||
@domainChange="id => dedicatedDomainId = id"
|
||||
@accountChange="id => dedicatedAccount = id"
|
||||
:error="domainError" />
|
||||
</template>
|
||||
|
||||
<a-divider></a-divider>
|
||||
|
||||
<div class="actions">
|
||||
<a-button @click="() => this.$parent.$parent.close()">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmitForm" type="primary">{{ $t('ok') }}</a-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import DedicateDomain from '../../components/view/DedicateDomain'
|
||||
|
||||
export default {
|
||||
name: 'ClusterAdd',
|
||||
components: {
|
||||
DedicateDomain
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
inject: ['parentFetchData', 'parentToggleLoading'],
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
zoneId: null,
|
||||
hypervisor: null,
|
||||
podId: null,
|
||||
clustername: null,
|
||||
clustertype: 'CloudManaged',
|
||||
username: null,
|
||||
password: null,
|
||||
url: null,
|
||||
host: null,
|
||||
dataCenter: null,
|
||||
ovm3pool: null,
|
||||
ovm3cluster: null,
|
||||
ovm3vip: null,
|
||||
zonesList: [],
|
||||
hypervisorsList: [],
|
||||
podsList: [],
|
||||
showDedicated: false,
|
||||
dedicatedDomainId: null,
|
||||
dedicatedAccount: null,
|
||||
domainError: false,
|
||||
params: [],
|
||||
placeholder: {
|
||||
clustername: null
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
fetchData () {
|
||||
this.fetchZones()
|
||||
this.fetchHypervisors()
|
||||
this.params = this.$store.getters.apis.addCluster.params
|
||||
Object.keys(this.placeholder).forEach(item => { this.returnPlaceholder(item) })
|
||||
},
|
||||
fetchZones () {
|
||||
this.loading = true
|
||||
api('listZones').then(response => {
|
||||
this.zonesList = response.listzonesresponse.zone || []
|
||||
this.zoneId = this.zonesList[0].id || null
|
||||
this.fetchPods()
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: `Error ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
fetchHypervisors () {
|
||||
this.loading = true
|
||||
api('listHypervisors').then(response => {
|
||||
this.hypervisorsList = response.listhypervisorsresponse.hypervisor || []
|
||||
this.hypervisor = this.hypervisorsList[0].name || null
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: `Error ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
fetchPods () {
|
||||
this.loading = true
|
||||
api('listPods', {
|
||||
zoneid: this.zoneId
|
||||
}).then(response => {
|
||||
this.podsList = response.listpodsresponse.pod || []
|
||||
this.podId = this.podsList[0].id || null
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: `Error ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
toggleDedicated () {
|
||||
this.dedicatedDomainId = null
|
||||
this.dedicatedAccount = null
|
||||
this.showDedicated = !this.showDedicated
|
||||
},
|
||||
handleSubmitForm () {
|
||||
if (!this.clustername) {
|
||||
this.$refs.requiredCluster.classList.add('required-label--visible')
|
||||
return
|
||||
}
|
||||
this.$refs.requiredCluster.classList.remove('required-label--visible')
|
||||
|
||||
if (this.hypervisor === 'Ovm3') {
|
||||
this.ovm3pool = 'on'
|
||||
this.ovm3cluster = 'undefined'
|
||||
this.ovm3vip = ''
|
||||
}
|
||||
|
||||
if (this.hypervisor === 'VMware') {
|
||||
this.clustertype = 'ExternalManaged'
|
||||
const clusternameVal = this.clustername
|
||||
this.url = `http://${this.host}/${this.dataCenter}/${clusternameVal}`
|
||||
this.clustername = `${this.host}/${this.dataCenter}/${clusternameVal}`
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
this.parentToggleLoading()
|
||||
api('addCluster', {
|
||||
zoneId: this.zoneId,
|
||||
hypervisor: this.hypervisor,
|
||||
clustertype: this.clustertype,
|
||||
podId: this.podId,
|
||||
clustername: this.clustername,
|
||||
ovm3pool: this.ovm3pool,
|
||||
ovm3cluster: this.ovm3cluster,
|
||||
ovm3vip: this.ovm3vip,
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
url: this.url
|
||||
}).then(response => {
|
||||
const cluster = response.addclusterresponse.cluster[0] || {}
|
||||
if (cluster.id && this.showDedicated) {
|
||||
this.dedicateCluster(cluster.id)
|
||||
}
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: `Error ${error.response.status}`,
|
||||
description: error.response.data.addclusterresponse.errortext,
|
||||
duration: 0
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.parentFetchData()
|
||||
this.parentToggleLoading()
|
||||
this.$parent.$parent.close()
|
||||
})
|
||||
},
|
||||
dedicateCluster (clusterId) {
|
||||
this.loading = true
|
||||
api('dedicateCluster', {
|
||||
clusterId,
|
||||
domainId: this.dedicatedDomainId,
|
||||
account: this.dedicatedAccount
|
||||
}).then(response => {
|
||||
this.$pollJob({
|
||||
jobId: response.dedicateclusterresponse.jobid,
|
||||
successMessage: `Successfully dedicated cluster`,
|
||||
successMethod: () => {
|
||||
this.loading = false
|
||||
this.$store.dispatch('AddAsyncJob', {
|
||||
title: 'Successfully dedicated cluster',
|
||||
jobid: response.dedicateclusterresponse.jobid,
|
||||
description: `Domain ID: ${this.dedicateddedicatedDomainId}`,
|
||||
status: 'progress'
|
||||
})
|
||||
},
|
||||
errorMessage: 'Failed to dedicate cluster',
|
||||
errorMethod: () => {
|
||||
this.loading = false
|
||||
},
|
||||
loadingMessage: `Dedicating cluster...`,
|
||||
catchMessage: 'Error encountered while fetching async job result',
|
||||
catchMethod: () => {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: `Error ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
})
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
resetAllFields () {
|
||||
this.clustertype = 'CloudManaged'
|
||||
this.username = null
|
||||
this.password = null
|
||||
this.url = null
|
||||
this.host = null
|
||||
this.dataCenter = null
|
||||
this.ovm3pool = null
|
||||
this.ovm3cluster = null
|
||||
this.ovm3vip = null
|
||||
},
|
||||
returnPlaceholder (field) {
|
||||
this.params.find(i => {
|
||||
if (i.name === field) this.placeholder[field] = i.description
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form {
|
||||
|
||||
&__label {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ant-select {
|
||||
width: 85vw;
|
||||
|
||||
@media (min-width: 760px) {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
button {
|
||||
&:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #ff0000;
|
||||
|
||||
&-label {
|
||||
display: none;
|
||||
|
||||
&--visible {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
|
||||
<div class="actions">
|
||||
<a-button @click="() => this.$parent.$parent.close()">{{ $t('cancel') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('OK') }}</a-button>
|
||||
<a-button @click="handleSubmit" type="primary">{{ $t('ok') }}</a-button>
|
||||
</div>
|
||||
|
||||
</a-form>
|
||||
|
|
@ -170,9 +170,9 @@ export default {
|
|||
})
|
||||
},
|
||||
toggleDedicate () {
|
||||
this.showDedicated = !this.showDedicated
|
||||
this.dedicatedDomainId = null
|
||||
this.dedicatedAccount = null
|
||||
this.showDedicated = !this.showDedicated
|
||||
},
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
|
|
@ -189,7 +189,7 @@ export default {
|
|||
endip: values.endip
|
||||
}).then(response => {
|
||||
const pod = response.createpodresponse.pod || {}
|
||||
if (pod && pod.id && this.showDedicated) {
|
||||
if (pod.id && this.showDedicated) {
|
||||
this.dedicatePod(pod.id)
|
||||
}
|
||||
this.loading = false
|
||||
|
|
|
|||
Loading…
Reference in New Issue