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

Reply via email to