fix: 切换子节点请求方式 (#6195)

This commit is contained in:
ssongliu 2024-08-21 15:14:50 +08:00 committed by GitHub
parent 6dec845848
commit 1215e3bb30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 83 additions and 509 deletions

View File

@ -44,6 +44,10 @@ build_agent_xpack_on_darwin:
cd $(AGENT_PATH) \
&& GOOS=linux GOARCH=amd64 $(GOBUILD) -tags=xpack -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(AGENT_NAME) $(AGENT_MAIN)
build_agent_xpack_on_linux:
cd $(AGENT_PATH) \
&& GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -tags=xpack -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(AGENT_NAME) $(AGENT_MAIN)
build_all: build_frontend build_core_on_linux build_agent_on_linux
build_on_local: clean_assets build_frontend build_core_on_darwin build_agent_on_darwin upx_bin

View File

@ -32,7 +32,7 @@ func (b *BaseApi) CheckBackupUsed(c *gin.Context) {
// @Param request body dto.RecordSearch true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/record/search [post]
// @Router /backup/record/search [post]
func (b *BaseApi) SearchBackupRecords(c *gin.Context) {
var req dto.RecordSearch
if err := helper.CheckBindAndValidate(&req, c); err != nil {
@ -58,7 +58,7 @@ func (b *BaseApi) SearchBackupRecords(c *gin.Context) {
// @Param request body dto.RecordSearchByCronjob true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/record/search/bycronjob [post]
// @Router /backup/record/search/bycronjob [post]
func (b *BaseApi) SearchBackupRecordsByCronjob(c *gin.Context) {
var req dto.RecordSearchByCronjob
if err := helper.CheckBindAndValidate(&req, c); err != nil {
@ -84,7 +84,7 @@ func (b *BaseApi) SearchBackupRecordsByCronjob(c *gin.Context) {
// @Param request body dto.DownloadRecord true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/record/download [post]
// @Router /backup/record/download [post]
// @x-panel-log {"bodyKeys":["source","fileName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载备份记录 [source][fileName]","formatEN":"download backup records [source][fileName]"}
func (b *BaseApi) DownloadRecord(c *gin.Context) {
var req dto.DownloadRecord
@ -107,7 +107,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
// @Param request body dto.BatchDeleteReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/record/del [post]
// @Router /record/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"backup_records","output_column":"file_name","output_value":"files"}],"formatZH":"删除备份记录 [files]","formatEN":"delete backup records [files]"}
func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
var req dto.BatchDeleteReq
@ -129,7 +129,7 @@ func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
// @Param request body dto.OperateByID true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Router /settings/backup/search/files [post]
// @Router /backup/search/files [post]
func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
@ -147,7 +147,7 @@ func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
// @Param request body dto.CommonBackup true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/backup [post]
// @Router /backup/backup [post]
// @x-panel-log {"bodyKeys":["type","name","detailName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"备份 [type] 数据 [name][detailName]","formatEN":"backup [type] data [name][detailName]"}
func (b *BaseApi) Backup(c *gin.Context) {
var req dto.CommonBackup
@ -192,7 +192,7 @@ func (b *BaseApi) Backup(c *gin.Context) {
// @Param request body dto.CommonRecover true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/recover [post]
// @Router /backup/recover [post]
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
func (b *BaseApi) Recover(c *gin.Context) {
var req dto.CommonRecover
@ -247,7 +247,7 @@ func (b *BaseApi) Recover(c *gin.Context) {
// @Param request body dto.CommonRecover true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/backup/recover/byupload [post]
// @Router /backup/recover/byupload [post]
// @x-panel-log {"bodyKeys":["type","name","detailName","file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"从 [file] 恢复 [type] 数据 [name][detailName]","formatEN":"recover [type] data [name][detailName] from [file]"}
func (b *BaseApi) RecoverByUpload(c *gin.Context) {
var req dto.CommonRecover

View File

@ -5,12 +5,12 @@ import (
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/agent/constant"
httpUtils "github.com/1Panel-dev/1Panel/agent/utils/http"
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
"github.com/gin-gonic/gin"
)
func (b *BaseApi) CheckHealth(c *gin.Context) {
_, err := httpUtils.RequestToMaster("/api/v2/agent/health", http.MethodGet, nil)
_, err := xpack.RequestToMaster("/api/v2/agent/health", http.MethodGet, nil)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return

View File

@ -21,7 +21,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cloud_storage"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
httpUtils "github.com/1Panel-dev/1Panel/agent/utils/http"
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
)
@ -277,7 +277,7 @@ func NewBackupClientWithID(id uint) (*model.BackupAccount, cloud_storage.CloudSt
if err != nil {
return nil, nil, err
}
data, err := httpUtils.RequestToMaster("/api/v2/agent/backup", http.MethodPost, bytes.NewReader(bodyItem))
data, err := xpack.RequestToMaster("/api/v2/agent/backup", http.MethodPost, bytes.NewReader(bodyItem))
if err != nil {
return nil, nil, err
}
@ -342,7 +342,7 @@ func NewBackupClientMap(ids []string) (map[string]backupClientHelper, error) {
if err != nil {
return nil, err
}
data, err := httpUtils.RequestToMaster("/api/v2/agent/backup/list", http.MethodPost, bytes.NewReader(bodyItem))
data, err := xpack.RequestToMaster("/api/v2/agent/backup/list", http.MethodPost, bytes.NewReader(bodyItem))
if err != nil {
return nil, err
}

View File

@ -1,20 +1,19 @@
package configs
type System struct {
MasterAddr string `mapstructure:"master_addr"`
MasterToken string `mapstructure:"master_token"`
DbFile string `mapstructure:"db_agent_file"`
DbPath string `mapstructure:"db_path"`
LogPath string `mapstructure:"log_path"`
DataDir string `mapstructure:"data_dir"`
TmpDir string `mapstructure:"tmp_dir"`
Cache string `mapstructure:"cache"`
Backup string `mapstructure:"backup"`
EncryptKey string `mapstructure:"encrypt_key"`
BaseDir string `mapstructure:"base_dir"`
Mode string `mapstructure:"mode"`
RepoUrl string `mapstructure:"repo_url"`
Version string `mapstructure:"version"`
IsDemo bool `mapstructure:"is_demo"`
AppRepo string `mapstructure:"app_repo"`
MasterAddr string `mapstructure:"master_addr"`
DbFile string `mapstructure:"db_agent_file"`
DbPath string `mapstructure:"db_path"`
LogPath string `mapstructure:"log_path"`
DataDir string `mapstructure:"data_dir"`
TmpDir string `mapstructure:"tmp_dir"`
Cache string `mapstructure:"cache"`
Backup string `mapstructure:"backup"`
EncryptKey string `mapstructure:"encrypt_key"`
BaseDir string `mapstructure:"base_dir"`
Mode string `mapstructure:"mode"`
RepoUrl string `mapstructure:"repo_url"`
Version string `mapstructure:"version"`
IsDemo bool `mapstructure:"is_demo"`
AppRepo string `mapstructure:"app_repo"`
}

View File

@ -1,5 +0,0 @@
package constant
const (
JWTHeaderName = "PanelAuthorization"
)

View File

@ -35,11 +35,6 @@ func Init() {
global.LOG.Fatalf("load master addr before start failed, err: %v", err)
}
global.CONF.System.MasterAddr = masterAddr.Value
token, err := settingRepo.Get(settingRepo.WithByKey("Token"))
if err != nil {
global.LOG.Fatalf("load token before start failed, err: %v", err)
}
global.CONF.System.MasterToken, _ = encrypt.StringDecrypt(token.Value)
}
handleCronjobStatus()

View File

@ -1,7 +1,6 @@
package migrations
import (
"encoding/json"
"os"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
@ -10,7 +9,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
@ -73,53 +72,18 @@ var AddMonitorTable = &gormigrate.Migration{
var InitSetting = &gormigrate.Migration{
ID: "20240722-init-setting",
Migrate: func(tx *gorm.DB) error {
encryptKey := common.RandStr(16)
global.CONF.System.EncryptKey = encryptKey
if err := tx.Create(&model.Setting{Key: "EncryptKey", Value: encryptKey}).Error; err != nil {
global.CONF.System.EncryptKey = common.RandStr(16)
isMaster, currentNode, err := xpack.InitNodeData(tx)
if err != nil {
return err
}
currentNode := ""
if _, err := os.Stat("/opt/1panel/nodeJson"); err == nil {
type nodeInfo struct {
MasterAddr string `json:"masterAddr"`
Token string `json:"token"`
ServerCrt string `json:"serverCrt"`
ServerKey string `json:"serverKey"`
CurrentNode string `json:"currentNode"`
}
nodeJson, err := os.ReadFile("/opt/1panel/nodeJson")
if err != nil {
return err
}
var node nodeInfo
if err := json.Unmarshal(nodeJson, &node); err != nil {
return err
}
itemKey, _ := encrypt.StringEncryptWithBase64(node.ServerKey)
if err := tx.Create(&model.Setting{Key: "ServerKey", Value: itemKey}).Error; err != nil {
return err
}
itemCrt, _ := encrypt.StringEncryptWithBase64(node.ServerCrt)
if err := tx.Create(&model.Setting{Key: "ServerCrt", Value: itemCrt}).Error; err != nil {
return err
}
itemToken, _ := encrypt.StringEncryptWithBase64(node.Token)
if err := tx.Create(&model.Setting{Key: "Token", Value: itemToken}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "MasterAddr", Value: node.MasterAddr}).Error; err != nil {
return err
}
global.CONF.System.MasterAddr = node.MasterAddr
global.CONF.System.MasterToken = itemToken
global.IsMaster = false
currentNode = node.CurrentNode
} else {
global.IsMaster = true
}
global.IsMaster = isMaster
if err := tx.Create(&model.Setting{Key: "CurrentNode", Value: currentNode}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "EncryptKey", Value: global.CONF.System.EncryptKey}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "SystemIP", Value: ""}).Error; err != nil {
return err

View File

@ -24,15 +24,6 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) {
settingRouter.POST("/snapshot/rollback", baseApi.RollbackSnapshot)
settingRouter.POST("/snapshot/description/update", baseApi.UpdateSnapDescription)
settingRouter.POST("/backup/backup", baseApi.Backup)
settingRouter.POST("/backup/recover", baseApi.Recover)
settingRouter.POST("/backup/recover/byupload", baseApi.RecoverByUpload)
settingRouter.POST("/backup/search/files", baseApi.LoadFilesFromBackup)
settingRouter.POST("/backup/record/search", baseApi.SearchBackupRecords)
settingRouter.POST("/backup/record/search/bycronjob", baseApi.SearchBackupRecordsByCronjob)
settingRouter.POST("/backup/record/download", baseApi.DownloadRecord)
settingRouter.POST("/backup/record/del", baseApi.DeleteBackupRecord)
settingRouter.GET("/basedir", baseApi.LoadBaseDir)
}
}

View File

@ -1,57 +0,0 @@
package http
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
)
func RequestToMaster(reqUrl, reqMethod string, reqBody io.Reader) (interface{}, error) {
client := &http.Client{
Timeout: time.Second * 5,
}
parsedURL, err := url.Parse(global.CONF.System.MasterAddr)
if err != nil {
return nil, fmt.Errorf("handle url Parse failed, err: %v \n", err)
}
rURL := &url.URL{
Scheme: "http",
Path: reqUrl,
Host: parsedURL.Host,
}
req, err := http.NewRequest(reqMethod, rURL.String(), reqBody)
if err != nil {
return nil, fmt.Errorf("handle request failed, err: %v \n", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set(constant.JWTHeaderName, global.CONF.System.MasterToken)
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("client do request failed, err: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("do request failed, err: %v", resp.Status)
}
bodyByte, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read resp body from request failed, err: %v", err)
}
var respJson dto.Response
if err := json.Unmarshal(bodyByte, &respJson); err != nil {
return nil, fmt.Errorf("json unmarshal resp data failed, err: %v", err)
}
if respJson.Code != http.StatusOK {
return nil, fmt.Errorf("do request success but handle failed, err: %v", respJson.Message)
}
return respJson.Data, nil
}

View File

@ -4,6 +4,7 @@ package xpack
import (
"crypto/tls"
"io"
"net"
"net/http"
"time"
@ -11,6 +12,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/app/model"
"github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/constant"
"gorm.io/gorm"
)
func RemoveTamper(website string) {}
@ -35,3 +37,9 @@ func LoadGpuInfo() []interface{} {
func StartClam(startClam model.Clam, isUpdate bool) (int, error) {
return 0, buserr.New(constant.ErrXpackNotFound)
}
func InitNodeData(tx *gorm.DB) (bool, string, error) { return true, "127.0.0.1", nil }
func RequestToMaster(reqUrl, reqMethod string, reqBody io.Reader) (interface{}, error) {
return nil, nil
}

View File

@ -179,32 +179,3 @@ func (b *BaseApi) GetLocalDir(c *gin.Context) {
helper.SuccessWithData(c, dir)
}
func (b *BaseApi) GetBackup(c *gin.Context) {
var req dto.OperateByID
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
data, err := backupService.Get(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, data)
}
func (b *BaseApi) ListBackup(c *gin.Context) {
var req dto.OperateByIDs
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
list, err := backupService.List(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, list)
}

View File

@ -6,13 +6,11 @@ import (
"github.com/1Panel-dev/1Panel/cmd/server/docs"
"github.com/1Panel-dev/1Panel/cmd/server/web"
"github.com/1Panel-dev/1Panel/core/app/dto"
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/i18n"
"github.com/1Panel-dev/1Panel/core/middleware"
"github.com/1Panel-dev/1Panel/core/router"
rou "github.com/1Panel-dev/1Panel/core/router"
"github.com/1Panel-dev/1Panel/core/utils/xpack"
"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
swaggerfiles "github.com/swaggo/files"
@ -54,12 +52,7 @@ func Routers() *gin.Engine {
}
agentRouter := Router.Group("/api/v2/agent")
agentRouter.Use(middleware.JwtAuth())
var agent router.AgentRouter
agent.InitRouter(agentRouter)
agentRouter.GET("/health", func(c *gin.Context) {
c.JSON(200, dto.Response{Code: constant.CodeSuccess, Data: "ok"})
})
xpack.InitAgentRouter(agentRouter)
Router.Use(middleware.OperationLog())
if global.CONF.System.IsDemo {

View File

@ -1,16 +0,0 @@
package router
import (
v2 "github.com/1Panel-dev/1Panel/core/app/api/v2"
"github.com/gin-gonic/gin"
)
type AgentRouter struct{}
func (s *AgentRouter) InitRouter(Router *gin.RouterGroup) {
baseApi := v2.ApiGroupApp.BaseApi
{
Router.POST("/backup", baseApi.GetBackup)
Router.POST("/backup/list", baseApi.ListBackup)
}
}

View File

@ -45,6 +45,13 @@ func StringEncrypt(text string) (string, error) {
global.CONF.System.EncryptKey = encryptSetting.Value
}
key := global.CONF.System.EncryptKey
return StringEncryptWithKey(text, key)
}
func StringEncryptWithKey(text, key string) (string, error) {
if len(text) == 0 || len(key) == 0 {
return "", nil
}
pass := []byte(text)
xpass, err := aesEncryptWithSalt([]byte(key), pass)
if err == nil {
@ -66,6 +73,13 @@ func StringDecrypt(text string) (string, error) {
global.CONF.System.EncryptKey = encryptSetting.Value
}
key := global.CONF.System.EncryptKey
return StringDecryptWithKey(text, key)
}
func StringDecryptWithKey(text, key string) (string, error) {
if len(text) == 0 {
return "", nil
}
bytesPass, err := base64.StdEncoding.DecodeString(text)
if err != nil {
return "", err

View File

@ -17,3 +17,5 @@ func UpdateGroup(name string, group, newGroup uint) error {
func CheckBackupUsed(id uint) error {
return nil
}
func InitAgentRouter(Router *gin.RouterGroup) {}

View File

@ -2,9 +2,7 @@ import http from '@/api';
import { deepCopy } from '@/utils/util';
import { Base64 } from 'js-base64';
import { ResPage, SearchWithPage, DescriptionUpdate } from '../interface';
import { Backup } from '../interface/backup';
import { Setting } from '../interface/setting';
import { TimeoutEnum } from '@/enums/http-enum';
// license
export const UploadFileData = (params: FormData) => {
@ -83,82 +81,6 @@ export const bindMFA = (param: Setting.MFABind) => {
return http.post(`/core/settings/mfa/bind`, param);
};
// backup-agent
export const handleBackup = (params: Backup.Backup) => {
return http.post(`/settings/backup/backup`, params, TimeoutEnum.T_1H);
};
export const handleRecover = (params: Backup.Recover) => {
return http.post(`/settings/backup/recover`, params, TimeoutEnum.T_1D);
};
export const handleRecoverByUpload = (params: Backup.Recover) => {
return http.post(`/settings/backup/recover/byupload`, params, TimeoutEnum.T_1D);
};
export const downloadBackupRecord = (params: Backup.RecordDownload) => {
return http.post<string>(`/settings/backup/record/download`, params, TimeoutEnum.T_10M);
};
export const deleteBackupRecord = (params: { ids: number[] }) => {
return http.post(`/settings/backup/record/del`, params);
};
export const searchBackupRecords = (params: Backup.SearchBackupRecord) => {
return http.post<ResPage<Backup.RecordInfo>>(`/settings/backup/record/search`, params, TimeoutEnum.T_5M);
};
export const searchBackupRecordsByCronjob = (params: Backup.SearchBackupRecordByCronjob) => {
return http.post<ResPage<Backup.RecordInfo>>(`/settings/backup/record/search/bycronjob`, params, TimeoutEnum.T_5M);
};
export const getFilesFromBackup = (type: string) => {
return http.post<Array<any>>(`/settings/backup/search/files`, { type: type });
};
// backup-core
export const refreshOneDrive = () => {
return http.post(`/core/backup/refresh/onedrive`, {});
};
export const getBackupList = () => {
return http.get<Array<Backup.BackupOption>>(`/core/backup/options`);
};
export const getLocalBackupDir = () => {
return http.get<string>(`/core/backup/local`);
};
export const searchBackup = (params: Backup.SearchWithType) => {
return http.post<ResPage<Backup.BackupInfo>>(`/core/backup/search`, params);
};
export const getOneDriveInfo = () => {
return http.get<Backup.OneDriveInfo>(`/core/backup/onedrive`);
};
export const addBackup = (params: Backup.BackupOperate) => {
let request = deepCopy(params) as Backup.BackupOperate;
if (request.accessKey) {
request.accessKey = Base64.encode(request.accessKey);
}
if (request.credential) {
request.credential = Base64.encode(request.credential);
}
return http.post<Backup.BackupOperate>(`/core/backup`, request, TimeoutEnum.T_60S);
};
export const editBackup = (params: Backup.BackupOperate) => {
let request = deepCopy(params) as Backup.BackupOperate;
if (request.accessKey) {
request.accessKey = Base64.encode(request.accessKey);
}
if (request.credential) {
request.credential = Base64.encode(request.credential);
}
return http.post(`/core/backup/update`, request);
};
export const deleteBackup = (params: { id: number }) => {
return http.post(`/core/backup/del`, params);
};
export const listBucket = (params: Backup.ForBucket) => {
let request = deepCopy(params) as Backup.BackupOperate;
if (request.accessKey) {
request.accessKey = Base64.encode(request.accessKey);
}
if (request.credential) {
request.credential = Base64.encode(request.credential);
}
return http.post(`/core/backup/buckets`, request);
};
// snapshot
export const snapshotCreate = (param: Setting.SnapshotCreate) => {
return http.post(`/settings/snapshot`, param);

View File

@ -101,9 +101,15 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { computeSize, dateFormat, downloadFile } from '@/utils/util';
import { getLocalBackupDir, handleBackup, handleRecover } from '@/api/modules/setting';
import {
getLocalBackupDir,
handleBackup,
handleRecover,
deleteBackupRecord,
downloadBackupRecord,
searchBackupRecords,
} from '@/api/modules/backup';
import i18n from '@/lang';
import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/setting';
import { Backup } from '@/api/interface/backup';
import router from '@/routers';
import { MsgSuccess } from '@/utils/message';

View File

@ -135,8 +135,9 @@ import i18n from '@/lang';
import { UploadFile, UploadFiles, UploadInstance } from 'element-plus';
import { File } from '@/api/interface/file';
import { BatchDeleteFile, CheckFile, ChunkUploadFileData, GetUploadList } from '@/api/modules/files';
import { handleRecoverByUpload, loadBaseDir } from '@/api/modules/setting';
import { loadBaseDir } from '@/api/modules/setting';
import { MsgError, MsgSuccess } from '@/utils/message';
import { handleRecoverByUpload } from '@/api/modules/backup';
const loading = ref();
const isUpload = ref();

View File

@ -1,96 +0,0 @@
<template>
<el-dialog
v-model="open"
:title="$t('commons.button.backup') + ' - ' + appInstallName"
width="40%"
:close-on-click-modal="false"
:before-close="handleClose"
>
<el-form ref="backupForm" label-position="left" v-loading="loading">
<el-form-item
:label="$t('setting.compressPassword')"
style="margin-top: 10px"
v-if="backupReq.type === 'app' || backupReq.type === 'website'"
>
<el-input v-model="backupReq.secret" :placeholder="$t('setting.backupRecoverMessage')" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button type="primary" @click="submit" :disabled="loading">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { FormInstance } from 'element-plus';
import i18n from '@/lang';
import { handleBackup } from '@/api/modules/setting';
import { MsgSuccess } from '@/utils/message';
let appInstallName = ref('');
let loading = ref(false);
let open = ref(false);
const backupForm = ref<FormInstance>();
const emit = defineEmits<{ (e: 'search'): void }>();
interface DialogProps {
type: string;
name: string;
detailName: string;
status: string;
}
let backupReq = ref({
type: '',
name: '',
detailName: '',
secret: '',
});
const handleClose = () => {
open.value = false;
};
const acceptParams = (params: DialogProps): void => {
appInstallName.value = params.name;
backupReq.value = {
type: params.type,
name: params.name,
detailName: params.detailName,
secret: '',
};
open.value = true;
};
const submit = async () => {
let params = {
type: backupReq.value.type,
name: backupReq.value.name,
detailName: backupReq.value.detailName,
secret: backupReq.value.secret,
};
loading.value = true;
await handleBackup(params)
.then(() => {
loading.value = false;
handleClose();
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
emit('search');
})
.catch(() => {
loading.value = false;
});
};
defineExpose({
acceptParams,
});
</script>
<style scoped lang="scss"></style>

View File

@ -1,116 +0,0 @@
<template>
<el-dialog
v-model="open"
:title="$t('commons.button.recover') + ' - ' + appInstallName"
width="40%"
:close-on-click-modal="false"
:before-close="handleClose"
>
<el-form ref="recoverForm" label-position="left" v-loading="loading">
<el-form-item
:label="$t('setting.compressPassword')"
style="margin-top: 10px"
v-if="recoverReq.type === 'app' || recoverReq.type === 'website'"
>
<el-input v-model="recoverReq.secret" :placeholder="$t('setting.backupRecoverMessage')" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">
{{ $t('commons.button.cancel') }}
</el-button>
<el-button type="primary" @click="submit" :disabled="loading">
{{ $t('commons.button.confirm') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { FormInstance } from 'element-plus';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { handleRecover, handleRecoverByUpload } from '@/api/modules/setting';
let appInstallName = ref('');
let loading = ref(false);
let open = ref(false);
const recoverForm = ref<FormInstance>();
interface DialogProps {
source: string;
type: string;
name: string;
detailName: string;
file: string;
recoverType: string;
}
let recoverReq = ref({
source: '',
type: '',
name: '',
detailName: '',
file: '',
secret: '',
recoverType: '',
});
const handleClose = () => {
open.value = false;
};
const acceptParams = (params: DialogProps): void => {
appInstallName.value = params.name;
recoverReq.value = {
source: params.source,
type: params.type,
name: params.name,
detailName: params.detailName,
file: params.file,
secret: '',
recoverType: params.recoverType,
};
open.value = true;
};
const submit = async () => {
let params = {
source: recoverReq.value.source,
type: recoverReq.value.type,
name: recoverReq.value.name,
detailName: recoverReq.value.detailName,
file: recoverReq.value.file,
secret: recoverReq.value.secret,
};
loading.value = true;
if (recoverReq.value.recoverType === 'upload') {
await handleRecoverByUpload(params)
.then(() => {
loading.value = false;
handleClose();
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
return false;
}
await handleRecover(params)
.then(() => {
loading.value = false;
handleClose();
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
})
.catch(() => {
loading.value = false;
});
};
defineExpose({
acceptParams,
});
</script>
<style scoped lang="scss"></style>

View File

@ -51,7 +51,7 @@
import { reactive, ref } from 'vue';
import { computeSize, dateFormat, downloadFile } from '@/utils/util';
import i18n from '@/lang';
import { downloadBackupRecord, searchBackupRecordsByCronjob } from '@/api/modules/setting';
import { downloadBackupRecord, searchBackupRecordsByCronjob } from '@/api/modules/backup';
import { Backup } from '@/api/interface/backup';
const selects = ref<any>([]);

View File

@ -332,7 +332,7 @@
import { reactive, ref } from 'vue';
import { Rules } from '@/global/form-rules';
import FileList from '@/components/file-list/index.vue';
import { getBackupList } from '@/api/modules/setting';
import { getBackupList } from '@/api/modules/backup';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { Cronjob } from '@/api/interface/cronjob';

View File

@ -116,7 +116,7 @@
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { Database } from '@/api/interface/database';
import { redisPersistenceConf, updateRedisPersistenceConf } from '@/api/modules/database';
import { deleteBackupRecord, handleBackup, handleRecover, searchBackupRecords } from '@/api/modules/setting';
import { deleteBackupRecord, handleBackup, handleRecover, searchBackupRecords } from '@/api/modules/backup';
import { Rules } from '@/global/form-rules';
import { dateFormat } from '@/utils/util';
import i18n from '@/lang';
@ -205,7 +205,7 @@ const onBackup = async () => {
};
const onRecover = async () => {
let param = {
source: currentRow.value.source,
downloadAccountID: currentRow.value.source,
type: 'redis',
name: database.value,
detailName: '',

View File

@ -46,7 +46,7 @@ import { reactive, ref } from 'vue';
import { FormInstance } from 'element-plus';
import i18n from '@/lang';
import { snapshotImport } from '@/api/modules/setting';
import { getBackupList, getFilesFromBackup } from '@/api/modules/setting';
import { getBackupList, getFilesFromBackup } from '@/api/modules/backup';
import { Rules } from '@/global/form-rules';
import { MsgSuccess } from '@/utils/message';
import router from '@/routers';
@ -125,13 +125,7 @@ const loadBackups = async () => {
loading.value = false;
backupOptions.value = [];
for (const item of res.data) {
if (item.id !== 0) {
backupOptions.value.push({ label: i18n.global.t('setting.' + item.type), value: item.type });
}
if (item.type === 'LOCAL') {
item.varsJson = JSON.parse(item.vars);
backupPath.value = item.varsJson['dir'] + '/system_snapshot';
}
backupOptions.value.push({ label: i18n.global.t('setting.' + item.type), value: item.type });
}
})
.catch(() => {

View File

@ -191,7 +191,7 @@ import IgnoreRule from '@/views/setting/snapshot/ignore-rule/index.vue';
import SnapStatus from '@/views/setting/snapshot/snap_status/index.vue';
import RecoverStatus from '@/views/setting/snapshot/status/index.vue';
import SnapshotImport from '@/views/setting/snapshot/import/index.vue';
import { getBackupList } from '@/api/modules/setting';
import { getBackupList } from '@/api/modules/backup';
import { MsgSuccess } from '@/utils/message';
const loading = ref(false);