From 25311a729df6739c591658b72245a7280836ee5a Mon Sep 17 00:00:00 2001
From: ssongliu <73214554+ssongliu@users.noreply.github.com>
Date: Thu, 31 Oct 2024 22:22:03 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=87=E4=BB=BD=E8=B4=A6=E5=8F=B7?=
=?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=88=E6=8B=8D=E4=BA=91=20(#6911)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Refs #2698
---
agent/app/service/backup.go | 3 +
agent/constant/backup.go | 1 +
agent/go.mod | 1 +
agent/go.sum | 2 +
agent/utils/cloud_storage/client/up.go | 94 +++++++++++++++++++
.../cloud_storage/cloud_storage_client.go | 2 +
core/app/service/backup.go | 3 +
core/constant/common.go | 1 +
core/utils/cloud_storage/client/up.go | 47 ++++++++++
.../cloud_storage/cloud_storage_client.go | 2 +
frontend/src/lang/modules/en.ts | 3 +
frontend/src/lang/modules/tw.ts | 3 +
frontend/src/lang/modules/zh.ts | 3 +
.../setting/backup-account/operate/index.vue | 21 +++++
go.mod | 3 +-
go.sum | 2 +
16 files changed, 190 insertions(+), 1 deletion(-)
create mode 100644 agent/utils/cloud_storage/client/up.go
create mode 100644 core/utils/cloud_storage/client/up.go
diff --git a/agent/app/service/backup.go b/agent/app/service/backup.go
index 162c59f52..af3188555 100644
--- a/agent/app/service/backup.go
+++ b/agent/app/service/backup.go
@@ -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)
diff --git a/agent/constant/backup.go b/agent/constant/backup.go
index 37baa994e..8636226b1 100644
--- a/agent/constant/backup.go
+++ b/agent/constant/backup.go
@@ -13,6 +13,7 @@ const (
Kodo = "KODO"
WebDAV = "WebDAV"
Local = "LOCAL"
+ UPYUN = "UPYUN"
OneDriveRedirectURI = "http://localhost/login/authorized"
)
diff --git a/agent/go.mod b/agent/go.mod
index 33fd75995..a1d586f74 100644
--- a/agent/go.mod
+++ b/agent/go.mod
@@ -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
diff --git a/agent/go.sum b/agent/go.sum
index c39fc24f4..d5f32354c 100644
--- a/agent/go.sum
+++ b/agent/go.sum
@@ -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=
diff --git a/agent/utils/cloud_storage/client/up.go b/agent/utils/cloud_storage/client/up.go
new file mode 100644
index 000000000..d044f0c6f
--- /dev/null
+++ b/agent/utils/cloud_storage/client/up.go
@@ -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
+}
diff --git a/agent/utils/cloud_storage/cloud_storage_client.go b/agent/utils/cloud_storage/cloud_storage_client.go
index 0cc233858..5cc59f1c3 100644
--- a/agent/utils/cloud_storage/cloud_storage_client.go
+++ b/agent/utils/cloud_storage/cloud_storage_client.go
@@ -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
}
diff --git a/core/app/service/backup.go b/core/app/service/backup.go
index e249fe6d3..59204f4ed 100644
--- a/core/app/service/backup.go
+++ b/core/app/service/backup.go
@@ -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)
diff --git a/core/constant/common.go b/core/constant/common.go
index fdb09a806..10f2a9c7e 100644
--- a/core/constant/common.go
+++ b/core/constant/common.go
@@ -28,5 +28,6 @@ const (
Kodo = "KODO"
WebDAV = "WebDAV"
Local = "LOCAL"
+ UPYUN = "UPYUN"
OneDriveRedirectURI = "http://localhost/login/authorized"
)
diff --git a/core/utils/cloud_storage/client/up.go b/core/utils/cloud_storage/client/up.go
new file mode 100644
index 000000000..f96d5aa8e
--- /dev/null
+++ b/core/utils/cloud_storage/client/up.go
@@ -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
+}
diff --git a/core/utils/cloud_storage/cloud_storage_client.go b/core/utils/cloud_storage/cloud_storage_client.go
index 6c4cb4f26..912f3cc8f 100644
--- a/core/utils/cloud_storage/cloud_storage_client.go
+++ b/core/utils/cloud_storage/cloud_storage_client.go
@@ -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
}
diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index 23b8716d5..b096a07d9 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -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',
diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts
index 8114b446a..686845418 100644
--- a/frontend/src/lang/modules/tw.ts
+++ b/frontend/src/lang/modules/tw.ts
@@ -1364,6 +1364,9 @@ const message = {
SFTP: 'SFTP',
WebDAV: 'WebDAV',
WebDAVAlist: 'WebDAV 連接 Alist 可參考官方文檔',
+ UPYUN: '又拍雲',
+ serviceName: '服務名稱',
+ operator: '操作員',
OneDrive: '微軟 OneDrive',
isCN: '世紀互聯',
isNotCN: '國際版',
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 7a1231471..3de1445ff 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -1366,6 +1366,9 @@ const message = {
SFTP: 'SFTP',
WebDAV: 'WebDAV',
WebDAVAlist: 'WebDAV 连接 Alist 可参考官方文档',
+ UPYUN: '又拍云',
+ serviceName: '服务名称',
+ operator: '操作员',
OneDrive: '微软 OneDrive',
isCN: '世纪互联',
isNotCN: '国际版',
diff --git a/frontend/src/views/setting/backup-account/operate/index.vue b/frontend/src/views/setting/backup-account/operate/index.vue
index d67d51829..21b34bd44 100644
--- a/frontend/src/views/setting/backup-account/operate/index.vue
+++ b/frontend/src/views/setting/backup-account/operate/index.vue
@@ -16,6 +16,7 @@
+
@@ -24,6 +25,14 @@
+
+
+
+
+
+
+
+
{{ $t('commons.rule.requiredSelect') }}
+
+
+
{
+ 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';
diff --git a/go.mod b/go.mod
index 835d325d9..7d7bec108 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 15345a83a..86c7e4c97 100644
--- a/go.sum
+++ b/go.sum
@@ -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=