feat: 备份账号增加又拍云 (#6911)

Refs #2698
This commit is contained in:
ssongliu 2024-10-31 22:22:03 +08:00 committed by GitHub
parent 638f390308
commit 25311a729d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 190 additions and 1 deletions

View File

@ -401,6 +401,9 @@ func newClient(account *model.BackupAccount) (cloud_storage.CloudStorageClient,
case constant.OSS, constant.S3, constant.MinIo, constant.Cos, constant.Kodo:
varMap["accessKey"] = account.AccessKey
varMap["secretKey"] = account.Credential
case constant.UPYUN:
varMap["operator"] = account.AccessKey
varMap["password"] = account.Credential
}
client, err := cloud_storage.NewCloudStorageClient(account.Type, varMap)

View File

@ -13,6 +13,7 @@ const (
Kodo = "KODO"
WebDAV = "WebDAV"
Local = "LOCAL"
UPYUN = "UPYUN"
OneDriveRedirectURI = "http://localhost/login/authorized"
)

View File

@ -43,6 +43,7 @@ require (
github.com/studio-b12/gowebdav v0.9.0
github.com/subosito/gotenv v1.6.0
github.com/tencentyun/cos-go-sdk-v5 v0.7.54
github.com/upyun/go-sdk v2.1.0+incompatible
golang.org/x/crypto v0.25.0
golang.org/x/net v0.27.0
golang.org/x/oauth2 v0.21.0

View File

@ -753,6 +753,8 @@ github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/upyun/go-sdk v2.1.0+incompatible h1:OdjXghQ/TVetWV16Pz3C1/SUpjhGBVPr+cLiqZLLyq0=
github.com/upyun/go-sdk v2.1.0+incompatible/go.mod h1:eu3F5Uz4b9ZE5bE5QsCL6mgSNWRwfj0zpJ9J626HEqs=
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=

View File

@ -0,0 +1,94 @@
package client
import (
"path"
"github.com/upyun/go-sdk/upyun"
)
type upClient struct {
bucket string
client *upyun.UpYun
}
func NewUpClient(vars map[string]interface{}) (*upClient, error) {
operator := loadParamFromVars("operator", vars)
password := loadParamFromVars("password", vars)
bucket := loadParamFromVars("bucket", vars)
client := upyun.NewUpYun(&upyun.UpYunConfig{
Bucket: bucket,
Operator: operator,
Password: password,
})
return &upClient{bucket: bucket, client: client}, nil
}
func (o upClient) ListBuckets() ([]interface{}, error) {
var result []interface{}
return result, nil
}
func (s upClient) Upload(src, target string) (bool, error) {
if _, err := s.client.GetInfo(path.Dir(src)); err != nil {
_ = s.client.Mkdir(path.Dir(src))
}
if err := s.client.Put(&upyun.PutObjectConfig{
Path: target,
LocalPath: src,
UseResumeUpload: true,
}); err != nil {
return false, err
}
return true, nil
}
func (s upClient) Size(path string) (int64, error) {
fileInfo, err := s.client.GetInfo(path)
if err != nil {
return 0, err
}
return fileInfo.Size, nil
}
func (s upClient) Delete(path string) (bool, error) {
if err := s.client.Delete(&upyun.DeleteObjectConfig{
Path: path,
}); err != nil {
return false, err
}
return true, nil
}
func (s upClient) Exist(filePath string) (bool, error) {
if _, err := s.client.GetInfo(filePath); err != nil {
return false, err
}
return true, nil
}
func (s upClient) Download(src, target string) (bool, error) {
if _, err := s.client.Get(&upyun.GetObjectConfig{
Path: src,
LocalPath: target,
}); err != nil {
return false, err
}
return true, nil
}
func (s *upClient) ListObjects(prefix string) ([]string, error) {
objsChan := make(chan *upyun.FileInfo, 10)
if err := s.client.List(&upyun.GetObjectsConfig{
Path: prefix,
ObjectsChan: objsChan,
MaxListTries: 1,
}); err != nil {
return nil, err
}
var files []string
for obj := range objsChan {
files = append(files, obj.Name)
}
return files, nil
}

View File

@ -36,6 +36,8 @@ func NewCloudStorageClient(backupType string, vars map[string]interface{}) (Clou
return client.NewKodoClient(vars)
case constant.OneDrive:
return client.NewOneDriveClient(vars)
case constant.UPYUN:
return client.NewUpClient(vars)
default:
return nil, constant.ErrNotSupportType
}

View File

@ -378,6 +378,9 @@ func (u *BackupService) NewClient(backup *model.BackupAccount) (cloud_storage.Cl
case constant.OSS, constant.S3, constant.MinIo, constant.Cos, constant.Kodo:
varMap["accessKey"] = backup.AccessKey
varMap["secretKey"] = backup.Credential
case constant.UPYUN:
varMap["operator"] = backup.AccessKey
varMap["password"] = backup.Credential
}
backClient, err := cloud_storage.NewCloudStorageClient(backup.Type, varMap)

View File

@ -28,5 +28,6 @@ const (
Kodo = "KODO"
WebDAV = "WebDAV"
Local = "LOCAL"
UPYUN = "UPYUN"
OneDriveRedirectURI = "http://localhost/login/authorized"
)

View File

@ -0,0 +1,47 @@
package client
import (
"fmt"
"path"
"github.com/upyun/go-sdk/upyun"
)
type upClient struct {
bucket string
client *upyun.UpYun
}
func NewUpClient(vars map[string]interface{}) (*upClient, error) {
operator := loadParamFromVars("operator", vars)
password := loadParamFromVars("password", vars)
bucket := loadParamFromVars("bucket", vars)
client := upyun.NewUpYun(&upyun.UpYunConfig{
Bucket: bucket,
Operator: operator,
Password: password,
UserAgent: "1panel-son.test.upcdn.net",
})
return &upClient{bucket: bucket, client: client}, nil
}
func (o upClient) ListBuckets() ([]interface{}, error) {
var result []interface{}
return result, nil
}
func (s upClient) Upload(src, target string) (bool, error) {
if _, err := s.client.GetInfo(path.Dir(target)); err != nil {
if err := s.client.Mkdir(path.Dir(target)); err != nil {
fmt.Println(err)
}
}
if err := s.client.Put(&upyun.PutObjectConfig{
Path: target,
LocalPath: src,
}); err != nil {
return false, err
}
return true, nil
}

View File

@ -30,6 +30,8 @@ func NewCloudStorageClient(backupType string, vars map[string]interface{}) (Clou
return client.NewKodoClient(vars)
case constant.OneDrive:
return client.NewOneDriveClient(vars)
case constant.UPYUN:
return client.NewUpClient(vars)
default:
return nil, constant.ErrNotSupportType
}

View File

@ -1451,6 +1451,9 @@ const message = {
SFTP: 'SFTP',
WebDAV: 'WebDAV',
WebDAVAlist: 'WebDAV connect Alist can refer to the official documentation',
UPYUN: 'UPYUN',
serviceName: 'Service Name',
operator: 'Operator',
OneDrive: 'Microsoft OneDrive',
isCN: 'Century Internet',
isNotCN: 'International Version',

View File

@ -1364,6 +1364,9 @@ const message = {
SFTP: 'SFTP',
WebDAV: 'WebDAV',
WebDAVAlist: 'WebDAV 連接 Alist 可參考官方文檔',
UPYUN: '又拍雲',
serviceName: '服務名稱',
operator: '操作員',
OneDrive: '微軟 OneDrive',
isCN: '世紀互聯',
isNotCN: '國際版',

View File

@ -1366,6 +1366,9 @@ const message = {
SFTP: 'SFTP',
WebDAV: 'WebDAV',
WebDAVAlist: 'WebDAV 连接 Alist 可参考官方文档',
UPYUN: '又拍云',
serviceName: '服务名称',
operator: '操作员',
OneDrive: '微软 OneDrive',
isCN: '世纪互联',
isNotCN: '国际版',

View File

@ -16,6 +16,7 @@
<el-option :label="$t('setting.S3')" value="S3"></el-option>
<el-option :label="$t('setting.SFTP')" value="SFTP"></el-option>
<el-option :label="$t('setting.WebDAV')" value="WebDAV"></el-option>
<el-option :label="$t('setting.UPYUN')" value="UPYUN"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="hasAccessKey()" label="Access Key ID" prop="accessKey" :rules="Rules.requiredInput">
@ -24,6 +25,14 @@
<el-form-item v-if="hasAccessKey()" label="Secret Key" prop="credential" :rules="Rules.requiredInput">
<el-input show-password clearable v-model.trim="dialogData.rowData!.credential" />
</el-form-item>
<div v-if="isUPYUN()">
<el-form-item :label="$t('setting.operator')" prop="accessKey" :rules="Rules.requiredInput">
<el-input clearable v-model.trim="dialogData.rowData!.accessKey" />
</el-form-item>
<el-form-item :label="$t('commons.login.password')" prop="credential" :rules="Rules.requiredInput">
<el-input show-password clearable v-model.trim="dialogData.rowData!.credential" />
</el-form-item>
</div>
<el-form-item
v-if="dialogData.rowData!.type === 'WebDAV'"
:label="$t('setting.address')"
@ -143,6 +152,14 @@
</el-button>
<span v-if="errBuckets" class="input-error">{{ $t('commons.rule.requiredSelect') }}</span>
</el-form-item>
<el-form-item
v-if="isUPYUN()"
:label="$t('setting.serviceName')"
prop="bucket"
:rules="Rules.requiredInput"
>
<el-input v-model="dialogData.rowData!.bucket" />
</el-form-item>
<el-form-item
v-if="dialogData.rowData!.type === 'COS'"
:label="$t('setting.scType')"
@ -420,6 +437,10 @@ function callback(error: any) {
}
}
const isUPYUN = () => {
let itemType = dialogData.value.rowData!.type;
return itemType === 'UPYUN';
};
const hasAccessKey = () => {
let itemType = dialogData.value.rowData!.type;
return itemType === 'COS' || itemType === 'KODO' || itemType === 'MINIO' || itemType === 'OSS' || itemType === 'S3';

3
go.mod
View File

@ -21,6 +21,7 @@ require (
github.com/minio/minio-go/v7 v7.0.74
github.com/mojocn/base64Captcha v1.3.6
github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/oschwald/maxminddb-golang v1.13.1
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.13.6
github.com/qiniu/go-sdk/v7 v7.21.1
@ -34,6 +35,7 @@ require (
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.3
github.com/tencentyun/cos-go-sdk-v5 v0.7.54
github.com/upyun/go-sdk v2.1.0+incompatible
github.com/xlzd/gotp v0.1.0
golang.org/x/crypto v0.24.0
golang.org/x/oauth2 v0.18.0
@ -99,7 +101,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mozillazg/go-httpheader v0.2.1 // indirect
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rs/xid v1.5.0 // indirect

2
go.sum
View File

@ -382,6 +382,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/upyun/go-sdk v2.1.0+incompatible h1:OdjXghQ/TVetWV16Pz3C1/SUpjhGBVPr+cLiqZLLyq0=
github.com/upyun/go-sdk v2.1.0+incompatible/go.mod h1:eu3F5Uz4b9ZE5bE5QsCL6mgSNWRwfj0zpJ9J626HEqs=
github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=