mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 11:27:17 +08:00
chore: update framework
This commit is contained in:
@@ -25,7 +25,8 @@ func NewCronController() *CronController {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CronController) List(ctx http.Context) {
|
||||
// List 获取计划任务列表
|
||||
func (c *CronController) List(ctx http.Context) http.Response {
|
||||
limit := ctx.Request().QueryInt("limit")
|
||||
page := ctx.Request().QueryInt("page")
|
||||
|
||||
@@ -34,17 +35,17 @@ func (c *CronController) List(ctx http.Context) {
|
||||
err := facades.Orm().Query().Paginate(page, limit, &crons, &total)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 查询计划任务列表失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": total,
|
||||
"items": crons,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *CronController) Add(ctx http.Context) {
|
||||
// Add 添加计划任务
|
||||
func (c *CronController) Add(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required",
|
||||
@@ -53,18 +54,15 @@ func (c *CronController) Add(ctx http.Context) {
|
||||
"backup_type": "required_if:type,backup|in:website,mysql,postgresql",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
// 单独验证时间格式
|
||||
if !regexp.MustCompile(`^((\*|\d+|\d+-\d+|\d+/\d+|\d+-\d+/\d+|\*/\d+)(,(\*|\d+|\d+-\d+|\d+/\d+|\d+-\d+/\d+|\*/\d+))*\s?){5}$`).MatchString(ctx.Request().Input("time")) {
|
||||
Error(ctx, http.StatusBadRequest, "时间格式错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "时间格式错误")
|
||||
}
|
||||
|
||||
shell := ctx.Request().Input("script")
|
||||
@@ -114,19 +112,16 @@ panel cutoff ${name} ${save} 2>&1
|
||||
shellLogDir := "/www/server/cron/logs/"
|
||||
if !tools.Exists(shellDir) {
|
||||
facades.Log().Error("[面板][CronController] 计划任务目录不存在")
|
||||
Error(ctx, http.StatusInternalServerError, "计划任务目录不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "计划任务目录不存在")
|
||||
}
|
||||
if !tools.Exists(shellLogDir) {
|
||||
facades.Log().Error("[面板][CronController] 计划任务日志目录不存在")
|
||||
Error(ctx, http.StatusInternalServerError, "计划任务日志目录不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "计划任务日志目录不存在")
|
||||
}
|
||||
shellFile := strconv.Itoa(int(carbon.Now().Timestamp())) + tools.RandomString(16)
|
||||
if !tools.Write(shellDir+shellFile+".sh", shell, 0700) {
|
||||
facades.Log().Error("[面板][CronController] 创建计划任务脚本失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
tools.Exec("dos2unix " + shellDir + shellFile + ".sh")
|
||||
|
||||
@@ -141,60 +136,54 @@ panel cutoff ${name} ${save} 2>&1
|
||||
err = facades.Orm().Query().Create(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 创建计划任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.cron.AddToSystem(cron)
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"id": cron.ID,
|
||||
})
|
||||
}
|
||||
|
||||
// Script 获取脚本内容
|
||||
func (c *CronController) Script(ctx http.Context) {
|
||||
func (c *CronController) Script(ctx http.Context) http.Response {
|
||||
var cron models.Cron
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
}
|
||||
|
||||
Success(ctx, tools.Read(cron.Shell))
|
||||
return Success(ctx, tools.Read(cron.Shell))
|
||||
}
|
||||
|
||||
func (c *CronController) Update(ctx http.Context) {
|
||||
// Update 更新计划任务
|
||||
func (c *CronController) Update(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required",
|
||||
"script": "required",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
// 单独验证时间格式
|
||||
if !regexp.MustCompile(`^((\*|\d+|\d+-\d+|\d+/\d+|\d+-\d+/\d+|\*/\d+)(,(\*|\d+|\d+-\d+|\d+/\d+|\d+-\d+/\d+|\*/\d+))*\s?){5}$`).MatchString(ctx.Request().Input("time")) {
|
||||
Error(ctx, http.StatusBadRequest, "时间格式错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "时间格式错误")
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
}
|
||||
|
||||
if !cron.Status {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务已禁用")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "计划任务已禁用")
|
||||
}
|
||||
|
||||
cron.Time = ctx.Request().Input("time")
|
||||
@@ -202,14 +191,12 @@ func (c *CronController) Update(ctx http.Context) {
|
||||
err = facades.Orm().Query().Save(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 更新计划任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if !tools.Write(cron.Shell, ctx.Request().Input("script"), 0644) {
|
||||
facades.Log().Error("[面板][CronController] 更新计划任务脚本失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
tools.Exec("dos2unix " + cron.Shell)
|
||||
|
||||
@@ -218,15 +205,15 @@ func (c *CronController) Update(ctx http.Context) {
|
||||
c.cron.AddToSystem(cron)
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (c *CronController) Delete(ctx http.Context) {
|
||||
// Delete 删除计划任务
|
||||
func (c *CronController) Delete(ctx http.Context) http.Response {
|
||||
var cron models.Cron
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
}
|
||||
|
||||
c.cron.DeleteFromSystem(cron)
|
||||
@@ -235,39 +222,35 @@ func (c *CronController) Delete(ctx http.Context) {
|
||||
_, err = facades.Orm().Query().Delete(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 删除计划任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (c *CronController) Status(ctx http.Context) {
|
||||
// Status 更新计划任务状态
|
||||
func (c *CronController) Status(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"status": "bool",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
}
|
||||
|
||||
cron.Status = ctx.Request().InputBool("status")
|
||||
err = facades.Orm().Query().Save(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 更新计划任务状态失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.cron.DeleteFromSystem(cron)
|
||||
@@ -275,21 +258,20 @@ func (c *CronController) Status(ctx http.Context) {
|
||||
c.cron.AddToSystem(cron)
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (c *CronController) Log(ctx http.Context) {
|
||||
// Log 获取计划任务日志
|
||||
func (c *CronController) Log(ctx http.Context) http.Response {
|
||||
var cron models.Cron
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
}
|
||||
|
||||
if !tools.Exists(cron.Log) {
|
||||
Error(ctx, http.StatusBadRequest, "日志文件不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "日志文件不存在")
|
||||
}
|
||||
|
||||
Success(ctx, tools.Read(cron.Log))
|
||||
return Success(ctx, tools.Read(cron.Log))
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
)
|
||||
|
||||
type FileController struct {
|
||||
// Dependent services
|
||||
}
|
||||
@@ -13,6 +9,3 @@ func NewFileController() *FileController {
|
||||
// Inject services
|
||||
}
|
||||
}
|
||||
|
||||
func (r *FileController) Index(ctx http.Context) {
|
||||
}
|
||||
|
||||
@@ -9,16 +9,16 @@ import (
|
||||
"panel/app/services"
|
||||
)
|
||||
|
||||
func Success(ctx http.Context, data any) {
|
||||
ctx.Response().Success().Json(http.Json{
|
||||
func Success(ctx http.Context, data any) http.Response {
|
||||
return ctx.Response().Success().Json(http.Json{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": data,
|
||||
})
|
||||
}
|
||||
|
||||
func Error(ctx http.Context, code int, message any) {
|
||||
ctx.Response().Json(http.StatusOK, http.Json{
|
||||
func Error(ctx http.Context, code int, message any) http.Response {
|
||||
return ctx.Response().Json(http.StatusOK, http.Json{
|
||||
"code": code,
|
||||
"message": message,
|
||||
})
|
||||
|
||||
@@ -30,22 +30,23 @@ func NewInfoController() *InfoController {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *InfoController) Name(ctx http.Context) {
|
||||
// Name 获取面板名称
|
||||
func (c *InfoController) Name(ctx http.Context) http.Response {
|
||||
var setting models.Setting
|
||||
err := facades.Orm().Query().Where("key", "name").First(&setting)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][InfoController] 查询面板名称失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"name": setting.Value,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *InfoController) Menu(ctx http.Context) {
|
||||
Success(ctx, []MenuItem{
|
||||
// Menu 获取面板菜单
|
||||
func (c *InfoController) Menu(ctx http.Context) http.Response {
|
||||
return Success(ctx, []MenuItem{
|
||||
{Name: "home", Title: "主页", Icon: "layui-icon-home", Jump: "/"},
|
||||
{Name: "website", Title: "网站管理", Icon: "layui-icon-website", Jump: "website/list"},
|
||||
{Name: "monitor", Title: "资源监控", Icon: "layui-icon-chart-screen", Jump: "monitor"},
|
||||
@@ -58,13 +59,13 @@ func (c *InfoController) Menu(ctx http.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *InfoController) HomePlugins(ctx http.Context) {
|
||||
// HomePlugins 获取首页插件
|
||||
func (c *InfoController) HomePlugins(ctx http.Context) http.Response {
|
||||
var plugins []models.Plugin
|
||||
err := facades.Orm().Query().Where("show", 1).Find(&plugins)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][InfoController] 查询首页插件失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
type pluginsData struct {
|
||||
@@ -80,29 +81,31 @@ func (c *InfoController) HomePlugins(ctx http.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
Success(ctx, pluginsJson)
|
||||
return Success(ctx, pluginsJson)
|
||||
}
|
||||
|
||||
func (c *InfoController) NowMonitor(ctx http.Context) {
|
||||
Success(ctx, tools.GetMonitoringInfo())
|
||||
// NowMonitor 获取当前监控信息
|
||||
func (c *InfoController) NowMonitor(ctx http.Context) http.Response {
|
||||
return Success(ctx, tools.GetMonitoringInfo())
|
||||
}
|
||||
|
||||
func (c *InfoController) SystemInfo(ctx http.Context) {
|
||||
// SystemInfo 获取系统信息
|
||||
func (c *InfoController) SystemInfo(ctx http.Context) http.Response {
|
||||
monitorInfo := tools.GetMonitoringInfo()
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"os_name": monitorInfo.Host.Platform + " " + monitorInfo.Host.PlatformVersion,
|
||||
"uptime": fmt.Sprintf("%.2f", float64(monitorInfo.Host.Uptime)/86400),
|
||||
"panel_version": facades.Config().GetString("panel.version"),
|
||||
})
|
||||
}
|
||||
|
||||
func (c *InfoController) InstalledDbAndPhp(ctx http.Context) {
|
||||
// InstalledDbAndPhp 获取已安装的数据库和 PHP 版本
|
||||
func (c *InfoController) InstalledDbAndPhp(ctx http.Context) http.Response {
|
||||
var php []models.Plugin
|
||||
err := facades.Orm().Query().Where("slug like ?", "php%").Find(&php)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
var mysql models.Plugin
|
||||
@@ -134,33 +137,32 @@ func (c *InfoController) InstalledDbAndPhp(ctx http.Context) {
|
||||
phpData = append(phpData, data{Slug: strings.ReplaceAll(p.Slug, "php", ""), Name: c.plugin.GetBySlug(p.Slug).Name})
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"php": phpData,
|
||||
"mysql": mysqlInstalled,
|
||||
"postgresql": postgresqlInstalled,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *InfoController) CheckUpdate(ctx http.Context) {
|
||||
// CheckUpdate 检查面板更新
|
||||
func (c *InfoController) CheckUpdate(ctx http.Context) http.Response {
|
||||
version := facades.Config().GetString("panel.version")
|
||||
remote, err := tools.GetLatestPanelVersion()
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusInternalServerError, "获取最新版本失败")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "获取最新版本失败")
|
||||
}
|
||||
|
||||
if version == remote.Version {
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"update": false,
|
||||
"version": remote.Version,
|
||||
"name": remote.Name,
|
||||
"body": remote.Body,
|
||||
"date": remote.Date,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"update": true,
|
||||
"version": remote.Version,
|
||||
"name": remote.Name,
|
||||
@@ -169,33 +171,32 @@ func (c *InfoController) CheckUpdate(ctx http.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *InfoController) Update(ctx http.Context) {
|
||||
// Update 更新面板
|
||||
func (c *InfoController) Update(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).FirstOrFail(&task)
|
||||
if err == nil {
|
||||
Error(ctx, http.StatusInternalServerError, "当前有任务正在执行,禁止更新")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "当前有任务正在执行,禁止更新")
|
||||
}
|
||||
|
||||
proxy := ctx.Request().InputBool("proxy")
|
||||
err = tools.UpdatePanel(proxy)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][InfoController] 更新面板失败 ", err.Error())
|
||||
Error(ctx, http.StatusInternalServerError, "更新失败: "+err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "更新失败: "+err.Error())
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (c *InfoController) Restart(ctx http.Context) {
|
||||
// Restart 重启面板
|
||||
func (c *InfoController) Restart(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).FirstOrFail(&task)
|
||||
if err == nil {
|
||||
Error(ctx, http.StatusInternalServerError, "当前有任务正在执行,禁止重启")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "当前有任务正在执行,禁止重启")
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart panel")
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -22,56 +22,53 @@ func NewMonitorController() *MonitorController {
|
||||
}
|
||||
|
||||
// Switch 监控开关
|
||||
func (r *MonitorController) Switch(ctx http.Context) {
|
||||
func (r *MonitorController) Switch(ctx http.Context) http.Response {
|
||||
value := ctx.Request().InputBool("switch")
|
||||
err := r.setting.Set(models.SettingKeyMonitor, cast.ToString(value))
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][MonitorController] 更新监控开关失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SaveDays 保存监控天数
|
||||
func (r *MonitorController) SaveDays(ctx http.Context) {
|
||||
func (r *MonitorController) SaveDays(ctx http.Context) http.Response {
|
||||
days := ctx.Request().Input("days")
|
||||
err := r.setting.Set(models.SettingKeyMonitorDays, days)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][MonitorController] 更新监控天数失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SwitchAndDays 监控开关和监控天数
|
||||
func (r *MonitorController) SwitchAndDays(ctx http.Context) {
|
||||
func (r *MonitorController) SwitchAndDays(ctx http.Context) http.Response {
|
||||
monitor := r.setting.Get(models.SettingKeyMonitor)
|
||||
monitorDays := r.setting.Get(models.SettingKeyMonitorDays)
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"switch": cast.ToBool(monitor),
|
||||
"days": cast.ToInt(monitorDays),
|
||||
})
|
||||
}
|
||||
|
||||
// Clear 清空监控数据
|
||||
func (r *MonitorController) Clear(ctx http.Context) {
|
||||
func (r *MonitorController) Clear(ctx http.Context) http.Response {
|
||||
_, err := facades.Orm().Query().Where("1 = 1").Delete(&models.Monitor{})
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][MonitorController] 清空监控数据失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// List 监控数据列表
|
||||
func (r *MonitorController) List(ctx http.Context) {
|
||||
func (r *MonitorController) List(ctx http.Context) http.Response {
|
||||
start := ctx.Request().InputInt64("start")
|
||||
end := ctx.Request().InputInt64("end")
|
||||
startTime := carbon.FromTimestampMilli(start)
|
||||
@@ -81,13 +78,11 @@ func (r *MonitorController) List(ctx http.Context) {
|
||||
err := facades.Orm().Query().Where("created_at >= ?", startTime.ToDateTimeString()).Where("created_at <= ?", endTime.ToDateTimeString()).Get(&monitors)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][MonitorController] 查询监控数据失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if len(monitors) == 0 {
|
||||
Error(ctx, http.StatusNotFound, "监控数据为空")
|
||||
return
|
||||
return Error(ctx, http.StatusNotFound, "监控数据为空")
|
||||
}
|
||||
|
||||
type load struct {
|
||||
@@ -172,5 +167,5 @@ func (r *MonitorController) List(ctx http.Context) {
|
||||
bytesRecv2 = 0
|
||||
}
|
||||
|
||||
Success(ctx, data)
|
||||
return Success(ctx, data)
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ func NewPluginController() *PluginController {
|
||||
}
|
||||
|
||||
// List 列出所有插件
|
||||
func (r *PluginController) List(ctx http.Context) {
|
||||
func (r *PluginController) List(ctx http.Context) http.Response {
|
||||
plugins := r.plugin.All()
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
var lock sync.RWMutex
|
||||
@@ -72,24 +72,22 @@ func (r *PluginController) List(ctx http.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
Success(ctx, p)
|
||||
return Success(ctx, p)
|
||||
}
|
||||
|
||||
// Install 安装插件
|
||||
func (r *PluginController) Install(ctx http.Context) {
|
||||
func (r *PluginController) Install(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
plugin := r.plugin.GetBySlug(slug)
|
||||
installedPlugin := r.plugin.GetInstalledBySlug(slug)
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 获取已安装插件失败")
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if installedPlugin.ID != 0 {
|
||||
Error(ctx, http.StatusBadRequest, "插件已安装")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "插件已安装")
|
||||
}
|
||||
|
||||
var lock sync.RWMutex
|
||||
@@ -106,8 +104,7 @@ func (r *PluginController) Install(ctx http.Context) {
|
||||
_, requireFound := pluginsMap[require]
|
||||
lock.RUnlock()
|
||||
if !requireFound {
|
||||
Error(ctx, http.StatusForbidden, "插件 "+slug+" 需要依赖 "+require+" 插件")
|
||||
return
|
||||
return Error(ctx, http.StatusForbidden, "插件 "+slug+" 需要依赖 "+require+" 插件")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,8 +113,7 @@ func (r *PluginController) Install(ctx http.Context) {
|
||||
_, excludeFound := pluginsMap[exclude]
|
||||
lock.RUnlock()
|
||||
if excludeFound {
|
||||
Error(ctx, http.StatusForbidden, "插件 "+slug+" 不兼容 "+exclude+" 插件")
|
||||
return
|
||||
return Error(ctx, http.StatusForbidden, "插件 "+slug+" 不兼容 "+exclude+" 插件")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,29 +124,26 @@ func (r *PluginController) Install(ctx http.Context) {
|
||||
task.Log = "/tmp/" + plugin.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 创建任务失败: " + err.Error())
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
r.task.Process(task.ID)
|
||||
Success(ctx, "任务已提交")
|
||||
return Success(ctx, "任务已提交")
|
||||
}
|
||||
|
||||
// Uninstall 卸载插件
|
||||
func (r *PluginController) Uninstall(ctx http.Context) {
|
||||
func (r *PluginController) Uninstall(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
plugin := r.plugin.GetBySlug(slug)
|
||||
installedPlugin := r.plugin.GetInstalledBySlug(slug)
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 获取已安装插件失败")
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if installedPlugin.ID == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "插件未安装")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "插件未安装")
|
||||
}
|
||||
|
||||
var lock sync.RWMutex
|
||||
@@ -167,8 +160,7 @@ func (r *PluginController) Uninstall(ctx http.Context) {
|
||||
_, requireFound := pluginsMap[require]
|
||||
lock.RUnlock()
|
||||
if !requireFound {
|
||||
Error(ctx, http.StatusForbidden, "插件 "+slug+" 需要依赖 "+require+" 插件")
|
||||
return
|
||||
return Error(ctx, http.StatusForbidden, "插件 "+slug+" 需要依赖 "+require+" 插件")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,8 +169,7 @@ func (r *PluginController) Uninstall(ctx http.Context) {
|
||||
_, excludeFound := pluginsMap[exclude]
|
||||
lock.RUnlock()
|
||||
if excludeFound {
|
||||
Error(ctx, http.StatusForbidden, "插件 "+slug+" 不兼容 "+exclude+" 插件")
|
||||
return
|
||||
return Error(ctx, http.StatusForbidden, "插件 "+slug+" 不兼容 "+exclude+" 插件")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,29 +180,26 @@ func (r *PluginController) Uninstall(ctx http.Context) {
|
||||
task.Log = "/tmp/" + plugin.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 创建任务失败: " + err.Error())
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
r.task.Process(task.ID)
|
||||
Success(ctx, "任务已提交")
|
||||
return Success(ctx, "任务已提交")
|
||||
}
|
||||
|
||||
// Update 更新插件
|
||||
func (r *PluginController) Update(ctx http.Context) {
|
||||
func (r *PluginController) Update(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
plugin := r.plugin.GetBySlug(slug)
|
||||
installedPlugin := r.plugin.GetInstalledBySlug(slug)
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 获取已安装插件失败")
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if installedPlugin.ID == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "插件未安装")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "插件未安装")
|
||||
}
|
||||
|
||||
var lock sync.RWMutex
|
||||
@@ -228,8 +216,7 @@ func (r *PluginController) Update(ctx http.Context) {
|
||||
_, requireFound := pluginsMap[require]
|
||||
lock.RUnlock()
|
||||
if !requireFound {
|
||||
Error(ctx, http.StatusForbidden, "插件 "+slug+" 需要依赖 "+require+" 插件")
|
||||
return
|
||||
return Error(ctx, http.StatusForbidden, "插件 "+slug+" 需要依赖 "+require+" 插件")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,8 +225,7 @@ func (r *PluginController) Update(ctx http.Context) {
|
||||
_, excludeFound := pluginsMap[exclude]
|
||||
lock.RUnlock()
|
||||
if excludeFound {
|
||||
Error(ctx, http.StatusForbidden, "插件 "+slug+" 不兼容 "+exclude+" 插件")
|
||||
return
|
||||
return Error(ctx, http.StatusForbidden, "插件 "+slug+" 不兼容 "+exclude+" 插件")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,36 +236,32 @@ func (r *PluginController) Update(ctx http.Context) {
|
||||
task.Log = "/tmp/" + plugin.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 创建任务失败: " + err.Error())
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
r.task.Process(task.ID)
|
||||
Success(ctx, "任务已提交")
|
||||
return Success(ctx, "任务已提交")
|
||||
}
|
||||
|
||||
// UpdateShow 更新插件首页显示状态
|
||||
func (r *PluginController) UpdateShow(ctx http.Context) {
|
||||
func (r *PluginController) UpdateShow(ctx http.Context) http.Response {
|
||||
slug := ctx.Request().Input("slug")
|
||||
show := ctx.Request().InputBool("show")
|
||||
|
||||
var plugin models.Plugin
|
||||
if err := facades.Orm().Query().Where("slug", slug).First(&plugin); err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 查询插件失败: " + err.Error())
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
if plugin.ID == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "插件未安装")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "插件未安装")
|
||||
}
|
||||
|
||||
plugin.Show = show
|
||||
if err := facades.Orm().Query().Save(&plugin); err != nil {
|
||||
facades.Log().Error("[面板][PluginController] 更新插件失败: " + err.Error())
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, "操作成功")
|
||||
return Success(ctx, "操作成功")
|
||||
}
|
||||
|
||||
@@ -34,122 +34,115 @@ type Jail struct {
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (c *Fail2banController) Status(ctx http.Context) {
|
||||
func (c *Fail2banController) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (c *Fail2banController) Reload(ctx http.Context) {
|
||||
func (c *Fail2banController) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (c *Fail2banController) Restart(ctx http.Context) {
|
||||
func (c *Fail2banController) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (c *Fail2banController) Start(ctx http.Context) {
|
||||
func (c *Fail2banController) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (c *Fail2banController) Stop(ctx http.Context) {
|
||||
func (c *Fail2banController) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// List 所有 Fail2ban 规则
|
||||
func (c *Fail2banController) List(ctx http.Context) {
|
||||
func (c *Fail2banController) List(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
raw := tools.Read("/etc/fail2ban/jail.local")
|
||||
if len(raw) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "Fail2ban 规则为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "Fail2ban 规则为空")
|
||||
}
|
||||
|
||||
jailList := regexp.MustCompile(`\[(.*?)]`).FindAllStringSubmatch(raw, -1)
|
||||
if len(jailList) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "Fail2ban 规则为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "Fail2ban 规则为空")
|
||||
}
|
||||
|
||||
var jails []Jail
|
||||
@@ -182,27 +175,26 @@ func (c *Fail2banController) List(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(jails) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []Jail{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(jails) {
|
||||
endIndex = len(jails)
|
||||
}
|
||||
pagedJails := jails[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(jails),
|
||||
"items": pagedJails,
|
||||
})
|
||||
}
|
||||
|
||||
// Add 添加 Fail2ban 规则
|
||||
func (c *Fail2banController) Add(ctx http.Context) {
|
||||
func (c *Fail2banController) Add(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -215,12 +207,10 @@ func (c *Fail2banController) Add(ctx http.Context) {
|
||||
"website_path": "required_if:type,website",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
jailName := ctx.Request().Input("name")
|
||||
@@ -233,8 +223,7 @@ func (c *Fail2banController) Add(ctx http.Context) {
|
||||
|
||||
raw := tools.Read("/etc/fail2ban/jail.local")
|
||||
if strings.Contains(raw, "["+jailName+"]") || (strings.Contains(raw, "["+jailName+"]"+"-cc") && jailWebsiteMode == "cc") || (strings.Contains(raw, "["+jailName+"]"+"-path") && jailWebsiteMode == "path") {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "规则已存在")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "规则已存在")
|
||||
}
|
||||
|
||||
switch jailType {
|
||||
@@ -242,13 +231,11 @@ func (c *Fail2banController) Add(ctx http.Context) {
|
||||
var website models.Website
|
||||
err := facades.Orm().Query().Where("name", jailName).FirstOrFail(&website)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "网站不存在")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "网站不存在")
|
||||
}
|
||||
config, err := c.website.GetConfig(int(website.ID))
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "获取网站配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取网站配置失败")
|
||||
}
|
||||
var ports string
|
||||
for _, port := range config.Ports {
|
||||
@@ -313,12 +300,10 @@ ignoreregex =
|
||||
filter = "pure-ftpd"
|
||||
port = tools.Exec(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
default:
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "未知服务")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "未知服务")
|
||||
}
|
||||
if len(port) == 0 {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "获取服务端口失败,请检查是否安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取服务端口失败,请检查是否安装")
|
||||
}
|
||||
|
||||
rule := `
|
||||
@@ -339,20 +324,19 @@ logpath = ` + logPath + `
|
||||
}
|
||||
|
||||
tools.Exec("fail2ban-client reload")
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Delete 删除规则
|
||||
func (c *Fail2banController) Delete(ctx http.Context) {
|
||||
func (c *Fail2banController) Delete(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
jailName := ctx.Request().Input("name")
|
||||
raw := tools.Read("/etc/fail2ban/jail.local")
|
||||
if !strings.Contains(raw, "["+jailName+"]") {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "规则不存在")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "规则不存在")
|
||||
}
|
||||
|
||||
rule := tools.Cut(raw, "# "+jailName+"-START", "# "+jailName+"-END")
|
||||
@@ -361,19 +345,18 @@ func (c *Fail2banController) Delete(ctx http.Context) {
|
||||
tools.Write("/etc/fail2ban/jail.local", raw, 0644)
|
||||
|
||||
tools.Exec("fail2ban-client reload")
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// BanList 获取封禁列表
|
||||
func (c *Fail2banController) BanList(ctx http.Context) {
|
||||
func (c *Fail2banController) BanList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
name := ctx.Request().Query("name")
|
||||
if len(name) == 0 {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
}
|
||||
|
||||
currentlyBan := tools.Exec(`fail2ban-client status ` + name + ` | grep "Currently banned" | awk '{print $4}'`)
|
||||
@@ -391,7 +374,7 @@ func (c *Fail2banController) BanList(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"currentlyBan": currentlyBan,
|
||||
"totalBan": totalBan,
|
||||
"bannedIpList": list,
|
||||
@@ -399,32 +382,30 @@ func (c *Fail2banController) BanList(ctx http.Context) {
|
||||
}
|
||||
|
||||
// Unban 解封
|
||||
func (c *Fail2banController) Unban(ctx http.Context) {
|
||||
func (c *Fail2banController) Unban(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
name := ctx.Request().Input("name")
|
||||
ip := ctx.Request().Input("ip")
|
||||
if len(name) == 0 || len(ip) == 0 {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
}
|
||||
|
||||
tools.Exec("fail2ban-client set " + name + " unbanip " + ip)
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetWhiteList 设置白名单
|
||||
func (c *Fail2banController) SetWhiteList(ctx http.Context) {
|
||||
func (c *Fail2banController) SetWhiteList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
ip := ctx.Request().Input("ip")
|
||||
if len(ip) == 0 {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
}
|
||||
|
||||
raw := tools.Read("/etc/fail2ban/jail.local")
|
||||
@@ -433,27 +414,26 @@ func (c *Fail2banController) SetWhiteList(ctx http.Context) {
|
||||
if reg.MatchString(raw) {
|
||||
raw = reg.ReplaceAllString(raw, "ignoreip = "+ip+"\n")
|
||||
} else {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "解析Fail2ban规则失败,Fail2ban可能已损坏")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "解析Fail2ban规则失败,Fail2ban可能已损坏")
|
||||
}
|
||||
|
||||
tools.Write("/etc/fail2ban/jail.local", raw, 0644)
|
||||
tools.Exec("fail2ban-client reload")
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetWhiteList 获取白名单
|
||||
func (c *Fail2banController) GetWhiteList(ctx http.Context) {
|
||||
func (c *Fail2banController) GetWhiteList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "fail2ban") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
raw := tools.Read("/etc/fail2ban/jail.local")
|
||||
reg := regexp.MustCompile(`ignoreip\s*=\s*(.*)\n`)
|
||||
if reg.MatchString(raw) {
|
||||
ignoreIp := reg.FindStringSubmatch(raw)[1]
|
||||
controllers.Success(ctx, ignoreIp)
|
||||
return controllers.Success(ctx, ignoreIp)
|
||||
} else {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "解析Fail2ban规则失败,Fail2ban可能已损坏")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "解析Fail2ban规则失败,Fail2ban可能已损坏")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,166 +29,154 @@ func NewMysql57Controller() *Mysql57Controller {
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (c *Mysql57Controller) Status(ctx http.Context) {
|
||||
func (c *Mysql57Controller) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (c *Mysql57Controller) Reload(ctx http.Context) {
|
||||
func (c *Mysql57Controller) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (c *Mysql57Controller) Restart(ctx http.Context) {
|
||||
func (c *Mysql57Controller) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (c *Mysql57Controller) Start(ctx http.Context) {
|
||||
func (c *Mysql57Controller) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (c *Mysql57Controller) Stop(ctx http.Context) {
|
||||
func (c *Mysql57Controller) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (c *Mysql57Controller) GetConfig(ctx http.Context) {
|
||||
func (c *Mysql57Controller) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
config := tools.Read("/www/server/mysql/conf/my.cnf")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (c *Mysql57Controller) SaveConfig(ctx http.Context) {
|
||||
func (c *Mysql57Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
}
|
||||
|
||||
if !tools.Write("/www/server/mysql/conf/my.cnf", config, 0644) {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败")
|
||||
}
|
||||
|
||||
c.Restart(ctx)
|
||||
return c.Restart(ctx)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (c *Mysql57Controller) Load(ctx http.Context) {
|
||||
func (c *Mysql57Controller) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "MySQL 已停止运行")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 已停止运行")
|
||||
}
|
||||
|
||||
raw := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
if strings.Contains(raw, "Access denied for user") {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码错误")
|
||||
}
|
||||
if !strings.Contains(raw, "Uptime") {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL负载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL负载失败")
|
||||
}
|
||||
|
||||
data := make(map[int]map[string]string)
|
||||
@@ -238,84 +226,80 @@ func (c *Mysql57Controller) Load(ctx http.Context) {
|
||||
bufferPoolReadRequests := cast.ToFloat64(data[12]["value"])
|
||||
data[10]["value"] = fmt.Sprintf("%.2f%%", bufferPoolReadRequests/(bufferPoolReads+bufferPoolReadRequests)*100)
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
// ErrorLog 获取错误日志
|
||||
func (c *Mysql57Controller) ErrorLog(ctx http.Context) {
|
||||
func (c *Mysql57Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearErrorLog 清空错误日志
|
||||
func (c *Mysql57Controller) ClearErrorLog(ctx http.Context) {
|
||||
func (c *Mysql57Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-error.log")
|
||||
controllers.Success(ctx, "清空错误日志成功")
|
||||
return controllers.Success(ctx, "清空错误日志成功")
|
||||
}
|
||||
|
||||
// SlowLog 获取慢查询日志
|
||||
func (c *Mysql57Controller) SlowLog(ctx http.Context) {
|
||||
func (c *Mysql57Controller) SlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearSlowLog 清空慢查询日志
|
||||
func (c *Mysql57Controller) ClearSlowLog(ctx http.Context) {
|
||||
func (c *Mysql57Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-slow.log")
|
||||
controllers.Success(ctx, "清空慢查询日志成功")
|
||||
return controllers.Success(ctx, "清空慢查询日志成功")
|
||||
}
|
||||
|
||||
// GetRootPassword 获取root密码
|
||||
func (c *Mysql57Controller) GetRootPassword(ctx http.Context) {
|
||||
func (c *Mysql57Controller) GetRootPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, rootPassword)
|
||||
return controllers.Success(ctx, rootPassword)
|
||||
}
|
||||
|
||||
// SetRootPassword 设置root密码
|
||||
func (c *Mysql57Controller) SetRootPassword(ctx http.Context) {
|
||||
func (c *Mysql57Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
if status != "active" {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
}
|
||||
|
||||
rootPassword := ctx.Request().Input(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码不能为空")
|
||||
}
|
||||
|
||||
oldRootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -326,18 +310,17 @@ func (c *Mysql57Controller) SetRootPassword(ctx http.Context) {
|
||||
if err != nil {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "设置root密码成功")
|
||||
return controllers.Success(ctx, "设置root密码成功")
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
func (c *Mysql57Controller) DatabaseList(ctx http.Context) {
|
||||
func (c *Mysql57Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -348,16 +331,14 @@ func (c *Mysql57Controller) DatabaseList(ctx http.Context) {
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MySQL57] 连接数据库失败" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SHOW DATABASES")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MySQL57] 获取数据库列表失败" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -374,8 +355,7 @@ func (c *Mysql57Controller) DatabaseList(ctx http.Context) {
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
facades.Log().Error("[MySQL57] 获取数据库列表失败" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -383,27 +363,26 @@ func (c *Mysql57Controller) DatabaseList(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(databases) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(databases) {
|
||||
endIndex = len(databases)
|
||||
}
|
||||
pagedDatabases := databases[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(databases),
|
||||
"items": pagedDatabases,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (c *Mysql57Controller) AddDatabase(ctx http.Context) {
|
||||
func (c *Mysql57Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -412,12 +391,10 @@ func (c *Mysql57Controller) AddDatabase(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -430,60 +407,56 @@ func (c *Mysql57Controller) AddDatabase(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "添加数据库成功")
|
||||
return controllers.Success(ctx, "添加数据库成功")
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (c *Mysql57Controller) DeleteDatabase(ctx http.Context) {
|
||||
func (c *Mysql57Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\"")
|
||||
|
||||
controllers.Success(ctx, "删除数据库成功")
|
||||
return controllers.Success(ctx, "删除数据库成功")
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
func (c *Mysql57Controller) BackupList(ctx http.Context) {
|
||||
func (c *Mysql57Controller) BackupList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
backupList, err := c.backup.MysqlList()
|
||||
if err != nil {
|
||||
facades.Log().Error("[MySQL57] 获取备份列表失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, backupList)
|
||||
return controllers.Success(ctx, backupList)
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (c *Mysql57Controller) UploadBackup(ctx http.Context) {
|
||||
func (c *Mysql57Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/mysql"
|
||||
@@ -494,71 +467,65 @@ func (c *Mysql57Controller) UploadBackup(ctx http.Context) {
|
||||
name := file.GetClientOriginalName()
|
||||
_, err = file.StoreAs(backupPath, name)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "上传文件成功")
|
||||
return controllers.Success(ctx, "上传文件成功")
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (c *Mysql57Controller) CreateBackup(ctx http.Context) {
|
||||
func (c *Mysql57Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
err = c.backup.MysqlBackup(database)
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL57] 创建备份失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "备份成功")
|
||||
return controllers.Success(ctx, "备份成功")
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (c *Mysql57Controller) DeleteBackup(ctx http.Context) {
|
||||
func (c *Mysql57Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/mysql"
|
||||
fileName := ctx.Request().Input("name")
|
||||
tools.Remove(backupPath + "/" + fileName)
|
||||
|
||||
controllers.Success(ctx, "删除备份成功")
|
||||
return controllers.Success(ctx, "删除备份成功")
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (c *Mysql57Controller) RestoreBackup(ctx http.Context) {
|
||||
func (c *Mysql57Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -566,28 +533,25 @@ func (c *Mysql57Controller) RestoreBackup(ctx http.Context) {
|
||||
"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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
err = c.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("name"))
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL57] 还原失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "还原成功")
|
||||
return controllers.Success(ctx, "还原成功")
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
func (c *Mysql57Controller) UserList(ctx http.Context) {
|
||||
func (c *Mysql57Controller) UserList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
type user struct {
|
||||
@@ -600,14 +564,14 @@ func (c *Mysql57Controller) UserList(ctx http.Context) {
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL57] 连接数据库失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT user, host FROM mysql.user")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL57] 查询数据库失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "查询数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "查询数据库失败")
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -645,8 +609,7 @@ func (c *Mysql57Controller) UserList(ctx http.Context) {
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取用户列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取用户列表失败")
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -654,27 +617,26 @@ func (c *Mysql57Controller) UserList(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(userGrants) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(userGrants) {
|
||||
endIndex = len(userGrants)
|
||||
}
|
||||
pagedUserGrants := userGrants[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(userGrants),
|
||||
"items": pagedUserGrants,
|
||||
})
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
func (c *Mysql57Controller) AddUser(ctx http.Context) {
|
||||
func (c *Mysql57Controller) AddUser(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -683,12 +645,10 @@ func (c *Mysql57Controller) AddUser(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -699,38 +659,36 @@ func (c *Mysql57Controller) AddUser(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "添加成功")
|
||||
return controllers.Success(ctx, "添加成功")
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (c *Mysql57Controller) DeleteUser(ctx http.Context) {
|
||||
func (c *Mysql57Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\"")
|
||||
|
||||
controllers.Success(ctx, "删除成功")
|
||||
return controllers.Success(ctx, "删除成功")
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (c *Mysql57Controller) SetUserPassword(ctx http.Context) {
|
||||
func (c *Mysql57Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -738,12 +696,10 @@ func (c *Mysql57Controller) SetUserPassword(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -752,13 +708,13 @@ func (c *Mysql57Controller) SetUserPassword(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
}
|
||||
|
||||
// SetUserPrivileges 设置用户权限
|
||||
func (c *Mysql57Controller) SetUserPrivileges(ctx http.Context) {
|
||||
func (c *Mysql57Controller) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql57") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -766,12 +722,10 @@ func (c *Mysql57Controller) SetUserPrivileges(ctx http.Context) {
|
||||
"database": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -781,5 +735,5 @@ func (c *Mysql57Controller) SetUserPrivileges(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
}
|
||||
|
||||
@@ -29,166 +29,154 @@ func NewMysql80Controller() *Mysql80Controller {
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (c *Mysql80Controller) Status(ctx http.Context) {
|
||||
func (c *Mysql80Controller) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (c *Mysql80Controller) Reload(ctx http.Context) {
|
||||
func (c *Mysql80Controller) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (c *Mysql80Controller) Restart(ctx http.Context) {
|
||||
func (c *Mysql80Controller) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (c *Mysql80Controller) Start(ctx http.Context) {
|
||||
func (c *Mysql80Controller) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (c *Mysql80Controller) Stop(ctx http.Context) {
|
||||
func (c *Mysql80Controller) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (c *Mysql80Controller) GetConfig(ctx http.Context) {
|
||||
func (c *Mysql80Controller) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
config := tools.Read("/www/server/mysql/conf/my.cnf")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (c *Mysql80Controller) SaveConfig(ctx http.Context) {
|
||||
func (c *Mysql80Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
}
|
||||
|
||||
if !tools.Write("/www/server/mysql/conf/my.cnf", config, 0644) {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败")
|
||||
}
|
||||
|
||||
c.Restart(ctx)
|
||||
return c.Restart(ctx)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (c *Mysql80Controller) Load(ctx http.Context) {
|
||||
func (c *Mysql80Controller) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "MySQL 已停止运行")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 已停止运行")
|
||||
}
|
||||
|
||||
raw := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
if strings.Contains(raw, "Access denied for user") {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码错误")
|
||||
}
|
||||
if !strings.Contains(raw, "Uptime") {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL负载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL负载失败")
|
||||
}
|
||||
|
||||
data := make(map[int]map[string]string)
|
||||
@@ -238,84 +226,80 @@ func (c *Mysql80Controller) Load(ctx http.Context) {
|
||||
bufferPoolReadRequests := cast.ToFloat64(data[12]["value"])
|
||||
data[10]["value"] = fmt.Sprintf("%.2f%%", bufferPoolReadRequests/(bufferPoolReads+bufferPoolReadRequests)*100)
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
// ErrorLog 获取错误日志
|
||||
func (c *Mysql80Controller) ErrorLog(ctx http.Context) {
|
||||
func (c *Mysql80Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearErrorLog 清空错误日志
|
||||
func (c *Mysql80Controller) ClearErrorLog(ctx http.Context) {
|
||||
func (c *Mysql80Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-error.log")
|
||||
controllers.Success(ctx, "清空错误日志成功")
|
||||
return controllers.Success(ctx, "清空错误日志成功")
|
||||
}
|
||||
|
||||
// SlowLog 获取慢查询日志
|
||||
func (c *Mysql80Controller) SlowLog(ctx http.Context) {
|
||||
func (c *Mysql80Controller) SlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearSlowLog 清空慢查询日志
|
||||
func (c *Mysql80Controller) ClearSlowLog(ctx http.Context) {
|
||||
func (c *Mysql80Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-slow.log")
|
||||
controllers.Success(ctx, "清空慢查询日志成功")
|
||||
return controllers.Success(ctx, "清空慢查询日志成功")
|
||||
}
|
||||
|
||||
// GetRootPassword 获取root密码
|
||||
func (c *Mysql80Controller) GetRootPassword(ctx http.Context) {
|
||||
func (c *Mysql80Controller) GetRootPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, rootPassword)
|
||||
return controllers.Success(ctx, rootPassword)
|
||||
}
|
||||
|
||||
// SetRootPassword 设置root密码
|
||||
func (c *Mysql80Controller) SetRootPassword(ctx http.Context) {
|
||||
func (c *Mysql80Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
if status != "active" {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
}
|
||||
|
||||
rootPassword := ctx.Request().Input(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码不能为空")
|
||||
}
|
||||
|
||||
oldRootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -326,18 +310,17 @@ func (c *Mysql80Controller) SetRootPassword(ctx http.Context) {
|
||||
if err != nil {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "设置root密码成功")
|
||||
return controllers.Success(ctx, "设置root密码成功")
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
func (c *Mysql80Controller) DatabaseList(ctx http.Context) {
|
||||
func (c *Mysql80Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -348,16 +331,14 @@ func (c *Mysql80Controller) DatabaseList(ctx http.Context) {
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MySQL80] 连接数据库失败" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SHOW DATABASES")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MySQL80] 获取数据库列表失败" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -374,8 +355,7 @@ func (c *Mysql80Controller) DatabaseList(ctx http.Context) {
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
facades.Log().Error("[MySQL80] 获取数据库列表失败" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -383,27 +363,26 @@ func (c *Mysql80Controller) DatabaseList(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(databases) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(databases) {
|
||||
endIndex = len(databases)
|
||||
}
|
||||
pagedDatabases := databases[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(databases),
|
||||
"items": pagedDatabases,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (c *Mysql80Controller) AddDatabase(ctx http.Context) {
|
||||
func (c *Mysql80Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -412,12 +391,10 @@ func (c *Mysql80Controller) AddDatabase(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -430,60 +407,56 @@ func (c *Mysql80Controller) AddDatabase(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "添加数据库成功")
|
||||
return controllers.Success(ctx, "添加数据库成功")
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (c *Mysql80Controller) DeleteDatabase(ctx http.Context) {
|
||||
func (c *Mysql80Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\"")
|
||||
|
||||
controllers.Success(ctx, "删除数据库成功")
|
||||
return controllers.Success(ctx, "删除数据库成功")
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
func (c *Mysql80Controller) BackupList(ctx http.Context) {
|
||||
func (c *Mysql80Controller) BackupList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
backupList, err := c.backup.MysqlList()
|
||||
if err != nil {
|
||||
facades.Log().Error("[MySQL80] 获取备份列表失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, backupList)
|
||||
return controllers.Success(ctx, backupList)
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (c *Mysql80Controller) UploadBackup(ctx http.Context) {
|
||||
func (c *Mysql80Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/mysql"
|
||||
@@ -494,71 +467,65 @@ func (c *Mysql80Controller) UploadBackup(ctx http.Context) {
|
||||
name := file.GetClientOriginalName()
|
||||
_, err = file.StoreAs(backupPath, name)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "上传文件成功")
|
||||
return controllers.Success(ctx, "上传文件成功")
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (c *Mysql80Controller) CreateBackup(ctx http.Context) {
|
||||
func (c *Mysql80Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
err = c.backup.MysqlBackup(database)
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL80] 创建备份失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "备份成功")
|
||||
return controllers.Success(ctx, "备份成功")
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (c *Mysql80Controller) DeleteBackup(ctx http.Context) {
|
||||
func (c *Mysql80Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/mysql"
|
||||
fileName := ctx.Request().Input("name")
|
||||
tools.Remove(backupPath + "/" + fileName)
|
||||
|
||||
controllers.Success(ctx, "删除备份成功")
|
||||
return controllers.Success(ctx, "删除备份成功")
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (c *Mysql80Controller) RestoreBackup(ctx http.Context) {
|
||||
func (c *Mysql80Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -566,28 +533,25 @@ func (c *Mysql80Controller) RestoreBackup(ctx http.Context) {
|
||||
"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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
err = c.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("name"))
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL80] 还原失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
}
|
||||
|
||||
controllers.Success(ctx, "还原成功")
|
||||
return controllers.Success(ctx, "还原成功")
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
func (c *Mysql80Controller) UserList(ctx http.Context) {
|
||||
func (c *Mysql80Controller) UserList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
type user struct {
|
||||
@@ -600,14 +564,14 @@ func (c *Mysql80Controller) UserList(ctx http.Context) {
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL80] 连接数据库失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT user, host FROM mysql.user")
|
||||
if err != nil {
|
||||
facades.Log().Error("[MYSQL80] 查询数据库失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "查询数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "查询数据库失败")
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -645,8 +609,7 @@ func (c *Mysql80Controller) UserList(ctx http.Context) {
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取用户列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取用户列表失败")
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -654,27 +617,26 @@ func (c *Mysql80Controller) UserList(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(userGrants) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(userGrants) {
|
||||
endIndex = len(userGrants)
|
||||
}
|
||||
pagedUserGrants := userGrants[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(userGrants),
|
||||
"items": pagedUserGrants,
|
||||
})
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
func (c *Mysql80Controller) AddUser(ctx http.Context) {
|
||||
func (c *Mysql80Controller) AddUser(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -683,12 +645,10 @@ func (c *Mysql80Controller) AddUser(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -699,38 +659,36 @@ func (c *Mysql80Controller) AddUser(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "添加成功")
|
||||
return controllers.Success(ctx, "添加成功")
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (c *Mysql80Controller) DeleteUser(ctx http.Context) {
|
||||
func (c *Mysql80Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\"")
|
||||
|
||||
controllers.Success(ctx, "删除成功")
|
||||
return controllers.Success(ctx, "删除成功")
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (c *Mysql80Controller) SetUserPassword(ctx http.Context) {
|
||||
func (c *Mysql80Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -738,12 +696,10 @@ func (c *Mysql80Controller) SetUserPassword(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -752,13 +708,13 @@ func (c *Mysql80Controller) SetUserPassword(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
}
|
||||
|
||||
// SetUserPrivileges 设置用户权限
|
||||
func (c *Mysql80Controller) SetUserPrivileges(ctx http.Context) {
|
||||
func (c *Mysql80Controller) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "mysql80") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -766,12 +722,10 @@ func (c *Mysql80Controller) SetUserPrivileges(ctx http.Context) {
|
||||
"database": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -781,5 +735,5 @@ func (c *Mysql80Controller) SetUserPrivileges(ctx http.Context) {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
|
||||
controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
}
|
||||
|
||||
@@ -24,176 +24,166 @@ func NewOpenrestyController() *OpenRestyController {
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (c *OpenRestyController) Status(ctx http.Context) {
|
||||
func (c *OpenRestyController) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (c *OpenRestyController) Reload(ctx http.Context) {
|
||||
func (c *OpenRestyController) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, "重载OpenResty成功")
|
||||
return controllers.Success(ctx, "重载OpenResty成功")
|
||||
} else {
|
||||
controllers.Error(ctx, 1, "重载OpenResty失败: "+status)
|
||||
return controllers.Error(ctx, 1, "重载OpenResty失败: "+status)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动OpenResty
|
||||
func (c *OpenRestyController) Start(ctx http.Context) {
|
||||
func (c *OpenRestyController) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, "启动OpenResty成功")
|
||||
return controllers.Success(ctx, "启动OpenResty成功")
|
||||
} else {
|
||||
controllers.Error(ctx, 1, "启动OpenResty失败: "+status)
|
||||
return controllers.Error(ctx, 1, "启动OpenResty失败: "+status)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止OpenResty
|
||||
func (c *OpenRestyController) Stop(ctx http.Context) {
|
||||
func (c *OpenRestyController) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, "停止OpenResty成功")
|
||||
return controllers.Success(ctx, "停止OpenResty成功")
|
||||
} else {
|
||||
controllers.Error(ctx, 1, "停止OpenResty失败: "+status)
|
||||
return controllers.Error(ctx, 1, "停止OpenResty失败: "+status)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启OpenResty
|
||||
func (c *OpenRestyController) Restart(ctx http.Context) {
|
||||
func (c *OpenRestyController) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, "重启OpenResty成功")
|
||||
return controllers.Success(ctx, "重启OpenResty成功")
|
||||
} else {
|
||||
controllers.Error(ctx, 1, "重启OpenResty失败: "+status)
|
||||
return controllers.Error(ctx, 1, "重启OpenResty失败: "+status)
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (c *OpenRestyController) GetConfig(ctx http.Context) {
|
||||
func (c *OpenRestyController) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := tools.Read("/www/server/openresty/conf/nginx.conf")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty配置失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (c *OpenRestyController) SaveConfig(ctx http.Context) {
|
||||
func (c *OpenRestyController) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "配置不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "配置不能为空")
|
||||
}
|
||||
|
||||
if !tools.Write("/www/server/openresty/conf/nginx.conf", config, 0644) {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "保存OpenResty配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "保存OpenResty配置失败")
|
||||
}
|
||||
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
// ErrorLog 获取错误日志
|
||||
func (c *OpenRestyController) ErrorLog(ctx http.Context) {
|
||||
func (c *OpenRestyController) ErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
if !tools.Exists("/www/wwwlogs/nginx_error.log") {
|
||||
controllers.Success(ctx, "")
|
||||
return
|
||||
return controllers.Success(ctx, "")
|
||||
}
|
||||
|
||||
out := tools.Exec("tail -n 100 /www/wwwlogs/nginx_error.log")
|
||||
controllers.Success(ctx, out)
|
||||
return controllers.Success(ctx, out)
|
||||
}
|
||||
|
||||
// ClearErrorLog 清空错误日志
|
||||
func (c *OpenRestyController) ClearErrorLog(ctx http.Context) {
|
||||
func (c *OpenRestyController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/wwwlogs/nginx_error.log")
|
||||
controllers.Success(ctx, "清空OpenResty错误日志成功")
|
||||
return controllers.Success(ctx, "清空OpenResty错误日志成功")
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (c *OpenRestyController) Load(ctx http.Context) {
|
||||
func (c *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/nginx_status")
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
facades.Log().Error("[OpenResty] 获取OpenResty负载失败: " + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
@@ -256,5 +246,5 @@ func (c *OpenRestyController) Load(ctx http.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
@@ -30,134 +30,128 @@ func NewPhp74Controller() *Php74Controller {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php74Controller) Status(ctx http.Context) {
|
||||
func (c *Php74Controller) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php74Controller) Reload(ctx http.Context) {
|
||||
func (c *Php74Controller) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php74Controller) Start(ctx http.Context) {
|
||||
func (c *Php74Controller) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php74Controller) Stop(ctx http.Context) {
|
||||
func (c *Php74Controller) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php74Controller) Restart(ctx http.Context) {
|
||||
func (c *Php74Controller) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php74Controller) GetConfig(ctx http.Context) {
|
||||
func (c *Php74Controller) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := tools.Read("/www/server/php/" + c.version + "/etc/php.ini")
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
func (c *Php74Controller) SaveConfig(ctx http.Context) {
|
||||
func (c *Php74Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
tools.Write("/www/server/php/"+c.version+"/etc/php.ini", config, 0644)
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
func (c *Php74Controller) Load(ctx http.Context) {
|
||||
func (c *Php74Controller) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + c.version)
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
facades.Log().Error("获取PHP-" + c.version + "运行状态失败")
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
@@ -180,43 +174,43 @@ func (c *Php74Controller) Load(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
func (c *Php74Controller) ErrorLog(ctx http.Context) {
|
||||
func (c *Php74Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/php-fpm.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php74Controller) SlowLog(ctx http.Context) {
|
||||
func (c *Php74Controller) SlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/slow.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php74Controller) ClearErrorLog(ctx http.Context) {
|
||||
func (c *Php74Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/php-fpm.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
func (c *Php74Controller) ClearSlowLog(ctx http.Context) {
|
||||
func (c *Php74Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/slow.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
type Extension struct {
|
||||
@@ -226,32 +220,30 @@ type Extension struct {
|
||||
Installed bool `json:"installed"`
|
||||
}
|
||||
|
||||
func (c *Php74Controller) GetExtensionList(ctx http.Context) {
|
||||
func (c *Php74Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
controllers.Success(ctx, extensions)
|
||||
return controllers.Success(ctx, extensions)
|
||||
}
|
||||
|
||||
func (c *Php74Controller) InstallExtension(ctx http.Context) {
|
||||
func (c *Php74Controller) InstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -261,37 +253,33 @@ func (c *Php74Controller) InstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建安装拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php74Controller) UninstallExtension(ctx http.Context) {
|
||||
func (c *Php74Controller) UninstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if !item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -301,18 +289,16 @@ func (c *Php74Controller) UninstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建卸载拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php74Controller) GetExtensions() []Extension {
|
||||
|
||||
@@ -30,134 +30,128 @@ func NewPhp80Controller() *Php80Controller {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php80Controller) Status(ctx http.Context) {
|
||||
func (c *Php80Controller) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php80Controller) Reload(ctx http.Context) {
|
||||
func (c *Php80Controller) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php80Controller) Start(ctx http.Context) {
|
||||
func (c *Php80Controller) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php80Controller) Stop(ctx http.Context) {
|
||||
func (c *Php80Controller) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php80Controller) Restart(ctx http.Context) {
|
||||
func (c *Php80Controller) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php80Controller) GetConfig(ctx http.Context) {
|
||||
func (c *Php80Controller) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := tools.Read("/www/server/php/" + c.version + "/etc/php.ini")
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
func (c *Php80Controller) SaveConfig(ctx http.Context) {
|
||||
func (c *Php80Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
tools.Write("/www/server/php/"+c.version+"/etc/php.ini", config, 0644)
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
func (c *Php80Controller) Load(ctx http.Context) {
|
||||
func (c *Php80Controller) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + c.version)
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
facades.Log().Error("获取PHP-" + c.version + "运行状态失败")
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
@@ -180,43 +174,43 @@ func (c *Php80Controller) Load(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
func (c *Php80Controller) ErrorLog(ctx http.Context) {
|
||||
func (c *Php80Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/php-fpm.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php80Controller) SlowLog(ctx http.Context) {
|
||||
func (c *Php80Controller) SlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/slow.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php80Controller) ClearErrorLog(ctx http.Context) {
|
||||
func (c *Php80Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/php-fpm.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
func (c *Php80Controller) ClearSlowLog(ctx http.Context) {
|
||||
func (c *Php80Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/slow.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
type Extension struct {
|
||||
@@ -226,32 +220,30 @@ type Extension struct {
|
||||
Installed bool `json:"installed"`
|
||||
}
|
||||
|
||||
func (c *Php80Controller) GetExtensionList(ctx http.Context) {
|
||||
func (c *Php80Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
controllers.Success(ctx, extensions)
|
||||
return controllers.Success(ctx, extensions)
|
||||
}
|
||||
|
||||
func (c *Php80Controller) InstallExtension(ctx http.Context) {
|
||||
func (c *Php80Controller) InstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -261,37 +253,33 @@ func (c *Php80Controller) InstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建安装拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php80Controller) UninstallExtension(ctx http.Context) {
|
||||
func (c *Php80Controller) UninstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if !item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -301,18 +289,16 @@ func (c *Php80Controller) UninstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建卸载拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php80Controller) GetExtensions() []Extension {
|
||||
|
||||
@@ -30,134 +30,128 @@ func NewPhp81Controller() *Php81Controller {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php81Controller) Status(ctx http.Context) {
|
||||
func (c *Php81Controller) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php81Controller) Reload(ctx http.Context) {
|
||||
func (c *Php81Controller) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php81Controller) Start(ctx http.Context) {
|
||||
func (c *Php81Controller) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php81Controller) Stop(ctx http.Context) {
|
||||
func (c *Php81Controller) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php81Controller) Restart(ctx http.Context) {
|
||||
func (c *Php81Controller) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php81Controller) GetConfig(ctx http.Context) {
|
||||
func (c *Php81Controller) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := tools.Read("/www/server/php/" + c.version + "/etc/php.ini")
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
func (c *Php81Controller) SaveConfig(ctx http.Context) {
|
||||
func (c *Php81Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
tools.Write("/www/server/php/"+c.version+"/etc/php.ini", config, 0644)
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
func (c *Php81Controller) Load(ctx http.Context) {
|
||||
func (c *Php81Controller) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + c.version)
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
facades.Log().Error("获取PHP-" + c.version + "运行状态失败")
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
@@ -180,43 +174,43 @@ func (c *Php81Controller) Load(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
func (c *Php81Controller) ErrorLog(ctx http.Context) {
|
||||
func (c *Php81Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/php-fpm.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php81Controller) SlowLog(ctx http.Context) {
|
||||
func (c *Php81Controller) SlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/slow.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php81Controller) ClearErrorLog(ctx http.Context) {
|
||||
func (c *Php81Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/php-fpm.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
func (c *Php81Controller) ClearSlowLog(ctx http.Context) {
|
||||
func (c *Php81Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/slow.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
type Extension struct {
|
||||
@@ -226,32 +220,30 @@ type Extension struct {
|
||||
Installed bool `json:"installed"`
|
||||
}
|
||||
|
||||
func (c *Php81Controller) GetExtensionList(ctx http.Context) {
|
||||
func (c *Php81Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
controllers.Success(ctx, extensions)
|
||||
return controllers.Success(ctx, extensions)
|
||||
}
|
||||
|
||||
func (c *Php81Controller) InstallExtension(ctx http.Context) {
|
||||
func (c *Php81Controller) InstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -261,37 +253,33 @@ func (c *Php81Controller) InstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建安装拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php81Controller) UninstallExtension(ctx http.Context) {
|
||||
func (c *Php81Controller) UninstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if !item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -301,18 +289,16 @@ func (c *Php81Controller) UninstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建卸载拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php81Controller) GetExtensions() []Extension {
|
||||
|
||||
@@ -30,134 +30,128 @@ func NewPhp82Controller() *Php82Controller {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php82Controller) Status(ctx http.Context) {
|
||||
func (c *Php82Controller) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php82Controller) Reload(ctx http.Context) {
|
||||
func (c *Php82Controller) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php82Controller) Start(ctx http.Context) {
|
||||
func (c *Php82Controller) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php82Controller) Stop(ctx http.Context) {
|
||||
func (c *Php82Controller) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php82Controller) Restart(ctx http.Context) {
|
||||
func (c *Php82Controller) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + c.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Php82Controller) GetConfig(ctx http.Context) {
|
||||
func (c *Php82Controller) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := tools.Read("/www/server/php/" + c.version + "/etc/php.ini")
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
func (c *Php82Controller) SaveConfig(ctx http.Context) {
|
||||
func (c *Php82Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
tools.Write("/www/server/php/"+c.version+"/etc/php.ini", config, 0644)
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
func (c *Php82Controller) Load(ctx http.Context) {
|
||||
func (c *Php82Controller) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + c.version)
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
facades.Log().Error("获取PHP-" + c.version + "运行状态失败")
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败")
|
||||
}
|
||||
|
||||
raw := resp.String()
|
||||
@@ -180,43 +174,43 @@ func (c *Php82Controller) Load(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
func (c *Php82Controller) ErrorLog(ctx http.Context) {
|
||||
func (c *Php82Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/php-fpm.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php82Controller) SlowLog(ctx http.Context) {
|
||||
func (c *Php82Controller) SlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + c.version + "/var/log/slow.log"))
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
func (c *Php82Controller) ClearErrorLog(ctx http.Context) {
|
||||
func (c *Php82Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/php-fpm.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
func (c *Php82Controller) ClearSlowLog(ctx http.Context) {
|
||||
func (c *Php82Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + c.version + "/var/log/slow.log")
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
|
||||
type Extension struct {
|
||||
@@ -226,32 +220,30 @@ type Extension struct {
|
||||
Installed bool `json:"installed"`
|
||||
}
|
||||
|
||||
func (c *Php82Controller) GetExtensionList(ctx http.Context) {
|
||||
func (c *Php82Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
controllers.Success(ctx, extensions)
|
||||
return controllers.Success(ctx, extensions)
|
||||
}
|
||||
|
||||
func (c *Php82Controller) InstallExtension(ctx http.Context) {
|
||||
func (c *Php82Controller) InstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展已安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -261,37 +253,33 @@ func (c *Php82Controller) InstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建安装拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php82Controller) UninstallExtension(ctx http.Context) {
|
||||
func (c *Php82Controller) UninstallExtension(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "php"+c.version) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
slug := ctx.Request().Input("slug")
|
||||
if len(slug) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
extensions := c.GetExtensions()
|
||||
for _, item := range extensions {
|
||||
if item.Slug == slug {
|
||||
if !item.Installed {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展未安装")
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
@@ -301,18 +289,16 @@ func (c *Php82Controller) UninstallExtension(ctx http.Context) {
|
||||
task.Log = "/tmp/" + item.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Error("[PHP-" + c.version + "] 创建卸载拓展任务失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
c.task.Process(task.ID)
|
||||
|
||||
controllers.Success(ctx, true)
|
||||
return
|
||||
return controllers.Success(ctx, true)
|
||||
}
|
||||
}
|
||||
|
||||
controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "扩展不存在")
|
||||
}
|
||||
|
||||
func (c *Php82Controller) GetExtensions() []Extension {
|
||||
|
||||
@@ -18,15 +18,14 @@ func NewPhpMyAdminController() *PhpMyAdminController {
|
||||
return &PhpMyAdminController{}
|
||||
}
|
||||
|
||||
func (c *PhpMyAdminController) Info(ctx http.Context) {
|
||||
func (c *PhpMyAdminController) Info(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "phpmyadmin") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
files, err := os.ReadDir("/www/server/phpmyadmin")
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "找不到 phpMyAdmin 目录")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "找不到 phpMyAdmin 目录")
|
||||
}
|
||||
|
||||
var phpmyadmin string
|
||||
@@ -36,32 +35,29 @@ func (c *PhpMyAdminController) Info(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
if len(phpmyadmin) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "找不到 phpMyAdmin 目录")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "找不到 phpMyAdmin 目录")
|
||||
}
|
||||
|
||||
conf := tools.Read("/www/server/vhost/phpmyadmin.conf")
|
||||
match := regexp.MustCompile(`listen\s+(\d+);`).FindStringSubmatch(conf)
|
||||
if len(match) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "找不到 phpMyAdmin 端口")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "找不到 phpMyAdmin 端口")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"phpmyadmin": phpmyadmin,
|
||||
"port": match[1],
|
||||
})
|
||||
}
|
||||
|
||||
func (c *PhpMyAdminController) SetPort(ctx http.Context) {
|
||||
func (c *PhpMyAdminController) SetPort(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "phpmyadmin") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
port := ctx.Request().Input("port")
|
||||
if len(port) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "端口不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "端口不能为空")
|
||||
}
|
||||
|
||||
conf := tools.Read("/www/server/vhost/phpmyadmin.conf")
|
||||
@@ -77,5 +73,5 @@ func (c *PhpMyAdminController) SetPort(ctx http.Context) {
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -31,186 +31,174 @@ func NewPostgresql15Controller() *Postgresql15Controller {
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (c *Postgresql15Controller) Status(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (c *Postgresql15Controller) Reload(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (c *Postgresql15Controller) Restart(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (c *Postgresql15Controller) Start(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (c *Postgresql15Controller) Stop(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (c *Postgresql15Controller) GetConfig(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
config := tools.Read("/www/server/postgresql/data/postgresql.conf")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// GetUserConfig 获取用户配置
|
||||
func (c *Postgresql15Controller) GetUserConfig(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) GetUserConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
config := tools.Read("/www/server/postgresql/data/pg_hba.conf")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (c *Postgresql15Controller) SaveConfig(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
}
|
||||
|
||||
if !tools.Write("/www/server/postgresql/data/postgresql.conf", config, 0644) {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
c.Restart(ctx)
|
||||
return c.Restart(ctx)
|
||||
}
|
||||
|
||||
// SaveUserConfig 保存用户配置
|
||||
func (c *Postgresql15Controller) SaveUserConfig(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) SaveUserConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
}
|
||||
|
||||
if !tools.Write("/www/server/postgresql/data/pg_hba.conf", config, 0644) {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败")
|
||||
}
|
||||
|
||||
c.Restart(ctx)
|
||||
return c.Restart(ctx)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (c *Postgresql15Controller) Load(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
}
|
||||
|
||||
data := []Info{
|
||||
@@ -221,39 +209,38 @@ func (c *Postgresql15Controller) Load(ctx http.Context) {
|
||||
{"空间占用", tools.Exec(`echo "select pg_size_pretty(pg_database_size('postgres'));" | su - postgres -c "psql" | sed -n 3p`)},
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
// Log 获取日志
|
||||
func (c *Postgresql15Controller) Log(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) Log(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearLog 清空日志
|
||||
func (c *Postgresql15Controller) ClearLog(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) ClearLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
func (c *Postgresql15Controller) DatabaseList(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
}
|
||||
|
||||
raw := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
@@ -285,27 +272,26 @@ func (c *Postgresql15Controller) DatabaseList(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(databaseList) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(databaseList) {
|
||||
endIndex = len(databaseList)
|
||||
}
|
||||
pagedDatabases := databaseList[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(databaseList),
|
||||
"items": pagedDatabases,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (c *Postgresql15Controller) AddDatabase(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -314,12 +300,10 @@ func (c *Postgresql15Controller) AddDatabase(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
@@ -333,59 +317,55 @@ func (c *Postgresql15Controller) AddDatabase(ctx http.Context) {
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (c *Postgresql15Controller) DeleteDatabase(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
func (c *Postgresql15Controller) BackupList(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) BackupList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
backupList, err := c.backup.PostgresqlList()
|
||||
if err != nil {
|
||||
facades.Log().Error("[PostgreSQL] 获取备份列表失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, backupList)
|
||||
return controllers.Success(ctx, backupList)
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (c *Postgresql15Controller) UploadBackup(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/postgresql"
|
||||
@@ -396,71 +376,65 @@ func (c *Postgresql15Controller) UploadBackup(ctx http.Context) {
|
||||
name := file.GetClientOriginalName()
|
||||
_, err = file.StoreAs(backupPath, name)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (c *Postgresql15Controller) CreateBackup(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
err = c.backup.PostgresqlBackup(database)
|
||||
if err != nil {
|
||||
facades.Log().Error("[PostgreSQL] 创建备份失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (c *Postgresql15Controller) DeleteBackup(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/postgresql"
|
||||
fileName := ctx.Request().Input("name")
|
||||
tools.Remove(backupPath + "/" + fileName)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (c *Postgresql15Controller) RestoreBackup(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -468,28 +442,25 @@ func (c *Postgresql15Controller) RestoreBackup(ctx http.Context) {
|
||||
"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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
err = c.backup.PostgresqlRestore(ctx.Request().Input("database"), ctx.Request().Input("name"))
|
||||
if err != nil {
|
||||
facades.Log().Error("[PostgreSQL] 还原失败:" + err.Error())
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
}
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
func (c *Postgresql15Controller) UserList(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) UserList(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
type user struct {
|
||||
@@ -500,8 +471,7 @@ func (c *Postgresql15Controller) UserList(ctx http.Context) {
|
||||
raw := tools.Exec(`echo "\du" | su - postgres -c "psql"`)
|
||||
users := strings.Split(raw, "\n")
|
||||
if len(users) < 4 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "用户列表为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "用户列表为空")
|
||||
}
|
||||
users = users[3:]
|
||||
|
||||
@@ -523,27 +493,26 @@ func (c *Postgresql15Controller) UserList(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(userList) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(userList) {
|
||||
endIndex = len(userList)
|
||||
}
|
||||
pagedUsers := userList[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(userList),
|
||||
"items": pagedUsers,
|
||||
})
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
func (c *Postgresql15Controller) AddUser(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) AddUser(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -552,12 +521,10 @@ func (c *Postgresql15Controller) AddUser(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
@@ -569,38 +536,36 @@ func (c *Postgresql15Controller) AddUser(ctx http.Context) {
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (c *Postgresql15Controller) DeleteUser(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
tools.Exec(`echo "DROP USER ` + user + `;" | su - postgres -c "psql"`)
|
||||
tools.Exec(`sed -i '/` + user + `/d' /www/server/postgresql/data/pg_hba.conf`)
|
||||
|
||||
c.Reload(ctx)
|
||||
return c.Reload(ctx)
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (c *Postgresql15Controller) SetUserPassword(ctx http.Context) {
|
||||
func (c *Postgresql15Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "postgresql15") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -608,17 +573,15 @@ func (c *Postgresql15Controller) SetUserPassword(ctx http.Context) {
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
tools.Exec(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -23,117 +23,111 @@ func NewPureFtpdController() *PureFtpdController {
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (c *PureFtpdController) Status(ctx http.Context) {
|
||||
func (c *PureFtpdController) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (c *PureFtpdController) Reload(ctx http.Context) {
|
||||
func (c *PureFtpdController) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload pure-ftpd")
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (c *PureFtpdController) Restart(ctx http.Context) {
|
||||
func (c *PureFtpdController) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart pure-ftpd")
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (c *PureFtpdController) Start(ctx http.Context) {
|
||||
func (c *PureFtpdController) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start pure-ftpd")
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (c *PureFtpdController) Stop(ctx http.Context) {
|
||||
func (c *PureFtpdController) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop pure-ftpd")
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// List 获取用户列表
|
||||
func (c *PureFtpdController) List(ctx http.Context) {
|
||||
func (c *PureFtpdController) List(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
listRaw := tools.Exec("pure-pw list")
|
||||
if len(listRaw) == 0 {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []User{},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
listArr := strings.Split(listRaw, "\n")
|
||||
@@ -155,27 +149,26 @@ func (c *PureFtpdController) List(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(users) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []User{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(users) {
|
||||
endIndex = len(users)
|
||||
}
|
||||
pagedUsers := users[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(users),
|
||||
"items": pagedUsers,
|
||||
})
|
||||
}
|
||||
|
||||
// Add 添加用户
|
||||
func (c *PureFtpdController) Add(ctx http.Context) {
|
||||
func (c *PureFtpdController) Add(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -184,12 +177,10 @@ func (c *PureFtpdController) Add(ctx http.Context) {
|
||||
"path": "required",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
@@ -200,8 +191,7 @@ func (c *PureFtpdController) Add(ctx http.Context) {
|
||||
path = "/" + path
|
||||
}
|
||||
if !tools.Exists(path) {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "目录不存在")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "目录不存在")
|
||||
}
|
||||
|
||||
tools.Chmod(path, 0755)
|
||||
@@ -209,25 +199,23 @@ func (c *PureFtpdController) Add(ctx http.Context) {
|
||||
tools.Exec(`yes '` + password + `' | pure-pw useradd ` + username + ` -u www -g www -d ` + path)
|
||||
tools.Exec("pure-pw mkdb")
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Delete 删除用户
|
||||
func (c *PureFtpdController) Delete(ctx http.Context) {
|
||||
func (c *PureFtpdController) Delete(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"username": "required",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
@@ -235,13 +223,13 @@ func (c *PureFtpdController) Delete(ctx http.Context) {
|
||||
tools.Exec("pure-pw userdel " + username + " -m")
|
||||
tools.Exec("pure-pw mkdb")
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ChangePassword 修改密码
|
||||
func (c *PureFtpdController) ChangePassword(ctx http.Context) {
|
||||
func (c *PureFtpdController) ChangePassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -249,12 +237,10 @@ func (c *PureFtpdController) ChangePassword(ctx http.Context) {
|
||||
"password": "required|min_len:6",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
@@ -263,40 +249,37 @@ func (c *PureFtpdController) ChangePassword(ctx http.Context) {
|
||||
tools.Exec(`yes '` + password + `' | pure-pw passwd ` + username + ` -m`)
|
||||
tools.Exec("pure-pw mkdb")
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetPort 获取端口
|
||||
func (c *PureFtpdController) GetPort(ctx http.Context) {
|
||||
func (c *PureFtpdController) GetPort(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
port := tools.Exec(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
if len(port) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd端口失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd端口失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, port)
|
||||
return controllers.Success(ctx, port)
|
||||
}
|
||||
|
||||
// SetPort 设置端口
|
||||
func (c *PureFtpdController) SetPort(ctx http.Context) {
|
||||
func (c *PureFtpdController) SetPort(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "pureftpd") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"port": "required",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
port := ctx.Request().Input("port")
|
||||
@@ -310,5 +293,5 @@ func (c *PureFtpdController) SetPort(ctx http.Context) {
|
||||
}
|
||||
tools.Exec("systemctl restart pure-ftpd")
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -22,156 +22,146 @@ func NewRedisController() *RedisController {
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (c *RedisController) Status(ctx http.Context) {
|
||||
func (c *RedisController) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (c *RedisController) Reload(ctx http.Context) {
|
||||
func (c *RedisController) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload redis")
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (c *RedisController) Restart(ctx http.Context) {
|
||||
func (c *RedisController) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart redis")
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (c *RedisController) Start(ctx http.Context) {
|
||||
func (c *RedisController) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start redis")
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (c *RedisController) Stop(ctx http.Context) {
|
||||
func (c *RedisController) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop redis")
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (c *RedisController) GetConfig(ctx http.Context) {
|
||||
func (c *RedisController) GetConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
config := tools.Read("/www/server/redis/redis.conf")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取Redis配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis配置失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (c *RedisController) SaveConfig(ctx http.Context) {
|
||||
func (c *RedisController) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "配置不能为空")
|
||||
}
|
||||
|
||||
if !tools.Write("/www/server/redis/redis.conf", config, 0644) {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "写入Redis配置失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入Redis配置失败")
|
||||
}
|
||||
|
||||
c.Restart(ctx)
|
||||
return c.Restart(ctx)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (c *RedisController) Load(ctx http.Context) {
|
||||
func (c *RedisController) Load(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "redis") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "Redis 已停止运行")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "Redis 已停止运行")
|
||||
}
|
||||
|
||||
raw := tools.Exec("redis-cli info")
|
||||
if len(raw) == 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取Redis负载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis负载失败")
|
||||
}
|
||||
|
||||
infoLines := strings.Split(raw, "\n")
|
||||
@@ -200,5 +190,5 @@ func (c *RedisController) Load(ctx http.Context) {
|
||||
{"最近一次 fork() 操作耗费的毫秒数", dataRaw["latest_fork_usec"]},
|
||||
}
|
||||
|
||||
controllers.Success(ctx, data)
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
@@ -31,9 +31,9 @@ func NewS3fsController() *S3fsController {
|
||||
}
|
||||
|
||||
// List 所有 S3fs 挂载
|
||||
func (c *S3fsController) List(ctx http.Context) {
|
||||
func (c *S3fsController) List(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "s3fs") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -42,34 +42,32 @@ func (c *S3fsController) List(ctx http.Context) {
|
||||
var s3fsList []s3fs
|
||||
err := sonic.UnmarshalString(c.setting.Get("s3fs", "[]"), &s3fsList)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "获取 S3fs 挂载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "获取 S3fs 挂载失败")
|
||||
}
|
||||
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(s3fsList) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []s3fs{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(s3fsList) {
|
||||
endIndex = len(s3fsList)
|
||||
}
|
||||
pagedS3fsList := s3fsList[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(s3fsList),
|
||||
"items": pagedS3fsList,
|
||||
})
|
||||
}
|
||||
|
||||
// Add 添加 S3fs 挂载
|
||||
func (c *S3fsController) Add(ctx http.Context) {
|
||||
func (c *S3fsController) Add(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "s3fs") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -80,12 +78,10 @@ func (c *S3fsController) Add(ctx http.Context) {
|
||||
"path": "required|regex:^/[a-zA-Z0-9_-]+$",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
ak := ctx.Request().Input("ak")
|
||||
@@ -96,8 +92,7 @@ func (c *S3fsController) Add(ctx http.Context) {
|
||||
|
||||
// 检查下地域节点中是否包含bucket,如果包含了,肯定是错误的
|
||||
if strings.Contains(url, bucket) {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "地域节点不能包含 Bucket 名称")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "地域节点不能包含 Bucket 名称")
|
||||
}
|
||||
|
||||
// 检查挂载目录是否存在且为空
|
||||
@@ -105,21 +100,18 @@ func (c *S3fsController) Add(ctx http.Context) {
|
||||
tools.Mkdir(path, 0755)
|
||||
}
|
||||
if !tools.Empty(path) {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载目录必须为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载目录必须为空")
|
||||
}
|
||||
|
||||
var s3fsList []s3fs
|
||||
err = sonic.UnmarshalString(c.setting.Get("s3fs", "[]"), &s3fsList)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取 S3fs 挂载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 S3fs 挂载失败")
|
||||
}
|
||||
|
||||
for _, s := range s3fsList {
|
||||
if s.Path == path {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "路径已存在")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "路径已存在")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,14 +122,12 @@ func (c *S3fsController) Add(ctx http.Context) {
|
||||
check := tools.Exec("mount -a 2>&1")
|
||||
if len(check) != 0 {
|
||||
tools.Exec(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+check)
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+check)
|
||||
}
|
||||
check2 := tools.Exec("df -h | grep " + path + " 2>&1")
|
||||
if len(check2) == 0 {
|
||||
tools.Exec(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "挂载失败,请检查配置是否正确")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "挂载失败,请检查配置是否正确")
|
||||
}
|
||||
|
||||
s3fsList = append(s3fsList, s3fs{
|
||||
@@ -148,35 +138,31 @@ func (c *S3fsController) Add(ctx http.Context) {
|
||||
})
|
||||
json, err := sonic.MarshalString(s3fsList)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "添加 S3fs 挂载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "添加 S3fs 挂载失败")
|
||||
}
|
||||
err = c.setting.Set("s3fs", json)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "添加 S3fs 挂载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "添加 S3fs 挂载失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Delete 删除 S3fs 挂载
|
||||
func (c *S3fsController) Delete(ctx http.Context) {
|
||||
func (c *S3fsController) Delete(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "s3fs") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
id := ctx.Request().Input("id")
|
||||
if len(id) == 0 {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载ID不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载ID不能为空")
|
||||
}
|
||||
|
||||
var s3fsList []s3fs
|
||||
err := sonic.UnmarshalString(c.setting.Get("s3fs", "[]"), &s3fsList)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "获取 S3fs 挂载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 S3fs 挂载失败")
|
||||
}
|
||||
|
||||
var mount s3fs
|
||||
@@ -187,8 +173,7 @@ func (c *S3fsController) Delete(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
if mount.ID == 0 {
|
||||
controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载ID不存在")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载ID不存在")
|
||||
}
|
||||
|
||||
tools.Exec(`fusermount -u '` + mount.Path + `' 2>&1`)
|
||||
@@ -196,8 +181,7 @@ func (c *S3fsController) Delete(ctx http.Context) {
|
||||
tools.Exec(`sed -i 's@^s3fs#` + mount.Bucket + `\s` + mount.Path + `.*$@@g' /etc/fstab`)
|
||||
check := tools.Exec("mount -a 2>&1")
|
||||
if len(check) != 0 {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+check)
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+check)
|
||||
}
|
||||
tools.Remove("/etc/passwd-s3fs-" + cast.ToString(mount.ID))
|
||||
|
||||
@@ -209,14 +193,12 @@ func (c *S3fsController) Delete(ctx http.Context) {
|
||||
}
|
||||
json, err := sonic.MarshalString(newS3fsList)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "删除 S3fs 挂载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "删除 S3fs 挂载失败")
|
||||
}
|
||||
err = c.setting.Set("s3fs", json)
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusInternalServerError, "删除 S3fs 挂载失败")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "删除 S3fs 挂载失败")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -28,103 +28,103 @@ func NewSupervisorController() *SupervisorController {
|
||||
}
|
||||
|
||||
// Status 状态
|
||||
func (c *SupervisorController) Status(ctx http.Context) {
|
||||
func (c *SupervisorController) Status(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
status := tools.Exec(`systemctl status ` + c.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动
|
||||
func (c *SupervisorController) Start(ctx http.Context) {
|
||||
func (c *SupervisorController) Start(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl start ` + c.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + c.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop 停止
|
||||
func (c *SupervisorController) Stop(ctx http.Context) {
|
||||
func (c *SupervisorController) Stop(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl stop ` + c.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + c.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status != "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart 重启
|
||||
func (c *SupervisorController) Restart(ctx http.Context) {
|
||||
func (c *SupervisorController) Restart(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl restart ` + c.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + c.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Reload 重载
|
||||
func (c *SupervisorController) Reload(ctx http.Context) {
|
||||
func (c *SupervisorController) Reload(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl reload ` + c.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + c.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
controllers.Success(ctx, true)
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
controllers.Success(ctx, false)
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Log 日志
|
||||
func (c *SupervisorController) Log(ctx http.Context) {
|
||||
func (c *SupervisorController) Log(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log := tools.Exec(`tail -n 200 /var/log/supervisor/supervisord.log`)
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearLog 清空日志
|
||||
func (c *SupervisorController) ClearLog(ctx http.Context) {
|
||||
func (c *SupervisorController) ClearLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
tools.Exec(`echo "" > /var/log/supervisor/supervisord.log`)
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Config 获取配置
|
||||
func (c *SupervisorController) Config(ctx http.Context) {
|
||||
func (c *SupervisorController) Config(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
var config string
|
||||
@@ -133,13 +133,13 @@ func (c *SupervisorController) Config(ctx http.Context) {
|
||||
} else {
|
||||
config = tools.Read(`/etc/supervisor/supervisord.conf`)
|
||||
}
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (c *SupervisorController) SaveConfig(ctx http.Context) {
|
||||
func (c *SupervisorController) SaveConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
config := ctx.Request().Input("config")
|
||||
@@ -149,13 +149,13 @@ func (c *SupervisorController) SaveConfig(ctx http.Context) {
|
||||
tools.Write(`/etc/supervisor/supervisord.conf`, config, 0644)
|
||||
}
|
||||
|
||||
c.Restart(ctx)
|
||||
return c.Restart(ctx)
|
||||
}
|
||||
|
||||
// Processes 进程列表
|
||||
func (c *SupervisorController) Processes(ctx http.Context) {
|
||||
func (c *SupervisorController) Processes(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -191,60 +191,59 @@ func (c *SupervisorController) Processes(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(processList) {
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []process{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(processList) {
|
||||
endIndex = len(processList)
|
||||
}
|
||||
pagedProcessList := processList[startIndex:endIndex]
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(processList),
|
||||
"items": pagedProcessList,
|
||||
})
|
||||
}
|
||||
|
||||
// StartProcess 启动进程
|
||||
func (c *SupervisorController) StartProcess(ctx http.Context) {
|
||||
func (c *SupervisorController) StartProcess(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
tools.Exec(`supervisorctl start ` + process)
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// StopProcess 停止进程
|
||||
func (c *SupervisorController) StopProcess(ctx http.Context) {
|
||||
func (c *SupervisorController) StopProcess(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
tools.Exec(`supervisorctl stop ` + process)
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// RestartProcess 重启进程
|
||||
func (c *SupervisorController) RestartProcess(ctx http.Context) {
|
||||
func (c *SupervisorController) RestartProcess(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
tools.Exec(`supervisorctl restart ` + process)
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ProcessLog 进程日志
|
||||
func (c *SupervisorController) ProcessLog(ctx http.Context) {
|
||||
func (c *SupervisorController) ProcessLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
@@ -256,13 +255,13 @@ func (c *SupervisorController) ProcessLog(ctx http.Context) {
|
||||
}
|
||||
|
||||
log := tools.Exec(`tail -n 200 ` + logPath)
|
||||
controllers.Success(ctx, log)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
// ClearProcessLog 清空进程日志
|
||||
func (c *SupervisorController) ClearProcessLog(ctx http.Context) {
|
||||
func (c *SupervisorController) ClearProcessLog(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
@@ -274,13 +273,13 @@ func (c *SupervisorController) ClearProcessLog(ctx http.Context) {
|
||||
}
|
||||
|
||||
tools.Exec(`echo "" > ` + logPath)
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ProcessConfig 获取进程配置
|
||||
func (c *SupervisorController) ProcessConfig(ctx http.Context) {
|
||||
func (c *SupervisorController) ProcessConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Query("process")
|
||||
@@ -291,13 +290,13 @@ func (c *SupervisorController) ProcessConfig(ctx http.Context) {
|
||||
config = tools.Read(`/etc/supervisor/conf.d/` + process + `.conf`)
|
||||
}
|
||||
|
||||
controllers.Success(ctx, config)
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveProcessConfig 保存进程配置
|
||||
func (c *SupervisorController) SaveProcessConfig(ctx http.Context) {
|
||||
func (c *SupervisorController) SaveProcessConfig(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
@@ -311,13 +310,13 @@ func (c *SupervisorController) SaveProcessConfig(ctx http.Context) {
|
||||
tools.Exec(`supervisorctl update`)
|
||||
tools.Exec(`supervisorctl start ` + process)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// AddProcess 添加进程
|
||||
func (c *SupervisorController) AddProcess(ctx http.Context) {
|
||||
func (c *SupervisorController) AddProcess(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
@@ -328,12 +327,10 @@ func (c *SupervisorController) AddProcess(ctx http.Context) {
|
||||
"num": "required",
|
||||
})
|
||||
if err != nil {
|
||||
controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
name := ctx.Request().Input("name")
|
||||
@@ -362,13 +359,13 @@ stdout_logfile_maxbytes=2MB
|
||||
tools.Exec(`supervisorctl update`)
|
||||
tools.Exec(`supervisorctl start ` + name)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteProcess 删除进程
|
||||
func (c *SupervisorController) DeleteProcess(ctx http.Context) {
|
||||
func (c *SupervisorController) DeleteProcess(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "supervisor") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
@@ -385,5 +382,5 @@ func (c *SupervisorController) DeleteProcess(ctx http.Context) {
|
||||
tools.Exec(`supervisorctl reread`)
|
||||
tools.Exec(`supervisorctl update`)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -20,16 +20,15 @@ func NewToolBoxController() *ToolBoxController {
|
||||
}
|
||||
|
||||
// GetDNS 获取 DNS 信息
|
||||
func (c *ToolBoxController) GetDNS(ctx http.Context) {
|
||||
func (c *ToolBoxController) GetDNS(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
raw := tools.Read("/etc/resolv.conf")
|
||||
match := regexp.MustCompile(`nameserver\s+(\S+)`).FindAllStringSubmatch(raw, -1)
|
||||
if len(match) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "找不到 DNS 信息")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "找不到 DNS 信息")
|
||||
}
|
||||
|
||||
var dns []string
|
||||
@@ -37,21 +36,20 @@ func (c *ToolBoxController) GetDNS(ctx http.Context) {
|
||||
dns = append(dns, m[1])
|
||||
}
|
||||
|
||||
controllers.Success(ctx, dns)
|
||||
return controllers.Success(ctx, dns)
|
||||
}
|
||||
|
||||
// SetDNS 设置 DNS 信息
|
||||
func (c *ToolBoxController) SetDNS(ctx http.Context) {
|
||||
func (c *ToolBoxController) SetDNS(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
dns1 := ctx.Request().Input("dns1")
|
||||
dns2 := ctx.Request().Input("dns2")
|
||||
|
||||
if len(dns1) == 0 || len(dns2) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "DNS 信息不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "DNS 信息不能为空")
|
||||
}
|
||||
|
||||
var dns string
|
||||
@@ -59,13 +57,13 @@ func (c *ToolBoxController) SetDNS(ctx http.Context) {
|
||||
dns += "nameserver " + dns2 + "\n"
|
||||
|
||||
tools.Write("/etc/resolv.conf", dns, 0644)
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetSWAP 获取 SWAP 信息
|
||||
func (c *ToolBoxController) GetSWAP(ctx http.Context) {
|
||||
func (c *ToolBoxController) GetSWAP(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
var total, size, used, free string
|
||||
@@ -85,7 +83,7 @@ func (c *ToolBoxController) GetSWAP(ctx http.Context) {
|
||||
free = tools.FormatBytes(cast.ToFloat64(match[3]) * 1024)
|
||||
}
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": total,
|
||||
"size": size,
|
||||
"used": used,
|
||||
@@ -94,9 +92,9 @@ func (c *ToolBoxController) GetSWAP(ctx http.Context) {
|
||||
}
|
||||
|
||||
// SetSWAP 设置 SWAP 信息
|
||||
func (c *ToolBoxController) SetSWAP(ctx http.Context) {
|
||||
func (c *ToolBoxController) SetSWAP(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
size := ctx.Request().InputInt("size")
|
||||
@@ -110,8 +108,7 @@ func (c *ToolBoxController) SetSWAP(ctx http.Context) {
|
||||
if size > 1 {
|
||||
free := tools.Exec("df -k /www | awk '{print $4}' | tail -n 1")
|
||||
if cast.ToInt64(free)*1024 < int64(size)*1024*1024 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "磁盘空间不足,当前剩余 "+tools.FormatBytes(cast.ToFloat64(free)))
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "磁盘空间不足,当前剩余 "+tools.FormatBytes(cast.ToFloat64(free)))
|
||||
}
|
||||
|
||||
if strings.Contains(tools.Exec("df -T /www | awk '{print $2}' | tail -n 1"), "btrfs") {
|
||||
@@ -125,92 +122,87 @@ func (c *ToolBoxController) SetSWAP(ctx http.Context) {
|
||||
tools.Exec("echo '/www/swap swap swap defaults 0 0' >> /etc/fstab")
|
||||
}
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetTimezone 获取时区
|
||||
func (c *ToolBoxController) GetTimezone(ctx http.Context) {
|
||||
func (c *ToolBoxController) GetTimezone(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
raw := tools.Exec("LC_ALL=C timedatectl | grep zone")
|
||||
match := regexp.MustCompile(`zone:\s+(\S+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "找不到时区信息")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "找不到时区信息")
|
||||
}
|
||||
|
||||
zonesRaw := tools.Exec("LC_ALL=C timedatectl list-timezones")
|
||||
zones := strings.Split(zonesRaw, "\n")
|
||||
|
||||
controllers.Success(ctx, http.Json{
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"zone": match[1],
|
||||
"zones": zones,
|
||||
})
|
||||
}
|
||||
|
||||
// SetTimezone 设置时区
|
||||
func (c *ToolBoxController) SetTimezone(ctx http.Context) {
|
||||
func (c *ToolBoxController) SetTimezone(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
timezone := ctx.Request().Input("timezone")
|
||||
if len(timezone) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "时区不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "时区不能为空")
|
||||
}
|
||||
|
||||
tools.Exec("timedatectl set-timezone " + timezone)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetHosts 获取 hosts 信息
|
||||
func (c *ToolBoxController) GetHosts(ctx http.Context) {
|
||||
func (c *ToolBoxController) GetHosts(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
controllers.Success(ctx, tools.Read("/etc/hosts"))
|
||||
return controllers.Success(ctx, tools.Read("/etc/hosts"))
|
||||
}
|
||||
|
||||
// SetHosts 设置 hosts 信息
|
||||
func (c *ToolBoxController) SetHosts(ctx http.Context) {
|
||||
func (c *ToolBoxController) SetHosts(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
hosts := ctx.Request().Input("hosts")
|
||||
if len(hosts) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "hosts 信息不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "hosts 信息不能为空")
|
||||
}
|
||||
|
||||
tools.Write("/etc/hosts", hosts, 0644)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetRootPassword 设置 root 密码
|
||||
func (c *ToolBoxController) SetRootPassword(ctx http.Context) {
|
||||
func (c *ToolBoxController) SetRootPassword(ctx http.Context) http.Response {
|
||||
if !controllers.Check(ctx, "toolbox") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
password := ctx.Request().Input("password")
|
||||
if len(password) == 0 {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "密码不能为空")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "密码不能为空")
|
||||
}
|
||||
if !regexp.MustCompile(`^[a-zA-Z0-9·~!@#$%^&*()_+-=\[\]{};:'",./<>?]{6,20}$`).MatchString(password) {
|
||||
controllers.Error(ctx, http.StatusBadRequest, "密码必须为 6-20 位字母、数字或特殊字符")
|
||||
return
|
||||
return controllers.Error(ctx, http.StatusBadRequest, "密码必须为 6-20 位字母、数字或特殊字符")
|
||||
}
|
||||
|
||||
password = strings.ReplaceAll(password, `'`, `\'`)
|
||||
tools.Exec(`yes '` + password + `' | passwd root`)
|
||||
|
||||
controllers.Success(ctx, nil)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -20,11 +20,13 @@ func NewSafeController() *SafeController {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SafeController) GetFirewallStatus(ctx http.Context) {
|
||||
Success(ctx, r.firewallStatus())
|
||||
// GetFirewallStatus 获取防火墙状态
|
||||
func (r *SafeController) GetFirewallStatus(ctx http.Context) http.Response {
|
||||
return Success(ctx, r.firewallStatus())
|
||||
}
|
||||
|
||||
func (r *SafeController) SetFirewallStatus(ctx http.Context) {
|
||||
// SetFirewallStatus 设置防火墙状态
|
||||
func (r *SafeController) SetFirewallStatus(ctx http.Context) http.Response {
|
||||
var out string
|
||||
if ctx.Request().InputBool("status") {
|
||||
if tools.IsRHEL() {
|
||||
@@ -40,13 +42,13 @@ func (r *SafeController) SetFirewallStatus(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
Success(ctx, out)
|
||||
return Success(ctx, out)
|
||||
}
|
||||
|
||||
func (r *SafeController) GetFirewallRules(ctx http.Context) {
|
||||
// GetFirewallRules 获取防火墙规则
|
||||
func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
if !r.firewallStatus() {
|
||||
Success(ctx, nil)
|
||||
return
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
@@ -55,11 +57,10 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) {
|
||||
out := tools.Exec("firewall-cmd --list-all 2>&1")
|
||||
match := regexp.MustCompile(`ports: (.*)`).FindStringSubmatch(out)
|
||||
if len(match) == 0 {
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
return
|
||||
}
|
||||
ports := strings.Split(match[1], " ")
|
||||
var rules []map[string]string
|
||||
@@ -74,29 +75,27 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(rules) {
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(rules) {
|
||||
endIndex = len(rules)
|
||||
}
|
||||
pagedRules := rules[startIndex:endIndex]
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(rules),
|
||||
"items": pagedRules,
|
||||
})
|
||||
} else {
|
||||
out := tools.Exec("ufw status | grep -v '(v6)' | grep ALLOW | awk '{print $1}'")
|
||||
if len(out) == 0 {
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
return
|
||||
}
|
||||
var rules []map[string]string
|
||||
for _, port := range strings.Split(out, "\n") {
|
||||
@@ -110,35 +109,33 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) {
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(rules) {
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
return
|
||||
}
|
||||
if endIndex > len(rules) {
|
||||
endIndex = len(rules)
|
||||
}
|
||||
pagedRules := rules[startIndex:endIndex]
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(rules),
|
||||
"items": pagedRules,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SafeController) AddFirewallRule(ctx http.Context) {
|
||||
// AddFirewallRule 添加防火墙规则
|
||||
func (r *SafeController) AddFirewallRule(ctx http.Context) http.Response {
|
||||
if !r.firewallStatus() {
|
||||
Error(ctx, http.StatusBadRequest, "防火墙未启动")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "防火墙未启动")
|
||||
}
|
||||
|
||||
port := ctx.Request().InputInt("port", 0)
|
||||
protocol := ctx.Request().Input("protocol", "")
|
||||
if port == 0 || protocol == "" {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
@@ -151,20 +148,19 @@ func (r *SafeController) AddFirewallRule(ctx http.Context) {
|
||||
tools.Exec("ufw reload")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *SafeController) DeleteFirewallRule(ctx http.Context) {
|
||||
// DeleteFirewallRule 删除防火墙规则
|
||||
func (r *SafeController) DeleteFirewallRule(ctx http.Context) http.Response {
|
||||
if !r.firewallStatus() {
|
||||
Error(ctx, http.StatusBadRequest, "防火墙未启动")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "防火墙未启动")
|
||||
}
|
||||
|
||||
port := ctx.Request().InputInt("port", 0)
|
||||
protocol := ctx.Request().Input("protocol", "")
|
||||
if port == 0 || protocol == "" {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
@@ -175,9 +171,10 @@ func (r *SafeController) DeleteFirewallRule(ctx http.Context) {
|
||||
tools.Exec("ufw reload")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// firewallStatus 获取防火墙状态
|
||||
func (r *SafeController) firewallStatus() bool {
|
||||
var out string
|
||||
var running bool
|
||||
@@ -200,7 +197,8 @@ func (r *SafeController) firewallStatus() bool {
|
||||
return running
|
||||
}
|
||||
|
||||
func (r *SafeController) GetSshStatus(ctx http.Context) {
|
||||
// GetSshStatus 获取 SSH 状态
|
||||
func (r *SafeController) GetSshStatus(ctx http.Context) http.Response {
|
||||
var out string
|
||||
if tools.IsRHEL() {
|
||||
out = tools.Exec("systemctl status sshd | grep Active | awk '{print $3}'")
|
||||
@@ -213,10 +211,11 @@ func (r *SafeController) GetSshStatus(ctx http.Context) {
|
||||
running = true
|
||||
}
|
||||
|
||||
Success(ctx, running)
|
||||
return Success(ctx, running)
|
||||
}
|
||||
|
||||
func (r *SafeController) SetSshStatus(ctx http.Context) {
|
||||
// SetSshStatus 设置 SSH 状态
|
||||
func (r *SafeController) SetSshStatus(ctx http.Context) http.Response {
|
||||
if ctx.Request().InputBool("status") {
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("systemctl enable sshd")
|
||||
@@ -235,19 +234,20 @@ func (r *SafeController) SetSshStatus(ctx http.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *SafeController) GetSshPort(ctx http.Context) {
|
||||
// GetSshPort 获取 SSH 端口
|
||||
func (r *SafeController) GetSshPort(ctx http.Context) http.Response {
|
||||
out := tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
Success(ctx, out)
|
||||
return Success(ctx, out)
|
||||
}
|
||||
|
||||
func (r *SafeController) SetSshPort(ctx http.Context) {
|
||||
// SetSshPort 设置 SSH 端口
|
||||
func (r *SafeController) SetSshPort(ctx http.Context) http.Response {
|
||||
port := ctx.Request().InputInt("port", 0)
|
||||
if port == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
oldPort := tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
@@ -258,28 +258,30 @@ func (r *SafeController) SetSshPort(ctx http.Context) {
|
||||
tools.Exec("systemctl restart sshd")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *SafeController) GetPingStatus(ctx http.Context) {
|
||||
// GetPingStatus 获取 Ping 状态
|
||||
func (r *SafeController) GetPingStatus(ctx http.Context) http.Response {
|
||||
if tools.IsRHEL() {
|
||||
out := tools.Exec(`firewall-cmd --list-all 2>&1`)
|
||||
if !strings.Contains(out, `rule protocol value="icmp" drop`) {
|
||||
Success(ctx, true)
|
||||
return Success(ctx, true)
|
||||
} else {
|
||||
Success(ctx, false)
|
||||
return Success(ctx, false)
|
||||
}
|
||||
} else {
|
||||
config := tools.Read("/etc/ufw/before.rules")
|
||||
if strings.Contains(config, "-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT") {
|
||||
Success(ctx, true)
|
||||
return Success(ctx, true)
|
||||
} else {
|
||||
Success(ctx, false)
|
||||
return Success(ctx, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SafeController) SetPingStatus(ctx http.Context) {
|
||||
// SetPingStatus 设置 Ping 状态
|
||||
func (r *SafeController) SetPingStatus(ctx http.Context) http.Response {
|
||||
if tools.IsRHEL() {
|
||||
if ctx.Request().InputBool("status") {
|
||||
tools.Exec(`firewall-cmd --permanent --remove-rich-rule='rule protocol value=icmp drop'`)
|
||||
@@ -296,5 +298,5 @@ func (r *SafeController) SetPingStatus(ctx http.Context) {
|
||||
tools.Exec(`ufw reload`)
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -19,14 +19,13 @@ func NewSettingController() *SettingController {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SettingController) List(ctx http.Context) {
|
||||
// List 获取设置列表
|
||||
func (r *SettingController) List(ctx http.Context) http.Response {
|
||||
var settings []models.Setting
|
||||
err := facades.Orm().Query().Get(&settings)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 查询设置列表失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
var result = make(map[string]string)
|
||||
@@ -42,19 +41,18 @@ func (r *SettingController) List(ctx http.Context) {
|
||||
err = facades.Auth().User(ctx, &user)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 获取用户失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
result["username"] = user.Username
|
||||
result["email"] = user.Email
|
||||
|
||||
result["port"] = tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
|
||||
Success(ctx, result)
|
||||
return Success(ctx, result)
|
||||
}
|
||||
|
||||
func (r *SettingController) Save(ctx http.Context) {
|
||||
// Save 保存设置
|
||||
func (r *SettingController) Save(ctx http.Context) http.Response {
|
||||
name := ctx.Request().Input("name")
|
||||
port := ctx.Request().Input("port")
|
||||
backupPath := ctx.Request().Input("backup_path")
|
||||
@@ -67,9 +65,7 @@ func (r *SettingController) Save(ctx http.Context) {
|
||||
err := r.setting.Set(models.SettingKeyName, name)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 保存设置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
oldPort := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if oldPort != port {
|
||||
@@ -81,9 +77,7 @@ func (r *SettingController) Save(ctx http.Context) {
|
||||
err = r.setting.Set(models.SettingKeyBackupPath, backupPath)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 保存设置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
if !tools.Exists(websitePath) {
|
||||
tools.Mkdir(websitePath, 0755)
|
||||
@@ -92,25 +86,19 @@ func (r *SettingController) Save(ctx http.Context) {
|
||||
err = r.setting.Set(models.SettingKeyWebsitePath, websitePath)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 保存设置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeyEntrance, entrance)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 保存设置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
var user models.User
|
||||
err = facades.Auth().User(ctx, &user)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 获取用户失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if len(username) > 0 {
|
||||
@@ -123,19 +111,15 @@ func (r *SettingController) Save(ctx http.Context) {
|
||||
hash, err := facades.Hash().Make(password)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 保存设置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
user.Password = hash
|
||||
}
|
||||
|
||||
if err = facades.Orm().Query().Save(&user); err != nil {
|
||||
facades.Log().Error("[面板][SettingController] 保存设置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -28,17 +28,17 @@ func NewSshController() *SshController {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SshController) GetInfo(ctx http.Context) {
|
||||
// GetInfo 获取 SSH 配置
|
||||
func (r *SshController) GetInfo(ctx http.Context) http.Response {
|
||||
host := r.setting.Get(models.SettingKeySshHost)
|
||||
port := r.setting.Get(models.SettingKeySshPort)
|
||||
user := r.setting.Get(models.SettingKeySshUser)
|
||||
password := r.setting.Get(models.SettingKeySshPassword)
|
||||
if len(host) == 0 || len(user) == 0 || len(password) == 0 {
|
||||
Error(ctx, http.StatusInternalServerError, "SSH 配置不完整")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "SSH 配置不完整")
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"host": host,
|
||||
"port": port,
|
||||
"user": user,
|
||||
@@ -46,7 +46,8 @@ func (r *SshController) GetInfo(ctx http.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func (r *SshController) UpdateInfo(ctx http.Context) {
|
||||
// UpdateInfo 更新 SSH 配置
|
||||
func (r *SshController) UpdateInfo(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"host": "required",
|
||||
"port": "required",
|
||||
@@ -54,12 +55,10 @@ func (r *SshController) UpdateInfo(ctx http.Context) {
|
||||
"password": "required",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
host := ctx.Request().Input("host")
|
||||
@@ -69,32 +68,29 @@ func (r *SshController) UpdateInfo(ctx http.Context) {
|
||||
err = r.setting.Set(models.SettingKeySshHost, host)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SSH] 更新配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeySshPort, port)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SSH] 更新配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeySshUser, user)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SSH] 更新配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeySshPassword, password)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SSH] 更新配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *SshController) Session(ctx http.Context) {
|
||||
// Session SSH 会话
|
||||
func (r *SshController) Session(ctx http.Context) http.Response {
|
||||
upGrader := websocket.Upgrader{
|
||||
ReadBufferSize: 4096,
|
||||
WriteBufferSize: 4096,
|
||||
@@ -107,8 +103,7 @@ func (r *SshController) Session(ctx http.Context) {
|
||||
ws, err := upGrader.Upgrade(ctx.Response().Writer(), ctx.Request().Origin(), nil)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][SSH] 建立连接失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
defer ws.Close()
|
||||
|
||||
@@ -121,7 +116,7 @@ func (r *SshController) Session(ctx http.Context) {
|
||||
if err != nil {
|
||||
_ = ws.WriteControl(websocket.CloseMessage,
|
||||
[]byte(err.Error()), time.Now().Add(time.Second))
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
@@ -129,7 +124,7 @@ func (r *SshController) Session(ctx http.Context) {
|
||||
if err != nil {
|
||||
_ = ws.WriteControl(websocket.CloseMessage,
|
||||
[]byte(err.Error()), time.Now().Add(time.Second))
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
defer turn.Close()
|
||||
|
||||
@@ -161,4 +156,6 @@ func (r *SshController) Session(ctx http.Context) {
|
||||
cancel()
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
return Success(ctx, logBuff.String())
|
||||
}
|
||||
|
||||
@@ -17,22 +17,23 @@ func NewTaskController() *TaskController {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *TaskController) Status(ctx http.Context) {
|
||||
// Status 获取当前任务状态
|
||||
func (r *TaskController) Status(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("status", models.TaskStatusWaiting).OrWhere("status", models.TaskStatusRunning).FirstOrFail(&task)
|
||||
if err == nil {
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"task": true,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"task": false,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *TaskController) List(ctx http.Context) {
|
||||
// List 获取任务列表
|
||||
func (r *TaskController) List(ctx http.Context) http.Response {
|
||||
status := ctx.Request().Query("status")
|
||||
if len(status) == 0 {
|
||||
status = models.TaskStatusWaiting
|
||||
@@ -43,38 +44,37 @@ func (r *TaskController) List(ctx http.Context) {
|
||||
err := facades.Orm().Query().Where("status", status).Paginate(ctx.Request().QueryInt("page"), ctx.Request().QueryInt("limit"), &tasks, &total)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][TaskController] 查询任务列表失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": total,
|
||||
"items": tasks,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *TaskController) Log(ctx http.Context) {
|
||||
// Log 获取任务日志
|
||||
func (r *TaskController) Log(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().QueryInt("id")).FirstOrFail(&task)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][TaskController] 查询任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
log := tools.Exec("tail -n 30 " + task.Log)
|
||||
|
||||
Success(ctx, log)
|
||||
return Success(ctx, log)
|
||||
}
|
||||
|
||||
func (r *TaskController) Delete(ctx http.Context) {
|
||||
// Delete 删除任务
|
||||
func (r *TaskController) Delete(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
_, err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).Delete(&task)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][TaskController] 删除任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -18,60 +18,55 @@ func NewUserController() *UserController {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *UserController) Login(ctx http.Context) {
|
||||
// Login 用户登录
|
||||
func (r *UserController) Login(ctx http.Context) http.Response {
|
||||
var loginRequest requests.LoginRequest
|
||||
errors, err := ctx.Request().ValidateRequest(&loginRequest)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if errors != nil {
|
||||
Error(ctx, http.StatusUnprocessableEntity, errors.All())
|
||||
return
|
||||
return Error(ctx, http.StatusUnprocessableEntity, errors.All())
|
||||
}
|
||||
|
||||
var user models.User
|
||||
err = facades.Orm().Query().Where("username", loginRequest.Username).First(&user)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][UserController] 查询用户失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if user.ID == 0 || !facades.Hash().Check(loginRequest.Password, user.Password) {
|
||||
Error(ctx, http.StatusForbidden, "用户名或密码错误")
|
||||
return
|
||||
return Error(ctx, http.StatusForbidden, "用户名或密码错误")
|
||||
}
|
||||
|
||||
if facades.Hash().NeedsRehash(user.Password) {
|
||||
user.Password, err = facades.Hash().Make(loginRequest.Password)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][UserController] 更新密码失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
}
|
||||
|
||||
token, loginErr := facades.Auth().LoginUsingID(ctx, user.ID)
|
||||
if loginErr != nil {
|
||||
facades.Log().Error("[面板][UserController] 登录失败 ", loginErr)
|
||||
Error(ctx, http.StatusInternalServerError, loginErr.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, loginErr.Error())
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"access_token": token,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *UserController) Info(ctx http.Context) {
|
||||
// Info 用户信息
|
||||
func (r *UserController) Info(ctx http.Context) http.Response {
|
||||
user, ok := ctx.Value("user").(models.User)
|
||||
if !ok {
|
||||
Error(ctx, http.StatusUnauthorized, "登录已过期")
|
||||
return
|
||||
return Error(ctx, http.StatusUnauthorized, "登录已过期")
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"username": user.Username,
|
||||
"email": user.Email,
|
||||
})
|
||||
|
||||
@@ -29,27 +29,26 @@ func NewWebsiteController() *WebsiteController {
|
||||
}
|
||||
|
||||
// List 网站列表
|
||||
func (c *WebsiteController) List(ctx http.Context) {
|
||||
func (c *WebsiteController) List(ctx http.Context) http.Response {
|
||||
limit := ctx.Request().QueryInt("limit")
|
||||
page := ctx.Request().QueryInt("page")
|
||||
|
||||
total, websites, err := c.website.List(page, limit)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站列表失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"total": total,
|
||||
"items": websites,
|
||||
})
|
||||
}
|
||||
|
||||
// Add 添加网站
|
||||
func (c *WebsiteController) Add(ctx http.Context) {
|
||||
func (c *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|regex:^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$|not_exists:websites,name",
|
||||
@@ -62,12 +61,10 @@ func (c *WebsiteController) Add(ctx http.Context) {
|
||||
"db_password": "required_if:db,true",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
var website services.PanelWebsite
|
||||
@@ -83,91 +80,85 @@ func (c *WebsiteController) Add(ctx http.Context) {
|
||||
newSite, err := c.website.Add(website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 添加网站失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, newSite)
|
||||
return Success(ctx, newSite)
|
||||
}
|
||||
|
||||
// Delete 删除网站
|
||||
func (c *WebsiteController) Delete(ctx http.Context) {
|
||||
func (c *WebsiteController) Delete(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
id := ctx.Request().InputInt("id")
|
||||
err := c.website.Delete(id)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 删除网站失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "删除网站失败: "+err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "删除网站失败: "+err.Error())
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetDefaultConfig 获取默认配置
|
||||
func (c *WebsiteController) GetDefaultConfig(ctx http.Context) {
|
||||
func (c *WebsiteController) GetDefaultConfig(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
index := tools.Read("/www/server/openresty/html/index.html")
|
||||
stop := tools.Read("/www/server/openresty/html/stop.html")
|
||||
|
||||
Success(ctx, http.Json{
|
||||
return Success(ctx, http.Json{
|
||||
"index": index,
|
||||
"stop": stop,
|
||||
})
|
||||
}
|
||||
|
||||
// SaveDefaultConfig 保存默认配置
|
||||
func (c *WebsiteController) SaveDefaultConfig(ctx http.Context) {
|
||||
func (c *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
index := ctx.Request().Input("index")
|
||||
stop := ctx.Request().Input("stop")
|
||||
|
||||
if !tools.Write("/www/server/openresty/html/index.html", index, 0644) {
|
||||
facades.Log().Error("[面板][WebsiteController] 保存默认配置失败")
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
if !tools.Write("/www/server/openresty/html/stop.html", stop, 0644) {
|
||||
facades.Log().Error("[面板][WebsiteController] 保存默认配置失败")
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (c *WebsiteController) GetConfig(ctx http.Context) {
|
||||
func (c *WebsiteController) GetConfig(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
id := ctx.Request().InputInt("id")
|
||||
if id == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
config, err := c.website.GetConfig(id)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, config)
|
||||
return Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
func (c *WebsiteController) SaveConfig(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"id": "required",
|
||||
@@ -190,23 +181,19 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
"ssl_certificate_key": "required_if:ssl,true",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, validator.Errors().One())
|
||||
}
|
||||
|
||||
var website models.Website
|
||||
if facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&website) != nil {
|
||||
Error(ctx, http.StatusBadRequest, "网站不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "网站不存在")
|
||||
}
|
||||
|
||||
if !website.Status {
|
||||
Error(ctx, http.StatusBadRequest, "网站已停用,请先启用")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "网站已停用,请先启用")
|
||||
}
|
||||
|
||||
// 原文
|
||||
@@ -214,15 +201,13 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
if strings.TrimSpace(raw) != strings.TrimSpace(ctx.Request().Input("raw")) {
|
||||
tools.Write("/www/server/vhost/"+website.Name+".conf", ctx.Request().Input("raw"), 0644)
|
||||
tools.Exec("systemctl reload openresty")
|
||||
Success(ctx, nil)
|
||||
return
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// 目录
|
||||
path := ctx.Request().Input("path")
|
||||
if !tools.Exists(path) {
|
||||
Error(ctx, http.StatusBadRequest, "网站目录不存在")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "网站目录不存在")
|
||||
}
|
||||
website.Path = path
|
||||
|
||||
@@ -230,8 +215,7 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
domain := "server_name"
|
||||
domains := strings.Split(ctx.Request().Input("domains"), "\n")
|
||||
if len(domains) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "域名不能为空")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "域名不能为空")
|
||||
}
|
||||
for _, v := range domains {
|
||||
if v == "" {
|
||||
@@ -242,8 +226,7 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
domain += ";"
|
||||
domainConfigOld := tools.Cut(raw, "# server_name标记位开始", "# server_name标记位结束")
|
||||
if len(strings.TrimSpace(domainConfigOld)) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "配置文件中缺少server_name标记位")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "配置文件中缺少server_name标记位")
|
||||
}
|
||||
raw = strings.Replace(raw, domainConfigOld, "\n "+domain+"\n ", -1)
|
||||
|
||||
@@ -251,13 +234,11 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
var port strings.Builder
|
||||
ports := strings.Split(ctx.Request().Input("ports"), "\n")
|
||||
if len(ports) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "端口不能为空")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "端口不能为空")
|
||||
}
|
||||
for i, v := range ports {
|
||||
if _, err := strconv.Atoi(v); err != nil && v != "443 ssl http2" {
|
||||
Error(ctx, http.StatusBadRequest, "端口格式错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "端口格式错误")
|
||||
}
|
||||
if v == "443" && ctx.Request().InputBool("ssl") {
|
||||
v = "443 ssl http2"
|
||||
@@ -270,21 +251,18 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
}
|
||||
portConfigOld := tools.Cut(raw, "# port标记位开始", "# port标记位结束")
|
||||
if len(strings.TrimSpace(portConfigOld)) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "配置文件中缺少port标记位")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "配置文件中缺少port标记位")
|
||||
}
|
||||
raw = strings.Replace(raw, portConfigOld, "\n"+port.String()+"\n ", -1)
|
||||
|
||||
// 运行目录
|
||||
root := tools.Cut(raw, "# root标记位开始", "# root标记位结束")
|
||||
if len(strings.TrimSpace(root)) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "配置文件中缺少root标记位")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "配置文件中缺少root标记位")
|
||||
}
|
||||
match := regexp.MustCompile(`root\s+(.+);`).FindStringSubmatch(root)
|
||||
if len(match) != 2 {
|
||||
Error(ctx, http.StatusBadRequest, "配置文件中root标记位格式错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "配置文件中root标记位格式错误")
|
||||
}
|
||||
rootNew := strings.Replace(root, match[1], ctx.Request().Input("root"), -1)
|
||||
raw = strings.Replace(raw, root, rootNew, -1)
|
||||
@@ -292,13 +270,11 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
// 默认文件
|
||||
index := tools.Cut(raw, "# index标记位开始", "# index标记位结束")
|
||||
if len(strings.TrimSpace(index)) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "配置文件中缺少index标记位")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "配置文件中缺少index标记位")
|
||||
}
|
||||
match = regexp.MustCompile(`index\s+(.+);`).FindStringSubmatch(index)
|
||||
if len(match) != 2 {
|
||||
Error(ctx, http.StatusBadRequest, "配置文件中index标记位格式错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "配置文件中index标记位格式错误")
|
||||
}
|
||||
indexNew := strings.Replace(index, match[1], ctx.Request().Input("index"), -1)
|
||||
raw = strings.Replace(raw, index, indexNew, -1)
|
||||
@@ -391,112 +367,101 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) {
|
||||
err = facades.Orm().Query().Save(&website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 保存网站配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
tools.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644)
|
||||
tools.Write("/www/server/vhost/rewrite/"+website.Name+".conf", ctx.Request().Input("rewrite"), 0644)
|
||||
tools.Exec("systemctl reload openresty")
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ClearLog 清空日志
|
||||
func (c *WebsiteController) ClearLog(ctx http.Context) {
|
||||
func (c *WebsiteController) ClearLog(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
id := ctx.Request().InputInt("id")
|
||||
if id == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
website := models.Website{}
|
||||
err := facades.Orm().Query().Where("id", id).Get(&website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站信息失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
tools.Remove("/www/wwwlogs/" + website.Name + ".log")
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UpdateRemark 更新备注
|
||||
func (c *WebsiteController) UpdateRemark(ctx http.Context) {
|
||||
func (c *WebsiteController) UpdateRemark(ctx http.Context) http.Response {
|
||||
id := ctx.Request().InputInt("id")
|
||||
if id == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
website := models.Website{}
|
||||
err := facades.Orm().Query().Where("id", id).Get(&website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站信息失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
website.Remark = ctx.Request().Input("remark")
|
||||
err = facades.Orm().Query().Save(&website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 保存网站备注失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// BackupList 备份列表
|
||||
func (c *WebsiteController) BackupList(ctx http.Context) {
|
||||
func (c *WebsiteController) BackupList(ctx http.Context) http.Response {
|
||||
backupList, err := c.backup.WebsiteList()
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站备份列表失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
Success(ctx, backupList)
|
||||
return Success(ctx, backupList)
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (c *WebsiteController) CreateBackup(ctx http.Context) {
|
||||
func (c *WebsiteController) CreateBackup(ctx http.Context) http.Response {
|
||||
id := ctx.Request().InputInt("id")
|
||||
if id == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
website := models.Website{}
|
||||
err := facades.Orm().Query().Where("id", id).Get(&website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站信息失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "获取网站信息失败: "+err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "获取网站信息失败: "+err.Error())
|
||||
}
|
||||
|
||||
err = c.backup.WebSiteBackup(website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 备份网站失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "备份网站失败: "+err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "备份网站失败: "+err.Error())
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (c *WebsiteController) UploadBackup(ctx http.Context) {
|
||||
func (c *WebsiteController) UploadBackup(ctx http.Context) http.Response {
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/website"
|
||||
@@ -507,50 +472,44 @@ func (c *WebsiteController) UploadBackup(ctx http.Context) {
|
||||
name := file.GetClientOriginalName()
|
||||
_, err = file.StoreAs(backupPath, name)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "上传文件失败")
|
||||
}
|
||||
|
||||
Success(ctx, "上传文件成功")
|
||||
return Success(ctx, "上传文件成功")
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (c *WebsiteController) RestoreBackup(ctx http.Context) {
|
||||
func (c *WebsiteController) RestoreBackup(ctx http.Context) http.Response {
|
||||
id := ctx.Request().InputInt("id")
|
||||
if id == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
fileName := ctx.Request().Input("name")
|
||||
if len(fileName) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
website := models.Website{}
|
||||
err := facades.Orm().Query().Where("id", id).Get(&website)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站信息失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "获取网站信息失败: "+err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "获取网站信息失败: "+err.Error())
|
||||
}
|
||||
|
||||
err = c.backup.WebsiteRestore(website, fileName)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 还原网站失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "还原网站失败: "+err.Error())
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "还原网站失败: "+err.Error())
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (c *WebsiteController) DeleteBackup(ctx http.Context) {
|
||||
func (c *WebsiteController) DeleteBackup(ctx http.Context) http.Response {
|
||||
fileName := ctx.Request().Input("name")
|
||||
if len(fileName) == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/website"
|
||||
@@ -559,37 +518,33 @@ func (c *WebsiteController) DeleteBackup(ctx http.Context) {
|
||||
}
|
||||
|
||||
if !tools.Remove(backupPath + "/" + fileName) {
|
||||
Error(ctx, http.StatusInternalServerError, "删除备份失败")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "删除备份失败")
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// ResetConfig 重置配置
|
||||
func (c *WebsiteController) ResetConfig(ctx http.Context) {
|
||||
func (c *WebsiteController) ResetConfig(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
id := ctx.Request().InputInt("id")
|
||||
if id == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
website := models.Website{}
|
||||
if err := facades.Orm().Query().Where("id", id).Get(&website); err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站信息失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
website.Status = true
|
||||
website.Ssl = false
|
||||
if err := facades.Orm().Query().Save(&website); err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 保存网站配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
raw := fmt.Sprintf(`
|
||||
@@ -655,32 +610,29 @@ server
|
||||
tools.Write("/www/server/vhost/rewrite"+website.Name+".conf", "", 0644)
|
||||
tools.Exec("systemctl reload openresty")
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Status 网站状态
|
||||
func (c *WebsiteController) Status(ctx http.Context) {
|
||||
func (c *WebsiteController) Status(ctx http.Context) http.Response {
|
||||
if !Check(ctx, "openresty") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
id := ctx.Request().InputInt("id")
|
||||
if id == 0 {
|
||||
Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
return
|
||||
return Error(ctx, http.StatusBadRequest, "参数错误")
|
||||
}
|
||||
|
||||
website := models.Website{}
|
||||
if err := facades.Orm().Query().Where("id", id).Get(&website); err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 获取网站信息失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
website.Status = ctx.Request().InputBool("status")
|
||||
if err := facades.Orm().Query().Save(&website); err != nil {
|
||||
facades.Log().Error("[面板][WebsiteController] 保存网站配置失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
return Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
}
|
||||
|
||||
raw := tools.Read("/www/server/vhost/" + website.Name + ".conf")
|
||||
@@ -712,5 +664,5 @@ func (c *WebsiteController) Status(ctx http.Context) {
|
||||
tools.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644)
|
||||
tools.Exec("systemctl reload openresty")
|
||||
|
||||
Success(ctx, nil)
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
22
app/providers/database_service_provider.go
Normal file
22
app/providers/database_service_provider.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package providers
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/database/seeder"
|
||||
"github.com/goravel/framework/contracts/foundation"
|
||||
"github.com/goravel/framework/facades"
|
||||
|
||||
"panel/database/seeders"
|
||||
)
|
||||
|
||||
type DatabaseServiceProvider struct {
|
||||
}
|
||||
|
||||
func (receiver *DatabaseServiceProvider) Register(app foundation.Application) {
|
||||
|
||||
}
|
||||
|
||||
func (receiver *DatabaseServiceProvider) Boot(app foundation.Application) {
|
||||
facades.Seeder().Register([]seeder.Seeder{
|
||||
&seeders.DatabaseSeeder{},
|
||||
})
|
||||
}
|
||||
@@ -12,11 +12,12 @@ type RouteServiceProvider struct {
|
||||
}
|
||||
|
||||
func (receiver *RouteServiceProvider) Register(app foundation.Application) {
|
||||
//Add HTTP middlewares
|
||||
facades.Route().GlobalMiddleware(http.Kernel{}.Middleware()...)
|
||||
}
|
||||
|
||||
func (receiver *RouteServiceProvider) Boot(app foundation.Application) {
|
||||
// Add HTTP middlewares
|
||||
facades.Route().GlobalMiddleware(http.Kernel{}.Middleware()...)
|
||||
|
||||
receiver.configureRateLimiting()
|
||||
|
||||
routes.Web()
|
||||
|
||||
@@ -18,7 +18,9 @@ import (
|
||||
"github.com/goravel/framework/route"
|
||||
"github.com/goravel/framework/schedule"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
"github.com/goravel/framework/testing"
|
||||
"github.com/goravel/framework/validation"
|
||||
"github.com/goravel/gin"
|
||||
|
||||
"panel/app/providers"
|
||||
)
|
||||
@@ -80,6 +82,7 @@ func init() {
|
||||
&crypt.ServiceProvider{},
|
||||
&filesystem.ServiceProvider{},
|
||||
&validation.ServiceProvider{},
|
||||
&testing.ServiceProvider{},
|
||||
&providers.AppServiceProvider{},
|
||||
&providers.AuthServiceProvider{},
|
||||
&providers.RouteServiceProvider{},
|
||||
@@ -87,6 +90,8 @@ func init() {
|
||||
&providers.QueueServiceProvider{},
|
||||
&providers.EventServiceProvider{},
|
||||
&providers.ValidationServiceProvider{},
|
||||
&providers.DatabaseServiceProvider{},
|
||||
&gin.ServiceProvider{},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@ func init() {
|
||||
// in web browsers. You are free to adjust these settings as needed.
|
||||
//
|
||||
// To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
"paths": []string{"*"},
|
||||
"allowed_methods": []string{"*"},
|
||||
"allowed_origins": []string{"*"},
|
||||
"allowed_headers": []string{"*"},
|
||||
"exposed_headers": []string{"*"},
|
||||
"exposed_headers": []string{""},
|
||||
"max_age": 0,
|
||||
"supports_credentials": false,
|
||||
})
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/route"
|
||||
"github.com/goravel/framework/facades"
|
||||
ginfacades "github.com/goravel/gin/facades"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config := facades.Config()
|
||||
config.Add("http", map[string]any{
|
||||
// HTTP Driver
|
||||
"default": "gin",
|
||||
// HTTP Drivers
|
||||
"drivers": map[string]any{
|
||||
"gin": map[string]any{
|
||||
"route": func() (route.Route, error) {
|
||||
return ginfacades.Route("gin"), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
// HTTP URL
|
||||
"url": "http://localhost",
|
||||
// HTTP Host
|
||||
|
||||
14
database/seeders/database_seeder.go
Normal file
14
database/seeders/database_seeder.go
Normal file
@@ -0,0 +1,14 @@
|
||||
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
|
||||
}
|
||||
88
go.mod
88
go.mod
@@ -3,28 +3,29 @@ module panel
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.9.2
|
||||
github.com/bytedance/sonic v1.10.0
|
||||
github.com/gertd/go-pluralize v0.2.1
|
||||
github.com/gin-contrib/static v0.0.1
|
||||
github.com/gookit/color v1.5.4
|
||||
github.com/goravel/framework v1.12.1-0.20230809103226-03eb8ad21087
|
||||
github.com/goravel/framework v1.13.1
|
||||
github.com/goravel/gin v1.1.5
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/iancoleman/strcase v0.3.0
|
||||
github.com/imroc/req/v3 v3.40.1
|
||||
github.com/imroc/req/v3 v3.41.12
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/spf13/cast v1.5.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
golang.org/x/crypto v0.12.0
|
||||
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819
|
||||
golang.org/x/crypto v0.13.0
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.0 // indirect
|
||||
cloud.google.com/go/compute v1.19.1 // indirect
|
||||
cloud.google.com/go v0.110.6 // indirect
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v0.13.0 // indirect
|
||||
cloud.google.com/go/pubsub v1.30.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
cloud.google.com/go/pubsub v1.33.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.16 // indirect
|
||||
@@ -37,15 +38,17 @@ require (
|
||||
github.com/RichardKnop/machinery/v2 v2.0.11 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/aws/aws-sdk-go v1.37.16 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/containerd/continuity v0.4.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/docker/cli v20.10.22+incompatible // indirect
|
||||
github.com/docker/docker v20.10.24+incompatible // indirect
|
||||
github.com/docker/cli v24.0.6+incompatible // indirect
|
||||
github.com/docker/docker v24.0.6+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
@@ -59,7 +62,7 @@ require (
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.15.3 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
github.com/go-redsync/redsync/v4 v4.0.4 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||
@@ -70,7 +73,7 @@ require (
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.16.2 // indirect
|
||||
github.com/golang-module/carbon/v2 v2.2.3 // indirect
|
||||
github.com/golang-module/carbon/v2 v2.2.6 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
@@ -80,13 +83,13 @@ require (
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/pprof v0.0.0-20230808223545-4887780b67fb // indirect
|
||||
github.com/google/s2a-go v0.1.3 // indirect
|
||||
github.com/google/pprof v0.0.0-20230907193218-d3ddc7976beb // indirect
|
||||
github.com/google/s2a-go v0.1.4 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.8.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
|
||||
github.com/gookit/filter v1.2.0 // indirect
|
||||
github.com/gookit/goutil v0.6.12 // indirect
|
||||
github.com/gookit/validate v1.5.1 // indirect
|
||||
@@ -96,7 +99,7 @@ require (
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.3.1 // indirect
|
||||
@@ -118,23 +121,25 @@ require (
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.5 // indirect
|
||||
github.com/opencontainers/runc v1.1.9 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/ory/dockertest/v3 v3.10.0 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.2 // indirect
|
||||
github.com/quic-go/quic-go v0.37.4 // indirect
|
||||
github.com/refraction-networking/utls v1.3.3 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
|
||||
github.com/quic-go/quic-go v0.38.1 // indirect
|
||||
github.com/refraction-networking/utls v1.5.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/rotisserie/eris v0.5.4 // indirect
|
||||
github.com/rs/cors v1.10.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
@@ -148,6 +153,7 @@ require (
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/unrolled/secure v1.13.0 // indirect
|
||||
github.com/urfave/cli/v2 v2.25.7 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
@@ -162,30 +168,30 @@ require (
|
||||
go.mongodb.org/mongo-driver v1.7.5 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
golang.org/x/arch v0.4.0 // indirect
|
||||
golang.org/x/arch v0.5.0 // indirect
|
||||
golang.org/x/image v0.11.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/oauth2 v0.7.0 // indirect
|
||||
golang.org/x/net v0.15.0 // indirect
|
||||
golang.org/x/oauth2 v0.10.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/tools v0.12.0 // indirect
|
||||
google.golang.org/api v0.122.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.13.0 // indirect
|
||||
google.golang.org/api v0.126.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
|
||||
google.golang.org/grpc v1.57.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
google.golang.org/grpc v1.58.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/mysql v1.5.1 // indirect
|
||||
gorm.io/driver/postgres v1.5.2 // indirect
|
||||
gorm.io/driver/sqlserver v1.5.1 // indirect
|
||||
gorm.io/gorm v1.25.2 // indirect
|
||||
gorm.io/plugin/dbresolver v1.4.2 // indirect
|
||||
gorm.io/gorm v1.25.4 // indirect
|
||||
gorm.io/plugin/dbresolver v1.4.7 // indirect
|
||||
modernc.org/libc v1.22.5 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
|
||||
212
go.sum
212
go.sum
@@ -17,31 +17,30 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
|
||||
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
|
||||
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
|
||||
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
|
||||
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
|
||||
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
|
||||
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
|
||||
cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
|
||||
cloud.google.com/go/kms v1.10.1 h1:7hm1bRqGCA1GBRQUrp831TwJ9TWhP+tvLuP497CQS2g=
|
||||
cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
|
||||
cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
|
||||
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
||||
cloud.google.com/go/kms v1.15.0 h1:xYl5WEaSekKYN5gGRyhjvZKM22GVBBCzegGNVPy+aIs=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/pubsub v1.10.0/go.mod h1:eNpTrkOy7dCpkNyaSNetMa6udbgecJMd0ZsTJS/cuNo=
|
||||
cloud.google.com/go/pubsub v1.30.0 h1:vCge8m7aUKBJYOgrZp7EsNDf6QMd2CAlXZqWTn3yq6s=
|
||||
cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4=
|
||||
cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g=
|
||||
cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
@@ -85,25 +84,29 @@ github.com/aws/aws-sdk-go v1.37.16 h1:Q4YOP2s00NpB9wfmTDZArdcLRuG9ijbnoAwTW3ivle
|
||||
github.com/aws/aws-sdk-go v1.37.16/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||
github.com/brianvoe/gofakeit/v6 v6.23.1 h1:k2gX0hQpJStvixDbbw8oJOvPBg0XmHJWbSOF5JkiUHw=
|
||||
github.com/brianvoe/gofakeit/v6 v6.23.2 h1:lVde18uhad5wII/f5RMVFLtdQNE0HaGFuBUXmYKk8i8=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.2 h1:GDaNjuWSGu09guE9Oql0MSTNhNCLlWwO8y/xM5BzcbM=
|
||||
github.com/bytedance/sonic v1.9.2/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
|
||||
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk=
|
||||
github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
@@ -111,15 +114,12 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
|
||||
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -128,14 +128,13 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
|
||||
github.com/dhui/dktest v0.3.16 h1:i6gq2YQEtcrjKbeJpBkWjE8MmLZPYllcjOFbTZuPDnw=
|
||||
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/cli v20.10.22+incompatible h1:0E7UqWPcn4SlvLImMHyh6xwyNRUGdPxhstpHeh0bFL0=
|
||||
github.com/docker/cli v20.10.22+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY=
|
||||
github.com/docker/cli v24.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE=
|
||||
github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE=
|
||||
github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
@@ -148,7 +147,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
@@ -189,8 +187,8 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
|
||||
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-playground/validator/v10 v10.15.3 h1:S+sSpunYjNPDuXkWbK+x+bA7iXiW296KG4dL3X7xUZo=
|
||||
github.com/go-playground/validator/v10 v10.15.3/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
|
||||
@@ -236,8 +234,6 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
@@ -248,8 +244,8 @@ github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJ
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-migrate/migrate/v4 v4.16.2 h1:8coYbMKUyInrFk1lfGfRovTLAW7PhWp8qQDT2iKfuoA=
|
||||
github.com/golang-migrate/migrate/v4 v4.16.2/go.mod h1:pfcJX4nPHaVdc5nmdCikFBWtm+UBpiZjRNNsyBbp0/o=
|
||||
github.com/golang-module/carbon/v2 v2.2.3 h1:WvGIc5+qzq9drNzH+Gnjh1TZ0JgDY/IA+m2Dvk7Qm4Q=
|
||||
github.com/golang-module/carbon/v2 v2.2.3/go.mod h1:LdzRApgmDT/wt0eNT8MEJbHfJdSqCtT46uZhfF30dqI=
|
||||
github.com/golang-module/carbon/v2 v2.2.6 h1:4nHkIx7A7d+aoRDAGLwxZEJWAAZpmH5Bm/pVUl58FXI=
|
||||
github.com/golang-module/carbon/v2 v2.2.6/go.mod h1:XDALX7KgqmHk95xyLeaqX9/LJGbfLATyruTziq68SZ8=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
@@ -324,26 +320,27 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20230808223545-4887780b67fb h1:oqpb3Cwpc7EOml5PVGMYbSGmwNui2R7i8IW83gs4W0c=
|
||||
github.com/google/pprof v0.0.0-20230808223545-4887780b67fb/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
|
||||
github.com/google/pprof v0.0.0-20230907193218-d3ddc7976beb h1:LCMfzVg3sflxTs4UvuP4D8CkoZnfHLe2qzqgDn/4OHs=
|
||||
github.com/google/pprof v0.0.0-20230907193218-d3ddc7976beb/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE=
|
||||
github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
|
||||
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
|
||||
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
|
||||
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc=
|
||||
github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
|
||||
github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
|
||||
github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||
@@ -357,8 +354,10 @@ github.com/goravel/file-rotatelogs v0.0.0-20211215053220-2ab31dd9575c h1:obhFK91
|
||||
github.com/goravel/file-rotatelogs v0.0.0-20211215053220-2ab31dd9575c/go.mod h1:YSWsLXlG16u5CWFaXNZHhEQD10+NwF3xfgDV816OwLE=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.1 h1:ogkeIFcTHSBRUBpZYiyJbpul8hkVXxHPuDbOaP78O1M=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.1/go.mod h1:euk9qr52WrzM8ICs1hecFcR4CZ/ZZOPdacHfvHgbOf0=
|
||||
github.com/goravel/framework v1.12.1-0.20230809103226-03eb8ad21087 h1:YOKs5GFzbWOZz3ojiX5jl082Y1BRGOCig3ldnNBTrRs=
|
||||
github.com/goravel/framework v1.12.1-0.20230809103226-03eb8ad21087/go.mod h1:qc8dK2vVVVdTSashuby7+KZZ2CfGztNgMaoDGWtvtVI=
|
||||
github.com/goravel/framework v1.13.1 h1:3VM0ZEqbPtHN5llrtB1Mtw9Vr4VK/wPcupzNU7dreSs=
|
||||
github.com/goravel/framework v1.13.1/go.mod h1:CKsMPL8D72wKEZILHUo8Zzi6I9GDW424GpoLAMlB9b8=
|
||||
github.com/goravel/gin v1.1.5 h1:HWVBxSDHsfpq2lWvuagQVMJlCwznf6ifc71IYEo3sCE=
|
||||
github.com/goravel/gin v1.1.5/go.mod h1:FxnhnqcMJk/Sk6jA/xcXn6tHtFzayNXeFuw7GnLORMY=
|
||||
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.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
@@ -383,10 +382,10 @@ github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSAS
|
||||
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/imroc/req/v3 v3.40.1 h1:/7YAmkrI4HsOTO6Md5FUUWPId90bTD074BV8sA0bt18=
|
||||
github.com/imroc/req/v3 v3.40.1/go.mod h1:4wMbz0QYY5jmXNWk0BsWrRTR9ItZqOxzSJdGL0M9kzY=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/imroc/req/v3 v3.41.12 h1:OyPoCpVr8lpWuBwaEnqshA2xYLoxKPnjRIRVaZ+/NoQ=
|
||||
github.com/imroc/req/v3 v3.41.12/go.mod h1:W7dOrfQORA9nFoj+CafIZ6P5iyk+rWdbp2sffOAvABU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
@@ -433,11 +432,11 @@ github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQs
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
@@ -464,7 +463,6 @@ github.com/microsoft/go-mssqldb v1.1.0 h1:jsV+tpvcPTbNNKW0o3kiCD69kOHICsfjZ2VcVu
|
||||
github.com/microsoft/go-mssqldb v1.1.0/go.mod h1:LzkFdl4z2Ck+Hi+ycGOTbL56VEfgoyA2DvYejrNGbRk=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -479,7 +477,6 @@ github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -488,22 +485,20 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
|
||||
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
|
||||
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/opencontainers/runc v1.1.9 h1:XR0VIHTGce5eWPkaPesqTBrhW2yAcaraWfsEalNwQLM=
|
||||
github.com/opencontainers/runc v1.1.9/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
@@ -512,8 +507,8 @@ github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnz
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -525,12 +520,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
|
||||
github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
|
||||
github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw=
|
||||
github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE=
|
||||
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4=
|
||||
github.com/refraction-networking/utls v1.5.3 h1:Ds5Ocg1+MC1ahNx5iBEcHe0jHeLaA/fLey61EENm7ro=
|
||||
github.com/refraction-networking/utls v1.5.3/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
@@ -543,18 +538,19 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
|
||||
github.com/rotisserie/eris v0.5.4 h1:Il6IvLdAapsMhvuOahHWiBnl1G++Q0/L5UIkI5mARSk=
|
||||
github.com/rotisserie/eris v0.5.4/go.mod h1:Z/kgYTJiJtocxCbFfvRmO+QejApzG6zpyky9G1A4g9s=
|
||||
github.com/rs/cors v1.10.0 h1:62NOS1h+r8p1mW6FM0FSB0exioXLhd/sh15KpjWBZ+8=
|
||||
github.com/rs/cors v1.10.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
|
||||
@@ -586,14 +582,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM=
|
||||
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
@@ -608,12 +602,10 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
|
||||
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
@@ -669,8 +661,8 @@ go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
|
||||
golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y=
|
||||
golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
@@ -688,8 +680,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0
|
||||
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=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -700,8 +692,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U=
|
||||
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
@@ -776,8 +768,8 @@ 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=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -788,8 +780,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
|
||||
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -819,7 +811,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -827,8 +818,6 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -864,9 +853,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -875,14 +862,14 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -896,8 +883,9 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
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=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -961,8 +949,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
|
||||
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -987,8 +975,8 @@ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.39.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.122.0 h1:zDobeejm3E7pEG1mNHvdxvjs5XJoCMzyNH+CmwL94Es=
|
||||
google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
|
||||
google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
|
||||
google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1036,12 +1024,12 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 h1:9NWlQfY2ePejTmfwUH1OWwmznFa+0kKcHGPDvcPza9M=
|
||||
google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 h1:m8v1xLLLzMe1m5P+gCTF8nJB9epwZQUBERm20Oy1poQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
|
||||
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -1061,8 +1049,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
|
||||
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
|
||||
google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o=
|
||||
google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -1075,9 +1063,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -1100,7 +1087,6 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/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=
|
||||
@@ -1112,10 +1098,11 @@ gorm.io/driver/sqlserver v1.5.1 h1:wpyW/pR26U94uaujltiFGXY7fd2Jw5hC9PB1ZF/Y5s4=
|
||||
gorm.io/driver/sqlserver v1.5.1/go.mod h1:AYHzzte2msKTmYBYsSIq8ZUsznLJwBdkB2wpI+kt0nM=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
|
||||
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/plugin/dbresolver v1.4.2 h1:IeLSH20ayxbo4rN6HMIQ0ccdsh/fkLK23pp6ivZrqBI=
|
||||
gorm.io/plugin/dbresolver v1.4.2/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
|
||||
gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw=
|
||||
gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/plugin/dbresolver v1.4.7 h1:ZwtwmJQxTx9us7o6zEHFvH1q4OeEo1pooU7efmnunJA=
|
||||
gorm.io/plugin/dbresolver v1.4.7/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
|
||||
gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -1132,6 +1119,7 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
|
||||
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
|
||||
30
tests/feature/example_test.go
Normal file
30
tests/feature/example_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package feature
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"panel/tests"
|
||||
)
|
||||
|
||||
type ExampleTestSuite struct {
|
||||
suite.Suite
|
||||
tests.TestCase
|
||||
}
|
||||
|
||||
func TestExampleTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
}
|
||||
|
||||
// SetupTest will run before each test in the suite.
|
||||
func (s *ExampleTestSuite) SetupTest() {
|
||||
}
|
||||
|
||||
// TearDownTest will run after each test in the suite.
|
||||
func (s *ExampleTestSuite) TearDownTest() {
|
||||
}
|
||||
|
||||
func (s *ExampleTestSuite) TestIndex() {
|
||||
s.True(true)
|
||||
}
|
||||
15
tests/test_case.go
Normal file
15
tests/test_case.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/testing"
|
||||
|
||||
"panel/bootstrap"
|
||||
)
|
||||
|
||||
func init() {
|
||||
bootstrap.Boot()
|
||||
}
|
||||
|
||||
type TestCase struct {
|
||||
testing.TestCase
|
||||
}
|
||||
Reference in New Issue
Block a user