From 39818b84248f277a813b194d5c60956470055e25 Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:40:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20PostgreSQL=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=8E=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=8E=B7=E5=8F=96=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=20(#3526)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/database.go | 28 -- backend/app/api/v1/database_common.go | 75 ++++ backend/app/api/v1/database_mysql.go | 46 --- backend/app/api/v1/database_postgresql.go | 79 ++-- backend/app/api/v1/database_redis.go | 46 --- backend/app/api/v1/entry.go | 1 + backend/app/dto/database.go | 39 +- backend/app/dto/database_postgresql.go | 7 + backend/app/service/database_common.go | 94 +++++ backend/app/service/database_mysql.go | 62 ---- backend/app/service/database_postgresql.go | 95 ++--- backend/init/migration/migrations/v_1_9.go | 8 +- backend/router/ro_database.go | 14 +- backend/utils/postgresql/client.go | 1 + cmd/server/docs/docs.go | 339 +++++++----------- cmd/server/docs/swagger.json | 339 +++++++----------- cmd/server/docs/swagger.yaml | 232 +++++------- frontend/src/api/interface/database.ts | 9 +- frontend/src/api/modules/database.ts | 40 ++- frontend/src/lang/modules/en.ts | 1 + frontend/src/lang/modules/tw.ts | 1 + frontend/src/lang/modules/zh.ts | 1 + .../src/views/database/mysql/bind/index.vue | 4 +- frontend/src/views/database/mysql/index.vue | 1 + .../views/database/mysql/setting/index.vue | 8 +- .../database/mysql/setting/slow-log/index.vue | 4 +- .../views/database/postgresql/bind/index.vue | 103 ++++++ .../src/views/database/postgresql/index.vue | 41 ++- .../database/postgresql/setting/index.vue | 8 +- .../views/database/redis/setting/index.vue | 9 +- go.mod | 4 +- 31 files changed, 804 insertions(+), 935 deletions(-) create mode 100644 backend/app/api/v1/database_common.go create mode 100644 backend/app/service/database_common.go create mode 100644 frontend/src/views/database/postgresql/bind/index.vue diff --git a/backend/app/api/v1/database.go b/backend/app/api/v1/database.go index 3fc426a3a..5a198f7c1 100644 --- a/backend/app/api/v1/database.go +++ b/backend/app/api/v1/database.go @@ -227,31 +227,3 @@ func (b *BaseApi) UpdateDatabase(c *gin.Context) { } helper.SuccessWithData(c, nil) } - -// @Tags Database -// @Summary Load Database file -// @Description 获取数据库文件 -// @Accept json -// @Param request body dto.OperationWithNameAndType true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /databases/load/file [post] -func (b *BaseApi) LoadDatabaseFile(c *gin.Context) { - var req dto.OperationWithNameAndType - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - var content string - var err error - switch req.Name { - case constant.AppPostgresql: - content, err = postgresqlService.LoadDatabaseFile(req) - default: - content, err = mysqlService.LoadDatabaseFile(req) - } - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, content) -} diff --git a/backend/app/api/v1/database_common.go b/backend/app/api/v1/database_common.go new file mode 100644 index 000000000..5ff57736e --- /dev/null +++ b/backend/app/api/v1/database_common.go @@ -0,0 +1,75 @@ +package v1 + +import ( + "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" + "github.com/1Panel-dev/1Panel/backend/app/dto" + "github.com/1Panel-dev/1Panel/backend/constant" + "github.com/gin-gonic/gin" +) + +// @Tags Database Common +// @Summary Load base info +// @Description 获取数据库基础信息 +// @Accept json +// @Param request body dto.OperationWithNameAndType true "request" +// @Success 200 {object} dto.DBBaseInfo +// @Security ApiKeyAuth +// @Router /databases/common/info [post] +func (b *BaseApi) LoadDBBaseInfo(c *gin.Context) { + var req dto.OperationWithNameAndType + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + data, err := dbCommonService.LoadBaseInfo(req) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, data) +} + +// @Tags Database Common +// @Summary Load Database conf +// @Description 获取数据库配置文件 +// @Accept json +// @Param request body dto.OperationWithNameAndType true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /databases/common/load/file [post] +func (b *BaseApi) LoadDBFile(c *gin.Context) { + var req dto.OperationWithNameAndType + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + content, err := dbCommonService.LoadDatabaseFile(req) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, content) +} + +// @Tags Database Common +// @Summary Update conf by upload file +// @Description 上传替换配置文件 +// @Accept json +// @Param request body dto.DBConfUpdateByFile true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /databases/common/update/conf [post] +// @x-panel-log {"bodyKeys":["type","database"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 [type] 数据库 [database] 配置信息","formatEN":"update the [type] [database] database configuration information"} +func (b *BaseApi) UpdateDBConfByFile(c *gin.Context) { + var req dto.DBConfUpdateByFile + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + if err := dbCommonService.UpdateConfByFile(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, nil) +} diff --git a/backend/app/api/v1/database_mysql.go b/backend/app/api/v1/database_mysql.go index 24a89ffab..ba6720740 100644 --- a/backend/app/api/v1/database_mysql.go +++ b/backend/app/api/v1/database_mysql.go @@ -169,29 +169,6 @@ func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) { helper.SuccessWithData(c, nil) } -// @Tags Database Mysql -// @Summary Update mysql conf by upload file -// @Description 上传替换 mysql 配置文件 -// @Accept json -// @Param request body dto.MysqlConfUpdateByFile true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /databases/conffile/update [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mysql 数据库配置信息","formatEN":"update the mysql database configuration information"} -func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) { - var req dto.MysqlConfUpdateByFile - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := mysqlService.UpdateConfByFile(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, nil) -} - // @Tags Database Mysql // @Summary Page mysql databases // @Description 获取 mysql 数据库列表分页 @@ -304,29 +281,6 @@ func (b *BaseApi) DeleteMysql(c *gin.Context) { helper.SuccessWithData(c, nil) } -// @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 [post] -func (b *BaseApi) LoadBaseinfo(c *gin.Context) { - var req dto.OperationWithNameAndType - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - data, err := mysqlService.LoadBaseInfo(req) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, data) -} - // @Tags Database Mysql // @Summary Load mysql remote access // @Description 获取 mysql 远程访问权限 diff --git a/backend/app/api/v1/database_postgresql.go b/backend/app/api/v1/database_postgresql.go index e9bd3c6c4..ce9761984 100644 --- a/backend/app/api/v1/database_postgresql.go +++ b/backend/app/api/v1/database_postgresql.go @@ -41,6 +41,28 @@ func (b *BaseApi) CreatePostgresql(c *gin.Context) { helper.SuccessWithData(c, nil) } +// @Tags Database Postgresql +// @Summary Bind postgresql user +// @Description 绑定 postgresql 数据库用户 +// @Accept json +// @Param request body dto.PostgresqlBindUser true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /databases/pg/bind [post] +// @x-panel-log {"bodyKeys":["name", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"绑定 postgresql 数据库 [name] 用户 [username]","formatEN":"bind postgresql database [name] user [username]"} +func (b *BaseApi) BindPostgresqlUser(c *gin.Context) { + var req dto.PostgresqlBindUser + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + if err := postgresqlService.BindUser(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, nil) +} + // @Tags Database Postgresql // @Summary Update postgresql database description // @Description 更新 postgresql 数据库库描述信息 @@ -94,29 +116,6 @@ func (b *BaseApi) ChangePostgresqlPassword(c *gin.Context) { helper.SuccessWithData(c, nil) } -// @Tags Database Postgresql -// @Summary Update postgresql conf by upload file -// @Description 上传替换 postgresql 配置文件 -// @Accept json -// @Param request body dto.PostgresqlConfUpdateByFile true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /databases/pg/conf [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 postgresql 数据库配置信息","formatEN":"update the postgresql database configuration information"} -func (b *BaseApi) UpdatePostgresqlConfByFile(c *gin.Context) { - var req dto.PostgresqlConfUpdateByFile - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := postgresqlService.UpdateConfByFile(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, nil) -} - // @Tags Database Postgresql // @Summary Page postgresql databases // @Description 获取 postgresql 数据库列表分页 @@ -167,21 +166,20 @@ func (b *BaseApi) ListPostgresqlDBName(c *gin.Context) { // @Accept json // @Param request body dto.PostgresqlLoadDB true "request" // @Security ApiKeyAuth -// @Router /databases/pg/load [post] +// @Router /databases/pg/:database/load [post] func (b *BaseApi) LoadPostgresqlDBFromRemote(c *gin.Context) { - var req dto.PostgresqlLoadDB - if err := helper.CheckBindAndValidate(&req, c); err != nil { + database, err := helper.GetStrParamByKey(c, "database") + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - if err := postgresqlService.LoadFromRemote(req); err != nil { + if err := postgresqlService.LoadFromRemote(database); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } helper.SuccessWithData(c, nil) - - helper.SuccessWithData(c, nil) } // @Tags Database Postgresql @@ -229,26 +227,3 @@ func (b *BaseApi) DeletePostgresql(c *gin.Context) { tx.Commit() helper.SuccessWithData(c, nil) } - -// @Tags Database Postgresql -// @Summary Load postgresql base info -// @Description 获取 postgresql 基础信息 -// @Accept json -// @Param request body dto.OperationWithNameAndType true "request" -// @Success 200 {object} dto.DBBaseInfo -// @Security ApiKeyAuth -// @Router /databases/pg/baseinfo [post] -func (b *BaseApi) LoadPostgresqlBaseinfo(c *gin.Context) { - var req dto.OperationWithNameAndType - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - data, err := postgresqlService.LoadBaseInfo(req) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, data) -} diff --git a/backend/app/api/v1/database_redis.go b/backend/app/api/v1/database_redis.go index 306f4beab..489d1645c 100644 --- a/backend/app/api/v1/database_redis.go +++ b/backend/app/api/v1/database_redis.go @@ -1,15 +1,11 @@ package v1 import ( - "bufio" "encoding/base64" - "fmt" - "os" "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/constant" - "github.com/1Panel-dev/1Panel/backend/utils/compose" "github.com/gin-gonic/gin" ) @@ -161,45 +157,3 @@ func (b *BaseApi) RedisBackupList(c *gin.Context) { Total: total, }) } - -// @Tags Database Redis -// @Summary Update redis conf by file -// @Description 上传更新 redis 配置信息 -// @Accept json -// @Param request body dto.RedisConfUpdateByFile true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /databases/redis/conffile/update [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 redis 数据库配置信息","formatEN":"update the redis database configuration information"} -func (b *BaseApi) UpdateRedisConfByFile(c *gin.Context) { - var req dto.RedisConfUpdateByFile - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - redisInfo, err := redisService.LoadConf() - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - path := fmt.Sprintf("%s/redis/%s/conf/redis.conf", constant.AppInstallDir, redisInfo.Name) - file, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0640) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - defer file.Close() - write := bufio.NewWriter(file) - _, _ = write.WriteString(req.File) - write.Flush() - - if req.RestartNow { - composeDir := fmt.Sprintf("%s/redis/%s/docker-compose.yml", constant.AppInstallDir, redisInfo.Name) - if _, err := compose.Restart(composeDir); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - } - - helper.SuccessWithData(c, nil) -} diff --git a/backend/app/api/v1/entry.go b/backend/app/api/v1/entry.go index f1638c09f..611cc343d 100644 --- a/backend/app/api/v1/entry.go +++ b/backend/app/api/v1/entry.go @@ -21,6 +21,7 @@ var ( imageService = service.NewIImageService() dockerService = service.NewIDockerService() + dbCommonService = service.NewIDBCommonService() mysqlService = service.NewIMysqlService() postgresqlService = service.NewIPostgresqlService() databaseService = service.NewIDatabaseService() diff --git a/backend/app/dto/database.go b/backend/app/dto/database.go index af9797953..8fe07b443 100644 --- a/backend/app/dto/database.go +++ b/backend/app/dto/database.go @@ -2,6 +2,27 @@ package dto import "time" +// common +type DBConfUpdateByFile struct { + Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis"` + Database string `json:"database" validate:"required"` + File string `json:"file"` +} +type ChangeDBInfo struct { + ID uint `json:"id"` + From string `json:"from" validate:"required,oneof=local remote"` + Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql"` + Database string `json:"database" validate:"required"` + Value string `json:"value" validate:"required"` +} + +type DBBaseInfo struct { + Name string `json:"name"` + ContainerName string `json:"containerName"` + Port int64 `json:"port"` +} + +// mysql type MysqlDBSearch struct { PageInfo Info string `json:"info"` @@ -141,24 +162,6 @@ type MysqlVariablesUpdateHelper struct { Param string `json:"param"` Value interface{} `json:"value"` } -type MysqlConfUpdateByFile struct { - 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" validate:"required,oneof=local remote"` - Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql"` - Database string `json:"database" validate:"required"` - Value string `json:"value" validate:"required"` -} - -type DBBaseInfo struct { - Name string `json:"name"` - ContainerName string `json:"containerName"` - Port int64 `json:"port"` -} // redis type ChangeRedisPass struct { diff --git a/backend/app/dto/database_postgresql.go b/backend/app/dto/database_postgresql.go index 7d26b4b11..929c8578d 100644 --- a/backend/app/dto/database_postgresql.go +++ b/backend/app/dto/database_postgresql.go @@ -43,6 +43,13 @@ type PostgresqlDBCreate struct { Description string `json:"description"` } +type PostgresqlBindUser struct { + Name string `json:"name" validate:"required"` + Database string `json:"database" validate:"required"` + Username string `json:"username" validate:"required"` + Password string `json:"password" validate:"required"` +} + type PostgresqlLoadDB struct { From string `json:"from" validate:"required,oneof=local remote"` Type string `json:"type" validate:"required,oneof=postgresql"` diff --git a/backend/app/service/database_common.go b/backend/app/service/database_common.go new file mode 100644 index 000000000..75d6973e6 --- /dev/null +++ b/backend/app/service/database_common.go @@ -0,0 +1,94 @@ +package service + +import ( + "bufio" + "fmt" + "os" + "path" + + "github.com/1Panel-dev/1Panel/backend/app/dto" + "github.com/1Panel-dev/1Panel/backend/buserr" + "github.com/1Panel-dev/1Panel/backend/constant" + "github.com/1Panel-dev/1Panel/backend/global" + "github.com/1Panel-dev/1Panel/backend/utils/compose" +) + +type DBCommonService struct{} + +type IDBCommonService interface { + LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) + LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error) + + UpdateConfByFile(req dto.DBConfUpdateByFile) error +} + +func NewIDBCommonService() IDBCommonService { + return &DBCommonService{} +} + +func (u *DBCommonService) LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) { + var data dto.DBBaseInfo + app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name) + if err != nil { + return nil, err + } + data.ContainerName = app.ContainerName + data.Name = app.Name + data.Port = int64(app.Port) + + return &data, nil +} + +func (u *DBCommonService) LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error) { + filePath := "" + 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 "postgresql-conf": + filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/postgresql/%s/data/postgresql.conf", req.Name)) + case "redis-conf": + filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/redis/%s/conf/redis.conf", req.Name)) + 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") + } + content, err := os.ReadFile(filePath) + if err != nil { + return "", err + } + return string(content), nil +} + +func (u *DBCommonService) UpdateConfByFile(req dto.DBConfUpdateByFile) error { + app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database) + if err != nil { + return err + } + path := "" + switch req.Type { + case constant.AppMariaDB, constant.AppMysql: + path = fmt.Sprintf("%s/%s/%s/conf/my.cnf", constant.AppInstallDir, req.Type, app.Name) + case constant.AppPostgresql: + path = fmt.Sprintf("%s/%s/%s/data/postgresql.conf", constant.AppInstallDir, req.Type, app.Name) + case constant.AppRedis: + path = fmt.Sprintf("%s/%s/%s/conf/redis.conf", 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(req.File) + write.Flush() + if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, req.Type, app.Name)); err != nil { + return err + } + return nil +} diff --git a/backend/app/service/database_mysql.go b/backend/app/service/database_mysql.go index fe293bc9e..be93f006f 100644 --- a/backend/app/service/database_mysql.go +++ b/backend/app/service/database_mysql.go @@ -1,7 +1,6 @@ package service import ( - "bufio" "context" "encoding/json" "fmt" @@ -40,17 +39,13 @@ type IMysqlService interface { ChangeAccess(info dto.ChangeDBInfo) error ChangePassword(info dto.ChangeDBInfo) error UpdateVariables(req dto.MysqlVariablesUpdate) error - UpdateConfByFile(info dto.MysqlConfUpdateByFile) error UpdateDescription(req dto.UpdateDescription) error DeleteCheck(req dto.MysqlDBDeleteCheck) ([]string, error) Delete(ctx context.Context, req dto.MysqlDBDelete) 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) } func NewIMysqlService() IMysqlService { @@ -406,26 +401,6 @@ func (u *MysqlService) ChangeAccess(req dto.ChangeDBInfo) error { return nil } -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/%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(req.File) - write.Flush() - 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(req dto.MysqlVariablesUpdate) error { app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database) if err != nil { @@ -471,19 +446,6 @@ func (u *MysqlService) UpdateVariables(req dto.MysqlVariablesUpdate) error { return nil } -func (u *MysqlService) LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) { - var data dto.DBBaseInfo - app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name) - if err != nil { - return nil, err - } - data.ContainerName = app.ContainerName - data.Name = app.Name - data.Port = int64(app.Port) - - return &data, nil -} - func (u *MysqlService) LoadRemoteAccess(req dto.OperationWithNameAndType) (bool, error) { app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name) if err != nil { @@ -565,30 +527,6 @@ func (u *MysqlService) LoadStatus(req dto.OperationWithNameAndType) (*dto.MysqlS return &info, nil } -func (u *MysqlService) LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error) { - filePath := "" - 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 "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") - } - content, err := os.ReadFile(filePath) - if err != nil { - return "", err - } - return string(content), nil -} - func executeSqlForMaps(containerName, password, command string) (map[string]string, error) { cmd := exec.Command("docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command) stdout, err := cmd.CombinedOutput() diff --git a/backend/app/service/database_postgresql.go b/backend/app/service/database_postgresql.go index 92ad94939..d5a8fb97c 100644 --- a/backend/app/service/database_postgresql.go +++ b/backend/app/service/database_postgresql.go @@ -1,7 +1,6 @@ package service import ( - "bufio" "context" "fmt" "os" @@ -14,7 +13,6 @@ import ( "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/global" "github.com/1Panel-dev/1Panel/backend/utils/cmd" - "github.com/1Panel-dev/1Panel/backend/utils/compose" "github.com/1Panel-dev/1Panel/backend/utils/encrypt" "github.com/1Panel-dev/1Panel/backend/utils/postgresql" "github.com/1Panel-dev/1Panel/backend/utils/postgresql/client" @@ -28,16 +26,13 @@ type PostgresqlService struct{} type IPostgresqlService interface { SearchWithPage(search dto.PostgresqlDBSearch) (int64, interface{}, error) ListDBOption() ([]dto.PostgresqlOption, error) + BindUser(req dto.PostgresqlBindUser) error Create(ctx context.Context, req dto.PostgresqlDBCreate) (*model.DatabasePostgresql, error) - LoadFromRemote(req dto.PostgresqlLoadDB) error + LoadFromRemote(database string) error ChangePassword(info dto.ChangeDBInfo) error - UpdateConfByFile(info dto.PostgresqlConfUpdateByFile) error UpdateDescription(req dto.UpdateDescription) error DeleteCheck(req dto.PostgresqlDBDeleteCheck) ([]string, error) Delete(ctx context.Context, req dto.PostgresqlDBDelete) error - - LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) - LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error) } func NewIPostgresqlService() IPostgresqlService { @@ -88,6 +83,37 @@ func (u *PostgresqlService) ListDBOption() ([]dto.PostgresqlOption, error) { return dbs, err } +func (u *PostgresqlService) BindUser(req dto.PostgresqlBindUser) error { + dbItem, err := postgresqlRepo.Get(postgresqlRepo.WithByPostgresqlName(req.Database), commonRepo.WithByName(req.Name)) + if err != nil { + return err + } + + pgClient, err := LoadPostgresqlClientByFrom(req.Database) + if err != nil { + return err + } + if err := pgClient.CreateUser(client.CreateInfo{ + Name: req.Name, + Username: req.Username, + Password: req.Password, + Timeout: 300, + }, false); err != nil { + return err + } + pass, err := encrypt.StringEncrypt(req.Password) + if err != nil { + return fmt.Errorf("decrypt database db password failed, err: %v", err) + } + if err := postgresqlRepo.Update(dbItem.ID, map[string]interface{}{ + "username": req.Username, + "password": pass, + }); err != nil { + return err + } + return nil +} + func (u *PostgresqlService) Create(ctx context.Context, req dto.PostgresqlDBCreate) (*model.DatabasePostgresql, error) { if cmd.CheckIllegal(req.Name, req.Username, req.Password, req.Format) { return nil, buserr.New(constant.ErrCmdIllegal) @@ -168,14 +194,14 @@ func LoadPostgresqlClientByFrom(database string) (postgresql.PostgresqlClient, e return cli, nil } -func (u *PostgresqlService) LoadFromRemote(req dto.PostgresqlLoadDB) error { - client, err := LoadPostgresqlClientByFrom(req.Database) +func (u *PostgresqlService) LoadFromRemote(database string) error { + client, err := LoadPostgresqlClientByFrom(database) if err != nil { return err } defer client.Close() - databases, err := postgresqlRepo.List(postgresqlRepo.WithByPostgresqlName(req.Database)) + databases, err := postgresqlRepo.List(postgresqlRepo.WithByPostgresqlName(database)) if err != nil { return err } @@ -353,52 +379,3 @@ func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error { } return nil } - -func (u *PostgresqlService) UpdateConfByFile(req dto.PostgresqlConfUpdateByFile) error { - app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database) - if err != nil { - return err - } - conf := fmt.Sprintf("%s/%s/%s/data/postgresql.conf", constant.AppInstallDir, req.Type, app.Name) - file, err := os.OpenFile(conf, os.O_WRONLY|os.O_TRUNC, 0640) - if err != nil { - return err - } - defer file.Close() - write := bufio.NewWriter(file) - _, _ = write.WriteString(req.File) - write.Flush() - 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 *PostgresqlService) LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) { - var data dto.DBBaseInfo - app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name) - if err != nil { - return nil, err - } - data.ContainerName = app.ContainerName - data.Name = app.Name - data.Port = int64(app.Port) - - return &data, nil -} - -func (u *PostgresqlService) LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error) { - filePath := "" - switch req.Type { - case "postgresql-conf": - filePath = path.Join(global.CONF.System.DataDir, fmt.Sprintf("apps/postgresql/%s/data/postgresql.conf", req.Name)) - } - if _, err := os.Stat(filePath); err != nil { - return "", buserr.New("ErrHttpReqNotFound") - } - content, err := os.ReadFile(filePath) - if err != nil { - return "", err - } - return string(content), nil -} diff --git a/backend/init/migration/migrations/v_1_9.go b/backend/init/migration/migrations/v_1_9.go index 2dc542f15..91c60a43e 100644 --- a/backend/init/migration/migrations/v_1_9.go +++ b/backend/init/migration/migrations/v_1_9.go @@ -5,6 +5,7 @@ import ( "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/app/repo" "github.com/1Panel-dev/1Panel/backend/app/service" + "github.com/1Panel-dev/1Panel/backend/global" "github.com/go-gormigrate/gormigrate/v2" "gorm.io/gorm" ) @@ -133,14 +134,15 @@ var AddTableDatabasePostgresql = &gormigrate.Migration{ for _, job := range jobs { var db model.DatabaseMysql if err := tx.Where("id == ?", job.DBName).First(&db).Error; err != nil { - return err + continue } var database model.Database if err := tx.Where("name == ?", db.MysqlName).First(&database).Error; err != nil { - return err + continue } if err := tx.Model(&model.Cronjob{}).Where("id = ?", job.ID).Update("db_type", database.Type).Error; err != nil { - return err + global.LOG.Errorf("update db type of cronjob %s failed, err: %v", job.Name, err) + continue } } return nil diff --git a/backend/router/ro_database.go b/backend/router/ro_database.go index 20451985a..bebb13f28 100644 --- a/backend/router/ro_database.go +++ b/backend/router/ro_database.go @@ -16,6 +16,10 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) { Use(middleware.PasswordExpired()) baseApi := v1.ApiGroupApp.BaseApi { + cmdRouter.POST("/common/info", baseApi.LoadDBBaseInfo) + cmdRouter.POST("/common/load/file", baseApi.LoadDBFile) + cmdRouter.POST("/common/update/conf", baseApi.UpdateDBConfByFile) + cmdRouter.POST("", baseApi.CreateMysql) cmdRouter.POST("/bind", baseApi.BindUser) cmdRouter.POST("load", baseApi.LoadDBFromRemote) @@ -25,12 +29,9 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) { cmdRouter.POST("/del", baseApi.DeleteMysql) cmdRouter.POST("/description/update", baseApi.UpdateMysqlDescription) cmdRouter.POST("/variables/update", baseApi.UpdateMysqlVariables) - cmdRouter.POST("/conffile/update", baseApi.UpdateMysqlConfByFile) cmdRouter.POST("/search", baseApi.SearchMysql) - cmdRouter.POST("/load/file", baseApi.LoadDatabaseFile) 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) @@ -41,7 +42,6 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) { cmdRouter.POST("/redis/password", baseApi.ChangeRedisPassword) cmdRouter.POST("/redis/backup/search", baseApi.RedisBackupList) cmdRouter.POST("/redis/conf/update", baseApi.UpdateRedisConf) - cmdRouter.POST("/redis/conffile/update", baseApi.UpdateRedisConfByFile) cmdRouter.POST("/redis/persistence/update", baseApi.UpdateRedisPersistenceConf) cmdRouter.POST("/db/check", baseApi.CheckDatabase) @@ -56,11 +56,11 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) { cmdRouter.POST("/pg", baseApi.CreatePostgresql) cmdRouter.POST("/pg/search", baseApi.SearchPostgresql) - cmdRouter.POST("/pg/load", baseApi.LoadPostgresqlDBFromRemote) + cmdRouter.POST("/pg/:database/load", baseApi.LoadPostgresqlDBFromRemote) + cmdRouter.POST("/pg/bind", baseApi.BindPostgresqlUser) cmdRouter.POST("/pg/del/check", baseApi.DeleteCheckPostgresql) + cmdRouter.POST("/pg/del", baseApi.DeletePostgresql) cmdRouter.POST("/pg/password", baseApi.ChangePostgresqlPassword) cmdRouter.POST("/pg/description", baseApi.UpdatePostgresqlDescription) - cmdRouter.POST("/pg/del", baseApi.DeletePostgresql) - cmdRouter.POST("/pg/conf", baseApi.UpdatePostgresqlConfByFile) } } diff --git a/backend/utils/postgresql/client.go b/backend/utils/postgresql/client.go index eb0bdccd9..fbb59d62c 100644 --- a/backend/utils/postgresql/client.go +++ b/backend/utils/postgresql/client.go @@ -14,6 +14,7 @@ import ( type PostgresqlClient interface { Create(info client.CreateInfo) error + CreateUser(info client.CreateInfo, withDeleteDB bool) error Delete(info client.DeleteInfo) error ChangePassword(info client.PasswordChangeInfo) error diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index 1e4f64c1b..8e440e448 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -3916,42 +3916,6 @@ const docTemplate = `{ } } }, - "/databases/baseinfo": { - "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", - "schema": { - "$ref": "#/definitions/dto.DBBaseInfo" - } - } - } - } - }, "/databases/bind": { "post": { "security": [ @@ -4097,21 +4061,21 @@ const docTemplate = `{ } } }, - "/databases/conffile/update": { + "/databases/common/info": { "post": { "security": [ { "ApiKeyAuth": [] } ], - "description": "上传替换 mysql 配置文件", + "description": "获取数据库基础信息", "consumes": [ "application/json" ], "tags": [ - "Database Mysql" + "Database Common" ], - "summary": "Update mysql conf by upload file", + "summary": "Load base info", "parameters": [ { "description": "request", @@ -4119,7 +4083,76 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.MysqlConfUpdateByFile" + "$ref": "#/definitions/dto.OperationWithNameAndType" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.DBBaseInfo" + } + } + } + } + }, + "/databases/common/load/file": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取数据库配置文件", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Common" + ], + "summary": "Load Database conf", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.OperationWithNameAndType" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/databases/common/update/conf": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "上传替换配置文件", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Common" + ], + "summary": "Update conf by upload file", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.DBConfUpdateByFile" } } ], @@ -4130,9 +4163,12 @@ const docTemplate = `{ }, "x-panel-log": { "BeforeFunctions": [], - "bodyKeys": [], - "formatEN": "update the mysql database configuration information", - "formatZH": "更新 mysql 数据库配置信息", + "bodyKeys": [ + "type", + "database" + ], + "formatEN": "update the [type] [database] database configuration information", + "formatZH": "更新 [type] 数据库 [database] 配置信息", "paramKeys": [] } } @@ -4595,39 +4631,6 @@ const docTemplate = `{ "responses": {} } }, - "/databases/load/file": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "获取数据库文件", - "consumes": [ - "application/json" - ], - "tags": [ - "Database" - ], - "summary": "Load Database file", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.OperationWithNameAndType" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, "/databases/options": { "get": { "security": [ @@ -4709,21 +4712,21 @@ const docTemplate = `{ } } }, - "/databases/pg/baseinfo": { + "/databases/pg/:database/load": { "post": { "security": [ { "ApiKeyAuth": [] } ], - "description": "获取 postgresql 基础信息", + "description": "从服务器获取", "consumes": [ "application/json" ], "tags": [ "Database Postgresql" ], - "summary": "Load postgresql base info", + "summary": "Load postgresql database from remote", "parameters": [ { "description": "request", @@ -4731,35 +4734,28 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.OperationWithNameAndType" + "$ref": "#/definitions/dto.PostgresqlLoadDB" } } ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dto.DBBaseInfo" - } - } - } + "responses": {} } }, - "/databases/pg/conf": { + "/databases/pg/bind": { "post": { "security": [ { "ApiKeyAuth": [] } ], - "description": "上传替换 postgresql 配置文件", + "description": "绑定 postgresql 数据库用户", "consumes": [ "application/json" ], "tags": [ "Database Postgresql" ], - "summary": "Update postgresql conf by upload file", + "summary": "Bind postgresql user", "parameters": [ { "description": "request", @@ -4767,7 +4763,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PostgresqlConfUpdateByFile" + "$ref": "#/definitions/dto.PostgresqlBindUser" } } ], @@ -4778,9 +4774,12 @@ const docTemplate = `{ }, "x-panel-log": { "BeforeFunctions": [], - "bodyKeys": [], - "formatEN": "update the postgresql database configuration information", - "formatZH": "更新 postgresql 数据库配置信息", + "bodyKeys": [ + "name", + "username" + ], + "formatEN": "bind postgresql database [name] user [username]", + "formatZH": "绑定 postgresql 数据库 [name] 用户 [username]", "paramKeys": [] } } @@ -4927,35 +4926,6 @@ const docTemplate = `{ } } }, - "/databases/pg/load": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "从服务器获取", - "consumes": [ - "application/json" - ], - "tags": [ - "Database Postgresql" - ], - "summary": "Load postgresql database from remote", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.PostgresqlLoadDB" - } - } - ], - "responses": {} - } - }, "/databases/pg/options": { "get": { "security": [ @@ -5180,46 +5150,6 @@ const docTemplate = `{ } } }, - "/databases/redis/conffile/update": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "上传更新 redis 配置信息", - "consumes": [ - "application/json" - ], - "tags": [ - "Database Redis" - ], - "summary": "Update redis conf by file", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.RedisConfUpdateByFile" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - }, - "x-panel-log": { - "BeforeFunctions": [], - "bodyKeys": [], - "formatEN": "update the redis database configuration information", - "formatZH": "更新 redis 数据库配置信息", - "paramKeys": [] - } - } - }, "/databases/redis/password": { "post": { "security": [ @@ -15084,6 +15014,30 @@ const docTemplate = `{ } } }, + "dto.DBConfUpdateByFile": { + "type": "object", + "required": [ + "database", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "file": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "mysql", + "mariadb", + "postgresql", + "redis" + ] + } + } + }, "dto.DaemonJsonConf": { "type": "object", "properties": { @@ -16289,28 +16243,6 @@ const docTemplate = `{ } } }, - "dto.MysqlConfUpdateByFile": { - "type": "object", - "required": [ - "database", - "type" - ], - "properties": { - "database": { - "type": "string" - }, - "file": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "mysql", - "mariadb" - ] - } - } - }, "dto.MysqlDBCreate": { "type": "object", "required": [ @@ -16992,25 +16924,26 @@ const docTemplate = `{ } } }, - "dto.PostgresqlConfUpdateByFile": { + "dto.PostgresqlBindUser": { "type": "object", "required": [ "database", - "type" + "name", + "password", + "username" ], "properties": { "database": { "type": "string" }, - "file": { + "name": { "type": "string" }, - "type": { - "type": "string", - "enum": [ - "postgresql", - "mariadb" - ] + "password": { + "type": "string" + }, + "username": { + "type": "string" } } }, @@ -17268,20 +17201,6 @@ const docTemplate = `{ } } }, - "dto.RedisConfUpdateByFile": { - "type": "object", - "required": [ - "file" - ], - "properties": { - "file": { - "type": "string" - }, - "restartNow": { - "type": "boolean" - } - } - }, "dto.RedisPersistence": { "type": "object", "properties": { diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index 51bacf85c..302db6215 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -3909,42 +3909,6 @@ } } }, - "/databases/baseinfo": { - "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", - "schema": { - "$ref": "#/definitions/dto.DBBaseInfo" - } - } - } - } - }, "/databases/bind": { "post": { "security": [ @@ -4090,21 +4054,21 @@ } } }, - "/databases/conffile/update": { + "/databases/common/info": { "post": { "security": [ { "ApiKeyAuth": [] } ], - "description": "上传替换 mysql 配置文件", + "description": "获取数据库基础信息", "consumes": [ "application/json" ], "tags": [ - "Database Mysql" + "Database Common" ], - "summary": "Update mysql conf by upload file", + "summary": "Load base info", "parameters": [ { "description": "request", @@ -4112,7 +4076,76 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.MysqlConfUpdateByFile" + "$ref": "#/definitions/dto.OperationWithNameAndType" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.DBBaseInfo" + } + } + } + } + }, + "/databases/common/load/file": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取数据库配置文件", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Common" + ], + "summary": "Load Database conf", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.OperationWithNameAndType" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/databases/common/update/conf": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "上传替换配置文件", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Common" + ], + "summary": "Update conf by upload file", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.DBConfUpdateByFile" } } ], @@ -4123,9 +4156,12 @@ }, "x-panel-log": { "BeforeFunctions": [], - "bodyKeys": [], - "formatEN": "update the mysql database configuration information", - "formatZH": "更新 mysql 数据库配置信息", + "bodyKeys": [ + "type", + "database" + ], + "formatEN": "update the [type] [database] database configuration information", + "formatZH": "更新 [type] 数据库 [database] 配置信息", "paramKeys": [] } } @@ -4588,39 +4624,6 @@ "responses": {} } }, - "/databases/load/file": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "获取数据库文件", - "consumes": [ - "application/json" - ], - "tags": [ - "Database" - ], - "summary": "Load Database file", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.OperationWithNameAndType" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, "/databases/options": { "get": { "security": [ @@ -4702,21 +4705,21 @@ } } }, - "/databases/pg/baseinfo": { + "/databases/pg/:database/load": { "post": { "security": [ { "ApiKeyAuth": [] } ], - "description": "获取 postgresql 基础信息", + "description": "从服务器获取", "consumes": [ "application/json" ], "tags": [ "Database Postgresql" ], - "summary": "Load postgresql base info", + "summary": "Load postgresql database from remote", "parameters": [ { "description": "request", @@ -4724,35 +4727,28 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.OperationWithNameAndType" + "$ref": "#/definitions/dto.PostgresqlLoadDB" } } ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dto.DBBaseInfo" - } - } - } + "responses": {} } }, - "/databases/pg/conf": { + "/databases/pg/bind": { "post": { "security": [ { "ApiKeyAuth": [] } ], - "description": "上传替换 postgresql 配置文件", + "description": "绑定 postgresql 数据库用户", "consumes": [ "application/json" ], "tags": [ "Database Postgresql" ], - "summary": "Update postgresql conf by upload file", + "summary": "Bind postgresql user", "parameters": [ { "description": "request", @@ -4760,7 +4756,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PostgresqlConfUpdateByFile" + "$ref": "#/definitions/dto.PostgresqlBindUser" } } ], @@ -4771,9 +4767,12 @@ }, "x-panel-log": { "BeforeFunctions": [], - "bodyKeys": [], - "formatEN": "update the postgresql database configuration information", - "formatZH": "更新 postgresql 数据库配置信息", + "bodyKeys": [ + "name", + "username" + ], + "formatEN": "bind postgresql database [name] user [username]", + "formatZH": "绑定 postgresql 数据库 [name] 用户 [username]", "paramKeys": [] } } @@ -4920,35 +4919,6 @@ } } }, - "/databases/pg/load": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "从服务器获取", - "consumes": [ - "application/json" - ], - "tags": [ - "Database Postgresql" - ], - "summary": "Load postgresql database from remote", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.PostgresqlLoadDB" - } - } - ], - "responses": {} - } - }, "/databases/pg/options": { "get": { "security": [ @@ -5173,46 +5143,6 @@ } } }, - "/databases/redis/conffile/update": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "description": "上传更新 redis 配置信息", - "consumes": [ - "application/json" - ], - "tags": [ - "Database Redis" - ], - "summary": "Update redis conf by file", - "parameters": [ - { - "description": "request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/dto.RedisConfUpdateByFile" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - }, - "x-panel-log": { - "BeforeFunctions": [], - "bodyKeys": [], - "formatEN": "update the redis database configuration information", - "formatZH": "更新 redis 数据库配置信息", - "paramKeys": [] - } - } - }, "/databases/redis/password": { "post": { "security": [ @@ -15077,6 +15007,30 @@ } } }, + "dto.DBConfUpdateByFile": { + "type": "object", + "required": [ + "database", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "file": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "mysql", + "mariadb", + "postgresql", + "redis" + ] + } + } + }, "dto.DaemonJsonConf": { "type": "object", "properties": { @@ -16282,28 +16236,6 @@ } } }, - "dto.MysqlConfUpdateByFile": { - "type": "object", - "required": [ - "database", - "type" - ], - "properties": { - "database": { - "type": "string" - }, - "file": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "mysql", - "mariadb" - ] - } - } - }, "dto.MysqlDBCreate": { "type": "object", "required": [ @@ -16985,25 +16917,26 @@ } } }, - "dto.PostgresqlConfUpdateByFile": { + "dto.PostgresqlBindUser": { "type": "object", "required": [ "database", - "type" + "name", + "password", + "username" ], "properties": { "database": { "type": "string" }, - "file": { + "name": { "type": "string" }, - "type": { - "type": "string", - "enum": [ - "postgresql", - "mariadb" - ] + "password": { + "type": "string" + }, + "username": { + "type": "string" } } }, @@ -17261,20 +17194,6 @@ } } }, - "dto.RedisConfUpdateByFile": { - "type": "object", - "required": [ - "file" - ], - "properties": { - "file": { - "type": "string" - }, - "restartNow": { - "type": "boolean" - } - } - }, "dto.RedisPersistence": { "type": "object", "properties": { diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index 742e69c36..8e9cea8b0 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -705,6 +705,23 @@ definitions: port: type: integer type: object + dto.DBConfUpdateByFile: + properties: + database: + type: string + file: + type: string + type: + enum: + - mysql + - mariadb + - postgresql + - redis + type: string + required: + - database + - type + type: object dto.DaemonJsonConf: properties: cgroupDriver: @@ -1518,21 +1535,6 @@ definitions: - interval - secret type: object - dto.MysqlConfUpdateByFile: - properties: - database: - type: string - file: - type: string - type: - enum: - - mysql - - mariadb - type: string - required: - - database - - type - type: object dto.MysqlDBCreate: properties: database: @@ -1998,20 +2000,21 @@ definitions: required: - serverPort type: object - dto.PostgresqlConfUpdateByFile: + dto.PostgresqlBindUser: properties: database: type: string - file: + name: type: string - type: - enum: - - postgresql - - mariadb + password: + type: string + username: type: string required: - database - - type + - name + - password + - username type: object dto.PostgresqlDBCreate: properties: @@ -2185,15 +2188,6 @@ definitions: timeout: type: string type: object - dto.RedisConfUpdateByFile: - properties: - file: - type: string - restartNow: - type: boolean - required: - - file - type: object dto.RedisPersistence: properties: appendfsync: @@ -7466,28 +7460,6 @@ paths: formatEN: create mysql database [name] formatZH: 创建 mysql 数据库 [name] paramKeys: [] - /databases/baseinfo: - post: - consumes: - - application/json - description: 获取 mysql 基础信息 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/dto.OperationWithNameAndType' - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dto.DBBaseInfo' - security: - - ApiKeyAuth: [] - summary: Load mysql base info - tags: - - Database Mysql /databases/bind: post: consumes: @@ -7582,31 +7554,75 @@ paths: formatEN: Update database [name] password formatZH: 更新数据库 [name] 密码 paramKeys: [] - /databases/conffile/update: + /databases/common/info: post: consumes: - application/json - description: 上传替换 mysql 配置文件 + description: 获取数据库基础信息 parameters: - description: request in: body name: request required: true schema: - $ref: '#/definitions/dto.MysqlConfUpdateByFile' + $ref: '#/definitions/dto.OperationWithNameAndType' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.DBBaseInfo' + security: + - ApiKeyAuth: [] + summary: Load base info + tags: + - Database Common + /databases/common/load/file: + post: + consumes: + - application/json + description: 获取数据库配置文件 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.OperationWithNameAndType' responses: "200": description: OK security: - ApiKeyAuth: [] - summary: Update mysql conf by upload file + summary: Load Database conf tags: - - Database Mysql + - Database Common + /databases/common/update/conf: + post: + consumes: + - application/json + description: 上传替换配置文件 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.DBConfUpdateByFile' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Update conf by upload file + tags: + - Database Common x-panel-log: BeforeFunctions: [] - bodyKeys: [] - formatEN: update the mysql database configuration information - formatZH: 更新 mysql 数据库配置信息 + bodyKeys: + - type + - database + formatEN: update the [type] [database] database configuration information + formatZH: 更新 [type] 数据库 [database] 配置信息 paramKeys: [] /databases/db: post: @@ -7898,26 +7914,6 @@ paths: summary: Load mysql database from remote tags: - Database Mysql - /databases/load/file: - post: - consumes: - - application/json - description: 获取数据库文件 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/dto.OperationWithNameAndType' - responses: - "200": - description: OK - security: - - ApiKeyAuth: [] - summary: Load Database file - tags: - - Database /databases/options: get: consumes: @@ -7969,53 +7965,51 @@ paths: formatEN: create postgresql database [name] formatZH: 创建 postgresql 数据库 [name] paramKeys: [] - /databases/pg/baseinfo: + /databases/pg/:database/load: post: consumes: - application/json - description: 获取 postgresql 基础信息 + description: 从服务器获取 parameters: - description: request in: body name: request required: true schema: - $ref: '#/definitions/dto.OperationWithNameAndType' - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dto.DBBaseInfo' + $ref: '#/definitions/dto.PostgresqlLoadDB' + responses: {} security: - ApiKeyAuth: [] - summary: Load postgresql base info + summary: Load postgresql database from remote tags: - Database Postgresql - /databases/pg/conf: + /databases/pg/bind: post: consumes: - application/json - description: 上传替换 postgresql 配置文件 + description: 绑定 postgresql 数据库用户 parameters: - description: request in: body name: request required: true schema: - $ref: '#/definitions/dto.PostgresqlConfUpdateByFile' + $ref: '#/definitions/dto.PostgresqlBindUser' responses: "200": description: OK security: - ApiKeyAuth: [] - summary: Update postgresql conf by upload file + summary: Bind postgresql user tags: - Database Postgresql x-panel-log: BeforeFunctions: [] - bodyKeys: [] - formatEN: update the postgresql database configuration information - formatZH: 更新 postgresql 数据库配置信息 + bodyKeys: + - name + - username + formatEN: bind postgresql database [name] user [username] + formatZH: 绑定 postgresql 数据库 [name] 用户 [username] paramKeys: [] /databases/pg/del: post: @@ -8109,24 +8103,6 @@ paths: [description] formatZH: postgresql 数据库 [name] 描述信息修改 [description] paramKeys: [] - /databases/pg/load: - post: - consumes: - - application/json - description: 从服务器获取 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/dto.PostgresqlLoadDB' - responses: {} - security: - - ApiKeyAuth: [] - summary: Load postgresql database from remote - tags: - - Database Postgresql /databases/pg/options: get: consumes: @@ -8267,32 +8243,6 @@ paths: formatEN: update the redis database configuration information formatZH: 更新 redis 数据库配置信息 paramKeys: [] - /databases/redis/conffile/update: - post: - consumes: - - application/json - description: 上传更新 redis 配置信息 - parameters: - - description: request - in: body - name: request - required: true - schema: - $ref: '#/definitions/dto.RedisConfUpdateByFile' - responses: - "200": - description: OK - security: - - ApiKeyAuth: [] - summary: Update redis conf by file - tags: - - Database Redis - x-panel-log: - BeforeFunctions: [] - bodyKeys: [] - formatEN: update the redis database configuration information - formatZH: 更新 redis 数据库配置信息 - paramKeys: [] /databases/redis/password: post: consumes: diff --git a/frontend/src/api/interface/database.ts b/frontend/src/api/interface/database.ts index 2c48d8ce3..ca3a6f039 100644 --- a/frontend/src/api/interface/database.ts +++ b/frontend/src/api/interface/database.ts @@ -33,7 +33,7 @@ export namespace Database { mysqlKey: string; containerName: string; } - export interface MysqlConfUpdateByFile { + export interface DBConfUpdate { type: string; database: string; file: string; @@ -146,10 +146,11 @@ export namespace Database { type: string; database: string; } - export interface PgLoadDB { - from: string; - type: string; + export interface PgBind { + name: string; database: string; + username: string; + password: string; } export interface PostgresqlDBDelete { id: number; diff --git a/frontend/src/api/modules/database.ts b/frontend/src/api/modules/database.ts index 62bd62501..aa83c9458 100644 --- a/frontend/src/api/modules/database.ts +++ b/frontend/src/api/modules/database.ts @@ -5,22 +5,27 @@ import { ResPage, DescriptionUpdate } from '../interface'; import { Database } from '../interface/database'; import { TimeoutEnum } from '@/enums/http-enum'; -export const searchMysqlDBs = (params: Database.SearchDBWithPage) => { - return http.post>(`/databases/search`, params); +// common +export const loadDBBaseInfo = (type: string, database: string) => { + return http.post(`/databases/common/info`, { type: type, name: database }); +}; +export const loadDBFile = (type: string, database: string) => { + return http.post(`/databases/common/load/file`, { type: type, name: database }); +}; +export const updateDBFile = (params: Database.DBConfUpdate) => { + return http.post(`/databases/common/update/conf`, params); }; -export const loadDatabaseFile = (type: string, database: string) => { - return http.post(`/databases/load/file`, { type: type, name: database }); -}; +// pg export const addPostgresqlDB = (params: Database.PostgresqlDBCreate) => { let request = deepCopy(params) as Database.PostgresqlDBCreate; if (request.password) { request.password = Base64.encode(request.password); } - return http.post(`/databases/pg`, request); + return http.post(`/databases/pg`, request, TimeoutEnum.T_40S); }; -export const updatePostgresqlConfByFile = (params: Database.PostgresqlConfUpdateByFile) => { - return http.post(`/databases/pg/conf`, params); +export const bindPostgresqlUser = (params: Database.PgBind) => { + return http.post(`/databases/pg/bind`, params, TimeoutEnum.T_40S); }; export const searchPostgresqlDBs = (params: Database.SearchDBWithPage) => { return http.post>(`/databases/pg/search`, params); @@ -28,24 +33,27 @@ export const searchPostgresqlDBs = (params: Database.SearchDBWithPage) => { export const updatePostgresqlDescription = (params: DescriptionUpdate) => { return http.post(`/databases/pg/description`, params); }; -export const loadPgFromRemote = (params: Database.PgLoadDB) => { - return http.post(`/databases/pg/load`, params); +export const loadPgFromRemote = (database: string) => { + return http.post(`/databases/pg/${database}/load`); }; export const deleteCheckPostgresqlDB = (params: Database.PostgresqlDBDeleteCheck) => { - return http.post>(`/databases/pg/del/check`, params); + return http.post>(`/databases/pg/del/check`, params, TimeoutEnum.T_40S); }; export const updatePostgresqlPassword = (params: Database.ChangeInfo) => { let request = deepCopy(params) as Database.ChangeInfo; if (request.value) { request.value = Base64.encode(request.value); } - return http.post(`/databases/pg/password`, request); + return http.post(`/databases/pg/password`, request, TimeoutEnum.T_40S); }; export const deletePostgresqlDB = (params: Database.PostgresqlDBDelete) => { - return http.post(`/databases/pg/del`, params); + return http.post(`/databases/pg/del`, params, TimeoutEnum.T_40S); }; // mysql +export const searchMysqlDBs = (params: Database.SearchDBWithPage) => { + return http.post>(`/databases/search`, params); +}; export const addMysqlDB = (params: Database.MysqlDBCreate) => { let request = deepCopy(params) as Database.MysqlDBCreate; if (request.password) { @@ -79,9 +87,6 @@ export const updateMysqlDescription = (params: DescriptionUpdate) => { 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 = (params: Database.MysqlDBDeleteCheck) => { return http.post>(`/databases/del/check`, params); }; @@ -89,9 +94,6 @@ export const deleteMysqlDB = (params: Database.MysqlDBDelete) => { return http.post(`/databases/del`, params); }; -export const loadMysqlBaseInfo = (type: string, database: string) => { - return http.post(`/databases/baseinfo`, { type: type, name: database }); -}; export const loadMysqlVariables = (type: string, database: string) => { return http.post(`/databases/variables`, { type: type, name: database }); }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 471bb81db..b6379f3ad 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -383,6 +383,7 @@ const message = { loadFromRemote: 'Load from server', userBind: 'Bind User', + pgBind: 'Bind User (Binding existing users is not currently supported)', loadFromRemoteHelper: 'This action will synchronize the database info on the server to 1Panel, do you want to continue?', passwordHelper: 'Unable to retrieve, please modify', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index c389a6656..3bba9284e 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -376,6 +376,7 @@ const message = { loadFromRemote: '從服務器獲取', userBind: '綁定使用者', + pgBind: '綁定用戶(暫不支持綁定已有用戶)', loadFromRemoteHelper: '此操作將同步服務器上數據庫信息到 1Panel,是否繼續?', passwordHelper: '無法獲取密碼,請修改', local: '本地', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index f419b3ae2..3b295a92e 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -376,6 +376,7 @@ const message = { loadFromRemote: '从服务器获取', userBind: '绑定用户', + pgBind: '绑定用户(暂不支持绑定已有用户)', loadFromRemoteHelper: '此操作将同步服务器上数据库信息到 1Panel,是否继续?', passwordHelper: '无法获取密码,请修改', local: '本地', diff --git a/frontend/src/views/database/mysql/bind/index.vue b/frontend/src/views/database/mysql/bind/index.vue index d3ad0e5fb..a9aa2e0d2 100644 --- a/frontend/src/views/database/mysql/bind/index.vue +++ b/frontend/src/views/database/mysql/bind/index.vue @@ -66,6 +66,7 @@ const bindVisible = ref(false); type FormInstance = InstanceType; const changeFormRef = ref(); const form = reactive({ + from: '', database: '', mysqlName: '', username: '', @@ -93,13 +94,14 @@ function checkIPs(rule: any, value: any, callback: any) { } interface DialogProps { + from: string; database: string; mysqlName: string; } const acceptParams = (params: DialogProps): void => { - form.id = params.id; form.database = params.database; form.mysqlName = params.mysqlName; + form.from = params.from; bindVisible.value = true; }; const emit = defineEmits<{ (e: 'search'): void }>(); diff --git a/frontend/src/views/database/mysql/index.vue b/frontend/src/views/database/mysql/index.vue index 61532f0a5..6365fb2d8 100644 --- a/frontend/src/views/database/mysql/index.vue +++ b/frontend/src/views/database/mysql/index.vue @@ -529,6 +529,7 @@ const onBind = async (row: Database.MysqlDBInfo) => { let param = { database: currentDBName.value, mysqlName: row.name, + from: row.from, }; bindRef.value.acceptParams(param); }; diff --git a/frontend/src/views/database/mysql/setting/index.vue b/frontend/src/views/database/mysql/setting/index.vue index 23a410b11..c9208c1df 100644 --- a/frontend/src/views/database/mysql/setting/index.vue +++ b/frontend/src/views/database/mysql/setting/index.vue @@ -147,7 +147,7 @@ import { onMounted, reactive, ref } from 'vue'; import { Codemirror } from 'vue-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import { oneDark } from '@codemirror/theme-one-dark'; -import { loadDatabaseFile, loadMysqlBaseInfo, loadMysqlVariables, updateMysqlConfByFile } from '@/api/modules/database'; +import { loadDBFile, loadDBBaseInfo, loadMysqlVariables, updateDBFile } from '@/api/modules/database'; import { ChangePort, CheckAppInstalled, GetAppDefaultConfig } from '@/api/modules/app'; import { Rules } from '@/global/form-rules'; import i18n from '@/lang'; @@ -260,7 +260,7 @@ const onSubmitChangeConf = async () => { file: mysqlConf.value, }; loading.value = true; - await updateMysqlConfByFile(param) + await updateDBFile(param) .then(() => { useOld.value = false; loading.value = false; @@ -286,7 +286,7 @@ const loadContainerLog = async (containerID: string) => { }; const loadBaseInfo = async () => { - const res = await loadMysqlBaseInfo(props.type, props.database); + const res = await loadDBBaseInfo(props.type, props.database); mysqlName.value = res.data?.name; baseInfo.port = res.data?.port; baseInfo.containerID = res.data?.containerName; @@ -323,7 +323,7 @@ const loadSlowLogs = async () => { const loadMysqlConf = async () => { useOld.value = false; - await loadDatabaseFile(props.type + '-conf', props.database) + await loadDBFile(props.type + '-conf', props.database) .then((res) => { loading.value = false; mysqlConf.value = res.data; diff --git a/frontend/src/views/database/mysql/setting/slow-log/index.vue b/frontend/src/views/database/mysql/setting/slow-log/index.vue index d658fd396..256c18914 100644 --- a/frontend/src/views/database/mysql/setting/slow-log/index.vue +++ b/frontend/src/views/database/mysql/setting/slow-log/index.vue @@ -52,7 +52,7 @@ import { oneDark } from '@codemirror/theme-one-dark'; import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue'; import { Database } from '@/api/interface/database'; import ConfirmDialog from '@/components/confirm-dialog/index.vue'; -import { loadDatabaseFile, updateMysqlVariables } from '@/api/modules/database'; +import { loadDBFile, updateMysqlVariables } from '@/api/modules/database'; import { dateFormatForName, downloadWithContent } from '@/utils/util'; import i18n from '@/lang'; import { MsgError, MsgInfo, MsgSuccess } from '@/utils/message'; @@ -175,7 +175,7 @@ const onDownload = async () => { }; const loadMysqlSlowlogs = async () => { - const res = await loadDatabaseFile(currentDB.type + '-slow-logs', currentDB.database); + const res = await loadDBFile(currentDB.type + '-slow-logs', currentDB.database); slowLogs.value = res.data || ''; nextTick(() => { const state = view.value.state; diff --git a/frontend/src/views/database/postgresql/bind/index.vue b/frontend/src/views/database/postgresql/bind/index.vue new file mode 100644 index 000000000..14e29e474 --- /dev/null +++ b/frontend/src/views/database/postgresql/bind/index.vue @@ -0,0 +1,103 @@ + + diff --git a/frontend/src/views/database/postgresql/index.vue b/frontend/src/views/database/postgresql/index.vue index 55b38cb13..11286cce4 100644 --- a/frontend/src/views/database/postgresql/index.vue +++ b/frontend/src/views/database/postgresql/index.vue @@ -101,10 +101,24 @@ + @@ -212,6 +222,7 @@