Files
ppgo_job/jobs/job.go

827 lines
20 KiB
Go
Raw Normal View History

2017-06-23 12:24:42 +08:00
/*
* @Author: haodaquan
* @Date: 2017-06-21 12:56:08
* @Last Modified by: Bee
* @Last Modified time: 2019-02-17 22:10:15
2017-06-23 12:24:42 +08:00
*/
package jobs
import (
"bytes"
2019-07-03 22:31:27 +08:00
"errors"
2017-06-23 12:24:42 +08:00
"fmt"
2019-07-03 22:31:27 +08:00
"github.com/astaxie/beego/logs"
"github.com/george518/PPGo_Job/libs"
"github.com/george518/PPGo_Job/models"
2017-08-29 15:30:55 +08:00
"io/ioutil"
"net"
2019-07-03 22:31:27 +08:00
"net/rpc"
"net/rpc/jsonrpc"
2017-06-23 12:24:42 +08:00
"os/exec"
"runtime/debug"
2019-07-03 22:31:27 +08:00
"sync"
2017-06-23 12:24:42 +08:00
"time"
2017-08-29 15:30:55 +08:00
2018-08-15 00:05:37 +08:00
"runtime"
"strconv"
"strings"
"encoding/json"
2017-08-29 15:30:55 +08:00
"github.com/astaxie/beego"
"github.com/george518/PPGo_Job/notify"
2019-02-18 02:35:22 +08:00
"github.com/linxiaozhi/go-telnet"
"golang.org/x/crypto/ssh"
2017-06-23 12:24:42 +08:00
)
type Job struct {
2019-07-03 22:31:27 +08:00
JobKey int // jobId = id*10000+serverId
Id int // taskID
LogId int64 // 日志记录ID
ServerId int // 执行器信息
ServerName string // 执行器名称
ServerType int // 执行器类型2-agent 1-telnet 0-ssh
Name string // 任务名称
Task *models.Task // 任务对象
RunFunc func(time.Duration) *JobResult // 执行函数
Status int // 任务状态大于0表示正在执行中
Concurrent bool // 同一个任务是否允许并行执行
}
type JobResult struct {
OutMsg string
ErrMsg string
IsOk bool
IsTimeout bool
}
//调度计数器
var Counter sync.Map
func GetCounter(key string) int {
if v, ok := Counter.LoadOrStore(key, 0); ok {
n := v.(int)
return n
}
return 0
}
func SetCounter(key string) {
if v, ok := Counter.Load(key); ok {
n := v.(int)
m := n + 1
if n > 1000 {
m = 0
}
Counter.Store(key, m)
}
2017-06-23 12:24:42 +08:00
}
func NewJobFromTask(task *models.Task) ([]*Job, error) {
2017-06-23 12:24:42 +08:00
if task.Id < 1 {
return nil, fmt.Errorf("ToJob: 缺少id")
}
2018-07-13 17:53:34 +08:00
if task.ServerIds == "" {
return nil, fmt.Errorf("任务执行失败,找不到执行的服务器")
}
TaskServerIdsArr := strings.Split(task.ServerIds, ",")
jobArr := make([]*Job, 0)
for _, server_id := range TaskServerIdsArr {
if server_id == "0" {
//本地执行
job := NewCommandJob(task.Id, 0, task.TaskName, task.Command)
2019-07-03 22:31:27 +08:00
job.Task = task
job.Concurrent = false
if task.Concurrent == 1 {
job.Concurrent = true
}
//job.Concurrent = task.Concurrent == 1
job.ServerId = 0
job.ServerName = "本地服务器"
jobArr = append(jobArr, job)
} else {
server_id_int, _ := strconv.Atoi(server_id)
//远程执行
server, _ := models.TaskServerGetById(server_id_int)
2019-07-03 22:31:27 +08:00
if server.Status == 2 {
fmt.Println("服务器已禁用")
continue
}
if server.ConnectionType == 0 {
if server.Type == 0 {
//密码验证登录服务器
job := RemoteCommandJobByPassword(task.Id, server_id_int, task.TaskName, task.Command, server)
2019-07-03 22:31:27 +08:00
job.Task = task
job.Concurrent = false
if task.Concurrent == 1 {
job.Concurrent = true
}
//job.Concurrent = task.Concurrent == 1
job.ServerId = server_id_int
job.ServerName = server.ServerName
jobArr = append(jobArr, job)
} else {
job := RemoteCommandJob(task.Id, server_id_int, task.TaskName, task.Command, server)
2019-07-03 22:31:27 +08:00
job.Task = task
job.Concurrent = false
if task.Concurrent == 1 {
job.Concurrent = true
}
//job.Concurrent = task.Concurrent == 1
job.ServerId = server_id_int
job.ServerName = server.ServerName
jobArr = append(jobArr, job)
}
} else if server.ConnectionType == 1 {
if server.Type == 0 {
//密码验证登录服务器
job := RemoteCommandJobByTelnetPassword(task.Id, server_id_int, task.TaskName, task.Command, server)
2019-07-03 22:31:27 +08:00
job.Task = task
job.Concurrent = false
if task.Concurrent == 1 {
job.Concurrent = true
}
//job.Concurrent = task.Concurrent == 1
job.ServerId = server_id_int
job.ServerName = server.ServerName
jobArr = append(jobArr, job)
}
2019-07-03 22:31:27 +08:00
} else if server.ConnectionType == 2 {
//密码验证登录服务器
job := RemoteCommandJobByAgentPassword(task.Id, server_id_int, task.TaskName, task.Command, server)
job.Task = task
job.Concurrent = false
if task.Concurrent == 1 {
job.Concurrent = true
}
//job.Concurrent = task.Concurrent == 1
job.ServerId = server_id_int
job.ServerName = server.ServerName
jobArr = append(jobArr, job)
}
}
}
return jobArr, nil
2017-06-23 12:24:42 +08:00
}
func NewCommandJob(id int, serverId int, name string, command string) *Job {
2017-06-23 12:24:42 +08:00
job := &Job{
2019-07-03 22:31:27 +08:00
Id: id,
Name: name,
2017-06-23 12:24:42 +08:00
}
2019-07-03 22:31:27 +08:00
job.JobKey = libs.JobKey(id, serverId)
job.RunFunc = func(timeout time.Duration) (jobresult *JobResult) {
2017-06-23 12:24:42 +08:00
bufOut := new(bytes.Buffer)
bufErr := new(bytes.Buffer)
//cmd := exec.Command("/bin/bash", "-c", command)
2018-08-15 00:05:37 +08:00
var cmd *exec.Cmd
if runtime.GOOS == "windows" {
cmd = exec.Command("CMD", "/C", command)
2018-08-15 10:22:07 +08:00
} else {
cmd = exec.Command("sh", "-c", command)
2018-08-15 00:05:37 +08:00
}
2017-06-23 12:24:42 +08:00
cmd.Stdout = bufOut
cmd.Stderr = bufErr
cmd.Start()
err, isTimeout := runCmdWithTimeout(cmd, timeout)
2019-07-03 22:31:27 +08:00
jobresult = new(JobResult)
2019-07-06 17:05:19 +08:00
jobresult.OutMsg = bufOut.String()
jobresult.ErrMsg = bufErr.String()
2019-07-03 22:31:27 +08:00
jobresult.IsOk = true
if err != nil {
jobresult.IsOk = false
}
2017-06-23 12:24:42 +08:00
2019-07-03 22:31:27 +08:00
jobresult.IsTimeout = isTimeout
return jobresult
2017-06-23 12:24:42 +08:00
}
return job
}
2017-08-29 15:30:55 +08:00
//远程执行任务 密钥验证
func RemoteCommandJob(id int, serverId int, name string, command string, servers *models.TaskServer) *Job {
job := &Job{
2019-07-03 22:31:27 +08:00
Id: id,
Name: name,
ServerId: serverId,
}
2019-07-03 22:31:27 +08:00
job.JobKey = libs.JobKey(id, serverId)
2019-07-03 22:31:27 +08:00
job.RunFunc = func(timeout time.Duration) (jobresult *JobResult) {
jobresult = new(JobResult)
jobresult.OutMsg = ""
jobresult.ErrMsg = ""
jobresult.IsTimeout = false
key, err := ioutil.ReadFile(servers.PrivateKeySrc)
if err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
// Create the Signer for this private key.
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
addr := fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port)
config := &ssh.ClientConfig{
User: servers.ServerAccount,
Auth: []ssh.AuthMethod{
// Use the PublicKeys method for remote authentication.
ssh.PublicKeys(signer),
},
//HostKeyCallback: ssh.FixedHostKey(hostKey),
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
// Connect to the remote server and perform the SSH handshake.47.93.220.5
client, err := ssh.Dial("tcp", addr, config)
if err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
2018-05-09 15:44:32 +08:00
defer client.Close()
session, err := client.NewSession()
if err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
defer session.Close()
// Once a Session is created, you can execute a single command on
// the remote side using the Run method.
var b bytes.Buffer
var c bytes.Buffer
session.Stdout = &b
session.Stderr = &c
//session.Output(command)
if err := session.Run(command); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
2019-07-03 22:31:27 +08:00
jobresult.OutMsg = b.String()
jobresult.ErrMsg = c.String()
jobresult.IsOk = true
jobresult.IsTimeout = false
return
}
return job
}
func RemoteCommandJobByPassword(id int, serverId int, name string, command string, servers *models.TaskServer) *Job {
var (
auth []ssh.AuthMethod
addr string
clientConfig *ssh.ClientConfig
client *ssh.Client
session *ssh.Session
err error
)
job := &Job{
2019-07-03 22:31:27 +08:00
Id: id,
Name: name,
ServerId: serverId,
ServerType: servers.ConnectionType,
}
2019-07-03 22:31:27 +08:00
job.JobKey = libs.JobKey(id, serverId)
job.RunFunc = func(timeout time.Duration) (jobresult *JobResult) {
jobresult = new(JobResult)
jobresult.OutMsg = ""
jobresult.ErrMsg = ""
jobresult.IsTimeout = false
// get auth method
auth = make([]ssh.AuthMethod, 0)
auth = append(auth, ssh.Password(servers.Password))
clientConfig = &ssh.ClientConfig{
User: servers.ServerAccount,
Auth: auth,
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
//Timeout: 1000 * time.Second,
}
// connet to ssh
addr = fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port)
if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
2018-05-09 15:44:32 +08:00
defer client.Close()
// create session
if session, err = client.NewSession(); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
var b bytes.Buffer
var c bytes.Buffer
session.Stdout = &b
session.Stderr = &c
//session.Output(command)
if err := session.Run(command); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
2019-07-03 22:31:27 +08:00
jobresult.OutMsg = b.String()
jobresult.ErrMsg = c.String()
jobresult.IsOk = true
jobresult.IsTimeout = false
return
}
return job
}
func RemoteCommandJobByTelnetPassword(id int, serverId int, name string, command string, servers *models.TaskServer) *Job {
job := &Job{
2019-07-03 22:31:27 +08:00
Id: id,
Name: name,
ServerId: serverId,
}
2019-07-03 22:31:27 +08:00
job.JobKey = libs.JobKey(id, serverId)
job.RunFunc = func(timeout time.Duration) (jobresult *JobResult) {
jobresult = new(JobResult)
jobresult.OutMsg = ""
jobresult.ErrMsg = ""
jobresult.IsTimeout = false
addr := fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port)
2019-02-18 02:35:22 +08:00
conn, err := gote.DialTimeout("tcp", addr, timeout)
if err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
2019-02-18 02:50:12 +08:00
defer conn.Close()
buf := make([]byte, 4096)
if _, err = conn.Read(buf); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
if _, err = conn.Write([]byte(servers.ServerAccount + "\r\n")); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
if _, err = conn.Read(buf); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
if _, err = conn.Write([]byte(servers.Password + "\r\n")); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
if _, err = conn.Read(buf); err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
2019-07-03 22:31:27 +08:00
loginStr := libs.GbkAsUtf8(string(buf[:]))
if !strings.Contains(loginStr, ">") {
2019-07-03 22:31:27 +08:00
jobresult.ErrMsg = jobresult.ErrMsg + "Login failed!"
jobresult.IsOk = false
return
}
commandArr := strings.Split(command, "\n")
2019-02-18 14:41:06 +08:00
out, n := "", 0
for _, c := range commandArr {
_, err = conn.Write([]byte(c + "\r\n"))
if err != nil {
2019-07-03 22:31:27 +08:00
jobresult.IsOk = false
return
}
2019-02-18 14:41:06 +08:00
n, err = conn.Read(buf)
2019-07-03 22:31:27 +08:00
out = out + libs.GbkAsUtf8(string(buf[0:n]))
if err != nil ||
strings.Contains(out, "'"+c+"' is not recognized as an internal or external command") ||
strings.Contains(out, "'"+c+"' 不是内部或外部命令,也不是可运行的程序") {
2019-07-03 22:31:27 +08:00
jobresult.ErrMsg = jobresult.ErrMsg + " " + libs.GbkAsUtf8(string(buf[0:n]))
jobresult.IsOk = false
jobresult.OutMsg = out
return
}
}
2019-07-03 22:31:27 +08:00
jobresult.IsOk = true
jobresult.OutMsg = out
return
}
return job
}
func RemoteCommandJobByAgentPassword(id int, serverId int, name string, command string, servers *models.TaskServer) *Job {
2019-07-03 22:31:27 +08:00
job := &Job{
Id: id,
Name: name,
ServerType: servers.ConnectionType,
}
2019-07-03 22:31:27 +08:00
job.JobKey = libs.JobKey(id, serverId)
job.RunFunc = func(timeout time.Duration) *JobResult {
return new(JobResult)
}
return job
2019-07-03 22:31:27 +08:00
}
2019-07-03 22:31:27 +08:00
func (j *Job) GetStatus() int {
return j.Status
2017-06-23 12:24:42 +08:00
}
func (j *Job) GetName() string {
2019-07-03 22:31:27 +08:00
return j.Name
2017-06-23 12:24:42 +08:00
}
func (j *Job) GetId() int {
2019-07-03 22:31:27 +08:00
return j.Id
2017-06-23 12:24:42 +08:00
}
func (j *Job) GetLogId() int64 {
2019-07-03 22:31:27 +08:00
return j.LogId
}
type RpcResult struct {
Status int
Message string
}
func (j *Job) agentRun() (reply *JobResult) {
server, _ := models.TaskServerGetById(j.ServerId)
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", server.ServerIp, server.Port))
reply = new(JobResult)
if err != nil {
logs.Error("Net error:", err)
reply.IsOk = false
reply.ErrMsg = "Net error:" + err.Error()
reply.IsTimeout = false
reply.OutMsg = ""
return reply
}
defer conn.Close()
client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
defer client.Close()
reply = new(JobResult)
task := j.Task
err = client.Call("RpcTask.RunTask", task, &reply)
if err != nil {
reply.IsOk = false
reply.ErrMsg = "Net error:" + err.Error()
reply.IsTimeout = false
reply.OutMsg = ""
return reply
}
return
}
func TestServer(server *models.TaskServer) error {
if server.ConnectionType == 0 {
switch server.Type {
case 0:
//密码登录
return libs.RemoteCommandByPassword(server)
case 1:
//密钥登录
return libs.RemoteCommandByKey(server)
default:
return errors.New("未知的登录方式")
}
} else if server.ConnectionType == 1 {
if server.Type == 0 {
//密码登录]
return libs.RemoteCommandByTelnetPassword(server)
} else {
return errors.New("Telnet方式暂不支持密钥登陆")
}
} else if server.ConnectionType == 2 {
return libs.RemoteAgent(server)
}
return errors.New("未知错误")
}
func PollServer(j *Job) bool {
//判断是否是当前执行器执行
TaskServerIdsArr := strings.Split(j.Task.ServerIds, ",")
num := len(TaskServerIdsArr)
if num == 0 {
return false
}
count := GetCounter(strconv.Itoa(j.Task.Id))
index := count % num
pollServerId, _ := strconv.Atoi(TaskServerIdsArr[index])
if j.ServerId != pollServerId {
return false
}
//本地服务器
if pollServerId == 0 {
return true
}
//判断执行器或者服务器是否存活
server, _ := models.TaskServerGetById(pollServerId)
if server.Status != 0 {
return false
}
if err := TestServer(server); err != nil {
server.Status = 1
server.Update()
return false
2019-08-13 23:20:17 +08:00
} else {
server.Status = 0
server.Update()
2019-07-03 22:31:27 +08:00
}
return true
2017-06-23 12:24:42 +08:00
}
func (j *Job) Run() {
2019-07-03 22:31:27 +08:00
//执行策略 轮询
if j.Task.ServerType == 1 {
if !PollServer(j) {
return
} else {
SetCounter(strconv.Itoa(j.Task.Id))
}
}
if !j.Concurrent && j.Status > 0 {
beego.Warn(fmt.Sprintf("任务[%d]上一次执行尚未结束,本次被忽略。", j.JobKey))
2017-06-23 12:24:42 +08:00
return
}
defer func() {
if err := recover(); err != nil {
beego.Error(err, "\n", string(debug.Stack()))
}
}()
if workPool != nil {
workPool <- true
defer func() {
<-workPool
}()
}
2019-07-03 22:31:27 +08:00
beego.Debug(fmt.Sprintf("开始执行任务: %d", j.JobKey))
2017-06-23 12:24:42 +08:00
2019-07-03 22:31:27 +08:00
j.Status++
2017-06-23 12:24:42 +08:00
defer func() {
2019-07-03 22:31:27 +08:00
j.Status--
2017-06-23 12:24:42 +08:00
}()
t := time.Now()
timeout := time.Duration(time.Hour * 24)
2019-07-03 22:31:27 +08:00
if j.Task.Timeout > 0 {
timeout = time.Second * time.Duration(j.Task.Timeout)
2017-06-23 12:24:42 +08:00
}
2019-07-03 22:31:27 +08:00
var jobResult = new(JobResult)
//anget
if j.ServerType == 2 {
jobResult = j.agentRun()
} else {
jobResult = j.RunFunc(timeout)
}
2017-06-23 12:24:42 +08:00
ut := time.Now().Sub(t) / time.Millisecond
// 插入日志
log := new(models.TaskLog)
2019-07-03 22:31:27 +08:00
log.TaskId = j.Id
log.ServerId = j.ServerId
log.ServerName = j.ServerName
log.Output = jobResult.OutMsg
log.Error = jobResult.ErrMsg
2017-06-23 12:24:42 +08:00
log.ProcessTime = int(ut)
log.CreateTime = t.Unix()
2019-07-03 22:31:27 +08:00
if jobResult.IsTimeout {
2017-06-23 12:24:42 +08:00
log.Status = models.TASK_TIMEOUT
2019-07-03 22:31:27 +08:00
log.Error = fmt.Sprintf("任务执行超过 %d 秒\n----------------------\n%s\n", int(timeout/time.Second), jobResult.ErrMsg)
} else if !jobResult.IsOk {
2017-06-23 12:24:42 +08:00
log.Status = models.TASK_ERROR
2019-07-03 22:31:27 +08:00
log.Error = "ERROR:" + jobResult.ErrMsg
2017-06-23 12:24:42 +08:00
}
2019-07-03 22:31:27 +08:00
if log.Status < 0 && j.Task.IsNotify == 1 {
if j.Task.NotifyUserIds != "0" && j.Task.NotifyUserIds != "" {
adminInfo := AllAdminInfo(j.Task.NotifyUserIds)
phone := make(map[string]string, 0)
dingtalk := make(map[string]string, 0)
wechat := make(map[string]string, 0)
toEmail := ""
2018-08-09 18:47:42 +08:00
for _, v := range adminInfo {
if v.Phone != "0" && v.Phone != "" {
phone[v.Phone] = v.Phone
}
if v.Email != "0" && v.Email != "" {
toEmail += v.Email + ";"
}
2019-02-15 11:50:09 +08:00
if v.Dingtalk != "0" && v.Dingtalk != "" {
dingtalk[v.Dingtalk] = v.Dingtalk
2019-02-15 11:50:09 +08:00
}
if v.Wechat != "0" && v.Wechat != "" {
wechat[v.Wechat] = v.Wechat
}
}
toEmail = strings.TrimRight(toEmail, ";")
TextStatus := []string{
2019-02-16 20:43:33 +08:00
"超时",
"错误",
"正常",
}
status := log.Status + 2
title, content, taskOutput, errOutput := "", "", "", ""
2019-07-03 22:31:27 +08:00
notifyTpl, err := models.NotifyTplGetById(j.Task.NotifyTplId)
if err != nil {
2019-07-03 22:31:27 +08:00
notifyTpl, err := models.NotifyTplGetByTplType(j.Task.NotifyType, models.NotifyTplTypeSystem)
if err == nil {
title = notifyTpl.Title
content = notifyTpl.Content
}
} else {
2019-02-16 20:43:33 +08:00
title = notifyTpl.Title
content = notifyTpl.Content
}
taskOutput = strings.Replace(log.Output, "\n", " ", -1)
taskOutput = strings.Replace(taskOutput, "\"", "\\\"", -1)
errOutput = strings.Replace(log.Error, "\n", " ", -1)
errOutput = strings.Replace(errOutput, "\"", "\\\"", -1)
2019-02-16 20:43:33 +08:00
if title != "" {
2019-07-03 22:31:27 +08:00
title = strings.Replace(title, "{{TaskId}}", strconv.Itoa(j.Task.Id), -1)
title = strings.Replace(title, "{{ServerId}}", strconv.Itoa(j.ServerId), -1)
title = strings.Replace(title, "{{TaskName}}", j.Task.TaskName, -1)
title = strings.Replace(title, "{{ExecuteCommand}}", j.Task.Command, -1)
title = strings.Replace(title, "{{ExecuteTime}}", beego.Date(time.Unix(log.CreateTime, 0), "Y-m-d H:i:s"), -1)
title = strings.Replace(title, "{{ProcessTime}}", strconv.FormatFloat(float64(log.ProcessTime)/1000, 'f', 6, 64), -1)
title = strings.Replace(title, "{{ExecuteStatus}}", TextStatus[status], -1)
title = strings.Replace(title, "{{TaskOutput}}", taskOutput, -1)
title = strings.Replace(title, "{{ErrorOutput}}", errOutput, -1)
2019-02-16 20:43:33 +08:00
}
if content != "" {
2019-07-03 22:31:27 +08:00
content = strings.Replace(content, "{{TaskId}}", strconv.Itoa(j.Task.Id), -1)
content = strings.Replace(content, "{{ServerId}}", strconv.Itoa(j.ServerId), -1)
content = strings.Replace(content, "{{TaskName}}", j.Task.TaskName, -1)
content = strings.Replace(content, "{{ExecuteCommand}}", j.Task.Command, -1)
content = strings.Replace(content, "{{ExecuteTime}}", beego.Date(time.Unix(log.CreateTime, 0), "Y-m-d H:i:s"), -1)
content = strings.Replace(content, "{{ProcessTime}}", strconv.FormatFloat(float64(log.ProcessTime)/1000, 'f', 6, 64), -1)
content = strings.Replace(content, "{{ExecuteStatus}}", TextStatus[status], -1)
content = strings.Replace(content, "{{TaskOutput}}", taskOutput, -1)
content = strings.Replace(content, "{{ErrorOutput}}", errOutput, -1)
2019-02-16 20:43:33 +08:00
}
2019-07-03 22:31:27 +08:00
if j.Task.NotifyType == 0 && toEmail != "" {
//邮件
mailtype := "html"
2019-02-16 20:43:33 +08:00
ok := notify.SendToChan(toEmail, title, content, mailtype)
if !ok {
fmt.Println("发送邮件错误", toEmail)
}
2019-07-03 22:31:27 +08:00
} else if j.Task.NotifyType == 1 && len(phone) > 0 {
//信息
2018-08-09 18:47:42 +08:00
param := make(map[string]string)
2019-02-16 20:43:33 +08:00
err := json.Unmarshal([]byte(content), &param)
if err != nil {
fmt.Println("发送信息错误", err)
2019-02-16 23:04:47 +08:00
return
2019-02-15 11:57:08 +08:00
}
2019-02-15 11:50:09 +08:00
ok := notify.SendSmsToChan(phone, param)
if !ok {
fmt.Println("发送信息错误", phone)
}
2019-07-03 22:31:27 +08:00
} else if j.Task.NotifyType == 2 && len(dingtalk) > 0 {
2019-02-16 20:43:33 +08:00
//钉钉
param := make(map[string]interface{})
err := json.Unmarshal([]byte(content), &param)
if err != nil {
fmt.Println("发送钉钉错误", err)
return
}
ok := notify.SendDingtalkToChan(dingtalk, param)
if !ok {
fmt.Println("发送钉钉错误", dingtalk)
}
2019-07-03 22:31:27 +08:00
} else if j.Task.NotifyType == 3 && len(wechat) > 0 {
//微信
param := make(map[string]string)
err := json.Unmarshal([]byte(content), &param)
if err != nil {
fmt.Println("发送微信错误", err)
return
}
ok := notify.SendWechatToChan(phone, param)
if !ok {
fmt.Println("发送微信错误", phone)
}
}
}
}
2019-07-03 22:31:27 +08:00
j.LogId, _ = models.TaskLogAdd(log)
2017-06-23 12:24:42 +08:00
// 更新上次执行时间
2019-07-03 22:31:27 +08:00
j.Task.PrevTime = t.Unix()
j.Task.ExecuteTimes++
j.Task.Update("PrevTime", "ExecuteTimes")
2017-06-23 12:24:42 +08:00
}
//冗余代码
type adminInfo struct {
Id int
Email string
Phone string
2019-02-15 11:50:09 +08:00
Dingtalk string
Wechat string
RealName string
}
func AllAdminInfo(adminIds string) []*adminInfo {
Filters := make([]interface{}, 0)
Filters = append(Filters, "status", 1)
//Filters = append(Filters, "id__gt", 1)
var notifyUserIds []int
if adminIds != "0" && adminIds != "" {
notifyUserIdsStr := strings.Split(adminIds, ",")
for _, v := range notifyUserIdsStr {
i, _ := strconv.Atoi(v)
notifyUserIds = append(notifyUserIds, i)
}
Filters = append(Filters, "id__in", notifyUserIds)
}
Result, _ := models.AdminGetList(1, 1000, Filters...)
adminInfos := make([]*adminInfo, 0)
for _, v := range Result {
ai := adminInfo{
Id: v.Id,
Email: v.Email,
Phone: v.Phone,
2019-02-15 11:50:09 +08:00
Dingtalk: v.Dingtalk,
Wechat: v.Wechat,
RealName: v.RealName,
}
adminInfos = append(adminInfos, &ai)
}
return adminInfos
}