From 8b262cf28950028f6a7f33e17bc586274e6e2a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sat, 24 Jun 2023 22:27:41 +0800 Subject: [PATCH] feat: openresty plugin --- README.md | 3 +- app/http/controllers/helpers.go | 2 +- app/http/controllers/info_controller.go | 29 ++ app/http/controllers/website_controller.go | 36 ++ app/services/user_test.go | 3 +- go.mod | 21 +- go.sum | 49 +- .../http/controllers/openresty_controller.go | 294 +++++++++++- plugins/openresty/openresty.go | 2 + plugins/openresty/public/views/openresty.html | 250 ++++++++++ plugins/openresty/routes.go | 23 +- public/index.html | 2 +- .../{res => panel}/adminui/src/css/admin.css | 0 .../{res => panel}/adminui/src/css/login.css | 0 .../adminui/src/modules/admin.js | 2 +- .../adminui/src/modules/index.js | 2 +- .../adminui/src/modules/view.js | 4 +- public/{res => panel}/config.js | 0 public/{res => panel}/index.js | 0 public/{res => panel}/modules/common.js | 0 public/{res => panel}/modules/echartsTheme.js | 0 public/{res => panel}/style/imgs/bg-none.jpg | Bin .../{res => panel}/style/imgs/layui-logo.jpg | Bin .../{res => panel}/style/imgs/logo-black.png | Bin public/{res => panel}/style/imgs/logo.png | Bin .../style/imgs/template/character.jpg | Bin .../style/imgs/template/huge.jpg | Bin .../style/imgs/template/portrait.png | Bin public/{res => panel}/style/template.css | 0 public/{res => panel}/views/index.html | 0 public/{res => panel}/views/login.html | 0 public/{res => panel}/views/logout.html | 0 .../template/tips => panel/views/ui}/404.html | 0 .../tips => panel/views/ui}/error.html | 0 .../{res/views => panel/views/ui}/layout.html | 0 public/panel/views/ui/theme.html | 43 ++ public/panel/views/website/add.html | 166 +++++++ .../panel/views/website/default_settings.html | 82 ++++ public/panel/views/website/edit.html | 379 +++++++++++++++ public/panel/views/website/list.html | 241 ++++++++++ public/res/views/template/addresslist.html | 368 --------------- public/res/views/template/caller.html | 203 -------- public/res/views/template/goodslist.html | 422 ----------------- public/res/views/template/msgboard.html | 100 ---- public/res/views/template/personalpage.html | 443 ------------------ public/res/views/template/search.html | 100 ---- public/res/views/template/tips/test.html | 12 - public/res/views/template/说明.txt | 2 - public/robots.txt | 2 +- routes/web.go | 5 + 50 files changed, 1604 insertions(+), 1686 deletions(-) create mode 100644 app/http/controllers/website_controller.go create mode 100644 plugins/openresty/public/views/openresty.html rename public/{res => panel}/adminui/src/css/admin.css (100%) rename public/{res => panel}/adminui/src/css/login.css (100%) rename public/{res => panel}/adminui/src/modules/admin.js (99%) rename public/{res => panel}/adminui/src/modules/index.js (98%) rename public/{res => panel}/adminui/src/modules/view.js (99%) rename public/{res => panel}/config.js (100%) rename public/{res => panel}/index.js (100%) rename public/{res => panel}/modules/common.js (100%) rename public/{res => panel}/modules/echartsTheme.js (100%) rename public/{res => panel}/style/imgs/bg-none.jpg (100%) rename public/{res => panel}/style/imgs/layui-logo.jpg (100%) rename public/{res => panel}/style/imgs/logo-black.png (100%) rename public/{res => panel}/style/imgs/logo.png (100%) rename public/{res => panel}/style/imgs/template/character.jpg (100%) rename public/{res => panel}/style/imgs/template/huge.jpg (100%) rename public/{res => panel}/style/imgs/template/portrait.png (100%) rename public/{res => panel}/style/template.css (100%) rename public/{res => panel}/views/index.html (100%) rename public/{res => panel}/views/login.html (100%) rename public/{res => panel}/views/logout.html (100%) rename public/{res/views/template/tips => panel/views/ui}/404.html (100%) rename public/{res/views/template/tips => panel/views/ui}/error.html (100%) rename public/{res/views => panel/views/ui}/layout.html (100%) create mode 100644 public/panel/views/ui/theme.html create mode 100644 public/panel/views/website/add.html create mode 100644 public/panel/views/website/default_settings.html create mode 100644 public/panel/views/website/edit.html create mode 100644 public/panel/views/website/list.html delete mode 100644 public/res/views/template/addresslist.html delete mode 100644 public/res/views/template/caller.html delete mode 100644 public/res/views/template/goodslist.html delete mode 100644 public/res/views/template/msgboard.html delete mode 100644 public/res/views/template/personalpage.html delete mode 100644 public/res/views/template/search.html delete mode 100644 public/res/views/template/tips/test.html delete mode 100644 public/res/views/template/说明.txt diff --git a/README.md b/README.md index 1ecb30cd..5b83a388 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![Test](https://github.com/HaoZi-Team/Panel/actions/workflows/test.yml/badge.svg)](https://github.com/HaoZi-Team/Panel/actions) [![Report Card](https://goreportcard.com/badge/github.com/HaoZi-Team/Panel)](https://goreportcard.com/report/github.com/HaoZi-Team/Panel) [![Codecov](https://codecov.io/gh/HaoZi-Team/Panel/branch/main/graph/badge.svg?token=XFT5NGNSRG)](https://codecov.io/gh/HaoZi-Team/Panel) -[![Doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/HaoZi-Team/Panel) ![License](https://img.shields.io/github/license/HaoZi-Team/Panel) 这是耗子Linux面板的开源仓库,基于Apache License 2.0协议进行开源,目前处于积极开发状态。 @@ -21,7 +20,7 @@ 低配机器建议使用 `Debian`,资源占用较 `RHEL` 系更低。其他机器建议使用 `RockyLinux` | `AlmaLinux`,维护周期更长。 -不在下表中的其他 `RHEL` 系统,可自行尝试安装,但不保证能够正常运行,且不提供技术支持。 +不在下表中的其他同版本的 `RHEL` 系统(OpenCloudOS、Anolis、CentOS Stream等),可自行尝试安装,但不保证能够正常运行,且不提供技术支持。 | 系统 | 版本 | |------------|----| diff --git a/app/http/controllers/helpers.go b/app/http/controllers/helpers.go index 59302750..d25806fa 100644 --- a/app/http/controllers/helpers.go +++ b/app/http/controllers/helpers.go @@ -11,7 +11,7 @@ func Success(ctx http.Context, data any) { } func Error(ctx http.Context, code int, message any) { - ctx.Response().Json(code, http.Json{ + ctx.Response().Json(http.StatusOK, http.Json{ "code": code, "message": message, }) diff --git a/app/http/controllers/info_controller.go b/app/http/controllers/info_controller.go index 63648a82..da29e285 100644 --- a/app/http/controllers/info_controller.go +++ b/app/http/controllers/info_controller.go @@ -79,3 +79,32 @@ func (r *InfoController) SystemInfo(ctx http.Context) { "panel_version": facades.Config().GetString("panel.version"), }) } + +func (r *InfoController) InstalledDbAndPhp(ctx http.Context) { + var php []models.Plugin + err := facades.Orm().Query().Where("slug like ?", "php%").Find(&php) + if err != nil { + Error(ctx, http.StatusInternalServerError, "系统内部错误") + return + } + + var mysql models.Plugin + mysqlInstalled := true + err = facades.Orm().Query().Where("slug like ?", "mysql%").FirstOrFail(&mysql) + if err != nil { + mysqlInstalled = false + } + + var postgresql models.Plugin + postgresqlInstalled := true + err = facades.Orm().Query().Where("slug like ?", "postgresql%").FirstOrFail(&postgresql) + if err != nil { + postgresqlInstalled = false + } + + Success(ctx, http.Json{ + "php": php, + "mysql": mysqlInstalled, + "postgresql": postgresqlInstalled, + }) +} diff --git a/app/http/controllers/website_controller.go b/app/http/controllers/website_controller.go new file mode 100644 index 00000000..504e5ce4 --- /dev/null +++ b/app/http/controllers/website_controller.go @@ -0,0 +1,36 @@ +package controllers + +import ( + "github.com/goravel/framework/contracts/http" + "github.com/goravel/framework/facades" + "panel/app/models" +) + +type WebsiteController struct { + //Dependent services +} + +func NewWebsiteController() *WebsiteController { + return &WebsiteController{ + //Inject services + } +} + +func (r *WebsiteController) List(ctx http.Context) { + limit := ctx.Request().QueryInt("limit") + page := ctx.Request().QueryInt("page") + + var websites []models.Website + var total int64 + err := facades.Orm().Query().Paginate(page, limit, &websites, &total) + if err != nil { + facades.Log().Error("[面板][WebsiteController] 查询网站列表失败 ", err) + Error(ctx, http.StatusInternalServerError, "系统内部错误") + return + } + + Success(ctx, http.Json{ + "total": total, + "items": websites, + }) +} diff --git a/app/services/user_test.go b/app/services/user_test.go index 09e121f5..8acf85e7 100644 --- a/app/services/user_test.go +++ b/app/services/user_test.go @@ -3,9 +3,10 @@ package services import ( "testing" - "github.com/goravel/framework/testing/mock" "github.com/stretchr/testify/suite" + "github.com/goravel/framework/testing/mock" + "panel/app/models" ) diff --git a/go.mod b/go.mod index a3f14a61..8754576c 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,9 @@ require ( github.com/gookit/color v1.5.3 github.com/goravel/framework v1.12.3 github.com/iancoleman/strcase v0.2.0 + github.com/imroc/req/v3 v3.37.1 github.com/mojocn/base64Captcha v1.3.5 + github.com/shirou/gopsutil v3.21.11+incompatible github.com/spf13/cast v1.5.1 github.com/stretchr/testify v1.8.4 ) @@ -29,6 +31,7 @@ require ( github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae // indirect github.com/RichardKnop/machinery/v2 v2.0.11 // indirect + github.com/andybalholm/brotli v1.0.5 // indirect github.com/aws/aws-sdk-go v1.37.16 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect @@ -45,6 +48,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gaukas/godicttls v0.0.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.9.1 // indirect github.com/glebarez/go-sqlite v1.21.1 // indirect @@ -57,6 +61,7 @@ require ( github.com/go-redsync/redsync/v4 v4.0.4 // indirect github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/go-stack/stack v1.8.0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect @@ -66,10 +71,12 @@ require ( github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gomodule/redigo v2.0.0+incompatible // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/google/s2a-go v0.1.3 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect @@ -107,6 +114,7 @@ require ( github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/runc v1.1.5 // indirect @@ -116,11 +124,15 @@ require ( github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-19 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/quic-go v0.36.0 // indirect + github.com/refraction-networking/utls v1.3.2 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -149,14 +161,15 @@ require ( go.uber.org/atomic v1.11.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.10.0 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect - golang.org/x/mod v0.10.0 // indirect + golang.org/x/mod v0.11.0 // indirect golang.org/x/net v0.11.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sync v0.2.0 // indirect + golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.9.0 // indirect golang.org/x/text v0.10.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/tools v0.10.0 // indirect google.golang.org/api v0.122.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 // indirect diff --git a/go.sum b/go.sum index 53e0fe99..daf38099 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,8 @@ github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae h1:DcFpTQBYQ9C github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae/go.mod h1:rJJ84PyA/Wlmw1hO+xTzV2wsSUon6J5ktg0g8BF2PuU= github.com/RichardKnop/machinery/v2 v2.0.11 h1:BTfLGOmOju3W/OtlZmLX26OjYNZsU4PJo04pQReycdc= github.com/RichardKnop/machinery/v2 v2.0.11/go.mod h1:b5Q6cT/w7YLlIl4Vi+jpdEoyYiqhTgx+0USoKb1wzqU= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.37.16 h1:Q4YOP2s00NpB9wfmTDZArdcLRuG9ijbnoAwTW3ivleI= @@ -153,6 +155,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk= +github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI= github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlLgiA= github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -172,6 +176,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -202,6 +207,8 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -259,6 +266,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -312,7 +321,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= +github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= @@ -372,6 +382,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imroc/req/v3 v3.37.1 h1:HUs5/jazZWTlTGMs3PCV15vqQq/ha9fY1NV+RYACrxI= +github.com/imroc/req/v3 v3.37.1/go.mod h1:DECzjVIrj6jcUr5n6e+z0ygmCO93rx4Jy0RjOEe1YCI= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= @@ -474,12 +486,14 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= @@ -507,6 +521,16 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.36.0 h1:JIrO7p7Ug6hssFcARjWDiqS2RAKJHCiwPxBAA989rbI= +github.com/quic-go/quic-go v0.36.0/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= +github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8= +github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -618,6 +642,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -677,7 +702,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= @@ -703,10 +729,11 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -743,6 +770,7 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -774,10 +802,11 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -832,6 +861,7 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -932,10 +962,11 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/plugins/openresty/http/controllers/openresty_controller.go b/plugins/openresty/http/controllers/openresty_controller.go index 69f09258..1a3a1948 100644 --- a/plugins/openresty/http/controllers/openresty_controller.go +++ b/plugins/openresty/http/controllers/openresty_controller.go @@ -1,7 +1,19 @@ package controllers import ( + "os" + "os/exec" + "regexp" + "strings" + "time" + + "github.com/imroc/req/v3" + "github.com/spf13/cast" + "github.com/goravel/framework/contracts/http" + + "panel/app/http/controllers" + "panel/packages/helpers" ) type OpenRestyController struct { @@ -14,8 +26,282 @@ func NewOpenrestyController() *OpenRestyController { } } -func (r *OpenRestyController) Show(ctx http.Context) { - ctx.Response().Success().Json(http.Json{ - "Hello": "Goravel", - }) +// Status 获取运行状态 +func (r *OpenRestyController) Status(ctx http.Context) { + cmd := exec.Command("bash", "-c", "systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + } + + status := strings.TrimSpace(string(out)) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Success(ctx, false) + } +} + +// Reload 重载配置 +func (r *OpenRestyController) Reload(ctx http.Context) { + cmd := exec.Command("bash", "-c", "systemctl reload openresty") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + cmd = exec.Command("bash", "-c", "systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + out, err = cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + status := strings.TrimSpace(string(out)) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Error(ctx, 1, "重载OpenResty失败: "+string(out)) + } +} + +// Start 启动OpenResty +func (r *OpenRestyController) Start(ctx http.Context) { + cmd := exec.Command("bash", "-c", "systemctl start openresty") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + cmd = exec.Command("bash", "-c", "systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + out, err = cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + status := strings.TrimSpace(string(out)) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Error(ctx, 1, "启动OpenResty失败: "+string(out)) + } +} + +// Stop 停止OpenResty +func (r *OpenRestyController) Stop(ctx http.Context) { + cmd := exec.Command("bash", "-c", "systemctl stop openresty") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + cmd = exec.Command("bash", "-c", "systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + out, err = cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + status := strings.TrimSpace(string(out)) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Error(ctx, 1, "停止OpenResty失败: "+string(out)) + } +} + +// Restart 重启OpenResty +func (r *OpenRestyController) Restart(ctx http.Context) { + cmd := exec.Command("bash", "-c", "systemctl restart openresty") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + cmd = exec.Command("bash", "-c", "systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + out, err = cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, err.Error()) + return + } + + status := strings.TrimSpace(string(out)) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Error(ctx, 1, "重启OpenResty失败: "+string(out)) + } +} + +// GetConfig 获取配置 +func (r *OpenRestyController) GetConfig(ctx http.Context) { + config, err := os.ReadFile("/www/server/openresty/conf/nginx.conf") + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty配置失败") + return + } + + controllers.Success(ctx, string(config)) +} + +// SaveConfig 保存配置 +func (r *OpenRestyController) SaveConfig(ctx http.Context) { + config := ctx.Request().Input("config") + if len(config) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "配置不能为空") + return + } + + oldConfig, err := os.ReadFile("/www/server/openresty/conf/nginx.conf") + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty配置失败") + return + } + + err = os.WriteFile("/www/server/openresty/conf/nginx.conf", []byte(config), 0644) + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "保存OpenResty配置失败") + return + } + + cmd := exec.Command("bash", "-c", "openresty -t 2>&1") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "检查OpenResty配置失败") + return + } + + if !strings.Contains(string(out), "test is successful") { + err = os.WriteFile("/www/server/openresty/conf/nginx.conf", oldConfig, 0644) + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "保存OpenResty配置失败") + return + } + + controllers.Error(ctx, http.StatusForbidden, "OpenResty配置有误,请修正后再保存: "+string(out)) + } + + cmd = exec.Command("bash", "-c", "systemctl reload openresty") + _, err = cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "重载OpenResty配置失败") + return + } + + controllers.Success(ctx, true) +} + +// ErrorLog 获取错误日志 +func (r *OpenRestyController) ErrorLog(ctx http.Context) { + cmd := exec.Command("bash", "-c", "tail -n 100 /www/wwwlogs/nginx_error.log") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty错误日志失败") + return + } + + controllers.Success(ctx, string(out)) +} + +// ClearErrorLog 清空错误日志 +func (r *OpenRestyController) ClearErrorLog(ctx http.Context) { + cmd := exec.Command("bash", "-c", "echo '' > /www/wwwlogs/nginx_error.log") + _, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "清空OpenResty错误日志失败") + return + } + + controllers.Success(ctx, true) +} + +// Load 获取负载 +func (r *OpenRestyController) Load(ctx http.Context) { + client := req.C().SetTimeout(10 * time.Second) + resp, err := client.R().Get("http://127.0.0.1/nginx_status") + if err != nil || !resp.IsSuccessState() { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败") + return + } + + raw := resp.String() + var data map[int]map[string]any + + cmd := exec.Command("bash", "-c", "ps aux | grep nginx | grep 'worker process' | wc -l") + out, err := cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败") + return + } + workers := strings.TrimSpace(string(out)) + data[0]["name"] = "工作进程" + data[0]["value"] = workers + + cmd = exec.Command("bash", "-c", "ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'") + out, err = cmd.CombinedOutput() + if err != nil { + controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败") + return + } + mem := helpers.FormatBytes(cast.ToFloat64(strings.TrimSpace(string(out)))) + data[1]["name"] = "内存占用" + data[1]["value"] = mem + + match := regexp.MustCompile(`Active connections:\s+(\d+)`).FindStringSubmatch(raw) + if len(match) == 2 { + data[2]["name"] = "活跃连接数" + data[2]["value"] = match[1] + } + + match = regexp.MustCompile(`server accepts handled requests\s+(\d+)\s+(\d+)\s+(\d+)`).FindStringSubmatch(raw) + if len(match) == 4 { + data[3]["name"] = "总连接次数" + data[3]["value"] = match[1] + data[4]["name"] = "总握手次数" + data[4]["value"] = match[2] + data[5]["name"] = "总请求次数" + data[5]["value"] = match[3] + } + + match = regexp.MustCompile(`Reading:\s+(\d+)\s+Writing:\s+(\d+)\s+Waiting:\s+(\d+)`).FindStringSubmatch(raw) + if len(match) == 4 { + data[6]["name"] = "请求数" + data[6]["value"] = match[1] + data[7]["name"] = "响应数" + data[7]["value"] = match[2] + data[8]["name"] = "驻留进程" + data[8]["value"] = match[3] + } + + controllers.Success(ctx, data) } diff --git a/plugins/openresty/openresty.go b/plugins/openresty/openresty.go index 19d2c92e..be7371f1 100644 --- a/plugins/openresty/openresty.go +++ b/plugins/openresty/openresty.go @@ -6,6 +6,8 @@ const ( Description = "OpenResty® 是一款基于 NGINX 和 LuaJIT 的 Web 平台。" Slug = "openresty" Version = "1.21.4.1" + Requires = "" + Excludes = "" ) func Boot() { diff --git a/plugins/openresty/public/views/openresty.html b/plugins/openresty/public/views/openresty.html new file mode 100644 index 00000000..0b16f174 --- /dev/null +++ b/plugins/openresty/public/views/openresty.html @@ -0,0 +1,250 @@ + +OpenResty +
+
+
+
+
OpenResty管理
+
+
+
    +
  • 运行状态
  • +
  • 配置修改
  • +
  • 负载状态
  • +
  • 错误日志
  • +
+
+
+
当前状态:获取中
+
+ + + + +
+
+
+
此处修改的是OpenResty主配置文件,如果你不了解各参数的含义,请不要随意修改!
+ 提示:Ctrl+F 搜索关键字,Ctrl+S 保存,Ctrl+H 查找替换! +
+
+
+ +
+
+
+
+
+
+
+ +
+
+                                    获取中...
+                                
+
+
+
+
+
+
+
+
+ + diff --git a/plugins/openresty/routes.go b/plugins/openresty/routes.go index de46aff8..bf749777 100644 --- a/plugins/openresty/routes.go +++ b/plugins/openresty/routes.go @@ -1,22 +1,27 @@ package openresty import ( - "github.com/goravel/framework/contracts/http" "github.com/goravel/framework/contracts/route" "github.com/goravel/framework/facades" + "panel/app/http/middleware" "panel/plugins/openresty/http/controllers" ) func Route() { - facades.Route().Prefix("api/plugins/openresty").Group(func(route route.Route) { - route.Get("/openresty", func(ctx http.Context) { - ctx.Response().Json(http.StatusOK, http.Json{ - "Hello": "Openresty", - }) - }) - + facades.Route().Prefix("api/plugins/openresty").Middleware(middleware.Jwt()).Group(func(route route.Route) { openRestyController := controllers.NewOpenrestyController() - route.Get("/openresty/users/{id}", openRestyController.Show) + route.Get("status", openRestyController.Status) + route.Post("reload", openRestyController.Reload) + route.Post("start", openRestyController.Start) + route.Post("stop", openRestyController.Stop) + route.Post("restart", openRestyController.Restart) + route.Get("load", openRestyController.Load) + route.Get("config", openRestyController.GetConfig) + route.Post("config", openRestyController.SaveConfig) + route.Get("errorLog", openRestyController.ErrorLog) + route.Get("cleanErrorLog", openRestyController.ClearErrorLog) }) + + facades.Route().StaticFile("panel/views/plugins/openresty.html", "plugins/openresty/public/views/openresty.html") } diff --git a/public/index.html b/public/index.html index d0ece897..336b099b 100644 --- a/public/index.html +++ b/public/index.html @@ -41,7 +41,7 @@ + + diff --git a/public/panel/views/website/add.html b/public/panel/views/website/add.html new file mode 100644 index 00000000..032cba24 --- /dev/null +++ b/public/panel/views/website/add.html @@ -0,0 +1,166 @@ + + + diff --git a/public/panel/views/website/default_settings.html b/public/panel/views/website/default_settings.html new file mode 100644 index 00000000..218d39a1 --- /dev/null +++ b/public/panel/views/website/default_settings.html @@ -0,0 +1,82 @@ + + + diff --git a/public/panel/views/website/edit.html b/public/panel/views/website/edit.html new file mode 100644 index 00000000..e5315dac --- /dev/null +++ b/public/panel/views/website/edit.html @@ -0,0 +1,379 @@ + + + diff --git a/public/panel/views/website/list.html b/public/panel/views/website/list.html new file mode 100644 index 00000000..66879851 --- /dev/null +++ b/public/panel/views/website/list.html @@ -0,0 +1,241 @@ + +网站 +
+
+
+
+
网站列表
+
+
+ + + + + + + + + +
+
+
+
+
+ + diff --git a/public/res/views/template/addresslist.html b/public/res/views/template/addresslist.html deleted file mode 100644 index 3b54f34e..00000000 --- a/public/res/views/template/addresslist.html +++ /dev/null @@ -1,368 +0,0 @@ -通讯录 - - - -
- -
- -
-
- - - - - - - - - -
-
- - \ No newline at end of file diff --git a/public/res/views/template/caller.html b/public/res/views/template/caller.html deleted file mode 100644 index 69b1583d..00000000 --- a/public/res/views/template/caller.html +++ /dev/null @@ -1,203 +0,0 @@ -客户列表 - - - -
- -
- -
-
-
- - - -
-
-
    -
  • 所有联系人
  • -
  • 联系方式
  • -
  • 联系地址
  • -
-
-
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
- -
-

张三 最近联系:1 小时前

-

浙江省广州市越秀区中山六路109 -

-
- - - -
-
- -
-
-
-
-
- - \ No newline at end of file diff --git a/public/res/views/template/goodslist.html b/public/res/views/template/goodslist.html deleted file mode 100644 index 97971721..00000000 --- a/public/res/views/template/goodslist.html +++ /dev/null @@ -1,422 +0,0 @@ -商品列表 - - - -
- -
- -
-
- - - - - - - - - - - - - - - - -
-
-
-
-
- - \ No newline at end of file diff --git a/public/res/views/template/msgboard.html b/public/res/views/template/msgboard.html deleted file mode 100644 index d4e7233a..00000000 --- a/public/res/views/template/msgboard.html +++ /dev/null @@ -1,100 +0,0 @@ -留言板 - - - -
- -
- -
-
-
-
-
-
- -
-
- -
-
- -
-
- - - -
-
-
-
-
-
- - - -
-

张三

-

- - - 从移动 - 11分钟前 - -

-
-

- 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容

-
-
- - - -
-

张三

-

- - - 从移动 - 11分钟前 - -

-
-

- 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容

-
-
- 更多 -
-
-
-
- - \ No newline at end of file diff --git a/public/res/views/template/personalpage.html b/public/res/views/template/personalpage.html deleted file mode 100644 index 058b94ce..00000000 --- a/public/res/views/template/personalpage.html +++ /dev/null @@ -1,443 +0,0 @@ -个人主页 - - - -
- -
- -
-
-
-
-
-
-
- -
-

张三

-

中国非知名前端

-
- - - - -
- -
-
-

- 关于我 -

- -
- 介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍介绍 -
-

- 技能 -

- -
-
-
-
-
-
-
-
-
-

52K

- 关注 -
-
-

72K

- 以下 -
-
-

5343

- 照片 -
-
-

4.5

- 排行 -
-
-
- -
-
-
-
-
- - - -
-
-

张三普通照片添加了新的照片 -

-

- - - 从移动 - 11分钟前 - -

-
-

- 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容

- - - -
-
- - - - -
-
- 张三 - 3月21日 19:56 -
-
一次难忘更难得的拍摄经历 谢谢
-
-
-
- - - -
-
- 张三 - 3月21日 19:56 -
-
一次难忘更难得的拍摄经历 谢谢
-
-
-
- - - -
-
- 张三 - 3月21日 19:56 -
-
一次难忘更难得的拍摄经历 谢谢
-
-
- 更多 -
-
-
-
- - - -
-
-

张三普通照片添加了新的照片 -

-

- - - 从移动 - 11分钟前 - -

-
-

- 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容

- -
-
-
-
-
-
-
-
-

- - 画廊 -

-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- 更多 -
-
-
-
- -
-
-
-
-
-
-
- - \ No newline at end of file diff --git a/public/res/views/template/search.html b/public/res/views/template/search.html deleted file mode 100644 index f2891b43..00000000 --- a/public/res/views/template/search.html +++ /dev/null @@ -1,100 +0,0 @@ -搜索结果 - - - -
- -
- -
-
-
-
-
-

- 关键词 查询到 - 66 个结果 -

-

耗时:350ms

-
-
- -
    -
  • -
    -

    前端的进化?

    -

    - 在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。

    -
    -
  • -
  • - - - -
    -

    前端 UI

    -

    UI 设计(或称界面设计)是指对软件的人机交互、操作逻辑、界面美观的整体设计。 UI 设计分为实体 - UI和虚拟 UI,互联网常用的 UI 设计是虚拟 UI, UI即 User Interface (用户界面)的简称。

    -
    -
  • -
  • -
    -

    前端的进化?

    -

    - 在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。

    -

    - 前端 - 性别 - -

    -
    -
  • -
  • -
    -

    - 热点 - UI 设计 -

    -

    UI 设计(或称界面设计)是指对软件的人机交互、操作逻辑、界面美观的整体设计。 UI 设计分为实体 - UI和虚拟 UI,互联网常用的 UI 设计是虚拟 UI, UI即 User Interface (用户界面)的简称。

    -
    -
  • -
  • -
    -

    前端的进化?

    -

    - 在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。在前端技术的快速发展中找准你的定位,在思考与实践中沉淀。。

    -
    -
  • -
-
- -
-
-
-
-
- - diff --git a/public/res/views/template/tips/test.html b/public/res/views/template/tips/test.html deleted file mode 100644 index 9d790cfa..00000000 --- a/public/res/views/template/tips/test.html +++ /dev/null @@ -1,12 +0,0 @@ -出错了 - -
-
- - -
- 好像出错了呢 -
- -
-
\ No newline at end of file diff --git a/public/res/views/template/说明.txt b/public/res/views/template/说明.txt deleted file mode 100644 index fac6420d..00000000 --- a/public/res/views/template/说明.txt +++ /dev/null @@ -1,2 +0,0 @@ - -该目录存放【模板】的视图文件 \ No newline at end of file diff --git a/public/robots.txt b/public/robots.txt index eb053628..1f53798b 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,2 +1,2 @@ User-agent: * -Disallow: +Disallow: / diff --git a/routes/web.go b/routes/web.go index 8129e112..dd497079 100644 --- a/routes/web.go +++ b/routes/web.go @@ -18,6 +18,7 @@ func Web() { r.Middleware(middleware.Jwt()).Get("homePlugins", infoController.HomePlugins) r.Middleware(middleware.Jwt()).Get("nowMonitor", infoController.NowMonitor) r.Middleware(middleware.Jwt()).Get("systemInfo", infoController.SystemInfo) + r.Middleware(middleware.Jwt()).Get("installedDbAndPhp", infoController.InstalledDbAndPhp) }) r.Prefix("user").Group(func(r route.Route) { userController := controllers.NewUserController() @@ -28,6 +29,10 @@ func Web() { taskController := controllers.NewTaskController() r.Get("status", taskController.Status) }) + r.Prefix("website").Middleware(middleware.Jwt()).Group(func(r route.Route) { + websiteController := controllers.NewWebsiteController() + r.Get("list", websiteController.List) + }) }) facades.Route().Fallback(func(ctx http.Context) {