mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 16:10:59 +08:00
feat: cron controller
This commit is contained in:
@@ -1,18 +1,241 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
|
||||
"panel/app/models"
|
||||
"panel/app/services"
|
||||
"panel/packages/helper"
|
||||
)
|
||||
|
||||
type CronController struct {
|
||||
//Dependent services
|
||||
cron services.Cron
|
||||
}
|
||||
|
||||
func NewCronController() *CronController {
|
||||
return &CronController{
|
||||
//Inject services
|
||||
cron: services.NewCronImpl(),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *CronController) Index(ctx http.Context) {
|
||||
func (r *CronController) List(ctx http.Context) {
|
||||
limit := ctx.Request().QueryInt("limit")
|
||||
page := ctx.Request().QueryInt("page")
|
||||
|
||||
var crons []models.Cron
|
||||
var total int64
|
||||
err := facades.Orm().Query().Paginate(page, limit, &crons, &total)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 查询计划任务列表失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
"total": total,
|
||||
"items": crons,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *CronController) Add(ctx http.Context) {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required|regex:^((\\*|\\d+|\\d+-\\d+|\\d+\\/\\d+|\\d+-\\d+\\/\\d+|\\*\\/\\d+)(\\,(\\*|\\d+|\\d+-\\d+|\\d+\\/\\d+|\\d+-\\d+\\/\\d+|\\*\\/\\d+))*\\s?){5}$",
|
||||
"script": "required",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().All())
|
||||
return
|
||||
}
|
||||
|
||||
// 写入shell
|
||||
shellDir := "/www/server/cron/"
|
||||
shellLogDir := "/www/server/cron/logs/"
|
||||
if !helper.Exists(shellDir) {
|
||||
if !helper.Mkdir(shellDir, 0644) {
|
||||
facades.Log().Error("[面板][CronController] 创建计划任务目录失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
}
|
||||
if !helper.Exists(shellLogDir) {
|
||||
if !helper.Mkdir(shellLogDir, 0644) {
|
||||
facades.Log().Error("[面板][CronController] 创建计划任务日志目录失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
}
|
||||
shellFile := strconv.Itoa(int(carbon.Now().Timestamp())) + helper.RandomString(16)
|
||||
if !helper.WriteFile(shellDir+shellFile+".sh", ctx.Request().Input("script"), 0644) {
|
||||
facades.Log().Error("[面板][CronController] 创建计划任务脚本失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
helper.ExecShell("dos2unix " + shellDir + shellFile + ".sh")
|
||||
|
||||
var cron models.Cron
|
||||
cron.Name = ctx.Request().Input("name")
|
||||
cron.Type = "shell"
|
||||
cron.Status = true
|
||||
cron.Time = ctx.Request().Input("time")
|
||||
cron.Shell = shellDir + shellFile + ".sh"
|
||||
cron.Log = shellLogDir + shellFile + ".log"
|
||||
|
||||
err = facades.Orm().Query().Create(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 创建计划任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
|
||||
r.cron.AddToSystem(cron)
|
||||
|
||||
Success(ctx, http.Json{
|
||||
"id": cron.ID,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *CronController) Update(ctx http.Context) {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"id": "required|int",
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required|regex:^((\\*|\\d+|\\d+-\\d+|\\d+\\/\\d+|\\d+-\\d+\\/\\d+|\\*\\/\\d+)(\\,(\\*|\\d+|\\d+-\\d+|\\d+\\/\\d+|\\d+-\\d+\\/\\d+|\\*\\/\\d+))*\\s?){5}$",
|
||||
"script": "required",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().All())
|
||||
return
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
}
|
||||
|
||||
if !helper.WriteFile(cron.Shell, ctx.Request().Input("script"), 0644) {
|
||||
facades.Log().Error("[面板][CronController] 更新计划任务脚本失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
helper.ExecShell("dos2unix " + cron.Shell)
|
||||
|
||||
r.cron.DeleteFromSystem(cron)
|
||||
if cron.Status {
|
||||
r.cron.AddToSystem(cron)
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *CronController) Delete(ctx http.Context) {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"id": "required|int",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().All())
|
||||
return
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = facades.Orm().Query().Delete(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 删除计划任务失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
|
||||
r.cron.DeleteFromSystem(cron)
|
||||
|
||||
Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *CronController) Status(ctx http.Context) {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"id": "required|int",
|
||||
"status": "required|in:true,false",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().All())
|
||||
return
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
}
|
||||
|
||||
cron.Status = ctx.Request().InputBool("status")
|
||||
_, err = facades.Orm().Query().Update(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][CronController] 更新计划任务状态失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
|
||||
r.cron.DeleteFromSystem(cron)
|
||||
if cron.Status {
|
||||
r.cron.AddToSystem(cron)
|
||||
}
|
||||
|
||||
Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *CronController) Log(ctx http.Context) {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"id": "required|int",
|
||||
})
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if validator.Fails() {
|
||||
Error(ctx, http.StatusBadRequest, validator.Errors().All())
|
||||
return
|
||||
}
|
||||
|
||||
var cron models.Cron
|
||||
err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
Error(ctx, http.StatusBadRequest, "计划任务不存在")
|
||||
return
|
||||
}
|
||||
|
||||
if !helper.Exists(cron.Log) {
|
||||
Error(ctx, http.StatusBadRequest, "日志文件不存在")
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
"log": helper.ReadFile(cron.Log),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
)
|
||||
|
||||
type FileController struct {
|
||||
//Dependent services
|
||||
// Dependent services
|
||||
}
|
||||
|
||||
func NewFileController() *FileController {
|
||||
return &FileController{
|
||||
//Inject services
|
||||
// Inject services
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ func (r *TaskController) List(ctx http.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func (r *TaskController) TaskLog(ctx http.Context) {
|
||||
func (r *TaskController) Log(ctx http.Context) {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().QueryInt("id")).FirstOrFail(&task)
|
||||
if err != nil {
|
||||
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
)
|
||||
|
||||
type UserController struct {
|
||||
//Dependent services
|
||||
// Dependent services
|
||||
}
|
||||
|
||||
func NewUserController() *UserController {
|
||||
return &UserController{
|
||||
//Inject services
|
||||
// Inject services
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
40
app/services/cron.go
Normal file
40
app/services/cron.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"panel/app/models"
|
||||
"panel/packages/helper"
|
||||
)
|
||||
|
||||
type Cron interface {
|
||||
AddToSystem(cron models.Cron)
|
||||
DeleteFromSystem(cron models.Cron)
|
||||
}
|
||||
|
||||
type CronImpl struct {
|
||||
}
|
||||
|
||||
func NewCronImpl() *CronImpl {
|
||||
return &CronImpl{}
|
||||
}
|
||||
|
||||
// AddToSystem 添加到系统
|
||||
func (r *CronImpl) AddToSystem(cron models.Cron) {
|
||||
if helper.IsRHEL() {
|
||||
helper.ExecShell("echo \"" + cron.Time + " " + cron.Shell + " >> " + cron.Log + " 2>&1\" >> /var/spool/cron/root")
|
||||
} else {
|
||||
helper.ExecShell("echo \"" + cron.Time + " " + cron.Shell + " >> " + cron.Log + " 2>&1\" >> /var/spool/cron/crontabs/root")
|
||||
}
|
||||
|
||||
helper.ExecShell("systemctl restart crond")
|
||||
}
|
||||
|
||||
// DeleteFromSystem 从系统中删除
|
||||
func (r *CronImpl) DeleteFromSystem(cron models.Cron) {
|
||||
if helper.IsRHEL() {
|
||||
helper.ExecShell("sed -i '/" + cron.Shell + "/d' /var/spool/cron/root")
|
||||
} else {
|
||||
helper.ExecShell("sed -i '/" + cron.Shell + "/d' /var/spool/cron/crontabs/root")
|
||||
}
|
||||
|
||||
helper.ExecShell("systemctl restart crond")
|
||||
}
|
||||
@@ -28,6 +28,9 @@ func Web() {
|
||||
r.Prefix("task").Middleware(middleware.Jwt()).Group(func(r route.Route) {
|
||||
taskController := controllers.NewTaskController()
|
||||
r.Get("status", taskController.Status)
|
||||
r.Get("list", taskController.List)
|
||||
r.Get("log", taskController.Log)
|
||||
r.Post("delete", taskController.Delete)
|
||||
})
|
||||
r.Prefix("website").Middleware(middleware.Jwt()).Group(func(r route.Route) {
|
||||
websiteController := controllers.NewWebsiteController()
|
||||
@@ -41,6 +44,41 @@ func Web() {
|
||||
r.Post("update", pluginController.Update)
|
||||
r.Post("updateShow", pluginController.UpdateShow)
|
||||
})
|
||||
r.Prefix("cron").Middleware(middleware.Jwt()).Group(func(r route.Route) {
|
||||
cronController := controllers.NewCronController()
|
||||
r.Get("list", cronController.List)
|
||||
r.Post("add", cronController.Add)
|
||||
r.Post("update", cronController.Update)
|
||||
r.Post("delete", cronController.Delete)
|
||||
r.Post("status", cronController.Status)
|
||||
r.Get("log", cronController.Log)
|
||||
})
|
||||
r.Prefix("safe").Middleware(middleware.Jwt()).Group(func(r route.Route) {
|
||||
safeController := controllers.NewSafeController()
|
||||
r.Get("firewallStatus", safeController.GetFirewallStatus)
|
||||
r.Post("firewallStatus", safeController.SetFirewallStatus)
|
||||
r.Get("firewallRules", safeController.GetFirewallRules)
|
||||
r.Post("addFirewallRules", safeController.AddFirewallRule)
|
||||
r.Post("deleteFirewallRules", safeController.DeleteFirewallRule)
|
||||
r.Get("sshStatus", safeController.GetSshStatus)
|
||||
r.Post("sshStatus", safeController.SetSshStatus)
|
||||
r.Get("sshPort", safeController.GetSshPort)
|
||||
r.Post("sshPort", safeController.SetSshPort)
|
||||
r.Get("pingStatus", safeController.GetPingStatus)
|
||||
r.Post("pingStatus", safeController.SetPingStatus)
|
||||
})
|
||||
r.Prefix("monitor").Middleware(middleware.Jwt()).Group(func(r route.Route) {
|
||||
monitorController := controllers.NewMonitorController()
|
||||
r.Post("switch", monitorController.Switch)
|
||||
r.Post("saveDays", monitorController.SaveDays)
|
||||
r.Post("clear", monitorController.Clear)
|
||||
r.Get("list", monitorController.List)
|
||||
})
|
||||
r.Prefix("setting").Middleware(middleware.Jwt()).Group(func(r route.Route) {
|
||||
settingController := controllers.NewSettingController()
|
||||
r.Get("list", settingController.List)
|
||||
r.Post("save", settingController.Save)
|
||||
})
|
||||
})
|
||||
|
||||
facades.Route().Fallback(func(ctx http.Context) {
|
||||
|
||||
Reference in New Issue
Block a user