liuhaijun e94826ce29 add server
Change-Id: I0760f17f6a01c0121b59fcbfafc666032dbc30af
2024-09-19 09:44:15 +00:00

550 lines
15 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package v1
import (
"fmt"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/controller"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/middleware"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/event"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/id"
sc "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/schedule"
tk "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/schedule"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/model/user"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/errors"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/request"
excel "git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/pkg/utils"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/service/schedule_engine"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/internal/validator"
"git.inspur.com/sbg-jszt/cfn/cfn-schedule/pkg/log"
"github.com/gin-gonic/gin"
"time"
)
func CreateSchedRule(c *gin.Context) {
rule := &sc.SchedRule{}
err := validator.CheckPostParams(c, rule)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
if ur, bl := c.Get(middleware.LoginUserKey); bl {
if u, b := ur.(*user.User); b {
rule.CreateBy = u.Name
}
}
if _, err = rule.Create(); err != nil {
controller.FailCode(c, errors.ServerError, err, "内部错误!")
return
}
controller.Success(c, "")
}
// 编辑调度规则
func EditSchedRule(c *gin.Context) {
rule := &sc.SchedRule{}
err := validator.CheckPostParams(c, rule)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
fields := map[string]interface{}{}
fields["id"] = rule.Id
_, err = rule.Get(fields)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "无法查找到对象!")
return
}
updateColumns := []string{}
_, err = rule.Update(updateColumns)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "数据库错误!")
return
}
controller.Success(c, "")
}
// 根据ID获取规则
func GetSchedRule(c *gin.Context) {
rule := &sc.SchedRule{}
id := c.Param("id")
fields := map[string]interface{}{}
fields["id"] = id
result, err := rule.Get(fields)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
controller.Success(c, result)
}
func StatisticSchedRule(c *gin.Context) {
rule := &sc.SchedRule{}
total, err := rule.Count()
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "数据库异常!")
return
}
now := time.Now()
lastYear := now.AddDate(-1, 1, 0)
startDate := time.Date(lastYear.Year(), lastYear.Month(), 1, 0, 0, 0, 0, time.Local)
tmp, err := rule.CountByMonth(startDate)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "数据库异常!")
return
}
group := make(map[string]interface{})
for _, item := range tmp {
dateStr := item["date"].(string)
group[dateStr] = item["count"]
}
for startDate.Before(now) {
dateStr := startDate.Format("2006-01")
if _, exist := group[dateStr]; !exist {
group[dateStr] = 0
}
startDate = startDate.AddDate(0, 1, 0)
}
result := map[string]interface{}{
"total": total,
"group": group,
}
controller.Success(c, result)
}
type PageBodySchedRule struct {
PageInfo *request.PageInfo `json:"pageInfo" binding:"required"`
Keyword string `json:"keyword"`
Status string `json:"status"`
}
// 分页获取规则
func PageSchedRules(c *gin.Context) {
var pageBody PageBodySchedRule
err := c.ShouldBindJSON(&pageBody)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
rule := &sc.SchedRule{}
fields := map[string]interface{}{}
fields["keyword"] = pageBody.Keyword
if pageBody.Status != "" {
fields["rule_status"] = pageBody.Status
}
page := &model.Page[sc.SchedRule]{}
page.Covert(pageBody.PageInfo)
err = rule.Page(page, fields)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "内部错误!")
return
}
controller.Success(c, page)
}
type DeleteBodySchedRule struct {
Ids []int64 `json:"ids" binding:"required"`
}
// 批量删除规则
func DeleteSchedRules(c *gin.Context) {
var deleteBody DeleteBodySchedRule
err := c.ShouldBindJSON(&deleteBody)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
rule := &sc.SchedRule{}
_, err = rule.DeleteBatch(deleteBody.Ids)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "删除失败!")
return
}
controller.Success(c, "删除成功!")
}
// 停用启用操作
func DoSchedRule(c *gin.Context) {
rule := &sc.SchedRule{}
id := c.Param("id")
option := c.Param("option")
fields := map[string]interface{}{}
fields["id"] = id
result, err := rule.Get(fields)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
if option == "0" {
//todo 开启任务
} else if option == "1" {
//todo 停止任务
} else {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
result.RuleStatus = option
result.Update(nil)
controller.Success(c, "执行成功!")
}
type PageBodySchedTask struct {
PageInfo *request.PageInfo `json:"pageInfo" binding:"required"`
ListBodySchedTask
}
type ListBodySchedTask struct {
TaskName string `json:"taskName"`
TaskStatus string `json:"taskStatus"`
StartTime *time.Time `json:"startTime"`
EndTime *time.Time `json:"endTime"`
}
// 分页获取规则
func PageSchedTasks(c *gin.Context) {
var pageBody PageBodySchedTask
err := c.ShouldBindJSON(&pageBody)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
task := &sc.SchedTask{}
fields := map[string]interface{}{}
fields["task_name"] = pageBody.TaskName
if pageBody.TaskStatus != "" {
fields["task_status"] = pageBody.TaskStatus
}
if pageBody.StartTime == nil {
fields["start_time"] = time.Now().Add(-30 * 24 * time.Hour)
} else {
fields["start_time"] = pageBody.StartTime
}
if pageBody.EndTime == nil {
fields["end_time"] = time.Now()
} else {
fields["end_time"] = pageBody.EndTime
}
page := &model.Page[sc.SchedTask]{}
page.Covert(pageBody.PageInfo)
err = task.Page(page, fields)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "内部错误!")
return
}
controller.Success(c, page)
}
// 分页获取规则
func ExportSchedTasks(c *gin.Context) {
var listBody ListBodySchedTask
err := c.ShouldBindJSON(&listBody)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
task := &sc.SchedTask{}
fields := map[string]interface{}{}
fields["task_name"] = listBody.TaskName
if listBody.TaskStatus != "" {
fields["task_status"] = listBody.TaskStatus
}
fields["start_time"] = listBody.StartTime
fields["end_time"] = listBody.EndTime
tasks, err := task.ListAll(fields)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "未找到记录!")
return
}
rows := [][]interface{}{}
for _, t := range tasks {
row := []interface{}{
t.TaskName, t.Id, t.StartTime, t.EndTime, tk.TriggerTypeMap[t.TriggerType], "", tk.TaskStatusMap[t.TaskStatus],
}
rows = append(rows, row)
}
header := []string{"任务名称", "任务编号", "开始时间", "结束时间", "触发方式", "触发事件", "状态"}
f, err := excel.ExportExcel("调度任务", header, rows)
if err != nil {
controller.FailCode(c, errors.ServerError, err, "生成excel文件失败")
return
}
f.SetColWidth("调度任务", "A", "A", 40)
f.SetColWidth("调度任务", "C", "D", 15)
f.SetColWidth("调度任务", "F", "F", 40)
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
if err := f.SaveAs("/tmp/task.xlsx"); err != nil {
fmt.Println(err)
controller.FailCode(c, errors.ServerError, err, "生成下载文件失败!")
return
}
c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Disposition", "attachment; filename=task.xlsx")
c.Header("Content-Transfer-Encoding", "binary")
c.File("/tmp/task.xlsx")
return
}
// 根据ID获取调度任务
func GetSchedTask(c *gin.Context) {
task := &sc.SchedTask{}
id := c.Param("id")
fields := map[string]interface{}{}
fields["id"] = id
result, err := task.Get(fields)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
controller.Success(c, result)
}
// 根据EventId获取调度任务
func GetSchedTaskByEvent(c *gin.Context) {
task := &sc.SchedTask{}
eventId := c.Param("eventId")
fields := map[string]interface{}{}
fields["event_id"] = eventId
result, err := task.Get(fields)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
controller.Success(c, result)
}
type TriggerTaskBody struct {
PlanId string `json:"planId" validate:"required"`
HandleAdvice string `json:"handleAdvice"`
// 资源Id
ResourceID string `json:"resourceId"`
// 资源名称(cpCode)
ResourceName string `json:"resourceName"`
// 资源节点
ResourceNode string `json:"resourceNode"`
// 资源类型
ResourceType string `json:"resourceType"`
// 方案参数
SchemeParams string `json:"schemeParams"`
}
// 手动触发调度任务
func TriggerSchedTask_UserManual(c *gin.Context) {
var body TriggerTaskBody
err := c.ShouldBindJSON(&body)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
// 暂不入库
record := event.EventRecord{
ResourceType: body.ResourceType,
ResourceNode: body.ResourceNode,
ResourceName: body.ResourceName,
ResourceId: body.ResourceID,
Id: id.NewEventRecord(),
}
task := &sc.SchedTask{}
t := time.Now()
sno := fmt.Sprintf("%d-%d%d-%s", t.Year(), t.Month(), t.Day(), record.Id)
task.Id = record.ResourceType + "-" + sno
task.TaskName = ""
task.EventId = record.Id
task.StartTime = time.Now()
task.PlanId = body.PlanId
task.CreateTime = time.Now()
task.HandleAdvice = body.HandleAdvice
task.HandleTime = time.Now()
err = schedule_engine.PlanHandle(task.PlanId, task.Id, body.SchemeParams, record)
if err != nil {
//log.Errorf("%v", err)
controller.FailCode(c, errors.ServerError, err, "调度方案失败!")
return
}
task.TaskStatus = sc.TASK_STATUS_ING
task.TriggerType = sc.TRIGGER_TYPE_MANUAL
_, err = task.Create()
if err != nil {
log.Errorf("生成调度任务失败:%v事件ID:%s", err, record.Id)
controller.FailCode(c, errors.ServerError, err, "生成调度任务失败!")
return
}
controller.Success(c, "")
}
// 手动触发调度任务
func TriggerSchedTask(c *gin.Context) {
eventId := c.Param("eventId")
event := &event.EventRecord{}
eventFields := map[string]interface{}{}
eventFields["id"] = eventId
record, err := event.Get(eventFields)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
var body TriggerTaskBody
err = c.ShouldBindJSON(&body)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
task := &sc.SchedTask{}
fields := map[string]interface{}{}
fields["event_id"] = eventId
taskRecord, err := task.Get(fields)
if ur, bl := c.Get(middleware.LoginUserKey); bl {
if u, b := ur.(*user.User); b {
task.HandleUsername = u.Name
taskRecord.HandleUsername = u.Name
}
}
if err != nil {
t := time.Now()
sno := fmt.Sprintf("%d-%d%d-%s", t.Year(), t.Month(), t.Day(), eventId)
task.Id = record.ResourceType + "-" + sno
task.TaskName = ""
task.EventId = eventId
task.StartTime = time.Now()
task.PlanId = body.PlanId
task.CreateTime = time.Now()
task.HandleAdvice = body.HandleAdvice
task.HandleTime = time.Now()
err = schedule_engine.PlanHandle(task.PlanId, task.Id, "", record)
if err != nil {
log.Errorf("%v", err)
controller.FailCode(c, errors.ServerError, err, "调度方案失败!")
return
}
task.TaskStatus = sc.TASK_STATUS_ING
task.TriggerType = sc.TRIGGER_TYPE_MANUAL
_, err = task.Create()
if err != nil {
log.Errorf("生成调度任务失败:%v事件ID:%s", err, eventId)
controller.FailCode(c, errors.ServerError, err, "生成调度任务失败!")
return
}
} else {
taskRecord.TriggerType = sc.TRIGGER_TYPE_MANUAL
taskRecord.StartTime = time.Now()
taskRecord.EventId = eventId
taskRecord.PlanId = body.PlanId
taskRecord.HandleAdvice = body.HandleAdvice
taskRecord.HandleTime = time.Now()
err = schedule_engine.PlanHandle(taskRecord.PlanId, taskRecord.Id, "", record)
if err != nil {
log.Errorf("%v", err)
controller.FailCode(c, errors.ServerError, err, "调度失败!")
return
}
taskRecord.TaskStatus = sc.TASK_STATUS_ING
_, err = taskRecord.Update(nil)
if err != nil {
log.Errorf("生成调度任务失败:%v事件ID:%s", err, eventId)
controller.FailCode(c, errors.ServerError, err, "生成调度任务失败!")
return
}
}
controller.Success(c, "")
}
type TaskCallBackBody struct {
Status string `json:"status" validate:"required"` // 1:成功2:失败
EndTime int64 `json:"endTime"` //秒级时间戳
}
// 调度任务回调
func TaskCallBack(c *gin.Context) {
taskId := c.Param("taskId")
var body TaskCallBackBody
err := c.ShouldBindJSON(&body)
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
task := &sc.SchedTask{}
fields := map[string]interface{}{}
fields["id"] = taskId
taskRecord, err := task.Get(fields)
if err != nil {
log.Errorf("回调任务失败:%v", err)
controller.FailCode(c, errors.InvalidParameter, err, "未找到调度任务,请检查参数!")
return
}
taskRecord.TaskStatus = body.Status
if body.EndTime <= 0 {
taskRecord.EndTime = time.Now()
} else {
taskRecord.EndTime = time.Unix(body.EndTime, 22)
}
_, err = taskRecord.Update(nil)
// todo 将事件更新至事件历史表(一删一增)
if err != nil {
log.Errorf("更新回调任务失败:%v", err)
controller.FailCode(c, errors.ServerError, err, "内部错误!")
return
}
go func() {
evt := &event.EventRecord{}
f := map[string]interface{}{}
f["id"] = taskRecord.EventId
e, err := evt.Get(f)
if err == nil {
eh := &event.HistoryEventRecord{
Id: e.Id,
EventName: e.EventName,
EventKey: e.EventKey,
Level: e.Level,
ResourceId: e.ResourceId,
ResourceName: e.ResourceName,
ResourceType: e.ResourceType,
ResourceNode: e.ResourceNode,
EventTime: e.EventTime,
EventInfo: e.EventInfo,
OperatorUser: taskRecord.HandleUsername,
OperatorFinishTime: taskRecord.EndTime,
CreateTime: time.Now(),
}
rows, _ := eh.SaveOrUpdate()
if rows > 0 {
e.Delete()
}
}
}()
controller.Success(c, "回调成功")
}
// 任务状态数统计
func CountTaskStatus(c *gin.Context) {
task := &sc.SchedTask{}
result, err := task.CountStatusNum()
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "请检查参数!")
return
}
controller.Success(c, result)
}
// 调度任务自动化率
func AutoRatio(c *gin.Context) {
task := &sc.SchedTask{}
result, err := task.AutoRatio()
if err != nil {
controller.FailCode(c, errors.InvalidParameter, err, "数据库异常!")
return
}
controller.Success(c, result)
}