mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-24 02:59:16 +08:00
fix: 切换子节点请求方式 (#6195)
This commit is contained in:
parent
6dec845848
commit
1215e3bb30
4
Makefile
4
Makefile
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
package constant
|
||||
|
||||
const (
|
||||
JWTHeaderName = "PanelAuthorization"
|
||||
)
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -17,3 +17,5 @@ func UpdateGroup(name string, group, newGroup uint) error {
|
||||
func CheckBackupUsed(id uint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitAgentRouter(Router *gin.RouterGroup) {}
|
||||
|
@ -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);
|
||||
|
@ -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';
|
||||
|
@ -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();
|
||||
|
@ -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>
|
@ -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>
|
@ -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>([]);
|
||||
|
@ -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';
|
||||
|
@ -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: '',
|
||||
|
@ -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(() => {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user