550 lines
15 KiB
Go
550 lines
15 KiB
Go
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)
|
||
}
|