Skip to content

Commit 86a55ce

Browse files
Pearl1594yadvr
andcommitted
infraa: add secondary storage form (#121)
This implements the add secondary storage form Signed-off-by: Rohit Yadav <[email protected]> Co-authored-by: Rohit Yadav <[email protected]>
1 parent 1df0e0c commit 86a55ce

File tree

2 files changed

+316
-1
lines changed

2 files changed

+316
-1
lines changed

ui/src/config/section/infra/secondaryStorages.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export default {
3535
icon: 'plus',
3636
label: 'label.add.secondary.storage',
3737
listView: true,
38-
args: ['name', 'provider', 'zoneid', 'url', 'details']
38+
popup: true,
39+
component: () => import('@/views/infra/AddSecondaryStorage.vue')
3940
},
4041
{
4142
api: 'deleteImageStore',
Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
<template>
19+
<div class="form-layout">
20+
<a-spin :spinning="loading">
21+
<a-form :form="form" layout="vertical">
22+
<a-form-item :label="$t('name')">
23+
<a-input v-decorator="['name']" />
24+
</a-form-item>
25+
<a-form-item :label="$t('providername')">
26+
<a-select
27+
v-decorator="[
28+
'provider',
29+
{
30+
initialValue: 'NFS'
31+
}]"
32+
@change="val => { this.provider = val }"
33+
>
34+
<a-select-option
35+
:value="prov"
36+
v-for="(prov,idx) in providers"
37+
:key="idx"
38+
>{{ prov }}</a-select-option>
39+
</a-select>
40+
</a-form-item>
41+
<div v-if="provider !== 'Swift'">
42+
<a-form-item :label="$t('zone')">
43+
<a-select
44+
v-decorator="[
45+
'zone',
46+
{
47+
initialValue: this.zoneSelected,
48+
rules: [{ required: true, message: 'required'}]
49+
}]"
50+
>
51+
<a-select-option
52+
:value="zone.id"
53+
v-for="(zone) in zones"
54+
:key="zone.id"
55+
>{{ zone.name }}</a-select-option>
56+
</a-select>
57+
</a-form-item>
58+
<a-form-item :label="$t('server')">
59+
<a-input
60+
v-decorator="[
61+
'server',
62+
{
63+
rules: [{ required: true, message: 'required' }]
64+
}]"
65+
/>
66+
</a-form-item>
67+
<a-form-item :label="$t('path')">
68+
<a-input
69+
v-decorator="[
70+
'path',
71+
{
72+
rules: [{ required: true, message: 'required' }]
73+
}]"
74+
/>
75+
</a-form-item>
76+
</div>
77+
<div v-if="provider === 'SMB/CIFS'">
78+
<a-form-item :label="$t('smbUsername')">
79+
<a-input
80+
v-decorator="[
81+
'smbUsername',
82+
{
83+
rules: [{ required: true, message: 'required' }]
84+
}]"
85+
/>
86+
</a-form-item>
87+
<a-form-item :label="$t('smbPassword')">
88+
<a-input-password
89+
v-decorator="[
90+
'smbPassword',
91+
{
92+
rules: [{ required: true, message: 'required' }]
93+
}]"
94+
/>
95+
</a-form-item>
96+
<a-form-item :label="$t('smbDomain')">
97+
<a-input
98+
v-decorator="[
99+
'smbDomain',
100+
{
101+
rules: [{ required: true, message: 'required' }]
102+
}]"
103+
/>
104+
</a-form-item>
105+
</div>
106+
<div v-if="provider === 'Swift'">
107+
<a-form-item :label="$t('url')">
108+
<a-input
109+
v-decorator="[
110+
'url',
111+
{
112+
rules: [{ required: true, message: 'required' }]
113+
}]"
114+
/>
115+
</a-form-item>
116+
<a-form-item :label="$t('account')">
117+
<a-input
118+
v-decorator="[
119+
'account',
120+
{
121+
rules: [{ required: true, message: 'required' }]
122+
}]"
123+
/>
124+
</a-form-item>
125+
<a-form-item :label="$t('username')">
126+
<a-input
127+
v-decorator="[
128+
'username',
129+
{
130+
rules: [{ required: true, message: 'required' }]
131+
}]"
132+
/>
133+
</a-form-item>
134+
<a-form-item :label="$t('key')">
135+
<a-input
136+
v-decorator="[
137+
'key',
138+
{
139+
rules: [{ required: true, message: 'required' }]
140+
}]"
141+
/>
142+
</a-form-item>
143+
<a-form-item :label="$t('storagepolicy')">
144+
<a-input
145+
v-decorator="[
146+
'storagepolicy'
147+
]"
148+
/>
149+
</a-form-item>
150+
</div>
151+
<div class="actions">
152+
<a-button @click="closeModal">{{ $t('Cancel') }}</a-button>
153+
<a-button type="primary" @click="handleSubmit">{{ $t('OK') }}</a-button>
154+
</div>
155+
</a-form>
156+
</a-spin>
157+
</div>
158+
</template>
159+
<script>
160+
import { api } from '@/api'
161+
162+
export default {
163+
name: 'AddSecondryStorage',
164+
props: {
165+
resource: {
166+
type: Object,
167+
required: true
168+
}
169+
},
170+
inject: ['parentFetchData'],
171+
data () {
172+
return {
173+
providers: ['NFS', 'SMB/CIFS', 'Swift'],
174+
provider: '',
175+
zones: [],
176+
zoneSelected: '',
177+
loading: false
178+
}
179+
},
180+
beforeCreate () {
181+
this.form = this.$form.createForm(this)
182+
},
183+
mounted () {
184+
this.fetchData()
185+
},
186+
methods: {
187+
fetchData () {
188+
this.listZones()
189+
},
190+
closeModal () {
191+
this.$parent.$parent.close()
192+
},
193+
listZones () {
194+
api('listZones').then(json => {
195+
if (json && json.listzonesresponse && json.listzonesresponse.zone) {
196+
this.zones = json.listzonesresponse.zone
197+
if (this.zones.length > 0) {
198+
this.zoneSelected = this.zones[0].name
199+
}
200+
}
201+
})
202+
},
203+
nfsURL (server, path) {
204+
var url
205+
if (path.substring(0, 1) !== '/') {
206+
path = '/' + path
207+
}
208+
if (server.indexOf('://') === -1) {
209+
url = 'nfs://' + server + path
210+
} else {
211+
url = server + path
212+
}
213+
return url
214+
},
215+
smbURL (server, path, smbUsername, smbPassword, smbDomain) {
216+
var url = ''
217+
if (path.substring(0, 1) !== '/') {
218+
path = '/' + path
219+
}
220+
if (server.indexOf('://') === -1) {
221+
url += 'cifs://'
222+
}
223+
url += (server + path)
224+
return url
225+
},
226+
handleSubmit (e) {
227+
e.preventDefault()
228+
this.form.validateFields((err, values) => {
229+
if (err) {
230+
return
231+
}
232+
233+
var data = {
234+
name: values.name
235+
}
236+
var url = ''
237+
var provider = values.provider
238+
if (provider === 'NFS') {
239+
url = this.nfsURL(values.server, values.path)
240+
}
241+
if (provider === 'SMB/CIFS') {
242+
provider = 'SMB'
243+
url = this.smbURL(values.server, values.path, values.smbUsername, values.smbPassword, values.smbDomain)
244+
const smbParams = {
245+
user: values.smbUsername,
246+
password: values.smbPassword,
247+
domain: values.smbDomain
248+
}
249+
Object.keys(smbParams).forEach((key, index) => {
250+
data['details[' + index.toString() + '].key'] = key
251+
data['details[' + index.toString() + '].value'] = smbParams[key]
252+
})
253+
}
254+
if (provider === 'Swift') {
255+
url = values.url
256+
const swiftParams = {
257+
account: values.account,
258+
username: values.username,
259+
key: values.key,
260+
storagepolicy: values.storagepolicy
261+
}
262+
Object.keys(swiftParams).forEach((key, index) => {
263+
data['details[' + index.toString() + '].key'] = key
264+
data['details[' + index.toString() + '].value'] = swiftParams[key]
265+
})
266+
}
267+
268+
data.url = url
269+
data.provider = provider
270+
if (values.zone && provider !== 'Swift') {
271+
data.zoneid = values.zone
272+
}
273+
274+
this.loading = true
275+
api('addImageStore', data).then(json => {
276+
this.$notification.success({
277+
message: this.$t('label.add.secondary.storage'),
278+
description: this.$t('label.add.secondary.storage')
279+
})
280+
}).catch(error => {
281+
this.$notification.error({
282+
message: 'Request Failed',
283+
description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
284+
})
285+
}).finally(() => {
286+
this.loading = false
287+
this.closeModal()
288+
this.parentFetchData()
289+
})
290+
})
291+
}
292+
}
293+
}
294+
</script>
295+
<style lang="scss" scoped>
296+
.form-layout {
297+
width: 85vw;
298+
299+
@media (min-width: 1000px) {
300+
width: 35vw;
301+
}
302+
}
303+
304+
.actions {
305+
display: flex;
306+
justify-content: flex-end;
307+
margin-top: 20px;
308+
button {
309+
&:not(:last-child) {
310+
margin-right: 10px;
311+
}
312+
}
313+
}
314+
</style>

0 commit comments

Comments
 (0)