mirror of
https://github.com/rustfs/console.git
synced 2026-09-24 16:30:56 +08:00
feat :add aliyun tencent huaweicloud azure gcs r2 backend tier
This commit is contained in:
@@ -2,7 +2,12 @@
|
||||
<Modal v-model="visible" :title="t('Add Tier')" size="lg" :close-on-backdrop="false">
|
||||
<div class="space-y-6">
|
||||
<div v-if="!formData.type" class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div v-for="item in typeOptions" :key="item.value" class="cursor-pointer border border-border/70 transition hover:border-primary" @click="chooseType(item.value)">
|
||||
<div
|
||||
v-for="item in typeOptions"
|
||||
:key="item.value"
|
||||
class="cursor-pointer border border-border/70 transition hover:border-primary"
|
||||
@click="chooseType(item.value)"
|
||||
>
|
||||
<div class="flex items-center gap-3 p-4">
|
||||
<img :src="item.iconUrl" class="h-10 w-10" alt="" />
|
||||
<div>
|
||||
@@ -28,7 +33,12 @@
|
||||
<Field>
|
||||
<FieldLabel>{{ t('Name') }} (A-Z,0-9,_)</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input v-model="formData.name" :placeholder="t('Please enter name')" autocomplete="off" @input="filterName" />
|
||||
<Input
|
||||
v-model="formData.name"
|
||||
:placeholder="t('Please enter name')"
|
||||
autocomplete="off"
|
||||
@input="filterName"
|
||||
/>
|
||||
</FieldContent>
|
||||
<FieldDescription v-if="errors.name" class="text-destructive">
|
||||
{{ errors.name }}
|
||||
@@ -42,19 +52,40 @@
|
||||
</FieldContent>
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<FieldLabel>{{ t('Access Key') }}</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input v-model="formData.accesskey" :placeholder="t('Please enter Access Key')" autocomplete="off" />
|
||||
</FieldContent>
|
||||
</Field>
|
||||
<template v-if="isGCS">
|
||||
<Field>
|
||||
<FieldLabel>{{ t('Credentials') }} (JSON)</FieldLabel>
|
||||
<FieldContent>
|
||||
<Textarea
|
||||
v-model="formData.creds"
|
||||
:placeholder="t('Please enter GCS credentials JSON')"
|
||||
autocomplete="off"
|
||||
:rows="6"
|
||||
/>
|
||||
</FieldContent>
|
||||
</Field>
|
||||
</template>
|
||||
|
||||
<Field>
|
||||
<FieldLabel>{{ t('Secret Key') }}</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input v-model="formData.secretkey" type="password" autocomplete="off" :placeholder="t('Please enter Secret Key')" />
|
||||
</FieldContent>
|
||||
</Field>
|
||||
<template v-else>
|
||||
<Field>
|
||||
<FieldLabel>{{ t('Access Key') }}</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input v-model="formData.accesskey" :placeholder="t('Please enter Access Key')" autocomplete="off" />
|
||||
</FieldContent>
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<FieldLabel>{{ t('Secret Key') }}</FieldLabel>
|
||||
<FieldContent>
|
||||
<Input
|
||||
v-model="formData.secretkey"
|
||||
type="password"
|
||||
autocomplete="off"
|
||||
:placeholder="t('Please enter Secret Key')"
|
||||
/>
|
||||
</FieldContent>
|
||||
</Field>
|
||||
</template>
|
||||
|
||||
<Field>
|
||||
<FieldLabel>{{ t('Bucket') }}</FieldLabel>
|
||||
@@ -101,13 +132,20 @@
|
||||
<script setup lang="ts">
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
|
||||
import { Field, FieldContent, FieldDescription, FieldLabel } from '@/components/ui/field'
|
||||
import { reactive, ref } from 'vue'
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import RustfsIcon from '~/assets/logo.svg'
|
||||
import AWSIcon from '~/assets/svg/aws.svg'
|
||||
import MinioIcon from '~/assets/svg/minio.svg'
|
||||
import AliyunIcon from '~/assets/svg/aliyun.svg'
|
||||
import TencentIcon from '~/assets/svg/tenxunyun.svg'
|
||||
import HuaweiIcon from '~/assets/svg/huaweiyun.svg'
|
||||
import AzureIcon from '~/assets/svg/azure.svg'
|
||||
import GoogleIcon from '~/assets/svg/google.svg'
|
||||
import CloudflareIcon from '~/assets/svg/cloudflare.svg'
|
||||
import Modal from '~/components/modal.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -118,6 +156,22 @@ const typeOptions = [
|
||||
{ label: t('RustFS'), value: 'rustfs', iconUrl: RustfsIcon, description: t('RustFS built-in cold storage') },
|
||||
{ label: t('Minio'), value: 'minio', iconUrl: MinioIcon, description: t('External MinIO tier') },
|
||||
{ label: t('AWS S3'), value: 's3', iconUrl: AWSIcon, description: t('Standard AWS S3 tier') },
|
||||
{
|
||||
label: t('Aliyun OSS'),
|
||||
value: 'aliyun',
|
||||
iconUrl: AliyunIcon,
|
||||
description: t('Alibaba Cloud Object Storage Service'),
|
||||
},
|
||||
{ label: t('Tencent COS'), value: 'tencent', iconUrl: TencentIcon, description: t('Tencent Cloud Object Storage') },
|
||||
{
|
||||
label: t('Huawei OBS'),
|
||||
value: 'huaweicloud',
|
||||
iconUrl: HuaweiIcon,
|
||||
description: t('Huawei Cloud Object Storage Service'),
|
||||
},
|
||||
{ label: t('Azure Blob'), value: 'azure', iconUrl: AzureIcon, description: t('Microsoft Azure Blob Storage') },
|
||||
{ label: t('Google Cloud Storage'), value: 'gcs', iconUrl: GoogleIcon, description: t('Google Cloud Storage') },
|
||||
{ label: t('Cloudflare R2'), value: 'r2', iconUrl: CloudflareIcon, description: t('Cloudflare R2 Storage') },
|
||||
]
|
||||
|
||||
const visible = ref(false)
|
||||
@@ -130,12 +184,15 @@ const formData = reactive({
|
||||
endpoint: '',
|
||||
accesskey: '',
|
||||
secretkey: '',
|
||||
creds: '',
|
||||
bucket: '',
|
||||
prefix: '',
|
||||
region: '',
|
||||
storageclass: 'STANDARD',
|
||||
})
|
||||
|
||||
const isGCS = computed(() => formData.type === 'gcs')
|
||||
|
||||
const errors = reactive({
|
||||
name: '',
|
||||
})
|
||||
@@ -160,6 +217,7 @@ const resetForm = () => {
|
||||
formData.endpoint = ''
|
||||
formData.accesskey = ''
|
||||
formData.secretkey = ''
|
||||
formData.creds = ''
|
||||
formData.bucket = ''
|
||||
formData.prefix = ''
|
||||
formData.region = ''
|
||||
@@ -188,18 +246,25 @@ const handleSave = async () => {
|
||||
if (!validate()) return
|
||||
submitting.value = true
|
||||
try {
|
||||
const config: any = {
|
||||
name: formData.name,
|
||||
endpoint: formData.endpoint,
|
||||
bucket: formData.bucket,
|
||||
prefix: formData.prefix,
|
||||
region: formData.region,
|
||||
storageClass: formData.storageclass,
|
||||
}
|
||||
|
||||
if (isGCS.value) {
|
||||
config.creds = formData.creds
|
||||
} else {
|
||||
config.accessKey = formData.accesskey
|
||||
config.secretKey = formData.secretkey
|
||||
}
|
||||
|
||||
const payload = {
|
||||
type: formData.type,
|
||||
[formData.type]: {
|
||||
name: formData.name,
|
||||
endpoint: formData.endpoint,
|
||||
bucket: formData.bucket,
|
||||
prefix: formData.prefix,
|
||||
region: formData.region,
|
||||
accessKey: formData.accesskey,
|
||||
secretKey: formData.secretkey,
|
||||
storageClass: formData.storageclass,
|
||||
},
|
||||
[formData.type]: config,
|
||||
}
|
||||
|
||||
await usetier.addTiers(payload)
|
||||
|
||||
Reference in New Issue
Block a user