mirror of
https://github.com/tnb-labs/panel.git
synced 2026-09-01 04:17:20 +08:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 49b72aa656 | |||
| e0f642cbff | |||
| eb2c6cab81 | |||
| 0a3d3828c8 | |||
| 46b431de30 | |||
| 8a5b46ad7e | |||
| 5bd14946de | |||
| f6c091c725 | |||
| f4dc94ad9a | |||
| 8bcc0c0c05 | |||
| 0be04e1859 | |||
| bec9336f2f | |||
| 0be4ce9891 | |||
| 634a9a3219 | |||
| 1f2a32f883 | |||
| 32a56aa2dc | |||
| 8185a69354 | |||
| d41862f63b | |||
| 20e5122425 | |||
| 17bb8ad62b | |||
| 43624de2e4 | |||
| cc6a45b127 | |||
| 7a4a71f0a0 | |||
| 27cbb92a06 | |||
| 5ddbdfc5df | |||
| b3b1b0971f | |||
| 9caad365e9 | |||
| 5b54232e16 | |||
| a510bdb05d | |||
| 50a8b16832 | |||
| 2f56241da1 | |||
| 8557259b53 | |||
| 1d7ea0280a | |||
| 10145da2f9 | |||
| 6ba7d01875 | |||
| 763fa7379d | |||
| a36eaf7e9a | |||
| 18de16047d |
@@ -1,32 +0,0 @@
|
||||
root = "."
|
||||
tmp_dir = "storage/temp"
|
||||
|
||||
[build]
|
||||
bin = "./storage/temp/main.exe --env=panel.conf"
|
||||
cmd = "go build -o ./storage/temp/main.exe ."
|
||||
delay = 1000
|
||||
exclude_dir = ["storage", "database"]
|
||||
exclude_file = []
|
||||
exclude_regex = []
|
||||
exclude_unchanged = false
|
||||
follow_symlink = false
|
||||
full_bin = ""
|
||||
include_dir = []
|
||||
include_ext = ["go", "tpl", "tmpl", "html"]
|
||||
kill_delay = "0s"
|
||||
log = "build-errors.log"
|
||||
send_interrupt = false
|
||||
stop_on_error = true
|
||||
|
||||
[color]
|
||||
app = ""
|
||||
build = "yellow"
|
||||
main = "magenta"
|
||||
runner = "green"
|
||||
watcher = "cyan"
|
||||
|
||||
[log]
|
||||
time = false
|
||||
|
||||
[misc]
|
||||
clean_on_exit = false
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
CGO_ENABLED: 0
|
||||
GOOS: linux
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
run: go build -ldflags '-s -w --extldflags "-static"' -o panel-${{ matrix.goarch }}
|
||||
run: go build -ldflags '-s -w --extldflags "-static"' -tags='nomsgpack' -o panel-${{ matrix.goarch }}
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
unzip frontend.zip
|
||||
mv dist public
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean
|
||||
|
||||
@@ -19,6 +19,5 @@ jobs:
|
||||
cp panel-example.conf .env
|
||||
echo "DB_FILE=$(pwd)/storage/panel.db" >> .env
|
||||
go run . artisan key:generate
|
||||
go run . artisan migrate
|
||||
- name: Run tests
|
||||
run: go test ./...
|
||||
|
||||
+1
-2
@@ -40,7 +40,6 @@ unit_test:
|
||||
- cp panel-example.conf .env
|
||||
- echo "DB_FILE=$(pwd)/storage/panel.db" >> .env
|
||||
- go run . artisan key:generate
|
||||
- go run . artisan migrate
|
||||
- go test -v -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
build:
|
||||
@@ -48,7 +47,7 @@ build:
|
||||
extends: .go_cache
|
||||
script:
|
||||
- go mod download
|
||||
- CGO_ENABLED=0 go build -ldflags '-s -w --extldflags "-static"' -o panel
|
||||
- CGO_ENABLED=0 go build -ldflags '-s -w --extldflags "-static"' -tags='nomsgpack' -o panel
|
||||
artifacts:
|
||||
name: "panel"
|
||||
paths:
|
||||
|
||||
+2
-1
@@ -15,6 +15,8 @@ builds:
|
||||
- v2
|
||||
ldflags:
|
||||
- -s -w --extldflags "-static"
|
||||
tags:
|
||||
- nomsgpack
|
||||
|
||||
upx:
|
||||
- enabled: true
|
||||
@@ -40,7 +42,6 @@ archives:
|
||||
- docs/*
|
||||
- public/*
|
||||
- storage/*
|
||||
- database/*
|
||||
- lang/*
|
||||
- scripts/*
|
||||
- panel-example.conf
|
||||
|
||||
@@ -28,7 +28,7 @@ func NewCertController() *CertController {
|
||||
//
|
||||
// @Summary 获取 CA 提供商
|
||||
// @Description 获取面板证书管理支持的 CA 提供商
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse
|
||||
@@ -62,7 +62,7 @@ func (r *CertController) CAProviders(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取 DNS 提供商
|
||||
// @Description 获取面板证书管理支持的 DNS 提供商
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse
|
||||
@@ -88,7 +88,7 @@ func (r *CertController) DNSProviders(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取算法列表
|
||||
// @Description 获取面板证书管理支持的算法列表
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse
|
||||
@@ -118,7 +118,7 @@ func (r *CertController) Algorithms(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取用户列表
|
||||
// @Description 获取面板证书管理的 ACME 用户列表
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
@@ -126,7 +126,7 @@ func (r *CertController) Algorithms(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/users [get]
|
||||
func (r *CertController) UserList(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func (r *CertController) UserList(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 添加 ACME 用户
|
||||
// @Description 添加 ACME 用户到面板证书管理
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -160,7 +160,7 @@ func (r *CertController) UserList(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/users [post]
|
||||
func (r *CertController) UserStore(ctx http.Context) http.Response {
|
||||
var storeRequest requests.UserStore
|
||||
sanitize := Sanitize(ctx, &storeRequest)
|
||||
sanitize := SanitizeRequest(ctx, &storeRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func (r *CertController) UserStore(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 更新 ACME 用户
|
||||
// @Description 更新面板证书管理的 ACME 用户
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -190,7 +190,7 @@ func (r *CertController) UserStore(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/users/{id} [put]
|
||||
func (r *CertController) UserUpdate(ctx http.Context) http.Response {
|
||||
var updateRequest requests.UserUpdate
|
||||
sanitize := Sanitize(ctx, &updateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -211,7 +211,7 @@ func (r *CertController) UserUpdate(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取 ACME 用户
|
||||
// @Description 获取面板证书管理的 ACME 用户
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "用户 ID"
|
||||
@@ -219,7 +219,7 @@ func (r *CertController) UserUpdate(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/users/{id} [get]
|
||||
func (r *CertController) UserShow(ctx http.Context) http.Response {
|
||||
var showAndDestroyRequest requests.UserShowAndDestroy
|
||||
sanitize := Sanitize(ctx, &showAndDestroyRequest)
|
||||
sanitize := SanitizeRequest(ctx, &showAndDestroyRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -240,7 +240,7 @@ func (r *CertController) UserShow(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 删除 ACME 用户
|
||||
// @Description 删除面板证书管理的 ACME 用户
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -249,7 +249,7 @@ func (r *CertController) UserShow(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/users/{id} [delete]
|
||||
func (r *CertController) UserDestroy(ctx http.Context) http.Response {
|
||||
var showAndDestroyRequest requests.UserShowAndDestroy
|
||||
sanitize := Sanitize(ctx, &showAndDestroyRequest)
|
||||
sanitize := SanitizeRequest(ctx, &showAndDestroyRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -270,7 +270,7 @@ func (r *CertController) UserDestroy(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取 DNS 接口列表
|
||||
// @Description 获取面板证书管理的 DNS 接口列表
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
@@ -278,7 +278,7 @@ func (r *CertController) UserDestroy(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/dns [get]
|
||||
func (r *CertController) DNSList(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func (r *CertController) DNSList(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 添加 DNS 接口
|
||||
// @Description 添加 DNS 接口到面板证书管理
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -312,7 +312,7 @@ func (r *CertController) DNSList(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/dns [post]
|
||||
func (r *CertController) DNSStore(ctx http.Context) http.Response {
|
||||
var storeRequest requests.DNSStore
|
||||
sanitize := Sanitize(ctx, &storeRequest)
|
||||
sanitize := SanitizeRequest(ctx, &storeRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -332,7 +332,7 @@ func (r *CertController) DNSStore(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取 DNS 接口
|
||||
// @Description 获取面板证书管理的 DNS 接口
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "DNS 接口 ID"
|
||||
@@ -340,7 +340,7 @@ func (r *CertController) DNSStore(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/dns/{id} [get]
|
||||
func (r *CertController) DNSShow(ctx http.Context) http.Response {
|
||||
var showAndDestroyRequest requests.DNSShowAndDestroy
|
||||
sanitize := Sanitize(ctx, &showAndDestroyRequest)
|
||||
sanitize := SanitizeRequest(ctx, &showAndDestroyRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -361,7 +361,7 @@ func (r *CertController) DNSShow(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 更新 DNS 接口
|
||||
// @Description 更新面板证书管理的 DNS 接口
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -371,7 +371,7 @@ func (r *CertController) DNSShow(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/dns/{id} [put]
|
||||
func (r *CertController) DNSUpdate(ctx http.Context) http.Response {
|
||||
var updateRequest requests.DNSUpdate
|
||||
sanitize := Sanitize(ctx, &updateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -392,7 +392,7 @@ func (r *CertController) DNSUpdate(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 删除 DNS 接口
|
||||
// @Description 删除面板证书管理的 DNS 接口
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -401,7 +401,7 @@ func (r *CertController) DNSUpdate(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/dns/{id} [delete]
|
||||
func (r *CertController) DNSDestroy(ctx http.Context) http.Response {
|
||||
var showAndDestroyRequest requests.DNSShowAndDestroy
|
||||
sanitize := Sanitize(ctx, &showAndDestroyRequest)
|
||||
sanitize := SanitizeRequest(ctx, &showAndDestroyRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -422,7 +422,7 @@ func (r *CertController) DNSDestroy(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取证书列表
|
||||
// @Description 获取面板证书管理的证书列表
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
@@ -430,7 +430,7 @@ func (r *CertController) DNSDestroy(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/certs [get]
|
||||
func (r *CertController) CertList(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -455,7 +455,7 @@ func (r *CertController) CertList(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 添加证书
|
||||
// @Description 添加证书到面板证书管理
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -464,7 +464,7 @@ func (r *CertController) CertList(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/certs [post]
|
||||
func (r *CertController) CertStore(ctx http.Context) http.Response {
|
||||
var storeRequest requests.CertStore
|
||||
sanitize := Sanitize(ctx, &storeRequest)
|
||||
sanitize := SanitizeRequest(ctx, &storeRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -484,7 +484,7 @@ func (r *CertController) CertStore(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 更新证书
|
||||
// @Description 更新面板证书管理的证书
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -494,7 +494,7 @@ func (r *CertController) CertStore(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/certs/{id} [put]
|
||||
func (r *CertController) CertUpdate(ctx http.Context) http.Response {
|
||||
var updateRequest requests.CertUpdate
|
||||
sanitize := Sanitize(ctx, &updateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -515,7 +515,7 @@ func (r *CertController) CertUpdate(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取证书
|
||||
// @Description 获取面板证书管理的证书
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "证书 ID"
|
||||
@@ -523,7 +523,7 @@ func (r *CertController) CertUpdate(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/certs/{id} [get]
|
||||
func (r *CertController) CertShow(ctx http.Context) http.Response {
|
||||
var showAndDestroyRequest requests.CertShowAndDestroy
|
||||
sanitize := Sanitize(ctx, &showAndDestroyRequest)
|
||||
sanitize := SanitizeRequest(ctx, &showAndDestroyRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -544,7 +544,7 @@ func (r *CertController) CertShow(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 删除证书
|
||||
// @Description 删除面板证书管理的证书
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -553,7 +553,7 @@ func (r *CertController) CertShow(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/certs/{id} [delete]
|
||||
func (r *CertController) CertDestroy(ctx http.Context) http.Response {
|
||||
var showAndDestroyRequest requests.CertShowAndDestroy
|
||||
sanitize := Sanitize(ctx, &showAndDestroyRequest)
|
||||
sanitize := SanitizeRequest(ctx, &showAndDestroyRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -574,7 +574,7 @@ func (r *CertController) CertDestroy(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 签发证书
|
||||
// @Description 签发面板证书管理的证书
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -583,7 +583,7 @@ func (r *CertController) CertDestroy(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/obtain [post]
|
||||
func (r *CertController) Obtain(ctx http.Context) http.Response {
|
||||
var obtainRequest requests.Obtain
|
||||
sanitize := Sanitize(ctx, &obtainRequest)
|
||||
sanitize := SanitizeRequest(ctx, &obtainRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -616,7 +616,7 @@ func (r *CertController) Obtain(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 续签证书
|
||||
// @Description 续签面板证书管理的证书
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -625,7 +625,7 @@ func (r *CertController) Obtain(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/renew [post]
|
||||
func (r *CertController) Renew(ctx http.Context) http.Response {
|
||||
var renewRequest requests.Renew
|
||||
sanitize := Sanitize(ctx, &renewRequest)
|
||||
sanitize := SanitizeRequest(ctx, &renewRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -645,7 +645,7 @@ func (r *CertController) Renew(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取手动 DNS 记录
|
||||
// @Description 获取签发证书所需的 DNS 记录
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -654,7 +654,7 @@ func (r *CertController) Renew(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/manualDNS [post]
|
||||
func (r *CertController) ManualDNS(ctx http.Context) http.Response {
|
||||
var obtainRequest requests.Obtain
|
||||
sanitize := Sanitize(ctx, &obtainRequest)
|
||||
sanitize := SanitizeRequest(ctx, &obtainRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -674,7 +674,7 @@ func (r *CertController) ManualDNS(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 部署证书
|
||||
// @Description 部署面板证书管理的证书
|
||||
// @Tags 证书管理
|
||||
// @Tags TLS证书
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -683,7 +683,7 @@ func (r *CertController) ManualDNS(ctx http.Context) http.Response {
|
||||
// @Router /panel/cert/deploy [post]
|
||||
func (r *CertController) Deploy(ctx http.Context) http.Response {
|
||||
var deployRequest requests.CertDeploy
|
||||
sanitize := Sanitize(ctx, &deployRequest)
|
||||
sanitize := SanitizeRequest(ctx, &deployRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func NewContainerController() *ContainerController {
|
||||
// @Router /panel/container/list [get]
|
||||
func (r *ContainerController) ContainerList(ctx http.Context) http.Response {
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ func (r *ContainerController) ContainerSearch(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/create [post]
|
||||
func (r *ContainerController) ContainerCreate(ctx http.Context) http.Response {
|
||||
var request requests.ContainerCreate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ func (r *ContainerController) ContainerCreate(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/remove [post]
|
||||
func (r *ContainerController) ContainerRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ func (r *ContainerController) ContainerRemove(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/start [post]
|
||||
func (r *ContainerController) ContainerStart(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ func (r *ContainerController) ContainerStart(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/stop [post]
|
||||
func (r *ContainerController) ContainerStop(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ func (r *ContainerController) ContainerStop(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/restart [post]
|
||||
func (r *ContainerController) ContainerRestart(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ func (r *ContainerController) ContainerRestart(ctx http.Context) http.Response {
|
||||
// @Success 200 {object} SuccessResponse
|
||||
func (r *ContainerController) ContainerPause(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ func (r *ContainerController) ContainerPause(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/unpause [post]
|
||||
func (r *ContainerController) ContainerUnpause(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ func (r *ContainerController) ContainerUnpause(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/inspect [get]
|
||||
func (r *ContainerController) ContainerInspect(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -382,7 +382,7 @@ func (r *ContainerController) ContainerInspect(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/kill [post]
|
||||
func (r *ContainerController) ContainerKill(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ func (r *ContainerController) ContainerKill(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/rename [post]
|
||||
func (r *ContainerController) ContainerRename(ctx http.Context) http.Response {
|
||||
var request requests.ContainerRename
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ func (r *ContainerController) ContainerRename(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/stats [get]
|
||||
func (r *ContainerController) ContainerStats(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ func (r *ContainerController) ContainerStats(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/exist [get]
|
||||
func (r *ContainerController) ContainerExist(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -476,7 +476,7 @@ func (r *ContainerController) ContainerExist(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/logs [get]
|
||||
func (r *ContainerController) ContainerLogs(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -517,7 +517,7 @@ func (r *ContainerController) ContainerPrune(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/network/list [get]
|
||||
func (r *ContainerController) NetworkList(ctx http.Context) http.Response {
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -542,7 +542,7 @@ func (r *ContainerController) NetworkList(ctx http.Context) http.Response {
|
||||
paged = []types.NetworkResource{}
|
||||
}
|
||||
|
||||
var items []any
|
||||
items := make([]any, 0)
|
||||
for _, item := range paged {
|
||||
var ipamConfig []any
|
||||
for _, v := range item.IPAM.Config {
|
||||
@@ -592,7 +592,7 @@ func (r *ContainerController) NetworkList(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/network/create [post]
|
||||
func (r *ContainerController) NetworkCreate(ctx http.Context) http.Response {
|
||||
var request requests.NetworkCreate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ func (r *ContainerController) NetworkCreate(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/network/remove [post]
|
||||
func (r *ContainerController) NetworkRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -639,7 +639,7 @@ func (r *ContainerController) NetworkRemove(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/network/exist [get]
|
||||
func (r *ContainerController) NetworkExist(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -663,7 +663,7 @@ func (r *ContainerController) NetworkExist(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/network/inspect [get]
|
||||
func (r *ContainerController) NetworkInspect(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ func (r *ContainerController) NetworkInspect(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/network/connect [post]
|
||||
func (r *ContainerController) NetworkConnect(ctx http.Context) http.Response {
|
||||
var request requests.NetworkConnectDisConnect
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -712,7 +712,7 @@ func (r *ContainerController) NetworkConnect(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/network/disconnect [post]
|
||||
func (r *ContainerController) NetworkDisconnect(ctx http.Context) http.Response {
|
||||
var request requests.NetworkConnectDisConnect
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -752,7 +752,7 @@ func (r *ContainerController) NetworkPrune(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/image/list [get]
|
||||
func (r *ContainerController) ImageList(ctx http.Context) http.Response {
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -777,7 +777,7 @@ func (r *ContainerController) ImageList(ctx http.Context) http.Response {
|
||||
paged = []image.Summary{}
|
||||
}
|
||||
|
||||
var items []any
|
||||
items := make([]any, 0)
|
||||
for _, item := range paged {
|
||||
items = append(items, map[string]any{
|
||||
"id": item.ID,
|
||||
@@ -808,7 +808,7 @@ func (r *ContainerController) ImageList(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/image/exist [get]
|
||||
func (r *ContainerController) ImageExist(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -833,7 +833,7 @@ func (r *ContainerController) ImageExist(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/image/pull [post]
|
||||
func (r *ContainerController) ImagePull(ctx http.Context) http.Response {
|
||||
var request requests.ImagePull
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -856,7 +856,7 @@ func (r *ContainerController) ImagePull(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/image/remove [post]
|
||||
func (r *ContainerController) ImageRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -896,7 +896,7 @@ func (r *ContainerController) ImagePrune(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/image/inspect [get]
|
||||
func (r *ContainerController) ImageInspect(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -920,7 +920,7 @@ func (r *ContainerController) ImageInspect(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/volume/list [get]
|
||||
func (r *ContainerController) VolumeList(ctx http.Context) http.Response {
|
||||
var request commonrequests.Paginate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -945,7 +945,7 @@ func (r *ContainerController) VolumeList(ctx http.Context) http.Response {
|
||||
paged = []*volume.Volume{}
|
||||
}
|
||||
|
||||
var items []any
|
||||
items := make([]any, 0)
|
||||
for _, item := range paged {
|
||||
var usage any
|
||||
if item.UsageData != nil {
|
||||
@@ -986,7 +986,7 @@ func (r *ContainerController) VolumeList(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/volume/create [post]
|
||||
func (r *ContainerController) VolumeCreate(ctx http.Context) http.Response {
|
||||
var request requests.VolumeCreate
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -1010,7 +1010,7 @@ func (r *ContainerController) VolumeCreate(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/volume/exist [get]
|
||||
func (r *ContainerController) VolumeExist(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -1034,7 +1034,7 @@ func (r *ContainerController) VolumeExist(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/volume/inspect [get]
|
||||
func (r *ContainerController) VolumeInspect(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -1058,7 +1058,7 @@ func (r *ContainerController) VolumeInspect(ctx http.Context) http.Response {
|
||||
// @Router /panel/container/volume/remove [post]
|
||||
func (r *ContainerController) VolumeRemove(ctx http.Context) http.Response {
|
||||
var request requests.ID
|
||||
if sanitize := Sanitize(ctx, &request); sanitize != nil {
|
||||
if sanitize := SanitizeRequest(ctx, &request); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ func ErrorSystem(ctx http.Context) http.Response {
|
||||
})
|
||||
}
|
||||
|
||||
// Sanitize 消毒请求参数
|
||||
func Sanitize(ctx http.Context, request http.FormRequest) http.Response {
|
||||
// SanitizeRequest 消毒请求参数
|
||||
func SanitizeRequest(ctx http.Context, request http.FormRequest) http.Response {
|
||||
errors, err := ctx.Request().ValidateRequest(request)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
@@ -50,3 +50,16 @@ func Sanitize(ctx http.Context, request http.FormRequest) http.Response {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sanitize 消毒参数
|
||||
func Sanitize(ctx http.Context, rules map[string]string) http.Response {
|
||||
validator, err := ctx.Request().Validate(rules)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -50,18 +50,14 @@ func (r *CronController) List(ctx http.Context) http.Response {
|
||||
|
||||
// Add 添加计划任务
|
||||
func (r *CronController) Add(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required",
|
||||
"script": "required",
|
||||
"type": "required|in:shell,backup,cutoff",
|
||||
"backup_type": "required_if:type,backup|in:website,mysql,postgresql",
|
||||
})
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
// 单独验证时间格式
|
||||
@@ -121,7 +117,7 @@ panel cutoff ${name} ${save} 2>&1
|
||||
return Error(ctx, http.StatusInternalServerError, "计划任务日志目录不存在")
|
||||
}
|
||||
shellFile := strconv.Itoa(int(carbon.Now().Timestamp())) + tools.RandomString(16)
|
||||
if err = tools.Write(shellDir+shellFile+".sh", shell, 0700); err != nil {
|
||||
if err := tools.Write(shellDir+shellFile+".sh", shell, 0700); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("dos2unix " + shellDir + shellFile + ".sh"); err != nil {
|
||||
@@ -136,8 +132,7 @@ panel cutoff ${name} ${save} 2>&1
|
||||
cron.Shell = shellDir + shellFile + ".sh"
|
||||
cron.Log = shellLogDir + shellFile + ".log"
|
||||
|
||||
err = facades.Orm().Query().Create(&cron)
|
||||
if err != nil {
|
||||
if err := facades.Orm().Query().Create(&cron); err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("保存计划任务失败")
|
||||
@@ -171,16 +166,12 @@ func (r *CronController) Script(ctx http.Context) http.Response {
|
||||
|
||||
// Update 更新计划任务
|
||||
func (r *CronController) Update(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required",
|
||||
"script": "required",
|
||||
})
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
// 单独验证时间格式
|
||||
@@ -189,8 +180,7 @@ func (r *CronController) Update(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
if err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron); err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在")
|
||||
}
|
||||
|
||||
@@ -200,15 +190,14 @@ func (r *CronController) Update(ctx http.Context) http.Response {
|
||||
|
||||
cron.Time = ctx.Request().Input("time")
|
||||
cron.Name = ctx.Request().Input("name")
|
||||
err = facades.Orm().Query().Save(&cron)
|
||||
if err != nil {
|
||||
if err := facades.Orm().Query().Save(&cron); err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("更新计划任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
if err = tools.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil {
|
||||
if err := tools.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("dos2unix " + cron.Shell); err != nil {
|
||||
@@ -253,25 +242,19 @@ func (r *CronController) Delete(ctx http.Context) http.Response {
|
||||
|
||||
// Status 更新计划任务状态
|
||||
func (r *CronController) Status(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"status": "bool",
|
||||
})
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
if err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron); err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在")
|
||||
}
|
||||
|
||||
cron.Status = ctx.Request().InputBool("status")
|
||||
err = facades.Orm().Query().Save(&cron)
|
||||
if err != nil {
|
||||
if err := facades.Orm().Query().Save(&cron); err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("更新计划任务状态失败")
|
||||
|
||||
@@ -27,7 +27,7 @@ func NewFileController() *FileController {
|
||||
//
|
||||
// @Summary 创建文件/目录
|
||||
// @Description 创建文件/目录到给定路径
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -36,7 +36,7 @@ func NewFileController() *FileController {
|
||||
// @Router /panel/file/create [post]
|
||||
func (r *FileController) Create(ctx http.Context) http.Response {
|
||||
var request requests.NotExist
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func (r *FileController) Create(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取文件内容
|
||||
// @Description 获取给定路径的文件内容
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -69,7 +69,7 @@ func (r *FileController) Create(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/content [get]
|
||||
func (r *FileController) Content(ctx http.Context) http.Response {
|
||||
var request requests.Exist
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -97,17 +97,16 @@ func (r *FileController) Content(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 保存文件内容
|
||||
// @Description 保存给定路径的文件内容
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.Save true "request"
|
||||
// @Param content body string true "content"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/file/save [post]
|
||||
func (r *FileController) Save(ctx http.Context) http.Response {
|
||||
var request requests.Save
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -128,7 +127,7 @@ func (r *FileController) Save(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 删除文件/目录
|
||||
// @Description 删除给定路径的文件/目录
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -137,7 +136,7 @@ func (r *FileController) Save(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/delete [post]
|
||||
func (r *FileController) Delete(ctx http.Context) http.Response {
|
||||
var request requests.Exist
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -153,7 +152,7 @@ func (r *FileController) Delete(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 上传文件
|
||||
// @Description 上传文件到给定路径
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -163,7 +162,7 @@ func (r *FileController) Delete(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/upload [post]
|
||||
func (r *FileController) Upload(ctx http.Context) http.Response {
|
||||
var request requests.Upload
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -195,7 +194,7 @@ func (r *FileController) Upload(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 移动文件/目录
|
||||
// @Description 移动文件/目录到给定路径,等效于重命名
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -204,7 +203,7 @@ func (r *FileController) Upload(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/move [post]
|
||||
func (r *FileController) Move(ctx http.Context) http.Response {
|
||||
var request requests.Move
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -225,7 +224,7 @@ func (r *FileController) Move(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 复制文件/目录
|
||||
// @Description 复制文件/目录到给定路径
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -234,7 +233,7 @@ func (r *FileController) Move(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/copy [post]
|
||||
func (r *FileController) Copy(ctx http.Context) http.Response {
|
||||
var request requests.Copy
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -255,7 +254,7 @@ func (r *FileController) Copy(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 下载文件
|
||||
// @Description 下载给定路径的文件
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -264,7 +263,7 @@ func (r *FileController) Copy(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/download [get]
|
||||
func (r *FileController) Download(ctx http.Context) http.Response {
|
||||
var request requests.Exist
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -284,7 +283,7 @@ func (r *FileController) Download(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 下载远程文件
|
||||
// @Description 下载远程文件到给定路径
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -293,7 +292,7 @@ func (r *FileController) Download(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/remoteDownload [post]
|
||||
func (r *FileController) RemoteDownload(ctx http.Context) http.Response {
|
||||
var request requests.NotExist
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -306,7 +305,7 @@ func (r *FileController) RemoteDownload(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取文件/目录信息
|
||||
// @Description 获取给定路径的文件/目录信息
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -315,7 +314,7 @@ func (r *FileController) RemoteDownload(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/info [get]
|
||||
func (r *FileController) Info(ctx http.Context) http.Response {
|
||||
var request requests.Exist
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -339,7 +338,7 @@ func (r *FileController) Info(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 修改文件/目录权限
|
||||
// @Description 修改给定路径的文件/目录权限
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -348,7 +347,7 @@ func (r *FileController) Info(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/permission [post]
|
||||
func (r *FileController) Permission(ctx http.Context) http.Response {
|
||||
var request requests.Permission
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -367,7 +366,7 @@ func (r *FileController) Permission(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 压缩文件/目录
|
||||
// @Description 压缩文件/目录到给定路径
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -376,7 +375,7 @@ func (r *FileController) Permission(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/archive [post]
|
||||
func (r *FileController) Archive(ctx http.Context) http.Response {
|
||||
var request requests.Archive
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -393,7 +392,7 @@ func (r *FileController) Archive(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 解压文件/目录
|
||||
// @Description 解压文件/目录到给定路径
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
@@ -402,7 +401,7 @@ func (r *FileController) Archive(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/unArchive [post]
|
||||
func (r *FileController) UnArchive(ctx http.Context) http.Response {
|
||||
var request requests.UnArchive
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -419,7 +418,7 @@ func (r *FileController) UnArchive(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 搜索文件/目录
|
||||
// @Description 通过关键词搜索给定路径的文件/目录
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body requests.Search true "request"
|
||||
@@ -427,7 +426,7 @@ func (r *FileController) UnArchive(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/search [post]
|
||||
func (r *FileController) Search(ctx http.Context) http.Response {
|
||||
var request requests.Search
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -453,7 +452,7 @@ func (r *FileController) Search(ctx http.Context) http.Response {
|
||||
//
|
||||
// @Summary 获取文件/目录列表
|
||||
// @Description 获取给定路径的文件/目录列表
|
||||
// @Tags 文件管理
|
||||
// @Tags 文件
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data query requests.Exist true "request"
|
||||
@@ -462,13 +461,13 @@ func (r *FileController) Search(ctx http.Context) http.Response {
|
||||
// @Router /panel/file/list [get]
|
||||
func (r *FileController) List(ctx http.Context) http.Response {
|
||||
var request requests.Exist
|
||||
sanitize := Sanitize(ctx, &request)
|
||||
sanitize := SanitizeRequest(ctx, &request)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
var paginate commonrequests.Paginate
|
||||
paginateSanitize := Sanitize(ctx, &paginate)
|
||||
paginateSanitize := SanitizeRequest(ctx, &paginate)
|
||||
if paginateSanitize != nil {
|
||||
return paginateSanitize
|
||||
}
|
||||
|
||||
@@ -21,7 +21,14 @@ func NewPluginController() *PluginController {
|
||||
}
|
||||
}
|
||||
|
||||
// List 列出所有插件
|
||||
// List
|
||||
//
|
||||
// @Summary 插件列表
|
||||
// @Tags 插件
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/plugin/list [get]
|
||||
func (r *PluginController) List(ctx http.Context) http.Response {
|
||||
plugins := r.plugin.All()
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
@@ -89,7 +96,15 @@ func (r *PluginController) List(ctx http.Context) http.Response {
|
||||
})
|
||||
}
|
||||
|
||||
// Install 安装插件
|
||||
// Install
|
||||
//
|
||||
// @Summary 安装插件
|
||||
// @Tags 插件
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param slug query string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/plugin/install [post]
|
||||
func (r *PluginController) Install(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
|
||||
@@ -100,7 +115,15 @@ func (r *PluginController) Install(ctx http.Context) http.Response {
|
||||
return Success(ctx, "任务已提交")
|
||||
}
|
||||
|
||||
// Uninstall 卸载插件
|
||||
// Uninstall
|
||||
//
|
||||
// @Summary 卸载插件
|
||||
// @Tags 插件
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param slug query string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/plugin/uninstall [post]
|
||||
func (r *PluginController) Uninstall(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
|
||||
@@ -111,7 +134,15 @@ func (r *PluginController) Uninstall(ctx http.Context) http.Response {
|
||||
return Success(ctx, "任务已提交")
|
||||
}
|
||||
|
||||
// Update 更新插件
|
||||
// Update
|
||||
//
|
||||
// @Summary 更新插件
|
||||
// @Tags 插件
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param slug query string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/plugin/update [post]
|
||||
func (r *PluginController) Update(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
|
||||
@@ -122,7 +153,16 @@ func (r *PluginController) Update(ctx http.Context) http.Response {
|
||||
return Success(ctx, "任务已提交")
|
||||
}
|
||||
|
||||
// UpdateShow 更新插件首页显示状态
|
||||
// UpdateShow
|
||||
//
|
||||
// @Summary 更新插件首页显示状态
|
||||
// @Tags 插件
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param slug query string true "request"
|
||||
// @Param show query bool true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/plugin/updateShow [post]
|
||||
func (r *PluginController) UpdateShow(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
show := ctx.Request().InputBool("show")
|
||||
@@ -150,3 +190,30 @@ func (r *PluginController) UpdateShow(ctx http.Context) http.Response {
|
||||
|
||||
return Success(ctx, "操作成功")
|
||||
}
|
||||
|
||||
// IsInstalled
|
||||
//
|
||||
// @Summary 检查插件是否已安装
|
||||
// @Tags 插件
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param slug query string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/plugin/isInstalled [get]
|
||||
func (r *PluginController) IsInstalled(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
|
||||
plugin := r.plugin.GetInstalledBySlug(slug)
|
||||
info := r.plugin.GetBySlug(slug)
|
||||
if plugin.Slug != slug {
|
||||
return Success(ctx, http.Json{
|
||||
"name": info.Name,
|
||||
"installed": false,
|
||||
})
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"name": info.Name,
|
||||
"installed": true,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -26,56 +26,6 @@ func NewFail2banController() *Fail2banController {
|
||||
}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *Fail2banController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("fail2ban")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (r *Fail2banController) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload("fail2ban"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *Fail2banController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("fail2ban"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *Fail2banController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("fail2ban"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *Fail2banController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("fail2ban"); err != nil {
|
||||
return nil
|
||||
}
|
||||
status, err := tools.ServiceStatus("fail2ban")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, !status)
|
||||
}
|
||||
|
||||
// List 所有 Fail2ban 规则
|
||||
func (r *Fail2banController) List(ctx http.Context) http.Response {
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -141,7 +91,7 @@ func (r *Fail2banController) List(ctx http.Context) http.Response {
|
||||
|
||||
// Add 添加 Fail2ban 规则
|
||||
func (r *Fail2banController) Add(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"name": "required",
|
||||
"type": "required|in:website,service",
|
||||
"maxretry": "required",
|
||||
@@ -150,12 +100,8 @@ func (r *Fail2banController) Add(ctx http.Context) http.Response {
|
||||
"website_name": "required_if:type,website",
|
||||
"website_mode": "required_if:type,website",
|
||||
"website_path": "required_if:website_mode,path",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
jailName := ctx.Request().Input("name")
|
||||
|
||||
@@ -17,186 +17,6 @@ func NewFrpController() *FrpController {
|
||||
return &FrpController{}
|
||||
}
|
||||
|
||||
// Status
|
||||
//
|
||||
// @Summary 服务状态
|
||||
// @Description 获取 Frp 服务状态
|
||||
// @Tags 插件-Frp
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/frp/status [get]
|
||||
func (r *FrpController) Status(ctx http.Context) http.Response {
|
||||
frps, err := tools.ServiceStatus("frps")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 frps 服务运行状态失败")
|
||||
}
|
||||
frpc, err := tools.ServiceStatus("frpc")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 frpc 服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"frps": frps,
|
||||
"frpc": frpc,
|
||||
})
|
||||
}
|
||||
|
||||
// IsEnabled
|
||||
//
|
||||
// @Summary 是否启用服务
|
||||
// @Description 获取是否启用 Frp 服务
|
||||
// @Tags 插件-Frp
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/frp/isEnabled [get]
|
||||
func (r *FrpController) IsEnabled(ctx http.Context) http.Response {
|
||||
frps, err := tools.ServiceIsEnabled("frps")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 frps 服务启用状态失败")
|
||||
}
|
||||
frpc, err := tools.ServiceIsEnabled("frpc")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 frpc 服务启用状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"frps": frps,
|
||||
"frpc": frpc,
|
||||
})
|
||||
}
|
||||
|
||||
// Enable
|
||||
//
|
||||
// @Summary 启用服务
|
||||
// @Description 启用 Frp 服务
|
||||
// @Tags 插件-Frp
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.Service true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/frp/enable [post]
|
||||
func (r *FrpController) Enable(ctx http.Context) http.Response {
|
||||
var serviceRequest requests.Service
|
||||
sanitize := controllers.Sanitize(ctx, &serviceRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := tools.ServiceEnable(serviceRequest.Service); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("启用 %s 服务失败", serviceRequest.Service))
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Disable
|
||||
//
|
||||
// @Summary 禁用服务
|
||||
// @Description 禁用 Frp 服务
|
||||
// @Tags 插件-Frp
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.Service true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/frp/disable [post]
|
||||
func (r *FrpController) Disable(ctx http.Context) http.Response {
|
||||
var serviceRequest requests.Service
|
||||
sanitize := controllers.Sanitize(ctx, &serviceRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := tools.ServiceDisable(serviceRequest.Service); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("禁用 %s 服务失败", serviceRequest.Service))
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart
|
||||
//
|
||||
// @Summary 重启服务
|
||||
// @Description 重启 Frp 服务
|
||||
// @Tags 插件-Frp
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @param data body requests.Service true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/frp/restart [post]
|
||||
func (r *FrpController) Restart(ctx http.Context) http.Response {
|
||||
var serviceRequest requests.Service
|
||||
sanitize := controllers.Sanitize(ctx, &serviceRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := tools.ServiceRestart(serviceRequest.Service); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("重启 %s 服务失败", serviceRequest.Service))
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start
|
||||
//
|
||||
// @Summary 启动服务
|
||||
// @Description 启动 Frp 服务
|
||||
// @Tags 插件-Frp
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.Service true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/frp/start [post]
|
||||
func (r *FrpController) Start(ctx http.Context) http.Response {
|
||||
var serviceRequest requests.Service
|
||||
sanitize := controllers.Sanitize(ctx, &serviceRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := tools.ServiceStart(serviceRequest.Service); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("启动 %s 服务失败", serviceRequest.Service))
|
||||
}
|
||||
|
||||
status, err := tools.ServiceStatus(serviceRequest.Service)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("获取 %s 服务运行状态失败", serviceRequest.Service))
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Stop
|
||||
//
|
||||
// @Summary 停止服务
|
||||
// @Description 停止 Frp 服务
|
||||
// @Tags 插件-Frp
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.Service true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/frp/stop [post]
|
||||
func (r *FrpController) Stop(ctx http.Context) http.Response {
|
||||
var serviceRequest requests.Service
|
||||
sanitize := controllers.Sanitize(ctx, &serviceRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if err := tools.ServiceStop(serviceRequest.Service); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("停止 %s 服务失败", serviceRequest.Service))
|
||||
}
|
||||
|
||||
status, err := tools.ServiceStatus(serviceRequest.Service)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("获取 %s 服务运行状态失败", serviceRequest.Service))
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, !status)
|
||||
}
|
||||
|
||||
// GetConfig
|
||||
//
|
||||
// @Summary 获取配置
|
||||
@@ -209,7 +29,7 @@ func (r *FrpController) Stop(ctx http.Context) http.Response {
|
||||
// @Router /plugins/frp/config [get]
|
||||
func (r *FrpController) GetConfig(ctx http.Context) http.Response {
|
||||
var serviceRequest requests.Service
|
||||
sanitize := controllers.Sanitize(ctx, &serviceRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &serviceRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -234,7 +54,7 @@ func (r *FrpController) GetConfig(ctx http.Context) http.Response {
|
||||
// @Router /plugins/frp/config [post]
|
||||
func (r *FrpController) UpdateConfig(ctx http.Context) http.Response {
|
||||
var updateRequest requests.UpdateConfig
|
||||
sanitize := controllers.Sanitize(ctx, &updateRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -15,137 +15,6 @@ func NewGiteaController() *GiteaController {
|
||||
return &GiteaController{}
|
||||
}
|
||||
|
||||
// Status
|
||||
//
|
||||
// @Summary 服务状态
|
||||
// @Description 获取 Gitea 服务状态
|
||||
// @Tags 插件-Gitea
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/gitea/status [get]
|
||||
func (r *GiteaController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("gitea")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Gitea 服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// IsEnabled
|
||||
//
|
||||
// @Summary 是否启用服务
|
||||
// @Description 获取是否启用 Gitea 服务
|
||||
// @Tags 插件-Gitea
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/gitea/isEnabled [get]
|
||||
func (r *GiteaController) IsEnabled(ctx http.Context) http.Response {
|
||||
enabled, err := tools.ServiceIsEnabled("gitea")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Gitea 服务启用状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, enabled)
|
||||
}
|
||||
|
||||
// Enable
|
||||
//
|
||||
// @Summary 启用服务
|
||||
// @Description 启用 Gitea 服务
|
||||
// @Tags 插件-Gitea
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/gitea/enable [post]
|
||||
func (r *GiteaController) Enable(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceEnable("gitea"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启用 Gitea 服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Disable
|
||||
//
|
||||
// @Summary 禁用服务
|
||||
// @Description 禁用 Gitea 服务
|
||||
// @Tags 插件-Gitea
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/gitea/disable [post]
|
||||
func (r *GiteaController) Disable(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceDisable("gitea"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "禁用 Gitea 服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart
|
||||
//
|
||||
// @Summary 重启服务
|
||||
// @Description 重启 Gitea 服务
|
||||
// @Tags 插件-Gitea
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/gitea/restart [post]
|
||||
func (r *GiteaController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("gitea"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启 Gitea 服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start
|
||||
//
|
||||
// @Summary 启动服务
|
||||
// @Description 启动 Gitea 服务
|
||||
// @Tags 插件-Gitea
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/gitea/start [post]
|
||||
func (r *GiteaController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("gitea"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动 Gitea 服务失败")
|
||||
}
|
||||
|
||||
status, err := tools.ServiceStatus("gitea")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Gitea 服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Stop
|
||||
//
|
||||
// @Summary 停止服务
|
||||
// @Description 停止 Gitea 服务
|
||||
// @Tags 插件-Gitea
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/gitea/stop [post]
|
||||
func (r *GiteaController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("gitea"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止 Gitea 服务失败")
|
||||
}
|
||||
|
||||
status, err := tools.ServiceStatus("gitea")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Gitea 服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, !status)
|
||||
}
|
||||
|
||||
// GetConfig
|
||||
//
|
||||
// @Summary 获取配置
|
||||
@@ -176,7 +45,7 @@ func (r *GiteaController) GetConfig(ctx http.Context) http.Response {
|
||||
// @Router /plugins/gitea/config [post]
|
||||
func (r *GiteaController) UpdateConfig(ctx http.Context) http.Response {
|
||||
var updateRequest requests.UpdateConfig
|
||||
sanitize := controllers.Sanitize(ctx, &updateRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -28,52 +28,6 @@ func NewMySQLController() *MySQLController {
|
||||
}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *MySQLController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (r *MySQLController) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载MySQL配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *MySQLController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启MySQL服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *MySQLController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动MySQL服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *MySQLController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止MySQL服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (r *MySQLController) GetConfig(ctx http.Context) http.Response {
|
||||
config, err := tools.Read("/www/server/mysql/conf/my.cnf")
|
||||
@@ -95,7 +49,11 @@ func (r *MySQLController) SaveConfig(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败")
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
if err := tools.ServiceReload("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载MySQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
@@ -105,12 +63,9 @@ func (r *MySQLController) Load(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
status, _ := tools.ServiceStatus("mysqld")
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
return controllers.Success(ctx, []types.NV{})
|
||||
}
|
||||
|
||||
raw, err := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
@@ -262,10 +217,20 @@ func (r *MySQLController) DatabaseList(ctx http.Context) http.Response {
|
||||
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
if err = db.Ping(); err != nil {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
|
||||
rows, err := db.Query("SHOW DATABASES")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
@@ -302,6 +267,10 @@ func (r *MySQLController) DatabaseList(ctx http.Context) http.Response {
|
||||
}
|
||||
pagedDatabases := databases[startIndex:endIndex]
|
||||
|
||||
if pagedDatabases == nil {
|
||||
pagedDatabases = []database{}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(databases),
|
||||
"items": pagedDatabases,
|
||||
@@ -310,16 +279,12 @@ func (r *MySQLController) DatabaseList(ctx http.Context) http.Response {
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (r *MySQLController) AddDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -345,14 +310,10 @@ func (r *MySQLController) AddDatabase(ctx http.Context) http.Response {
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (r *MySQLController) DeleteDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -420,19 +381,14 @@ func (r *MySQLController) UploadBackup(ctx http.Context) http.Response {
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (r *MySQLController) CreateBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.MysqlBackup(database)
|
||||
if err != nil {
|
||||
if err := r.backup.MysqlBackup(database); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
@@ -441,14 +397,10 @@ func (r *MySQLController) CreateBackup(ctx http.Context) http.Response {
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (r *MySQLController) DeleteBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/mysql"
|
||||
@@ -462,19 +414,14 @@ func (r *MySQLController) DeleteBackup(ctx http.Context) http.Response {
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (r *MySQLController) RestoreBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"backup": "required|min_len:1|max_len:255",
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
err = r.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
if err := r.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup")); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
@@ -492,10 +439,20 @@ func (r *MySQLController) UserList(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
})
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
if err = db.Ping(); err != nil {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
})
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT user, host FROM mysql.user")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
@@ -554,6 +511,10 @@ func (r *MySQLController) UserList(ctx http.Context) http.Response {
|
||||
}
|
||||
pagedUserGrants := userGrants[startIndex:endIndex]
|
||||
|
||||
if pagedUserGrants == nil {
|
||||
pagedUserGrants = []user{}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(userGrants),
|
||||
"items": pagedUserGrants,
|
||||
@@ -562,16 +523,12 @@ func (r *MySQLController) UserList(ctx http.Context) http.Response {
|
||||
|
||||
// AddUser 添加用户
|
||||
func (r *MySQLController) AddUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -593,14 +550,10 @@ func (r *MySQLController) AddUser(ctx http.Context) http.Response {
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (r *MySQLController) DeleteUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -614,15 +567,11 @@ func (r *MySQLController) DeleteUser(ctx http.Context) http.Response {
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (r *MySQLController) SetUserPassword(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -640,15 +589,11 @@ func (r *MySQLController) SetUserPassword(ctx http.Context) http.Response {
|
||||
|
||||
// SetUserPrivileges 设置用户权限
|
||||
func (r *MySQLController) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"database": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
|
||||
type OpenRestyController struct {
|
||||
@@ -17,68 +18,35 @@ type OpenRestyController struct {
|
||||
}
|
||||
|
||||
func NewOpenrestyController() *OpenRestyController {
|
||||
return &OpenRestyController{
|
||||
// Inject services
|
||||
}
|
||||
return &OpenRestyController{}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *OpenRestyController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("openresty")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (r *OpenRestyController) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载OpenResty失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动OpenResty
|
||||
func (r *OpenRestyController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动OpenResty失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止OpenResty
|
||||
func (r *OpenRestyController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止OpenResty失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启OpenResty
|
||||
func (r *OpenRestyController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启OpenResty失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
// GetConfig
|
||||
//
|
||||
// @Summary 获取配置
|
||||
// @Tags 插件-OpenResty
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/openresty/config [get]
|
||||
func (r *OpenRestyController) GetConfig(ctx http.Context) http.Response {
|
||||
config, err := tools.Read("/www/server/openresty/conf/nginx.conf")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty配置失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
// SaveConfig
|
||||
//
|
||||
// @Summary 保存配置
|
||||
// @Tags 插件-OpenResty
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param config body string true "配置"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/openresty/config [post]
|
||||
func (r *OpenRestyController) SaveConfig(ctx http.Context) http.Response {
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
@@ -86,13 +54,24 @@ func (r *OpenRestyController) SaveConfig(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if err := tools.Write("/www/server/openresty/conf/nginx.conf", config, 0644); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "保存OpenResty配置失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "保存配置失败")
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
if err := tools.ServiceReload("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ErrorLog 获取错误日志
|
||||
// ErrorLog
|
||||
//
|
||||
// @Summary 获取错误日志
|
||||
// @Tags 插件-OpenResty
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/openresty/errorLog [get]
|
||||
func (r *OpenRestyController) ErrorLog(ctx http.Context) http.Response {
|
||||
if !tools.Exists("/www/wwwlogs/nginx_error.log") {
|
||||
return controllers.Success(ctx, "")
|
||||
@@ -106,7 +85,14 @@ func (r *OpenRestyController) ErrorLog(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, out)
|
||||
}
|
||||
|
||||
// ClearErrorLog 清空错误日志
|
||||
// ClearErrorLog
|
||||
//
|
||||
// @Summary 清空错误日志
|
||||
// @Tags 插件-OpenResty
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/openresty/clearErrorLog [post]
|
||||
func (r *OpenRestyController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/wwwlogs/openresty_error.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
@@ -115,43 +101,46 @@ func (r *OpenRestyController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
// Load
|
||||
//
|
||||
// @Summary 获取负载状态
|
||||
// @Tags 插件-OpenResty
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/openresty/load [get]
|
||||
func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
client := resty.New().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/nginx_status")
|
||||
if err != nil || !resp.IsSuccess() {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
return controllers.Success(ctx, []types.NV{})
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
type nginxStatus struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
var data []nginxStatus
|
||||
var data []types.NV
|
||||
|
||||
workers, err := tools.Exec("ps aux | grep nginx | grep 'worker process' | wc -l")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取负载失败")
|
||||
}
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "工作进程",
|
||||
Value: workers,
|
||||
})
|
||||
|
||||
out, err := tools.Exec("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取负载失败")
|
||||
}
|
||||
mem := tools.FormatBytes(cast.ToFloat64(out))
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "内存占用",
|
||||
Value: mem,
|
||||
})
|
||||
|
||||
match := regexp.MustCompile(`Active connections:\s+(\d+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 2 {
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "活跃连接数",
|
||||
Value: match[1],
|
||||
})
|
||||
@@ -159,15 +148,15 @@ func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
|
||||
match = regexp.MustCompile(`server accepts handled requests\s+(\d+)\s+(\d+)\s+(\d+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 4 {
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "总连接次数",
|
||||
Value: match[1],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "总握手次数",
|
||||
Value: match[2],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "总请求次数",
|
||||
Value: match[3],
|
||||
})
|
||||
@@ -175,15 +164,15 @@ func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
|
||||
match = regexp.MustCompile(`Reading:\s+(\d+)\s+Writing:\s+(\d+)\s+Waiting:\s+(\d+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 4 {
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "请求数",
|
||||
Value: match[1],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "响应数",
|
||||
Value: match[2],
|
||||
})
|
||||
data = append(data, nginxStatus{
|
||||
data = append(data, types.NV{
|
||||
Name: "驻留进程",
|
||||
Value: match[3],
|
||||
})
|
||||
|
||||
@@ -2,64 +2,28 @@ package plugins
|
||||
|
||||
import (
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/internal"
|
||||
"github.com/TheTNB/panel/internal/services"
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
)
|
||||
|
||||
type PHPController struct {
|
||||
service internal.PHP
|
||||
}
|
||||
|
||||
func NewPHPController(version uint) *PHPController {
|
||||
return &PHPController{
|
||||
service: services.NewPHPImpl(version),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PHPController) Status(ctx http.Context) http.Response {
|
||||
status, err := r.service.Status()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
func (r *PHPController) Reload(ctx http.Context) http.Response {
|
||||
if err := r.service.Reload(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *PHPController) Start(ctx http.Context) http.Response {
|
||||
if err := r.service.Start(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *PHPController) Stop(ctx http.Context) http.Response {
|
||||
if err := r.service.Stop(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *PHPController) Restart(ctx http.Context) http.Response {
|
||||
if err := r.service.Restart(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
type PHPController struct{}
|
||||
|
||||
func NewPHPController() *PHPController {
|
||||
return &PHPController{}
|
||||
}
|
||||
|
||||
// GetConfig
|
||||
//
|
||||
// @Summary 获取配置
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/config [get]
|
||||
func (r *PHPController) GetConfig(ctx http.Context) http.Response {
|
||||
config, err := r.service.GetConfig()
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
config, err := service.GetConfig()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -67,17 +31,38 @@ func (r *PHPController) GetConfig(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig
|
||||
//
|
||||
// @Summary 保存配置
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Param config body string true "配置"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/config [post]
|
||||
func (r *PHPController) SaveConfig(ctx http.Context) http.Response {
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
config := ctx.Request().Input("config")
|
||||
if err := r.service.SaveConfig(config); err != nil {
|
||||
if err := service.SaveConfig(config); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetFPMConfig
|
||||
//
|
||||
// @Summary 获取 FPM 配置
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/fpmConfig [get]
|
||||
func (r *PHPController) GetFPMConfig(ctx http.Context) http.Response {
|
||||
config, err := r.service.GetFPMConfig()
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
config, err := service.GetFPMConfig()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -85,17 +70,38 @@ func (r *PHPController) GetFPMConfig(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveFPMConfig
|
||||
//
|
||||
// @Summary 保存 FPM 配置
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Param config body string true "配置"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/fpmConfig [post]
|
||||
func (r *PHPController) SaveFPMConfig(ctx http.Context) http.Response {
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
config := ctx.Request().Input("config")
|
||||
if err := r.service.SaveFPMConfig(config); err != nil {
|
||||
if err := service.SaveFPMConfig(config); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Load
|
||||
//
|
||||
// @Summary 获取负载状态
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/load [get]
|
||||
func (r *PHPController) Load(ctx http.Context) http.Response {
|
||||
load, err := r.service.Load()
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
load, err := service.Load()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -103,18 +109,48 @@ func (r *PHPController) Load(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, load)
|
||||
}
|
||||
|
||||
// ErrorLog
|
||||
//
|
||||
// @Summary 获取错误日志
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/errorLog [get]
|
||||
func (r *PHPController) ErrorLog(ctx http.Context) http.Response {
|
||||
log, _ := r.service.GetErrorLog()
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
log, _ := service.GetErrorLog()
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// SlowLog
|
||||
//
|
||||
// @Summary 获取慢日志
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/slowLog [get]
|
||||
func (r *PHPController) SlowLog(ctx http.Context) http.Response {
|
||||
log, _ := r.service.GetSlowLog()
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
log, _ := service.GetSlowLog()
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearErrorLog
|
||||
//
|
||||
// @Summary 清空错误日志
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/clearErrorLog [post]
|
||||
func (r *PHPController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
err := r.service.ClearErrorLog()
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
err := service.ClearErrorLog()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -122,8 +158,18 @@ func (r *PHPController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ClearSlowLog
|
||||
//
|
||||
// @Summary 清空慢日志
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/clearSlowLog [post]
|
||||
func (r *PHPController) ClearSlowLog(ctx http.Context) http.Response {
|
||||
err := r.service.ClearSlowLog()
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
err := service.ClearSlowLog()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -131,8 +177,18 @@ func (r *PHPController) ClearSlowLog(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *PHPController) GetExtensionList(ctx http.Context) http.Response {
|
||||
extensions, err := r.service.GetExtensions()
|
||||
// ExtensionList
|
||||
//
|
||||
// @Summary 获取扩展列表
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/extensions [get]
|
||||
func (r *PHPController) ExtensionList(ctx http.Context) http.Response {
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
extensions, err := service.GetExtensions()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -140,26 +196,48 @@ func (r *PHPController) GetExtensionList(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, extensions)
|
||||
}
|
||||
|
||||
// InstallExtension
|
||||
//
|
||||
// @Summary 安装扩展
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Param slug query string true "slug"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/extensions [post]
|
||||
func (r *PHPController) InstallExtension(ctx http.Context) http.Response {
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
|
||||
}
|
||||
|
||||
if err := r.service.InstallExtension(slug); err != nil {
|
||||
if err := service.InstallExtension(slug); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UninstallExtension
|
||||
//
|
||||
// @Summary 卸载扩展
|
||||
// @Tags 插件-PHP
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param version path int true "PHP 版本"
|
||||
// @Param slug query string true "slug"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/php/{version}/extensions [delete]
|
||||
func (r *PHPController) UninstallExtension(ctx http.Context) http.Response {
|
||||
service := services.NewPHPImpl(uint(ctx.Request().RouteInt("version")))
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "参数错误")
|
||||
}
|
||||
|
||||
if err := r.service.UninstallExtension(slug); err != nil {
|
||||
if err := service.UninstallExtension(slug); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
|
||||
@@ -15,137 +15,6 @@ func NewPodmanController() *PodmanController {
|
||||
return &PodmanController{}
|
||||
}
|
||||
|
||||
// Status
|
||||
//
|
||||
// @Summary 服务状态
|
||||
// @Description 获取 Podman 服务状态
|
||||
// @Tags 插件-Podman
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/podman/status [get]
|
||||
func (r *PodmanController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("podman")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// IsEnabled
|
||||
//
|
||||
// @Summary 是否启用服务
|
||||
// @Description 获取是否启用 Podman 服务
|
||||
// @Tags 插件-Podman
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/podman/isEnabled [get]
|
||||
func (r *PodmanController) IsEnabled(ctx http.Context) http.Response {
|
||||
enabled, err := tools.ServiceIsEnabled("podman")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务启用状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, enabled)
|
||||
}
|
||||
|
||||
// Enable
|
||||
//
|
||||
// @Summary 启用服务
|
||||
// @Description 启用 Podman 服务
|
||||
// @Tags 插件-Podman
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/podman/enable [post]
|
||||
func (r *PodmanController) Enable(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceEnable("podman"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启用 Podman 服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Disable
|
||||
//
|
||||
// @Summary 禁用服务
|
||||
// @Description 禁用 Podman 服务
|
||||
// @Tags 插件-Podman
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/podman/disable [post]
|
||||
func (r *PodmanController) Disable(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceDisable("podman"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "禁用 Podman 服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart
|
||||
//
|
||||
// @Summary 重启服务
|
||||
// @Description 重启 Podman 服务
|
||||
// @Tags 插件-Podman
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/podman/restart [post]
|
||||
func (r *PodmanController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("podman"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启 Podman 服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start
|
||||
//
|
||||
// @Summary 启动服务
|
||||
// @Description 启动 Podman 服务
|
||||
// @Tags 插件-Podman
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/podman/start [post]
|
||||
func (r *PodmanController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("podman"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动 Podman 服务失败")
|
||||
}
|
||||
|
||||
status, err := tools.ServiceStatus("podman")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Stop
|
||||
//
|
||||
// @Summary 停止服务
|
||||
// @Description 停止 Podman 服务
|
||||
// @Tags 插件-Podman
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/podman/stop [post]
|
||||
func (r *PodmanController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("podman"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止 Podman 服务失败")
|
||||
}
|
||||
|
||||
status, err := tools.ServiceStatus("podman")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, !status)
|
||||
}
|
||||
|
||||
// GetRegistryConfig
|
||||
//
|
||||
// @Summary 获取注册表配置
|
||||
@@ -176,7 +45,7 @@ func (r *PodmanController) GetRegistryConfig(ctx http.Context) http.Response {
|
||||
// @Router /plugins/podman/registryConfig [post]
|
||||
func (r *PodmanController) UpdateRegistryConfig(ctx http.Context) http.Response {
|
||||
var updateRequest requests.UpdateRegistryConfig
|
||||
sanitize := controllers.Sanitize(ctx, &updateRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -222,7 +91,7 @@ func (r *PodmanController) GetStorageConfig(ctx http.Context) http.Response {
|
||||
// @Router /plugins/podman/storageConfig [post]
|
||||
func (r *PodmanController) UpdateStorageConfig(ctx http.Context) http.Response {
|
||||
var updateRequest requests.UpdateStorageConfig
|
||||
sanitize := controllers.Sanitize(ctx, &updateRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -1,553 +0,0 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"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"
|
||||
)
|
||||
|
||||
type Postgresql16Controller struct {
|
||||
setting internal.Setting
|
||||
backup internal.Backup
|
||||
}
|
||||
|
||||
func NewPostgresql16Controller() *Postgresql16Controller {
|
||||
return &Postgresql16Controller{
|
||||
setting: services.NewSettingImpl(),
|
||||
backup: services.NewBackupImpl(),
|
||||
}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *Postgresql16Controller) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (r *Postgresql16Controller) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *Postgresql16Controller) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *Postgresql16Controller) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *Postgresql16Controller) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (r *Postgresql16Controller) GetConfig(ctx http.Context) http.Response {
|
||||
// 获取配置
|
||||
config, err := tools.Read("/www/server/postgresql/data/postgresql.conf")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// GetUserConfig 获取用户配置
|
||||
func (r *Postgresql16Controller) GetUserConfig(ctx http.Context) http.Response {
|
||||
// 获取配置
|
||||
config, err := tools.Read("/www/server/postgresql/data/pg_hba.conf")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (r *Postgresql16Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空")
|
||||
}
|
||||
|
||||
if err := tools.Write("/www/server/postgresql/data/postgresql.conf", config, 0644); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
}
|
||||
|
||||
// SaveUserConfig 保存用户配置
|
||||
func (r *Postgresql16Controller) SaveUserConfig(ctx http.Context) http.Response {
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空")
|
||||
}
|
||||
|
||||
if err := tools.Write("/www/server/postgresql/data/pg_hba.conf", config, 0644); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (r *Postgresql16Controller) Load(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
}
|
||||
|
||||
time, err := tools.Exec(`echo "select pg_postmaster_start_time();" | su - postgres -c "psql" | sed -n 3p | cut -d'.' -f1`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL启动时间失败")
|
||||
}
|
||||
pid, err := tools.Exec(`echo "select pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL进程PID失败")
|
||||
}
|
||||
process, err := tools.Exec(`ps aux | grep postgres | grep -v grep | wc -l`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL进程数失败")
|
||||
}
|
||||
connections, err := tools.Exec(`echo "SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL连接数失败")
|
||||
}
|
||||
storage, err := tools.Exec(`echo "select pg_size_pretty(pg_database_size('postgres'));" | su - postgres -c "psql" | sed -n 3p`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL空间占用失败")
|
||||
}
|
||||
|
||||
data := []types.NV{
|
||||
{Name: "启动时间", Value: carbon.Parse(time).ToDateTimeString()},
|
||||
{Name: "进程 PID", Value: pid},
|
||||
{Name: "进程数", Value: process},
|
||||
{Name: "总连接数", Value: connections},
|
||||
{Name: "空间占用", Value: storage},
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
// Log 获取日志
|
||||
func (r *Postgresql16Controller) Log(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearLog 清空日志
|
||||
func (r *Postgresql16Controller) ClearLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
func (r *Postgresql16Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
}
|
||||
|
||||
type database struct {
|
||||
Name string `json:"name"`
|
||||
Owner string `json:"owner"`
|
||||
Encoding string `json:"encoding"`
|
||||
}
|
||||
|
||||
raw, err := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
}
|
||||
databases := strings.Split(raw, "\n")
|
||||
if len(databases) >= 4 {
|
||||
databases = databases[3 : len(databases)-1]
|
||||
} else {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
|
||||
var databaseList []database
|
||||
for _, db := range databases {
|
||||
parts := strings.Split(db, "|")
|
||||
if len(parts) != 9 || len(strings.TrimSpace(parts[0])) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
databaseList = append(databaseList, database{
|
||||
Name: strings.TrimSpace(parts[0]),
|
||||
Owner: strings.TrimSpace(parts[1]),
|
||||
Encoding: strings.TrimSpace(parts[2]),
|
||||
})
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(databaseList) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(databaseList) {
|
||||
endIndex = len(databaseList)
|
||||
}
|
||||
pagedDatabases := databaseList[startIndex:endIndex]
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(databaseList),
|
||||
"items": pagedDatabases,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (r *Postgresql16Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
if out, err := tools.Exec(`echo "CREATE DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "ALTER DATABASE ` + database + ` OWNER TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (r *Postgresql16Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:postgres,template0,template1",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
func (r *Postgresql16Controller) BackupList(ctx http.Context) http.Response {
|
||||
backupList, err := r.backup.PostgresqlList()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(backupList) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []types.BackupFile{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(backupList) {
|
||||
endIndex = len(backupList)
|
||||
}
|
||||
pagedBackupList := backupList[startIndex:endIndex]
|
||||
if pagedBackupList == nil {
|
||||
pagedBackupList = []types.BackupFile{}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(backupList),
|
||||
"items": pagedBackupList,
|
||||
})
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (r *Postgresql16Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
}
|
||||
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/postgresql"
|
||||
if !tools.Exists(backupPath) {
|
||||
if err = tools.Mkdir(backupPath, 0644); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
name := file.GetClientOriginalName()
|
||||
_, err = file.StoreAs(backupPath, name)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (r *Postgresql16Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.PostgresqlBackup(database)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (r *Postgresql16Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/postgresql"
|
||||
fileName := ctx.Request().Input("name")
|
||||
if err := tools.Remove(backupPath + "/" + fileName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (r *Postgresql16Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"backup": "required|min_len:1|max_len:255",
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
err = r.backup.PostgresqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
func (r *Postgresql16Controller) UserList(ctx http.Context) http.Response {
|
||||
type user struct {
|
||||
User string `json:"user"`
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
raw, err := tools.Exec(`echo "\du" | su - postgres -c "psql"`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
}
|
||||
users := strings.Split(raw, "\n")
|
||||
if len(users) < 4 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "用户列表为空")
|
||||
}
|
||||
users = users[3:]
|
||||
|
||||
var userList []user
|
||||
for _, u := range users {
|
||||
userInfo := strings.Split(u, "|")
|
||||
if len(userInfo) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
userList = append(userList, user{
|
||||
User: strings.TrimSpace(userInfo[0]),
|
||||
Role: strings.TrimSpace(userInfo[1]),
|
||||
})
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(userList) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(userList) {
|
||||
endIndex = len(userList)
|
||||
}
|
||||
pagedUsers := userList[startIndex:endIndex]
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(userList),
|
||||
"items": pagedUsers,
|
||||
})
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
func (r *Postgresql16Controller) AddUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (r *Postgresql16Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
if out, err := tools.Exec(`echo "DROP USER ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`sed -i '/` + user + `/d' /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (r *Postgresql16Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
if out, err := tools.Exec(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
+185
-199
@@ -1,10 +1,11 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"database/sql"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
_ "github.com/lib/pq"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
@@ -14,66 +15,20 @@ import (
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
|
||||
type Postgresql15Controller struct {
|
||||
type PostgreSQLController struct {
|
||||
setting internal.Setting
|
||||
backup internal.Backup
|
||||
}
|
||||
|
||||
func NewPostgresql15Controller() *Postgresql15Controller {
|
||||
return &Postgresql15Controller{
|
||||
func NewPostgreSQLController() *PostgreSQLController {
|
||||
return &PostgreSQLController{
|
||||
setting: services.NewSettingImpl(),
|
||||
backup: services.NewBackupImpl(),
|
||||
}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *Postgresql15Controller) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (r *Postgresql15Controller) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *Postgresql15Controller) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *Postgresql15Controller) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *Postgresql15Controller) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PostgreSQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (r *Postgresql15Controller) GetConfig(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) GetConfig(ctx http.Context) http.Response {
|
||||
// 获取配置
|
||||
config, err := tools.Read("/www/server/postgresql/data/postgresql.conf")
|
||||
if err != nil {
|
||||
@@ -84,7 +39,7 @@ func (r *Postgresql15Controller) GetConfig(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// GetUserConfig 获取用户配置
|
||||
func (r *Postgresql15Controller) GetUserConfig(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) GetUserConfig(ctx http.Context) http.Response {
|
||||
// 获取配置
|
||||
config, err := tools.Read("/www/server/postgresql/data/pg_hba.conf")
|
||||
if err != nil {
|
||||
@@ -95,7 +50,7 @@ func (r *Postgresql15Controller) GetUserConfig(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (r *Postgresql15Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) SaveConfig(ctx http.Context) http.Response {
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空")
|
||||
@@ -105,11 +60,15 @@ func (r *Postgresql15Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SaveUserConfig 保存用户配置
|
||||
func (r *Postgresql15Controller) SaveUserConfig(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) SaveUserConfig(ctx http.Context) http.Response {
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空")
|
||||
@@ -119,17 +78,18 @@ func (r *Postgresql15Controller) SaveUserConfig(ctx http.Context) http.Response
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (r *Postgresql15Controller) Load(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
func (r *PostgreSQLController) Load(ctx http.Context) http.Response {
|
||||
status, _ := tools.ServiceStatus("postgresql")
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
return controllers.Success(ctx, []types.NV{})
|
||||
}
|
||||
|
||||
time, err := tools.Exec(`echo "select pg_postmaster_start_time();" | su - postgres -c "psql" | sed -n 3p | cut -d'.' -f1`)
|
||||
@@ -165,7 +125,7 @@ func (r *Postgresql15Controller) Load(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Log 获取日志
|
||||
func (r *Postgresql15Controller) Log(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) Log(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
@@ -175,7 +135,7 @@ func (r *Postgresql15Controller) Log(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// ClearLog 清空日志
|
||||
func (r *Postgresql15Controller) ClearLog(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) ClearLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -184,82 +144,84 @@ func (r *Postgresql15Controller) ClearLog(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
func (r *Postgresql15Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
}
|
||||
|
||||
func (r *PostgreSQLController) DatabaseList(ctx http.Context) http.Response {
|
||||
type database struct {
|
||||
Name string `json:"name"`
|
||||
Owner string `json:"owner"`
|
||||
Encoding string `json:"encoding"`
|
||||
}
|
||||
|
||||
raw, err := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
db, err := sql.Open("postgres", "host=localhost port=5432 user=postgres dbname=postgres sslmode=disable")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
}
|
||||
databases := strings.Split(raw, "\n")
|
||||
if len(databases) >= 4 {
|
||||
databases = databases[3 : len(databases)-1]
|
||||
} else {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
|
||||
var databaseList []database
|
||||
for _, db := range databases {
|
||||
parts := strings.Split(db, "|")
|
||||
if len(parts) != 8 || len(strings.TrimSpace(parts[0])) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
databaseList = append(databaseList, database{
|
||||
Name: strings.TrimSpace(parts[0]),
|
||||
Owner: strings.TrimSpace(parts[1]),
|
||||
Encoding: strings.TrimSpace(parts[2]),
|
||||
if err = db.Ping(); err != nil {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
|
||||
query := `
|
||||
SELECT d.datname, pg_catalog.pg_get_userbyid(d.datdba), pg_catalog.pg_encoding_to_char(d.encoding)
|
||||
FROM pg_catalog.pg_database d
|
||||
WHERE datistemplate = false;
|
||||
`
|
||||
rows, err := db.Query(query)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var databases []database
|
||||
for rows.Next() {
|
||||
var db database
|
||||
if err := rows.Scan(&db.Name, &db.Owner, &db.Encoding); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
databases = append(databases, db)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(databaseList) {
|
||||
if startIndex > len(databases) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(databaseList) {
|
||||
endIndex = len(databaseList)
|
||||
if endIndex > len(databases) {
|
||||
endIndex = len(databases)
|
||||
}
|
||||
pagedDatabases := databases[startIndex:endIndex]
|
||||
|
||||
if pagedDatabases == nil {
|
||||
pagedDatabases = []database{}
|
||||
}
|
||||
pagedDatabases := databaseList[startIndex:endIndex]
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(databaseList),
|
||||
"total": len(databases),
|
||||
"items": pagedDatabases,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (r *Postgresql15Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
func (r *PostgreSQLController) AddDatabase(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
@@ -284,19 +246,19 @@ func (r *Postgresql15Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (r *Postgresql15Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
func (r *PostgreSQLController) DeleteDatabase(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:postgres,template0,template1",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
@@ -308,7 +270,7 @@ func (r *Postgresql15Controller) DeleteDatabase(ctx http.Context) http.Response
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
func (r *Postgresql15Controller) BackupList(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) BackupList(ctx http.Context) http.Response {
|
||||
backupList, err := r.backup.PostgresqlList()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
@@ -339,7 +301,7 @@ func (r *Postgresql15Controller) BackupList(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (r *Postgresql15Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
func (r *PostgreSQLController) UploadBackup(ctx http.Context) http.Response {
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
@@ -362,20 +324,15 @@ func (r *Postgresql15Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (r *Postgresql15Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
func (r *PostgreSQLController) CreateBackup(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.PostgresqlBackup(database)
|
||||
if err != nil {
|
||||
if err := r.backup.PostgresqlBackup(database); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
@@ -383,15 +340,11 @@ func (r *Postgresql15Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (r *Postgresql15Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
func (r *PostgreSQLController) DeleteBackup(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/postgresql"
|
||||
@@ -404,89 +357,122 @@ func (r *Postgresql15Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (r *Postgresql15Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
func (r *PostgreSQLController) RestoreBackup(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"backup": "required|min_len:1|max_len:255",
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
err = r.backup.PostgresqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
if err := r.backup.PostgresqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup")); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
func (r *Postgresql15Controller) UserList(ctx http.Context) http.Response {
|
||||
type user struct {
|
||||
User string `json:"user"`
|
||||
Role string `json:"role"`
|
||||
// RoleList 角色列表
|
||||
func (r *PostgreSQLController) RoleList(ctx http.Context) http.Response {
|
||||
type role struct {
|
||||
Role string `json:"role"`
|
||||
Attributes []string `json:"attributes"`
|
||||
}
|
||||
|
||||
raw, err := tools.Exec(`echo "\du" | su - postgres -c "psql"`)
|
||||
db, err := sql.Open("postgres", "host=localhost port=5432 user=postgres dbname=postgres sslmode=disable")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []role{},
|
||||
})
|
||||
}
|
||||
users := strings.Split(raw, "\n")
|
||||
if len(users) < 4 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "用户列表为空")
|
||||
if err = db.Ping(); err != nil {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []role{},
|
||||
})
|
||||
}
|
||||
users = users[3:]
|
||||
|
||||
var userList []user
|
||||
for _, u := range users {
|
||||
userInfo := strings.Split(u, "|")
|
||||
if len(userInfo) != 3 {
|
||||
continue
|
||||
query := `
|
||||
SELECT rolname,
|
||||
rolsuper,
|
||||
rolcreaterole,
|
||||
rolcreatedb,
|
||||
rolreplication,
|
||||
rolbypassrls
|
||||
FROM pg_roles
|
||||
WHERE rolcanlogin = true;
|
||||
`
|
||||
rows, err := db.Query(query)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var roles []role
|
||||
for rows.Next() {
|
||||
var r role
|
||||
var super, canCreateRole, canCreateDb, replication, bypassRls bool
|
||||
if err = rows.Scan(&r.Role, &super, &canCreateRole, &canCreateDb, &replication, &bypassRls); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
userList = append(userList, user{
|
||||
User: strings.TrimSpace(userInfo[0]),
|
||||
Role: strings.TrimSpace(userInfo[1]),
|
||||
})
|
||||
permissions := map[string]bool{
|
||||
"超级用户": super,
|
||||
"创建角色": canCreateRole,
|
||||
"创建数据库": canCreateDb,
|
||||
"可以复制": replication,
|
||||
"绕过行级安全": bypassRls,
|
||||
}
|
||||
for perm, enabled := range permissions {
|
||||
if enabled {
|
||||
r.Attributes = append(r.Attributes, perm)
|
||||
}
|
||||
}
|
||||
|
||||
if len(r.Attributes) == 0 {
|
||||
r.Attributes = append(r.Attributes, "无")
|
||||
}
|
||||
|
||||
roles = append(roles, r)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(userList) {
|
||||
if startIndex > len(roles) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
"items": []role{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(userList) {
|
||||
endIndex = len(userList)
|
||||
if endIndex > len(roles) {
|
||||
endIndex = len(roles)
|
||||
}
|
||||
pagedRoles := roles[startIndex:endIndex]
|
||||
|
||||
if pagedRoles == nil {
|
||||
pagedRoles = []role{}
|
||||
}
|
||||
pagedUsers := userList[startIndex:endIndex]
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(userList),
|
||||
"items": pagedUsers,
|
||||
"total": len(roles),
|
||||
"items": pagedRoles,
|
||||
})
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
func (r *Postgresql15Controller) AddUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
// AddRole 添加角色
|
||||
func (r *PostgreSQLController) AddRole(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
@@ -504,19 +490,19 @@ func (r *Postgresql15Controller) AddUser(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (r *Postgresql15Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
// DeleteRole 删除角色
|
||||
func (r *PostgreSQLController) DeleteRole(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
@@ -527,20 +513,20 @@ func (r *Postgresql15Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (r *Postgresql15Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
// SetRolePassword 设置用户密码
|
||||
func (r *PostgreSQLController) SetRolePassword(ctx http.Context) http.Response {
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
@@ -9,79 +9,35 @@ import (
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
|
||||
type PureFtpdController struct {
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Username string `json:"username"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
func NewPureFtpdController() *PureFtpdController {
|
||||
return &PureFtpdController{}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *PureFtpdController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *PureFtpdController) Restart(ctx http.Context) http.Response {
|
||||
err := tools.ServiceRestart("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PureFtpd失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *PureFtpdController) Start(ctx http.Context) http.Response {
|
||||
err := tools.ServiceStart("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PureFtpd失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *PureFtpdController) Stop(ctx http.Context) http.Response {
|
||||
err := tools.ServiceStop("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PureFtpd失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// List 获取用户列表
|
||||
func (r *PureFtpdController) List(ctx http.Context) http.Response {
|
||||
listRaw, err := tools.Exec("pure-pw list")
|
||||
if err != nil {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []User{},
|
||||
"items": []types.PureFtpdUser{},
|
||||
})
|
||||
}
|
||||
|
||||
listArr := strings.Split(listRaw, "\n")
|
||||
var users []User
|
||||
var users []types.PureFtpdUser
|
||||
for _, v := range listArr {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
match := regexp.MustCompile(`(\S+)\s+(\S+)`).FindStringSubmatch(v)
|
||||
users = append(users, User{
|
||||
users = append(users, types.PureFtpdUser{
|
||||
Username: match[1],
|
||||
Path: strings.Replace(match[2], "/./", "/", 1),
|
||||
})
|
||||
@@ -94,7 +50,7 @@ func (r *PureFtpdController) List(ctx http.Context) http.Response {
|
||||
if startIndex > len(users) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []User{},
|
||||
"items": []types.PureFtpdUser{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(users) {
|
||||
@@ -102,6 +58,10 @@ func (r *PureFtpdController) List(ctx http.Context) http.Response {
|
||||
}
|
||||
pagedUsers := users[startIndex:endIndex]
|
||||
|
||||
if pagedUsers == nil {
|
||||
pagedUsers = []types.PureFtpdUser{}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(users),
|
||||
"items": pagedUsers,
|
||||
@@ -110,16 +70,12 @@ func (r *PureFtpdController) List(ctx http.Context) http.Response {
|
||||
|
||||
// Add 添加用户
|
||||
func (r *PureFtpdController) Add(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"username": "required",
|
||||
"password": "required|min_len:6",
|
||||
"path": "required",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
@@ -133,10 +89,10 @@ func (r *PureFtpdController) Add(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "目录不存在")
|
||||
}
|
||||
|
||||
if err = tools.Chmod(path, 0755); err != nil {
|
||||
if err := tools.Chmod(path, 0755); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "修改目录权限失败")
|
||||
}
|
||||
if err = tools.Chown(path, "www", "www"); err != nil {
|
||||
if err := tools.Chown(path, "www", "www"); err != nil {
|
||||
return nil
|
||||
}
|
||||
if out, err := tools.Exec(`yes '` + password + `' | pure-pw useradd ` + username + ` -u www -g www -d ` + path); err != nil {
|
||||
@@ -151,14 +107,10 @@ func (r *PureFtpdController) Add(ctx http.Context) http.Response {
|
||||
|
||||
// Delete 删除用户
|
||||
func (r *PureFtpdController) Delete(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"username": "required",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
@@ -175,15 +127,11 @@ func (r *PureFtpdController) Delete(ctx http.Context) http.Response {
|
||||
|
||||
// ChangePassword 修改密码
|
||||
func (r *PureFtpdController) ChangePassword(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"username": "required",
|
||||
"password": "required|min_len:6",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
@@ -211,14 +159,10 @@ func (r *PureFtpdController) GetPort(ctx http.Context) http.Response {
|
||||
|
||||
// SetPort 设置端口
|
||||
func (r *PureFtpdController) SetPort(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"port": "required",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
port := ctx.Request().Input("port")
|
||||
@@ -241,5 +185,9 @@ func (r *PureFtpdController) SetPort(ctx http.Context) http.Response {
|
||||
}
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
if err := tools.ServiceRestart("pure-ftpd"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -17,43 +17,6 @@ func NewRedisController() *RedisController {
|
||||
return &RedisController{}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *RedisController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("redis")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *RedisController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("redis"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启Redis失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *RedisController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("redis"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动Redis失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *RedisController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("redis"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止Redis失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (r *RedisController) GetConfig(ctx http.Context) http.Response {
|
||||
// 获取配置
|
||||
@@ -76,7 +39,11 @@ func (r *RedisController) SaveConfig(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入Redis配置失败")
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
if err := tools.ServiceRestart("redis"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启Redis失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
|
||||
@@ -20,79 +20,6 @@ func NewRsyncController() *RsyncController {
|
||||
return &RsyncController{}
|
||||
}
|
||||
|
||||
// Status
|
||||
//
|
||||
// @Summary 服务状态
|
||||
// @Description 获取 Rsync 服务状态
|
||||
// @Tags 插件-Rsync
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/rsync/status [get]
|
||||
func (r *RsyncController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("rsyncd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Restart
|
||||
//
|
||||
// @Summary 重启服务
|
||||
// @Description 重启 Rsync 服务
|
||||
// @Tags 插件-Rsync
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/rsync/restart [post]
|
||||
func (r *RsyncController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("rsyncd"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start
|
||||
//
|
||||
// @Summary 启动服务
|
||||
// @Description 启动 Rsync 服务
|
||||
// @Tags 插件-Rsync
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/rsync/start [post]
|
||||
func (r *RsyncController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("rsyncd"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop
|
||||
//
|
||||
// @Summary 停止服务
|
||||
// @Description 停止 Rsync 服务
|
||||
// @Tags 插件-Rsync
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/rsync/stop [post]
|
||||
func (r *RsyncController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("rsyncd"); err != nil {
|
||||
return nil
|
||||
}
|
||||
status, err := tools.ServiceStatus("rsyncd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, !status)
|
||||
}
|
||||
|
||||
// List
|
||||
//
|
||||
// @Summary 列出模块
|
||||
@@ -105,7 +32,7 @@ func (r *RsyncController) Stop(ctx http.Context) http.Response {
|
||||
// @Router /plugins/rsync/modules [get]
|
||||
func (r *RsyncController) List(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := controllers.Sanitize(ctx, &paginateRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -198,7 +125,7 @@ func (r *RsyncController) List(ctx http.Context) http.Response {
|
||||
// @Router /plugins/rsync/modules [post]
|
||||
func (r *RsyncController) Create(ctx http.Context) http.Response {
|
||||
var createRequest requests.Create
|
||||
sanitize := controllers.Sanitize(ctx, &createRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &createRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -295,7 +222,7 @@ func (r *RsyncController) Destroy(ctx http.Context) http.Response {
|
||||
// @Router /plugins/rsync/modules/{name} [post]
|
||||
func (r *RsyncController) Update(ctx http.Context) http.Response {
|
||||
var updateRequest requests.Update
|
||||
sanitize := controllers.Sanitize(ctx, &updateRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -373,7 +300,7 @@ func (r *RsyncController) GetConfig(ctx http.Context) http.Response {
|
||||
// @Router /plugins/rsync/config [post]
|
||||
func (r *RsyncController) UpdateConfig(ctx http.Context) http.Response {
|
||||
var updateRequest requests.UpdateConfig
|
||||
sanitize := controllers.Sanitize(ctx, &updateRequest)
|
||||
sanitize := controllers.SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -60,18 +60,14 @@ func (r *S3fsController) List(ctx http.Context) http.Response {
|
||||
|
||||
// Add 添加 S3fs 挂载
|
||||
func (r *S3fsController) Add(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"ak": "required|regex:^[a-zA-Z0-9]*$",
|
||||
"sk": "required|regex:^[a-zA-Z0-9]*$",
|
||||
"bucket": "required|regex:^[a-zA-Z0-9_-]*$",
|
||||
"url": "required|full_url",
|
||||
"path": "required|regex:^/[a-zA-Z0-9_-]+$",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
ak := ctx.Request().Input("ak")
|
||||
@@ -87,7 +83,7 @@ func (r *S3fsController) Add(ctx http.Context) http.Response {
|
||||
|
||||
// 检查挂载目录是否存在且为空
|
||||
if !tools.Exists(path) {
|
||||
if err = tools.Mkdir(path, 0755); err != nil {
|
||||
if err := tools.Mkdir(path, 0755); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载目录创建失败")
|
||||
}
|
||||
}
|
||||
@@ -96,8 +92,7 @@ func (r *S3fsController) Add(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
var s3fsList []types.S3fsMount
|
||||
err = json.UnmarshalString(r.setting.Get("s3fs", "[]"), &s3fsList)
|
||||
if err != nil {
|
||||
if err := json.UnmarshalString(r.setting.Get("s3fs", "[]"), &s3fsList); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 S3fs 挂载失败")
|
||||
}
|
||||
|
||||
@@ -109,7 +104,7 @@ func (r *S3fsController) Add(ctx http.Context) http.Response {
|
||||
|
||||
id := carbon.Now().TimestampMilli()
|
||||
password := ak + ":" + sk
|
||||
if err = tools.Write("/etc/passwd-s3fs-"+cast.ToString(id), password, 0600); err != nil {
|
||||
if err := tools.Write("/etc/passwd-s3fs-"+cast.ToString(id), password, 0600); err != nil {
|
||||
return nil
|
||||
}
|
||||
out, err := tools.Exec(`echo 's3fs#` + bucket + ` ` + path + ` fuse _netdev,allow_other,nonempty,url=` + url + `,passwd_file=/etc/passwd-s3fs-` + cast.ToString(id) + ` 0 0' >> /etc/fstab`)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -11,66 +12,25 @@ import (
|
||||
)
|
||||
|
||||
type SupervisorController struct {
|
||||
ServiceName string
|
||||
service string
|
||||
}
|
||||
|
||||
func NewSupervisorController() *SupervisorController {
|
||||
var serviceName string
|
||||
var service string
|
||||
if tools.IsRHEL() {
|
||||
serviceName = "supervisord"
|
||||
service = "supervisord"
|
||||
} else {
|
||||
serviceName = "supervisor"
|
||||
service = "supervisor"
|
||||
}
|
||||
|
||||
return &SupervisorController{
|
||||
ServiceName: serviceName,
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// Status 状态
|
||||
func (r *SupervisorController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus(r.ServiceName)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Supervisor状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Start 启动
|
||||
func (r *SupervisorController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止
|
||||
func (r *SupervisorController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启
|
||||
func (r *SupervisorController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Reload 重载
|
||||
func (r *SupervisorController) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
// Service 获取服务名称
|
||||
func (r *SupervisorController) Service(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, r.service)
|
||||
}
|
||||
|
||||
// Log 日志
|
||||
@@ -123,7 +83,11 @@ func (r *SupervisorController) SaveConfig(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
if err = tools.ServiceRestart(r.service); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("重启 %s 服务失败", r.service))
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Processes 进程列表
|
||||
@@ -305,18 +269,14 @@ func (r *SupervisorController) SaveProcessConfig(ctx http.Context) http.Response
|
||||
|
||||
// AddProcess 添加进程
|
||||
func (r *SupervisorController) AddProcess(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := controllers.Sanitize(ctx, map[string]string{
|
||||
"name": "required|alpha_dash",
|
||||
"user": "required|alpha_dash",
|
||||
"path": "required",
|
||||
"command": "required",
|
||||
"num": "required",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
name := ctx.Request().Input("name")
|
||||
@@ -336,6 +296,8 @@ redirect_stderr=true
|
||||
stdout_logfile=/var/log/supervisor/` + name + `.log
|
||||
stdout_logfile_maxbytes=2MB
|
||||
`
|
||||
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
err = tools.Write(`/etc/supervisord.d/`+name+`.conf`, config, 0644)
|
||||
} else {
|
||||
|
||||
@@ -39,14 +39,32 @@ func (r *SafeController) SetFirewallStatus(ctx http.Context) http.Response {
|
||||
if ctx.Request().InputBool("status") {
|
||||
if tools.IsRHEL() {
|
||||
err = tools.ServiceStart("firewalld")
|
||||
if err == nil {
|
||||
err = tools.ServiceEnable("firewalld")
|
||||
}
|
||||
} else {
|
||||
_, err = tools.Exec("echo y | ufw enable")
|
||||
if err == nil {
|
||||
err = tools.ServiceStart("ufw")
|
||||
}
|
||||
if err == nil {
|
||||
err = tools.ServiceEnable("ufw")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if tools.IsRHEL() {
|
||||
err = tools.ServiceStop("firewalld")
|
||||
if err == nil {
|
||||
err = tools.ServiceDisable("firewalld")
|
||||
}
|
||||
} else {
|
||||
_, err = tools.Exec("ufw disable")
|
||||
if err == nil {
|
||||
err = tools.ServiceStop("ufw")
|
||||
}
|
||||
if err == nil {
|
||||
err = tools.ServiceDisable("ufw")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +78,7 @@ func (r *SafeController) SetFirewallStatus(ctx http.Context) http.Response {
|
||||
// GetFirewallRules 获取防火墙规则
|
||||
func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -125,6 +143,10 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
}
|
||||
pagedRules := rules[startIndex:endIndex]
|
||||
|
||||
if pagedRules == nil {
|
||||
pagedRules = []map[string]string{}
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(rules),
|
||||
"items": pagedRules,
|
||||
|
||||
@@ -85,7 +85,7 @@ func (r *SettingController) List(ctx http.Context) http.Response {
|
||||
// @Router /panel/setting/update [post]
|
||||
func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
var updateRequest requests.Update
|
||||
sanitize := Sanitize(ctx, &updateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &updateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -50,33 +50,29 @@ func (r *SshController) GetInfo(ctx http.Context) http.Response {
|
||||
|
||||
// UpdateInfo 更新 SSH 配置
|
||||
func (r *SshController) UpdateInfo(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"host": "required",
|
||||
"port": "required",
|
||||
"user": "required",
|
||||
"password": "required",
|
||||
})
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
host := ctx.Request().Input("host")
|
||||
port := ctx.Request().Input("port")
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
if err = r.setting.Set(models.SettingKeySshHost, host); err != nil {
|
||||
if err := r.setting.Set(models.SettingKeySshHost, host); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if err = r.setting.Set(models.SettingKeySshPort, port); err != nil {
|
||||
if err := r.setting.Set(models.SettingKeySshPort, port); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if err = r.setting.Set(models.SettingKeySshUser, user); err != nil {
|
||||
if err := r.setting.Set(models.SettingKeySshUser, user); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if err = r.setting.Set(models.SettingKeySshPassword, password); err != nil {
|
||||
if err := r.setting.Set(models.SettingKeySshPassword, password); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
type SystemController struct {
|
||||
}
|
||||
|
||||
func NewSystemController() *SystemController {
|
||||
return &SystemController{}
|
||||
}
|
||||
|
||||
// ServiceStatus
|
||||
//
|
||||
// @Summary 服务状态
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/status [get]
|
||||
func (r *SystemController) ServiceStatus(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Query("service")
|
||||
status, err := tools.ServiceStatus(service)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("获取 %s 服务运行状态失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, status)
|
||||
}
|
||||
|
||||
// ServiceIsEnabled
|
||||
//
|
||||
// @Summary 是否启用服务
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/isEnabled [get]
|
||||
func (r *SystemController) ServiceIsEnabled(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Query("service")
|
||||
enabled, err := tools.ServiceIsEnabled(service)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("获取 %s 服务启用状态失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, enabled)
|
||||
}
|
||||
|
||||
// ServiceEnable
|
||||
//
|
||||
// @Summary 启用服务
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/enable [post]
|
||||
func (r *SystemController) ServiceEnable(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Input("service")
|
||||
if err := tools.ServiceEnable(service); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("启用 %s 服务失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ServiceDisable
|
||||
//
|
||||
// @Summary 禁用服务
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/disable [post]
|
||||
func (r *SystemController) ServiceDisable(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Input("service")
|
||||
if err := tools.ServiceDisable(service); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("禁用 %s 服务失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ServiceRestart
|
||||
//
|
||||
// @Summary 重启服务
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/restart [post]
|
||||
func (r *SystemController) ServiceRestart(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Input("service")
|
||||
if err := tools.ServiceRestart(service); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("重启 %s 服务失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ServiceReload
|
||||
//
|
||||
// @Summary 重载服务
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/reload [post]
|
||||
func (r *SystemController) ServiceReload(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Input("service")
|
||||
if err := tools.ServiceReload(service); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("重载 %s 服务失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ServiceStart
|
||||
//
|
||||
// @Summary 启动服务
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/start [post]
|
||||
func (r *SystemController) ServiceStart(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Input("service")
|
||||
if err := tools.ServiceStart(service); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("启动 %s 服务失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ServiceStop
|
||||
//
|
||||
// @Summary 停止服务
|
||||
// @Tags 系统
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body string true "request"
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /panel/system/service/stop [post]
|
||||
func (r *SystemController) ServiceStop(ctx http.Context) http.Response {
|
||||
if sanitize := Sanitize(ctx, map[string]string{
|
||||
"service": "required|string",
|
||||
}); sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
service := ctx.Request().Input("service")
|
||||
if err := tools.ServiceStop(service); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, fmt.Sprintf("停止 %s 服务失败", service))
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
@@ -32,7 +32,7 @@ func NewUserController() *UserController {
|
||||
// @Router /panel/user/login [post]
|
||||
func (r *UserController) Login(ctx http.Context) http.Response {
|
||||
var loginRequest requests.Login
|
||||
sanitize := Sanitize(ctx, &loginRequest)
|
||||
sanitize := SanitizeRequest(ctx, &loginRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -33,17 +33,16 @@ func NewWebsiteController() *WebsiteController {
|
||||
|
||||
// List
|
||||
//
|
||||
// @Summary 获取网站列表
|
||||
// @Description 获取网站管理的网站列表
|
||||
// @Tags 网站管理
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites [get]
|
||||
// @Summary 获取网站列表
|
||||
// @Tags 网站
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites [get]
|
||||
func (r *WebsiteController) List(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -64,18 +63,17 @@ func (r *WebsiteController) List(ctx http.Context) http.Response {
|
||||
|
||||
// Add
|
||||
//
|
||||
// @Summary 添加网站
|
||||
// @Description 添加网站到网站管理
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.Add true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites [post]
|
||||
// @Summary 添加网站
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.Add true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites [post]
|
||||
func (r *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
var addRequest requests.Add
|
||||
sanitize := Sanitize(ctx, &addRequest)
|
||||
sanitize := SanitizeRequest(ctx, &addRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -112,18 +110,17 @@ func (r *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
|
||||
// Delete
|
||||
//
|
||||
// @Summary 删除网站
|
||||
// @Description 删除网站管理的网站
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id} [delete]
|
||||
// @Summary 删除网站
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id} [delete]
|
||||
func (r *WebsiteController) Delete(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
sanitize := SanitizeRequest(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -142,13 +139,12 @@ func (r *WebsiteController) Delete(ctx http.Context) http.Response {
|
||||
|
||||
// GetDefaultConfig
|
||||
//
|
||||
// @Summary 获取默认配置
|
||||
// @Description 获取默认首页和停止页配置
|
||||
// @Tags 网站管理
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse{data=map[string]string}
|
||||
// @Router /panel/website/defaultConfig [get]
|
||||
// @Summary 获取默认配置
|
||||
// @Tags 网站
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse{data=map[string]string}
|
||||
// @Router /panel/website/defaultConfig [get]
|
||||
func (r *WebsiteController) GetDefaultConfig(ctx http.Context) http.Response {
|
||||
index, err := tools.Read("/www/server/openresty/html/index.html")
|
||||
if err != nil {
|
||||
@@ -167,15 +163,14 @@ func (r *WebsiteController) GetDefaultConfig(ctx http.Context) http.Response {
|
||||
|
||||
// SaveDefaultConfig
|
||||
//
|
||||
// @Summary 保存默认配置
|
||||
// @Description 保存默认首页和停止页配置
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body map[string]string true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/defaultConfig [post]
|
||||
// @Summary 保存默认配置
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body map[string]string true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/defaultConfig [post]
|
||||
func (r *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response {
|
||||
index := ctx.Request().Input("index")
|
||||
stop := ctx.Request().Input("stop")
|
||||
@@ -199,18 +194,17 @@ func (r *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response {
|
||||
|
||||
// GetConfig
|
||||
//
|
||||
// @Summary 获取配置
|
||||
// @Description 获取网站的配置
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse{data=types.Website}
|
||||
// @Router /panel/websites/{id}/config [get]
|
||||
// @Summary 获取网站配置
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @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
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
sanitize := SanitizeRequest(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -229,19 +223,18 @@ func (r *WebsiteController) GetConfig(ctx http.Context) http.Response {
|
||||
|
||||
// SaveConfig
|
||||
//
|
||||
// @Summary 保存配置
|
||||
// @Description 保存网站的配置
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Param data body requests.SaveConfig true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/config [post]
|
||||
// @Summary 保存网站配置
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Param data body requests.SaveConfig true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/config [post]
|
||||
func (r *WebsiteController) SaveConfig(ctx http.Context) http.Response {
|
||||
var saveConfigRequest requests.SaveConfig
|
||||
sanitize := Sanitize(ctx, &saveConfigRequest)
|
||||
sanitize := SanitizeRequest(ctx, &saveConfigRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -256,18 +249,17 @@ func (r *WebsiteController) SaveConfig(ctx http.Context) http.Response {
|
||||
|
||||
// ClearLog
|
||||
//
|
||||
// @Summary 清空日志
|
||||
// @Description 清空网站的日志
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/log [delete]
|
||||
// @Summary 清空网站日志
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/log [delete]
|
||||
func (r *WebsiteController) ClearLog(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
sanitize := SanitizeRequest(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -287,18 +279,17 @@ func (r *WebsiteController) ClearLog(ctx http.Context) http.Response {
|
||||
|
||||
// UpdateRemark
|
||||
//
|
||||
// @Summary 更新备注
|
||||
// @Description 更新网站的备注
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/updateRemark [post]
|
||||
// @Summary 更新网站备注
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/updateRemark [post]
|
||||
func (r *WebsiteController) UpdateRemark(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
sanitize := SanitizeRequest(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -323,17 +314,16 @@ func (r *WebsiteController) UpdateRemark(ctx http.Context) http.Response {
|
||||
|
||||
// BackupList
|
||||
//
|
||||
// @Summary 获取备份列表
|
||||
// @Description 获取网站的备份列表
|
||||
// @Tags 网站管理
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse{data=[]types.BackupFile}
|
||||
// @Router /panel/website/backupList [get]
|
||||
// @Summary 获取网站备份列表
|
||||
// @Tags 网站
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @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
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
sanitize := SanitizeRequest(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -370,18 +360,17 @@ func (r *WebsiteController) BackupList(ctx http.Context) http.Response {
|
||||
|
||||
// CreateBackup
|
||||
//
|
||||
// @Summary 创建备份
|
||||
// @Description 创建网站的备份
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/createBackup [post]
|
||||
// @Summary 创建网站备份
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/createBackup [post]
|
||||
func (r *WebsiteController) CreateBackup(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
sanitize := SanitizeRequest(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -408,15 +397,14 @@ func (r *WebsiteController) CreateBackup(ctx http.Context) http.Response {
|
||||
|
||||
// UploadBackup
|
||||
//
|
||||
// @Summary 上传备份
|
||||
// @Description 上传网站的备份
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param file formData file true "备份文件"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/uploadBackup [put]
|
||||
// @Summary 上传网站备份
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param file formData file true "备份文件"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/uploadBackup [put]
|
||||
func (r *WebsiteController) UploadBackup(ctx http.Context) http.Response {
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
@@ -444,18 +432,17 @@ func (r *WebsiteController) UploadBackup(ctx http.Context) http.Response {
|
||||
|
||||
// RestoreBackup
|
||||
//
|
||||
// @Summary 还原备份
|
||||
// @Description 还原网站的备份
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/restoreBackup [post]
|
||||
// @Summary 还原网站备份
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/restoreBackup [post]
|
||||
func (r *WebsiteController) RestoreBackup(ctx http.Context) http.Response {
|
||||
var restoreBackupRequest requests.RestoreBackup
|
||||
sanitize := Sanitize(ctx, &restoreBackupRequest)
|
||||
sanitize := SanitizeRequest(ctx, &restoreBackupRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -479,18 +466,17 @@ func (r *WebsiteController) RestoreBackup(ctx http.Context) http.Response {
|
||||
|
||||
// DeleteBackup
|
||||
//
|
||||
// @Summary 删除备份
|
||||
// @Description 删除网站的备份
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.DeleteBackup true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/deleteBackup [delete]
|
||||
// @Summary 删除网站备份
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param data body requests.DeleteBackup true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/deleteBackup [delete]
|
||||
func (r *WebsiteController) DeleteBackup(ctx http.Context) http.Response {
|
||||
var deleteBackupRequest requests.DeleteBackup
|
||||
sanitize := Sanitize(ctx, &deleteBackupRequest)
|
||||
sanitize := SanitizeRequest(ctx, &deleteBackupRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -511,18 +497,17 @@ func (r *WebsiteController) DeleteBackup(ctx http.Context) http.Response {
|
||||
|
||||
// ResetConfig
|
||||
//
|
||||
// @Summary 重置配置
|
||||
// @Description 重置网站的配置
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/resetConfig [post]
|
||||
// @Summary 重置网站配置
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/resetConfig [post]
|
||||
func (r *WebsiteController) ResetConfig(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
sanitize := SanitizeRequest(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
@@ -615,18 +600,17 @@ server
|
||||
|
||||
// Status
|
||||
//
|
||||
// @Summary 状态
|
||||
// @Description 启用或停用网站
|
||||
// @Tags 网站管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/status [post]
|
||||
// @Summary 获取网站状态
|
||||
// @Tags 网站
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerToken
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/websites/{id}/status [post]
|
||||
func (r *WebsiteController) Status(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
sanitize := SanitizeRequest(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
@@ -3,16 +3,15 @@ package requests
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
type CertStore struct {
|
||||
Type string `form:"type" json:"type"`
|
||||
Domains []string `form:"domains" json:"domains"`
|
||||
AutoRenew bool `form:"auto_renew" json:"auto_renew"`
|
||||
UserID uint `form:"user_id" json:"user_id"`
|
||||
DNSID *uint `form:"dns_id" json:"dns_id"`
|
||||
WebsiteID *uint `form:"website_id" json:"website_id"`
|
||||
UserID uint `form:"user_id" json:"user_id" filter:"uint"`
|
||||
DNSID uint `form:"dns_id" json:"dns_id" filter:"uint"`
|
||||
WebsiteID uint `form:"website_id" json:"website_id" filter:"uint"`
|
||||
}
|
||||
|
||||
func (r *CertStore) Authorize(ctx http.Context) error {
|
||||
@@ -39,29 +38,5 @@ func (r *CertStore) Attributes(ctx http.Context) map[string]string {
|
||||
}
|
||||
|
||||
func (r *CertStore) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
// TODO 由于验证器 filter 标签的问题,暂时这里这样处理
|
||||
userID, exist := data.Get("user_id")
|
||||
if exist {
|
||||
err := data.Set("user_id", cast.ToUint(userID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dnsID, exist := data.Get("dns_id")
|
||||
if exist {
|
||||
err := data.Set("dns_id", cast.ToUint(dnsID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
websiteID, exist := data.Get("website_id")
|
||||
if exist {
|
||||
err := data.Set("website_id", cast.ToUint(websiteID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package requests
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/validation"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
type CertUpdate struct {
|
||||
@@ -11,9 +10,9 @@ type CertUpdate struct {
|
||||
Type string `form:"type" json:"type"`
|
||||
Domains []string `form:"domains" json:"domains"`
|
||||
AutoRenew bool `form:"auto_renew" json:"auto_renew"`
|
||||
UserID uint `form:"user_id" json:"user_id"`
|
||||
DNSID *uint `form:"dns_id" json:"dns_id"`
|
||||
WebsiteID *uint `form:"website_id" json:"website_id"`
|
||||
UserID uint `form:"user_id" json:"user_id" filter:"uint"`
|
||||
DNSID uint `form:"dns_id" json:"dns_id" filter:"uint"`
|
||||
WebsiteID uint `form:"website_id" json:"website_id" filter:"uint"`
|
||||
}
|
||||
|
||||
func (r *CertUpdate) Authorize(ctx http.Context) error {
|
||||
@@ -41,29 +40,5 @@ func (r *CertUpdate) Attributes(ctx http.Context) map[string]string {
|
||||
}
|
||||
|
||||
func (r *CertUpdate) PrepareForValidation(ctx http.Context, data validation.Data) error {
|
||||
// TODO 由于验证器 filter 标签的问题,暂时这里这样处理
|
||||
userID, exist := data.Get("user_id")
|
||||
if exist {
|
||||
err := data.Set("user_id", cast.ToUint(userID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dnsID, exist := data.Get("dns_id")
|
||||
if exist {
|
||||
err := data.Set("dns_id", cast.ToUint(dnsID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
websiteID, exist := data.Get("website_id")
|
||||
if exist {
|
||||
err := data.Set("website_id", cast.ToUint(websiteID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ func (r *Archive) Authorize(ctx http.Context) error {
|
||||
func (r *Archive) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"paths": "array",
|
||||
"paths.*": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"file": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_not_exists`,
|
||||
"paths.*": `regex:^/.*$|path_exists`,
|
||||
"file": `regex:^/.*$|path_not_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ func (r *Copy) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Copy) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"source": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"target": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"source": `regex:^/.*$|path_exists`,
|
||||
"target": `regex:^/.*$`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ func (r *Exist) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Exist) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": `regex:^/([a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*)?$|path_exists`,
|
||||
"path": `regex:^/.*$|path_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ func (r *Move) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Move) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"source": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"target": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"source": `regex:^/.*$|path_exists`,
|
||||
"target": `regex:^/.*$`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ func (r *NotExist) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *NotExist) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_not_exists`,
|
||||
"path": `regex:^/.*$|path_not_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func (r *Permission) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Permission) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"path": `regex:^/.*$|path_exists`,
|
||||
"mode": "regex:^[0-7]{3}$|uint",
|
||||
"owner": "regex:^[a-zA-Z0-9_-]+$",
|
||||
"group": "regex:^[a-zA-Z0-9_-]+$",
|
||||
|
||||
@@ -16,7 +16,7 @@ func (r *Save) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Save) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"path": `regex:^/.*$|path_exists`,
|
||||
"content": "required|string",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func (r *Search) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Search) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"path": `regex:^/.*$|path_exists`,
|
||||
"keyword": "required|string",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ func (r *UnArchive) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *UnArchive) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"file": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_not_exists`,
|
||||
"file": `regex:^/.*$|path_exists`,
|
||||
"path": `regex:^/.*$|path_not_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func (r *Upload) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Upload) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"path": `regex:^/.*$`,
|
||||
"file": "required",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func (r *Create) Authorize(ctx http.Context) error {
|
||||
func (r *Create) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"path": `regex:^/.*$`,
|
||||
"comment": "string",
|
||||
"auth_user": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"secret": "required|min_len:8",
|
||||
|
||||
@@ -21,7 +21,7 @@ func (r *Update) Authorize(ctx http.Context) error {
|
||||
func (r *Update) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"path": `regex:^/.*$`,
|
||||
"comment": "string",
|
||||
"auth_user": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"secret": "required|min_len:8",
|
||||
|
||||
@@ -27,7 +27,7 @@ func (r *Add) Rules(ctx http.Context) map[string]string {
|
||||
"name": "required|regex:^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$|not_exists:websites,name|not_in:phpmyadmin,mysql,panel,ssh",
|
||||
"domains": "required|slice",
|
||||
"ports": "required|slice",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"path": `regex:^/.*$`,
|
||||
"php": "required",
|
||||
"db": "bool",
|
||||
"db_type": "required_if:db,true|in:0,mysql,postgresql",
|
||||
|
||||
+11
-13
@@ -1,22 +1,20 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
"github.com/goravel/framework/database/orm"
|
||||
)
|
||||
|
||||
type Cert struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
UserID uint `gorm:"default:null" json:"user_id"` // 关联的 ACME 用户 ID
|
||||
WebsiteID *uint `gorm:"default:null" json:"website_id"` // 关联的网站 ID
|
||||
DNSID *uint `gorm:"column:dns_id;default:null" json:"dns_id"` // 关联的 DNS ID
|
||||
Type string `gorm:"not null" json:"type"` // 证书类型 (P256, P384, 2048, 4096)
|
||||
Domains []string `gorm:"type:json;serializer:json" json:"domains"`
|
||||
AutoRenew bool `gorm:"default:true" json:"auto_renew"` // 自动续签
|
||||
CertURL *string `gorm:"default:null" json:"cert_url"` // 证书 URL (续签时使用)
|
||||
Cert string `gorm:"default:null" json:"cert"` // 证书内容
|
||||
Key string `gorm:"default:null" json:"key"` // 私钥内容
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
UserID uint `gorm:"not null" json:"user_id"` // 关联的 ACME 用户 ID
|
||||
WebsiteID uint `gorm:"not null" json:"website_id"` // 关联的网站 ID
|
||||
DNSID uint `gorm:"not null" json:"dns_id"` // 关联的 DNS ID
|
||||
Type string `gorm:"not null" json:"type"` // 证书类型 (P256, P384, 2048, 4096)
|
||||
Domains []string `gorm:"not null;serializer:json" json:"domains"`
|
||||
AutoRenew bool `gorm:"not null" json:"auto_renew"` // 自动续签
|
||||
CertURL string `gorm:"not null" json:"cert_url"` // 证书 URL (续签时使用)
|
||||
Cert string `gorm:"not null" json:"cert"` // 证书内容
|
||||
Key string `gorm:"not null" json:"key"` // 私钥内容
|
||||
|
||||
Website *Website `gorm:"foreignKey:WebsiteID" json:"website"`
|
||||
User *CertUser `gorm:"foreignKey:UserID" json:"user"`
|
||||
|
||||
+5
-11
@@ -1,22 +1,16 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
"github.com/goravel/framework/database/orm"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/acme"
|
||||
)
|
||||
|
||||
type CertDNS struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null" json:"name"` // 备注名称
|
||||
Type string `gorm:"not null" json:"type"` // DNS 提供商 (dnspod, aliyun, cloudflare)
|
||||
Data acme.DNSParam `gorm:"type:json;serializer:json" json:"dns_param"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Name string `gorm:"not null" json:"name"` // 备注名称
|
||||
Type string `gorm:"not null" json:"type"` // DNS 提供商 (dnspod, aliyun, cloudflare)
|
||||
Data acme.DNSParam `gorm:"not null;serializer:json" json:"dns_param"`
|
||||
|
||||
Certs []*Cert `gorm:"foreignKey:DNSID" json:"-"`
|
||||
}
|
||||
|
||||
func (CertDNS) TableName() string {
|
||||
return "cert_dns"
|
||||
}
|
||||
|
||||
+8
-12
@@ -1,19 +1,15 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
)
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
type CertUser struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Email string `gorm:"not null" json:"email"`
|
||||
CA string `gorm:"not null" json:"ca"` // CA 提供商 (letsencrypt, zerossl, sslcom, google, buypass)
|
||||
Kid *string `gorm:"default:null" json:"kid"`
|
||||
HmacEncoded *string `gorm:"default:null" json:"hmac_encoded"`
|
||||
PrivateKey string `gorm:"not null" json:"private_key"`
|
||||
KeyType string `gorm:"not null" json:"key_type"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Email string `gorm:"not null" json:"email"`
|
||||
CA string `gorm:"not null" json:"ca"` // CA 提供商 (letsencrypt, zerossl, sslcom, google, buypass)
|
||||
Kid string `gorm:"not null" json:"kid"`
|
||||
HmacEncoded string `gorm:"not null" json:"hmac_encoded"`
|
||||
PrivateKey string `gorm:"not null" json:"private_key"`
|
||||
KeyType string `gorm:"not null" json:"key_type"`
|
||||
|
||||
Certs []*Cert `gorm:"foreignKey:UserID" json:"-"`
|
||||
}
|
||||
|
||||
+8
-12
@@ -1,17 +1,13 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
)
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
type Cron struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null;unique" json:"name"`
|
||||
Status bool `gorm:"not null;default:false" json:"status"`
|
||||
Type string `gorm:"not null" json:"type"`
|
||||
Time string `gorm:"not null" json:"time"`
|
||||
Shell string `gorm:"default:''" json:"shell"`
|
||||
Log string `gorm:"default:''" json:"log"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Name string `gorm:"not null;unique" json:"name"`
|
||||
Status bool `gorm:"not null" json:"status"`
|
||||
Type string `gorm:"not null" json:"type"`
|
||||
Time string `gorm:"not null" json:"time"`
|
||||
Shell string `gorm:"not null" json:"shell"`
|
||||
Log string `gorm:"not null" json:"log"`
|
||||
}
|
||||
|
||||
+9
-11
@@ -1,16 +1,14 @@
|
||||
package models
|
||||
|
||||
import "github.com/goravel/framework/support/carbon"
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
type Database struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"unique;not null" json:"name"`
|
||||
Type string `gorm:"not null;index" json:"type"`
|
||||
Host string `gorm:"not null" json:"host"`
|
||||
Port int `gorm:"not null" json:"port"`
|
||||
Username string `gorm:"not null" json:"username"`
|
||||
Password string `gorm:"default:''" json:"password"`
|
||||
Remark string `gorm:"default:''" json:"remark"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Name string `gorm:"not null;unique" json:"name"`
|
||||
Type string `gorm:"not null" json:"type"`
|
||||
Host string `gorm:"not null" json:"host"`
|
||||
Port int `gorm:"not null" json:"port"`
|
||||
Username string `gorm:"not null" json:"username"`
|
||||
Password string `gorm:"not null" json:"password"`
|
||||
Remark string `gorm:"not null" json:"remark"`
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
"github.com/goravel/framework/database/orm"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
type Monitor struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Info tools.MonitoringInfo `gorm:"type:json;serializer:json" json:"info"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Info tools.MonitoringInfo `gorm:"not null;serializer:json" json:"info"`
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package models
|
||||
|
||||
import "github.com/goravel/framework/support/carbon"
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
type Plugin struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Slug string `gorm:"unique;not null" json:"slug"`
|
||||
Version string `gorm:"not null" json:"version"`
|
||||
Show bool `gorm:"default:false;not null" json:"show"`
|
||||
ShowOrder int `gorm:"default:0;not null" json:"show_order"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Slug string `gorm:"not null;unique" json:"slug"`
|
||||
Version string `gorm:"not null" json:"version"`
|
||||
Show bool `gorm:"not null" json:"show"`
|
||||
ShowOrder int `gorm:"not null" json:"show_order"`
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package models
|
||||
|
||||
import "github.com/goravel/framework/support/carbon"
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
const (
|
||||
SettingKeyName = "name"
|
||||
@@ -17,9 +17,7 @@ const (
|
||||
)
|
||||
|
||||
type Setting struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Key string `gorm:"unique;not null" json:"key"`
|
||||
Value string `gorm:"default:''" json:"value"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Key string `gorm:"not null;unique" json:"key"`
|
||||
Value string `gorm:"not null" json:"value"`
|
||||
}
|
||||
|
||||
+6
-10
@@ -1,8 +1,6 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
)
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
const (
|
||||
TaskStatusWaiting = "waiting"
|
||||
@@ -12,11 +10,9 @@ const (
|
||||
)
|
||||
|
||||
type Task struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
Status string `gorm:"not null;default:'waiting'" json:"status"`
|
||||
Shell string `gorm:"default:''" json:"shell"`
|
||||
Log string `gorm:"default:''" json:"log"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Name string `gorm:"not null;index" json:"name"`
|
||||
Status string `gorm:"not null;default:'waiting'" json:"status"`
|
||||
Shell string `gorm:"not null" json:"shell"`
|
||||
Log string `gorm:"not null" json:"log"`
|
||||
}
|
||||
|
||||
+5
-7
@@ -1,12 +1,10 @@
|
||||
package models
|
||||
|
||||
import "github.com/goravel/framework/support/carbon"
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
type User struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Username string `gorm:"unique;not null" json:"username"`
|
||||
Password string `gorm:"not null" json:"password"`
|
||||
Email string `gorm:"default:''" json:"email"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Username string `gorm:"not null;unique" json:"username"`
|
||||
Password string `gorm:"not null" json:"password"`
|
||||
Email string `gorm:"not null" json:"email"`
|
||||
}
|
||||
|
||||
+8
-12
@@ -1,19 +1,15 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
)
|
||||
import "github.com/goravel/framework/database/orm"
|
||||
|
||||
type Website struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `json:"name"`
|
||||
Status bool `gorm:"default:true" json:"status"`
|
||||
Path string `json:"path"`
|
||||
Php int `gorm:"default:0;not null;index" json:"php"`
|
||||
Ssl bool `gorm:"default:false;not null;index" json:"ssl"`
|
||||
Remark string `gorm:"default:''" json:"remark"`
|
||||
CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"`
|
||||
UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"`
|
||||
orm.Model
|
||||
Name string `gorm:"not null;unique" json:"name"`
|
||||
Status bool `gorm:"not null;default:true" json:"status"`
|
||||
Path string `gorm:"not null" json:"path"`
|
||||
Php int `gorm:"not null" json:"php"`
|
||||
Ssl bool `gorm:"not null" json:"ssl"`
|
||||
Remark string `gorm:"not null" json:"remark"`
|
||||
|
||||
Cert *Cert `gorm:"foreignKey:WebsiteID" json:"cert"`
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package providers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goravel/framework/contracts/database/seeder"
|
||||
"github.com/goravel/framework/contracts/foundation"
|
||||
"github.com/goravel/framework/database/gorm"
|
||||
"github.com/goravel/framework/facades"
|
||||
|
||||
"github.com/TheTNB/panel/database/seeders"
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
)
|
||||
|
||||
type DatabaseServiceProvider struct {
|
||||
@@ -16,7 +19,20 @@ func (receiver *DatabaseServiceProvider) Register(app foundation.Application) {
|
||||
}
|
||||
|
||||
func (receiver *DatabaseServiceProvider) Boot(app foundation.Application) {
|
||||
facades.Seeder().Register([]seeder.Seeder{
|
||||
&seeders.DatabaseSeeder{},
|
||||
})
|
||||
facades.Seeder().Register([]seeder.Seeder{})
|
||||
if err := facades.Orm().Query().(*gorm.QueryImpl).Instance().AutoMigrate(
|
||||
&models.Cert{},
|
||||
&models.CertDNS{},
|
||||
&models.CertUser{},
|
||||
&models.Cron{},
|
||||
&models.Database{},
|
||||
&models.Monitor{},
|
||||
&models.Plugin{},
|
||||
&models.Setting{},
|
||||
&models.Task{},
|
||||
&models.User{},
|
||||
&models.Website{},
|
||||
); err != nil {
|
||||
panic(fmt.Sprintf("Failed to migrate database: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,12 @@ func init() {
|
||||
// the language folders that are provided through your application.
|
||||
"fallback_locale": "zh_CN",
|
||||
|
||||
// Application Lang Path
|
||||
//
|
||||
// The path to the language files for the application. You may change
|
||||
// the path to a different directory if you would like to customize it.
|
||||
"lang_path": facades.App().ExecutablePath("lang"),
|
||||
|
||||
// Encryption Key
|
||||
//
|
||||
// 32 character string, otherwise these encrypted strings
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ func init() {
|
||||
"connections": map[string]any{
|
||||
"panel": map[string]any{
|
||||
"driver": "sqlite",
|
||||
"database": config.Env("DB_FILE", "/www/panel/storage/panel.db"),
|
||||
"database": config.Env("DB_FILE", facades.App().ExecutablePath("storage/panel.db")),
|
||||
"prefix": "",
|
||||
"singular": false, // Table name is singular
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@ func init() {
|
||||
"disks": map[string]any{
|
||||
"local": map[string]any{
|
||||
"driver": "local",
|
||||
"root": "/www/panel/storage",
|
||||
"root": facades.App().ExecutablePath("storage"),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
+2
-2
@@ -39,9 +39,9 @@ func init() {
|
||||
// SSL Certificate
|
||||
"ssl": map[string]any{
|
||||
// ca.pem
|
||||
"cert": config.Env("APP_SSL_CERT", "/www/panel/storage/ssl.crt"),
|
||||
"cert": config.Env("APP_SSL_CERT", facades.App().ExecutablePath("storage/ssl.crt")),
|
||||
// ca.key
|
||||
"key": config.Env("APP_SSL_KEY", "/www/panel/storage/ssl.key"),
|
||||
"key": config.Env("APP_SSL_KEY", facades.App().ExecutablePath("storage/ssl.key")),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ func init() {
|
||||
config := facades.Config()
|
||||
config.Add("panel", map[string]any{
|
||||
"name": "耗子面板",
|
||||
"version": "v2.2.8",
|
||||
"version": "v2.2.9",
|
||||
"ssl": config.Env("APP_SSL", false),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS users;
|
||||
@@ -1,11 +0,0 @@
|
||||
CREATE TABLE users
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
username varchar(255) NOT NULL,
|
||||
password varchar(255) NOT NULL,
|
||||
email varchar(255) DEFAULT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX users_username_unique ON users (username);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS websites;
|
||||
@@ -1,17 +0,0 @@
|
||||
CREATE TABLE websites
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name varchar(255) NOT NULL,
|
||||
status boolean DEFAULT 1 NOT NULL,
|
||||
path varchar(255) NOT NULL,
|
||||
php integer DEFAULT 0 NOT NULL,
|
||||
ssl boolean DEFAULT 0 NOT NULL,
|
||||
remark text DEFAULT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX websites_name_unique ON websites (name);
|
||||
CREATE INDEX websites_status_index ON websites (status);
|
||||
CREATE INDEX websites_php_index ON websites (php);
|
||||
CREATE INDEX websites_ssl_index ON websites (ssl);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS settings;
|
||||
@@ -1,10 +0,0 @@
|
||||
CREATE TABLE settings
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
key varchar(255) NOT NULL,
|
||||
value varchar(255) DEFAULT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX settings_key_unique ON settings (key);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS databases;
|
||||
@@ -1,16 +0,0 @@
|
||||
CREATE TABLE databases
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name varchar(255) NOT NULL,
|
||||
type varchar(255) NOT NULL,
|
||||
host varchar(255) NOT NULL,
|
||||
port integer NOT NULL,
|
||||
username varchar(255) NOT NULL,
|
||||
password varchar(255) DEFAULT NULL,
|
||||
remark text DEFAULT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX databases_name_unique ON databases (name);
|
||||
CREATE INDEX databases_type_index ON databases (type);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS plugins;
|
||||
@@ -1,14 +0,0 @@
|
||||
CREATE TABLE plugins
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
slug varchar(255) NOT NULL,
|
||||
version varchar(255) NOT NULL,
|
||||
show boolean DEFAULT 0 NOT NULL,
|
||||
show_order integer DEFAULT 0 NOT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX plugins_slug_unique ON plugins (slug);
|
||||
CREATE INDEX plugins_show_index ON plugins (show);
|
||||
CREATE INDEX plugins_show_order_index ON plugins (show_order);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS tasks;
|
||||
@@ -1,12 +0,0 @@
|
||||
CREATE TABLE tasks
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name varchar(255) NOT NULL,
|
||||
status varchar(255) DEFAULT 'waiting' NOT NULL,
|
||||
shell varchar(255) DEFAULT NULL,
|
||||
log varchar(255) DEFAULT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX tasks_status_index ON tasks (status);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS monitors;
|
||||
@@ -1,7 +0,0 @@
|
||||
CREATE TABLE monitors
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
info text NOT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS crons;
|
||||
@@ -1,16 +0,0 @@
|
||||
CREATE TABLE crons
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name varchar(255) NOT NULL,
|
||||
status boolean DEFAULT 0 NOT NULL,
|
||||
type varchar(255) NOT NULL,
|
||||
time varchar(255) NOT NULL,
|
||||
shell varchar(255) DEFAULT NULL,
|
||||
log varchar(255) DEFAULT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX crons_name_unique ON crons (name);
|
||||
CREATE INDEX crons_status_index ON crons (status);
|
||||
CREATE INDEX crons_type_index ON crons (type);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS cert_users;
|
||||
@@ -1,14 +0,0 @@
|
||||
CREATE TABLE cert_users
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
email varchar(255) NOT NULL,
|
||||
ca varchar(255) NOT NULL,
|
||||
kid varchar(255) DEFAULT NULL,
|
||||
hmac_encoded varchar(255) DEFAULT NULL,
|
||||
private_key text NOT NULL,
|
||||
key_type varchar(255) NOT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cert_users_email ON cert_users (email);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS cert_dns;
|
||||
@@ -1,9 +0,0 @@
|
||||
CREATE TABLE cert_dns
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name varchar(255) NOT NULL,
|
||||
type varchar(255) NOT NULL,
|
||||
data text NOT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
@@ -1 +0,0 @@
|
||||
DROP TABLE IF EXISTS certs;
|
||||
@@ -1,15 +0,0 @@
|
||||
CREATE TABLE certs
|
||||
(
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
user_id integer NOT NULL,
|
||||
website_id integer DEFAULT NULL,
|
||||
dns_id integer DEFAULT NULL,
|
||||
type varchar(255) NOT NULL,
|
||||
domains text NOT NULL,
|
||||
auto_renew integer DEFAULT 1,
|
||||
cert_url varchar(255) DEFAULT NULL,
|
||||
cert text DEFAULT NULL,
|
||||
key text DEFAULT NULL,
|
||||
created_at datetime NOT NULL,
|
||||
updated_at datetime NOT NULL
|
||||
);
|
||||
@@ -1,14 +0,0 @@
|
||||
package seeders
|
||||
|
||||
type DatabaseSeeder struct {
|
||||
}
|
||||
|
||||
// Signature The name and signature of the seeder.
|
||||
func (s *DatabaseSeeder) Signature() string {
|
||||
return "DatabaseSeeder"
|
||||
}
|
||||
|
||||
// Run executes the seeder logic.
|
||||
func (s *DatabaseSeeder) Run() error {
|
||||
return nil
|
||||
}
|
||||
+993
-679
File diff suppressed because it is too large
Load Diff
+993
-679
File diff suppressed because it is too large
Load Diff
+640
-454
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,10 @@ require (
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/go-resty/resty/v2 v2.13.1
|
||||
github.com/gookit/validate v1.5.2
|
||||
github.com/goravel/framework v1.14.1-0.20240608091017-72e9e3621f24
|
||||
github.com/goravel/framework v1.14.1-0.20240618022250-731b8d9930a3
|
||||
github.com/goravel/gin v1.2.1
|
||||
github.com/gorilla/websocket v1.5.2
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/libdns/alidns v1.0.3
|
||||
github.com/libdns/cloudflare v0.1.1
|
||||
github.com/libdns/dnspod v0.0.3
|
||||
@@ -35,7 +36,7 @@ require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.22 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.16 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
@@ -121,7 +122,6 @@ require (
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/lithammer/fuzzysearch v1.1.8 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
@@ -200,11 +200,11 @@ require (
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/mysql v1.5.6 // indirect
|
||||
gorm.io/driver/postgres v1.5.7 // indirect
|
||||
gorm.io/driver/mysql v1.5.7 // indirect
|
||||
gorm.io/driver/postgres v1.5.9 // indirect
|
||||
gorm.io/driver/sqlserver v1.5.3 // indirect
|
||||
gorm.io/gorm v1.25.10 // indirect
|
||||
gorm.io/plugin/dbresolver v1.5.1 // indirect
|
||||
gorm.io/plugin/dbresolver v1.5.2 // indirect
|
||||
gotest.tools/v3 v3.5.0 // indirect
|
||||
modernc.org/libc v1.37.6 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
|
||||
@@ -33,8 +33,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.22 h1:/GblQdIudfEM3AWWZ0mrYJQSd7JS4S/Mbzh6F0ov0Xc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.16 h1:P8An8Z9rH1ldbOLdFpxYorgOt2sywL9V24dAwWHPuGc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.16/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
|
||||
@@ -200,7 +200,6 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx
|
||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
|
||||
github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
@@ -277,14 +276,14 @@ github.com/gookit/validate v1.5.2 h1:i5I2OQ7WYHFRPRATGu9QarR9snnNHydvwSuHXaRWAV0
|
||||
github.com/gookit/validate v1.5.2/go.mod h1:yuPy2WwDlwGRa06fFJ5XIO8QEwhRnTC2LmxmBa5SE14=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.2 h1:g68AzbePXcm0V2CpUMc9j4qVzcDn7+7aoWSjZ51C0m4=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.2/go.mod h1:23VuSW8cBS4ax5cmbV+5AaiLpq25b8UJ96IhbAkdo8I=
|
||||
github.com/goravel/framework v1.14.1-0.20240608091017-72e9e3621f24 h1:LEE75NYDaUasNfcxHvQU7Bpfyt7kA2P8izMXAxFqK9w=
|
||||
github.com/goravel/framework v1.14.1-0.20240608091017-72e9e3621f24/go.mod h1:xGI8IGkgJoqqjCE3ExbpUNJutbG1ZtjhFkzx68UuW7I=
|
||||
github.com/goravel/framework v1.14.1-0.20240618022250-731b8d9930a3 h1:G9aMInp4s2pL/bpVXrUj+NUtnVU8i7T9t6vGUJ60NaM=
|
||||
github.com/goravel/framework v1.14.1-0.20240618022250-731b8d9930a3/go.mod h1:RTwF0A7HySf5i+2jptT9oyFqmQAiQubWn1AQrJAzPWg=
|
||||
github.com/goravel/gin v1.2.1 h1:lnQX3NKUEaSx8x7AAJpoeVkXgi+MVQ9FXy4QywHQElo=
|
||||
github.com/goravel/gin v1.2.1/go.mod h1:Qt3NJysg/eoxXL4y/swwFUcfcIT7XG+xb0rWChweZfY=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.5.2 h1:qoW6V1GT3aZxybsbC6oLnailWnB+qTMVwMreOso9XUw=
|
||||
github.com/gorilla/websocket v1.5.2/go.mod h1:0n9H61RBAcf5/38py2MCYbxzPIY9rOkpvvMT24Rqs30=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
@@ -314,7 +313,6 @@ github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
@@ -581,8 +579,8 @@ golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
@@ -623,7 +621,6 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
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=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
@@ -660,7 +657,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -698,7 +694,6 @@ golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
@@ -784,21 +779,19 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
|
||||
gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
|
||||
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
|
||||
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||
gorm.io/driver/sqlserver v1.5.3 h1:rjupPS4PVw+rjJkfvr8jn2lJ8BMhT4UW5FwuJY0P3Z0=
|
||||
gorm.io/driver/sqlserver v1.5.3/go.mod h1:B+CZ0/7oFJ6tAlefsKoyxdgDCXJKSgwS2bMOQZT0I00=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
|
||||
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/plugin/dbresolver v1.5.1 h1:s9Dj9f7r+1rE3nx/Ywzc85nXptUEaeOO0pt27xdopM8=
|
||||
gorm.io/plugin/dbresolver v1.5.1/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
|
||||
gorm.io/plugin/dbresolver v1.5.2 h1:Iut7lW4TXNoVs++I+ra3zxjSxTRj4ocIeFEVp4lLhII=
|
||||
gorm.io/plugin/dbresolver v1.5.2/go.mod h1:jPh59GOQbO7v7v28ZKZPd45tr+u3vyT+8tHdfdfOWcU=
|
||||
gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
|
||||
gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
+18
-18
@@ -28,8 +28,8 @@ func (s *CertImpl) UserStore(request requests.UserStore) error {
|
||||
var user models.CertUser
|
||||
user.CA = request.CA
|
||||
user.Email = request.Email
|
||||
user.Kid = &request.Kid
|
||||
user.HmacEncoded = &request.HmacEncoded
|
||||
user.Kid = request.Kid
|
||||
user.HmacEncoded = request.HmacEncoded
|
||||
user.KeyType = request.KeyType
|
||||
|
||||
var err error
|
||||
@@ -40,11 +40,11 @@ func (s *CertImpl) UserStore(request requests.UserStore) error {
|
||||
case "buypass":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CABuypass, nil, acme.KeyType(user.KeyType))
|
||||
case "zerossl":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAZeroSSL, &acme.EAB{KeyID: *user.Kid, MACKey: *user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAZeroSSL, &acme.EAB{KeyID: user.Kid, MACKey: user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
case "sslcom":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CASSLcom, &acme.EAB{KeyID: *user.Kid, MACKey: *user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CASSLcom, &acme.EAB{KeyID: user.Kid, MACKey: user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
case "google":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAGoogle, &acme.EAB{KeyID: *user.Kid, MACKey: *user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAGoogle, &acme.EAB{KeyID: user.Kid, MACKey: user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
default:
|
||||
return errors.New("CA 提供商不支持")
|
||||
}
|
||||
@@ -72,8 +72,8 @@ func (s *CertImpl) UserUpdate(request requests.UserUpdate) error {
|
||||
|
||||
user.CA = request.CA
|
||||
user.Email = request.Email
|
||||
user.Kid = &request.Kid
|
||||
user.HmacEncoded = &request.HmacEncoded
|
||||
user.Kid = request.Kid
|
||||
user.HmacEncoded = request.HmacEncoded
|
||||
user.KeyType = request.KeyType
|
||||
|
||||
var client *acme.Client
|
||||
@@ -83,11 +83,11 @@ func (s *CertImpl) UserUpdate(request requests.UserUpdate) error {
|
||||
case "buypass":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CABuypass, nil, acme.KeyType(user.KeyType))
|
||||
case "zerossl":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAZeroSSL, &acme.EAB{KeyID: *user.Kid, MACKey: *user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAZeroSSL, &acme.EAB{KeyID: user.Kid, MACKey: user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
case "sslcom":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CASSLcom, &acme.EAB{KeyID: *user.Kid, MACKey: *user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CASSLcom, &acme.EAB{KeyID: user.Kid, MACKey: user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
case "google":
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAGoogle, &acme.EAB{KeyID: *user.Kid, MACKey: *user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
client, err = acme.NewRegisterAccount(context.Background(), user.Email, acme.CAGoogle, &acme.EAB{KeyID: user.Kid, MACKey: user.HmacEncoded}, acme.KeyType(user.KeyType))
|
||||
default:
|
||||
return errors.New("CA 提供商不支持")
|
||||
}
|
||||
@@ -262,7 +262,7 @@ func (s *CertImpl) ObtainAuto(ID uint) (acme.Certificate, error) {
|
||||
return acme.Certificate{}, err
|
||||
}
|
||||
|
||||
cert.CertURL = &ssl.URL
|
||||
cert.CertURL = ssl.URL
|
||||
cert.Cert = string(ssl.ChainPEM)
|
||||
cert.Key = string(ssl.PrivateKey)
|
||||
err = facades.Orm().Query().Save(&cert)
|
||||
@@ -302,7 +302,7 @@ func (s *CertImpl) ObtainManual(ID uint) (acme.Certificate, error) {
|
||||
return acme.Certificate{}, err
|
||||
}
|
||||
|
||||
cert.CertURL = &ssl.URL
|
||||
cert.CertURL = ssl.URL
|
||||
cert.Cert = string(ssl.ChainPEM)
|
||||
cert.Key = string(ssl.PrivateKey)
|
||||
err = facades.Orm().Query().Save(&cert)
|
||||
@@ -363,7 +363,7 @@ func (s *CertImpl) Renew(ID uint) (acme.Certificate, error) {
|
||||
return acme.Certificate{}, err
|
||||
}
|
||||
|
||||
if cert.CertURL == nil {
|
||||
if cert.CertURL == "" {
|
||||
return acme.Certificate{}, errors.New("该证书没有签发成功,无法续签")
|
||||
}
|
||||
|
||||
@@ -382,12 +382,12 @@ func (s *CertImpl) Renew(ID uint) (acme.Certificate, error) {
|
||||
}
|
||||
}
|
||||
|
||||
ssl, err := client.RenewSSL(context.Background(), *cert.CertURL, cert.Domains, acme.KeyType(cert.Type))
|
||||
ssl, err := client.RenewSSL(context.Background(), cert.CertURL, cert.Domains, acme.KeyType(cert.Type))
|
||||
if err != nil {
|
||||
return acme.Certificate{}, err
|
||||
}
|
||||
|
||||
cert.CertURL = &ssl.URL
|
||||
cert.CertURL = ssl.URL
|
||||
cert.Cert = string(ssl.ChainPEM)
|
||||
cert.Key = string(ssl.PrivateKey)
|
||||
err = facades.Orm().Query().Save(&cert)
|
||||
@@ -451,13 +451,13 @@ func (s *CertImpl) getClient(cert models.Cert) (*acme.Client, error) {
|
||||
ca = acme.CABuypass
|
||||
case "zerossl":
|
||||
ca = acme.CAZeroSSL
|
||||
eab = &acme.EAB{KeyID: *cert.User.Kid, MACKey: *cert.User.HmacEncoded}
|
||||
eab = &acme.EAB{KeyID: cert.User.Kid, MACKey: cert.User.HmacEncoded}
|
||||
case "sslcom":
|
||||
ca = acme.CASSLcom
|
||||
eab = &acme.EAB{KeyID: *cert.User.Kid, MACKey: *cert.User.HmacEncoded}
|
||||
eab = &acme.EAB{KeyID: cert.User.Kid, MACKey: cert.User.HmacEncoded}
|
||||
case "google":
|
||||
ca = acme.CAGoogle
|
||||
eab = &acme.EAB{KeyID: *cert.User.Kid, MACKey: *cert.User.HmacEncoded}
|
||||
eab = &acme.EAB{KeyID: cert.User.Kid, MACKey: cert.User.HmacEncoded}
|
||||
}
|
||||
|
||||
return acme.NewPrivateKeyAccount(cert.User.Email, cert.User.PrivateKey, ca, eab)
|
||||
|
||||
@@ -27,26 +27,10 @@ func NewPHPImpl(version uint) *PHPImpl {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PHPImpl) Status() (bool, error) {
|
||||
return tools.ServiceStatus("php-fpm-" + r.version)
|
||||
}
|
||||
|
||||
func (r *PHPImpl) Reload() error {
|
||||
return tools.ServiceReload("php-fpm-" + r.version)
|
||||
}
|
||||
|
||||
func (r *PHPImpl) Start() error {
|
||||
return tools.ServiceStart("php-fpm-" + r.version)
|
||||
}
|
||||
|
||||
func (r *PHPImpl) Stop() error {
|
||||
return tools.ServiceStop("php-fpm-" + r.version)
|
||||
}
|
||||
|
||||
func (r *PHPImpl) Restart() error {
|
||||
return tools.ServiceRestart("php-fpm-" + r.version)
|
||||
}
|
||||
|
||||
func (r *PHPImpl) GetConfig() (string, error) {
|
||||
return tools.Read("/www/server/php/" + r.version + "/etc/php.ini")
|
||||
}
|
||||
@@ -75,7 +59,7 @@ func (r *PHPImpl) Load() ([]types.NV, error) {
|
||||
client := resty.New().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
|
||||
if err != nil || !resp.IsSuccess() {
|
||||
return nil, errors.New("获取 PHP-" + r.version + " 运行状态失败")
|
||||
return []types.NV{}, nil
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
|
||||
@@ -76,10 +76,7 @@ func (r *PluginImpl) GetBySlug(slug string) types.Plugin {
|
||||
// GetInstalledBySlug 根据 slug 获取已安装的插件
|
||||
func (r *PluginImpl) GetInstalledBySlug(slug string) models.Plugin {
|
||||
var plugin models.Plugin
|
||||
if err := facades.Orm().Query().Where("slug", slug).Get(&plugin); err != nil {
|
||||
return plugin
|
||||
}
|
||||
|
||||
_ = facades.Orm().Query().Where("slug", slug).Get(&plugin)
|
||||
return plugin
|
||||
}
|
||||
|
||||
|
||||
@@ -476,10 +476,6 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
_, _ = Exec("chmod -R 700 /usr/bin/panel")
|
||||
color.Green().Printfln("设置完成")
|
||||
|
||||
if _, err = Exec("/www/panel/panel --env=panel.conf artisan migrate"); err != nil {
|
||||
color.Red().Printfln("运行面板数据库迁移失败")
|
||||
return err
|
||||
}
|
||||
if _, err = Exec("bash /www/panel/scripts/update_panel.sh"); err != nil {
|
||||
color.Red().Printfln("执行面板升级后脚本失败")
|
||||
return err
|
||||
|
||||
@@ -89,6 +89,7 @@ func Api() {
|
||||
r.Post("uninstall", pluginController.Uninstall)
|
||||
r.Post("update", pluginController.Update)
|
||||
r.Post("updateShow", pluginController.UpdateShow)
|
||||
r.Get("isInstalled", pluginController.IsInstalled)
|
||||
})
|
||||
r.Prefix("cron").Middleware(middleware.Jwt()).Group(func(r route.Router) {
|
||||
cronController := controllers.NewCronController()
|
||||
@@ -199,6 +200,17 @@ func Api() {
|
||||
r.Get("list", settingController.List)
|
||||
r.Post("update", settingController.Update)
|
||||
})
|
||||
r.Prefix("system").Middleware(middleware.Jwt()).Group(func(r route.Router) {
|
||||
controller := controllers.NewSystemController()
|
||||
r.Get("service/status", controller.ServiceStatus)
|
||||
r.Get("service/isEnabled", controller.ServiceIsEnabled)
|
||||
r.Post("service/enable", controller.ServiceEnable)
|
||||
r.Post("service/disable", controller.ServiceDisable)
|
||||
r.Post("service/restart", controller.ServiceRestart)
|
||||
r.Post("service/reload", controller.ServiceReload)
|
||||
r.Post("service/start", controller.ServiceStart)
|
||||
r.Post("service/stop", controller.ServiceStop)
|
||||
})
|
||||
})
|
||||
|
||||
// 文档
|
||||
|
||||
+37
-266
@@ -13,24 +13,14 @@ func Plugin() {
|
||||
facades.Route().Prefix("api/plugins").Middleware(middleware.Jwt(), middleware.MustInstall()).Group(func(r route.Router) {
|
||||
r.Prefix("openresty").Group(func(route route.Router) {
|
||||
openRestyController := plugins.NewOpenrestyController()
|
||||
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.Post("clearErrorLog", openRestyController.ClearErrorLog)
|
||||
})
|
||||
r.Prefix("mysql57").Group(func(route route.Router) {
|
||||
r.Prefix("mysql").Group(func(route route.Router) {
|
||||
mySQLController := plugins.NewMySQLController()
|
||||
route.Get("status", mySQLController.Status)
|
||||
route.Post("reload", mySQLController.Reload)
|
||||
route.Post("start", mySQLController.Start)
|
||||
route.Post("stop", mySQLController.Stop)
|
||||
route.Post("restart", mySQLController.Restart)
|
||||
route.Get("load", mySQLController.Load)
|
||||
route.Get("config", mySQLController.GetConfig)
|
||||
route.Post("config", mySQLController.SaveConfig)
|
||||
@@ -54,219 +44,42 @@ func Plugin() {
|
||||
route.Post("users/password", mySQLController.SetUserPassword)
|
||||
route.Post("users/privileges", mySQLController.SetUserPrivileges)
|
||||
})
|
||||
r.Prefix("mysql80").Group(func(route route.Router) {
|
||||
mySQLController := plugins.NewMySQLController()
|
||||
route.Get("status", mySQLController.Status)
|
||||
route.Post("reload", mySQLController.Reload)
|
||||
route.Post("start", mySQLController.Start)
|
||||
route.Post("stop", mySQLController.Stop)
|
||||
route.Post("restart", mySQLController.Restart)
|
||||
route.Get("load", mySQLController.Load)
|
||||
route.Get("config", mySQLController.GetConfig)
|
||||
route.Post("config", mySQLController.SaveConfig)
|
||||
route.Get("errorLog", mySQLController.ErrorLog)
|
||||
route.Post("clearErrorLog", mySQLController.ClearErrorLog)
|
||||
route.Get("slowLog", mySQLController.SlowLog)
|
||||
route.Post("clearSlowLog", mySQLController.ClearSlowLog)
|
||||
route.Get("rootPassword", mySQLController.GetRootPassword)
|
||||
route.Post("rootPassword", mySQLController.SetRootPassword)
|
||||
route.Get("databases", mySQLController.DatabaseList)
|
||||
route.Post("databases", mySQLController.AddDatabase)
|
||||
route.Delete("databases", mySQLController.DeleteDatabase)
|
||||
route.Get("backups", mySQLController.BackupList)
|
||||
route.Post("backups", mySQLController.CreateBackup)
|
||||
route.Put("backups", mySQLController.UploadBackup)
|
||||
route.Delete("backups", mySQLController.DeleteBackup)
|
||||
route.Post("backups/restore", mySQLController.RestoreBackup)
|
||||
route.Get("users", mySQLController.UserList)
|
||||
route.Post("users", mySQLController.AddUser)
|
||||
route.Delete("users", mySQLController.DeleteUser)
|
||||
route.Post("users/password", mySQLController.SetUserPassword)
|
||||
route.Post("users/privileges", mySQLController.SetUserPrivileges)
|
||||
r.Prefix("postgresql").Group(func(route route.Router) {
|
||||
controller := plugins.NewPostgreSQLController()
|
||||
route.Get("load", controller.Load)
|
||||
route.Get("config", controller.GetConfig)
|
||||
route.Post("config", controller.SaveConfig)
|
||||
route.Get("userConfig", controller.GetUserConfig)
|
||||
route.Post("userConfig", controller.SaveUserConfig)
|
||||
route.Get("log", controller.Log)
|
||||
route.Post("clearLog", controller.ClearLog)
|
||||
route.Get("databases", controller.DatabaseList)
|
||||
route.Post("databases", controller.AddDatabase)
|
||||
route.Delete("databases", controller.DeleteDatabase)
|
||||
route.Get("backups", controller.BackupList)
|
||||
route.Post("backups", controller.CreateBackup)
|
||||
route.Put("backups", controller.UploadBackup)
|
||||
route.Delete("backups", controller.DeleteBackup)
|
||||
route.Post("backups/restore", controller.RestoreBackup)
|
||||
route.Get("roles", controller.RoleList)
|
||||
route.Post("roles", controller.AddRole)
|
||||
route.Delete("roles", controller.DeleteRole)
|
||||
route.Post("roles/password", controller.SetRolePassword)
|
||||
})
|
||||
r.Prefix("mysql84").Group(func(route route.Router) {
|
||||
mySQLController := plugins.NewMySQLController()
|
||||
route.Get("status", mySQLController.Status)
|
||||
route.Post("reload", mySQLController.Reload)
|
||||
route.Post("start", mySQLController.Start)
|
||||
route.Post("stop", mySQLController.Stop)
|
||||
route.Post("restart", mySQLController.Restart)
|
||||
route.Get("load", mySQLController.Load)
|
||||
route.Get("config", mySQLController.GetConfig)
|
||||
route.Post("config", mySQLController.SaveConfig)
|
||||
route.Get("errorLog", mySQLController.ErrorLog)
|
||||
route.Post("clearErrorLog", mySQLController.ClearErrorLog)
|
||||
route.Get("slowLog", mySQLController.SlowLog)
|
||||
route.Post("clearSlowLog", mySQLController.ClearSlowLog)
|
||||
route.Get("rootPassword", mySQLController.GetRootPassword)
|
||||
route.Post("rootPassword", mySQLController.SetRootPassword)
|
||||
route.Get("databases", mySQLController.DatabaseList)
|
||||
route.Post("databases", mySQLController.AddDatabase)
|
||||
route.Delete("databases", mySQLController.DeleteDatabase)
|
||||
route.Get("backups", mySQLController.BackupList)
|
||||
route.Post("backups", mySQLController.CreateBackup)
|
||||
route.Put("backups", mySQLController.UploadBackup)
|
||||
route.Delete("backups", mySQLController.DeleteBackup)
|
||||
route.Post("backups/restore", mySQLController.RestoreBackup)
|
||||
route.Get("users", mySQLController.UserList)
|
||||
route.Post("users", mySQLController.AddUser)
|
||||
route.Delete("users", mySQLController.DeleteUser)
|
||||
route.Post("users/password", mySQLController.SetUserPassword)
|
||||
route.Post("users/privileges", mySQLController.SetUserPrivileges)
|
||||
})
|
||||
r.Prefix("postgresql15").Group(func(route route.Router) {
|
||||
postgresql15Controller := plugins.NewPostgresql15Controller()
|
||||
route.Get("status", postgresql15Controller.Status)
|
||||
route.Post("reload", postgresql15Controller.Reload)
|
||||
route.Post("start", postgresql15Controller.Start)
|
||||
route.Post("stop", postgresql15Controller.Stop)
|
||||
route.Post("restart", postgresql15Controller.Restart)
|
||||
route.Get("load", postgresql15Controller.Load)
|
||||
route.Get("config", postgresql15Controller.GetConfig)
|
||||
route.Post("config", postgresql15Controller.SaveConfig)
|
||||
route.Get("userConfig", postgresql15Controller.GetUserConfig)
|
||||
route.Post("userConfig", postgresql15Controller.SaveUserConfig)
|
||||
route.Get("log", postgresql15Controller.Log)
|
||||
route.Post("clearLog", postgresql15Controller.ClearLog)
|
||||
route.Get("databases", postgresql15Controller.DatabaseList)
|
||||
route.Post("databases", postgresql15Controller.AddDatabase)
|
||||
route.Delete("databases", postgresql15Controller.DeleteDatabase)
|
||||
route.Get("backups", postgresql15Controller.BackupList)
|
||||
route.Post("backups", postgresql15Controller.CreateBackup)
|
||||
route.Put("backups", postgresql15Controller.UploadBackup)
|
||||
route.Delete("backups", postgresql15Controller.DeleteBackup)
|
||||
route.Post("backups/restore", postgresql15Controller.RestoreBackup)
|
||||
route.Get("users", postgresql15Controller.UserList)
|
||||
route.Post("users", postgresql15Controller.AddUser)
|
||||
route.Delete("users", postgresql15Controller.DeleteUser)
|
||||
route.Post("users/password", postgresql15Controller.SetUserPassword)
|
||||
})
|
||||
r.Prefix("postgresql16").Group(func(route route.Router) {
|
||||
postgresql16Controller := plugins.NewPostgresql16Controller()
|
||||
route.Get("status", postgresql16Controller.Status)
|
||||
route.Post("reload", postgresql16Controller.Reload)
|
||||
route.Post("start", postgresql16Controller.Start)
|
||||
route.Post("stop", postgresql16Controller.Stop)
|
||||
route.Post("restart", postgresql16Controller.Restart)
|
||||
route.Get("load", postgresql16Controller.Load)
|
||||
route.Get("config", postgresql16Controller.GetConfig)
|
||||
route.Post("config", postgresql16Controller.SaveConfig)
|
||||
route.Get("userConfig", postgresql16Controller.GetUserConfig)
|
||||
route.Post("userConfig", postgresql16Controller.SaveUserConfig)
|
||||
route.Get("log", postgresql16Controller.Log)
|
||||
route.Post("clearLog", postgresql16Controller.ClearLog)
|
||||
route.Get("databases", postgresql16Controller.DatabaseList)
|
||||
route.Post("databases", postgresql16Controller.AddDatabase)
|
||||
route.Delete("databases", postgresql16Controller.DeleteDatabase)
|
||||
route.Get("backups", postgresql16Controller.BackupList)
|
||||
route.Post("backups", postgresql16Controller.CreateBackup)
|
||||
route.Put("backups", postgresql16Controller.UploadBackup)
|
||||
route.Delete("backups", postgresql16Controller.DeleteBackup)
|
||||
route.Post("backups/restore", postgresql16Controller.RestoreBackup)
|
||||
route.Get("users", postgresql16Controller.UserList)
|
||||
route.Post("users", postgresql16Controller.AddUser)
|
||||
route.Delete("users", postgresql16Controller.DeleteUser)
|
||||
route.Post("users/password", postgresql16Controller.SetUserPassword)
|
||||
})
|
||||
r.Prefix("php74").Group(func(route route.Router) {
|
||||
php74Controller := plugins.NewPHPController(74)
|
||||
route.Get("status", php74Controller.Status)
|
||||
route.Post("reload", php74Controller.Reload)
|
||||
route.Post("start", php74Controller.Start)
|
||||
route.Post("stop", php74Controller.Stop)
|
||||
route.Post("restart", php74Controller.Restart)
|
||||
route.Get("load", php74Controller.Load)
|
||||
route.Get("config", php74Controller.GetConfig)
|
||||
route.Post("config", php74Controller.SaveConfig)
|
||||
route.Get("fpmConfig", php74Controller.GetFPMConfig)
|
||||
route.Post("fpmConfig", php74Controller.SaveFPMConfig)
|
||||
route.Get("errorLog", php74Controller.ErrorLog)
|
||||
route.Get("slowLog", php74Controller.SlowLog)
|
||||
route.Post("clearErrorLog", php74Controller.ClearErrorLog)
|
||||
route.Post("clearSlowLog", php74Controller.ClearSlowLog)
|
||||
route.Get("extensions", php74Controller.GetExtensionList)
|
||||
route.Post("extensions", php74Controller.InstallExtension)
|
||||
route.Delete("extensions", php74Controller.UninstallExtension)
|
||||
})
|
||||
r.Prefix("php80").Group(func(route route.Router) {
|
||||
php80Controller := plugins.NewPHPController(80)
|
||||
route.Get("status", php80Controller.Status)
|
||||
route.Post("reload", php80Controller.Reload)
|
||||
route.Post("start", php80Controller.Start)
|
||||
route.Post("stop", php80Controller.Stop)
|
||||
route.Post("restart", php80Controller.Restart)
|
||||
route.Get("load", php80Controller.Load)
|
||||
route.Get("config", php80Controller.GetConfig)
|
||||
route.Post("config", php80Controller.SaveConfig)
|
||||
route.Get("fpmConfig", php80Controller.GetFPMConfig)
|
||||
route.Post("fpmConfig", php80Controller.SaveFPMConfig)
|
||||
route.Get("errorLog", php80Controller.ErrorLog)
|
||||
route.Get("slowLog", php80Controller.SlowLog)
|
||||
route.Post("clearErrorLog", php80Controller.ClearErrorLog)
|
||||
route.Post("clearSlowLog", php80Controller.ClearSlowLog)
|
||||
route.Get("extensions", php80Controller.GetExtensionList)
|
||||
route.Post("extensions", php80Controller.InstallExtension)
|
||||
route.Delete("extensions", php80Controller.UninstallExtension)
|
||||
})
|
||||
r.Prefix("php81").Group(func(route route.Router) {
|
||||
php81Controller := plugins.NewPHPController(81)
|
||||
route.Get("status", php81Controller.Status)
|
||||
route.Post("reload", php81Controller.Reload)
|
||||
route.Post("start", php81Controller.Start)
|
||||
route.Post("stop", php81Controller.Stop)
|
||||
route.Post("restart", php81Controller.Restart)
|
||||
route.Get("load", php81Controller.Load)
|
||||
route.Get("config", php81Controller.GetConfig)
|
||||
route.Post("config", php81Controller.SaveConfig)
|
||||
route.Get("fpmConfig", php81Controller.GetFPMConfig)
|
||||
route.Post("fpmConfig", php81Controller.SaveFPMConfig)
|
||||
route.Get("errorLog", php81Controller.ErrorLog)
|
||||
route.Get("slowLog", php81Controller.SlowLog)
|
||||
route.Post("clearErrorLog", php81Controller.ClearErrorLog)
|
||||
route.Post("clearSlowLog", php81Controller.ClearSlowLog)
|
||||
route.Get("extensions", php81Controller.GetExtensionList)
|
||||
route.Post("extensions", php81Controller.InstallExtension)
|
||||
route.Delete("extensions", php81Controller.UninstallExtension)
|
||||
})
|
||||
r.Prefix("php82").Group(func(route route.Router) {
|
||||
php82Controller := plugins.NewPHPController(82)
|
||||
route.Get("status", php82Controller.Status)
|
||||
route.Post("reload", php82Controller.Reload)
|
||||
route.Post("start", php82Controller.Start)
|
||||
route.Post("stop", php82Controller.Stop)
|
||||
route.Post("restart", php82Controller.Restart)
|
||||
route.Get("load", php82Controller.Load)
|
||||
route.Get("config", php82Controller.GetConfig)
|
||||
route.Post("config", php82Controller.SaveConfig)
|
||||
route.Get("fpmConfig", php82Controller.GetFPMConfig)
|
||||
route.Post("fpmConfig", php82Controller.SaveFPMConfig)
|
||||
route.Get("errorLog", php82Controller.ErrorLog)
|
||||
route.Get("slowLog", php82Controller.SlowLog)
|
||||
route.Post("clearErrorLog", php82Controller.ClearErrorLog)
|
||||
route.Post("clearSlowLog", php82Controller.ClearSlowLog)
|
||||
route.Get("extensions", php82Controller.GetExtensionList)
|
||||
route.Post("extensions", php82Controller.InstallExtension)
|
||||
route.Delete("extensions", php82Controller.UninstallExtension)
|
||||
})
|
||||
r.Prefix("php83").Group(func(route route.Router) {
|
||||
php83Controller := plugins.NewPHPController(83)
|
||||
route.Get("status", php83Controller.Status)
|
||||
route.Post("reload", php83Controller.Reload)
|
||||
route.Post("start", php83Controller.Start)
|
||||
route.Post("stop", php83Controller.Stop)
|
||||
route.Post("restart", php83Controller.Restart)
|
||||
route.Get("load", php83Controller.Load)
|
||||
route.Get("config", php83Controller.GetConfig)
|
||||
route.Post("config", php83Controller.SaveConfig)
|
||||
route.Get("fpmConfig", php83Controller.GetFPMConfig)
|
||||
route.Post("fpmConfig", php83Controller.SaveFPMConfig)
|
||||
route.Get("errorLog", php83Controller.ErrorLog)
|
||||
route.Get("slowLog", php83Controller.SlowLog)
|
||||
route.Post("clearErrorLog", php83Controller.ClearErrorLog)
|
||||
route.Post("clearSlowLog", php83Controller.ClearSlowLog)
|
||||
route.Get("extensions", php83Controller.GetExtensionList)
|
||||
route.Post("extensions", php83Controller.InstallExtension)
|
||||
route.Delete("extensions", php83Controller.UninstallExtension)
|
||||
r.Prefix("php").Group(func(route route.Router) {
|
||||
phpController := plugins.NewPHPController()
|
||||
route.Get("{version}/load", phpController.Load)
|
||||
route.Get("{version}/config", phpController.GetConfig)
|
||||
route.Post("{version}/config", phpController.SaveConfig)
|
||||
route.Get("{version}/fpmConfig", phpController.GetFPMConfig)
|
||||
route.Post("{version}/fpmConfig", phpController.SaveFPMConfig)
|
||||
route.Get("{version}/errorLog", phpController.ErrorLog)
|
||||
route.Get("{version}/slowLog", phpController.SlowLog)
|
||||
route.Post("{version}/clearErrorLog", phpController.ClearErrorLog)
|
||||
route.Post("{version}/clearSlowLog", phpController.ClearSlowLog)
|
||||
route.Get("{version}/extensions", phpController.ExtensionList)
|
||||
route.Post("{version}/extensions", phpController.InstallExtension)
|
||||
route.Delete("{version}/extensions", phpController.UninstallExtension)
|
||||
})
|
||||
r.Prefix("phpmyadmin").Group(func(route route.Router) {
|
||||
phpMyAdminController := plugins.NewPhpMyAdminController()
|
||||
@@ -275,10 +88,6 @@ func Plugin() {
|
||||
})
|
||||
r.Prefix("pureftpd").Group(func(route route.Router) {
|
||||
pureFtpdController := plugins.NewPureFtpdController()
|
||||
route.Get("status", pureFtpdController.Status)
|
||||
route.Post("start", pureFtpdController.Start)
|
||||
route.Post("stop", pureFtpdController.Stop)
|
||||
route.Post("restart", pureFtpdController.Restart)
|
||||
route.Get("list", pureFtpdController.List)
|
||||
route.Post("add", pureFtpdController.Add)
|
||||
route.Delete("delete", pureFtpdController.Delete)
|
||||
@@ -288,10 +97,6 @@ func Plugin() {
|
||||
})
|
||||
r.Prefix("redis").Group(func(route route.Router) {
|
||||
redisController := plugins.NewRedisController()
|
||||
route.Get("status", redisController.Status)
|
||||
route.Post("start", redisController.Start)
|
||||
route.Post("stop", redisController.Stop)
|
||||
route.Post("restart", redisController.Restart)
|
||||
route.Get("load", redisController.Load)
|
||||
route.Get("config", redisController.GetConfig)
|
||||
route.Post("config", redisController.SaveConfig)
|
||||
@@ -304,11 +109,7 @@ func Plugin() {
|
||||
})
|
||||
r.Prefix("supervisor").Group(func(route route.Router) {
|
||||
supervisorController := plugins.NewSupervisorController()
|
||||
route.Get("status", supervisorController.Status)
|
||||
route.Post("start", supervisorController.Start)
|
||||
route.Post("stop", supervisorController.Stop)
|
||||
route.Post("restart", supervisorController.Restart)
|
||||
route.Post("reload", supervisorController.Reload)
|
||||
route.Get("service", supervisorController.Service)
|
||||
route.Get("log", supervisorController.Log)
|
||||
route.Post("clearLog", supervisorController.ClearLog)
|
||||
route.Get("config", supervisorController.Config)
|
||||
@@ -327,11 +128,6 @@ func Plugin() {
|
||||
})
|
||||
r.Prefix("fail2ban").Group(func(route route.Router) {
|
||||
fail2banController := plugins.NewFail2banController()
|
||||
route.Get("status", fail2banController.Status)
|
||||
route.Post("start", fail2banController.Start)
|
||||
route.Post("stop", fail2banController.Stop)
|
||||
route.Post("restart", fail2banController.Restart)
|
||||
route.Post("reload", fail2banController.Reload)
|
||||
route.Get("jails", fail2banController.List)
|
||||
route.Post("jails", fail2banController.Add)
|
||||
route.Delete("jails", fail2banController.Delete)
|
||||
@@ -342,13 +138,6 @@ func Plugin() {
|
||||
})
|
||||
r.Prefix("podman").Group(func(route route.Router) {
|
||||
controller := plugins.NewPodmanController()
|
||||
route.Get("status", controller.Status)
|
||||
route.Get("isEnabled", controller.IsEnabled)
|
||||
route.Post("enable", controller.Enable)
|
||||
route.Post("disable", controller.Disable)
|
||||
route.Post("start", controller.Start)
|
||||
route.Post("stop", controller.Stop)
|
||||
route.Post("restart", controller.Restart)
|
||||
route.Get("registryConfig", controller.GetRegistryConfig)
|
||||
route.Post("registryConfig", controller.UpdateRegistryConfig)
|
||||
route.Get("storageConfig", controller.GetStorageConfig)
|
||||
@@ -356,10 +145,6 @@ func Plugin() {
|
||||
})
|
||||
r.Prefix("rsync").Group(func(route route.Router) {
|
||||
rsyncController := plugins.NewRsyncController()
|
||||
route.Get("status", rsyncController.Status)
|
||||
route.Post("start", rsyncController.Start)
|
||||
route.Post("stop", rsyncController.Stop)
|
||||
route.Post("restart", rsyncController.Restart)
|
||||
route.Get("modules", rsyncController.List)
|
||||
route.Post("modules", rsyncController.Create)
|
||||
route.Post("modules/{name}", rsyncController.Update)
|
||||
@@ -369,25 +154,11 @@ func Plugin() {
|
||||
})
|
||||
r.Prefix("frp").Group(func(route route.Router) {
|
||||
frpController := plugins.NewFrpController()
|
||||
route.Get("status", frpController.Status)
|
||||
route.Get("isEnabled", frpController.IsEnabled)
|
||||
route.Post("enable", frpController.Enable)
|
||||
route.Post("disable", frpController.Disable)
|
||||
route.Post("start", frpController.Start)
|
||||
route.Post("stop", frpController.Stop)
|
||||
route.Post("restart", frpController.Restart)
|
||||
route.Get("config", frpController.GetConfig)
|
||||
route.Post("config", frpController.UpdateConfig)
|
||||
})
|
||||
r.Prefix("gitea").Group(func(route route.Router) {
|
||||
giteaController := plugins.NewGiteaController()
|
||||
route.Get("status", giteaController.Status)
|
||||
route.Get("isEnabled", giteaController.IsEnabled)
|
||||
route.Post("enable", giteaController.Enable)
|
||||
route.Post("disable", giteaController.Disable)
|
||||
route.Post("start", giteaController.Start)
|
||||
route.Post("stop", giteaController.Stop)
|
||||
route.Post("restart", giteaController.Restart)
|
||||
route.Get("config", giteaController.GetConfig)
|
||||
route.Post("config", giteaController.UpdateConfig)
|
||||
})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user