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 71ffbcb infra: Add pod form (#123)
71ffbcb is described below
commit 71ffbcb78ea5971b60da9791fc7f7e3755a63279
Author: Ritchie Vincent <[email protected]>
AuthorDate: Sat Feb 15 10:01:54 2020 +0000
infra: Add pod form (#123)
This implements the add pod form with dedicate to domain/account option.
Signed-off-by: Rohit Yadav <[email protected]>
Co-authored-by: Rohit Yadav <[email protected]>
---
src/config/section/infra/pods.js | 3 +-
src/utils/plugins.js | 3 +-
src/views/infra/PodAdd.vue | 303 +++++++++++++++++++++++++++++++++++++++
3 files changed, 307 insertions(+), 2 deletions(-)
diff --git a/src/config/section/infra/pods.js b/src/config/section/infra/pods.js
index ad2cfc9..67f1976 100644
--- a/src/config/section/infra/pods.js
+++ b/src/config/section/infra/pods.js
@@ -37,7 +37,8 @@ export default {
icon: 'plus',
label: 'label.add.pod',
listView: true,
- args: ['zoneid', 'name', 'gateway', 'netmask', 'startip', 'endip']
+ popup: true,
+ component: () => import('@/views/infra/PodAdd.vue')
},
{
api: 'updatePod',
diff --git a/src/utils/plugins.js b/src/utils/plugins.js
index c0081e0..6c69cf1 100644
--- a/src/utils/plugins.js
+++ b/src/utils/plugins.js
@@ -68,7 +68,8 @@ export const pollJobPlugin = {
console.error(`${catchMessage} - ${e}`)
notification.error({
message: 'Error',
- description: catchMessage
+ description: catchMessage,
+ duration: 0
})
catchMethod && catchMethod()
})
diff --git a/src/views/infra/PodAdd.vue b/src/views/infra/PodAdd.vue
new file mode 100644
index 0000000..0f78f0b
--- /dev/null
+++ b/src/views/infra/PodAdd.vue
@@ -0,0 +1,303 @@
+// 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">
+ <a-form :form="form" layout="vertical" class="form">
+
+ <a-form-item class="form__item" :label="$t('zone')">
+ <a-select
+ v-decorator="['zoneid', {
+ initialValue: this.zoneId,
+ rules: [{ required: true, message: 'required' }] }
+ ]">
+ <a-select-option
+ v-for="zone in zonesList"
+ :value="zone.id"
+ :key="zone.id">
+ {{ zone.name }}
+ </a-select-option>
+ </a-select>
+ </a-form-item>
+
+ <a-form-item class="form__item" :label="$t('podname')">
+ <a-input
+ :placeholder="placeholder.name"
+ v-decorator="[
+ 'name',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+
+ <a-form-item class="form__item" :label="$t('reservedSystemGateway')">
+ <a-input
+ :placeholder="placeholder.gateway"
+ v-decorator="[
+ 'gateway',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+
+ <a-form-item class="form__item" :label="$t('reservedSystemNetmask')">
+ <a-input
+ :placeholder="placeholder.netmask"
+ v-decorator="[
+ 'netmask',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+
+ <a-form-item class="form__item" :label="$t('reservedSystemStartIp')">
+ <a-input
+ :placeholder="placeholder.startip"
+ v-decorator="[
+ 'startip',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+
+ <a-form-item class="form__item" :label="$t('reservedSystemEndIp')">
+ <a-input
+ :placeholder="placeholder.endip"
+ v-decorator="['endip']"
+ />
+ </a-form-item>
+
+ <div class="form__item">
+ <div class="form__label">{{ $t('isDedicated') }}</div>
+ <a-checkbox @change="toggleDedicate" />
+ </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="handleSubmit" type="primary">{{ $t('OK')
}}</a-button>
+ </div>
+
+ </a-form>
+ </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'],
+ data () {
+ return {
+ loading: false,
+ zonesList: [],
+ zoneId: null,
+ showDedicated: false,
+ dedicatedDomainId: null,
+ dedicatedAccount: null,
+ domainError: false,
+ params: [],
+ placeholder: {
+ name: null,
+ gateway: null,
+ netmask: null,
+ startip: null,
+ endip: null
+ }
+ }
+ },
+ beforeCreate () {
+ this.form = this.$form.createForm(this)
+ },
+ mounted () {
+ this.fetchData()
+ },
+ methods: {
+ fetchData () {
+ this.fetchZones()
+ },
+ fetchZones () {
+ this.loading = true
+ api('listZones').then(response => {
+ this.zonesList = response.listzonesresponse.zone || []
+ this.zoneId = this.zonesList[0].id
+ this.params = this.$store.getters.apis.createPod.params
+ Object.keys(this.placeholder).forEach(item => {
this.returnPlaceholder(item) })
+ }).catch(error => {
+ this.$notification.error({
+ message: `Error ${error.response.status}`,
+ description: error.response.data.errorresponse.errortext
+ })
+ }).finally(() => {
+ this.loading = false
+ })
+ },
+ toggleDedicate () {
+ this.showDedicated = !this.showDedicated
+ this.dedicatedDomainId = null
+ this.dedicatedAccount = null
+ },
+ handleSubmit (e) {
+ e.preventDefault()
+ this.form.validateFields((err, values) => {
+ if (err) return
+
+ this.loading = true
+ api('createPod', {
+ zoneId: values.zoneid,
+ name: values.name,
+ gateway: values.gateway,
+ netmask: values.netmask,
+ startip: values.startip,
+ endip: values.endip
+ }).then(response => {
+ const pod = response.createpodresponse.pod || {}
+ if (pod && pod.id && this.showDedicated) {
+ this.dedicatePod(pod.id)
+ }
+ this.loading = false
+ this.parentFetchData()
+ this.$parent.$parent.close()
+ }).catch(error => {
+ this.$notification.error({
+ message: `Error ${error.response.status}`,
+ description: error.response.data.createpodresponse.errortext,
+ duration: 0
+ })
+ this.loading = false
+ this.parentFetchData()
+ this.$parent.$parent.close()
+ })
+ })
+ },
+ dedicatePod (podId) {
+ this.loading = true
+ api('dedicatePod', {
+ podId,
+ domainid: this.dedicatedDomainId,
+ account: this.dedicatedAccount
+ }).then(response => {
+ this.$pollJob({
+ jobId: response.dedicatepodresponse.jobid,
+ successMessage: `Successfully dedicated pod`,
+ successMethod: () => {
+ this.loading = false
+ this.$store.dispatch('AddAsyncJob', {
+ title: 'Successfully dedicated pod',
+ jobid: response.dedicatepodresponse.jobid,
+ description: `Domain ID: ${this.dedicatedDomainId}`,
+ status: 'progress'
+ })
+ },
+ errorMessage: 'Failed to dedicate pod',
+ 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
+ })
+ },
+ 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>