diff --git a/backend/app/api/v1/database_postgresql.go b/backend/app/api/v1/database_postgresql.go index 5d8927634..e9bd3c6c4 100644 --- a/backend/app/api/v1/database_postgresql.go +++ b/backend/app/api/v1/database_postgresql.go @@ -94,50 +94,6 @@ func (b *BaseApi) ChangePostgresqlPassword(c *gin.Context) { helper.SuccessWithData(c, nil) } -// @Tags Database Postgresql -// @Summary Change postgresql access -// @Description 修改 postgresql 访问权限 -// @Accept json -// @Param request body dto.ChangeDBInfo true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /databases/pg/change/access [post] -// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_postgresqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 访问权限","formatEN":"Update database [name] access"} -func (b *BaseApi) ChangePostgresqlAccess(c *gin.Context) { - var req dto.ChangeDBInfo - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - if err := postgresqlService.ChangeAccess(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - helper.SuccessWithData(c, nil) -} - -// @Tags Database Postgresql -// @Summary Update postgresql variables -// @Description postgresql 性能调优 -// @Accept json -// @Param request body dto.PostgresqlVariablesUpdate true "request" -// @Success 200 -// @Security ApiKeyAuth -// @Router /databases/pg/variables/update [post] -// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"调整 postgresql 数据库性能参数","formatEN":"adjust postgresql database performance parameters"} -func (b *BaseApi) UpdatePostgresqlVariables(c *gin.Context) { - //var req dto.PostgresqlVariablesUpdate - //if err := helper.CheckBindAndValidate(&req, c); err != nil { - // return - //} - // - //if err := postgresqlService.UpdateVariables(req); err != nil { - // helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - // return - //} - helper.SuccessWithData(c, nil) -} - // @Tags Database Postgresql // @Summary Update postgresql conf by upload file // @Description 上传替换 postgresql 配置文件 @@ -213,15 +169,17 @@ func (b *BaseApi) ListPostgresqlDBName(c *gin.Context) { // @Security ApiKeyAuth // @Router /databases/pg/load [post] func (b *BaseApi) LoadPostgresqlDBFromRemote(c *gin.Context) { - //var req dto.PostgresqlLoadDB - //if err := helper.CheckBindAndValidate(&req, c); err != nil { - // return - //} - // - //if err := postgresqlService.LoadFromRemote(req); err != nil { - // helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - // return - //} + var req dto.PostgresqlLoadDB + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + + if err := postgresqlService.LoadFromRemote(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + + helper.SuccessWithData(c, nil) helper.SuccessWithData(c, nil) } @@ -294,28 +252,3 @@ func (b *BaseApi) LoadPostgresqlBaseinfo(c *gin.Context) { helper.SuccessWithData(c, data) } - - -// @Tags Database Postgresql -// @Summary Load postgresql status info -// @Description 获取 postgresql 状态信息 -// @Accept json -// @Param request body dto.OperationWithNameAndType true "request" -// @Success 200 {object} dto.PostgresqlStatus -// @Security ApiKeyAuth -// @Router /databases/pg/status [post] -func (b *BaseApi) LoadPostgresqlStatus(c *gin.Context) { - var req dto.OperationWithNameAndType - if err := helper.CheckBindAndValidate(&req, c); err != nil { - return - } - - data, err := postgresqlService.LoadStatus(req) - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - - helper.SuccessWithData(c, data) -} - diff --git a/backend/app/dto/database_postgresql.go b/backend/app/dto/database_postgresql.go index 5cdeeee59..7d26b4b11 100644 --- a/backend/app/dto/database_postgresql.go +++ b/backend/app/dto/database_postgresql.go @@ -63,51 +63,6 @@ type PostgresqlDBDelete struct { DeleteBackup bool `json:"deleteBackup"` } -type PostgresqlStatus struct { - Uptime string `json:"uptime"` - Version string `json:"version"` - MaxConnections string `json:"max_connections"` - Autovacuum string `json:"autovacuum"` - CurrentConnections string `json:"current_connections"` - HitRatio string `json:"hit_ratio"` - SharedBuffers string `json:"shared_buffers"` - BuffersClean string `json:"buffers_clean"` - MaxwrittenClean string `json:"maxwritten_clean"` - BuffersBackendFsync string `json:"buffers_backend_fsync"` -} - -type PostgresqlVariables struct { - BinlogCachSize string `json:"binlog_cache_size"` - InnodbBufferPoolSize string `json:"innodb_buffer_pool_size"` - InnodbLogBufferSize string `json:"innodb_log_buffer_size"` - JoinBufferSize string `json:"join_buffer_size"` - KeyBufferSize string `json:"key_buffer_size"` - MaxConnections string `json:"max_connections"` - MaxHeapTableSize string `json:"max_heap_table_size"` - QueryCacheSize string `json:"query_cache_size"` - QueryCache_type string `json:"query_cache_type"` - ReadBufferSize string `json:"read_buffer_size"` - ReadRndBufferSize string `json:"read_rnd_buffer_size"` - SortBufferSize string `json:"sort_buffer_size"` - TableOpenCache string `json:"table_open_cache"` - ThreadCacheSize string `json:"thread_cache_size"` - ThreadStack string `json:"thread_stack"` - TmpTableSize string `json:"tmp_table_size"` - - SlowQueryLog string `json:"slow_query_log"` - LongQueryTime string `json:"long_query_time"` -} - -type PostgresqlVariablesUpdate struct { - Type string `json:"type" validate:"required,oneof=postgresql"` - Database string `json:"database" validate:"required"` - Variables []PostgresqlVariablesUpdateHelper `json:"variables"` -} - -type PostgresqlVariablesUpdateHelper struct { - Param string `json:"param"` - Value interface{} `json:"value"` -} type PostgresqlConfUpdateByFile struct { Type string `json:"type" validate:"required,oneof=postgresql mariadb"` Database string `json:"database" validate:"required"` diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index c232bfd80..d33f95d7e 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -256,7 +256,6 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall } resourceId = pgdb.ID } - break case "mysql", "mariadb": iMysqlRepo := repo.NewIMysqlRepo() oldMysqlDb, _ := iMysqlRepo.Get(commonRepo.WithByName(dbConfig.DbName), iMysqlRepo.WithByFrom(constant.ResourceLocal)) @@ -280,8 +279,6 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall } resourceId = mysqldb.ID } - break - } } diff --git a/backend/app/service/backup_postgresql.go b/backend/app/service/backup_postgresql.go index 0a21da2bf..07a50647d 100644 --- a/backend/app/service/backup_postgresql.go +++ b/backend/app/service/backup_postgresql.go @@ -2,14 +2,15 @@ package service import ( "fmt" - "github.com/1Panel-dev/1Panel/backend/buserr" - pgclient "github.com/1Panel-dev/1Panel/backend/utils/postgresql/client" "os" "path" "path/filepath" "strings" "time" + "github.com/1Panel-dev/1Panel/backend/buserr" + pgclient "github.com/1Panel-dev/1Panel/backend/utils/postgresql/client" + "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/global" @@ -97,18 +98,14 @@ func (u *BackupService) PostgresqlRecoverByUpload(req dto.CommonRecover) error { return nil } func handlePostgresqlBackup(database, dbName, targetDir, fileName string) error { - dbInfo, err := postgresqlRepo.Get(commonRepo.WithByName(dbName), postgresqlRepo.WithByPostgresqlName(database)) - if err != nil { - return err - } - cli, _, err := LoadPostgresqlClientByFrom(database) + cli, err := LoadPostgresqlClientByFrom(database) if err != nil { return err } + defer cli.Close() backupInfo := pgclient.BackupInfo{ Name: dbName, - Format: dbInfo.Format, TargetDir: targetDir, FileName: fileName, @@ -130,16 +127,16 @@ func handlePostgresqlRecover(req dto.CommonRecover, isRollback bool) error { if err != nil { return err } - cli, _, err := LoadPostgresqlClientByFrom(req.Name) + cli, err := LoadPostgresqlClientByFrom(req.Name) if err != nil { return err } + defer cli.Close() if !isRollback { 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, TargetDir: path.Dir(rollbackFile), FileName: path.Base(rollbackFile), @@ -152,7 +149,6 @@ func handlePostgresqlRecover(req dto.CommonRecover, isRollback bool) error { global.LOG.Info("recover failed, start to rollback now") if err := cli.Recover(client.RecoverInfo{ Name: req.DetailName, - Format: dbInfo.Format, SourceFile: rollbackFile, Timeout: 300, @@ -168,10 +164,9 @@ func handlePostgresqlRecover(req dto.CommonRecover, isRollback bool) error { } if err := cli.Recover(client.RecoverInfo{ Name: req.DetailName, - Format: dbInfo.Format, SourceFile: req.File, - Username: dbInfo.Username, - Timeout: 300, + Username: dbInfo.Username, + Timeout: 300, }); err != nil { return err } diff --git a/backend/app/service/database.go b/backend/app/service/database.go index 7f7ddc98b..d358d1229 100644 --- a/backend/app/service/database.go +++ b/backend/app/service/database.go @@ -3,11 +3,12 @@ package service import ( "context" "fmt" - "github.com/1Panel-dev/1Panel/backend/utils/postgresql" - client2 "github.com/1Panel-dev/1Panel/backend/utils/postgresql/client" "os" "path" + "github.com/1Panel-dev/1Panel/backend/utils/postgresql" + client2 "github.com/1Panel-dev/1Panel/backend/utils/postgresql/client" + "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/buserr" "github.com/1Panel-dev/1Panel/backend/constant" @@ -88,13 +89,7 @@ func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool { Port: req.Port, Username: req.Username, Password: req.Password, - - SSL: false, - RootCert: req.RootCert, - ClientKey: req.ClientKey, - ClientCert: req.ClientCert, - SkipVerify: req.SkipVerify, - Timeout: 6, + Timeout: 6, }) return err == nil case "mysql", "mariadb": @@ -134,13 +129,7 @@ func (u *DatabaseService) Create(req dto.DatabaseCreate) error { Port: req.Port, Username: req.Username, Password: req.Password, - - SSL: req.SSL, - RootCert: req.RootCert, - ClientKey: req.ClientKey, - ClientCert: req.ClientCert, - SkipVerify: req.SkipVerify, - Timeout: 6, + Timeout: 6, }); err != nil { return err } @@ -230,13 +219,7 @@ func (u *DatabaseService) Update(req dto.DatabaseUpdate) error { Port: req.Port, Username: req.Username, Password: req.Password, - - SSL: req.SSL, - RootCert: req.RootCert, - ClientKey: req.ClientKey, - ClientCert: req.ClientCert, - SkipVerify: req.SkipVerify, - Timeout: 300, + Timeout: 300, }); err != nil { return err } diff --git a/backend/app/service/database_postgresql.go b/backend/app/service/database_postgresql.go index e5da60b46..b8af28991 100644 --- a/backend/app/service/database_postgresql.go +++ b/backend/app/service/database_postgresql.go @@ -4,6 +4,10 @@ import ( "bufio" "context" "fmt" + "os" + "path" + "strings" + "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/buserr" @@ -17,8 +21,6 @@ import ( _ "github.com/jackc/pgx/v5/stdlib" "github.com/jinzhu/copier" "github.com/pkg/errors" - "os" - "path" ) type PostgresqlService struct{} @@ -28,19 +30,13 @@ type IPostgresqlService interface { ListDBOption() ([]dto.PostgresqlOption, error) Create(ctx context.Context, req dto.PostgresqlDBCreate) (*model.DatabasePostgresql, error) LoadFromRemote(req dto.PostgresqlLoadDB) error - ChangeAccess(info dto.ChangeDBInfo) error ChangePassword(info dto.ChangeDBInfo) error - UpdateVariables(req dto.PostgresqlVariablesUpdate) 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 - LoadStatus(req dto.OperationWithNameAndType) (*dto.PostgresqlStatus, error) - LoadVariables(req dto.OperationWithNameAndType) (*dto.PostgresqlVariables, error) LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) - LoadRemoteAccess(req dto.OperationWithNameAndType) (bool, error) - LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error) } @@ -111,18 +107,18 @@ func (u *PostgresqlService) Create(ctx context.Context, req dto.PostgresqlDBCrea return nil, errors.New("Cannot set root as user name") } - cli, version, err := LoadPostgresqlClientByFrom(req.Database) + cli, err := LoadPostgresqlClientByFrom(req.Database) if err != nil { return nil, err } + defer cli.Close() + createItem.PostgresqlName = req.Database defer cli.Close() if err := cli.Create(client.CreateInfo{ Name: req.Name, - Format: req.Format, Username: req.Username, Password: req.Password, - Version: version, Timeout: 300, }); err != nil { return nil, err @@ -134,17 +130,17 @@ func (u *PostgresqlService) Create(ctx context.Context, req dto.PostgresqlDBCrea } return &createItem, nil } -func LoadPostgresqlClientByFrom(database string) (postgresql.PostgresqlClient, string, error) { + +func LoadPostgresqlClientByFrom(database string) (postgresql.PostgresqlClient, error) { var ( - dbInfo client.DBInfo - version string - err error + dbInfo client.DBInfo + err error ) dbInfo.Timeout = 300 databaseItem, err := databaseRepo.Get(commonRepo.WithByName(database)) if err != nil { - return nil, "", err + return nil, err } dbInfo.From = databaseItem.From dbInfo.Database = database @@ -153,17 +149,10 @@ func LoadPostgresqlClientByFrom(database string) (postgresql.PostgresqlClient, s dbInfo.Port = databaseItem.Port dbInfo.Username = databaseItem.Username dbInfo.Password = databaseItem.Password - dbInfo.SSL = databaseItem.SSL - dbInfo.ClientKey = databaseItem.ClientKey - dbInfo.ClientCert = databaseItem.ClientCert - dbInfo.RootCert = databaseItem.RootCert - dbInfo.SkipVerify = databaseItem.SkipVerify - version = databaseItem.Version - } else { app, err := appInstallRepo.LoadBaseInfo(databaseItem.Type, database) if err != nil { - return nil, "", err + return nil, err } dbInfo.From = "local" dbInfo.Address = app.ContainerName @@ -174,12 +163,44 @@ func LoadPostgresqlClientByFrom(database string) (postgresql.PostgresqlClient, s cli, err := postgresql.NewPostgresqlClient(dbInfo) if err != nil { - return nil, "", err + return nil, err } - return cli, version, nil + return cli, nil } -func (u *PostgresqlService) LoadFromRemote(req dto.PostgresqlLoadDB) error { +func (u *PostgresqlService) LoadFromRemote(req dto.PostgresqlLoadDB) error { + client, err := LoadPostgresqlClientByFrom(req.Database) + if err != nil { + return err + } + defer client.Close() + + databases, err := postgresqlRepo.List(postgresqlRepo.WithByPostgresqlName(req.Database)) + if err != nil { + return err + } + datas, err := client.SyncDB() + if err != nil { + return err + } + for _, data := range datas { + hasOld := false + for _, oldData := range databases { + if strings.EqualFold(oldData.Name, data.Name) && strings.EqualFold(oldData.PostgresqlName, data.PostgresqlName) { + hasOld = true + break + } + } + if !hasOld { + var createItem model.DatabasePostgresql + if err := copier.Copy(&createItem, &data); err != nil { + return errors.WithMessage(constant.ErrStructTransform, err.Error()) + } + if err := postgresqlRepo.Create(context.Background(), &createItem); err != nil { + return err + } + } + } return nil } @@ -224,17 +245,16 @@ func (u *PostgresqlService) Delete(ctx context.Context, req dto.PostgresqlDBDele if err != nil && !req.ForceDelete { return err } - cli, version, err := LoadPostgresqlClientByFrom(req.Database) + cli, err := LoadPostgresqlClientByFrom(req.Database) if err != nil { return err } defer cli.Close() if err := cli.Delete(client.DeleteInfo{ - Name: db.Name, - Version: version, - Username: db.Username, - Permission: "", - Timeout: 300, + Name: db.Name, + Username: db.Username, + ForceDelete: req.ForceDelete, + Timeout: 300, }); err != nil && !req.ForceDelete { return err } @@ -264,7 +284,7 @@ func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error { if cmd.CheckIllegal(req.Value) { return buserr.New(constant.ErrCmdIllegal) } - cli, version, err := LoadPostgresqlClientByFrom(req.Database) + cli, err := LoadPostgresqlClientByFrom(req.Database) if err != nil { return err } @@ -275,14 +295,12 @@ func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error { ) passwordInfo.Password = req.Value passwordInfo.Timeout = 300 - passwordInfo.Version = version if req.ID != 0 { postgresqlData, err = postgresqlRepo.Get(commonRepo.WithByID(req.ID)) if err != nil { return err } - passwordInfo.Name = postgresqlData.Name passwordInfo.Username = postgresqlData.Username } else { dbItem, err := databaseRepo.Get(commonRepo.WithByType(req.Type), commonRepo.WithByFrom(req.From)) @@ -317,7 +335,7 @@ func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error { } global.LOG.Infof("start to update postgresql password used by app %s-%s", appModel.Key, appInstall.Name) - if err := updateInstallInfoInDB(appModel.Key, appInstall.Name, "user-password", true, req.Value); err != nil { + if err := updateInstallInfoInDB(appModel.Key, appInstall.Name, "password", true, req.Value); err != nil { return err } } @@ -336,45 +354,6 @@ func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error { return nil } -func (u *PostgresqlService) ChangeAccess(req dto.ChangeDBInfo) error { - if cmd.CheckIllegal(req.Value) { - return buserr.New(constant.ErrCmdIllegal) - } - cli, version, err := LoadPostgresqlClientByFrom(req.Database) - if err != nil { - return err - } - defer cli.Close() - var ( - postgresqlData model.DatabasePostgresql - accessInfo client.AccessChangeInfo - ) - accessInfo.Permission = req.Value - accessInfo.Timeout = 300 - accessInfo.Version = version - - if req.ID != 0 { - postgresqlData, err = postgresqlRepo.Get(commonRepo.WithByID(req.ID)) - if err != nil { - return err - } - accessInfo.Name = postgresqlData.Name - accessInfo.Username = postgresqlData.Username - accessInfo.Password = postgresqlData.Password - } else { - accessInfo.Username = "root" - } - if err := cli.ChangeAccess(accessInfo); err != nil { - return err - } - - if postgresqlData.ID != 0 { - _ = postgresqlRepo.Update(postgresqlData.ID, map[string]interface{}{"permission": req.Value}) - } - - return nil -} - func (u *PostgresqlService) UpdateConfByFile(req dto.PostgresqlConfUpdateByFile) error { app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database) if err != nil { @@ -389,22 +368,12 @@ func (u *PostgresqlService) UpdateConfByFile(req dto.PostgresqlConfUpdateByFile) write := bufio.NewWriter(file) _, _ = write.WriteString(req.File) write.Flush() - cli, _, err := LoadPostgresqlClientByFrom(req.Database) - if err != nil { - return err - } - defer cli.Close() 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) UpdateVariables(req dto.PostgresqlVariablesUpdate) error { - - return nil -} - func (u *PostgresqlService) LoadBaseInfo(req dto.OperationWithNameAndType) (*dto.DBBaseInfo, error) { var data dto.DBBaseInfo app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name) @@ -418,32 +387,6 @@ func (u *PostgresqlService) LoadBaseInfo(req dto.OperationWithNameAndType) (*dto return &data, nil } -func (u *PostgresqlService) LoadRemoteAccess(req dto.OperationWithNameAndType) (bool, error) { - - return true, nil -} - -func (u *PostgresqlService) LoadVariables(req dto.OperationWithNameAndType) (*dto.PostgresqlVariables, error) { - - return nil, nil -} - -func (u *PostgresqlService) LoadStatus(req dto.OperationWithNameAndType) (*dto.PostgresqlStatus, error) { - app, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name) - if err != nil { - return nil, err - } - cli, _, err := LoadPostgresqlClientByFrom(app.Name) - if err != nil { - return nil, err - } - defer cli.Close() - status := cli.Status() - postgresqlStatus := dto.PostgresqlStatus{} - copier.Copy(&postgresqlStatus,&status) - return &postgresqlStatus, nil -} - func (u *PostgresqlService) LoadDatabaseFile(req dto.OperationWithNameAndType) (string, error) { filePath := "" switch req.Type { diff --git a/backend/router/ro_database.go b/backend/router/ro_database.go index cfbc22ad5..232869b72 100644 --- a/backend/router/ro_database.go +++ b/backend/router/ro_database.go @@ -53,15 +53,13 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) { cmdRouter.POST("/db/del/check", baseApi.DeleteCheckDatabase) cmdRouter.POST("/db/del", baseApi.DeleteDatabase) - //PGSQL管理系列接口 cmdRouter.POST("/pg", baseApi.CreatePostgresql) cmdRouter.POST("/pg/search", baseApi.SearchPostgresql) + cmdRouter.POST("/pg/load", baseApi.LoadPostgresqlDBFromRemote) cmdRouter.POST("/pg/del/check", baseApi.DeleteCheckPostgresql) cmdRouter.POST("/pg/password", baseApi.ChangePostgresqlPassword) cmdRouter.POST("/pg/description", baseApi.UpdatePostgresqlDescription) cmdRouter.POST("/pg/del", baseApi.DeletePostgresql) cmdRouter.POST("/pg/conf", baseApi.UpdatePostgresqlConfByFile) - cmdRouter.POST("/pg/status", baseApi.LoadPostgresqlStatus) - } } diff --git a/backend/utils/mysql/client/local.go b/backend/utils/mysql/client/local.go index 96711b382..a5cb3f837 100644 --- a/backend/utils/mysql/client/local.go +++ b/backend/utils/mysql/client/local.go @@ -63,13 +63,15 @@ func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error { if strings.Contains(strings.ToLower(err.Error()), "error 1396") { return buserr.New(constant.ErrUserIsExist) } - _ = r.Delete(DeleteInfo{ - Name: info.Name, - Version: info.Version, - Username: info.Username, - Permission: info.Permission, - ForceDelete: true, - Timeout: 300}) + if withDeleteDB { + _ = r.Delete(DeleteInfo{ + Name: info.Name, + Version: info.Version, + Username: info.Username, + Permission: info.Permission, + ForceDelete: true, + Timeout: 300}) + } return err } grantStr := fmt.Sprintf("grant all privileges on `%s`.* to %s", info.Name, user) @@ -82,13 +84,15 @@ func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error { grantStr = grantStr + " with grant option;" } if err := r.ExecSQL(grantStr, info.Timeout); err != nil { - _ = r.Delete(DeleteInfo{ - Name: info.Name, - Version: info.Version, - Username: info.Username, - Permission: info.Permission, - ForceDelete: true, - Timeout: 300}) + if withDeleteDB { + _ = r.Delete(DeleteInfo{ + Name: info.Name, + Version: info.Version, + Username: info.Username, + Permission: info.Permission, + ForceDelete: true, + Timeout: 300}) + } return err } } diff --git a/backend/utils/postgresql/client.go b/backend/utils/postgresql/client.go index 4c46e5b5f..8d9de1bfd 100644 --- a/backend/utils/postgresql/client.go +++ b/backend/utils/postgresql/client.go @@ -4,34 +4,32 @@ import ( "context" "database/sql" "fmt" + "time" + "github.com/1Panel-dev/1Panel/backend/buserr" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/utils/postgresql/client" _ "github.com/jackc/pgx/v5/stdlib" - "time" ) type PostgresqlClient interface { Create(info client.CreateInfo) error Delete(info client.DeleteInfo) error - ReloadConf()error + ReloadConf() error ChangePassword(info client.PasswordChangeInfo) error - ChangeAccess(info client.AccessChangeInfo) error Backup(info client.BackupInfo) error Recover(info client.RecoverInfo) error - Status() client.Status - SyncDB(version string) ([]client.SyncDBInfo, error) + SyncDB() ([]client.SyncDBInfo, error) Close() } func NewPostgresqlClient(conn client.DBInfo) (PostgresqlClient, error) { - if conn.Port==0 { - conn.Port=5432 - } if conn.From == "local" { - conn.Address = "127.0.0.1" + connArgs := []string{"exec", conn.Address, "psql", "-U", conn.Username, "-c"} + return client.NewLocal(connArgs, conn.Address, conn.Username, conn.Password, conn.Database), nil } + connArgs := fmt.Sprintf("postgres://%s:%s@%s:%d/?sslmode=disable", conn.Username, conn.Password, conn.Address, conn.Port) db, err := sql.Open("pgx", connArgs) if err != nil { @@ -54,11 +52,5 @@ func NewPostgresqlClient(conn client.DBInfo) (PostgresqlClient, error) { Password: conn.Password, Address: conn.Address, Port: conn.Port, - - SSL: conn.SSL, - RootCert: conn.RootCert, - ClientKey: conn.ClientKey, - ClientCert: conn.ClientCert, - SkipVerify: conn.SkipVerify, }), nil } diff --git a/backend/utils/postgresql/client/info.go b/backend/utils/postgresql/client/info.go index e5835ac89..7adaf13ab 100644 --- a/backend/utils/postgresql/client/info.go +++ b/backend/utils/postgresql/client/info.go @@ -12,60 +12,34 @@ type DBInfo struct { Username string `json:"userName"` Password string `json:"password"` - SSL bool `json:"ssl"` - RootCert string `json:"rootCert"` - ClientKey string `json:"clientKey"` - ClientCert string `json:"clientCert"` - SkipVerify bool `json:"skipVerify"` - Timeout uint `json:"timeout"` // second } type CreateInfo struct { - Name string `json:"name"` - Format string `json:"format"` - Version string `json:"version"` - Username string `json:"userName"` - Password string `json:"password"` - Permission string `json:"permission"` + Name string `json:"name"` + Username string `json:"userName"` + Password string `json:"password"` Timeout uint `json:"timeout"` // second } type DeleteInfo struct { - Name string `json:"name"` - Version string `json:"version"` - Username string `json:"userName"` - Permission string `json:"permission"` + Name string `json:"name"` + Username string `json:"userName"` ForceDelete bool `json:"forceDelete"` Timeout uint `json:"timeout"` // second } type PasswordChangeInfo struct { - Name string `json:"name"` - Version string `json:"version"` - Username string `json:"userName"` - Password string `json:"password"` - Permission string `json:"permission"` - - Timeout uint `json:"timeout"` // second -} - -type AccessChangeInfo struct { - Name string `json:"name"` - Version string `json:"version"` - Username string `json:"userName"` - Password string `json:"password"` - OldPermission string `json:"oldPermission"` - Permission string `json:"permission"` + Username string `json:"userName"` + Password string `json:"password"` Timeout uint `json:"timeout"` // second } type BackupInfo struct { Name string `json:"name"` - Format string `json:"format"` TargetDir string `json:"targetDir"` FileName string `json:"fileName"` @@ -74,19 +48,16 @@ type BackupInfo struct { type RecoverInfo struct { Name string `json:"name"` - Format string `json:"format"` SourceFile string `json:"sourceFile"` Username string `json:"username"` - Timeout uint `json:"timeout"` // second + + Timeout uint `json:"timeout"` // second } type SyncDBInfo struct { Name string `json:"name"` From string `json:"from"` PostgresqlName string `json:"postgresqlName"` - Format string `json:"format"` - Username string `json:"username"` - Password string `json:"password"` } type Status struct { Uptime string `json:"uptime"` diff --git a/backend/utils/postgresql/client/local.go b/backend/utils/postgresql/client/local.go new file mode 100644 index 000000000..e31bfd605 --- /dev/null +++ b/backend/utils/postgresql/client/local.go @@ -0,0 +1,201 @@ +package client + +import ( + "compress/gzip" + "context" + "errors" + "fmt" + "os" + "os/exec" + "path" + "strings" + "time" + + "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/files" +) + +type Local struct { + PrefixCommand []string + Database string + Username string + Password string + ContainerName string +} + +func NewLocal(command []string, containerName, username, password, database string) *Local { + return &Local{PrefixCommand: command, ContainerName: containerName, Username: username, Password: password, Database: database} +} + +func (r *Local) Create(info CreateInfo) error { + createSql := fmt.Sprintf("CREATE DATABASE %s", info.Name) + if err := r.ExecSQL(createSql, info.Timeout); err != nil { + if strings.Contains(strings.ToLower(err.Error()), "already exists") { + return buserr.New(constant.ErrDatabaseIsExist) + } + return err + } + + if err := r.CreateUser(info, true); err != nil { + _ = r.ExecSQL(fmt.Sprintf("DROP DATABASE %s", info.Name), info.Timeout) + return err + } + + return nil +} + +func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error { + createSql := fmt.Sprintf("CREATE USER \"%s\" WITH PASSWORD '%s'", info.Username, info.Username) + if err := r.ExecSQL(createSql, info.Timeout); err != nil { + if strings.Contains(strings.ToLower(err.Error()), "already exists") { + return buserr.New(constant.ErrUserIsExist) + } + if withDeleteDB { + _ = r.Delete(DeleteInfo{ + Name: info.Name, + Username: info.Username, + ForceDelete: true, + Timeout: 300}) + } + return err + } + grantStr := fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE %s TO %s", info.Name, info.Username) + if err := r.ExecSQL(grantStr, info.Timeout); err != nil { + if withDeleteDB { + _ = r.Delete(DeleteInfo{ + Name: info.Name, + Username: info.Username, + ForceDelete: true, + Timeout: 300}) + } + return err + } + return nil +} + +func (r *Local) Delete(info DeleteInfo) error { + if len(info.Name) != 0 { + dropSql := fmt.Sprintf("DROP DATABASE %s", info.Name) + if err := r.ExecSQL(dropSql, info.Timeout); err != nil && !info.ForceDelete { + return err + } + } + dropSql := fmt.Sprintf("DROP ROLE %s", info.Username) + if err := r.ExecSQL(dropSql, info.Timeout); err != nil && !info.ForceDelete { + if strings.Contains(strings.ToLower(err.Error()), "depend on it") { + return buserr.WithDetail(constant.ErrInUsed, info.Username, nil) + } + return err + } + return nil +} + +func (r *Local) ChangePassword(info PasswordChangeInfo) error { + changeSql := fmt.Sprintf("ALTER USER \"%s\" WITH PASSWORD '%s'", info.Username, info.Password) + if err := r.ExecSQL(changeSql, info.Timeout); err != nil { + return err + } + + return nil +} + +func (r *Local) Backup(info BackupInfo) error { + fileOp := files.NewFileOp() + if !fileOp.Stat(info.TargetDir) { + if err := os.MkdirAll(info.TargetDir, os.ModePerm); err != nil { + return fmt.Errorf("mkdir %s failed, err: %v", info.TargetDir, err) + } + } + outfile, _ := os.OpenFile(path.Join(info.TargetDir, info.FileName), os.O_RDWR|os.O_CREATE, 0755) + global.LOG.Infof("start to pg_dump | gzip > %s.gzip", info.TargetDir+"/"+info.FileName) + cmd := exec.Command("docker", "exec", r.ContainerName, "pg_dump", "-F", "c", "-U", r.Username, "-d", info.Name) + gzipCmd := exec.Command("gzip", "-cf") + gzipCmd.Stdin, _ = cmd.StdoutPipe() + gzipCmd.Stdout = outfile + _ = gzipCmd.Start() + _ = cmd.Run() + _ = gzipCmd.Wait() + return nil +} + +func (r *Local) Recover(info RecoverInfo) error { + fi, _ := os.Open(info.SourceFile) + defer fi.Close() + cmd := exec.Command("docker", "exec", "-i", r.ContainerName, "pg_restore", "-F", "c", "-c", "-U", r.Username, "-d", info.Name) + if strings.HasSuffix(info.SourceFile, ".gz") { + gzipFile, err := os.Open(info.SourceFile) + if err != nil { + return err + } + defer gzipFile.Close() + gzipReader, err := gzip.NewReader(gzipFile) + if err != nil { + return err + } + defer gzipReader.Close() + cmd.Stdin = gzipReader + } else { + cmd.Stdin = fi + } + stdout, err := cmd.CombinedOutput() + if err != nil || strings.HasPrefix(string(stdout), "ERROR ") { + return errors.New(string(stdout)) + } + + return nil +} + +func (r *Local) ReloadConf() error { + return nil +} + +func (r *Local) SyncDB() ([]SyncDBInfo, error) { + var datas []SyncDBInfo + lines, err := r.ExecSQLForRows("SELECT datname FROM pg_database", 300) + if err != nil { + return datas, err + } + for _, line := range lines { + if line == "postgres" || line == "template1" || line == "template0" || line == r.Username { + continue + } + datas = append(datas, SyncDBInfo{Name: line, From: "local", PostgresqlName: r.Database}) + } + return datas, nil +} + +func (r *Local) Close() {} + +func (r *Local) ExecSQL(command string, timeout uint) error { + itemCommand := r.PrefixCommand[:] + itemCommand = append(itemCommand, command) + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + cmd := exec.CommandContext(ctx, "docker", itemCommand...) + stdout, err := cmd.CombinedOutput() + if ctx.Err() == context.DeadlineExceeded { + return buserr.New(constant.ErrExecTimeOut) + } + if err != nil || strings.HasPrefix(string(stdout), "ERROR ") { + return errors.New(string(stdout)) + } + return nil +} + +func (r *Local) ExecSQLForRows(command string, timeout uint) ([]string, error) { + itemCommand := r.PrefixCommand[:] + itemCommand = append(itemCommand, command) + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + cmd := exec.CommandContext(ctx, "docker", itemCommand...) + stdout, err := cmd.CombinedOutput() + if ctx.Err() == context.DeadlineExceeded { + return nil, buserr.New(constant.ErrExecTimeOut) + } + if err != nil || strings.HasPrefix(string(stdout), "ERROR ") { + return nil, errors.New(string(stdout)) + } + return strings.Split(string(stdout), "\n"), nil +} diff --git a/backend/utils/postgresql/client/remote.go b/backend/utils/postgresql/client/remote.go index a9c48cb30..25fb53179 100644 --- a/backend/utils/postgresql/client/remote.go +++ b/backend/utils/postgresql/client/remote.go @@ -5,14 +5,15 @@ import ( "context" "database/sql" "fmt" - "github.com/1Panel-dev/1Panel/backend/global" - "github.com/pkg/errors" "io" "os" "os/exec" "strings" "time" + "github.com/1Panel-dev/1Panel/backend/global" + "github.com/pkg/errors" + "github.com/1Panel-dev/1Panel/backend/buserr" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/1Panel-dev/1Panel/backend/utils/files" @@ -21,115 +22,83 @@ import ( type Remote struct { Client *sql.DB + From string Database string User string Password string Address string Port uint - - SSL bool - RootCert string - ClientKey string - ClientCert string - SkipVerify bool } func NewRemote(db Remote) *Remote { return &db } -func (r *Remote) Status() Status { - status := Status{} - var i int64 - var s string - var f float64 - _ = r.Client.QueryRow("select count(*) from pg_stat_activity WHERE client_addr is not NULL;").Scan(&i) - status.CurrentConnections = fmt.Sprintf("%d",i) - _ = r.Client.QueryRow("SELECT current_timestamp - pg_postmaster_start_time();").Scan(&s) - before,_, _ := strings.Cut(s, ".") - status.Uptime = before - _ = r.Client.QueryRow("select sum(blks_hit)*100/sum(blks_hit+blks_read) as hit_ratio from pg_stat_database;").Scan(&f) - status.HitRatio = fmt.Sprintf("%0.2f",f) - var a1,a2,a3 int64 - _ = r.Client.QueryRow("select buffers_clean, maxwritten_clean, buffers_backend_fsync from pg_stat_bgwriter;").Scan(&a1, &a2, &a3) - status.BuffersClean = fmt.Sprintf("%d",a1) - status.MaxwrittenClean = fmt.Sprintf("%d",a2) - status.BuffersBackendFsync= fmt.Sprintf("%d",a3) - rows, err := r.Client.Query("SHOW ALL;") - if err == nil { - defer rows.Close() - for rows.Next() { - var k,v string - err := rows.Scan(&k, &v,&s) - if err != nil { - continue - } - if k == "autovacuum" { - status.Autovacuum = v - } - if k == "max_connections" { - status.MaxConnections = v - } - if k == "server_version" { - status.Version = v - } - if k == "shared_buffers" { - status.SharedBuffers = v - } - } - } - return status -} func (r *Remote) Create(info CreateInfo) error { - createUser := fmt.Sprintf(`CREATE USER "%s" WITH PASSWORD '%s';`, info.Username, info.Password) - createDB := fmt.Sprintf(`CREATE DATABASE "%s" OWNER "%s";`, info.Name, info.Username) - grant := fmt.Sprintf(`GRANT ALL PRIVILEGES ON DATABASE "%s" TO "%s";`, info.Name, info.Username) - if err := r.ExecSQL(createUser, info.Timeout); err != nil { - if strings.Contains(strings.ToLower(err.Error()), "already") { - return buserr.New(constant.ErrUserIsExist) - } - return err - } - if err := r.ExecSQL(createDB, info.Timeout); err != nil { - if strings.Contains(strings.ToLower(err.Error()), "already") { - _ = r.ExecSQL(fmt.Sprintf(`DROP DATABASE "%s"`, info.Name), info.Timeout) + createSql := fmt.Sprintf("CREATE DATABASE %s", info.Name) + if err := r.ExecSQL(createSql, info.Timeout); err != nil { + if strings.Contains(strings.ToLower(err.Error()), "already exists") { return buserr.New(constant.ErrDatabaseIsExist) } return err } - _ = r.ExecSQL(grant, info.Timeout) + if err := r.CreateUser(info, true); err != nil { + return err + } return nil } func (r *Remote) CreateUser(info CreateInfo, withDeleteDB bool) error { - sql1 := fmt.Sprintf(`CREATE USER "%s" WITH PASSWORD '%s'; -GRANT ALL PRIVILEGES ON DATABASE "%s" TO "%s";`, info.Username, info.Password, info.Name, info.Username) - err := r.ExecSQL(sql1, info.Timeout) - if err != nil { - if strings.Contains(strings.ToLower(err.Error()), "already") { + createSql := fmt.Sprintf("CREATE USER \"%s\" WITH PASSWORD '%s'", info.Username, info.Password) + if err := r.ExecSQL(createSql, info.Timeout); err != nil { + if strings.Contains(strings.ToLower(err.Error()), "already exists") { return buserr.New(constant.ErrUserIsExist) } + if withDeleteDB { + _ = r.Delete(DeleteInfo{ + Name: info.Name, + Username: info.Username, + ForceDelete: true, + Timeout: 300}) + } + return err + } + grantSql := fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE %s TO %s", info.Name, info.Username) + if err := r.ExecSQL(grantSql, info.Timeout); err != nil { + if withDeleteDB { + _ = r.Delete(DeleteInfo{ + Name: info.Name, + Username: info.Username, + ForceDelete: true, + Timeout: 300}) + } + return err } return nil } func (r *Remote) Delete(info DeleteInfo) error { - //暂时不支持强制删除,就算附加了 WITH(FORCE) 也会删除失败 - err := r.ExecSQL(fmt.Sprintf(`DROP DATABASE "%s"`, info.Name), info.Timeout) - if err != nil { + if len(info.Name) != 0 { + dropSql := fmt.Sprintf("DROP DATABASE %s", info.Name) + if err := r.ExecSQL(dropSql, info.Timeout); err != nil && !info.ForceDelete { + return err + } + } + dropSql := fmt.Sprintf("DROP ROLE %s", info.Username) + if err := r.ExecSQL(dropSql, info.Timeout); err != nil && !info.ForceDelete { + if strings.Contains(strings.ToLower(err.Error()), "depend on it") { + return buserr.WithDetail(constant.ErrInUsed, info.Username, nil) + } return err } - return r.ExecSQL(fmt.Sprintf(`DROP USER "%s"`, info.Username), info.Timeout) + return nil } func (r *Remote) ChangePassword(info PasswordChangeInfo) error { - return r.ExecSQL(fmt.Sprintf(`ALTER USER "%s" WITH ENCRYPTED PASSWORD '%s';`, info.Username, info.Password), info.Timeout) + return r.ExecSQL(fmt.Sprintf("ALTER USER \"%s\" WITH ENCRYPTED PASSWORD '%s'", info.Username, info.Password), info.Timeout) } -func (r *Remote) ReloadConf()error { - return r.ExecSQL("SELECT pg_reload_conf();",5) -} -func (r *Remote) ChangeAccess(info AccessChangeInfo) error { - return nil +func (r *Remote) ReloadConf() error { + return r.ExecSQL("SELECT pg_reload_conf()", 5) } func (r *Remote) Backup(info BackupInfo) error { @@ -173,7 +142,7 @@ func (r *Remote) Recover(info RecoverInfo) error { gzipCmd := exec.Command("gunzip", info.SourceFile) stdout, err := gzipCmd.CombinedOutput() if err != nil { - return fmt.Errorf("gunzip file %s failed, stdout: %v, err: %v", info.SourceFile, string(stdout), err) + return fmt.Errorf("gunzip file %s failed, stdout: %v, err: %v", info.SourceFile, string(stdout), err) } defer func() { gzipCmd := exec.Command("gzip", fileName) @@ -207,9 +176,29 @@ func (r *Remote) Recover(info RecoverInfo) error { return nil } -func (r *Remote) SyncDB(version string) ([]SyncDBInfo, error) { - //如果需要同步数据库,则需要强制修改用户密码,否则无法获取真实密码,后面可考虑改为添加服务器账号,手动将账号/数据库添加到管理列表 +func (r *Remote) SyncDB() ([]SyncDBInfo, error) { + ctx, cancel := context.WithTimeout(context.Background(), 300*time.Second) + defer cancel() + var datas []SyncDBInfo + rows, err := r.Client.Query("SELECT datname FROM pg_database;") + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + var dbName string + if err := rows.Scan(&dbName); err != nil { + continue + } + if dbName == "postgres" || dbName == "template1" || dbName == "template0" || dbName == r.User { + continue + } + datas = append(datas, SyncDBInfo{Name: dbName, From: r.From, PostgresqlName: r.Database}) + } + if ctx.Err() == context.DeadlineExceeded { + return nil, buserr.New(constant.ErrExecTimeOut) + } return datas, nil } diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index 3079d81a4..cc84b0314 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -4642,6 +4642,421 @@ const docTemplate = `{ } } }, + "/databases/pg": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建 postgresql 数据库", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Create postgresql database", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBCreate" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [], + "bodyKeys": [ + "name" + ], + "formatEN": "create postgresql database [name]", + "formatZH": "创建 postgresql 数据库 [name]", + "paramKeys": [] + } + } + }, + "/databases/pg/baseinfo": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取 postgresql 基础信息", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Load postgresql 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/pg/conf": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "上传替换 postgresql 配置文件", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Update postgresql conf by upload file", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlConfUpdateByFile" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [], + "bodyKeys": [], + "formatEN": "update the postgresql database configuration information", + "formatZH": "更新 postgresql 数据库配置信息", + "paramKeys": [] + } + } + }, + "/databases/pg/del": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "删除 postgresql 数据库", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Delete postgresql database", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBDelete" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [ + { + "db": "database_postgresqls", + "input_column": "id", + "input_value": "id", + "isList": false, + "output_column": "name", + "output_value": "name" + } + ], + "bodyKeys": [ + "id" + ], + "formatEN": "delete postgresql database [name]", + "formatZH": "删除 postgresql 数据库 [name]", + "paramKeys": [] + } + } + }, + "/databases/pg/del/check": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Postgresql 数据库删除前检查", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Check before delete postgresql database", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBDeleteCheck" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/databases/pg/description": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新 postgresql 数据库库描述信息", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Update postgresql database description", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateDescription" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [ + { + "db": "database_postgresqls", + "input_column": "id", + "input_value": "id", + "isList": false, + "output_column": "name", + "output_value": "name" + } + ], + "bodyKeys": [ + "id", + "description" + ], + "formatEN": "The description of the postgresql database [name] is modified =\u003e [description]", + "formatZH": "postgresql 数据库 [name] 描述信息修改 [description]", + "paramKeys": [] + } + } + }, + "/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": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取 postgresql 数据库列表", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "List postgresql database names", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PageInfo" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PostgresqlOption" + } + } + } + } + } + }, + "/databases/pg/password": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "修改 postgresql 密码", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Change postgresql password", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.ChangeDBInfo" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [ + { + "db": "database_postgresqls", + "input_column": "id", + "input_value": "id", + "isList": false, + "output_column": "name", + "output_value": "name" + } + ], + "bodyKeys": [ + "id" + ], + "formatEN": "Update database [name] password", + "formatZH": "更新数据库 [name] 密码", + "paramKeys": [] + } + } + }, + "/databases/pg/search": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取 postgresql 数据库列表分页", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Page postgresql databases", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBSearch" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageResult" + } + } + } + } + }, "/databases/redis/backup/search": { "post": { "security": [ @@ -13734,7 +14149,8 @@ const docTemplate = `{ "type": "string", "enum": [ "mysql", - "mariadb" + "mariadb", + "postgresql" ] }, "value": { @@ -13871,7 +14287,8 @@ const docTemplate = `{ "mysql", "mariadb", "redis", - "website" + "website", + "postgresql" ] } } @@ -13913,7 +14330,8 @@ const docTemplate = `{ "mysql", "mariadb", "redis", - "website" + "website", + "postgresql" ] } } @@ -16388,6 +16806,193 @@ const docTemplate = `{ } } }, + "dto.PostgresqlConfUpdateByFile": { + "type": "object", + "required": [ + "database", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "file": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "postgresql", + "mariadb" + ] + } + } + }, + "dto.PostgresqlDBCreate": { + "type": "object", + "required": [ + "database", + "from", + "name", + "password", + "permission", + "username" + ], + "properties": { + "database": { + "type": "string" + }, + "description": { + "type": "string" + }, + "format": { + "type": "string" + }, + "from": { + "type": "string", + "enum": [ + "local", + "remote" + ] + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "permission": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "dto.PostgresqlDBDelete": { + "type": "object", + "required": [ + "database", + "id", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "deleteBackup": { + "type": "boolean" + }, + "forceDelete": { + "type": "boolean" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string", + "enum": [ + "postgresql" + ] + } + } + }, + "dto.PostgresqlDBDeleteCheck": { + "type": "object", + "required": [ + "database", + "id", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string", + "enum": [ + "postgresql" + ] + } + } + }, + "dto.PostgresqlDBSearch": { + "type": "object", + "required": [ + "database", + "page", + "pageSize" + ], + "properties": { + "database": { + "type": "string" + }, + "info": { + "type": "string" + }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + } + } + }, + "dto.PostgresqlLoadDB": { + "type": "object", + "required": [ + "database", + "from", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "from": { + "type": "string", + "enum": [ + "local", + "remote" + ] + }, + "type": { + "type": "string", + "enum": [ + "postgresql" + ] + } + } + }, + "dto.PostgresqlOption": { + "type": "object", + "properties": { + "database": { + "type": "string" + }, + "from": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, "dto.RecordSearch": { "type": "object", "required": [ diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index 5c5996a61..7a3fcbdf4 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -4635,6 +4635,421 @@ } } }, + "/databases/pg": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建 postgresql 数据库", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Create postgresql database", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBCreate" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [], + "bodyKeys": [ + "name" + ], + "formatEN": "create postgresql database [name]", + "formatZH": "创建 postgresql 数据库 [name]", + "paramKeys": [] + } + } + }, + "/databases/pg/baseinfo": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取 postgresql 基础信息", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Load postgresql 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/pg/conf": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "上传替换 postgresql 配置文件", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Update postgresql conf by upload file", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlConfUpdateByFile" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [], + "bodyKeys": [], + "formatEN": "update the postgresql database configuration information", + "formatZH": "更新 postgresql 数据库配置信息", + "paramKeys": [] + } + } + }, + "/databases/pg/del": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "删除 postgresql 数据库", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Delete postgresql database", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBDelete" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [ + { + "db": "database_postgresqls", + "input_column": "id", + "input_value": "id", + "isList": false, + "output_column": "name", + "output_value": "name" + } + ], + "bodyKeys": [ + "id" + ], + "formatEN": "delete postgresql database [name]", + "formatZH": "删除 postgresql 数据库 [name]", + "paramKeys": [] + } + } + }, + "/databases/pg/del/check": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Postgresql 数据库删除前检查", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Check before delete postgresql database", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBDeleteCheck" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/databases/pg/description": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新 postgresql 数据库库描述信息", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Update postgresql database description", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.UpdateDescription" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [ + { + "db": "database_postgresqls", + "input_column": "id", + "input_value": "id", + "isList": false, + "output_column": "name", + "output_value": "name" + } + ], + "bodyKeys": [ + "id", + "description" + ], + "formatEN": "The description of the postgresql database [name] is modified =\u003e [description]", + "formatZH": "postgresql 数据库 [name] 描述信息修改 [description]", + "paramKeys": [] + } + } + }, + "/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": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取 postgresql 数据库列表", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "List postgresql database names", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PageInfo" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/dto.PostgresqlOption" + } + } + } + } + } + }, + "/databases/pg/password": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "修改 postgresql 密码", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Change postgresql password", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.ChangeDBInfo" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFunctions": [ + { + "db": "database_postgresqls", + "input_column": "id", + "input_value": "id", + "isList": false, + "output_column": "name", + "output_value": "name" + } + ], + "bodyKeys": [ + "id" + ], + "formatEN": "Update database [name] password", + "formatZH": "更新数据库 [name] 密码", + "paramKeys": [] + } + } + }, + "/databases/pg/search": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取 postgresql 数据库列表分页", + "consumes": [ + "application/json" + ], + "tags": [ + "Database Postgresql" + ], + "summary": "Page postgresql databases", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PostgresqlDBSearch" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dto.PageResult" + } + } + } + } + }, "/databases/redis/backup/search": { "post": { "security": [ @@ -13727,7 +14142,8 @@ "type": "string", "enum": [ "mysql", - "mariadb" + "mariadb", + "postgresql" ] }, "value": { @@ -13864,7 +14280,8 @@ "mysql", "mariadb", "redis", - "website" + "website", + "postgresql" ] } } @@ -13906,7 +14323,8 @@ "mysql", "mariadb", "redis", - "website" + "website", + "postgresql" ] } } @@ -16381,6 +16799,193 @@ } } }, + "dto.PostgresqlConfUpdateByFile": { + "type": "object", + "required": [ + "database", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "file": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "postgresql", + "mariadb" + ] + } + } + }, + "dto.PostgresqlDBCreate": { + "type": "object", + "required": [ + "database", + "from", + "name", + "password", + "permission", + "username" + ], + "properties": { + "database": { + "type": "string" + }, + "description": { + "type": "string" + }, + "format": { + "type": "string" + }, + "from": { + "type": "string", + "enum": [ + "local", + "remote" + ] + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "permission": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "dto.PostgresqlDBDelete": { + "type": "object", + "required": [ + "database", + "id", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "deleteBackup": { + "type": "boolean" + }, + "forceDelete": { + "type": "boolean" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string", + "enum": [ + "postgresql" + ] + } + } + }, + "dto.PostgresqlDBDeleteCheck": { + "type": "object", + "required": [ + "database", + "id", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "type": { + "type": "string", + "enum": [ + "postgresql" + ] + } + } + }, + "dto.PostgresqlDBSearch": { + "type": "object", + "required": [ + "database", + "page", + "pageSize" + ], + "properties": { + "database": { + "type": "string" + }, + "info": { + "type": "string" + }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + } + } + }, + "dto.PostgresqlLoadDB": { + "type": "object", + "required": [ + "database", + "from", + "type" + ], + "properties": { + "database": { + "type": "string" + }, + "from": { + "type": "string", + "enum": [ + "local", + "remote" + ] + }, + "type": { + "type": "string", + "enum": [ + "postgresql" + ] + } + } + }, + "dto.PostgresqlOption": { + "type": "object", + "properties": { + "database": { + "type": "string" + }, + "from": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, "dto.RecordSearch": { "type": "object", "required": [ diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index 41e80debf..bc20e3b66 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -178,6 +178,7 @@ definitions: enum: - mysql - mariadb + - postgresql type: string value: type: string @@ -272,6 +273,7 @@ definitions: - mariadb - redis - website + - postgresql type: string required: - type @@ -303,6 +305,7 @@ definitions: - mariadb - redis - website + - postgresql type: string required: - source @@ -1980,6 +1983,134 @@ definitions: required: - serverPort type: object + dto.PostgresqlConfUpdateByFile: + properties: + database: + type: string + file: + type: string + type: + enum: + - postgresql + - mariadb + type: string + required: + - database + - type + type: object + dto.PostgresqlDBCreate: + properties: + database: + type: string + description: + type: string + format: + type: string + from: + enum: + - local + - remote + type: string + name: + type: string + password: + type: string + permission: + type: string + username: + type: string + required: + - database + - from + - name + - password + - permission + - username + type: object + dto.PostgresqlDBDelete: + properties: + database: + type: string + deleteBackup: + type: boolean + forceDelete: + type: boolean + id: + type: integer + type: + enum: + - postgresql + type: string + required: + - database + - id + - type + type: object + dto.PostgresqlDBDeleteCheck: + properties: + database: + type: string + id: + type: integer + type: + enum: + - postgresql + type: string + required: + - database + - id + - type + type: object + dto.PostgresqlDBSearch: + properties: + database: + type: string + info: + type: string + order: + type: string + orderBy: + type: string + page: + type: integer + pageSize: + type: integer + required: + - database + - page + - pageSize + type: object + dto.PostgresqlLoadDB: + properties: + database: + type: string + from: + enum: + - local + - remote + type: string + type: + enum: + - postgresql + type: string + required: + - database + - from + - type + type: object + dto.PostgresqlOption: + properties: + database: + type: string + from: + type: string + id: + type: integer + name: + type: string + type: + type: string + type: object dto.RecordSearch: properties: detailName: @@ -7729,6 +7860,270 @@ paths: summary: List mysql database names tags: - Database Mysql + /databases/pg: + post: + consumes: + - application/json + description: 创建 postgresql 数据库 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PostgresqlDBCreate' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Create postgresql database + tags: + - Database Postgresql + x-panel-log: + BeforeFunctions: [] + bodyKeys: + - name + formatEN: create postgresql database [name] + formatZH: 创建 postgresql 数据库 [name] + paramKeys: [] + /databases/pg/baseinfo: + post: + consumes: + - application/json + description: 获取 postgresql 基础信息 + 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 postgresql base info + tags: + - Database Postgresql + /databases/pg/conf: + post: + consumes: + - application/json + description: 上传替换 postgresql 配置文件 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PostgresqlConfUpdateByFile' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Update postgresql conf by upload file + tags: + - Database Postgresql + x-panel-log: + BeforeFunctions: [] + bodyKeys: [] + formatEN: update the postgresql database configuration information + formatZH: 更新 postgresql 数据库配置信息 + paramKeys: [] + /databases/pg/del: + post: + consumes: + - application/json + description: 删除 postgresql 数据库 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PostgresqlDBDelete' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Delete postgresql database + tags: + - Database Postgresql + x-panel-log: + BeforeFunctions: + - db: database_postgresqls + input_column: id + input_value: id + isList: false + output_column: name + output_value: name + bodyKeys: + - id + formatEN: delete postgresql database [name] + formatZH: 删除 postgresql 数据库 [name] + paramKeys: [] + /databases/pg/del/check: + post: + consumes: + - application/json + description: Postgresql 数据库删除前检查 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PostgresqlDBDeleteCheck' + responses: + "200": + description: OK + schema: + items: + type: string + type: array + security: + - ApiKeyAuth: [] + summary: Check before delete postgresql database + tags: + - Database Postgresql + /databases/pg/description: + post: + consumes: + - application/json + description: 更新 postgresql 数据库库描述信息 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.UpdateDescription' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Update postgresql database description + tags: + - Database Postgresql + x-panel-log: + BeforeFunctions: + - db: database_postgresqls + input_column: id + input_value: id + isList: false + output_column: name + output_value: name + bodyKeys: + - id + - description + formatEN: The description of the postgresql database [name] is modified => + [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: + - application/json + description: 获取 postgresql 数据库列表 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PageInfo' + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/dto.PostgresqlOption' + type: array + security: + - ApiKeyAuth: [] + summary: List postgresql database names + tags: + - Database Postgresql + /databases/pg/password: + post: + consumes: + - application/json + description: 修改 postgresql 密码 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.ChangeDBInfo' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Change postgresql password + tags: + - Database Postgresql + x-panel-log: + BeforeFunctions: + - db: database_postgresqls + input_column: id + input_value: id + isList: false + output_column: name + output_value: name + bodyKeys: + - id + formatEN: Update database [name] password + formatZH: 更新数据库 [name] 密码 + paramKeys: [] + /databases/pg/search: + post: + consumes: + - application/json + description: 获取 postgresql 数据库列表分页 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/dto.PostgresqlDBSearch' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dto.PageResult' + security: + - ApiKeyAuth: [] + summary: Page postgresql databases + tags: + - Database Postgresql /databases/redis/backup/search: post: consumes: diff --git a/frontend/src/api/interface/database.ts b/frontend/src/api/interface/database.ts index 157cb8ee1..175c23f77 100644 --- a/frontend/src/api/interface/database.ts +++ b/frontend/src/api/interface/database.ts @@ -148,6 +148,11 @@ export namespace Database { database: string; name: string; } + export interface PgLoadDB { + from: string; + type: string; + database: string; + } export interface PostgresqlDBDelete { id: number; type: string; diff --git a/frontend/src/api/modules/database.ts b/frontend/src/api/modules/database.ts index 09539ca48..ea784568d 100644 --- a/frontend/src/api/modules/database.ts +++ b/frontend/src/api/modules/database.ts @@ -19,9 +19,6 @@ export const addPostgresqlDB = (params: Database.PostgresqlDBCreate) => { } return http.post(`/databases/pg`, request); }; -export const loadPostgresqlStatus = (type: string, database: string) => { - return http.post(`/databases/pg/status`, { type: type, name: database }); -}; export const updatePostgresqlConfByFile = (params: Database.PostgresqlConfUpdateByFile) => { return http.post(`/databases/pg/conf`, params); }; @@ -31,6 +28,9 @@ 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 deleteCheckPostgresqlDB = (params: Database.PostgresqlDBDeleteCheck) => { return http.post>(`/databases/pg/del/check`, params); }; @@ -44,6 +44,8 @@ export const updatePostgresqlPassword = (params: Database.ChangeInfo) => { export const deletePostgresqlDB = (params: Database.PostgresqlDBDelete) => { return http.post(`/databases/pg/del`, params); }; + +// mysql export const addMysqlDB = (params: Database.MysqlDBCreate) => { let request = deepCopy(params) as Database.MysqlDBCreate; if (request.password) { diff --git a/frontend/src/views/database/postgresql/index.vue b/frontend/src/views/database/postgresql/index.vue index a3ce51f0d..55b38cb13 100644 --- a/frontend/src/views/database/postgresql/index.vue +++ b/frontend/src/views/database/postgresql/index.vue @@ -70,6 +70,14 @@ > {{ $t('database.databaseConnInfo') }} + + {{ $t('database.loadFromRemote') }} + {{ $t('database.remoteDB') }} @@ -218,6 +226,7 @@ import { onMounted, reactive, ref } from 'vue'; import { deleteCheckPostgresqlDB, listDatabases, + loadPgFromRemote, searchPostgresqlDBs, updatePostgresqlDescription, } from '@/api/modules/database'; @@ -343,6 +352,29 @@ const search = async (column?: any) => { paginationConfig.total = res.data.total; }; +const loadDB = async () => { + ElMessageBox.confirm(i18n.global.t('database.loadFromRemoteHelper'), i18n.global.t('commons.msg.infoTitle'), { + confirmButtonText: i18n.global.t('commons.button.confirm'), + cancelButtonText: i18n.global.t('commons.button.cancel'), + type: 'info', + }).then(async () => { + loading.value = true; + let params = { + from: currentDB.value.from, + type: currentDB.value.type, + database: currentDBName.value, + }; + await loadPgFromRemote(params) + .then(() => { + loading.value = false; + search(); + }) + .catch(() => { + loading.value = false; + }); + }); +}; + const goRouter = async (target: string) => { if (target === 'app') { router.push({ name: 'AppAll', query: { install: 'postgresql' } }); diff --git a/frontend/src/views/database/postgresql/setting/index.vue b/frontend/src/views/database/postgresql/setting/index.vue index cf0a2218a..fafaa0ddd 100644 --- a/frontend/src/views/database/postgresql/setting/index.vue +++ b/frontend/src/views/database/postgresql/setting/index.vue @@ -7,14 +7,6 @@ {{ $t('database.confChange') }} - - {{ $t('database.currentStatus') }} - {{ $t('commons.table.port') }} @@ -49,23 +41,10 @@ :extensions="extensions" v-model="postgresqlConf" /> - {{ $t('commons.button.save') }} - - - - - -
@@ -114,7 +93,6 @@ - -