From 73cc5a35add993d5ecb12c80360d55fde747f460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Thu, 30 May 2024 01:58:17 +0800 Subject: [PATCH] refactor: move types --- app/console/commands/cert_renew.go | 4 +- app/console/commands/monitoring.go | 8 +- app/console/commands/panel.go | 10 +- app/console/commands/panel_task.go | 12 +- app/http/controllers/info_controller.go | 7 +- .../controllers/plugins/mysql_controller.go | 5 +- .../plugins/postgresql15_controller.go | 4 +- .../plugins/postgresql16_controller.go | 4 +- app/http/controllers/website_controller.go | 11 +- app/http/middleware/status.go | 12 +- docs/docs.go | 222 +++++++++--------- docs/swagger.json | 222 +++++++++--------- docs/swagger.yaml | 162 ++++++------- internal/backup.go | 16 +- internal/php.go | 9 +- internal/plugin.go | 22 +- internal/plugin_list.go | 40 ++-- internal/services/backup.go | 37 +-- internal/services/php.go | 13 +- internal/services/plugin.go | 9 +- internal/services/website.go | 17 +- internal/website.go | 52 +--- types/backup.go | 6 + types/php.go | 8 + types/plugin.go | 14 ++ {internal => types}/status.go | 2 +- types/website.go | 46 ++++ 27 files changed, 496 insertions(+), 478 deletions(-) create mode 100644 types/backup.go create mode 100644 types/php.go create mode 100644 types/plugin.go rename {internal => types}/status.go (89%) create mode 100644 types/website.go diff --git a/app/console/commands/cert_renew.go b/app/console/commands/cert_renew.go index 25c3ded6..2b8dde03 100644 --- a/app/console/commands/cert_renew.go +++ b/app/console/commands/cert_renew.go @@ -11,8 +11,8 @@ import ( "github.com/goravel/framework/support/carbon" "github.com/TheTNB/panel/app/models" - "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/types" ) // CertRenew 证书续签 @@ -39,7 +39,7 @@ func (receiver *CertRenew) Extend() command.Extend { // Handle Execute the console command. func (receiver *CertRenew) Handle(console.Context) error { - if internal.Status != internal.StatusNormal { + if types.Status != types.StatusNormal { return nil } diff --git a/app/console/commands/monitoring.go b/app/console/commands/monitoring.go index 1eabb0a4..a316b252 100644 --- a/app/console/commands/monitoring.go +++ b/app/console/commands/monitoring.go @@ -11,9 +11,9 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/models" - "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) // Monitoring 系统监控 @@ -40,7 +40,7 @@ func (receiver *Monitoring) Extend() command.Extend { // Handle Execute the console command. func (receiver *Monitoring) Handle(console.Context) error { - if internal.Status != internal.StatusNormal { + if types.Status != types.StatusNormal { return nil } @@ -68,7 +68,7 @@ func (receiver *Monitoring) Handle(console.Context) error { cpu.Flags = nil } - if internal.Status != internal.StatusNormal { + if types.Status != types.StatusNormal { return nil } err := facades.Orm().Query().Create(&models.Monitor{ @@ -82,7 +82,7 @@ func (receiver *Monitoring) Handle(console.Context) error { // 删除过期数据 days := cast.ToInt(setting.Get(models.SettingKeyMonitorDays)) - if days <= 0 || internal.Status != internal.StatusNormal { + if days <= 0 || types.Status != types.StatusNormal { return nil } if _, err = facades.Orm().Query().Where("created_at < ?", carbon.Now().SubDays(days).ToDateTimeString()).Delete(&models.Monitor{}); err != nil { diff --git a/app/console/commands/panel.go b/app/console/commands/panel.go index 85c647ca..4f60b188 100644 --- a/app/console/commands/panel.go +++ b/app/console/commands/panel.go @@ -16,9 +16,9 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/models" - "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) // Panel 面板命令行 @@ -99,14 +99,14 @@ func (receiver *Panel) Handle(ctx console.Context) error { return err } - internal.Status = internal.StatusUpgrade + types.Status = types.StatusUpgrade if err = tools.UpdatePanel(panel); err != nil { - internal.Status = internal.StatusFailed + types.Status = types.StatusFailed color.Red().Printfln(translate.Get("commands.panel.update.fail") + ": " + err.Error()) return nil } - internal.Status = internal.StatusNormal + types.Status = types.StatusNormal color.Green().Printfln(translate.Get("commands.panel.update.success")) tools.RestartPanel() @@ -603,7 +603,7 @@ func (receiver *Panel) Handle(ctx console.Context) error { return nil } - _, err = website.Add(internal.PanelWebsite{ + _, err = website.Add(types.Website{ Name: name, Status: true, Domains: domains, diff --git a/app/console/commands/panel_task.go b/app/console/commands/panel_task.go index 3498fd56..da101998 100644 --- a/app/console/commands/panel_task.go +++ b/app/console/commands/panel_task.go @@ -8,8 +8,8 @@ import ( "github.com/goravel/framework/facades" "github.com/goravel/framework/support/carbon" - "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) // PanelTask 面板每日任务 @@ -35,11 +35,11 @@ func (receiver *PanelTask) Extend() command.Extend { // Handle Execute the console command. func (receiver *PanelTask) Handle(console.Context) error { - internal.Status = internal.StatusMaintain + types.Status = types.StatusMaintain // 优化数据库 if _, err := facades.Orm().Query().Exec("VACUUM"); err != nil { - internal.Status = internal.StatusFailed + types.Status = types.StatusFailed facades.Log().Tags("面板", "每日任务"). With(map[string]any{ "error": err.Error(), @@ -49,7 +49,7 @@ func (receiver *PanelTask) Handle(console.Context) error { // 备份面板 if err := tools.Archive([]string{"/www/panel"}, "/www/backup/panel/panel-"+carbon.Now().ToShortDateTimeString()+".zip"); err != nil { - internal.Status = internal.StatusFailed + types.Status = types.StatusFailed facades.Log().Tags("面板", "每日任务"). With(map[string]any{ "error": err.Error(), @@ -59,7 +59,7 @@ func (receiver *PanelTask) Handle(console.Context) error { // 清理 7 天前的备份 if _, err := tools.Exec(`find /www/backup/panel -mtime +7 -name "*.zip" -exec rm -rf {} \;`); err != nil { - internal.Status = internal.StatusFailed + types.Status = types.StatusFailed facades.Log().Tags("面板", "每日任务"). With(map[string]any{ "error": err.Error(), @@ -67,6 +67,6 @@ func (receiver *PanelTask) Handle(console.Context) error { return err } - internal.Status = internal.StatusNormal + types.Status = types.StatusNormal return nil } diff --git a/app/http/controllers/info_controller.go b/app/http/controllers/info_controller.go index fe88f3f4..90191563 100644 --- a/app/http/controllers/info_controller.go +++ b/app/http/controllers/info_controller.go @@ -13,6 +13,7 @@ import ( "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) type MenuItem struct { @@ -310,16 +311,16 @@ func (r *InfoController) Update(ctx http.Context) http.Response { return Error(ctx, http.StatusInternalServerError, "获取最新版本失败") } - internal.Status = internal.StatusUpgrade + types.Status = types.StatusUpgrade if err = tools.UpdatePanel(panel); err != nil { - internal.Status = internal.StatusFailed + types.Status = types.StatusFailed facades.Log().Request(ctx.Request()).Tags("面板", "基础信息").With(map[string]any{ "error": err.Error(), }).Info("更新面板失败") return Error(ctx, http.StatusInternalServerError, err.Error()) } - internal.Status = internal.StatusNormal + types.Status = types.StatusNormal tools.RestartPanel() return Success(ctx, nil) } diff --git a/app/http/controllers/plugins/mysql_controller.go b/app/http/controllers/plugins/mysql_controller.go index 94139cd4..362de216 100644 --- a/app/http/controllers/plugins/mysql_controller.go +++ b/app/http/controllers/plugins/mysql_controller.go @@ -13,6 +13,7 @@ import ( "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) type MySQLController struct { @@ -377,7 +378,7 @@ func (r *MySQLController) BackupList(ctx http.Context) http.Response { if startIndex > len(backupList) { return controllers.Success(ctx, http.Json{ "total": 0, - "items": []internal.BackupFile{}, + "items": []types.BackupFile{}, }) } if endIndex > len(backupList) { @@ -385,7 +386,7 @@ func (r *MySQLController) BackupList(ctx http.Context) http.Response { } pagedBackupList := backupList[startIndex:endIndex] if pagedBackupList == nil { - pagedBackupList = []internal.BackupFile{} + pagedBackupList = []types.BackupFile{} } return controllers.Success(ctx, http.Json{ diff --git a/app/http/controllers/plugins/postgresql15_controller.go b/app/http/controllers/plugins/postgresql15_controller.go index 0db07631..57eee514 100644 --- a/app/http/controllers/plugins/postgresql15_controller.go +++ b/app/http/controllers/plugins/postgresql15_controller.go @@ -321,7 +321,7 @@ func (r *Postgresql15Controller) BackupList(ctx http.Context) http.Response { if startIndex > len(backupList) { return controllers.Success(ctx, http.Json{ "total": 0, - "items": []internal.BackupFile{}, + "items": []types.BackupFile{}, }) } if endIndex > len(backupList) { @@ -329,7 +329,7 @@ func (r *Postgresql15Controller) BackupList(ctx http.Context) http.Response { } pagedBackupList := backupList[startIndex:endIndex] if pagedBackupList == nil { - pagedBackupList = []internal.BackupFile{} + pagedBackupList = []types.BackupFile{} } return controllers.Success(ctx, http.Json{ diff --git a/app/http/controllers/plugins/postgresql16_controller.go b/app/http/controllers/plugins/postgresql16_controller.go index b01c4501..46173a16 100644 --- a/app/http/controllers/plugins/postgresql16_controller.go +++ b/app/http/controllers/plugins/postgresql16_controller.go @@ -321,7 +321,7 @@ func (r *Postgresql16Controller) BackupList(ctx http.Context) http.Response { if startIndex > len(backupList) { return controllers.Success(ctx, http.Json{ "total": 0, - "items": []internal.BackupFile{}, + "items": []types.BackupFile{}, }) } if endIndex > len(backupList) { @@ -329,7 +329,7 @@ func (r *Postgresql16Controller) BackupList(ctx http.Context) http.Response { } pagedBackupList := backupList[startIndex:endIndex] if pagedBackupList == nil { - pagedBackupList = []internal.BackupFile{} + pagedBackupList = []types.BackupFile{} } return controllers.Success(ctx, http.Json{ diff --git a/app/http/controllers/website_controller.go b/app/http/controllers/website_controller.go index 81d93aad..a43b331f 100644 --- a/app/http/controllers/website_controller.go +++ b/app/http/controllers/website_controller.go @@ -14,6 +14,7 @@ import ( "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) type WebsiteController struct { @@ -83,7 +84,7 @@ func (r *WebsiteController) Add(ctx http.Context) http.Response { addRequest.Path = r.setting.Get(models.SettingKeyWebsitePath) + "/" + addRequest.Name } - website := internal.PanelWebsite{ + website := types.Website{ Name: addRequest.Name, Status: true, Domains: addRequest.Domains, @@ -205,7 +206,7 @@ func (r *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response { // @Produce json // @Security BearerToken // @Param id path int true "网站 ID" -// @Success 200 {object} SuccessResponse{data=internal.PanelWebsite} +// @Success 200 {object} SuccessResponse{data=types.Website} // @Router /panel/websites/{id}/config [get] func (r *WebsiteController) GetConfig(ctx http.Context) http.Response { var idRequest requests.ID @@ -328,7 +329,7 @@ func (r *WebsiteController) UpdateRemark(ctx http.Context) http.Response { // @Produce json // @Security BearerToken // @Param data query commonrequests.Paginate true "request" -// @Success 200 {object} SuccessResponse{data=[]internal.BackupFile} +// @Success 200 {object} SuccessResponse{data=[]types.BackupFile} // @Router /panel/website/backupList [get] func (r *WebsiteController) BackupList(ctx http.Context) http.Response { var paginateRequest commonrequests.Paginate @@ -350,7 +351,7 @@ func (r *WebsiteController) BackupList(ctx http.Context) http.Response { if startIndex > len(backupList) { return Success(ctx, http.Json{ "total": 0, - "items": []internal.BackupFile{}, + "items": []types.BackupFile{}, }) } if endIndex > len(backupList) { @@ -358,7 +359,7 @@ func (r *WebsiteController) BackupList(ctx http.Context) http.Response { } pagedBackupList := backupList[startIndex:endIndex] if pagedBackupList == nil { - pagedBackupList = []internal.BackupFile{} + pagedBackupList = []types.BackupFile{} } return Success(ctx, http.Json{ diff --git a/app/http/middleware/status.go b/app/http/middleware/status.go index bee33cb7..9613f488 100644 --- a/app/http/middleware/status.go +++ b/app/http/middleware/status.go @@ -4,30 +4,30 @@ import ( "github.com/goravel/framework/contracts/http" "github.com/goravel/framework/facades" - "github.com/TheTNB/panel/internal" + "github.com/TheTNB/panel/types" ) // Status 检查程序状态 func Status() http.Middleware { return func(ctx http.Context) { translate := facades.Lang(ctx) - switch internal.Status { - case internal.StatusUpgrade: + switch types.Status { + case types.StatusUpgrade: ctx.Request().AbortWithStatusJson(http.StatusServiceUnavailable, http.Json{ "message": translate.Get("status.upgrade"), }) return - case internal.StatusMaintain: + case types.StatusMaintain: ctx.Request().AbortWithStatusJson(http.StatusServiceUnavailable, http.Json{ "message": translate.Get("status.maintain"), }) return - case internal.StatusClosed: + case types.StatusClosed: ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{ "message": translate.Get("status.closed"), }) return - case internal.StatusFailed: + case types.StatusFailed: ctx.Request().AbortWithStatusJson(http.StatusInternalServerError, http.Json{ "message": translate.Get("status.failed"), }) diff --git a/docs/docs.go b/docs/docs.go index 9dedea14..49e87fce 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -11,7 +11,7 @@ const docTemplate = `{ "title": "{{.Title}}", "contact": { "name": "耗子科技", - "email": "i@haozi.net" + "email": "admin@haozi.net" }, "license": { "name": "GNU Affero General Public License v3" @@ -1122,7 +1122,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1190,7 +1190,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1538,7 +1538,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1599,7 +1599,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1671,7 +1671,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1741,7 +1741,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1809,7 +1809,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1845,7 +1845,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -2046,7 +2046,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -2693,7 +2693,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_setting.Update" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_setting.Update" } } ], @@ -2819,7 +2819,7 @@ const docTemplate = `{ "data": { "type": "array", "items": { - "$ref": "#/definitions/internal.BackupFile" + "$ref": "#/definitions/types.BackupFile" } } } @@ -3136,7 +3136,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/internal.PanelWebsite" + "$ref": "#/definitions/types.Website" } } } @@ -3571,7 +3571,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_plugins_rsync.Update" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_plugins_rsync.Update" } } ], @@ -3784,64 +3784,69 @@ const docTemplate = `{ } } }, - "internal.BackupFile": { + "github_com_TheTNB_panel_app_http_requests_container.ID": { "type": "object", "properties": { - "name": { - "type": "string" - }, - "size": { + "id": { "type": "string" } } }, - "internal.PanelWebsite": { + "github_com_TheTNB_panel_app_http_requests_plugins_rsync.Update": { "type": "object", "properties": { - "db": { - "type": "boolean" - }, - "db_name": { + "auth_user": { "type": "string" }, - "db_password": { + "comment": { "type": "string" }, - "db_type": { + "hosts_allow": { "type": "string" }, - "db_user": { - "type": "string" - }, - "domains": { - "type": "array", - "items": { - "type": "string" - } - }, "name": { "type": "string" }, "path": { "type": "string" }, - "php": { + "secret": { + "type": "string" + } + } + }, + "github_com_TheTNB_panel_app_http_requests_setting.Update": { + "type": "object", + "properties": { + "backup_path": { "type": "string" }, - "ports": { - "type": "array", - "items": { - "type": "integer" - } - }, - "remark": { + "email": { "type": "string" }, + "entrance": { + "type": "string" + }, + "language": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, "ssl": { "type": "boolean" }, - "status": { - "type": "boolean" + "username": { + "type": "string" + }, + "website_path": { + "type": "string" } } }, @@ -3999,72 +4004,6 @@ const docTemplate = `{ } } }, - "panel_app_http_requests_container.ID": { - "type": "object", - "properties": { - "id": { - "type": "string" - } - } - }, - "panel_app_http_requests_plugins_rsync.Update": { - "type": "object", - "properties": { - "auth_user": { - "type": "string" - }, - "comment": { - "type": "string" - }, - "hosts_allow": { - "type": "string" - }, - "name": { - "type": "string" - }, - "path": { - "type": "string" - }, - "secret": { - "type": "string" - } - } - }, - "panel_app_http_requests_setting.Update": { - "type": "object", - "properties": { - "backup_path": { - "type": "string" - }, - "email": { - "type": "string" - }, - "entrance": { - "type": "string" - }, - "language": { - "type": "string" - }, - "name": { - "type": "string" - }, - "password": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "ssl": { - "type": "boolean" - }, - "username": { - "type": "string" - }, - "website_path": { - "type": "string" - } - } - }, "requests.Add": { "type": "object", "properties": { @@ -4650,6 +4589,17 @@ const docTemplate = `{ } } }, + "types.BackupFile": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "size": { + "type": "string" + } + } + }, "types.ContainerNetwork": { "type": "object", "properties": { @@ -4714,6 +4664,56 @@ const docTemplate = `{ "type": "string" } } + }, + "types.Website": { + "type": "object", + "properties": { + "db": { + "type": "boolean" + }, + "db_name": { + "type": "string" + }, + "db_password": { + "type": "string" + }, + "db_type": { + "type": "string" + }, + "db_user": { + "type": "string" + }, + "domains": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "php": { + "type": "string" + }, + "ports": { + "type": "array", + "items": { + "type": "integer" + } + }, + "remark": { + "type": "string" + }, + "ssl": { + "type": "boolean" + }, + "status": { + "type": "boolean" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.json b/docs/swagger.json index 1b68b31e..c5167a06 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -5,7 +5,7 @@ "title": "耗子 Linux 面板 API", "contact": { "name": "耗子科技", - "email": "i@haozi.net" + "email": "admin@haozi.net" }, "license": { "name": "GNU Affero General Public License v3" @@ -1115,7 +1115,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1183,7 +1183,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1531,7 +1531,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1592,7 +1592,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1664,7 +1664,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1734,7 +1734,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1802,7 +1802,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -1838,7 +1838,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -2039,7 +2039,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_container.ID" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID" } } ], @@ -2686,7 +2686,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_setting.Update" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_setting.Update" } } ], @@ -2812,7 +2812,7 @@ "data": { "type": "array", "items": { - "$ref": "#/definitions/internal.BackupFile" + "$ref": "#/definitions/types.BackupFile" } } } @@ -3129,7 +3129,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/internal.PanelWebsite" + "$ref": "#/definitions/types.Website" } } } @@ -3564,7 +3564,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/panel_app_http_requests_plugins_rsync.Update" + "$ref": "#/definitions/github_com_TheTNB_panel_app_http_requests_plugins_rsync.Update" } } ], @@ -3777,64 +3777,69 @@ } } }, - "internal.BackupFile": { + "github_com_TheTNB_panel_app_http_requests_container.ID": { "type": "object", "properties": { - "name": { - "type": "string" - }, - "size": { + "id": { "type": "string" } } }, - "internal.PanelWebsite": { + "github_com_TheTNB_panel_app_http_requests_plugins_rsync.Update": { "type": "object", "properties": { - "db": { - "type": "boolean" - }, - "db_name": { + "auth_user": { "type": "string" }, - "db_password": { + "comment": { "type": "string" }, - "db_type": { + "hosts_allow": { "type": "string" }, - "db_user": { - "type": "string" - }, - "domains": { - "type": "array", - "items": { - "type": "string" - } - }, "name": { "type": "string" }, "path": { "type": "string" }, - "php": { + "secret": { + "type": "string" + } + } + }, + "github_com_TheTNB_panel_app_http_requests_setting.Update": { + "type": "object", + "properties": { + "backup_path": { "type": "string" }, - "ports": { - "type": "array", - "items": { - "type": "integer" - } - }, - "remark": { + "email": { "type": "string" }, + "entrance": { + "type": "string" + }, + "language": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, "ssl": { "type": "boolean" }, - "status": { - "type": "boolean" + "username": { + "type": "string" + }, + "website_path": { + "type": "string" } } }, @@ -3992,72 +3997,6 @@ } } }, - "panel_app_http_requests_container.ID": { - "type": "object", - "properties": { - "id": { - "type": "string" - } - } - }, - "panel_app_http_requests_plugins_rsync.Update": { - "type": "object", - "properties": { - "auth_user": { - "type": "string" - }, - "comment": { - "type": "string" - }, - "hosts_allow": { - "type": "string" - }, - "name": { - "type": "string" - }, - "path": { - "type": "string" - }, - "secret": { - "type": "string" - } - } - }, - "panel_app_http_requests_setting.Update": { - "type": "object", - "properties": { - "backup_path": { - "type": "string" - }, - "email": { - "type": "string" - }, - "entrance": { - "type": "string" - }, - "language": { - "type": "string" - }, - "name": { - "type": "string" - }, - "password": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "ssl": { - "type": "boolean" - }, - "username": { - "type": "string" - }, - "website_path": { - "type": "string" - } - } - }, "requests.Add": { "type": "object", "properties": { @@ -4643,6 +4582,17 @@ } } }, + "types.BackupFile": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "size": { + "type": "string" + } + } + }, "types.ContainerNetwork": { "type": "object", "properties": { @@ -4707,6 +4657,56 @@ "type": "string" } } + }, + "types.Website": { + "type": "object", + "properties": { + "db": { + "type": "boolean" + }, + "db_name": { + "type": "string" + }, + "db_password": { + "type": "string" + }, + "db_type": { + "type": "string" + }, + "db_user": { + "type": "string" + }, + "domains": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "php": { + "type": "string" + }, + "ports": { + "type": "array", + "items": { + "type": "integer" + } + }, + "remark": { + "type": "string" + }, + "ssl": { + "type": "boolean" + }, + "status": { + "type": "boolean" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 984d40de..49c22bc9 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -31,45 +31,48 @@ definitions: message: type: string type: object - internal.BackupFile: + github_com_TheTNB_panel_app_http_requests_container.ID: properties: - name: - type: string - size: + id: type: string type: object - internal.PanelWebsite: + github_com_TheTNB_panel_app_http_requests_plugins_rsync.Update: properties: - db: - type: boolean - db_name: + auth_user: type: string - db_password: + comment: type: string - db_type: + hosts_allow: type: string - db_user: - type: string - domains: - items: - type: string - type: array name: type: string path: type: string - php: + secret: type: string - ports: - items: - type: integer - type: array - remark: + type: object + github_com_TheTNB_panel_app_http_requests_setting.Update: + properties: + backup_path: type: string + email: + type: string + entrance: + type: string + language: + type: string + name: + type: string + password: + type: string + port: + type: integer ssl: type: boolean - status: - type: boolean + username: + type: string + website_path: + type: string type: object models.Cert: properties: @@ -176,49 +179,6 @@ definitions: updated_at: type: string type: object - panel_app_http_requests_container.ID: - properties: - id: - type: string - type: object - panel_app_http_requests_plugins_rsync.Update: - properties: - auth_user: - type: string - comment: - type: string - hosts_allow: - type: string - name: - type: string - path: - type: string - secret: - type: string - type: object - panel_app_http_requests_setting.Update: - properties: - backup_path: - type: string - email: - type: string - entrance: - type: string - language: - type: string - name: - type: string - password: - type: string - port: - type: integer - ssl: - type: boolean - username: - type: string - website_path: - type: string - type: object requests.Add: properties: db: @@ -599,6 +559,13 @@ definitions: $ref: '#/definitions/types.KV' type: array type: object + types.BackupFile: + properties: + name: + type: string + size: + type: string + type: object types.ContainerNetwork: properties: enabled: @@ -641,9 +608,42 @@ definitions: value: type: string type: object + types.Website: + properties: + db: + type: boolean + db_name: + type: string + db_password: + type: string + db_type: + type: string + db_user: + type: string + domains: + items: + type: string + type: array + name: + type: string + path: + type: string + php: + type: string + ports: + items: + type: integer + type: array + remark: + type: string + ssl: + type: boolean + status: + type: boolean + type: object info: contact: - email: i@haozi.net + email: admin@haozi.net name: 耗子科技 description: 耗子 Linux 面板的 API 信息 license: @@ -1313,7 +1313,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1354,7 +1354,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1564,7 +1564,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1601,7 +1601,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1645,7 +1645,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1688,7 +1688,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1729,7 +1729,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1751,7 +1751,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -1872,7 +1872,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_container.ID' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_container.ID' produces: - application/json responses: @@ -2271,7 +2271,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_setting.Update' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_setting.Update' produces: - application/json responses: @@ -2350,7 +2350,7 @@ paths: - properties: data: items: - $ref: '#/definitions/internal.BackupFile' + $ref: '#/definitions/types.BackupFile' type: array type: object security: @@ -2541,7 +2541,7 @@ paths: - $ref: '#/definitions/controllers.SuccessResponse' - properties: data: - $ref: '#/definitions/internal.PanelWebsite' + $ref: '#/definitions/types.Website' type: object security: - BearerToken: [] @@ -2827,7 +2827,7 @@ paths: name: data required: true schema: - $ref: '#/definitions/panel_app_http_requests_plugins_rsync.Update' + $ref: '#/definitions/github_com_TheTNB_panel_app_http_requests_plugins_rsync.Update' produces: - application/json responses: diff --git a/internal/backup.go b/internal/backup.go index a926059c..ee4bd3ec 100644 --- a/internal/backup.go +++ b/internal/backup.go @@ -1,20 +1,18 @@ package internal -import "github.com/TheTNB/panel/app/models" +import ( + "github.com/TheTNB/panel/app/models" + "github.com/TheTNB/panel/types" +) type Backup interface { - WebsiteList() ([]BackupFile, error) + WebsiteList() ([]types.BackupFile, error) WebSiteBackup(website models.Website) error WebsiteRestore(website models.Website, backupFile string) error - MysqlList() ([]BackupFile, error) + MysqlList() ([]types.BackupFile, error) MysqlBackup(database string) error MysqlRestore(database string, backupFile string) error - PostgresqlList() ([]BackupFile, error) + PostgresqlList() ([]types.BackupFile, error) PostgresqlBackup(database string) error PostgresqlRestore(database string, backupFile string) error } - -type BackupFile struct { - Name string `json:"name"` - Size string `json:"size"` -} diff --git a/internal/php.go b/internal/php.go index e09c3888..1e401827 100644 --- a/internal/php.go +++ b/internal/php.go @@ -2,13 +2,6 @@ package internal import "github.com/TheTNB/panel/types" -type PHPExtension struct { - Name string `json:"name"` - Slug string `json:"slug"` - Description string `json:"description"` - Installed bool `json:"installed"` -} - type PHP interface { Status() (bool, error) Reload() error @@ -24,7 +17,7 @@ type PHP interface { GetSlowLog() (string, error) ClearErrorLog() error ClearSlowLog() error - GetExtensions() ([]PHPExtension, error) + GetExtensions() ([]types.PHPExtension, error) InstallExtension(slug string) error UninstallExtension(slug string) error } diff --git a/internal/plugin.go b/internal/plugin.go index eb859cd8..4f745221 100644 --- a/internal/plugin.go +++ b/internal/plugin.go @@ -1,24 +1,14 @@ package internal -import "github.com/TheTNB/panel/app/models" - -// PanelPlugin 插件元数据结构 -type PanelPlugin struct { - Name string - Description string - Slug string - Version string - Requires []string - Excludes []string - Install string - Uninstall string - Update string -} +import ( + "github.com/TheTNB/panel/app/models" + "github.com/TheTNB/panel/types" +) type Plugin interface { AllInstalled() ([]models.Plugin, error) - All() []PanelPlugin - GetBySlug(slug string) PanelPlugin + All() []types.Plugin + GetBySlug(slug string) types.Plugin GetInstalledBySlug(slug string) models.Plugin Install(slug string) error Uninstall(slug string) error diff --git a/internal/plugin_list.go b/internal/plugin_list.go index 172da494..b1466564 100644 --- a/internal/plugin_list.go +++ b/internal/plugin_list.go @@ -1,7 +1,9 @@ // Package internal 插件定义文件 package internal -var PluginOpenResty = PanelPlugin{ +import "github.com/TheTNB/panel/types" + +var PluginOpenResty = types.Plugin{ Name: "OpenResty", Description: "OpenResty® 是一款基于 NGINX 和 LuaJIT 的 Web 平台。", Slug: "openresty", @@ -13,7 +15,7 @@ var PluginOpenResty = PanelPlugin{ Update: "bash /www/panel/scripts/openresty/install.sh", } -var PluginMySQL57 = PanelPlugin{ +var PluginMySQL57 = types.Plugin{ Name: "MySQL-5.7", Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(已停止维护,不建议使用!预计 2025 年 12 月移除)", Slug: "mysql57", @@ -25,7 +27,7 @@ var PluginMySQL57 = PanelPlugin{ Update: `bash /www/panel/scripts/mysql/update.sh 57`, } -var PluginMySQL80 = PanelPlugin{ +var PluginMySQL80 = types.Plugin{ Name: "MySQL-8.0", Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(建议内存 > 2G 安装)", Slug: "mysql80", @@ -37,7 +39,7 @@ var PluginMySQL80 = PanelPlugin{ Update: `bash /www/panel/scripts/mysql/update.sh 80`, } -var PluginMySQL84 = PanelPlugin{ +var PluginMySQL84 = types.Plugin{ Name: "MySQL-8.4", Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(建议内存 > 2G 安装)", Slug: "mysql84", @@ -49,7 +51,7 @@ var PluginMySQL84 = PanelPlugin{ Update: `bash /www/panel/scripts/mysql/update.sh 84`, } -var PluginPostgreSQL15 = PanelPlugin{ +var PluginPostgreSQL15 = types.Plugin{ Name: "PostgreSQL-15", Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。", Slug: "postgresql15", @@ -61,7 +63,7 @@ var PluginPostgreSQL15 = PanelPlugin{ Update: `bash /www/panel/scripts/postgresql/update.sh 15`, } -var PluginPostgreSQL16 = PanelPlugin{ +var PluginPostgreSQL16 = types.Plugin{ Name: "PostgreSQL-16", Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。", Slug: "postgresql16", @@ -73,7 +75,7 @@ var PluginPostgreSQL16 = PanelPlugin{ Update: `bash /www/panel/scripts/postgresql/update.sh 16`, } -var PluginPHP74 = PanelPlugin{ +var PluginPHP74 = types.Plugin{ Name: "PHP-7.4", Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。(已停止维护,不建议使用!预计 2024 年 12 月移除)", Slug: "php74", @@ -85,7 +87,7 @@ var PluginPHP74 = PanelPlugin{ Update: `bash /www/panel/scripts/php/install.sh 74`, } -var PluginPHP80 = PanelPlugin{ +var PluginPHP80 = types.Plugin{ Name: "PHP-8.0", Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。(已停止维护,不建议使用!预计 2025 年 12 月移除)", Slug: "php80", @@ -97,7 +99,7 @@ var PluginPHP80 = PanelPlugin{ Update: `bash /www/panel/scripts/php/install.sh 80`, } -var PluginPHP81 = PanelPlugin{ +var PluginPHP81 = types.Plugin{ Name: "PHP-8.1", Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", Slug: "php81", @@ -109,7 +111,7 @@ var PluginPHP81 = PanelPlugin{ Update: `bash /www/panel/scripts/php/install.sh 81`, } -var PluginPHP82 = PanelPlugin{ +var PluginPHP82 = types.Plugin{ Name: "PHP-8.2", Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", Slug: "php82", @@ -121,7 +123,7 @@ var PluginPHP82 = PanelPlugin{ Update: `bash /www/panel/scripts/php/install.sh 82`, } -var PluginPHP83 = PanelPlugin{ +var PluginPHP83 = types.Plugin{ Name: "PHP-8.3", Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", Slug: "php83", @@ -133,7 +135,7 @@ var PluginPHP83 = PanelPlugin{ Update: `bash /www/panel/scripts/php/install.sh 83`, } -var PluginPHPMyAdmin = PanelPlugin{ +var PluginPHPMyAdmin = types.Plugin{ Name: "phpMyAdmin", Description: "phpMyAdmin 是一个以 PHP 为基础,以 Web-Base 方式架构在网站主机上的 MySQL 数据库管理工具。", Slug: "phpmyadmin", @@ -145,7 +147,7 @@ var PluginPHPMyAdmin = PanelPlugin{ Update: `bash /www/panel/scripts/phpmyadmin/uninstall.sh && bash /www/panel/scripts/phpmyadmin/install.sh`, } -var PluginPureFTPd = PanelPlugin{ +var PluginPureFTPd = types.Plugin{ Name: "Pure-FTPd", Description: "Pure-Ftpd 是一个快速、高效、轻便、安全的 FTP 服务器,它以安全和配置简单为设计目标,支持虚拟主机,IPV6,PAM 等功能。", Slug: "pureftpd", @@ -157,7 +159,7 @@ var PluginPureFTPd = PanelPlugin{ Update: `bash /www/panel/scripts/pureftpd/update.sh`, } -var PluginRedis = PanelPlugin{ +var PluginRedis = types.Plugin{ Name: "Redis", Description: "Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。", Slug: "redis", @@ -169,7 +171,7 @@ var PluginRedis = PanelPlugin{ Update: `bash /www/panel/scripts/redis/update.sh`, } -var PluginS3fs = PanelPlugin{ +var PluginS3fs = types.Plugin{ Name: "S3fs", Description: "S3fs 通过 FUSE 挂载兼容 S3 标准的存储桶,例如 Amazon S3、阿里云 OSS、腾讯云 COS、七牛云 Kodo 等。", Slug: "s3fs", @@ -181,7 +183,7 @@ var PluginS3fs = PanelPlugin{ Update: `bash /www/panel/scripts/s3fs/update.sh`, } -var PluginRsync = PanelPlugin{ +var PluginRsync = types.Plugin{ Name: "Rsync", Description: "Rsync 是一款提供快速增量文件传输的开源工具。", Slug: "rsync", @@ -193,7 +195,7 @@ var PluginRsync = PanelPlugin{ Update: `bash /www/panel/scripts/rsync/install.sh`, } -var PluginSupervisor = PanelPlugin{ +var PluginSupervisor = types.Plugin{ Name: "Supervisor", Description: "Supervisor 是一个客户端/服务器系统,允许用户监视和控制类 UNIX 操作系统上的多个进程。", Slug: "supervisor", @@ -205,7 +207,7 @@ var PluginSupervisor = PanelPlugin{ Update: `bash /www/panel/scripts/supervisor/update.sh`, } -var PluginFail2ban = PanelPlugin{ +var PluginFail2ban = types.Plugin{ Name: "Fail2ban", Description: "Fail2ban 扫描系统日志文件并从中找出多次尝试失败的IP地址,将该IP地址加入防火墙的拒绝访问列表中。", Slug: "fail2ban", @@ -217,7 +219,7 @@ var PluginFail2ban = PanelPlugin{ Update: `bash /www/panel/scripts/fail2ban/update.sh`, } -var PluginToolBox = PanelPlugin{ +var PluginToolBox = types.Plugin{ Name: "系统工具箱", Description: "可视化调整一些常用的配置项,如 DNS、SWAP、时区等", Slug: "toolbox", diff --git a/internal/services/backup.go b/internal/services/backup.go index b36f5e6b..eb6f2ad9 100644 --- a/internal/services/backup.go +++ b/internal/services/backup.go @@ -12,6 +12,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) type BackupImpl struct { @@ -25,30 +26,30 @@ func NewBackupImpl() *BackupImpl { } // WebsiteList 网站备份列表 -func (s *BackupImpl) WebsiteList() ([]internal.BackupFile, error) { +func (s *BackupImpl) WebsiteList() ([]types.BackupFile, error) { backupPath := s.setting.Get(models.SettingKeyBackupPath) if len(backupPath) == 0 { - return []internal.BackupFile{}, nil + return []types.BackupFile{}, nil } backupPath += "/website" if !tools.Exists(backupPath) { if err := tools.Mkdir(backupPath, 0644); err != nil { - return []internal.BackupFile{}, err + return []types.BackupFile{}, err } } files, err := os.ReadDir(backupPath) if err != nil { - return []internal.BackupFile{}, err + return []types.BackupFile{}, err } - var backupList []internal.BackupFile + var backupList []types.BackupFile for _, file := range files { info, err := file.Info() if err != nil { continue } - backupList = append(backupList, internal.BackupFile{ + backupList = append(backupList, types.BackupFile{ Name: file.Name(), Size: tools.FormatBytes(float64(info.Size())), }) @@ -115,30 +116,30 @@ func (s *BackupImpl) WebsiteRestore(website models.Website, backupFile string) e } // MysqlList MySQL备份列表 -func (s *BackupImpl) MysqlList() ([]internal.BackupFile, error) { +func (s *BackupImpl) MysqlList() ([]types.BackupFile, error) { backupPath := s.setting.Get(models.SettingKeyBackupPath) if len(backupPath) == 0 { - return []internal.BackupFile{}, nil + return []types.BackupFile{}, nil } backupPath += "/mysql" if !tools.Exists(backupPath) { if err := tools.Mkdir(backupPath, 0644); err != nil { - return []internal.BackupFile{}, err + return []types.BackupFile{}, err } } files, err := os.ReadDir(backupPath) if err != nil { - return []internal.BackupFile{}, err + return []types.BackupFile{}, err } - var backupList []internal.BackupFile + var backupList []types.BackupFile for _, file := range files { info, err := file.Info() if err != nil { continue } - backupList = append(backupList, internal.BackupFile{ + backupList = append(backupList, types.BackupFile{ Name: file.Name(), Size: tools.FormatBytes(float64(info.Size())), }) @@ -228,30 +229,30 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error { } // PostgresqlList PostgreSQL备份列表 -func (s *BackupImpl) PostgresqlList() ([]internal.BackupFile, error) { +func (s *BackupImpl) PostgresqlList() ([]types.BackupFile, error) { backupPath := s.setting.Get(models.SettingKeyBackupPath) if len(backupPath) == 0 { - return []internal.BackupFile{}, nil + return []types.BackupFile{}, nil } backupPath += "/postgresql" if !tools.Exists(backupPath) { if err := tools.Mkdir(backupPath, 0644); err != nil { - return []internal.BackupFile{}, err + return []types.BackupFile{}, err } } files, err := os.ReadDir(backupPath) if err != nil { - return []internal.BackupFile{}, err + return []types.BackupFile{}, err } - var backupList []internal.BackupFile + var backupList []types.BackupFile for _, file := range files { info, err := file.Info() if err != nil { continue } - backupList = append(backupList, internal.BackupFile{ + backupList = append(backupList, types.BackupFile{ Name: file.Name(), Size: tools.FormatBytes(float64(info.Size())), }) diff --git a/internal/services/php.go b/internal/services/php.go index 54ad7611..06c92f7a 100644 --- a/internal/services/php.go +++ b/internal/services/php.go @@ -13,7 +13,6 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/models" - "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" ) @@ -122,8 +121,8 @@ func (r *PHPImpl) ClearSlowLog() error { return nil } -func (r *PHPImpl) GetExtensions() ([]internal.PHPExtension, error) { - extensions := []internal.PHPExtension{ +func (r *PHPImpl) GetExtensions() ([]types.PHPExtension, error) { + extensions := []types.PHPExtension{ { Name: "fileinfo", Slug: "fileinfo", @@ -264,7 +263,7 @@ func (r *PHPImpl) GetExtensions() ([]internal.PHPExtension, error) { // ionCube 只支持 PHP 8.3 以下版本 if cast.ToUint(r.version) < 83 { - extensions = append(extensions, internal.PHPExtension{ + extensions = append(extensions, types.PHPExtension{ Name: "ionCube", Slug: "ionCube Loader", Description: "ionCube 是一个专业级的 PHP 加密解密工具。", @@ -273,13 +272,13 @@ func (r *PHPImpl) GetExtensions() ([]internal.PHPExtension, error) { } // Swoole 和 Swow 不支持 PHP 8.0 以下版本 if cast.ToUint(r.version) >= 80 { - extensions = append(extensions, internal.PHPExtension{ + extensions = append(extensions, types.PHPExtension{ Name: "Swoole", Slug: "swoole", Description: "Swoole 是一个用于构建高性能的异步并发服务器的 PHP 扩展。", Installed: false, }) - extensions = append(extensions, internal.PHPExtension{ + extensions = append(extensions, types.PHPExtension{ Name: "Swow", Slug: "Swow", Description: "Swow 是一个用于构建高性能的异步并发服务器的 PHP 扩展。", @@ -292,7 +291,7 @@ func (r *PHPImpl) GetExtensions() ([]internal.PHPExtension, error) { return extensions, err } - extensionMap := make(map[string]*internal.PHPExtension) + extensionMap := make(map[string]*types.PHPExtension) for i := range extensions { extensionMap[extensions[i].Slug] = &extensions[i] } diff --git a/internal/services/plugin.go b/internal/services/plugin.go index 0f9d58a7..5242f4a4 100644 --- a/internal/services/plugin.go +++ b/internal/services/plugin.go @@ -8,6 +8,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" + "github.com/TheTNB/panel/types" ) type PluginImpl struct { @@ -31,8 +32,8 @@ func (r *PluginImpl) AllInstalled() ([]models.Plugin, error) { } // All 获取所有插件 -func (r *PluginImpl) All() []internal.PanelPlugin { - var plugins = []internal.PanelPlugin{ +func (r *PluginImpl) All() []types.Plugin { + var plugins = []types.Plugin{ internal.PluginOpenResty, internal.PluginMySQL57, internal.PluginMySQL80, @@ -58,14 +59,14 @@ func (r *PluginImpl) All() []internal.PanelPlugin { } // GetBySlug 根据slug获取插件 -func (r *PluginImpl) GetBySlug(slug string) internal.PanelPlugin { +func (r *PluginImpl) GetBySlug(slug string) types.Plugin { for _, item := range r.All() { if item.Slug == slug { return item } } - return internal.PanelPlugin{} + return types.Plugin{} } // GetInstalledBySlug 根据slug获取已安装的插件 diff --git a/internal/services/website.go b/internal/services/website.go index dab048b6..25ee7b55 100644 --- a/internal/services/website.go +++ b/internal/services/website.go @@ -10,13 +10,14 @@ import ( "strconv" "strings" - requests "github.com/TheTNB/panel/app/http/requests/website" "github.com/goravel/framework/facades" "github.com/spf13/cast" + requests "github.com/TheTNB/panel/app/http/requests/website" "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/types" ) type WebsiteImpl struct { @@ -41,7 +42,7 @@ func (r *WebsiteImpl) List(page, limit int) (int64, []models.Website, error) { } // Add 添加网站 -func (r *WebsiteImpl) Add(website internal.PanelWebsite) (models.Website, error) { +func (r *WebsiteImpl) Add(website types.Website) (models.Website, error) { w := models.Website{ Name: website.Name, Status: website.Status, @@ -499,18 +500,18 @@ func (r *WebsiteImpl) Delete(id uint) error { } // GetConfig 获取网站配置 -func (r *WebsiteImpl) GetConfig(id uint) (internal.WebsiteSetting, error) { +func (r *WebsiteImpl) GetConfig(id uint) (types.WebsiteSetting, error) { var website models.Website if err := facades.Orm().Query().Where("id", id).First(&website); err != nil { - return internal.WebsiteSetting{}, err + return types.WebsiteSetting{}, err } config, err := tools.Read("/www/server/vhost/" + website.Name + ".conf") if err != nil { - return internal.WebsiteSetting{}, err + return types.WebsiteSetting{}, err } - var setting internal.WebsiteSetting + var setting types.WebsiteSetting setting.Name = website.Name setting.Path = website.Path setting.Ssl = website.Ssl @@ -612,10 +613,10 @@ func (r *WebsiteImpl) GetConfig(id uint) (internal.WebsiteSetting, error) { } // GetConfigByName 根据网站名称获取网站配置 -func (r *WebsiteImpl) GetConfigByName(name string) (internal.WebsiteSetting, error) { +func (r *WebsiteImpl) GetConfigByName(name string) (types.WebsiteSetting, error) { var website models.Website if err := facades.Orm().Query().Where("name", name).First(&website); err != nil { - return internal.WebsiteSetting{}, err + return types.WebsiteSetting{}, err } return r.GetConfig(website.ID) diff --git a/internal/website.go b/internal/website.go index 5c2b1c50..7b8c56d3 100644 --- a/internal/website.go +++ b/internal/website.go @@ -3,59 +3,15 @@ package internal import ( requests "github.com/TheTNB/panel/app/http/requests/website" "github.com/TheTNB/panel/app/models" + "github.com/TheTNB/panel/types" ) type Website interface { List(page int, limit int) (int64, []models.Website, error) - Add(website PanelWebsite) (models.Website, error) + Add(website types.Website) (models.Website, error) SaveConfig(config requests.SaveConfig) error Delete(id uint) error - GetConfig(id uint) (WebsiteSetting, error) - GetConfigByName(name string) (WebsiteSetting, error) + GetConfig(id uint) (types.WebsiteSetting, error) + GetConfigByName(name string) (types.WebsiteSetting, error) GetIDByName(name string) (uint, error) } - -type PanelWebsite struct { - Name string `json:"name"` - Status bool `json:"status"` - Domains []string `json:"domains"` - Ports []uint `json:"ports"` - Path string `json:"path"` - Php string `json:"php"` - Ssl bool `json:"ssl"` - Remark string `json:"remark"` - Db bool `json:"db"` - DbType string `json:"db_type"` - DbName string `json:"db_name"` - DbUser string `json:"db_user"` - DbPassword string `json:"db_password"` -} - -// WebsiteSetting 网站设置 -type WebsiteSetting struct { - Name string `json:"name"` - Domains []string `json:"domains"` - Ports []uint `json:"ports"` - Root string `json:"root"` - Path string `json:"path"` - Index string `json:"index"` - Php string `json:"php"` - OpenBasedir bool `json:"open_basedir"` - Ssl bool `json:"ssl"` - SslCertificate string `json:"ssl_certificate"` - SslCertificateKey string `json:"ssl_certificate_key"` - SslNotBefore string `json:"ssl_not_before"` - SslNotAfter string `json:"ssl_not_after"` - SSlDNSNames []string `json:"ssl_dns_names"` - SslIssuer string `json:"ssl_issuer"` - SslOCSPServer []string `json:"ssl_ocsp_server"` - HttpRedirect bool `json:"http_redirect"` - Hsts bool `json:"hsts"` - Waf bool `json:"waf"` - WafMode string `json:"waf_mode"` - WafCcDeny string `json:"waf_cc_deny"` - WafCache string `json:"waf_cache"` - Rewrite string `json:"rewrite"` - Raw string `json:"raw"` - Log string `json:"log"` -} diff --git a/types/backup.go b/types/backup.go new file mode 100644 index 00000000..151af976 --- /dev/null +++ b/types/backup.go @@ -0,0 +1,6 @@ +package types + +type BackupFile struct { + Name string `json:"name"` + Size string `json:"size"` +} diff --git a/types/php.go b/types/php.go new file mode 100644 index 00000000..7ee51ea3 --- /dev/null +++ b/types/php.go @@ -0,0 +1,8 @@ +package types + +type PHPExtension struct { + Name string `json:"name"` + Slug string `json:"slug"` + Description string `json:"description"` + Installed bool `json:"installed"` +} diff --git a/types/plugin.go b/types/plugin.go new file mode 100644 index 00000000..822d3713 --- /dev/null +++ b/types/plugin.go @@ -0,0 +1,14 @@ +package types + +// Plugin 插件元数据结构 +type Plugin struct { + Name string + Description string + Slug string + Version string + Requires []string + Excludes []string + Install string + Uninstall string + Update string +} diff --git a/internal/status.go b/types/status.go similarity index 89% rename from internal/status.go rename to types/status.go index e28cdf0f..51e3e67c 100644 --- a/internal/status.go +++ b/types/status.go @@ -1,4 +1,4 @@ -package internal +package types // 定义面板状态常量 const ( diff --git a/types/website.go b/types/website.go new file mode 100644 index 00000000..87cf06d3 --- /dev/null +++ b/types/website.go @@ -0,0 +1,46 @@ +package types + +type Website struct { + Name string `json:"name"` + Status bool `json:"status"` + Domains []string `json:"domains"` + Ports []uint `json:"ports"` + Path string `json:"path"` + Php string `json:"php"` + Ssl bool `json:"ssl"` + Remark string `json:"remark"` + Db bool `json:"db"` + DbType string `json:"db_type"` + DbName string `json:"db_name"` + DbUser string `json:"db_user"` + DbPassword string `json:"db_password"` +} + +// WebsiteSetting 网站设置 +type WebsiteSetting struct { + Name string `json:"name"` + Domains []string `json:"domains"` + Ports []uint `json:"ports"` + Root string `json:"root"` + Path string `json:"path"` + Index string `json:"index"` + Php string `json:"php"` + OpenBasedir bool `json:"open_basedir"` + Ssl bool `json:"ssl"` + SslCertificate string `json:"ssl_certificate"` + SslCertificateKey string `json:"ssl_certificate_key"` + SslNotBefore string `json:"ssl_not_before"` + SslNotAfter string `json:"ssl_not_after"` + SSlDNSNames []string `json:"ssl_dns_names"` + SslIssuer string `json:"ssl_issuer"` + SslOCSPServer []string `json:"ssl_ocsp_server"` + HttpRedirect bool `json:"http_redirect"` + Hsts bool `json:"hsts"` + Waf bool `json:"waf"` + WafMode string `json:"waf_mode"` + WafCcDeny string `json:"waf_cc_deny"` + WafCache string `json:"waf_cache"` + Rewrite string `json:"rewrite"` + Raw string `json:"raw"` + Log string `json:"log"` +}