From 4806a57d92068567a155ca44d2eb1bb1e785bee7 Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:58:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=87=E4=BB=BD=E8=B4=A6=E5=8F=B7?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=A2=9E=E5=8A=A0=E4=B8=8A=E4=BC=A0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=20(#2585)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/service/backup.go | 54 ++++++++++++++++++++++++++--- backend/i18n/lang/en.yaml | 1 + backend/i18n/lang/zh-Hant.yaml | 1 + backend/i18n/lang/zh.yaml | 1 + frontend/src/api/modules/host.ts | 36 +++++++++---------- frontend/src/api/modules/setting.ts | 36 +++++++++---------- 6 files changed, 89 insertions(+), 40 deletions(-) diff --git a/backend/app/service/backup.go b/backend/app/service/backup.go index 34a9b777ce60..82291f59c6bc 100644 --- a/backend/app/service/backup.go +++ b/backend/app/service/backup.go @@ -1,6 +1,7 @@ package service import ( + "bufio" "context" "encoding/base64" "encoding/json" @@ -150,20 +151,26 @@ func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error) return targetPath, nil } -func (u *BackupService) Create(backupDto dto.BackupOperate) error { - backup, _ := backupRepo.Get(commonRepo.WithByType(backupDto.Type)) +func (u *BackupService) Create(req dto.BackupOperate) error { + backup, _ := backupRepo.Get(commonRepo.WithByType(req.Type)) if backup.ID != 0 { return constant.ErrRecordExist } - if err := copier.Copy(&backup, &backupDto); err != nil { + if err := copier.Copy(&backup, &req); err != nil { return errors.WithMessage(constant.ErrStructTransform, err.Error()) } - if backupDto.Type == constant.OneDrive { + if req.Type == constant.OneDrive { if err := u.loadAccessToken(&backup); err != nil { return err } } + if req.Type != "LOCAL" { + isOk, err := u.checkBackupConn(&backup) + if err != nil || !isOk { + return buserr.WithMap("ErrBackupCheck", map[string]interface{}{"err": err.Error()}, err) + } + } if err := backupRepo.Create(&backup); err != nil { return err } @@ -242,10 +249,15 @@ func (u *BackupService) Update(req dto.BackupOperate) error { } upMap := make(map[string]interface{}) upMap["bucket"] = req.Bucket + upMap["access_key"] = req.AccessKey upMap["credential"] = req.Credential upMap["backup_path"] = req.BackupPath upMap["vars"] = req.Vars + backup.Bucket = req.Bucket backup.Vars = req.Vars + backup.Credential = req.Credential + backup.AccessKey = req.AccessKey + backup.BackupPath = req.BackupPath if req.Type == constant.OneDrive { if err := u.loadAccessToken(&backup); err != nil { @@ -254,6 +266,13 @@ func (u *BackupService) Update(req dto.BackupOperate) error { upMap["credential"] = backup.Credential upMap["vars"] = backup.Vars } + if backup.Type != "LOCAL" { + isOk, err := u.checkBackupConn(&backup) + if err != nil || !isOk { + return buserr.WithMap("ErrBackupCheck", map[string]interface{}{"err": err.Error()}, err) + } + } + if err := backupRepo.Update(req.ID, upMap); err != nil { return err } @@ -441,3 +460,30 @@ func copyDir(src, dst string) error { return nil } + +func (u *BackupService) checkBackupConn(backup *model.BackupAccount) (bool, error) { + client, err := u.NewClient(backup) + if err != nil { + return false, err + } + fileItem := path.Join(global.CONF.System.TmpDir, "test", "1panel") + if _, err := os.Stat(path.Dir(fileItem)); err != nil && os.IsNotExist(err) { + if err = os.MkdirAll(path.Dir(fileItem), os.ModePerm); err != nil { + return false, err + } + } + file, err := os.OpenFile(fileItem, os.O_WRONLY|os.O_CREATE, 0666) + if err != nil { + return false, err + } + defer file.Close() + write := bufio.NewWriter(file) + _, _ = write.WriteString(string("1Panel 备份账号测试文件。\n")) + _, _ = write.WriteString(string("1Panel 備份賬號測試文件。\n")) + _, _ = write.WriteString(string("1Panel Backs up account test files.\n")) + _, _ = write.WriteString(string("1Panelアカウントのテストファイルをバックアップします。\n")) + write.Flush() + + targetPath := strings.TrimPrefix(path.Join(backup.BackupPath, "test/1panel"), "/") + return client.Upload(fileItem, targetPath) +} diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml index 4a7e0812e671..6ce197a34d56 100644 --- a/backend/i18n/lang/en.yaml +++ b/backend/i18n/lang/en.yaml @@ -113,6 +113,7 @@ ErrNodeModulesNotFound: "The node_modules folder does not exist! Please edit the #setting ErrBackupInUsed: "The backup account is already being used in a cronjob and cannot be deleted." +ErrBackupCheck: "Backup account test connection failed {{ .err}}" ErrOSSConn: "Unable to successfully request the latest version. Please check if the server can connect to the external network environment." ErrEntrance: "Security entrance information error. Please check and try again!" diff --git a/backend/i18n/lang/zh-Hant.yaml b/backend/i18n/lang/zh-Hant.yaml index ceef285a3c7b..0fdc0d6a013e 100644 --- a/backend/i18n/lang/zh-Hant.yaml +++ b/backend/i18n/lang/zh-Hant.yaml @@ -113,6 +113,7 @@ ErrNodeModulesNotFound: "node_modules 文件夾不存在!請編輯運行環境 #setting ErrBackupInUsed: "該備份帳號已在計劃任務中使用,無法刪除" +ErrBackupCheck: "備份帳號測試連接失敗 {{ .err}}" ErrOSSConn: "無法成功請求最新版本,請檢查伺服器是否能夠連接到外部網絡環境。" ErrEntrance: "安全入口信息錯誤,請檢查後重試!" diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml index 5dd79d8533f0..9a9cdc218e8f 100644 --- a/backend/i18n/lang/zh.yaml +++ b/backend/i18n/lang/zh.yaml @@ -113,6 +113,7 @@ ErrNodeModulesNotFound: "node_modules 文件夹不存在!请编辑运行环境 #setting ErrBackupInUsed: "该备份账号已在计划任务中使用,无法删除" +ErrBackupCheck: "备份账号测试连接失败 {{ .err}}" ErrOSSConn: "无法成功请求最新版本,请检查服务器是否能够连接到外部网络环境。" ErrEntrance: "安全入口信息错误,请检查后重试!" diff --git a/frontend/src/api/modules/host.ts b/frontend/src/api/modules/host.ts index 5875f3886aad..15a62ad46871 100644 --- a/frontend/src/api/modules/host.ts +++ b/frontend/src/api/modules/host.ts @@ -13,37 +13,37 @@ export const getHostTree = (params: Host.ReqSearch) => { return http.post>(`/hosts/tree`, params); }; export const addHost = (params: Host.HostOperate) => { - let reqest = deepCopy(params) as Host.HostOperate; - if (reqest.password) { - reqest.password = Base64.encode(reqest.password); + let request = deepCopy(params) as Host.HostOperate; + if (request.password) { + request.password = Base64.encode(request.password); } - if (reqest.privateKey) { - reqest.privateKey = Base64.encode(reqest.privateKey); + if (request.privateKey) { + request.privateKey = Base64.encode(request.privateKey); } - return http.post(`/hosts`, reqest); + return http.post(`/hosts`, request); }; export const testByInfo = (params: Host.HostConnTest) => { - let reqest = deepCopy(params) as Host.HostOperate; - if (reqest.password) { - reqest.password = Base64.encode(reqest.password); + let request = deepCopy(params) as Host.HostOperate; + if (request.password) { + request.password = Base64.encode(request.password); } - if (reqest.privateKey) { - reqest.privateKey = Base64.encode(reqest.privateKey); + if (request.privateKey) { + request.privateKey = Base64.encode(request.privateKey); } - return http.post(`/hosts/test/byinfo`, reqest); + return http.post(`/hosts/test/byinfo`, request); }; export const testByID = (id: number) => { return http.post(`/hosts/test/byid/${id}`); }; export const editHost = (params: Host.HostOperate) => { - let reqest = deepCopy(params) as Host.HostOperate; - if (reqest.password) { - reqest.password = Base64.encode(reqest.password); + let request = deepCopy(params) as Host.HostOperate; + if (request.password) { + request.password = Base64.encode(request.password); } - if (reqest.privateKey) { - reqest.privateKey = Base64.encode(reqest.privateKey); + if (request.privateKey) { + request.privateKey = Base64.encode(request.privateKey); } - return http.post(`/hosts/update`, reqest); + return http.post(`/hosts/update`, request); }; export const editHostGroup = (params: Host.GroupChange) => { return http.post(`/hosts/update/group`, params); diff --git a/frontend/src/api/modules/setting.ts b/frontend/src/api/modules/setting.ts index f1d7636192f9..712a46682763 100644 --- a/frontend/src/api/modules/setting.ts +++ b/frontend/src/api/modules/setting.ts @@ -103,37 +103,37 @@ export const getFilesFromBackup = (type: string) => { return http.post>(`/settings/backup/search/files`, { type: type }); }; export const addBackup = (params: Backup.BackupOperate) => { - let reqest = deepCopy(params) as Backup.BackupOperate; - if (reqest.accessKey) { - reqest.accessKey = Base64.encode(reqest.accessKey); + let request = deepCopy(params) as Backup.BackupOperate; + if (request.accessKey) { + request.accessKey = Base64.encode(request.accessKey); } - if (reqest.credential) { - reqest.credential = Base64.encode(reqest.credential); + if (request.credential) { + request.credential = Base64.encode(request.credential); } - return http.post(`/settings/backup`, reqest); + return http.post(`/settings/backup`, request); }; export const editBackup = (params: Backup.BackupOperate) => { - let reqest = deepCopy(params) as Backup.BackupOperate; - if (reqest.accessKey) { - reqest.accessKey = Base64.encode(reqest.accessKey); + let request = deepCopy(params) as Backup.BackupOperate; + if (request.accessKey) { + request.accessKey = Base64.encode(request.accessKey); } - if (reqest.credential) { - reqest.credential = Base64.encode(reqest.credential); + if (request.credential) { + request.credential = Base64.encode(request.credential); } - return http.post(`/settings/backup/update`, reqest); + return http.post(`/settings/backup/update`, request); }; export const deleteBackup = (params: { id: number }) => { return http.post(`/settings/backup/del`, params); }; export const listBucket = (params: Backup.ForBucket) => { - let reqest = deepCopy(params) as Backup.BackupOperate; - if (reqest.accessKey) { - reqest.accessKey = Base64.encode(reqest.accessKey); + let request = deepCopy(params) as Backup.BackupOperate; + if (request.accessKey) { + request.accessKey = Base64.encode(request.accessKey); } - if (reqest.credential) { - reqest.credential = Base64.encode(reqest.credential); + if (request.credential) { + request.credential = Base64.encode(request.credential); } - return http.post(`/settings/backup/buckets`, reqest); + return http.post(`/settings/backup/buckets`, request); }; // snapshot