1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-13 17:24:44 +08:00

feat: 多数据库接口适配 (#2094)

This commit is contained in:
ssongliu 2023-08-29 10:50:15 +08:00 committed by GitHub
parent b54c79e196
commit ff141b21e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 2133 additions and 1183 deletions

View File

@ -1,7 +1,6 @@
package v1
import (
"errors"
"reflect"
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
@ -67,17 +66,21 @@ func (b *BaseApi) ListAppInstalled(c *gin.Context) {
// @Summary Check app installed
// @Description 检查应用安装情况
// @Accept json
// @Param key path string true "request"
// @Param request body request.AppInstalledInfo true "request"
// @Success 200 {object} response.AppInstalledCheck
// @Security ApiKeyAuth
// @Router /apps/installed/check/:key [get]
// @Router /apps/installed/check [post]
func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
key, ok := c.Params.Get("key")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
var req request.AppInstalledInfo
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
checkData, err := appInstallService.CheckExist(key)
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
checkData, err := appInstallService.CheckExist(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -89,17 +92,17 @@ func (b *BaseApi) CheckAppInstalled(c *gin.Context) {
// @Summary Search app port by key
// @Description 获取应用端口
// @Accept json
// @Param key path string true "request"
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {integer} port
// @Security ApiKeyAuth
// @Router /apps/installed/loadport/:key [get]
// @Router /apps/installed/loadport [post]
func (b *BaseApi) LoadPort(c *gin.Context) {
key, ok := c.Params.Get("key")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
var req dto.OperationWithNameAndType
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
port, err := appInstallService.LoadPort(key)
port, err := appInstallService.LoadPort(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -111,17 +114,17 @@ func (b *BaseApi) LoadPort(c *gin.Context) {
// @Summary Search app password by key
// @Description 获取应用连接信息
// @Accept json
// @Param key path string true "request"
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {string} response.DatabaseConn
// @Security ApiKeyAuth
// @Router /apps/installed/conninfo/:key [get]
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
key, ok := c.Params.Get("key")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
var req dto.OperationWithNameAndType
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
conn, err := appInstallService.LoadConnInfo(key)
conn, err := appInstallService.LoadConnInfo(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return

View File

@ -335,7 +335,7 @@ func (b *BaseApi) Backup(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
case "mysql":
case "mysql", "mariadb":
if err := backupService.MysqlBackup(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -383,7 +383,7 @@ func (b *BaseApi) Recover(c *gin.Context) {
req.File = downloadPath
}
switch req.Type {
case "mysql":
case "mysql", "mariadb":
if err := backupService.MysqlRecover(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -428,7 +428,7 @@ func (b *BaseApi) RecoverByUpload(c *gin.Context) {
}
switch req.Type {
case "mysql":
case "mysql", "mariadb":
if err := backupService.MysqlRecoverByUpload(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return

View File

@ -12,13 +12,13 @@ import (
// @Summary Create remote database
// @Description 创建远程数据库
// @Accept json
// @Param request body dto.RemoteDBCreate true "request"
// @Param request body dto.DatabaseCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/remote [post]
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建远程数据库 [name][type]","formatEN":"create remote database [name][type]"}
func (b *BaseApi) CreateRemoteDB(c *gin.Context) {
var req dto.RemoteDBCreate
func (b *BaseApi) CreateDatabase(c *gin.Context) {
var req dto.DatabaseCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@ -27,7 +27,7 @@ func (b *BaseApi) CreateRemoteDB(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := remoteDBService.Create(req); err != nil {
if err := databaseService.Create(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@ -38,13 +38,13 @@ func (b *BaseApi) CreateRemoteDB(c *gin.Context) {
// @Summary Check remote database
// @Description 检测远程数据库连接性
// @Accept json
// @Param request body dto.RemoteDBCreate true "request"
// @Param request body dto.DatabaseCreate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/remote/check [post]
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测远程数据库 [name][type] 连接性","formatEN":"check if remote database [name][type] is connectable"}
func (b *BaseApi) CheckeRemoteDB(c *gin.Context) {
var req dto.RemoteDBCreate
func (b *BaseApi) CheckDatabase(c *gin.Context) {
var req dto.DatabaseCreate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@ -53,25 +53,25 @@ func (b *BaseApi) CheckeRemoteDB(c *gin.Context) {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
helper.SuccessWithData(c, remoteDBService.CheckeRemoteDB(req))
helper.SuccessWithData(c, databaseService.CheckDatabase(req))
}
// @Tags Database
// @Summary Page remote databases
// @Description 获取远程数据库列表分页
// @Accept json
// @Param request body dto.RemoteDBSearch true "request"
// @Param request body dto.DatabaseSearch true "request"
// @Success 200 {object} dto.PageResult
// @Security ApiKeyAuth
// @Router /databases/remote/search [post]
func (b *BaseApi) SearchRemoteDB(c *gin.Context) {
var req dto.RemoteDBSearch
func (b *BaseApi) SearchDatabase(c *gin.Context) {
var req dto.DatabaseSearch
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, list, err := remoteDBService.SearchWithPage(req)
total, list, err := databaseService.SearchWithPage(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -86,16 +86,16 @@ func (b *BaseApi) SearchRemoteDB(c *gin.Context) {
// @Tags Database
// @Summary List remote databases
// @Description 获取远程数据库列表
// @Success 200 {array} dto.RemoteDBOption
// @Success 200 {array} dto.DatabaseOption
// @Security ApiKeyAuth
// @Router /databases/remote/list/:type [get]
func (b *BaseApi) ListRemoteDB(c *gin.Context) {
func (b *BaseApi) ListDatabase(c *gin.Context) {
dbType, err := helper.GetStrParamByKey(c, "type")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
list, err := remoteDBService.List(dbType)
list, err := databaseService.List(dbType)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -107,16 +107,16 @@ func (b *BaseApi) ListRemoteDB(c *gin.Context) {
// @Tags Database
// @Summary Get remote databases
// @Description 获取远程数据库
// @Success 200 {object} dto.RemoteDBInfo
// @Success 200 {object} dto.DatabaseInfo
// @Security ApiKeyAuth
// @Router /databases/remote/:name [get]
func (b *BaseApi) GetRemoteDB(c *gin.Context) {
func (b *BaseApi) GetDatabase(c *gin.Context) {
name, err := helper.GetStrParamByKey(c, "name")
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := remoteDBService.Get(name)
data, err := databaseService.Get(name)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -134,7 +134,7 @@ func (b *BaseApi) GetRemoteDB(c *gin.Context) {
// @Security ApiKeyAuth
// @Router /databases/remote/del [post]
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"databases","output_column":"name","output_value":"names"}],"formatZH":"删除远程数据库 [names]","formatEN":"delete remote database [names]"}
func (b *BaseApi) DeleteRemoteDB(c *gin.Context) {
func (b *BaseApi) DeleteDatabase(c *gin.Context) {
var req dto.OperateByID
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
@ -145,7 +145,7 @@ func (b *BaseApi) DeleteRemoteDB(c *gin.Context) {
return
}
if err := remoteDBService.Delete(req.ID); err != nil {
if err := databaseService.Delete(req.ID); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@ -156,13 +156,13 @@ func (b *BaseApi) DeleteRemoteDB(c *gin.Context) {
// @Summary Update remote database
// @Description 更新远程数据库
// @Accept json
// @Param request body dto.RemoteDBUpdate true "request"
// @Param request body dto.DatabaseUpdate true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /databases/remote/update [post]
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新远程数据库 [name]","formatEN":"update remote database [name]"}
func (b *BaseApi) UpdateRemoteDB(c *gin.Context) {
var req dto.RemoteDBUpdate
func (b *BaseApi) UpdateDatabase(c *gin.Context) {
var req dto.DatabaseUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@ -172,7 +172,7 @@ func (b *BaseApi) UpdateRemoteDB(c *gin.Context) {
return
}
if err := remoteDBService.Update(req); err != nil {
if err := databaseService.Update(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}

View File

@ -143,7 +143,7 @@ func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
// @Router /databases/variables/update [post]
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"调整 mysql 数据库性能参数","formatEN":"adjust mysql database performance parameters"}
func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
var req []dto.MysqlVariablesUpdate
var req dto.MysqlVariablesUpdate
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@ -232,15 +232,21 @@ func (b *BaseApi) ListDBName(c *gin.Context) {
// @Tags Database Mysql
// @Summary Load mysql database from remote
// @Description 从服务器获取
// @Accept json
// @Param request body dto.MysqlLodaDB true "request"
// @Security ApiKeyAuth
// @Router /databases/load/:from [get]
// @Router /databases/load [post]
func (b *BaseApi) LoadDBFromRemote(c *gin.Context) {
from, err := helper.GetStrParamByKey(c, "from")
if err != nil {
var req dto.MysqlLodaDB
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := mysqlService.LoadFromRemote(from); err != nil {
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := mysqlService.LoadFromRemote(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@ -252,12 +258,12 @@ func (b *BaseApi) LoadDBFromRemote(c *gin.Context) {
// @Summary Check before delete mysql database
// @Description Mysql 数据库删除前检查
// @Accept json
// @Param request body dto.OperateByID true "request"
// @Param request body dto.MysqlDBDeleteCheck true "request"
// @Success 200 {array} string
// @Security ApiKeyAuth
// @Router /databases/del/check [post]
func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
var req dto.OperateByID
var req dto.MysqlDBDeleteCheck
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
@ -267,7 +273,7 @@ func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
return
}
apps, err := mysqlService.DeleteCheck(req.ID)
apps, err := mysqlService.DeleteCheck(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -308,11 +314,18 @@ func (b *BaseApi) DeleteMysql(c *gin.Context) {
// @Tags Database Mysql
// @Summary Load mysql base info
// @Description 获取 mysql 基础信息
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {object} dto.DBBaseInfo
// @Security ApiKeyAuth
// @Router /databases/baseinfo [get]
// @Router /databases/baseinfo [post]
func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
data, err := mysqlService.LoadBaseInfo()
var req dto.OperationWithNameAndType
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := mysqlService.LoadBaseInfo(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -346,11 +359,18 @@ func (b *BaseApi) LoadDatabaseFile(c *gin.Context) {
// @Tags Database Mysql
// @Summary Load mysql remote access
// @Description 获取 mysql 远程访问权限
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {boolean} isRemote
// @Security ApiKeyAuth
// @Router /databases/remote [get]
// @Router /databases/remote [post]
func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
isRemote, err := mysqlService.LoadRemoteAccess()
var req dto.OperationWithNameAndType
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
isRemote, err := mysqlService.LoadRemoteAccess(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -362,11 +382,18 @@ func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
// @Tags Database Mysql
// @Summary Load mysql status info
// @Description 获取 mysql 状态信息
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {object} dto.MysqlStatus
// @Security ApiKeyAuth
// @Router /databases/status [get]
// @Router /databases/status [post]
func (b *BaseApi) LoadStatus(c *gin.Context) {
data, err := mysqlService.LoadStatus()
var req dto.OperationWithNameAndType
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := mysqlService.LoadStatus(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
@ -378,11 +405,18 @@ func (b *BaseApi) LoadStatus(c *gin.Context) {
// @Tags Database Mysql
// @Summary Load mysql variables info
// @Description 获取 mysql 性能参数信息
// @Accept json
// @Param request body dto.OperationWithNameAndType true "request"
// @Success 200 {object} dto.MysqlVariables
// @Security ApiKeyAuth
// @Router /databases/variables [get]
// @Router /databases/variables [post]
func (b *BaseApi) LoadVariables(c *gin.Context) {
data, err := mysqlService.LoadVariables()
var req dto.OperationWithNameAndType
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
data, err := mysqlService.LoadVariables(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return

View File

@ -22,7 +22,7 @@ var (
dockerService = service.NewIDockerService()
mysqlService = service.NewIMysqlService()
remoteDBService = service.NewIRemoteDBService()
databaseService = service.NewIDatabaseService()
redisService = service.NewIRedisService()
cronjobService = service.NewICronjobService()

View File

@ -21,25 +21,18 @@ type BackupInfo struct {
Vars string `json:"vars"`
}
type BackupSearch struct {
PageInfo
Type string `json:"type" validate:"required,oneof=website mysql"`
Name string `json:"name" validate:"required"`
DetailName string `json:"detailName"`
}
type BackupSearchFile struct {
Type string `json:"type" validate:"required"`
}
type CommonBackup struct {
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website"`
Name string `json:"name"`
DetailName string `json:"detailName"`
}
type CommonRecover struct {
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO OneDrive"`
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website"`
Name string `json:"name"`
DetailName string `json:"detailName"`
File string `json:"file"`

View File

@ -4,10 +4,10 @@ import "time"
type MysqlDBSearch struct {
PageInfo
Info string `json:"info"`
From string `json:"from"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
Info string `json:"info"`
Database string `json:"database" validate:"required"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
}
type MysqlDBInfo struct {
@ -25,14 +25,15 @@ type MysqlDBInfo struct {
}
type MysqlOption struct {
ID uint `json:"id"`
Name string `json:"name"`
From string `json:"from"`
ID uint `json:"id"`
From string `json:"from"`
Database string `json:"database"`
}
type MysqlDBCreate struct {
Name string `json:"name" validate:"required"`
From string `json:"from" validate:"required"`
From string `json:"from" validate:"required,oneof=local remote"`
Database string `json:"database" validate:"required"`
Format string `json:"format" validate:"required,oneof=utf8mb4 utf8 gbk big5"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
@ -40,10 +41,24 @@ type MysqlDBCreate struct {
Description string `json:"description"`
}
type MysqlLodaDB struct {
From string `json:"from" validate:"required,oneof=local remote"`
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
Database string `json:"database" validate:"required"`
}
type MysqlDBDeleteCheck struct {
ID uint `json:"id" validate:"required"`
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
Database string `json:"database" validate:"required"`
}
type MysqlDBDelete struct {
ID uint `json:"id" validate:"required"`
ForceDelete bool `json:"forceDelete"`
DeleteBackup bool `json:"deleteBackup"`
ID uint `json:"id" validate:"required"`
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
Database string `json:"database" validate:"required"`
ForceDelete bool `json:"forceDelete"`
DeleteBackup bool `json:"deleteBackup"`
}
type MysqlStatus struct {
@ -107,18 +122,27 @@ type MysqlVariables struct {
}
type MysqlVariablesUpdate struct {
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
Database string `json:"database" validate:"required"`
Variables []MysqlVariablesUpdateHelper `json:"variables"`
}
type MysqlVariablesUpdateHelper struct {
Param string `json:"param"`
Value interface{} `json:"value"`
}
type MysqlConfUpdateByFile struct {
MysqlName string `json:"mysqlName" validate:"required"`
File string `json:"file"`
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
Database string `json:"database" validate:"required"`
File string `json:"file"`
}
type ChangeDBInfo struct {
ID uint `json:"id"`
From string `json:"from"`
Value string `json:"value" validate:"required"`
ID uint `json:"id"`
From string `json:"from" validate:"required,oneof=local remote"`
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
Database string `json:"database" validate:"required"`
Value string `json:"value" validate:"required"`
}
type DBBaseInfo struct {
@ -127,11 +151,6 @@ type DBBaseInfo struct {
Port int64 `json:"port"`
}
type SearchDBWithPage struct {
PageInfo
MysqlName string `json:"mysqlName" validate:"required"`
}
type BackupDB struct {
MysqlName string `json:"mysqlName" validate:"required"`
DBName string `json:"dbName" validate:"required"`
@ -209,3 +228,56 @@ type RedisBackupRecover struct {
FileName string `json:"fileName"`
FileDir string `json:"fileDir"`
}
// database
type DatabaseSearch struct {
PageInfo
Info string `json:"info"`
Type string `json:"type"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
}
type DatabaseInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name" validate:"max=256"`
From string `json:"from"`
Version string `json:"version"`
Address string `json:"address"`
Port uint `json:"port"`
Username string `json:"username"`
Password string `json:"password"`
Description string `json:"description"`
}
type DatabaseOption struct {
ID uint `json:"id"`
Type string `json:"type"`
From string `json:"from"`
Database string `json:"database"`
Version string `json:"version"`
Address string `json:"address"`
}
type DatabaseCreate struct {
Name string `json:"name" validate:"required,max=256"`
Type string `json:"type" validate:"required,oneof=mysql"`
From string `json:"from" validate:"required,oneof=local remote"`
Version string `json:"version" validate:"required"`
Address string `json:"address"`
Port uint `json:"port"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Description string `json:"description"`
}
type DatabaseUpdate struct {
ID uint `json:"id"`
Version string `json:"version" validate:"required"`
Address string `json:"address"`
Port uint `json:"port"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Description string `json:"description"`
}

View File

@ -1,52 +0,0 @@
package dto
import "time"
type RemoteDBSearch struct {
PageInfo
Info string `json:"info"`
Type string `json:"type"`
OrderBy string `json:"orderBy"`
Order string `json:"order"`
}
type RemoteDBInfo struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"createdAt"`
Name string `json:"name" validate:"max=256"`
From string `json:"from"`
Version string `json:"version"`
Address string `json:"address"`
Port uint `json:"port"`
Username string `json:"username"`
Password string `json:"password"`
Description string `json:"description"`
}
type RemoteDBOption struct {
ID uint `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
}
type RemoteDBCreate struct {
Name string `json:"name" validate:"required,max=256"`
Type string `json:"type" validate:"required,oneof=mysql"`
From string `json:"from" validate:"required,oneof=local remote"`
Version string `json:"version" validate:"required"`
Address string `json:"address"`
Port uint `json:"port"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Description string `json:"description"`
}
type RemoteDBUpdate struct {
ID uint `json:"id"`
Version string `json:"version" validate:"required"`
Address string `json:"address"`
Port uint `json:"port"`
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
Description string `json:"description"`
}

View File

@ -41,6 +41,11 @@ type AppInstalledSearch struct {
Unused bool `json:"unused"`
}
type AppInstalledInfo struct {
Key string `json:"key" validate:"required"`
Name string `json:"name"`
}
type AppBackupSearch struct {
dto.PageInfo
AppInstallID uint `json:"appInstallID"`

View File

@ -0,0 +1,15 @@
package model
type Database struct {
BaseModel
AppInstallID uint `json:"appInstallID" gorm:"type:decimal"`
Name string `json:"name" gorm:"type:varchar(64);not null;unique"`
Type string `json:"type" gorm:"type:varchar(64);not null"`
Version string `json:"version" gorm:"type:varchar(64);not null"`
From string `json:"from" gorm:"type:varchar(64);not null"`
Address string `json:"address" gorm:"type:varchar(64);not null"`
Port uint `json:"port" gorm:"type:decimal;not null"`
Username string `json:"username" gorm:"type:varchar(64)"`
Password string `json:"password" gorm:"type:varchar(64)"`
Description string `json:"description" gorm:"type:varchar(256);"`
}

View File

@ -1,14 +0,0 @@
package model
type RemoteDB struct {
BaseModel
Name string `json:"name" gorm:"type:varchar(64);not null"`
Type string `json:"type" gorm:"type:varchar(64);not null"`
Version string `json:"version" gorm:"type:varchar(64);not null"`
From string `json:"from" gorm:"type:varchar(64);not null"`
Address string `json:"address" gorm:"type:varchar(64);not null"`
Port uint `json:"port" gorm:"type:decimal;not null"`
Username string `json:"username" gorm:"type:varchar(64)"`
Password string `json:"password" gorm:"type:varchar(64)"`
Description string `json:"description" gorm:"type:varchar(256);"`
}

View File

@ -3,6 +3,7 @@ package repo
import (
"context"
"encoding/json"
"gorm.io/gorm/clause"
"github.com/1Panel-dev/1Panel/backend/app/model"
@ -193,7 +194,7 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
return nil, err
}
switch app.Key {
case "mysql":
case "mysql", "mariadb":
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
if ok {
info.Password = password

View File

@ -0,0 +1,91 @@
package repo
import (
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/global"
"gorm.io/gorm"
)
type DatabaseRepo struct{}
type IDatabaseRepo interface {
GetList(opts ...DBOption) ([]model.Database, error)
Page(limit, offset int, opts ...DBOption) (int64, []model.Database, error)
Create(database *model.Database) error
Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error
Get(opts ...DBOption) (model.Database, error)
WithByFrom(from string) DBOption
WithoutByFrom(from string) DBOption
WithByMysqlList() DBOption
}
func NewIDatabaseRepo() IDatabaseRepo {
return &DatabaseRepo{}
}
func (u *DatabaseRepo) Get(opts ...DBOption) (model.Database, error) {
var database model.Database
db := global.DB
for _, opt := range opts {
db = opt(db)
}
err := db.First(&database).Error
return database, err
}
func (u *DatabaseRepo) Page(page, size int, opts ...DBOption) (int64, []model.Database, error) {
var users []model.Database
db := global.DB.Model(&model.Database{})
for _, opt := range opts {
db = opt(db)
}
count := int64(0)
db = db.Count(&count)
err := db.Limit(size).Offset(size * (page - 1)).Find(&users).Error
return count, users, err
}
func (u *DatabaseRepo) GetList(opts ...DBOption) ([]model.Database, error) {
var databases []model.Database
db := global.DB.Model(&model.Database{})
for _, opt := range opts {
db = opt(db)
}
err := db.Find(&databases).Error
return databases, err
}
func (c *DatabaseRepo) WithByMysqlList() DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("type == ? OR type == ?", "mysql", "mariadb")
}
}
func (c *DatabaseRepo) WithByFrom(from string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("`from` == ?", from)
}
}
func (c *DatabaseRepo) WithoutByFrom(from string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("`from` != ?", from)
}
}
func (u *DatabaseRepo) Create(database *model.Database) error {
return global.DB.Create(database).Error
}
func (u *DatabaseRepo) Update(id uint, vars map[string]interface{}) error {
return global.DB.Model(&model.Database{}).Where("id = ?", id).Updates(vars).Error
}
func (u *DatabaseRepo) Delete(opts ...DBOption) error {
db := global.DB
for _, opt := range opts {
db = opt(db)
}
return db.Delete(&model.Database{}).Error
}

View File

@ -1,84 +0,0 @@
package repo
import (
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/global"
"gorm.io/gorm"
)
type RemoteDBRepo struct{}
type IRemoteDBRepo interface {
GetList(opts ...DBOption) ([]model.RemoteDB, error)
Page(limit, offset int, opts ...DBOption) (int64, []model.RemoteDB, error)
Create(database *model.RemoteDB) error
Update(id uint, vars map[string]interface{}) error
Delete(opts ...DBOption) error
Get(opts ...DBOption) (model.RemoteDB, error)
WithByFrom(from string) DBOption
WithoutByFrom(from string) DBOption
}
func NewIRemoteDBRepo() IRemoteDBRepo {
return &RemoteDBRepo{}
}
func (u *RemoteDBRepo) Get(opts ...DBOption) (model.RemoteDB, error) {
var database model.RemoteDB
db := global.DB
for _, opt := range opts {
db = opt(db)
}
err := db.First(&database).Error
return database, err
}
func (u *RemoteDBRepo) Page(page, size int, opts ...DBOption) (int64, []model.RemoteDB, error) {
var users []model.RemoteDB
db := global.DB.Model(&model.RemoteDB{})
for _, opt := range opts {
db = opt(db)
}
count := int64(0)
db = db.Count(&count)
err := db.Limit(size).Offset(size * (page - 1)).Find(&users).Error
return count, users, err
}
func (u *RemoteDBRepo) GetList(opts ...DBOption) ([]model.RemoteDB, error) {
var databases []model.RemoteDB
db := global.DB.Model(&model.RemoteDB{})
for _, opt := range opts {
db = opt(db)
}
err := db.Find(&databases).Error
return databases, err
}
func (c *RemoteDBRepo) WithByFrom(from string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("`from` == ?", from)
}
}
func (c *RemoteDBRepo) WithoutByFrom(from string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("`from` != ?", from)
}
}
func (u *RemoteDBRepo) Create(database *model.RemoteDB) error {
return global.DB.Create(database).Error
}
func (u *RemoteDBRepo) Update(id uint, vars map[string]interface{}) error {
return global.DB.Model(&model.RemoteDB{}).Where("id = ?", id).Updates(vars).Error
}
func (u *RemoteDBRepo) Delete(opts ...DBOption) error {
db := global.DB
for _, opt := range opts {
db = opt(db)
}
return db.Delete(&model.RemoteDB{}).Error
}

View File

@ -41,9 +41,9 @@ type AppInstallService struct {
type IAppInstallService interface {
Page(req request.AppInstalledSearch) (int64, []response.AppInstalledDTO, error)
CheckExist(key string) (*response.AppInstalledCheck, error)
LoadPort(key string) (int64, error)
LoadConnInfo(key string) (response.DatabaseConn, error)
CheckExist(req request.AppInstalledInfo) (*response.AppInstalledCheck, error)
LoadPort(req dto.OperationWithNameAndType) (int64, error)
LoadConnInfo(req dto.OperationWithNameAndType) (response.DatabaseConn, error)
SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error)
Operate(req request.AppInstalledOperate) error
Update(req request.AppInstalledUpdate) error
@ -130,23 +130,31 @@ func (a *AppInstallService) Page(req request.AppInstalledSearch) (int64, []respo
return total, installDTOs, nil
}
func (a *AppInstallService) CheckExist(key string) (*response.AppInstalledCheck, error) {
func (a *AppInstallService) CheckExist(req request.AppInstalledInfo) (*response.AppInstalledCheck, error) {
res := &response.AppInstalledCheck{
IsExist: false,
}
app, err := appRepo.GetFirst(appRepo.WithKey(key))
app, err := appRepo.GetFirst(appRepo.WithKey(req.Key))
if err != nil {
return res, nil
}
res.App = app.Name
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID))
if reflect.DeepEqual(appInstall, model.AppInstall{}) {
return res, nil
var appInstall model.AppInstall
if len(req.Name) == 0 {
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID))
if reflect.DeepEqual(appInstall, model.AppInstall{}) {
return res, nil
}
if err := syncById(appInstall.ID); err != nil {
return nil, err
}
appInstall, _ = appInstallRepo.GetFirst(commonRepo.WithByID(appInstall.ID))
} else {
appInstall, _ = appInstallRepo.GetFirst(commonRepo.WithByName(req.Name))
}
if err := syncById(appInstall.ID); err != nil {
return nil, err
}
appInstall, _ = appInstallRepo.GetFirst(commonRepo.WithByID(appInstall.ID))
res.ContainerName = appInstall.ContainerName
res.Name = appInstall.Name
@ -155,24 +163,24 @@ func (a *AppInstallService) CheckExist(key string) (*response.AppInstalledCheck,
res.Status = appInstall.Status
res.AppInstallID = appInstall.ID
res.IsExist = true
res.InstallPath = path.Join(constant.AppInstallDir, app.Key, appInstall.Name)
res.InstallPath = path.Join(constant.AppInstallDir, appInstall.App.Key, appInstall.Name)
res.HttpPort = appInstall.HttpPort
res.HttpsPort = appInstall.HttpsPort
return res, nil
}
func (a *AppInstallService) LoadPort(key string) (int64, error) {
app, err := appInstallRepo.LoadBaseInfo(key, "")
func (a *AppInstallService) LoadPort(req dto.OperationWithNameAndType) (int64, error) {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
if err != nil {
return int64(0), nil
}
return app.Port, nil
}
func (a *AppInstallService) LoadConnInfo(key string) (response.DatabaseConn, error) {
func (a *AppInstallService) LoadConnInfo(req dto.OperationWithNameAndType) (response.DatabaseConn, error) {
var data response.DatabaseConn
app, err := appInstallRepo.LoadBaseInfo(key, "")
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
if err != nil {
return data, nil
}
@ -748,7 +756,7 @@ func updateInstallInfoInDB(appKey, appName, param string, isRestart bool, value
envKey := ""
switch param {
case "password":
if appKey == "mysql" {
if appKey == "mysql" || appKey == "mariadb" {
envKey = "PANEL_DB_ROOT_PASSWORD="
} else {
envKey = "PANEL_REDIS_ROOT_PASSWORD="

View File

@ -106,7 +106,7 @@ func handleAppBackup(install *model.AppInstall, backupDir, fileName string) erro
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
for _, resource := range resources {
if resource.Key == "mysql" {
if resource.Key == "mysql" || resource.Key == "mariadb" {
db, err := mysqlRepo.Get(commonRepo.WithByID(resource.ResourceId))
if err != nil {
return err
@ -173,7 +173,7 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
newEnvFile := ""
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
for _, resource := range resources {
if resource.Key == "mysql" {
if resource.Key == "mysql" || resource.Key == "maraidb" {
mysqlInfo, err := appInstallRepo.LoadBaseInfo(resource.Key, "")
if err != nil {
return err

View File

@ -23,7 +23,7 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
}
timeNow := time.Now().Format("20060102150405")
targetDir := path.Join(localDir, fmt.Sprintf("database/mysql/%s/%s", req.Name, req.DetailName))
targetDir := path.Join(localDir, fmt.Sprintf("database/%s/%s/%s", req.Type, req.Name, req.DetailName))
fileName := fmt.Sprintf("%s_%s.sql.gz", req.DetailName, timeNow)
if err := handleMysqlBackup(req.Name, req.DetailName, targetDir, fileName); err != nil {
@ -31,7 +31,7 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error {
}
record := &model.BackupRecord{
Type: "mysql",
Type: req.Type,
Name: req.Name,
DetailName: req.DetailName,
Source: "LOCAL",
@ -97,12 +97,12 @@ func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
return nil
}
func handleMysqlBackup(name, dbName, targetDir, fileName string) error {
dbInfo, err := mysqlRepo.Get(commonRepo.WithByName(dbName), mysqlRepo.WithByMysqlName(name))
func handleMysqlBackup(database, dbName, targetDir, fileName string) error {
dbInfo, err := mysqlRepo.Get(commonRepo.WithByName(dbName), mysqlRepo.WithByMysqlName(database))
if err != nil {
return err
}
cli, _, err := LoadMysqlClientByFrom(dbInfo.From)
cli, _, err := LoadMysqlClientByFrom(database)
if err != nil {
return err
}
@ -131,13 +131,13 @@ func handleMysqlRecover(req dto.CommonRecover, isRollback bool) error {
if err != nil {
return err
}
cli, _, err := LoadMysqlClientByFrom(dbInfo.From)
cli, _, err := LoadMysqlClientByFrom(req.Name)
if err != nil {
return err
}
if !isRollback {
rollbackFile := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("database/mysql/%s_%s.sql.gz", req.DetailName, time.Now().Format("20060102150405")))
rollbackFile := path.Join(global.CONF.System.TmpDir, fmt.Sprintf("database/%s/%s_%s.sql.gz", req.Type, req.DetailName, time.Now().Format("20060102150405")))
if err := cli.Backup(client.BackupInfo{
Name: req.DetailName,
Format: dbInfo.Format,

View File

@ -293,12 +293,13 @@ func (u *CronjobService) handleDatabase(cronjob model.Cronjob, backup model.Back
for _, dbInfo := range dbs {
var record model.BackupRecord
record.Type = "mysql"
database, _ := databaseRepo.Get(commonRepo.WithByName(dbInfo.MysqlName))
record.Type = database.Type
record.Source = "LOCAL"
record.BackupType = backup.Type
record.Name = dbInfo.MysqlName
backupDir := path.Join(localDir, fmt.Sprintf("database/mysql/%s/%s", record.Name, dbInfo.Name))
backupDir := path.Join(localDir, fmt.Sprintf("database/%s/%s/%s", database.Type, record.Name, dbInfo.Name))
record.FileName = fmt.Sprintf("db_%s_%s.sql.gz", dbInfo.Name, startTime.Format("20060102150405"))
if err = handleMysqlBackup(dbInfo.MysqlName, dbInfo.Name, backupDir, record.FileName); err != nil {
return paths, err

View File

@ -4,6 +4,7 @@ import (
"context"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/repo"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/mysql"
"github.com/1Panel-dev/1Panel/backend/utils/mysql/client"
@ -11,31 +12,31 @@ import (
"github.com/pkg/errors"
)
type RemoteDBService struct{}
type DatabaseService struct{}
type IRemoteDBService interface {
Get(name string) (dto.RemoteDBInfo, error)
SearchWithPage(search dto.RemoteDBSearch) (int64, interface{}, error)
CheckeRemoteDB(req dto.RemoteDBCreate) bool
Create(req dto.RemoteDBCreate) error
Update(req dto.RemoteDBUpdate) error
type IDatabaseService interface {
Get(name string) (dto.DatabaseInfo, error)
SearchWithPage(search dto.DatabaseSearch) (int64, interface{}, error)
CheckDatabase(req dto.DatabaseCreate) bool
Create(req dto.DatabaseCreate) error
Update(req dto.DatabaseUpdate) error
Delete(id uint) error
List(dbType string) ([]dto.RemoteDBOption, error)
List(dbType string) ([]dto.DatabaseOption, error)
}
func NewIRemoteDBService() IRemoteDBService {
return &RemoteDBService{}
func NewIDatabaseService() IDatabaseService {
return &DatabaseService{}
}
func (u *RemoteDBService) SearchWithPage(search dto.RemoteDBSearch) (int64, interface{}, error) {
total, dbs, err := remoteDBRepo.Page(search.Page, search.PageSize,
func (u *DatabaseService) SearchWithPage(search dto.DatabaseSearch) (int64, interface{}, error) {
total, dbs, err := databaseRepo.Page(search.Page, search.PageSize,
commonRepo.WithByType(search.Type),
commonRepo.WithLikeName(search.Info),
remoteDBRepo.WithoutByFrom("local"),
databaseRepo.WithoutByFrom("local"),
)
var datas []dto.RemoteDBInfo
var datas []dto.DatabaseInfo
for _, db := range dbs {
var item dto.RemoteDBInfo
var item dto.DatabaseInfo
if err := copier.Copy(&item, &db); err != nil {
return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
}
@ -44,9 +45,9 @@ func (u *RemoteDBService) SearchWithPage(search dto.RemoteDBSearch) (int64, inte
return total, datas, err
}
func (u *RemoteDBService) Get(name string) (dto.RemoteDBInfo, error) {
var data dto.RemoteDBInfo
remote, err := remoteDBRepo.Get(commonRepo.WithByName(name))
func (u *DatabaseService) Get(name string) (dto.DatabaseInfo, error) {
var data dto.DatabaseInfo
remote, err := databaseRepo.Get(commonRepo.WithByName(name))
if err != nil {
return data, err
}
@ -56,20 +57,27 @@ func (u *RemoteDBService) Get(name string) (dto.RemoteDBInfo, error) {
return data, nil
}
func (u *RemoteDBService) List(dbType string) ([]dto.RemoteDBOption, error) {
dbs, err := remoteDBRepo.GetList(commonRepo.WithByType(dbType))
var datas []dto.RemoteDBOption
func (u *DatabaseService) List(dbType string) ([]dto.DatabaseOption, error) {
var opts []repo.DBOption
if dbType == "mysql" {
opts = append(opts, databaseRepo.WithByMysqlList())
} else {
opts = append(opts, commonRepo.WithByType(dbType))
}
dbs, err := databaseRepo.GetList(opts...)
var datas []dto.DatabaseOption
for _, db := range dbs {
var item dto.RemoteDBOption
var item dto.DatabaseOption
if err := copier.Copy(&item, &db); err != nil {
return nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
}
item.Database = db.Name
datas = append(datas, item)
}
return datas, err
}
func (u *RemoteDBService) CheckeRemoteDB(req dto.RemoteDBCreate) bool {
func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
if _, err := mysql.NewMysqlClient(client.DBInfo{
From: "remote",
Address: req.Address,
@ -83,8 +91,8 @@ func (u *RemoteDBService) CheckeRemoteDB(req dto.RemoteDBCreate) bool {
return true
}
func (u *RemoteDBService) Create(req dto.RemoteDBCreate) error {
db, _ := remoteDBRepo.Get(commonRepo.WithByName(req.Name))
func (u *DatabaseService) Create(req dto.DatabaseCreate) error {
db, _ := databaseRepo.Get(commonRepo.WithByName(req.Name))
if db.ID != 0 {
return constant.ErrRecordExist
}
@ -101,29 +109,29 @@ func (u *RemoteDBService) Create(req dto.RemoteDBCreate) error {
if err := copier.Copy(&db, &req); err != nil {
return errors.WithMessage(constant.ErrStructTransform, err.Error())
}
if err := remoteDBRepo.Create(&db); err != nil {
if err := databaseRepo.Create(&db); err != nil {
return err
}
return nil
}
func (u *RemoteDBService) Delete(id uint) error {
db, _ := remoteDBRepo.Get(commonRepo.WithByID(id))
func (u *DatabaseService) Delete(id uint) error {
db, _ := databaseRepo.Get(commonRepo.WithByID(id))
if db.ID == 0 {
return constant.ErrRecordNotFound
}
if err := remoteDBRepo.Delete(commonRepo.WithByID(id)); err != nil {
if err := databaseRepo.Delete(commonRepo.WithByID(id)); err != nil {
return err
}
if db.From != "local" {
if err := mysqlRepo.Delete(context.Background(), remoteDBRepo.WithByFrom(db.Name)); err != nil {
if err := mysqlRepo.Delete(context.Background(), databaseRepo.WithByFrom(db.Name)); err != nil {
return err
}
}
return nil
}
func (u *RemoteDBService) Update(req dto.RemoteDBUpdate) error {
func (u *DatabaseService) Update(req dto.DatabaseUpdate) error {
if _, err := mysql.NewMysqlClient(client.DBInfo{
From: "remote",
Address: req.Address,
@ -142,5 +150,5 @@ func (u *RemoteDBService) Update(req dto.RemoteDBUpdate) error {
upMap["username"] = req.Username
upMap["password"] = req.Password
upMap["description"] = req.Description
return remoteDBRepo.Update(req.ID, upMap)
return databaseRepo.Update(req.ID, upMap)
}

View File

@ -34,18 +34,19 @@ type IMysqlService interface {
SearchWithPage(search dto.MysqlDBSearch) (int64, interface{}, error)
ListDBOption() ([]dto.MysqlOption, error)
Create(ctx context.Context, req dto.MysqlDBCreate) (*model.DatabaseMysql, error)
LoadFromRemote(from string) error
LoadFromRemote(req dto.MysqlLodaDB) error
ChangeAccess(info dto.ChangeDBInfo) error
ChangePassword(info dto.ChangeDBInfo) error
UpdateVariables(updates []dto.MysqlVariablesUpdate) error
UpdateVariables(req dto.MysqlVariablesUpdate) error
UpdateConfByFile(info dto.MysqlConfUpdateByFile) error
UpdateDescription(req dto.UpdateDescription) error
DeleteCheck(id uint) ([]string, error)
DeleteCheck(req dto.MysqlDBDeleteCheck) ([]string, error)
Delete(ctx context.Context, req dto.MysqlDBDelete) error
LoadStatus() (*dto.MysqlStatus, error)
LoadVariables() (*dto.MysqlVariables, error)
LoadBaseInfo() (*dto.DBBaseInfo, error)
LoadRemoteAccess() (bool, error)
LoadStatus(req dto.OperationWithNameAndType) (*dto.MysqlStatus, error)
LoadVariables(req dto.OperationWithNameAndType) (*dto.MysqlVariables, error)
LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error)
LoadRemoteAccess(req dto.OperationWithNameAndType) (bool, error)
LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error)
}
@ -56,7 +57,7 @@ func NewIMysqlService() IMysqlService {
func (u *MysqlService) SearchWithPage(search dto.MysqlDBSearch) (int64, interface{}, error) {
total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize,
mysqlRepo.WithByFrom(search.From),
mysqlRepo.WithByMysqlName(search.Database),
commonRepo.WithLikeName(search.Info),
commonRepo.WithOrderRuleBy(search.OrderBy, search.Order),
)
@ -89,7 +90,7 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
return nil, buserr.New(constant.ErrCmdIllegal)
}
mysql, _ := mysqlRepo.Get(commonRepo.WithByName(req.Name), remoteDBRepo.WithByFrom(req.From))
mysql, _ := mysqlRepo.Get(commonRepo.WithByName(req.Name), databaseRepo.WithByFrom(req.From))
if mysql.ID != 0 {
return nil, constant.ErrRecordExist
}
@ -103,20 +104,11 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
return nil, errors.New("Cannot set root as user name")
}
cli, version, err := LoadMysqlClientByFrom(req.From)
cli, version, err := LoadMysqlClientByFrom(req.Database)
if err != nil {
return nil, err
}
if req.From == "local" {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if err != nil {
return nil, err
}
createItem.MysqlName = app.Name
} else {
createItem.MysqlName = req.From
}
createItem.MysqlName = req.Database
defer cli.Close()
if err := cli.Create(client.CreateInfo{
Name: req.Name,
@ -137,22 +129,22 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
return &createItem, nil
}
func (u *MysqlService) LoadFromRemote(from string) error {
client, version, err := LoadMysqlClientByFrom(from)
func (u *MysqlService) LoadFromRemote(req dto.MysqlLodaDB) error {
client, version, err := LoadMysqlClientByFrom(req.Database)
if err != nil {
return err
}
mysqlName := from
if from == "local" {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
mysqlName := req.From
if req.From == "local" {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database)
if err != nil {
return err
}
mysqlName = app.Name
}
databases, err := mysqlRepo.List(remoteDBRepo.WithByFrom(from))
databases, err := mysqlRepo.List(databaseRepo.WithByFrom(req.From))
if err != nil {
return err
}
@ -186,15 +178,15 @@ func (u *MysqlService) UpdateDescription(req dto.UpdateDescription) error {
return mysqlRepo.Update(req.ID, map[string]interface{}{"description": req.Description})
}
func (u *MysqlService) DeleteCheck(id uint) ([]string, error) {
func (u *MysqlService) DeleteCheck(req dto.MysqlDBDeleteCheck) ([]string, error) {
var appInUsed []string
db, err := mysqlRepo.Get(commonRepo.WithByID(id))
db, err := mysqlRepo.Get(commonRepo.WithByID(req.ID))
if err != nil {
return appInUsed, err
}
if db.From == "local" {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database)
if err != nil {
return appInUsed, err
}
@ -223,7 +215,7 @@ func (u *MysqlService) Delete(ctx context.Context, req dto.MysqlDBDelete) error
if err != nil && !req.ForceDelete {
return err
}
cli, version, err := LoadMysqlClientByFrom(db.From)
cli, version, err := LoadMysqlClientByFrom(req.Database)
if err != nil {
return err
}
@ -238,12 +230,7 @@ func (u *MysqlService) Delete(ctx context.Context, req dto.MysqlDBDelete) error
return err
}
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if err != nil && !req.ForceDelete {
return err
}
uploadDir := path.Join(global.CONF.System.BaseDir, fmt.Sprintf("1panel/uploads/database/mysql/%s/%s", app.Name, db.Name))
uploadDir := path.Join(global.CONF.System.BaseDir, fmt.Sprintf("1panel/uploads/database/%s/%s/%s", req.Type, req.Database, db.Name))
if _, err := os.Stat(uploadDir); err == nil {
_ = os.RemoveAll(uploadDir)
}
@ -252,23 +239,23 @@ func (u *MysqlService) Delete(ctx context.Context, req dto.MysqlDBDelete) error
if err != nil && !req.ForceDelete {
return err
}
backupDir := path.Join(localDir, fmt.Sprintf("database/mysql/%s/%s", db.MysqlName, db.Name))
backupDir := path.Join(localDir, fmt.Sprintf("database/%s/%s/%s", req.Type, db.MysqlName, db.Name))
if _, err := os.Stat(backupDir); err == nil {
_ = os.RemoveAll(backupDir)
}
global.LOG.Infof("delete database %s-%s backups successful", app.Name, db.Name)
global.LOG.Infof("delete database %s-%s backups successful", req.Database, db.Name)
}
_ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType("mysql"), commonRepo.WithByName(app.Name), backupRepo.WithByDetailName(db.Name))
_ = backupRepo.DeleteRecord(ctx, commonRepo.WithByType(req.Type), commonRepo.WithByName(req.Database), backupRepo.WithByDetailName(db.Name))
_ = mysqlRepo.Delete(ctx, commonRepo.WithByID(db.ID))
return nil
}
func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error {
if cmd.CheckIllegal(info.Value) {
func (u *MysqlService) ChangePassword(req dto.ChangeDBInfo) error {
if cmd.CheckIllegal(req.Value) {
return buserr.New(constant.ErrCmdIllegal)
}
cli, version, err := LoadMysqlClientByFrom(info.From)
cli, version, err := LoadMysqlClientByFrom(req.Database)
if err != nil {
return err
}
@ -277,12 +264,12 @@ func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error {
mysqlData model.DatabaseMysql
passwordInfo client.PasswordChangeInfo
)
passwordInfo.Password = info.Value
passwordInfo.Password = req.Value
passwordInfo.Timeout = 300
passwordInfo.Version = version
if info.ID != 0 {
mysqlData, err = mysqlRepo.Get(commonRepo.WithByID(info.ID))
if req.ID != 0 {
mysqlData, err = mysqlRepo.Get(commonRepo.WithByID(req.ID))
if err != nil {
return err
}
@ -296,10 +283,10 @@ func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error {
return err
}
if info.ID != 0 {
if req.ID != 0 {
var appRess []model.AppInstallResource
if info.From == "local" {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
if req.From == "local" {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database)
if err != nil {
return err
}
@ -318,29 +305,26 @@ func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error {
}
global.LOG.Infof("start to update mysql password used by app %s-%s", appModel.Key, appInstall.Name)
if err := updateInstallInfoInDB(appModel.Key, appInstall.Name, "user-password", true, info.Value); err != nil {
if err := updateInstallInfoInDB(appModel.Key, appInstall.Name, "user-password", true, req.Value); err != nil {
return err
}
}
global.LOG.Info("excute password change sql successful")
_ = mysqlRepo.Update(mysqlData.ID, map[string]interface{}{"password": info.Value})
_ = mysqlRepo.Update(mysqlData.ID, map[string]interface{}{"password": req.Value})
return nil
}
if err := updateInstallInfoInDB("mysql", "", "password", false, info.Value); err != nil {
return err
}
if err := updateInstallInfoInDB("phpmyadmin", "", "password", true, info.Value); err != nil {
if err := updateInstallInfoInDB(req.Type, req.Database, "password", false, req.Value); err != nil {
return err
}
return nil
}
func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
if cmd.CheckIllegal(info.Value) {
func (u *MysqlService) ChangeAccess(req dto.ChangeDBInfo) error {
if cmd.CheckIllegal(req.Value) {
return buserr.New(constant.ErrCmdIllegal)
}
cli, version, err := LoadMysqlClientByFrom(info.From)
cli, version, err := LoadMysqlClientByFrom(req.Database)
if err != nil {
return err
}
@ -349,12 +333,12 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
mysqlData model.DatabaseMysql
accessInfo client.AccessChangeInfo
)
accessInfo.Permission = info.Value
accessInfo.Permission = req.Value
accessInfo.Timeout = 300
accessInfo.Version = version
if info.ID != 0 {
mysqlData, err = mysqlRepo.Get(commonRepo.WithByID(info.ID))
if req.ID != 0 {
mysqlData, err = mysqlRepo.Get(commonRepo.WithByID(req.ID))
if err != nil {
return err
}
@ -370,40 +354,40 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
}
if mysqlData.ID != 0 {
_ = mysqlRepo.Update(mysqlData.ID, map[string]interface{}{"permission": info.Value})
_ = mysqlRepo.Update(mysqlData.ID, map[string]interface{}{"permission": req.Value})
}
return nil
}
func (u *MysqlService) UpdateConfByFile(info dto.MysqlConfUpdateByFile) error {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
func (u *MysqlService) UpdateConfByFile(req dto.MysqlConfUpdateByFile) error {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database)
if err != nil {
return err
}
path := fmt.Sprintf("%s/mysql/%s/conf/my.cnf", constant.AppInstallDir, app.Name)
path := fmt.Sprintf("%s/%s/%s/conf/my.cnf", constant.AppInstallDir, req.Type, app.Name)
file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0640)
if err != nil {
return err
}
defer file.Close()
write := bufio.NewWriter(file)
_, _ = write.WriteString(info.File)
_, _ = write.WriteString(req.File)
write.Flush()
if _, err := compose.Restart(fmt.Sprintf("%s/mysql/%s/docker-compose.yml", constant.AppInstallDir, app.Name)); err != nil {
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Type, app.Name)); err != nil {
return err
}
return nil
}
func (u *MysqlService) UpdateVariables(updates []dto.MysqlVariablesUpdate) error {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
func (u *MysqlService) UpdateVariables(req dto.MysqlVariablesUpdate) error {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database)
if err != nil {
return err
}
var files []string
path := fmt.Sprintf("%s/mysql/%s/conf/my.cnf", constant.AppInstallDir, app.Name)
path := fmt.Sprintf("%s/%s/%s/conf/my.cnf", constant.AppInstallDir, req.Type, app.Name)
lineBytes, err := os.ReadFile(path)
if err != nil {
return err
@ -411,7 +395,7 @@ func (u *MysqlService) UpdateVariables(updates []dto.MysqlVariablesUpdate) error
files = strings.Split(string(lineBytes), "\n")
group := "[mysqld]"
for _, info := range updates {
for _, info := range req.Variables {
if !strings.HasPrefix(app.Version, "5.7") && !strings.HasPrefix(app.Version, "5.6") {
if info.Param == "query_cache_size" {
continue
@ -434,16 +418,16 @@ func (u *MysqlService) UpdateVariables(updates []dto.MysqlVariablesUpdate) error
return err
}
if _, err := compose.Restart(fmt.Sprintf("%s/mysql/%s/docker-compose.yml", constant.AppInstallDir, app.Name)); err != nil {
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Type, app.Name)); err != nil {
return err
}
return nil
}
func (u *MysqlService) LoadBaseInfo() (*dto.DBBaseInfo, error) {
func (u *MysqlService) LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) {
var data dto.DBBaseInfo
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
if err != nil {
return nil, err
}
@ -454,8 +438,8 @@ func (u *MysqlService) LoadBaseInfo() (*dto.DBBaseInfo, error) {
return &data, nil
}
func (u *MysqlService) LoadRemoteAccess() (bool, error) {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
func (u *MysqlService) LoadRemoteAccess(req dto.OperationWithNameAndType) (bool, error) {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
if err != nil {
return false, err
}
@ -472,8 +456,8 @@ func (u *MysqlService) LoadRemoteAccess() (bool, error) {
return false, nil
}
func (u *MysqlService) LoadVariables() (*dto.MysqlVariables, error) {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
func (u *MysqlService) LoadVariables(req dto.OperationWithNameAndType) (*dto.MysqlVariables, error) {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
if err != nil {
return nil, err
}
@ -490,8 +474,8 @@ func (u *MysqlService) LoadVariables() (*dto.MysqlVariables, error) {
return &info, nil
}
func (u *MysqlService) LoadStatus() (*dto.MysqlStatus, error) {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
func (u *MysqlService) LoadStatus(req dto.OperationWithNameAndType) (*dto.MysqlStatus, error) {
app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
if err != nil {
return nil, err
}
@ -540,10 +524,14 @@ func (u *MysqlService) LoadDatabaseFile(req dto.OperationWithNameAndType) (strin
switch req.Type {
case "mysql-conf":
filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/mysql/%s/conf/my.cnf", req.Name))
case "mariadb-conf":
filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/mariadb/%s/conf/my.cnf", req.Name))
case "redis-conf":
filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/redis/%s/conf/redis.conf", req.Name))
case "slow-logs":
case "mysql-slow-logs":
filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/mysql/%s/data/1Panel-slow.log", req.Name))
case "mariadb-slow-logs":
filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/mariadb/%s/db/data/1Panel-slow.log", req.Name))
}
if _, err := os.Stat(filePath); err != nil {
return "", buserr.New("ErrHttpReqNotFound")
@ -625,20 +613,20 @@ func updateMyCnf(oldFiles []string, group string, param string, value interface{
return newFiles
}
func LoadMysqlClientByFrom(from string) (mysql.MysqlClient, string, error) {
func LoadMysqlClientByFrom(database string) (mysql.MysqlClient, string, error) {
var (
dbInfo client.DBInfo
version string
err error
)
dbInfo.From = from
dbInfo.Timeout = 300
if from != "local" {
databaseItem, err := remoteDBRepo.Get(commonRepo.WithByName(from))
if err != nil {
return nil, "", err
}
databaseItem, err := databaseRepo.Get(commonRepo.WithByName(database))
if err != nil {
return nil, "", err
}
dbInfo.From = databaseItem.From
if dbInfo.From != "local" {
dbInfo.Address = databaseItem.Address
dbInfo.Port = databaseItem.Port
dbInfo.Username = databaseItem.Username
@ -646,7 +634,7 @@ func LoadMysqlClientByFrom(from string) (mysql.MysqlClient, string, error) {
version = databaseItem.Version
} else {
app, err := appInstallRepo.LoadBaseInfo("mysql", "")
app, err := appInstallRepo.LoadBaseInfo(databaseItem.Type, database)
if err != nil {
return nil, "", err
}

View File

@ -13,7 +13,7 @@ var (
appInstallResourceRepo = repo.NewIAppInstallResourceRpo()
mysqlRepo = repo.NewIMysqlRepo()
remoteDBRepo = repo.NewIRemoteDBRepo()
databaseRepo = repo.NewIDatabaseRepo()
imageRepoRepo = repo.NewIImageRepoRepo()
composeRepo = repo.NewIComposeTemplateRepo()

View File

@ -82,33 +82,33 @@ func handleSnapStatus() {
status, _ := snapRepo.GetStatusList()
for _, statu := range status {
updatas := make(map[string]interface{})
updates := make(map[string]interface{})
if statu.Panel == constant.StatusRunning {
updatas["panel"] = constant.StatusFailed
updates["panel"] = constant.StatusFailed
}
if statu.PanelInfo == constant.StatusRunning {
updatas["panel_info"] = constant.StatusFailed
updates["panel_info"] = constant.StatusFailed
}
if statu.DaemonJson == constant.StatusRunning {
updatas["daemon_json"] = constant.StatusFailed
updates["daemon_json"] = constant.StatusFailed
}
if statu.AppData == constant.StatusRunning {
updatas["app_data"] = constant.StatusFailed
updates["app_data"] = constant.StatusFailed
}
if statu.PanelData == constant.StatusRunning {
updatas["panel_data"] = constant.StatusFailed
updates["panel_data"] = constant.StatusFailed
}
if statu.BackupData == constant.StatusRunning {
updatas["backup_data"] = constant.StatusFailed
updates["backup_data"] = constant.StatusFailed
}
if statu.Compress == constant.StatusRunning {
updatas["compress"] = constant.StatusFailed
updates["compress"] = constant.StatusFailed
}
if statu.Upload == constant.StatusUploading {
updatas["upload"] = constant.StatusFailed
updates["upload"] = constant.StatusFailed
}
if len(updatas) != 0 {
_ = snapRepo.UpdateStatus(statu.ID, updatas)
if len(updates) != 0 {
_ = snapRepo.UpdateStatus(statu.ID, updates)
}
}
}

View File

@ -39,6 +39,7 @@ func Init() {
migrations.UpdateRedisParam,
migrations.UpdateCronjobWithDb,
migrations.AddTableFirewall,
migrations.UpdateDatabase,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)

View File

@ -485,7 +485,7 @@ var EncryptHostPassword = &gormigrate.Migration{
var AddRemoteDB = &gormigrate.Migration{
ID: "20230724-add-remote-db",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.RemoteDB{}, &model.DatabaseMysql{}); err != nil {
if err := tx.AutoMigrate(&model.DatabaseMysql{}); err != nil {
return err
}
var (
@ -509,7 +509,7 @@ var AddRemoteDB = &gormigrate.Migration{
if !ok {
return errors.New("error password in app env")
}
if err := tx.Create(&model.RemoteDB{
if err := tx.Create(&model.Database{
Name: "local",
Type: "mysql",
Version: appInstall.Version,
@ -572,11 +572,90 @@ var UpdateCronjobWithDb = &gormigrate.Migration{
}
var AddTableFirewall = &gormigrate.Migration{
ID: "20230823-add-table-firewall",
ID: "20230825-add-table-firewall",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.Firewall{}, model.SnapshotStatus{}, &model.Cronjob{}); err != nil {
return err
}
if err := tx.Exec("alter table remote_dbs rename to databases;").Error; err != nil {
return err
}
return nil
},
}
var UpdateDatabase = &gormigrate.Migration{
ID: "20230828-update-database",
Migrate: func(tx *gorm.DB) error {
var (
app model.App
appInstall model.AppInstall
)
if err := tx.AutoMigrate(&model.Database{}); err != nil {
return err
}
if err := global.DB.Where("key = ?", "mariadb").First(&app).Error; err != nil {
return nil
}
if err := global.DB.Where("app_id = ?", app.ID).First(&appInstall).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil
}
return err
}
envMap := make(map[string]interface{})
if err := json.Unmarshal([]byte(appInstall.Env), &envMap); err != nil {
return err
}
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
if !ok {
return errors.New("error password in app env")
}
if err := tx.Create(&model.Database{
AppInstallID: appInstall.ID,
Name: appInstall.Name,
Type: "mariadb",
Version: appInstall.Version,
From: "local",
Address: appInstall.ServiceName,
Port: uint(appInstall.HttpPort),
Username: "root",
Password: password,
}).Error; err != nil {
return err
}
if err := global.DB.Model(&model.DatabaseMysql{}).Where("`from` != ?", "local").Updates(map[string]interface{}{
"from": "remote",
}).Error; err != nil {
return err
}
var (
appMysql model.App
appInstallMysql model.AppInstall
localDatabase model.Database
)
_ = global.DB.Where("name = ? AND address = ?", "local", "127.0.0.1").First(&localDatabase).Error
if localDatabase.ID == 0 {
return nil
}
if err := global.DB.Where("key = ?", "mysql").First(&appMysql).Error; err != nil {
return nil
}
if err := global.DB.Where("app_id = ?", appMysql.ID).First(&appInstallMysql).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil
}
return err
}
if err := global.DB.Model(&model.Database{}).Where("id = ?", localDatabase.ID).Updates(map[string]interface{}{
"app_install_id": appInstallMysql.ID,
"name": appInstallMysql.Name,
"address": appInstallMysql.ServiceName,
}).Error; err != nil {
return err
}
return nil
},
}

View File

@ -24,9 +24,9 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) {
appRouter.POST("/install", baseApi.InstallApp)
appRouter.GET("/tags", baseApi.GetAppTags)
appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions)
appRouter.GET("/installed/check/:key", baseApi.CheckAppInstalled)
appRouter.GET("/installed/loadport/:key", baseApi.LoadPort)
appRouter.GET("/installed/conninfo/:key", baseApi.LoadConnInfo)
appRouter.POST("/installed/check", baseApi.CheckAppInstalled)
appRouter.POST("/installed/loadport", baseApi.LoadPort)
appRouter.POST("/installed/conninfo", baseApi.LoadConnInfo)
appRouter.GET("/installed/delete/check/:appInstallId", baseApi.DeleteCheck)
appRouter.POST("/installed/search", baseApi.SearchAppInstalled)
appRouter.GET("/installed/list", baseApi.ListAppInstalled)

View File

@ -17,7 +17,7 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
baseApi := v1.ApiGroupApp.BaseApi
{
cmdRouter.POST("", baseApi.CreateMysql)
cmdRouter.GET("load/:from", baseApi.LoadDBFromRemote)
cmdRouter.POST("load", baseApi.LoadDBFromRemote)
cmdRouter.POST("/change/access", baseApi.ChangeMysqlAccess)
cmdRouter.POST("/change/password", baseApi.ChangeMysqlPassword)
cmdRouter.POST("/del/check", baseApi.DeleteCheckMysql)
@ -27,10 +27,10 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
cmdRouter.POST("/conffile/update", baseApi.UpdateMysqlConfByFile)
cmdRouter.POST("/search", baseApi.SearchMysql)
cmdRouter.POST("/load/file", baseApi.LoadDatabaseFile)
cmdRouter.GET("/variables", baseApi.LoadVariables)
cmdRouter.GET("/status", baseApi.LoadStatus)
cmdRouter.GET("/baseinfo", baseApi.LoadBaseinfo)
cmdRouter.GET("/remote", baseApi.LoadRemoteAccess)
cmdRouter.POST("/variables", baseApi.LoadVariables)
cmdRouter.POST("/status", baseApi.LoadStatus)
cmdRouter.POST("/baseinfo", baseApi.LoadBaseinfo)
cmdRouter.POST("/remote", baseApi.LoadRemoteAccess)
cmdRouter.GET("/options", baseApi.ListDBName)
cmdRouter.GET("/redis/persistence/conf", baseApi.LoadPersistenceConf)
@ -43,12 +43,12 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
cmdRouter.POST("/redis/conffile/update", baseApi.UpdateRedisConfByFile)
cmdRouter.POST("/redis/persistence/update", baseApi.UpdateRedisPersistenceConf)
cmdRouter.POST("/remote/check", baseApi.CheckeRemoteDB)
cmdRouter.POST("/remote", baseApi.CreateRemoteDB)
cmdRouter.GET("/remote/:name", baseApi.GetRemoteDB)
cmdRouter.GET("/remote/list/:type", baseApi.ListRemoteDB)
cmdRouter.POST("/remote/update", baseApi.UpdateRemoteDB)
cmdRouter.POST("/remote/search", baseApi.SearchRemoteDB)
cmdRouter.POST("/remote/del", baseApi.DeleteRemoteDB)
cmdRouter.POST("/db/check", baseApi.CheckDatabase)
cmdRouter.POST("/db", baseApi.CreateDatabase)
cmdRouter.GET("/db/:name", baseApi.GetDatabase)
cmdRouter.GET("/db/list/:type", baseApi.ListDatabase)
cmdRouter.POST("/db/update", baseApi.UpdateDatabase)
cmdRouter.POST("/db/search", baseApi.SearchDatabase)
cmdRouter.POST("/db/del", baseApi.DeleteDatabase)
}
}

View File

@ -164,7 +164,7 @@ func (r *Local) ChangePassword(info PasswordChangeInfo) error {
if host == "%" || host == "localhost" {
passwordRootChangeCMD := fmt.Sprintf("set password for 'root'@'%s' = password('%s')", host, info.Password)
if !strings.HasPrefix(info.Version, "5.7") && !strings.HasPrefix(info.Version, "5.6") {
passwordRootChangeCMD = fmt.Sprintf("alter user 'root'@'%s' identified with mysql_native_password BY '%s';", host, info.Password)
passwordRootChangeCMD = fmt.Sprintf("alter user 'root'@'%s' identified by '%s';", host, info.Password)
}
if err := r.ExecSQL(passwordRootChangeCMD, info.Timeout); err != nil {
return err

View File

@ -169,7 +169,7 @@ func (r *Remote) ChangePassword(info PasswordChangeInfo) error {
if host == "%" || host == "localhost" {
passwordRootChangeCMD := fmt.Sprintf("set password for 'root'@'%s' = password('%s')", host, info.Password)
if !strings.HasPrefix(info.Version, "5.7") && !strings.HasPrefix(info.Version, "5.6") {
passwordRootChangeCMD = fmt.Sprintf("alter user 'root'@'%s' identified with mysql_native_password BY '%s';", host, info.Password)
passwordRootChangeCMD = fmt.Sprintf("alter user 'root'@'%s' identified by '%s';", host, info.Password)
}
if err := r.ExecSQL(passwordRootChangeCMD, info.Timeout); err != nil {
return err

View File

@ -279,8 +279,8 @@ const docTemplate = `{
}
}
},
"/apps/installed/check/:key": {
"get": {
"/apps/installed/check": {
"post": {
"security": [
{
"ApiKeyAuth": []
@ -296,11 +296,13 @@ const docTemplate = `{
"summary": "Check app installed",
"parameters": [
{
"type": "string",
"description": "request",
"name": "key",
"in": "path",
"required": true
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.AppInstalledInfo"
}
}
],
"responses": {
@ -364,11 +366,13 @@ const docTemplate = `{
"summary": "Search app password by key",
"parameters": [
{
"type": "string",
"description": "request",
"name": "key",
"in": "path",
"required": true
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
@ -488,8 +492,8 @@ const docTemplate = `{
}
}
},
"/apps/installed/loadport/:key": {
"get": {
"/apps/installed/loadport": {
"post": {
"security": [
{
"ApiKeyAuth": []
@ -505,11 +509,13 @@ const docTemplate = `{
"summary": "Search app port by key",
"parameters": [
{
"type": "string",
"description": "request",
"name": "key",
"in": "path",
"required": true
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
@ -3699,17 +3705,31 @@ const docTemplate = `{
}
},
"/databases/baseinfo": {
"get": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 基础信息",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql base info",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK",
@ -3935,7 +3955,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
"$ref": "#/definitions/dto.MysqlDBDeleteCheck"
}
}
],
@ -4004,18 +4024,32 @@ const docTemplate = `{
}
}
},
"/databases/load/:from": {
"get": {
"/databases/load": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "从服务器获取",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql database from remote",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.MysqlLodaDB"
}
}
],
"responses": {}
}
},
@ -4354,40 +4388,20 @@ const docTemplate = `{
}
},
"/databases/remote": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 远程访问权限",
"tags": [
"Database Mysql"
],
"summary": "Load mysql remote access",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "boolean"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "创建远程数据库",
"description": "获取 mysql 远程访问权限",
"consumes": [
"application/json"
],
"tags": [
"Database"
"Database Mysql"
],
"summary": "Create remote database",
"summary": "Load mysql remote access",
"parameters": [
{
"description": "request",
@ -4395,24 +4409,17 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBCreate"
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK"
"description": "OK",
"schema": {
"type": "boolean"
}
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name",
"type"
],
"formatEN": "create remote database [name][type]",
"formatZH": "创建远程数据库 [name][type]",
"paramKeys": []
}
}
},
@ -4432,7 +4439,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.RemoteDBInfo"
"$ref": "#/definitions/dto.DatabaseInfo"
}
}
}
@ -4460,7 +4467,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBCreate"
"$ref": "#/definitions/dto.DatabaseCreate"
}
}
],
@ -4550,7 +4557,7 @@ const docTemplate = `{
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.RemoteDBOption"
"$ref": "#/definitions/dto.DatabaseOption"
}
}
}
@ -4579,7 +4586,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBSearch"
"$ref": "#/definitions/dto.DatabaseSearch"
}
}
],
@ -4615,7 +4622,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBUpdate"
"$ref": "#/definitions/dto.DatabaseUpdate"
}
}
],
@ -4672,17 +4679,31 @@ const docTemplate = `{
}
},
"/databases/status": {
"get": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 状态信息",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql status info",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK",
@ -4694,17 +4715,31 @@ const docTemplate = `{
}
},
"/databases/variables": {
"get": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 性能参数信息",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql variables info",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK",
@ -8910,6 +8945,39 @@ const docTemplate = `{
}
}
},
"/settings/snapshot/status": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取快照状态",
"consumes": [
"application/json"
],
"tags": [
"System Setting"
],
"summary": "Load Snapshot status",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/settings/ssl/download": {
"post": {
"security": [
@ -11767,15 +11835,32 @@ const docTemplate = `{
"dto.ChangeDBInfo": {
"type": "object",
"required": [
"database",
"from",
"type",
"value"
],
"properties": {
"from": {
"database": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"id": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
},
"value": {
"type": "string"
}
@ -11860,6 +11945,7 @@ const docTemplate = `{
"enum": [
"app",
"mysql",
"mariadb",
"redis",
"website"
]
@ -11900,6 +11986,7 @@ const docTemplate = `{
"enum": [
"app",
"mysql",
"mariadb",
"redis",
"website"
]
@ -12616,6 +12703,171 @@ const docTemplate = `{
}
}
},
"dto.DatabaseCreate": {
"type": "object",
"required": [
"from",
"name",
"password",
"type",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql"
]
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DatabaseInfo": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DatabaseOption": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"database": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"type": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DatabaseSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"type": {
"type": "string"
}
}
},
"dto.DatabaseUpdate": {
"type": "object",
"required": [
"password",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DiskInfo": {
"type": "object",
"properties": {
@ -13205,20 +13457,29 @@ const docTemplate = `{
"dto.MysqlConfUpdateByFile": {
"type": "object",
"required": [
"mysqlName"
"database",
"type"
],
"properties": {
"database": {
"type": "string"
},
"file": {
"type": "string"
},
"mysqlName": {
"type": "string"
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlDBCreate": {
"type": "object",
"required": [
"database",
"format",
"from",
"name",
@ -13227,6 +13488,9 @@ const docTemplate = `{
"username"
],
"properties": {
"database": {
"type": "string"
},
"description": {
"type": "string"
},
@ -13240,7 +13504,11 @@ const docTemplate = `{
]
},
"from": {
"type": "string"
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string"
@ -13259,9 +13527,14 @@ const docTemplate = `{
"dto.MysqlDBDelete": {
"type": "object",
"required": [
"id"
"database",
"id",
"type"
],
"properties": {
"database": {
"type": "string"
},
"deleteBackup": {
"type": "boolean"
},
@ -13270,17 +13543,48 @@ const docTemplate = `{
},
"id": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlDBDeleteCheck": {
"type": "object",
"required": [
"database",
"id",
"type"
],
"properties": {
"database": {
"type": "string"
},
"id": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlDBSearch": {
"type": "object",
"required": [
"database",
"page",
"pageSize"
],
"properties": {
"from": {
"database": {
"type": "string"
},
"info": {
@ -13300,17 +13604,44 @@ const docTemplate = `{
}
}
},
"dto.MysqlLodaDB": {
"type": "object",
"required": [
"database",
"from",
"type"
],
"properties": {
"database": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlOption": {
"type": "object",
"properties": {
"database": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
@ -13484,6 +13815,31 @@ const docTemplate = `{
}
},
"dto.MysqlVariablesUpdate": {
"type": "object",
"required": [
"database",
"type"
],
"properties": {
"database": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
},
"variables": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.MysqlVariablesUpdateHelper"
}
}
}
},
"dto.MysqlVariablesUpdateHelper": {
"type": "object",
"properties": {
"param": {
@ -13907,162 +14263,6 @@ const docTemplate = `{
}
}
},
"dto.RemoteDBCreate": {
"type": "object",
"required": [
"from",
"name",
"password",
"type",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql"
]
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.RemoteDBInfo": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.RemoteDBOption": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"dto.RemoteDBSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"type": {
"type": "string"
}
}
},
"dto.RemoteDBUpdate": {
"type": "object",
"required": [
"password",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.ResourceLimit": {
"type": "object",
"properties": {
@ -14484,6 +14684,9 @@ const docTemplate = `{
"KODO",
"OneDrive"
]
},
"id": {
"type": "integer"
}
}
},
@ -15141,6 +15344,20 @@ const docTemplate = `{
}
}
},
"request.AppInstalledInfo": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"request.AppInstalledOperate": {
"type": "object",
"required": [
@ -16938,6 +17155,12 @@ const docTemplate = `{
"createdAt": {
"type": "string"
},
"httpPort": {
"type": "integer"
},
"httpsPort": {
"type": "integer"
},
"installPath": {
"type": "string"
},

View File

@ -272,8 +272,8 @@
}
}
},
"/apps/installed/check/:key": {
"get": {
"/apps/installed/check": {
"post": {
"security": [
{
"ApiKeyAuth": []
@ -289,11 +289,13 @@
"summary": "Check app installed",
"parameters": [
{
"type": "string",
"description": "request",
"name": "key",
"in": "path",
"required": true
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.AppInstalledInfo"
}
}
],
"responses": {
@ -357,11 +359,13 @@
"summary": "Search app password by key",
"parameters": [
{
"type": "string",
"description": "request",
"name": "key",
"in": "path",
"required": true
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
@ -481,8 +485,8 @@
}
}
},
"/apps/installed/loadport/:key": {
"get": {
"/apps/installed/loadport": {
"post": {
"security": [
{
"ApiKeyAuth": []
@ -498,11 +502,13 @@
"summary": "Search app port by key",
"parameters": [
{
"type": "string",
"description": "request",
"name": "key",
"in": "path",
"required": true
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
@ -3692,17 +3698,31 @@
}
},
"/databases/baseinfo": {
"get": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 基础信息",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql base info",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK",
@ -3928,7 +3948,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
"$ref": "#/definitions/dto.MysqlDBDeleteCheck"
}
}
],
@ -3997,18 +4017,32 @@
}
}
},
"/databases/load/:from": {
"get": {
"/databases/load": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "从服务器获取",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql database from remote",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.MysqlLodaDB"
}
}
],
"responses": {}
}
},
@ -4347,40 +4381,20 @@
}
},
"/databases/remote": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 远程访问权限",
"tags": [
"Database Mysql"
],
"summary": "Load mysql remote access",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "boolean"
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "创建远程数据库",
"description": "获取 mysql 远程访问权限",
"consumes": [
"application/json"
],
"tags": [
"Database"
"Database Mysql"
],
"summary": "Create remote database",
"summary": "Load mysql remote access",
"parameters": [
{
"description": "request",
@ -4388,24 +4402,17 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBCreate"
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK"
"description": "OK",
"schema": {
"type": "boolean"
}
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"name",
"type"
],
"formatEN": "create remote database [name][type]",
"formatZH": "创建远程数据库 [name][type]",
"paramKeys": []
}
}
},
@ -4425,7 +4432,7 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/dto.RemoteDBInfo"
"$ref": "#/definitions/dto.DatabaseInfo"
}
}
}
@ -4453,7 +4460,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBCreate"
"$ref": "#/definitions/dto.DatabaseCreate"
}
}
],
@ -4543,7 +4550,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.RemoteDBOption"
"$ref": "#/definitions/dto.DatabaseOption"
}
}
}
@ -4572,7 +4579,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBSearch"
"$ref": "#/definitions/dto.DatabaseSearch"
}
}
],
@ -4608,7 +4615,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.RemoteDBUpdate"
"$ref": "#/definitions/dto.DatabaseUpdate"
}
}
],
@ -4665,17 +4672,31 @@
}
},
"/databases/status": {
"get": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 状态信息",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql status info",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK",
@ -4687,17 +4708,31 @@
}
},
"/databases/variables": {
"get": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取 mysql 性能参数信息",
"consumes": [
"application/json"
],
"tags": [
"Database Mysql"
],
"summary": "Load mysql variables info",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperationWithNameAndType"
}
}
],
"responses": {
"200": {
"description": "OK",
@ -8903,6 +8938,39 @@
}
}
},
"/settings/snapshot/status": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取快照状态",
"consumes": [
"application/json"
],
"tags": [
"System Setting"
],
"summary": "Load Snapshot status",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.OperateByID"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/settings/ssl/download": {
"post": {
"security": [
@ -11760,15 +11828,32 @@
"dto.ChangeDBInfo": {
"type": "object",
"required": [
"database",
"from",
"type",
"value"
],
"properties": {
"from": {
"database": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"id": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
},
"value": {
"type": "string"
}
@ -11853,6 +11938,7 @@
"enum": [
"app",
"mysql",
"mariadb",
"redis",
"website"
]
@ -11893,6 +11979,7 @@
"enum": [
"app",
"mysql",
"mariadb",
"redis",
"website"
]
@ -12609,6 +12696,171 @@
}
}
},
"dto.DatabaseCreate": {
"type": "object",
"required": [
"from",
"name",
"password",
"type",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql"
]
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DatabaseInfo": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DatabaseOption": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"database": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"type": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DatabaseSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"type": {
"type": "string"
}
}
},
"dto.DatabaseUpdate": {
"type": "object",
"required": [
"password",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.DiskInfo": {
"type": "object",
"properties": {
@ -13198,20 +13450,29 @@
"dto.MysqlConfUpdateByFile": {
"type": "object",
"required": [
"mysqlName"
"database",
"type"
],
"properties": {
"database": {
"type": "string"
},
"file": {
"type": "string"
},
"mysqlName": {
"type": "string"
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlDBCreate": {
"type": "object",
"required": [
"database",
"format",
"from",
"name",
@ -13220,6 +13481,9 @@
"username"
],
"properties": {
"database": {
"type": "string"
},
"description": {
"type": "string"
},
@ -13233,7 +13497,11 @@
]
},
"from": {
"type": "string"
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string"
@ -13252,9 +13520,14 @@
"dto.MysqlDBDelete": {
"type": "object",
"required": [
"id"
"database",
"id",
"type"
],
"properties": {
"database": {
"type": "string"
},
"deleteBackup": {
"type": "boolean"
},
@ -13263,17 +13536,48 @@
},
"id": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlDBDeleteCheck": {
"type": "object",
"required": [
"database",
"id",
"type"
],
"properties": {
"database": {
"type": "string"
},
"id": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlDBSearch": {
"type": "object",
"required": [
"database",
"page",
"pageSize"
],
"properties": {
"from": {
"database": {
"type": "string"
},
"info": {
@ -13293,17 +13597,44 @@
}
}
},
"dto.MysqlLodaDB": {
"type": "object",
"required": [
"database",
"from",
"type"
],
"properties": {
"database": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
}
}
},
"dto.MysqlOption": {
"type": "object",
"properties": {
"database": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
@ -13477,6 +13808,31 @@
}
},
"dto.MysqlVariablesUpdate": {
"type": "object",
"required": [
"database",
"type"
],
"properties": {
"database": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"mysql",
"mariadb"
]
},
"variables": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.MysqlVariablesUpdateHelper"
}
}
}
},
"dto.MysqlVariablesUpdateHelper": {
"type": "object",
"properties": {
"param": {
@ -13900,162 +14256,6 @@
}
}
},
"dto.RemoteDBCreate": {
"type": "object",
"required": [
"from",
"name",
"password",
"type",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string",
"enum": [
"local",
"remote"
]
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"type": {
"type": "string",
"enum": [
"mysql"
]
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.RemoteDBInfo": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"description": {
"type": "string"
},
"from": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string",
"maxLength": 256
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.RemoteDBOption": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"dto.RemoteDBSearch": {
"type": "object",
"required": [
"page",
"pageSize"
],
"properties": {
"info": {
"type": "string"
},
"order": {
"type": "string"
},
"orderBy": {
"type": "string"
},
"page": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"type": {
"type": "string"
}
}
},
"dto.RemoteDBUpdate": {
"type": "object",
"required": [
"password",
"username",
"version"
],
"properties": {
"address": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"username": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"dto.ResourceLimit": {
"type": "object",
"properties": {
@ -14477,6 +14677,9 @@
"KODO",
"OneDrive"
]
},
"id": {
"type": "integer"
}
}
},
@ -15134,6 +15337,20 @@
}
}
},
"request.AppInstalledInfo": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"request.AppInstalledOperate": {
"type": "object",
"required": [
@ -16931,6 +17148,12 @@
"createdAt": {
"type": "string"
},
"httpPort": {
"type": "integer"
},
"httpsPort": {
"type": "integer"
},
"installPath": {
"type": "string"
},

View File

@ -131,13 +131,26 @@ definitions:
type: object
dto.ChangeDBInfo:
properties:
database:
type: string
from:
enum:
- local
- remote
type: string
id:
type: integer
type:
enum:
- mysql
- mariadb
type: string
value:
type: string
required:
- database
- from
- type
- value
type: object
dto.ChangeHostGroup:
@ -191,6 +204,7 @@ definitions:
enum:
- app
- mysql
- mariadb
- redis
- website
type: string
@ -220,6 +234,7 @@ definitions:
enum:
- app
- mysql
- mariadb
- redis
- website
type: string
@ -703,6 +718,118 @@ definitions:
uptime:
type: integer
type: object
dto.DatabaseCreate:
properties:
address:
type: string
description:
type: string
from:
enum:
- local
- remote
type: string
name:
maxLength: 256
type: string
password:
type: string
port:
type: integer
type:
enum:
- mysql
type: string
username:
type: string
version:
type: string
required:
- from
- name
- password
- type
- username
- version
type: object
dto.DatabaseInfo:
properties:
address:
type: string
createdAt:
type: string
description:
type: string
from:
type: string
id:
type: integer
name:
maxLength: 256
type: string
password:
type: string
port:
type: integer
username:
type: string
version:
type: string
type: object
dto.DatabaseOption:
properties:
address:
type: string
database:
type: string
from:
type: string
id:
type: integer
type:
type: string
version:
type: string
type: object
dto.DatabaseSearch:
properties:
info:
type: string
order:
type: string
orderBy:
type: string
page:
type: integer
pageSize:
type: integer
type:
type: string
required:
- page
- pageSize
type: object
dto.DatabaseUpdate:
properties:
address:
type: string
description:
type: string
id:
type: integer
password:
type: string
port:
type: integer
username:
type: string
version:
type: string
required:
- password
- username
- version
type: object
dto.DiskInfo:
properties:
device:
@ -1100,15 +1227,23 @@ definitions:
type: object
dto.MysqlConfUpdateByFile:
properties:
database:
type: string
file:
type: string
mysqlName:
type:
enum:
- mysql
- mariadb
type: string
required:
- mysqlName
- database
- type
type: object
dto.MysqlDBCreate:
properties:
database:
type: string
description:
type: string
format:
@ -1119,6 +1254,9 @@ definitions:
- big5
type: string
from:
enum:
- local
- remote
type: string
name:
type: string
@ -1129,6 +1267,7 @@ definitions:
username:
type: string
required:
- database
- format
- from
- name
@ -1138,18 +1277,43 @@ definitions:
type: object
dto.MysqlDBDelete:
properties:
database:
type: string
deleteBackup:
type: boolean
forceDelete:
type: boolean
id:
type: integer
type:
enum:
- mysql
- mariadb
type: string
required:
- database
- id
- type
type: object
dto.MysqlDBDeleteCheck:
properties:
database:
type: string
id:
type: integer
type:
enum:
- mysql
- mariadb
type: string
required:
- database
- id
- type
type: object
dto.MysqlDBSearch:
properties:
from:
database:
type: string
info:
type: string
@ -1162,17 +1326,37 @@ definitions:
pageSize:
type: integer
required:
- database
- page
- pageSize
type: object
dto.MysqlLodaDB:
properties:
database:
type: string
from:
enum:
- local
- remote
type: string
type:
enum:
- mysql
- mariadb
type: string
required:
- database
- from
- type
type: object
dto.MysqlOption:
properties:
database:
type: string
from:
type: string
id:
type: integer
name:
type: string
type: object
dto.MysqlStatus:
properties:
@ -1287,6 +1471,23 @@ definitions:
type: string
type: object
dto.MysqlVariablesUpdate:
properties:
database:
type: string
type:
enum:
- mysql
- mariadb
type: string
variables:
items:
$ref: '#/definitions/dto.MysqlVariablesUpdateHelper'
type: array
required:
- database
- type
type: object
dto.MysqlVariablesUpdateHelper:
properties:
param:
type: string
@ -1571,112 +1772,6 @@ definitions:
used_memory_rss:
type: string
type: object
dto.RemoteDBCreate:
properties:
address:
type: string
description:
type: string
from:
enum:
- local
- remote
type: string
name:
maxLength: 256
type: string
password:
type: string
port:
type: integer
type:
enum:
- mysql
type: string
username:
type: string
version:
type: string
required:
- from
- name
- password
- type
- username
- version
type: object
dto.RemoteDBInfo:
properties:
address:
type: string
createdAt:
type: string
description:
type: string
from:
type: string
id:
type: integer
name:
maxLength: 256
type: string
password:
type: string
port:
type: integer
username:
type: string
version:
type: string
type: object
dto.RemoteDBOption:
properties:
address:
type: string
id:
type: integer
name:
type: string
type: object
dto.RemoteDBSearch:
properties:
info:
type: string
order:
type: string
orderBy:
type: string
page:
type: integer
pageSize:
type: integer
type:
type: string
required:
- page
- pageSize
type: object
dto.RemoteDBUpdate:
properties:
address:
type: string
description:
type: string
id:
type: integer
password:
type: string
port:
type: integer
username:
type: string
version:
type: string
required:
- password
- username
- version
type: object
dto.ResourceLimit:
properties:
cpu:
@ -1957,6 +2052,8 @@ definitions:
- KODO
- OneDrive
type: string
id:
type: integer
required:
- from
type: object
@ -2391,6 +2488,15 @@ definitions:
- detailID
- operate
type: object
request.AppInstalledInfo:
properties:
key:
type: string
name:
type: string
required:
- key
type: object
request.AppInstalledOperate:
properties:
backup:
@ -3601,6 +3707,10 @@ definitions:
type: string
createdAt:
type: string
httpPort:
type: integer
httpsPort:
type: integer
installPath:
type: string
isExist:
@ -4077,17 +4187,18 @@ paths:
summary: Search app update version by install id
tags:
- App
/apps/installed/check/:key:
get:
/apps/installed/check:
post:
consumes:
- application/json
description: 检查应用安装情况
parameters:
- description: request
in: path
name: key
in: body
name: request
required: true
type: string
schema:
$ref: '#/definitions/request.AppInstalledInfo'
responses:
"200":
description: OK
@ -4126,10 +4237,11 @@ paths:
description: 获取应用连接信息
parameters:
- description: request
in: path
name: key
in: body
name: request
required: true
type: string
schema:
$ref: '#/definitions/dto.OperationWithNameAndType'
responses:
"200":
description: OK
@ -4207,17 +4319,18 @@ paths:
summary: List app installed
tags:
- App
/apps/installed/loadport/:key:
get:
/apps/installed/loadport:
post:
consumes:
- application/json
description: 获取应用端口
parameters:
- description: request
in: path
name: key
in: body
name: request
required: true
type: string
schema:
$ref: '#/definitions/dto.OperationWithNameAndType'
responses:
"200":
description: OK
@ -6250,8 +6363,17 @@ paths:
formatZH: 创建 mysql 数据库 [name]
paramKeys: []
/databases/baseinfo:
get:
post:
consumes:
- application/json
description: 获取 mysql 基础信息
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperationWithNameAndType'
responses:
"200":
description: OK
@ -6398,7 +6520,7 @@ paths:
name: request
required: true
schema:
$ref: '#/definitions/dto.OperateByID'
$ref: '#/definitions/dto.MysqlDBDeleteCheck'
responses:
"200":
description: OK
@ -6445,9 +6567,18 @@ paths:
formatEN: The description of the mysql database [name] is modified => [description]
formatZH: mysql 数据库 [name] 描述信息修改 [description]
paramKeys: []
/databases/load/:from:
get:
/databases/load:
post:
consumes:
- application/json
description: 从服务器获取
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.MysqlLodaDB'
responses: {}
security:
- ApiKeyAuth: []
@ -6664,8 +6795,17 @@ paths:
tags:
- Database Redis
/databases/remote:
get:
post:
consumes:
- application/json
description: 获取 mysql 远程访问权限
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperationWithNameAndType'
responses:
"200":
description: OK
@ -6676,33 +6816,6 @@ paths:
summary: Load mysql remote access
tags:
- Database Mysql
post:
consumes:
- application/json
description: 创建远程数据库
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.RemoteDBCreate'
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Create remote database
tags:
- Database
x-panel-log:
BeforeFuntions: []
bodyKeys:
- name
- type
formatEN: create remote database [name][type]
formatZH: 创建远程数据库 [name][type]
paramKeys: []
/databases/remote/:name:
get:
description: 获取远程数据库
@ -6710,7 +6823,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/dto.RemoteDBInfo'
$ref: '#/definitions/dto.DatabaseInfo'
security:
- ApiKeyAuth: []
summary: Get remote databases
@ -6727,7 +6840,7 @@ paths:
name: request
required: true
schema:
$ref: '#/definitions/dto.RemoteDBCreate'
$ref: '#/definitions/dto.DatabaseCreate'
responses:
"200":
description: OK
@ -6785,7 +6898,7 @@ paths:
description: OK
schema:
items:
$ref: '#/definitions/dto.RemoteDBOption'
$ref: '#/definitions/dto.DatabaseOption'
type: array
security:
- ApiKeyAuth: []
@ -6803,7 +6916,7 @@ paths:
name: request
required: true
schema:
$ref: '#/definitions/dto.RemoteDBSearch'
$ref: '#/definitions/dto.DatabaseSearch'
responses:
"200":
description: OK
@ -6825,7 +6938,7 @@ paths:
name: request
required: true
schema:
$ref: '#/definitions/dto.RemoteDBUpdate'
$ref: '#/definitions/dto.DatabaseUpdate'
responses:
"200":
description: OK
@ -6864,8 +6977,17 @@ paths:
tags:
- Database Mysql
/databases/status:
get:
post:
consumes:
- application/json
description: 获取 mysql 状态信息
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperationWithNameAndType'
responses:
"200":
description: OK
@ -6877,8 +6999,17 @@ paths:
tags:
- Database Mysql
/databases/variables:
get:
post:
consumes:
- application/json
description: 获取 mysql 性能参数信息
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperationWithNameAndType'
responses:
"200":
description: OK
@ -9555,6 +9686,26 @@ paths:
summary: Page system snapshot
tags:
- System Setting
/settings/snapshot/status:
post:
consumes:
- application/json
description: 获取快照状态
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.OperateByID'
responses:
"200":
description: OK
security:
- ApiKeyAuth: []
summary: Load Snapshot status
tags:
- System Setting
/settings/ssl/download:
post:
description: 下载证书

View File

@ -3,7 +3,7 @@ import { ReqPage } from '.';
export namespace Database {
export interface SearchDBWithPage {
info: string;
from: string;
database: string;
page: number;
pageSize: number;
orderBy?: string;
@ -34,19 +34,34 @@ export namespace Database {
containerName: string;
}
export interface MysqlConfUpdateByFile {
mysqlName: string;
type: string;
database: string;
file: string;
}
export interface MysqlDBCreate {
name: string;
from: string;
database: string;
format: string;
username: string;
password: string;
permission: string;
description: string;
}
export interface MysqlLodaDB {
from: string;
type: string;
database: string;
}
export interface MysqlDBDeleteCheck {
id: number;
type: string;
database: string;
}
export interface MysqlDBDelete {
id: number;
type: string;
database: string;
forceDelete: boolean;
deleteBackup: boolean;
}
@ -71,6 +86,11 @@ export namespace Database {
long_query_time: number;
}
export interface VariablesUpdate {
type: string;
database: string;
variables: Array<VariablesUpdateHelper>;
}
export interface VariablesUpdateHelper {
param: string;
value: any;
}
@ -118,6 +138,9 @@ export namespace Database {
}
export interface ChangeInfo {
id: number;
from: string;
type: string;
database: string;
value: string;
}
@ -177,7 +200,7 @@ export namespace Database {
}
// remote
export interface RemoteDBInfo {
export interface DatabaseInfo {
id: number;
createdAt: Date;
name: string;
@ -190,7 +213,7 @@ export namespace Database {
password: string;
description: string;
}
export interface SearchRemoteDBPage {
export interface SearchDatabasePage {
info: string;
type: string;
page: number;
@ -198,12 +221,15 @@ export namespace Database {
orderBy?: string;
order?: string;
}
export interface RemoteDBOption {
export interface DatabaseOption {
id: number;
name: string;
from: string;
type: string;
database: string;
version: string;
address: string;
}
export interface RemoteDBCreate {
export interface DatabaseCreate {
name: string;
version: string;
from: string;
@ -213,7 +239,7 @@ export namespace Database {
password: string;
description: string;
}
export interface RemoteDBUpdate {
export interface DatabaseUpdate {
id: number;
version: string;
address: string;

View File

@ -46,16 +46,16 @@ export const ListAppInstalled = () => {
return http.get<Array<App.AppInstalledInfo>>('apps/installed/list');
};
export const GetAppPort = (key: string) => {
return http.get<number>(`apps/installed/loadport/${key}`);
export const GetAppPort = (type: string, name: string) => {
return http.post<number>(`apps/installed/loadport`, { type: type, name: name });
};
export const GetAppConnInfo = (key: string) => {
return http.get<App.DatabaseConnInfo>(`apps/installed/conninfo/${key}`);
export const GetAppConnInfo = (type: string, name: string) => {
return http.post<App.DatabaseConnInfo>(`apps/installed/conninfo`, { type: type, name: name });
};
export const CheckAppInstalled = (key: string) => {
return http.get<App.CheckInstalled>(`apps/installed/check/${key}`);
export const CheckAppInstalled = (key: string, name: string) => {
return http.post<App.CheckInstalled>(`apps/installed/check`, { key: key, name: name });
};
export const AppInstalledDeleteCheck = (appInstallId: number) => {

View File

@ -7,8 +7,8 @@ import { Database } from '../interface/database';
export const searchMysqlDBs = (params: Database.SearchDBWithPage) => {
return http.post<ResPage<Database.MysqlDBInfo>>(`/databases/search`, params);
};
export const loadDatabaseFile = (type: string, name: string) => {
return http.post<string>(`/databases/load/file`, { type: type, name: name });
export const loadDatabaseFile = (type: string, database: string) => {
return http.post<string>(`/databases/load/file`, { type: type, name: database });
};
export const addMysqlDB = (params: Database.MysqlDBCreate) => {
@ -18,8 +18,8 @@ export const addMysqlDB = (params: Database.MysqlDBCreate) => {
}
return http.post(`/databases`, reqest);
};
export const loadDBFromRemote = (from: string) => {
return http.get(`/databases/load/${from}`);
export const loadDBFromRemote = (params: Database.MysqlLodaDB) => {
return http.post(`/databases/load`, params);
};
export const updateMysqlAccess = (params: Database.ChangeInfo) => {
return http.post(`/databases/change/access`, params);
@ -34,30 +34,30 @@ export const updateMysqlPassword = (params: Database.ChangeInfo) => {
export const updateMysqlDescription = (params: DescriptionUpdate) => {
return http.post(`/databases/description/update`, params);
};
export const updateMysqlVariables = (params: Array<Database.VariablesUpdate>) => {
export const updateMysqlVariables = (params: Database.VariablesUpdate) => {
return http.post(`/databases/variables/update`, params);
};
export const updateMysqlConfByFile = (params: Database.MysqlConfUpdateByFile) => {
return http.post(`/databases/conffile/update`, params);
};
export const deleteCheckMysqlDB = (id: number) => {
return http.post<Array<string>>(`/databases/del/check`, { id: id });
export const deleteCheckMysqlDB = (params: Database.MysqlDBDeleteCheck) => {
return http.post<Array<string>>(`/databases/del/check`, params);
};
export const deleteMysqlDB = (params: Database.MysqlDBDelete) => {
return http.post(`/databases/del`, params);
};
export const loadMysqlBaseInfo = () => {
return http.get<Database.BaseInfo>(`/databases/baseinfo`);
export const loadMysqlBaseInfo = (type: string, database: string) => {
return http.post<Database.BaseInfo>(`/databases/baseinfo`, { type: type, name: database });
};
export const loadMysqlVariables = () => {
return http.get<Database.MysqlVariables>(`/databases/variables`);
export const loadMysqlVariables = (type: string, database: string) => {
return http.post<Database.MysqlVariables>(`/databases/variables`, { type: type, name: database });
};
export const loadMysqlStatus = () => {
return http.get<Database.MysqlStatus>(`/databases/status`);
export const loadMysqlStatus = (type: string, database: string) => {
return http.post<Database.MysqlStatus>(`/databases/status`, { type: type, name: database });
};
export const loadRemoteAccess = () => {
return http.get<boolean>(`/databases/remote`);
export const loadRemoteAccess = (type: string, database: string) => {
return http.post<boolean>(`/databases/remote`, { type: type, name: database });
};
export const loadDBOptions = () => {
return http.get<Array<Database.MysqlOption>>(`/databases/options`);
@ -90,25 +90,25 @@ export const updateRedisConfByFile = (params: Database.RedisConfUpdateByFile) =>
return http.post(`/databases/redis/conffile/update`, params);
};
// remote
export const getRemoteDB = (name: string) => {
return http.get<Database.RemoteDBInfo>(`/databases/remote/${name}`);
// databasae
export const getDatabase = (name: string) => {
return http.get<Database.DatabaseInfo>(`/databases/db/${name}`);
};
export const searchRemoteDBs = (params: Database.SearchRemoteDBPage) => {
return http.post<ResPage<Database.RemoteDBInfo>>(`/databases/remote/search`, params);
export const searchDatabases = (params: Database.SearchDatabasePage) => {
return http.post<ResPage<Database.DatabaseInfo>>(`/databases/db/search`, params);
};
export const listRemoteDBs = (type: string) => {
return http.get<Array<Database.RemoteDBOption>>(`/databases/remote/list/${type}`);
export const listDatabases = (type: string) => {
return http.get<Array<Database.DatabaseOption>>(`/databases/db/list/${type}`);
};
export const checkRemoteDB = (params: Database.RemoteDBCreate) => {
return http.post<boolean>(`/databases/remote/check`, params, 40000);
export const checkDatabase = (params: Database.DatabaseCreate) => {
return http.post<boolean>(`/databases/db/check`, params, 40000);
};
export const addRemoteDB = (params: Database.RemoteDBCreate) => {
return http.post(`/databases/remote`, params, 40000);
export const addDatabase = (params: Database.DatabaseCreate) => {
return http.post(`/databases/db`, params, 40000);
};
export const editRemoteDB = (params: Database.RemoteDBUpdate) => {
return http.post(`/databases/remote/update`, params, 40000);
export const editDatabase = (params: Database.DatabaseUpdate) => {
return http.post(`/databases/db/update`, params, 40000);
};
export const deleteRemoteDB = (id: number) => {
return http.post(`/databases/remote/del`, { id: id });
export const deleteDatabase = (id: number) => {
return http.post(`/databases/db/del`, { id: id });
};

View File

@ -73,7 +73,7 @@
<script lang="ts" setup>
import { CheckAppInstalled, InstalledOp } from '@/api/modules/app';
import router from '@/routers';
import { onMounted, reactive, ref } from 'vue';
import { onMounted, reactive, ref, watch } from 'vue';
import Status from '@/components/status/index.vue';
import { ElMessageBox } from 'element-plus';
import i18n from '@/lang';
@ -84,9 +84,30 @@ const props = defineProps({
type: String,
default: 'openresty',
},
appName: {
type: String,
default: '',
},
});
watch(
() => props.appKey,
(val) => {
key.value = val;
onCheck();
},
);
watch(
() => props.appName,
(val) => {
name.value = val;
onCheck();
},
);
let key = ref('');
let name = ref('');
let data = ref({
app: '',
version: '',
@ -113,8 +134,11 @@ const goRouter = async (key: string) => {
};
const onCheck = async () => {
await CheckAppInstalled(key.value)
await CheckAppInstalled(key.value, name.value)
.then((res) => {
if (res.data.appInstallId === 0) {
return;
}
data.value = res.data;
em('isExist', res.data);
operateReq.installId = res.data.appInstallId;
@ -171,6 +195,7 @@ const getTitle = (key: string) => {
onMounted(() => {
key.value = props.appKey;
name.value = props.appName;
onCheck();
});
</script>

View File

@ -126,10 +126,11 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
if (type.value === 'website' || type.value === 'app') {
title.value = name.value;
}
let dir = type.value === 'mysql' || type.value === 'mariadb' ? 'database/' + type.value : type.value;
if (detailName.value) {
baseDir.value = `${pathRes.data}/uploads/${type.value}/${name.value}/${detailName.value}/`;
baseDir.value = `${pathRes.data}/uploads/${dir}/${name.value}/${detailName.value}/`;
} else {
baseDir.value = `${pathRes.data}/uploads/${type.value}/${name.value}/`;
baseDir.value = `${pathRes.data}/uploads/${dir}/${name.value}/`;
}
upVisiable.value = true;
search();

View File

@ -346,6 +346,7 @@ const message = {
loadFromRemoteHelper:
'This action will synchronize the database info on the server to 1Panel, do you want to continue?',
passwordHelper: 'Unable to retrieve, please modify',
local: 'Local',
remote: 'Remote',
remoteDB: 'Remote DB',
createRemoteDB: 'Create Remote Server',

View File

@ -340,6 +340,7 @@ const message = {
loadFromRemote: '從服務器獲取',
loadFromRemoteHelper: '此操作將同步服務器上數據庫信息到 1Panel是否繼續',
passwordHelper: '無法獲取密碼請修改',
local: '本地',
remote: '遠程',
remoteDB: '遠程服務器',
createRemoteDB: '添加遠程服務器',

View File

@ -340,6 +340,7 @@ const message = {
loadFromRemote: '从服务器获取',
loadFromRemoteHelper: '此操作将同步服务器上数据库信息到 1Panel是否继续',
passwordHelper: '无法获取密码请修改',
local: '本地',
remote: '远程',
remoteDB: '远程服务器',
createRemoteDB: '添加远程服务器',

View File

@ -28,9 +28,10 @@ const databaseRouter = {
},
},
{
path: 'mysql/setting',
path: 'mysql/setting/:type/:database',
name: 'MySQL-Setting',
component: () => import('@/views/database/mysql/setting/index.vue'),
props: true,
hidden: true,
meta: {
activeMenu: '/databases',

View File

@ -97,7 +97,7 @@ import { reactive, ref } from 'vue';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { getRemoteDB, loadRemoteAccess, updateMysqlAccess, updateMysqlPassword } from '@/api/modules/database';
import { getDatabase, loadRemoteAccess, updateMysqlAccess, updateMysqlPassword } from '@/api/modules/database';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { GetAppConnInfo } from '@/api/modules/app';
import DrawerHeader from '@/components/drawer-header/index.vue';
@ -118,6 +118,8 @@ const form = reactive({
port: 0,
from: '',
type: '',
database: '',
username: '',
remoteIP: '',
});
@ -130,15 +132,16 @@ const formRef = ref<FormInstance>();
interface DialogProps {
from: string;
remoteIP: string;
type: string;
database: string;
}
const acceptParams = (param: DialogProps): void => {
form.password = '';
form.from = param.from;
if (form.from === 'local') {
loadAccess();
}
form.type = param.type;
form.database = param.database;
loadAccess();
loadPassword();
dialogVisiable.value = true;
};
@ -167,8 +170,10 @@ const handleClose = () => {
};
const loadAccess = async () => {
const res = await loadRemoteAccess();
form.privilege = res.data;
if (form.from === 'local') {
const res = await loadRemoteAccess(form.type, form.database);
form.privilege = res.data;
}
};
const loadSystemIP = async () => {
@ -178,14 +183,14 @@ const loadSystemIP = async () => {
const loadPassword = async () => {
if (form.from === 'local') {
const res = await GetAppConnInfo('mysql');
const res = await GetAppConnInfo(form.type, form.database);
form.password = res.data.password || '';
form.port = res.data.port || 3306;
form.serviceName = res.data.serviceName || '';
loadSystemIP();
return;
}
const res = await getRemoteDB(form.from);
const res = await getDatabase(form.database);
form.password = res.data.password || '';
form.port = res.data.port || 3306;
form.username = res.data.username;
@ -197,6 +202,8 @@ const onSubmit = async () => {
let param = {
id: 0,
from: form.from,
type: form.type,
database: form.database,
value: form.password,
};
loading.value = true;
@ -228,6 +235,8 @@ const onSubmitAccess = async () => {
let param = {
id: 0,
from: form.from,
type: form.type,
database: form.database,
value: form.privilege ? '%' : 'localhost',
};
loading.value = true;

View File

@ -91,7 +91,7 @@ const createVisiable = ref(false);
const form = reactive({
name: '',
from: 'local',
mysqlName: '',
database: '',
format: '',
username: '',
password: '',
@ -111,12 +111,12 @@ const formRef = ref<FormInstance>();
interface DialogProps {
from: string;
mysqlName: string;
database: string;
}
const acceptParams = (params: DialogProps): void => {
form.name = '';
form.from = params.from;
form.mysqlName = params.mysqlName;
form.database = params.database;
form.format = 'utf8mb4';
form.username = '';
form.permission = '%';

View File

@ -48,6 +48,8 @@ import { MsgSuccess } from '@/utils/message';
let deleteReq = ref({
id: 0,
type: '',
database: '',
deleteBackup: false,
forceDelete: false,
});
@ -60,13 +62,17 @@ const deleteForm = ref<FormInstance>();
interface DialogProps {
id: number;
type: string;
name: string;
database: string;
}
const emit = defineEmits<{ (e: 'search'): void }>();
const acceptParams = async (prop: DialogProps) => {
deleteReq.value = {
id: prop.id,
type: prop.type,
database: prop.database,
deleteBackup: false,
forceDelete: false,
};

View File

@ -1,9 +1,21 @@
<template>
<div v-loading="loading">
<div class="app-status" style="margin-top: 20px" v-if="!isLocal()">
<el-card>
<div>
<el-tag style="float: left" effect="dark" type="success">
{{ currentDB?.type === 'mysql' ? 'Mysql' : 'MariaDB' }}
</el-tag>
<el-tag class="status-content">{{ $t('app.version') }}: {{ currentDB?.version }}</el-tag>
</div>
</el-card>
</div>
<LayoutContent :title="'MySQL ' + $t('menu.database')">
<template #app v-if="mysqlIsExist">
<template #app v-if="mysqlIsExist && isLocal()">
<AppStatus
:app-key="'mysql'"
:app-key="appKey"
:app-name="appName"
v-model:loading="loading"
v-model:mask-show="maskShow"
@setting="onSetting"
@ -12,18 +24,25 @@
</template>
<template #search>
<el-select v-model="paginationConfig.from" @change="search()">
<el-select v-model="currentDBName" @change="changeDatabase()">
<template #prefix>{{ $t('commons.table.type') }}</template>
<el-option-group>
<el-option :label="$t('database.localDB')" value="local" />
<el-option-group :label="$t('database.local')" v-if="dbOptionsLocal.length !== 0">
<div v-for="(item, index) in dbOptionsLocal" :key="index">
<el-option
v-if="item.from === 'local'"
:value="item.database"
:label="item.database"
></el-option>
</div>
</el-option-group>
<el-option-group :label="$t('database.remote')" v-if="dbOptions.length !== 0">
<el-option
v-for="(item, index) in dbOptions"
:key="index"
:value="item.name"
:label="item.name"
></el-option>
<el-option-group :label="$t('database.remote')" v-if="dbOptionsRemote.length !== 0">
<div v-for="(item, index) in dbOptionsRemote" :key="index">
<el-option
v-if="item.from === 'remote'"
:value="item.database"
:label="item.database"
></el-option>
</div>
</el-option-group>
</el-select>
</template>
@ -213,7 +232,7 @@ import { ElMessageBox } from 'element-plus';
import { onMounted, reactive, ref } from 'vue';
import {
deleteCheckMysqlDB,
listRemoteDBs,
listDatabases,
loadDBFromRemote,
searchMysqlDBs,
updateMysqlDescription,
@ -230,9 +249,13 @@ const { toClipboard } = useClipboard();
const loading = ref(false);
const maskShow = ref(true);
const dbOptions = ref<Array<Database.RemoteDBOption>>([]);
const appKey = ref('mysql');
const appName = ref();
const mysqlName = ref();
const dbOptionsLocal = ref<Array<Database.DatabaseOption>>([]);
const dbOptionsRemote = ref<Array<Database.DatabaseOption>>([]);
const currentDB = ref<Database.DatabaseOption>();
const currentDBName = ref();
const checkRef = ref();
const deleteRef = ref();
@ -247,7 +270,6 @@ const paginationConfig = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
from: 'local',
orderBy: 'created_at',
order: 'null',
});
@ -261,8 +283,8 @@ const mysqlVersion = ref();
const dialogRef = ref();
const onOpenDialog = async () => {
let params = {
from: paginationConfig.from,
mysqlName: mysqlName.value,
from: currentDB.value.from,
database: currentDBName.value,
};
dialogRef.value!.acceptParams(params);
};
@ -273,7 +295,11 @@ const uploadRef = ref();
const connRef = ref();
const onChangeConn = async () => {
connRef.value!.acceptParams({ from: paginationConfig.from });
connRef.value!.acceptParams({
from: currentDB.value.from,
type: currentDB.value.type,
database: currentDBName.value,
});
};
const goRemoteDB = async () => {
@ -281,13 +307,35 @@ const goRemoteDB = async () => {
};
function isLocal() {
return paginationConfig.from === 'local';
if (!currentDB.value) {
return false;
}
return currentDB.value.from === 'local';
}
const passwordRef = ref();
const onSetting = async () => {
router.push({ name: 'MySQL-Setting' });
router.push({ name: 'MySQL-Setting', params: { type: currentDB.value.type, database: currentDB.value.database } });
};
const changeDatabase = async () => {
for (const item of dbOptionsLocal.value) {
if (item.database == currentDBName.value) {
currentDB.value = item;
appKey.value = item.type;
appName.value = item.database;
search();
return;
}
}
for (const item of dbOptionsRemote.value) {
if (item.database == currentDBName.value) {
currentDB.value = item;
break;
}
}
search();
};
const search = async (column?: any) => {
@ -297,7 +345,7 @@ const search = async (column?: any) => {
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
info: searchName.value,
from: paginationConfig.from,
database: currentDB.value.database,
orderBy: paginationConfig.orderBy,
order: paginationConfig.order,
};
@ -313,7 +361,12 @@ const loadDB = async () => {
type: 'info',
}).then(async () => {
loading.value = true;
await loadDBFromRemote(paginationConfig.from)
let params = {
from: currentDB.value.from,
type: currentDB.value.type,
database: currentDBName.value,
};
await loadDBFromRemote(params)
.then(() => {
loading.value = false;
search();
@ -348,13 +401,12 @@ const getAppDetail = (key: string) => {
};
const loadDashboardPort = async () => {
const res = await GetAppPort('phpmyadmin');
const res = await GetAppPort('phpmyadmin', '');
phpadminPort.value = res.data;
};
const checkExist = (data: App.CheckInstalled) => {
mysqlIsExist.value = data.isExist;
mysqlName.value = data.name;
mysqlStatus.value = data.status;
mysqlVersion.value = data.version;
mysqlContainer.value = data.containerName;
@ -365,13 +417,23 @@ const checkExist = (data: App.CheckInstalled) => {
};
const loadDBOptions = async () => {
const res = await listRemoteDBs('mysql');
dbOptions.value = res.data || [];
for (let i = 0; i < dbOptions.value.length; i++) {
if (dbOptions.value[i].name === 'local') {
dbOptions.value.splice(i, 1);
const res = await listDatabases('mysql');
let datas = res.data || [];
dbOptionsLocal.value = [];
dbOptionsRemote.value = [];
for (const item of datas) {
if (item.from === 'local') {
dbOptionsLocal.value.push(item);
} else {
dbOptionsRemote.value.push(item);
}
}
if (dbOptionsLocal.value.length !== 0) {
currentDB.value = dbOptionsLocal.value[0];
currentDBName.value = dbOptionsLocal.value[0].database;
appKey.value = dbOptionsLocal.value[0].type;
appName.value = dbOptionsLocal.value[0].database;
}
};
const onCopy = async (row: any) => {
@ -384,11 +446,21 @@ const onCopy = async (row: any) => {
};
const onDelete = async (row: Database.MysqlDBInfo) => {
const res = await deleteCheckMysqlDB(row.id);
let param = {
id: row.id,
type: currentDB.value.type,
database: currentDBName.value,
};
const res = await deleteCheckMysqlDB(param);
if (res.data && res.data.length > 0) {
checkRef.value.acceptParams({ items: res.data });
} else {
deleteRef.value.acceptParams({ id: row.id, name: row.name });
deleteRef.value.acceptParams({
id: row.id,
type: currentDB.value.type,
database: currentDBName.value,
name: row.name,
});
}
};
@ -396,6 +468,8 @@ const onChangePassword = async (row: Database.MysqlDBInfo) => {
let param = {
id: row.id,
from: row.from,
type: currentDB.value.type,
database: currentDBName.value,
mysqlName: row.name,
operation: 'password',
username: row.username,
@ -420,6 +494,8 @@ const buttons = [
let param = {
id: row.id,
from: row.from,
type: currentDB.value.type,
database: currentDBName.value,
mysqlName: row.name,
operation: 'privilege',
privilege: '',
@ -439,8 +515,8 @@ const buttons = [
label: i18n.global.t('database.backupList'),
click: (row: Database.MysqlDBInfo) => {
let params = {
type: 'mysql',
name: row.mysqlName,
type: currentDB.value.type,
name: currentDBName.value,
detailName: row.name,
};
dialogBackupRef.value!.acceptParams(params);
@ -450,8 +526,8 @@ const buttons = [
label: i18n.global.t('database.loadBackup'),
click: (row: Database.MysqlDBInfo) => {
let params = {
type: 'mysql',
name: row.mysqlName,
type: currentDB.value.type,
name: currentDBName.value,
detailName: row.name,
};
uploadRef.value!.acceptParams(params);

View File

@ -78,6 +78,8 @@ const title = ref();
const changeForm = reactive({
id: 0,
from: '',
type: '',
database: '',
mysqlName: '',
userName: '',
password: '',
@ -106,6 +108,8 @@ function checkIPs(rule: any, value: any, callback: any) {
interface DialogProps {
id: number;
from: string;
type: string;
database: string;
mysqlName: string;
username: string;
password: string;
@ -121,6 +125,8 @@ const acceptParams = (params: DialogProps): void => {
: i18n.global.t('database.permission');
changeForm.id = params.id;
changeForm.from = params.from;
changeForm.type = params.type;
changeForm.database = params.database;
changeForm.mysqlName = params.mysqlName;
changeForm.userName = params.username;
changeForm.password = params.password;
@ -143,10 +149,12 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
let param = {
id: changeForm.id,
from: changeForm.from,
type: changeForm.type,
database: changeForm.database,
value: '',
};
if (changeForm.operation === 'password') {
const res = await deleteCheckMysqlDB(changeForm.id);
const res = await deleteCheckMysqlDB(param);
if (res.data && res.data.length > 0) {
let params = {
header: i18n.global.t('database.changePassword'),
@ -193,6 +201,8 @@ const onSubmit = async () => {
let param = {
id: changeForm.id,
from: changeForm.from,
type: changeForm.type,
database: changeForm.database,
value: changeForm.password,
};
loading.value = true;

View File

@ -91,7 +91,7 @@
<script lang="ts" setup>
import { dateFormat } from '@/utils/util';
import { onMounted, reactive, ref } from 'vue';
import { deleteRemoteDB, searchRemoteDBs } from '@/api/modules/database';
import { deleteDatabase, searchDatabases } from '@/api/modules/database';
import OperateDialog from '@/views/database/mysql/remote/operate/index.vue';
import i18n from '@/lang';
import { MsgError, MsgSuccess } from '@/utils/message';
@ -125,14 +125,14 @@ const search = async (column?: any) => {
orderBy: paginationConfig.orderBy,
order: paginationConfig.order,
};
const res = await searchRemoteDBs(params);
const res = await searchDatabases(params);
data.value = res.data.items || [];
paginationConfig.total = res.data.total;
};
const onOpenDialog = async (
title: string,
rowData: Partial<Database.RemoteDBInfo> = {
rowData: Partial<Database.DatabaseInfo> = {
name: '',
type: 'mysql',
version: '5.6',
@ -159,21 +159,21 @@ const onCopy = async (row: any) => {
}
};
const onDelete = async (row: Database.RemoteDBInfo) => {
await useDeleteData(deleteRemoteDB, row.id, 'commons.msg.delete');
const onDelete = async (row: Database.DatabaseInfo) => {
await useDeleteData(deleteDatabase, row.id, 'commons.msg.delete');
search();
};
const buttons = [
{
label: i18n.global.t('commons.button.edit'),
click: (row: Database.RemoteDBInfo) => {
click: (row: Database.DatabaseInfo) => {
onOpenDialog('edit', row);
},
},
{
label: i18n.global.t('commons.button.delete'),
click: (row: Database.RemoteDBInfo) => {
click: (row: Database.DatabaseInfo) => {
onDelete(row);
},
},

View File

@ -74,11 +74,11 @@ import { Database } from '@/api/interface/database';
import DrawerHeader from '@/components/drawer-header/index.vue';
import { MsgError, MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules';
import { addRemoteDB, checkRemoteDB, editRemoteDB } from '@/api/modules/database';
import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database';
interface DialogProps {
title: string;
rowData?: Database.RemoteDBInfo;
rowData?: Database.DatabaseInfo;
getTableList?: () => Promise<any>;
}
const title = ref<string>('');
@ -131,7 +131,7 @@ const onSubmit = async (formEl: FormInstance | undefined, operation: string) =>
loading.value = true;
if (operation === 'check') {
await checkRemoteDB(param)
await checkDatabase(param)
.then((res) => {
loading.value = false;
if (res.data) {
@ -148,7 +148,7 @@ const onSubmit = async (formEl: FormInstance | undefined, operation: string) =>
}
if (operation === 'create') {
await addRemoteDB(param)
await addDatabase(param)
.then(() => {
loading.value = false;
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
@ -160,7 +160,7 @@ const onSubmit = async (formEl: FormInstance | undefined, operation: string) =>
});
}
if (operation === 'edit') {
await editRemoteDB(param)
await editDatabase(param)
.then(() => {
loading.value = false;
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));

View File

@ -155,6 +155,15 @@ const mysqlStatus = ref();
const mysqlVersion = ref();
const variables = ref();
interface DBProps {
type: string;
database: string;
}
const props = withDefaults(defineProps<DBProps>(), {
type: '',
database: '',
});
const dialogContainerLogRef = ref();
const jumpToConf = async () => {
activeName.value = 'conf';
@ -215,7 +224,8 @@ const getDefaultConfig = async () => {
const onSubmitChangeConf = async () => {
let param = {
mysqlName: mysqlName.value,
type: props.type,
database: props.database,
file: mysqlConf.value,
};
loading.value = true;
@ -245,7 +255,7 @@ const loadContainerLog = async (containerID: string) => {
};
const loadBaseInfo = async () => {
const res = await loadMysqlBaseInfo();
const res = await loadMysqlBaseInfo(props.type, props.database);
mysqlName.value = res.data?.name;
baseInfo.port = res.data?.port;
baseInfo.containerID = res.data?.containerName;
@ -258,21 +268,23 @@ const changeLoading = (status: boolean) => {
};
const loadVariables = async () => {
const res = await loadMysqlVariables();
const res = await loadMysqlVariables(props.type, props.database);
variables.value = res.data;
variablesRef.value!.acceptParams({
mysqlName: mysqlName.value,
type: props.type,
database: props.database,
mysqlVersion: mysqlVersion.value,
variables: res.data,
});
};
const loadSlowLogs = async () => {
const res = await loadMysqlVariables();
const res = await loadMysqlVariables(props.type, props.database);
variables.value = res.data;
let param = {
mysqlName: mysqlName.value,
type: props.type,
database: props.database,
variables: variables.value,
};
slowLogRef.value!.acceptParams(param);
@ -280,13 +292,13 @@ const loadSlowLogs = async () => {
const loadMysqlConf = async () => {
useOld.value = false;
const res = await loadDatabaseFile('mysql-conf', mysqlName.value);
const res = await loadDatabaseFile(props.type + '-conf', props.database);
loading.value = false;
mysqlConf.value = res.data;
};
const onLoadInfo = async () => {
await CheckAppInstalled('mysql').then((res) => {
await CheckAppInstalled(props.type, props.database).then((res) => {
mysqlName.value = res.data.name;
mysqlStatus.value = res.data.status;
mysqlVersion.value = res.data.version;
@ -294,7 +306,7 @@ const onLoadInfo = async () => {
if (mysqlStatus.value === 'Running') {
loadVariables();
loadSlowLogs();
statusRef.value!.acceptParams({ mysqlName: mysqlName.value });
statusRef.value!.acceptParams({ type: props.type, database: props.database });
}
});
};

View File

@ -71,18 +71,23 @@ const confirmDialogRef = ref();
const isWatch = ref();
let timer: NodeJS.Timer | null = null;
const mysqlName = ref();
const variables = reactive({
slow_query_log: 'OFF',
long_query_time: 10,
});
const currentDB = reactive({
type: '',
database: '',
});
interface DialogProps {
mysqlName: string;
type: string;
database: string;
variables: Database.MysqlVariables;
}
const acceptParams = async (params: DialogProps): Promise<void> => {
mysqlName.value = params.mysqlName;
currentDB.type = params.type;
currentDB.database = params.database;
variables.slow_query_log = params.variables.slow_query_log;
variables.long_query_time = Number(params.variables.long_query_time);
@ -137,14 +142,19 @@ const onCancel = async () => {
};
const onSave = async () => {
let param = [] as Array<Database.VariablesUpdate>;
let param = [] as Array<Database.VariablesUpdateHelper>;
param.push({ param: 'slow_query_log', value: variables.slow_query_log });
if (variables.slow_query_log === 'ON') {
param.push({ param: 'long_query_time', value: variables.long_query_time + '' });
param.push({ param: 'slow_query_log_file', value: '/var/lib/mysql/1Panel-slow.log' });
}
let params = {
type: currentDB.type,
database: currentDB.database,
variables: param,
};
emit('loading', true);
await updateMysqlVariables(param)
await updateMysqlVariables(params)
.then(() => {
emit('loading', false);
currentStatus.value = variables.slow_query_log === 'ON';
@ -161,11 +171,11 @@ const onDownload = async () => {
MsgInfo(i18n.global.t('database.noData'));
return;
}
downloadWithContent(slowLogs.value, mysqlName.value + '-slowlogs-' + dateFormatForName(new Date()) + '.log');
downloadWithContent(slowLogs.value, currentDB.database + '-slowlogs-' + dateFormatForName(new Date()) + '.log');
};
const loadMysqlSlowlogs = async () => {
const res = await loadDatabaseFile('slow-logs', mysqlName.value);
const res = await loadDatabaseFile(currentDB.type + '-slow-logs', currentDB.database);
slowLogs.value = res.data || '';
nextTick(() => {
const state = view.value.state;

View File

@ -208,12 +208,24 @@ let mysqlStatus = reactive({
tableLocksWaited: 0,
});
const acceptParams = (): void => {
const currentDB = reactive({
type: '',
database: '',
});
interface DialogProps {
type: string;
database: string;
}
const acceptParams = (params: DialogProps): void => {
currentDB.type = params.type;
currentDB.database = params.database;
loadStatus();
};
const loadStatus = async () => {
const res = await loadMysqlStatus();
const res = await loadMysqlStatus(currentDB.type, currentDB.database);
let queryPerSecond = res.data.Questions / res.data.Uptime;
let txPerSecond = (res.data!.Com_commit + res.data.Com_rollback) / res.data.Uptime;

View File

@ -126,7 +126,6 @@ import { MsgSuccess } from '@/utils/message';
const plan = ref();
const confirmDialogRef = ref();
const mysqlVersion = ref();
const variableFormRef = ref<FormInstance>();
const oldVariables = ref<Database.MysqlVariables>();
@ -170,15 +169,21 @@ const variablesRules = reactive({
long_query_time: [Rules.number, checkNumberRange(1, 102400)],
});
const mysqlName = ref();
const currentDB = reactive({
type: '',
database: '',
version: '',
});
interface DialogProps {
mysqlName: string;
mysqlVersion: string;
type: string;
database: string;
version: string;
variables: Database.MysqlVariables;
}
const acceptParams = (params: DialogProps): void => {
mysqlName.value = params.mysqlName;
mysqlVersion.value = params.mysqlVersion;
currentDB.type = params.type;
currentDB.database = params.database;
currentDB.version = params.version;
mysqlVariables.key_buffer_size = Number(params.variables.key_buffer_size) / 1024 / 1024;
mysqlVariables.query_cache_size = Number(params.variables.query_cache_size) / 1024 / 1024;
mysqlVariables.tmp_table_size = Number(params.variables.tmp_table_size) / 1024 / 1024;
@ -234,7 +239,7 @@ const onSaveStart = async (formEl: FormInstance | undefined) => {
};
const onSaveVariables = async () => {
let param = [] as Array<Database.VariablesUpdate>;
let param = [] as Array<Database.VariablesUpdateHelper>;
if (oldVariables.value?.key_buffer_size !== mysqlVariables.key_buffer_size) {
param.push({ param: 'key_buffer_size', value: mysqlVariables.key_buffer_size * 1024 * 1024 });
}
@ -282,7 +287,12 @@ const onSaveVariables = async () => {
param.push({ param: 'max_connections', value: mysqlVariables.max_connections });
}
emit('loading', true);
await updateMysqlVariables(param)
let params = {
type: currentDB.type,
database: currentDB.database,
variables: param,
};
await updateMysqlVariables(params)
.then(() => {
emit('loading', false);
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
@ -293,7 +303,7 @@ const onSaveVariables = async () => {
};
const showCacheSize = () => {
return mysqlVersion.value.startsWith('5.7');
return currentDB.version.startsWith('5.7');
};
defineExpose({
acceptParams,

View File

@ -106,7 +106,7 @@ const getAppDetail = (key: string) => {
};
const loadDashboardPort = async () => {
const res = await GetAppPort('redis-commander');
const res = await GetAppPort('redis-commander', '');
redisCommandPort.value = res.data;
};

View File

@ -109,13 +109,16 @@ const onCopy = async (value: string) => {
};
const loadPassword = async () => {
const res = await GetAppConnInfo('redis');
const res = await GetAppConnInfo('redis', '');
form.value = res.data;
};
const onSubmit = async () => {
let param = {
id: 0,
from: 'local',
type: 'redis',
database: '',
value: form.value.password,
};
loading.value = true;

View File

@ -433,7 +433,7 @@ const changeType = (type: string) => {
const checkNginxVersion = async () => {
try {
const res = await CheckAppInstalled('openresty');
const res = await CheckAppInstalled('openresty', '');
if (res.data && res.data.version) {
if (!compareVersions(res.data.version, '1.21.4')) {
versionExist.value = false;