diff --git a/internal/biz/database_server.go b/internal/biz/database_server.go
index 35c7ff395..7e0bac82f 100644
--- a/internal/biz/database_server.go
+++ b/internal/biz/database_server.go
@@ -69,4 +69,5 @@ type DatabaseServerRepo interface {
Create(req *request.DatabaseServerCreate) error
Update(req *request.DatabaseServerUpdate) error
Delete(id uint) error
+ Sync(id uint) error
}
diff --git a/internal/data/backup.go b/internal/data/backup.go
index f92417b95..6e4b1e8da 100644
--- a/internal/data/backup.go
+++ b/internal/data/backup.go
@@ -288,7 +288,7 @@ func (r *backupRepo) createMySQL(to string, name string) error {
// createPostgres 创建 PostgreSQL 备份
func (r *backupRepo) createPostgres(to string, name string) error {
- postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432, fmt.Sprintf("%s/server/postgresql/data/pg_hba.conf", app.Root))
+ postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432)
if err != nil {
return err
}
@@ -436,7 +436,7 @@ func (r *backupRepo) restorePostgres(backup, target string) error {
return errors.New("备份文件不存在")
}
- postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432, fmt.Sprintf("%s/server/postgresql/data/pg_hba.conf", app.Root))
+ postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432)
if err != nil {
return err
}
diff --git a/internal/data/database.go b/internal/data/database.go
index e6e646953..c6e71c11f 100644
--- a/internal/data/database.go
+++ b/internal/data/database.go
@@ -1,18 +1,25 @@
package data
import (
+ "fmt"
+
"github.com/TheTNB/panel/internal/app"
"github.com/TheTNB/panel/internal/biz"
"github.com/TheTNB/panel/internal/http/request"
+ "github.com/TheTNB/panel/pkg/db"
)
-type databaseRepo struct{}
-
-func NewDatabaseRepo() biz.DatabaseRepo {
- return &databaseRepo{}
+type databaseRepo struct {
+ databaseServer biz.DatabaseServerRepo
}
-func (d databaseRepo) Count() (int64, error) {
+func NewDatabaseRepo() biz.DatabaseRepo {
+ return &databaseRepo{
+ databaseServer: NewDatabaseServerRepo(),
+ }
+}
+
+func (r databaseRepo) Count() (int64, error) {
var count int64
if err := app.Orm.Model(&biz.Database{}).Count(&count).Error; err != nil {
return 0, err
@@ -21,14 +28,14 @@ func (d databaseRepo) Count() (int64, error) {
return count, nil
}
-func (d databaseRepo) List(page, limit uint) ([]*biz.Database, int64, error) {
+func (r databaseRepo) List(page, limit uint) ([]*biz.Database, int64, error) {
var database []*biz.Database
var total int64
err := app.Orm.Model(&biz.Database{}).Order("id desc").Count(&total).Offset(int((page - 1) * limit)).Limit(int(limit)).Find(&database).Error
return database, total, err
}
-func (d databaseRepo) Get(id uint) (*biz.Database, error) {
+func (r databaseRepo) Get(id uint) (*biz.Database, error) {
database := new(biz.Database)
if err := app.Orm.Where("id = ?", id).First(database).Error; err != nil {
return nil, err
@@ -37,7 +44,43 @@ func (d databaseRepo) Get(id uint) (*biz.Database, error) {
return database, nil
}
-func (d databaseRepo) Create(req *request.DatabaseCreate) error {
+func (r databaseRepo) Create(req *request.DatabaseCreate) error {
+ server, err := r.databaseServer.Get(req.ServerID)
+ if err != nil {
+ return err
+ }
+
+ switch server.Type {
+ case biz.DatabaseTypeMysql:
+ mysql, err := db.NewMySQL(server.Username, server.Password, fmt.Sprintf("%s:%d", server.Host, server.Port))
+ if err != nil {
+ return err
+ }
+ if err = mysql.UserCreate(req.Username, req.Password); err != nil {
+ return err
+ }
+ if err = mysql.DatabaseCreate(req.Name); err != nil {
+ return err
+ }
+ if err = mysql.PrivilegesGrant(req.Username, req.Name); err != nil {
+ return err
+ }
+ case biz.DatabaseTypePostgresql:
+ postgres, err := db.NewPostgres(server.Username, server.Password, server.Host, server.Port)
+ if err != nil {
+ return err
+ }
+ if err = postgres.UserCreate(req.Username, req.Password); err != nil {
+ return err
+ }
+ if err = postgres.DatabaseCreate(req.Name); err != nil {
+ return err
+ }
+ if err = postgres.PrivilegesGrant(req.Username, req.Name); err != nil {
+ return err
+ }
+ }
+
database := &biz.Database{
Name: req.Name,
Username: req.Username,
@@ -50,7 +93,7 @@ func (d databaseRepo) Create(req *request.DatabaseCreate) error {
return app.Orm.Create(database).Error
}
-func (d databaseRepo) Update(req *request.DatabaseUpdate) error {
+func (r databaseRepo) Update(req *request.DatabaseUpdate) error {
database := &biz.Database{
Name: req.Name,
Username: req.Username,
@@ -61,6 +104,6 @@ func (d databaseRepo) Update(req *request.DatabaseUpdate) error {
return app.Orm.Model(database).Where("id = ?", req.ID).Omit("ServerID").Updates(database).Error
}
-func (d databaseRepo) Delete(id uint) error {
+func (r databaseRepo) Delete(id uint) error {
return app.Orm.Delete(&biz.Database{}, id).Error
}
diff --git a/internal/data/database_server.go b/internal/data/database_server.go
index 2b47617be..78b4a8eef 100644
--- a/internal/data/database_server.go
+++ b/internal/data/database_server.go
@@ -18,7 +18,7 @@ func NewDatabaseServerRepo() biz.DatabaseServerRepo {
return &databaseServerRepo{}
}
-func (d databaseServerRepo) Count() (int64, error) {
+func (r databaseServerRepo) Count() (int64, error) {
var count int64
if err := app.Orm.Model(&biz.DatabaseServer{}).Count(&count).Error; err != nil {
return 0, err
@@ -27,14 +27,14 @@ func (d databaseServerRepo) Count() (int64, error) {
return count, nil
}
-func (d databaseServerRepo) List(page, limit uint) ([]*biz.DatabaseServer, int64, error) {
+func (r databaseServerRepo) List(page, limit uint) ([]*biz.DatabaseServer, int64, error) {
var databaseServer []*biz.DatabaseServer
var total int64
err := app.Orm.Model(&biz.DatabaseServer{}).Order("id desc").Count(&total).Offset(int((page - 1) * limit)).Limit(int(limit)).Find(&databaseServer).Error
return databaseServer, total, err
}
-func (d databaseServerRepo) Get(id uint) (*biz.DatabaseServer, error) {
+func (r databaseServerRepo) Get(id uint) (*biz.DatabaseServer, error) {
databaseServer := new(biz.DatabaseServer)
if err := app.Orm.Where("id = ?", id).First(databaseServer).Error; err != nil {
return nil, err
@@ -43,14 +43,14 @@ func (d databaseServerRepo) Get(id uint) (*biz.DatabaseServer, error) {
return databaseServer, nil
}
-func (d databaseServerRepo) Create(req *request.DatabaseServerCreate) error {
+func (r databaseServerRepo) Create(req *request.DatabaseServerCreate) error {
switch biz.DatabaseType(req.Type) {
case biz.DatabaseTypeMysql:
if _, err := db.NewMySQL(req.Username, req.Password, fmt.Sprintf("%s:%d", req.Host, req.Port)); err != nil {
return err
}
case biz.DatabaseTypePostgresql:
- if _, err := db.NewPostgres(req.Username, req.Password, req.Host, req.Port, ""); err != nil {
+ if _, err := db.NewPostgres(req.Username, req.Password, req.Host, req.Port); err != nil {
return err
}
case biz.DatabaseTypeRedis:
@@ -73,18 +73,18 @@ func (d databaseServerRepo) Create(req *request.DatabaseServerCreate) error {
return app.Orm.Create(databaseServer).Error
}
-func (d databaseServerRepo) Update(req *request.DatabaseServerUpdate) error {
+func (r databaseServerRepo) Update(req *request.DatabaseServerUpdate) error {
switch biz.DatabaseType(req.Type) {
case biz.DatabaseTypeMysql:
- if _, err := db.NewMySQL(req.Username, req.Password, fmt.Sprintf("%s:%d", req.Host, req.Port)); err != nil {
+ if _, err := db.NewMySQL(req.Username, req.Password, fmt.Sprintf("%s:%r", req.Host, req.Port)); err != nil {
return err
}
case biz.DatabaseTypePostgresql:
- if _, err := db.NewPostgres(req.Username, req.Password, req.Host, req.Port, ""); err != nil {
+ if _, err := db.NewPostgres(req.Username, req.Password, req.Host, req.Port); err != nil {
return err
}
case biz.DatabaseTypeRedis:
- if _, err := db.NewRedis(req.Username, req.Password, fmt.Sprintf("%s:%d", req.Host, req.Port)); err != nil {
+ if _, err := db.NewRedis(req.Username, req.Password, fmt.Sprintf("%s:%r", req.Host, req.Port)); err != nil {
return err
}
@@ -101,7 +101,7 @@ func (d databaseServerRepo) Update(req *request.DatabaseServerUpdate) error {
}).Error
}
-func (d databaseServerRepo) Delete(id uint) error {
+func (r databaseServerRepo) Delete(id uint) error {
ds := new(biz.DatabaseServer)
if err := app.Orm.Where("id = ?", id).First(ds).Error; err != nil {
return err
@@ -113,3 +113,46 @@ func (d databaseServerRepo) Delete(id uint) error {
return app.Orm.Delete(&biz.DatabaseServer{}, id).Error
}
+
+func (r databaseServerRepo) Sync(id uint) error {
+ /*server, err := r.Get(id)
+ if err != nil {
+ return err
+ }
+
+ switch server.Type {
+ case biz.DatabaseTypeMysql:
+ mysql, err := db.NewMySQL(server.Username, server.Password, fmt.Sprintf("%s:%d", server.Host, server.Port))
+ if err != nil {
+ return err
+ }
+ databases, err := mysql.Databases()
+ if err != nil {
+ return err
+ }
+ for database := range slices.Values(databases) {
+ db := &biz.Database{
+ Name: database.Name,
+ Username: server.Username,
+ Password: server.Password,
+ ServerID: server.ID,
+ Status: biz.DatabaseStatusInvalid,
+ }
+ if err := app.Orm.Where("name = ? AND server_id = ?", database.Name, server.ID).First(db).Error; err != nil {
+ app.Orm.Create(db)
+ }
+ }
+
+ case biz.DatabaseTypePostgresql:
+ postgres, err := db.NewPostgres(server.Username, server.Password, server.Host, server.Port)
+ if err != nil {
+ return err
+ }
+ databases, err := postgres.Databases()
+ if err != nil {
+ return err
+ }
+ }*/
+
+ return nil
+}
diff --git a/internal/data/website.go b/internal/data/website.go
index 8f72109eb..e60b238f6 100644
--- a/internal/data/website.go
+++ b/internal/data/website.go
@@ -307,10 +307,10 @@ func (r *websiteRepo) Create(req *request.WebsiteCreate) (*biz.Website, error) {
if err != nil {
return nil, err
}
- if err = mysql.DatabaseCreate(req.DBName); err != nil {
+ if err = mysql.UserCreate(req.DBUser, req.DBPassword); err != nil {
return nil, err
}
- if err = mysql.UserCreate(req.DBUser, req.DBPassword); err != nil {
+ if err = mysql.DatabaseCreate(req.DBName); err != nil {
return nil, err
}
if err = mysql.PrivilegesGrant(req.DBUser, req.DBName); err != nil {
@@ -318,20 +318,17 @@ func (r *websiteRepo) Create(req *request.WebsiteCreate) (*biz.Website, error) {
}
}
if req.DB && req.DBType == "postgresql" {
- postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432, fmt.Sprintf("%s/server/postgresql/data/pg_hba.conf", app.Root))
+ postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432)
if err != nil {
return nil, err
}
- if err = postgres.DatabaseCreate(req.DBName); err != nil {
- return nil, err
- }
if err = postgres.UserCreate(req.DBUser, req.DBPassword); err != nil {
return nil, err
}
- if err = postgres.PrivilegesGrant(req.DBUser, req.DBName); err != nil {
+ if err = postgres.DatabaseCreate(req.DBName); err != nil {
return nil, err
}
- if err = postgres.HostAdd(req.DBName, req.DBUser, "127.0.0.1/32"); err != nil {
+ if err = postgres.PrivilegesGrant(req.DBUser, req.DBName); err != nil {
return nil, err
}
}
@@ -526,13 +523,14 @@ func (r *websiteRepo) Delete(req *request.WebsiteDelete) error {
if err != nil {
return err
}
- mysql, err := db.NewMySQL("root", rootPassword, "/tmp/mysql.sock", "unix")
- if err == nil {
- _ = mysql.DatabaseDrop(website.Name)
+ if mysql, err := db.NewMySQL("root", rootPassword, "/tmp/mysql.sock", "unix"); err == nil {
_ = mysql.UserDrop(website.Name)
+ _ = mysql.DatabaseDrop(website.Name)
+ }
+ if postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432); err == nil {
+ _ = postgres.UserDrop(website.Name)
+ _ = postgres.DatabaseDrop(website.Name)
}
- _, _ = shell.Execf(`echo "DROP DATABASE IF EXISTS '%s';" | su - postgres -c "psql"`, website.Name)
- _, _ = shell.Execf(`echo "DROP USER IF EXISTS '%s';" | su - postgres -c "psql"`, website.Name)
}
if err := app.Orm.Delete(website).Error; err != nil {
diff --git a/internal/route/http.go b/internal/route/http.go
index 8d4f0205f..b6b7ef34e 100644
--- a/internal/route/http.go
+++ b/internal/route/http.go
@@ -71,7 +71,7 @@ func Http(r chi.Router) {
})
r.Route("/databaseServer", func(r chi.Router) {
- database := service.NewDatabaseService()
+ database := service.NewDatabaseServerService()
r.Get("/", database.List)
r.Post("/", database.Create)
r.Put("/{id}", database.Update)
diff --git a/internal/service/dashboard.go b/internal/service/dashboard.go
index 3a1285703..69058ff00 100644
--- a/internal/service/dashboard.go
+++ b/internal/service/dashboard.go
@@ -140,7 +140,7 @@ func (s *DashboardService) CountInfo(w http.ResponseWriter, r *http.Request) {
}
}
if postgresqlInstalled {
- postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432, fmt.Sprintf("%s/server/postgresql/data/pg_hba.conf", app.Root))
+ postgres, err := db.NewPostgres("postgres", "", "127.0.0.1", 5432)
if err == nil {
defer postgres.Close()
databases, err := postgres.Databases()
diff --git a/internal/service/database_server.go b/internal/service/database_server.go
index e2bbe5198..7f5eaada0 100644
--- a/internal/service/database_server.go
+++ b/internal/service/database_server.go
@@ -83,3 +83,18 @@ func (s *DatabaseServer) Delete(w http.ResponseWriter, r *http.Request) {
Success(w, nil)
}
+
+func (s *DatabaseServer) Sync(w http.ResponseWriter, r *http.Request) {
+ req, err := Bind[request.ID](r)
+ if err != nil {
+ Error(w, http.StatusUnprocessableEntity, "%v", err)
+ return
+ }
+
+ if err = s.databaseServerRepo.Sync(req.ID); err != nil {
+ Error(w, http.StatusInternalServerError, "%v", err)
+ return
+ }
+
+ Success(w, nil)
+}
diff --git a/pkg/db/postgres.go b/pkg/db/postgres.go
index fd8d26fb1..6031251ed 100644
--- a/pkg/db/postgres.go
+++ b/pkg/db/postgres.go
@@ -6,8 +6,6 @@ import (
_ "github.com/lib/pq"
- "github.com/TheTNB/panel/pkg/io"
- "github.com/TheTNB/panel/pkg/shell"
"github.com/TheTNB/panel/pkg/systemctl"
"github.com/TheTNB/panel/pkg/types"
)
@@ -17,13 +15,15 @@ type Postgres struct {
username string
password string
address string
- hbaFile string
port uint
}
-func NewPostgres(username, password, address string, port uint, hbaFile string) (*Postgres, error) {
+func NewPostgres(username, password, address string, port uint) (*Postgres, error) {
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=postgres sslmode=disable", address, port, username, password)
if password == "" {
+ if username == "" {
+ username = "postgres"
+ }
dsn = fmt.Sprintf("host=%s port=%d user=%s dbname=postgres sslmode=disable", address, port, username)
}
db, err := sql.Open("postgres", dsn)
@@ -38,7 +38,6 @@ func NewPostgres(username, password, address string, port uint, hbaFile string)
username: username,
password: password,
address: address,
- hbaFile: hbaFile,
port: port,
}, nil
}
@@ -109,7 +108,6 @@ func (m *Postgres) UserDrop(user string) error {
return err
}
- _, _ = shell.Execf(`sed -i '/%s/d' %s`, user, m.hbaFile)
return systemctl.Reload("postgresql")
}
@@ -134,24 +132,6 @@ func (m *Postgres) PrivilegesRevoke(user, database string) error {
return err
}
-func (m *Postgres) HostAdd(database, user, host string) error {
- config := fmt.Sprintf("host %s %s %s scram-sha-256", database, user, host)
- if err := io.WriteAppend(m.hbaFile, config, 0644); err != nil {
- return err
- }
-
- return systemctl.Reload("postgresql")
-}
-
-func (m *Postgres) HostRemove(database, user, host string) error {
- regex := fmt.Sprintf(`host\s+%s\s+%s\s+%s`, database, user, host)
- if _, err := shell.Execf(`sed -i '/%s/d' %s`, regex, m.hbaFile); err != nil {
- return err
- }
-
- return systemctl.Reload("postgresql")
-}
-
func (m *Postgres) Users() ([]types.PostgresUser, error) {
query := `
SELECT rolname,
diff --git a/web/src/api/panel/database/index.ts b/web/src/api/panel/database/index.ts
index 72e9560c7..6b885f0d2 100644
--- a/web/src/api/panel/database/index.ts
+++ b/web/src/api/panel/database/index.ts
@@ -11,11 +11,11 @@ export default {
delete: (id: number) => http.Delete(`/database/${id}`),
// 获取数据库服务器列表
serverList: (page: number, limit: number) =>
- http.Get('/database/serverList', { params: { page, limit } }),
+ http.Get('/databaseServer', { params: { page, limit } }),
// 创建数据库服务器
- createServer: (data: any) => http.Post('/database/server', data),
+ createServer: (data: any) => http.Post('/databaseServer', data),
// 更新数据库服务器
- updateServer: (id: number, data: any) => http.Put(`/database/server/${id}`, data),
+ updateServer: (id: number, data: any) => http.Put(`/databaseServer/${id}`, data),
// 删除数据库服务器
- deleteServer: (id: number) => http.Delete(`/database/server/${id}`)
+ deleteServer: (id: number) => http.Delete(`/databaseServer/${id}`)
}
diff --git a/web/src/utils/http/index.ts b/web/src/utils/http/index.ts
index 785898052..85aa15d00 100644
--- a/web/src/utils/http/index.ts
+++ b/web/src/utils/http/index.ts
@@ -24,6 +24,8 @@ export const request = createAxios({
})
export const http = createAlova({
+ id: 'panel',
+ cacheFor: null,
statesHook: VueHook,
requestAdapter: adapterFetch(),
baseURL: import.meta.env.VITE_BASE_API,
diff --git a/web/src/views/database/CreateDatabaseModal.vue b/web/src/views/database/CreateDatabaseModal.vue
new file mode 100644
index 000000000..13f42cc08
--- /dev/null
+++ b/web/src/views/database/CreateDatabaseModal.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
diff --git a/web/src/views/database/CreateServerModal.vue b/web/src/views/database/CreateServerModal.vue
new file mode 100644
index 000000000..10018f013
--- /dev/null
+++ b/web/src/views/database/CreateServerModal.vue
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
diff --git a/web/src/views/database/DatabaseListView.vue b/web/src/views/database/DatabaseListView.vue
new file mode 100644
index 000000000..a0cb7ff9e
--- /dev/null
+++ b/web/src/views/database/DatabaseListView.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
diff --git a/web/src/views/database/IndexView.vue b/web/src/views/database/IndexView.vue
new file mode 100644
index 000000000..54f5b6f7c
--- /dev/null
+++ b/web/src/views/database/IndexView.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+ 创建数据库
+
+
+
+
+ 同步数据库
+
+
+
+ 添加服务器
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/views/database/ServerListView.vue b/web/src/views/database/ServerListView.vue
new file mode 100644
index 000000000..a0cb7ff9e
--- /dev/null
+++ b/web/src/views/database/ServerListView.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
diff --git a/web/src/views/database/route.ts b/web/src/views/database/route.ts
new file mode 100644
index 000000000..a097198e4
--- /dev/null
+++ b/web/src/views/database/route.ts
@@ -0,0 +1,25 @@
+import type { RouteType } from '~/types/router'
+
+const Layout = () => import('@/layout/IndexView.vue')
+
+export default {
+ name: 'database',
+ path: '/database',
+ component: Layout,
+ meta: {
+ order: 2
+ },
+ children: [
+ {
+ name: 'database-index',
+ path: '',
+ component: () => import('./IndexView.vue'),
+ meta: {
+ title: '数据库',
+ icon: 'mdi:database',
+ role: ['admin'],
+ requireAuth: true
+ }
+ }
+ ]
+} as RouteType