mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
UI: Add s3 provider option to create secondary storage (#5726)
* add s3 provider option to create secondary storage * fixes label name * add storagepolicy for swift provider
This commit is contained in:
parent
946f9156e5
commit
0f926b5d68
@ -2949,6 +2949,9 @@
|
||||
"message.error.retrieve.kubeconfig": "Unable to retrieve Kubernetes cluster config",
|
||||
"message.error.s3nfs.path": "Please enter S3 NFS Path",
|
||||
"message.error.s3nfs.server": "Please enter S3 NFS Server",
|
||||
"message.error.swift.account": "Please enter account",
|
||||
"message.error.swift.key": "Please enter key",
|
||||
"message.error.swift.username": "Please enter username",
|
||||
"message.error.save.setting": "There was an error saving this setting.",
|
||||
"message.error.sbdomain": "Please enter SMB Domain",
|
||||
"message.error.sbdomain.password": "Please enter SMB Domain Password",
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
>{{ prov }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<div v-if="provider !== 'Swift'">
|
||||
<div v-if="!['Swift', 'S3'].includes(provider)">
|
||||
<a-form-item :label="$t('label.zone')">
|
||||
<a-select
|
||||
v-decorator="[
|
||||
@ -163,6 +163,91 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="provider === 'S3'">
|
||||
<a-form-item :label="$t('label.zone')">
|
||||
<a-select
|
||||
v-decorator="[
|
||||
'zone',
|
||||
{
|
||||
initialValue: this.zoneSelected,
|
||||
rules: [{ required: true, message: `${$t('label.required')}`}]
|
||||
}]"
|
||||
@change="val => { zoneSelected = val }"
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
:filterOption="(input, option) => {
|
||||
return option.componentOptions.propsData.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option
|
||||
:value="zone.id"
|
||||
v-for="(zone) in zones"
|
||||
:key="zone.id"
|
||||
:label="zone.name">
|
||||
<span>
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.access.key')">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'secondaryStorageAccessKey',
|
||||
{
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.secret.key')">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'secondaryStorageSecretKey',
|
||||
{
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.bucket')">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'secondaryStorageBucket',
|
||||
{
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.endpoint')">
|
||||
<a-input v-decorator="['secondaryStorageEndpoint']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.use.https')">
|
||||
<a-switch v-decorator="['secondaryStorageHttps', { initialValue: true }]" :default-checked="true" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.connection.timeout')">
|
||||
<a-input v-decorator="['secondaryStorageConnectionTimeout']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.max.error.retry')">
|
||||
<a-input v-decorator="['secondaryStorageMaxError']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.socket.timeout')">
|
||||
<a-input v-decorator="['secondaryStorageSocketTimeout']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.create.nfs.secondary.staging.storage')">
|
||||
<a-switch v-decorator="['secondaryStorageNFSStaging']" @change="val => secondaryStorageNFSStaging = val" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="secondaryStorageNFSStaging">
|
||||
<a-form-item :label="$t('label.s3.nfs.server')">
|
||||
<a-input
|
||||
v-decorator="['secondaryStorageNFSServer', {
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.nfs.path')">
|
||||
<a-input
|
||||
v-decorator="['secondaryStorageNFSPath', {
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div :span="24" class="action-button">
|
||||
<a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
|
||||
<a-button type="primary" ref="submit" @click="handleSubmit">{{ $t('label.ok') }}</a-button>
|
||||
@ -189,11 +274,12 @@ export default {
|
||||
inject: ['parentFetchData'],
|
||||
data () {
|
||||
return {
|
||||
providers: ['NFS', 'SMB/CIFS', 'Swift'],
|
||||
providers: ['NFS', 'SMB/CIFS', 'S3', 'Swift'],
|
||||
provider: '',
|
||||
zones: [],
|
||||
zoneSelected: '',
|
||||
loading: false
|
||||
loading: false,
|
||||
secondaryStorageNFSStaging: false
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
@ -245,7 +331,7 @@ export default {
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
if (this.loading) return
|
||||
this.form.validateFieldsAndScroll((err, values) => {
|
||||
this.form.validateFieldsAndScroll(async (err, values) => {
|
||||
if (err) {
|
||||
return
|
||||
}
|
||||
@ -283,26 +369,100 @@ export default {
|
||||
data['details[' + index.toString() + '].key'] = key
|
||||
data['details[' + index.toString() + '].value'] = swiftParams[key]
|
||||
})
|
||||
} else if (provider === 'S3') {
|
||||
let detailIdx = 0
|
||||
const s3Params = {
|
||||
accesskey: values.secondaryStorageAccessKey,
|
||||
secretkey: values.secondaryStorageSecretKey,
|
||||
bucket: values.secondaryStorageBucket,
|
||||
usehttps: values.secondaryStorageHttps ? values.secondaryStorageHttps : false
|
||||
}
|
||||
Object.keys(s3Params).forEach((key, index) => {
|
||||
data['details[' + index.toString() + '].key'] = key
|
||||
data['details[' + index.toString() + '].value'] = s3Params[key]
|
||||
detailIdx = index
|
||||
})
|
||||
|
||||
if (values.secondaryStorageEndpoint && values.secondaryStorageEndpoint.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'endpoint'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageEndpoint
|
||||
}
|
||||
|
||||
if (values.secondaryStorageConnectionTimeout && values.secondaryStorageConnectionTimeout.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'connectiontimeout'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageConnectionTimeout
|
||||
}
|
||||
|
||||
if (values.secondaryStorageMaxError && values.secondaryStorageMaxError.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'maxerrorretry'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageMaxError
|
||||
}
|
||||
|
||||
if (values.secondaryStorageSocketTimeout && values.secondaryStorageSocketTimeout.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'sockettimeout'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageSocketTimeout
|
||||
}
|
||||
}
|
||||
|
||||
data.url = url
|
||||
if (provider !== 'S3') {
|
||||
data.url = url
|
||||
}
|
||||
data.provider = provider
|
||||
if (values.zone && provider !== 'Swift') {
|
||||
if (values.zone && !['Swift', 'S3'].includes(provider)) {
|
||||
data.zoneid = values.zone
|
||||
}
|
||||
|
||||
const nfsParams = {}
|
||||
if (values.secondaryStorageNFSStaging) {
|
||||
const nfsServer = values.secondaryStorageNFSServer
|
||||
const path = values.secondaryStorageNFSPath
|
||||
const nfsUrl = this.nfsURL(nfsServer, path)
|
||||
|
||||
nfsParams.provider = 'nfs'
|
||||
nfsParams.zoneid = values.zone
|
||||
nfsParams.url = nfsUrl
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
api('addImageStore', data).then(json => {
|
||||
|
||||
try {
|
||||
await this.addImageStore(data)
|
||||
|
||||
if (values.secondaryStorageNFSStaging) {
|
||||
await this.createSecondaryStagingStore(nfsParams)
|
||||
}
|
||||
this.$notification.success({
|
||||
message: this.$t('label.add.secondary.storage'),
|
||||
description: this.$t('label.add.secondary.storage')
|
||||
})
|
||||
this.loading = false
|
||||
this.closeModal()
|
||||
this.parentFetchData()
|
||||
}).catch(error => {
|
||||
} catch (error) {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
addImageStore (params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('addImageStore', params).then(json => {
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
createSecondaryStagingStore (params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('createSecondaryStagingStore', params).then(json => {
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -216,21 +216,19 @@ export default {
|
||||
if (!conditions || Object.keys(conditions).length === 0) {
|
||||
return true
|
||||
}
|
||||
let isShow = false
|
||||
let isShow = true
|
||||
Object.keys(conditions).forEach(key => {
|
||||
const condition = conditions[key]
|
||||
const fieldVal = this.form.getFieldValue(key)
|
||||
? this.form.getFieldValue(key)
|
||||
: (this.prefillContent[key] ? this.prefillContent[key].value : null)
|
||||
if (Array.isArray(condition) && condition.includes(fieldVal)) {
|
||||
isShow = true
|
||||
return false
|
||||
} else if (!Array.isArray(condition) && fieldVal === condition) {
|
||||
isShow = true
|
||||
return false
|
||||
if (isShow) {
|
||||
const condition = conditions[key]
|
||||
const fieldVal = this.form.getFieldValue(key)
|
||||
? this.form.getFieldValue(key)
|
||||
: (this.prefillContent[key] ? this.prefillContent[key].value : null)
|
||||
if (Array.isArray(condition) && !condition.includes(fieldVal)) {
|
||||
isShow = false
|
||||
} else if (!Array.isArray(condition) && fieldVal !== condition) {
|
||||
isShow = false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return isShow
|
||||
|
||||
@ -570,7 +570,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.access_key',
|
||||
title: 'label.s3.access.key',
|
||||
key: 'secondaryStorageAccessKey',
|
||||
required: true,
|
||||
placeHolder: 'message.error.access.key',
|
||||
@ -579,7 +579,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.secret_key',
|
||||
title: 'label.s3.secret.key',
|
||||
key: 'secondaryStorageSecretKey',
|
||||
required: true,
|
||||
placeHolder: 'message.error.secret.key',
|
||||
@ -605,7 +605,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.use_https',
|
||||
title: 'label.s3.use.https',
|
||||
key: 'secondaryStorageHttps',
|
||||
required: false,
|
||||
switch: true,
|
||||
@ -615,7 +615,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.connection_timeoutt',
|
||||
title: 'label.s3.connection.timeout',
|
||||
key: 'secondaryStorageConnectionTimeout',
|
||||
required: false,
|
||||
display: {
|
||||
@ -623,7 +623,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.max_error_retry',
|
||||
title: 'label.s3.max.error.retry',
|
||||
key: 'secondaryStorageMaxError',
|
||||
required: false,
|
||||
display: {
|
||||
@ -631,7 +631,7 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.socket_timeout',
|
||||
title: 'label.s3.socket.timeout',
|
||||
key: 'secondaryStorageSocketTimeout',
|
||||
required: false,
|
||||
display: {
|
||||
@ -653,7 +653,8 @@ export default {
|
||||
required: true,
|
||||
placeHolder: 'message.error.s3nfs.server',
|
||||
display: {
|
||||
secondaryStorageProvider: ['S3']
|
||||
secondaryStorageProvider: ['S3'],
|
||||
secondaryStorageNFSStaging: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -662,7 +663,8 @@ export default {
|
||||
required: true,
|
||||
placeHolder: 'message.error.s3nfs.path',
|
||||
display: {
|
||||
secondaryStorageProvider: ['S3']
|
||||
secondaryStorageProvider: ['S3'],
|
||||
secondaryStorageNFSStaging: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -677,7 +679,8 @@ export default {
|
||||
{
|
||||
title: 'label.account',
|
||||
key: 'secondaryStorageAccount',
|
||||
required: false,
|
||||
required: true,
|
||||
placeHolder: 'message.error.swift.account',
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
}
|
||||
@ -685,7 +688,8 @@ export default {
|
||||
{
|
||||
title: 'label.username',
|
||||
key: 'secondaryStorageUsername',
|
||||
required: false,
|
||||
required: true,
|
||||
placeHolder: 'message.error.swift.username',
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
}
|
||||
@ -693,6 +697,15 @@ export default {
|
||||
{
|
||||
title: 'label.key',
|
||||
key: 'secondaryStorageKey',
|
||||
required: true,
|
||||
placeHolder: 'message.error.swift.key',
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.storagepolicy',
|
||||
key: 'secondaryStoragePolicy',
|
||||
required: false,
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
|
||||
@ -1471,6 +1471,12 @@ export default {
|
||||
params['details[' + index.toString() + '].value'] = this.prefillContent.secondaryStorageKey.value
|
||||
index++
|
||||
}
|
||||
if (this.prefillContent.secondaryStoragePolicy &&
|
||||
this.prefillContent.secondaryStoragePolicy.value.length > 0) {
|
||||
params['details[' + index.toString() + '].key'] = 'storagepolicy'
|
||||
params['details[' + index.toString() + '].value'] = this.prefillContent.secondaryStoragePolicy.value
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user