This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack-primate.git
The following commit(s) were added to refs/heads/master by this push:
new 67353ec infra: add cluster form (#114)
67353ec is described below
commit 67353ecfc03eabb6ceca2d48a735c8b3976e8c92
Author: Ritchie Vincent <[email protected]>
AuthorDate: Sat Feb 15 11:05:04 2020 +0000
infra: add cluster form (#114)
This adds the add cluster form with domain/account dedication option.
Signed-off-by: Rohit Yadav <[email protected]>
Co-authored-by: Rohit Yadav <[email protected]>
---
src/components/view/DedicateData.vue | 8 +-
src/components/view/DetailsTab.vue | 8 +-
src/config/section/infra/clusters.js | 3 +-
src/locales/en.json | 4 +-
src/views/infra/ClusterAdd.vue | 365 +++++++++++++++++++++++++++++++++++
src/views/infra/PodAdd.vue | 6 +-
6 files changed, 383 insertions(+), 11 deletions(-)
diff --git a/src/components/view/DedicateData.vue
b/src/components/view/DedicateData.vue
index 2d6e3a7..28ff13e 100644
--- a/src/components/view/DedicateData.vue
+++ b/src/components/view/DedicateData.vue
@@ -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
}
diff --git a/src/components/view/DetailsTab.vue
b/src/components/view/DetailsTab.vue
index abca482..641b671 100644
--- a/src/components/view/DetailsTab.vue
+++ b/src/components/view/DetailsTab.vue
@@ -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)
}
}
}
diff --git a/src/config/section/infra/clusters.js
b/src/config/section/infra/clusters.js
index 2c3216a..6ea959c 100644
--- a/src/config/section/infra/clusters.js
+++ b/src/config/section/infra/clusters.js
@@ -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',
diff --git a/src/locales/en.json b/src/locales/en.json
index 82988b6..8e8352d 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -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",
diff --git a/src/views/infra/ClusterAdd.vue b/src/views/infra/ClusterAdd.vue
new file mode 100644
index 0000000..c2cc465
--- /dev/null
+++ b/src/views/infra/ClusterAdd.vue
@@ -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>
diff --git a/src/views/infra/PodAdd.vue b/src/views/infra/PodAdd.vue
index 0f78f0b..1e82f64 100644
--- a/src/views/infra/PodAdd.vue
+++ b/src/views/infra/PodAdd.vue
@@ -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