You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2020/01/22 08:41:57 UTC
[cloudstack-primate] branch master updated: infraa: add secondary
storage form (#121)
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 cb2be30 infraa: add secondary storage form (#121)
cb2be30 is described below
commit cb2be303e25085623e8b19b2dbfe22c8c70bff10
Author: Pearl Dsilva <pe...@gmail.com>
AuthorDate: Wed Jan 22 14:11:50 2020 +0530
infraa: add secondary storage form (#121)
This implements the add secondary storage form
Signed-off-by: Rohit Yadav <ro...@shapeblue.com>
Co-authored-by: Rohit Yadav <ro...@apache.org>
---
src/config/section/infra/secondaryStorages.js | 3 +-
src/views/infra/AddSecondaryStorage.vue | 314 ++++++++++++++++++++++++++
2 files changed, 316 insertions(+), 1 deletion(-)
diff --git a/src/config/section/infra/secondaryStorages.js b/src/config/section/infra/secondaryStorages.js
index 0deea35..ffd8245 100644
--- a/src/config/section/infra/secondaryStorages.js
+++ b/src/config/section/infra/secondaryStorages.js
@@ -35,7 +35,8 @@ export default {
icon: 'plus',
label: 'label.add.secondary.storage',
listView: true,
- args: ['name', 'provider', 'zoneid', 'url', 'details']
+ popup: true,
+ component: () => import('@/views/infra/AddSecondaryStorage.vue')
},
{
api: 'deleteImageStore',
diff --git a/src/views/infra/AddSecondaryStorage.vue b/src/views/infra/AddSecondaryStorage.vue
new file mode 100644
index 0000000..6a97dd6
--- /dev/null
+++ b/src/views/infra/AddSecondaryStorage.vue
@@ -0,0 +1,314 @@
+// 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>
+ <div class="form-layout">
+ <a-spin :spinning="loading">
+ <a-form :form="form" layout="vertical">
+ <a-form-item :label="$t('name')">
+ <a-input v-decorator="['name']" />
+ </a-form-item>
+ <a-form-item :label="$t('providername')">
+ <a-select
+ v-decorator="[
+ 'provider',
+ {
+ initialValue: 'NFS'
+ }]"
+ @change="val => { this.provider = val }"
+ >
+ <a-select-option
+ :value="prov"
+ v-for="(prov,idx) in providers"
+ :key="idx"
+ >{{ prov }}</a-select-option>
+ </a-select>
+ </a-form-item>
+ <div v-if="provider !== 'Swift'">
+ <a-form-item :label="$t('zone')">
+ <a-select
+ v-decorator="[
+ 'zone',
+ {
+ initialValue: this.zoneSelected,
+ rules: [{ required: true, message: 'required'}]
+ }]"
+ >
+ <a-select-option
+ :value="zone.id"
+ v-for="(zone) in zones"
+ :key="zone.id"
+ >{{ zone.name }}</a-select-option>
+ </a-select>
+ </a-form-item>
+ <a-form-item :label="$t('server')">
+ <a-input
+ v-decorator="[
+ 'server',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ <a-form-item :label="$t('path')">
+ <a-input
+ v-decorator="[
+ 'path',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ </div>
+ <div v-if="provider === 'SMB/CIFS'">
+ <a-form-item :label="$t('smbUsername')">
+ <a-input
+ v-decorator="[
+ 'smbUsername',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ <a-form-item :label="$t('smbPassword')">
+ <a-input-password
+ v-decorator="[
+ 'smbPassword',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ <a-form-item :label="$t('smbDomain')">
+ <a-input
+ v-decorator="[
+ 'smbDomain',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ </div>
+ <div v-if="provider === 'Swift'">
+ <a-form-item :label="$t('url')">
+ <a-input
+ v-decorator="[
+ 'url',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ <a-form-item :label="$t('account')">
+ <a-input
+ v-decorator="[
+ 'account',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ <a-form-item :label="$t('username')">
+ <a-input
+ v-decorator="[
+ 'username',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ <a-form-item :label="$t('key')">
+ <a-input
+ v-decorator="[
+ 'key',
+ {
+ rules: [{ required: true, message: 'required' }]
+ }]"
+ />
+ </a-form-item>
+ <a-form-item :label="$t('storagepolicy')">
+ <a-input
+ v-decorator="[
+ 'storagepolicy'
+ ]"
+ />
+ </a-form-item>
+ </div>
+ <div class="actions">
+ <a-button @click="closeModal">{{ $t('Cancel') }}</a-button>
+ <a-button type="primary" @click="handleSubmit">{{ $t('OK') }}</a-button>
+ </div>
+ </a-form>
+ </a-spin>
+ </div>
+</template>
+<script>
+import { api } from '@/api'
+
+export default {
+ name: 'AddSecondryStorage',
+ props: {
+ resource: {
+ type: Object,
+ required: true
+ }
+ },
+ inject: ['parentFetchData'],
+ data () {
+ return {
+ providers: ['NFS', 'SMB/CIFS', 'Swift'],
+ provider: '',
+ zones: [],
+ zoneSelected: '',
+ loading: false
+ }
+ },
+ beforeCreate () {
+ this.form = this.$form.createForm(this)
+ },
+ mounted () {
+ this.fetchData()
+ },
+ methods: {
+ fetchData () {
+ this.listZones()
+ },
+ closeModal () {
+ this.$parent.$parent.close()
+ },
+ listZones () {
+ api('listZones').then(json => {
+ if (json && json.listzonesresponse && json.listzonesresponse.zone) {
+ this.zones = json.listzonesresponse.zone
+ if (this.zones.length > 0) {
+ this.zoneSelected = this.zones[0].name
+ }
+ }
+ })
+ },
+ nfsURL (server, path) {
+ var url
+ if (path.substring(0, 1) !== '/') {
+ path = '/' + path
+ }
+ if (server.indexOf('://') === -1) {
+ url = 'nfs://' + server + path
+ } else {
+ url = server + path
+ }
+ return url
+ },
+ smbURL (server, path, smbUsername, smbPassword, smbDomain) {
+ var url = ''
+ if (path.substring(0, 1) !== '/') {
+ path = '/' + path
+ }
+ if (server.indexOf('://') === -1) {
+ url += 'cifs://'
+ }
+ url += (server + path)
+ return url
+ },
+ handleSubmit (e) {
+ e.preventDefault()
+ this.form.validateFields((err, values) => {
+ if (err) {
+ return
+ }
+
+ var data = {
+ name: values.name
+ }
+ var url = ''
+ var provider = values.provider
+ if (provider === 'NFS') {
+ url = this.nfsURL(values.server, values.path)
+ }
+ if (provider === 'SMB/CIFS') {
+ provider = 'SMB'
+ url = this.smbURL(values.server, values.path, values.smbUsername, values.smbPassword, values.smbDomain)
+ const smbParams = {
+ user: values.smbUsername,
+ password: values.smbPassword,
+ domain: values.smbDomain
+ }
+ Object.keys(smbParams).forEach((key, index) => {
+ data['details[' + index.toString() + '].key'] = key
+ data['details[' + index.toString() + '].value'] = smbParams[key]
+ })
+ }
+ if (provider === 'Swift') {
+ url = values.url
+ const swiftParams = {
+ account: values.account,
+ username: values.username,
+ key: values.key,
+ storagepolicy: values.storagepolicy
+ }
+ Object.keys(swiftParams).forEach((key, index) => {
+ data['details[' + index.toString() + '].key'] = key
+ data['details[' + index.toString() + '].value'] = swiftParams[key]
+ })
+ }
+
+ data.url = url
+ data.provider = provider
+ if (values.zone && provider !== 'Swift') {
+ data.zoneid = values.zone
+ }
+
+ this.loading = true
+ api('addImageStore', data).then(json => {
+ this.$notification.success({
+ message: this.$t('label.add.secondary.storage'),
+ description: this.$t('label.add.secondary.storage')
+ })
+ }).catch(error => {
+ this.$notification.error({
+ message: 'Request Failed',
+ description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
+ })
+ }).finally(() => {
+ this.loading = false
+ this.closeModal()
+ this.parentFetchData()
+ })
+ })
+ }
+ }
+}
+</script>
+<style lang="scss" scoped>
+.form-layout {
+ width: 85vw;
+
+ @media (min-width: 1000px) {
+ width: 35vw;
+ }
+}
+
+.actions {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 20px;
+ button {
+ &:not(:last-child) {
+ margin-right: 10px;
+ }
+ }
+}
+</style>