2017-06-23 12:24:42 +08:00
|
|
|
|
/*
|
|
|
|
|
|
* @Author: haodaquan
|
|
|
|
|
|
* @Date: 2017-06-21 12:56:08
|
2019-02-18 00:03:35 +08:00
|
|
|
|
* @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"
|
|
|
|
|
|
"fmt"
|
2017-08-29 15:30:55 +08:00
|
|
|
|
"io/ioutil"
|
|
|
|
|
|
"net"
|
2017-06-23 12:24:42 +08:00
|
|
|
|
"os/exec"
|
|
|
|
|
|
"runtime/debug"
|
|
|
|
|
|
"time"
|
2017-08-29 15:30:55 +08:00
|
|
|
|
|
2018-08-15 00:05:37 +08:00
|
|
|
|
"runtime"
|
|
|
|
|
|
"strconv"
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
2017-08-29 15:30:55 +08:00
|
|
|
|
"github.com/astaxie/beego"
|
|
|
|
|
|
"github.com/george518/PPGo_Job/models"
|
2018-08-09 11:34:46 +08:00
|
|
|
|
"github.com/george518/PPGo_Job/notify"
|
2017-08-17 11:49:53 +08:00
|
|
|
|
"golang.org/x/crypto/ssh"
|
2019-02-16 20:43:33 +08:00
|
|
|
|
"encoding/json"
|
2019-02-18 00:03:35 +08:00
|
|
|
|
"github.com/axgle/mahonia"
|
|
|
|
|
|
"github.com/pkg/errors"
|
2019-02-18 02:35:22 +08:00
|
|
|
|
"github.com/linxiaozhi/go-telnet"
|
2017-06-23 12:24:42 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type Job struct {
|
|
|
|
|
|
id int // 任务ID
|
|
|
|
|
|
logId int64 // 日志记录ID
|
|
|
|
|
|
name string // 任务名称
|
|
|
|
|
|
task *models.Task // 任务对象
|
|
|
|
|
|
runFunc func(time.Duration) (string, string, error, bool) // 执行函数
|
|
|
|
|
|
status int // 任务状态,大于0表示正在执行中
|
|
|
|
|
|
Concurrent bool // 同一个任务是否允许并行执行
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func NewJobFromTask(task *models.Task) (*Job, error) {
|
|
|
|
|
|
if task.Id < 1 {
|
|
|
|
|
|
return nil, fmt.Errorf("ToJob: 缺少id")
|
|
|
|
|
|
}
|
2018-07-13 17:53:34 +08:00
|
|
|
|
|
2017-08-17 11:49:53 +08:00
|
|
|
|
//本地程序执行
|
2017-08-29 15:30:55 +08:00
|
|
|
|
if task.ServerId == 0 {
|
2017-08-17 11:49:53 +08:00
|
|
|
|
job := NewCommandJob(task.Id, task.TaskName, task.Command)
|
|
|
|
|
|
job.task = task
|
|
|
|
|
|
job.Concurrent = task.Concurrent == 1
|
|
|
|
|
|
return job, nil
|
2017-08-17 13:07:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
server, _ := models.TaskServerGetById(task.ServerId)
|
2019-02-18 00:03:35 +08:00
|
|
|
|
if server.ConnectionType == 0 {
|
|
|
|
|
|
if server.Type == 0 {
|
|
|
|
|
|
//密码验证登录服务器
|
|
|
|
|
|
job := RemoteCommandJobByPassword(task.Id, task.TaskName, task.Command, server)
|
|
|
|
|
|
job.task = task
|
|
|
|
|
|
job.Concurrent = task.Concurrent == 1
|
|
|
|
|
|
return job, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
job := RemoteCommandJob(task.Id, task.TaskName, task.Command, server)
|
2017-08-17 11:49:53 +08:00
|
|
|
|
job.task = task
|
|
|
|
|
|
job.Concurrent = task.Concurrent == 1
|
|
|
|
|
|
return job, nil
|
2019-02-18 00:03:35 +08:00
|
|
|
|
} else if server.ConnectionType == 1 {
|
|
|
|
|
|
if server.Type == 0 {
|
|
|
|
|
|
//密码验证登录服务器
|
|
|
|
|
|
job := RemoteCommandJobByTelnetPassword(task.Id, task.TaskName, task.Command, server)
|
|
|
|
|
|
job.task = task
|
|
|
|
|
|
job.Concurrent = task.Concurrent == 1
|
|
|
|
|
|
return job, nil
|
|
|
|
|
|
}
|
2017-08-17 11:49:53 +08:00
|
|
|
|
}
|
2017-08-17 13:07:23 +08:00
|
|
|
|
|
2019-02-18 00:03:35 +08:00
|
|
|
|
return nil, fmt.Errorf("未知ConnectionType")
|
2017-06-23 12:24:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func NewCommandJob(id int, name string, command string) *Job {
|
|
|
|
|
|
job := &Job{
|
|
|
|
|
|
id: id,
|
|
|
|
|
|
name: name,
|
|
|
|
|
|
}
|
|
|
|
|
|
job.runFunc = func(timeout time.Duration) (string, string, error, bool) {
|
|
|
|
|
|
bufOut := new(bytes.Buffer)
|
|
|
|
|
|
bufErr := new(bytes.Buffer)
|
2017-06-30 15:49:33 +08:00
|
|
|
|
//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)
|
|
|
|
|
|
|
|
|
|
|
|
return bufOut.String(), bufErr.String(), err, isTimeout
|
|
|
|
|
|
}
|
|
|
|
|
|
return job
|
|
|
|
|
|
}
|
2017-08-29 15:30:55 +08:00
|
|
|
|
|
2017-08-17 13:07:23 +08:00
|
|
|
|
//远程执行任务 密钥验证
|
2017-08-29 15:30:55 +08:00
|
|
|
|
func RemoteCommandJob(id int, name string, command string, servers *models.TaskServer) *Job {
|
2017-08-17 11:49:53 +08:00
|
|
|
|
job := &Job{
|
|
|
|
|
|
id: id,
|
|
|
|
|
|
name: name,
|
|
|
|
|
|
}
|
|
|
|
|
|
job.runFunc = func(timeout time.Duration) (string, string, error, bool) {
|
|
|
|
|
|
|
|
|
|
|
|
key, err := ioutil.ReadFile(servers.PrivateKeySrc)
|
|
|
|
|
|
if err != nil {
|
2017-08-29 15:30:55 +08:00
|
|
|
|
return "", "", err, false
|
2017-08-17 11:49:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
// Create the Signer for this private key.
|
|
|
|
|
|
signer, err := ssh.ParsePrivateKey(key)
|
|
|
|
|
|
if err != nil {
|
2017-08-29 15:30:55 +08:00
|
|
|
|
return "", "", err, false
|
2017-08-17 11:49:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
addr := fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port)
|
|
|
|
|
|
config := &ssh.ClientConfig{
|
2017-08-17 13:07:23 +08:00
|
|
|
|
User: servers.ServerAccount,
|
2017-08-17 11:49:53 +08:00
|
|
|
|
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 {
|
2017-08-29 15:30:55 +08:00
|
|
|
|
return "", "", err, false
|
2017-08-17 11:49:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-09 15:44:32 +08:00
|
|
|
|
defer client.Close()
|
|
|
|
|
|
|
2017-08-17 11:49:53 +08:00
|
|
|
|
session, err := client.NewSession()
|
|
|
|
|
|
if err != nil {
|
2017-08-29 15:30:55 +08:00
|
|
|
|
return "", "", err, false
|
2017-08-17 11:49:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
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 {
|
2017-08-29 15:30:55 +08:00
|
|
|
|
return "", "", err, false
|
2017-08-17 11:49:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
isTimeout := false
|
|
|
|
|
|
return b.String(), c.String(), err, isTimeout
|
|
|
|
|
|
}
|
|
|
|
|
|
return job
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-29 15:30:55 +08:00
|
|
|
|
func RemoteCommandJobByPassword(id int, name string, command string, servers *models.TaskServer) *Job {
|
2017-08-17 13:07:23 +08:00
|
|
|
|
var (
|
|
|
|
|
|
auth []ssh.AuthMethod
|
|
|
|
|
|
addr string
|
|
|
|
|
|
clientConfig *ssh.ClientConfig
|
|
|
|
|
|
client *ssh.Client
|
|
|
|
|
|
session *ssh.Session
|
|
|
|
|
|
err error
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
job := &Job{
|
|
|
|
|
|
id: id,
|
|
|
|
|
|
name: name,
|
|
|
|
|
|
}
|
|
|
|
|
|
job.runFunc = func(timeout time.Duration) (string, string, error, bool) {
|
|
|
|
|
|
// 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 {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-09 15:44:32 +08:00
|
|
|
|
defer client.Close()
|
|
|
|
|
|
|
2017-08-17 13:07:23 +08:00
|
|
|
|
// create session
|
|
|
|
|
|
if session, err = client.NewSession(); err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var b bytes.Buffer
|
|
|
|
|
|
var c bytes.Buffer
|
|
|
|
|
|
session.Stdout = &b
|
|
|
|
|
|
session.Stderr = &c
|
|
|
|
|
|
//session.Output(command)
|
|
|
|
|
|
if err := session.Run(command); err != nil {
|
2017-08-29 15:30:55 +08:00
|
|
|
|
return "", "", err, false
|
2017-08-17 13:07:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
isTimeout := false
|
|
|
|
|
|
return b.String(), c.String(), err, isTimeout
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return job
|
|
|
|
|
|
}
|
2017-08-17 11:49:53 +08:00
|
|
|
|
|
2019-02-18 00:03:35 +08:00
|
|
|
|
func RemoteCommandJobByTelnetPassword(id int, name string, command string, servers *models.TaskServer) *Job {
|
|
|
|
|
|
|
|
|
|
|
|
job := &Job{
|
|
|
|
|
|
id: id,
|
|
|
|
|
|
name: name,
|
|
|
|
|
|
}
|
|
|
|
|
|
job.runFunc = func(timeout time.Duration) (string, string, error, bool) {
|
|
|
|
|
|
|
|
|
|
|
|
addr := fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port)
|
2019-02-18 02:35:22 +08:00
|
|
|
|
conn, err := gote.DialTimeout("tcp", addr, timeout)
|
2019-02-18 00:03:35 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-02-18 02:50:12 +08:00
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
2019-02-18 00:03:35 +08:00
|
|
|
|
buf := make([]byte, 4096)
|
|
|
|
|
|
_, err = conn.Read(buf)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_, err = conn.Write([]byte(servers.ServerAccount + "\r\n"))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_, err = conn.Read(buf)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_, err = conn.Write([]byte(servers.Password + "\r\n"))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_, err = conn.Read(buf)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
loginStr := gbkAsUtf8(string(buf[:]))
|
|
|
|
|
|
if !strings.Contains(loginStr, ">") {
|
|
|
|
|
|
return "", "", errors.Errorf("Login failed!"), false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
commandArr := strings.Split(command, "\n")
|
|
|
|
|
|
|
|
|
|
|
|
out := ""
|
|
|
|
|
|
for _, c := range commandArr {
|
|
|
|
|
|
_, err = conn.Write([]byte(c + "\r\n"))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_, err = conn.Read(buf)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return "", "", err, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
out = out + gbkAsUtf8(string(buf[:]))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return out, "", nil, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return job
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-23 12:24:42 +08:00
|
|
|
|
func (j *Job) Status() int {
|
|
|
|
|
|
return j.status
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (j *Job) GetName() string {
|
|
|
|
|
|
return j.name
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (j *Job) GetId() int {
|
|
|
|
|
|
return j.id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (j *Job) GetLogId() int64 {
|
|
|
|
|
|
return j.logId
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (j *Job) Run() {
|
|
|
|
|
|
if !j.Concurrent && j.status > 0 {
|
|
|
|
|
|
beego.Warn(fmt.Sprintf("任务[%d]上一次执行尚未结束,本次被忽略。", j.id))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
|
beego.Error(err, "\n", string(debug.Stack()))
|
|
|
|
|
|
}
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
if workPool != nil {
|
|
|
|
|
|
workPool <- true
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
<-workPool
|
|
|
|
|
|
}()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
beego.Debug(fmt.Sprintf("开始执行任务: %d", j.id))
|
|
|
|
|
|
|
|
|
|
|
|
j.status++
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
j.status--
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
t := time.Now()
|
|
|
|
|
|
timeout := time.Duration(time.Hour * 24)
|
|
|
|
|
|
if j.task.Timeout > 0 {
|
|
|
|
|
|
timeout = time.Second * time.Duration(j.task.Timeout)
|
|
|
|
|
|
}
|
|
|
|
|
|
cmdOut, cmdErr, err, isTimeout := j.runFunc(timeout)
|
|
|
|
|
|
ut := time.Now().Sub(t) / time.Millisecond
|
|
|
|
|
|
|
|
|
|
|
|
// 插入日志
|
|
|
|
|
|
log := new(models.TaskLog)
|
|
|
|
|
|
log.TaskId = j.id
|
|
|
|
|
|
log.Output = cmdOut
|
|
|
|
|
|
log.Error = cmdErr
|
|
|
|
|
|
log.ProcessTime = int(ut)
|
|
|
|
|
|
log.CreateTime = t.Unix()
|
|
|
|
|
|
|
|
|
|
|
|
if isTimeout {
|
|
|
|
|
|
log.Status = models.TASK_TIMEOUT
|
|
|
|
|
|
log.Error = fmt.Sprintf("任务执行超过 %d 秒\n----------------------\n%s\n", int(timeout/time.Second), cmdErr)
|
|
|
|
|
|
} else if err != nil {
|
|
|
|
|
|
log.Status = models.TASK_ERROR
|
|
|
|
|
|
log.Error = err.Error() + ":" + cmdErr
|
|
|
|
|
|
}
|
2018-08-09 11:34:46 +08:00
|
|
|
|
|
|
|
|
|
|
if log.Status < 0 && j.task.IsNotify == 1 {
|
|
|
|
|
|
if j.task.NotifyUserIds != "0" && j.task.NotifyUserIds != "" {
|
2018-08-09 18:47:42 +08:00
|
|
|
|
adminInfo := AllAdminInfo(j.task.NotifyUserIds)
|
2019-02-15 18:29:17 +08:00
|
|
|
|
phone := make(map[string]string, 0)
|
|
|
|
|
|
dingtalk := make(map[string]string, 0)
|
2019-02-17 07:07:33 +08:00
|
|
|
|
wechat := make(map[string]string, 0)
|
2018-08-09 11:34:46 +08:00
|
|
|
|
toEmail := ""
|
2018-08-09 18:47:42 +08:00
|
|
|
|
for _, v := range adminInfo {
|
2018-08-09 11:34:46 +08:00
|
|
|
|
if v.Phone != "0" && v.Phone != "" {
|
2019-02-15 18:29:17 +08:00
|
|
|
|
phone[v.Phone] = v.Phone
|
2018-08-09 11:34:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
if v.Email != "0" && v.Email != "" {
|
|
|
|
|
|
toEmail += v.Email + ";"
|
|
|
|
|
|
}
|
2019-02-15 11:50:09 +08:00
|
|
|
|
if v.Dingtalk != "0" && v.Dingtalk != "" {
|
2019-02-15 18:29:17 +08:00
|
|
|
|
dingtalk[v.Dingtalk] = v.Dingtalk
|
2019-02-15 11:50:09 +08:00
|
|
|
|
}
|
2019-02-17 07:07:33 +08:00
|
|
|
|
if v.Wechat != "0" && v.Wechat != "" {
|
|
|
|
|
|
wechat[v.Wechat] = v.Wechat
|
|
|
|
|
|
}
|
2018-08-09 11:34:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
toEmail = strings.TrimRight(toEmail, ";")
|
|
|
|
|
|
|
|
|
|
|
|
TextStatus := []string{
|
2019-02-16 20:43:33 +08:00
|
|
|
|
"超时",
|
|
|
|
|
|
"错误",
|
|
|
|
|
|
"正常",
|
2018-08-09 11:34:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status := log.Status + 2
|
|
|
|
|
|
|
2019-02-17 07:07:33 +08:00
|
|
|
|
title, content := "", ""
|
|
|
|
|
|
|
2019-02-16 20:43:33 +08:00
|
|
|
|
notifyTpl, err := models.NotifyTplGetById(j.task.NotifyTplId)
|
2019-02-16 22:30:10 +08:00
|
|
|
|
if err != nil {
|
2019-02-16 22:42:25 +08:00
|
|
|
|
notifyTpl, err := models.NotifyTplGetByTplType(j.task.NotifyType, models.NotifyTplTypeSystem)
|
2019-02-16 22:30:10 +08:00
|
|
|
|
if err == nil {
|
|
|
|
|
|
title = notifyTpl.Title
|
|
|
|
|
|
content = notifyTpl.Content
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2019-02-16 20:43:33 +08:00
|
|
|
|
title = notifyTpl.Title
|
|
|
|
|
|
content = notifyTpl.Content
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if title != "" {
|
2019-02-17 01:37:24 +08:00
|
|
|
|
title = strings.Replace(title, "{{TaskId}}", strconv.Itoa(j.task.Id), -1)
|
|
|
|
|
|
title = strings.Replace(title, "{{TaskName}}", j.task.TaskName, -1)
|
2019-02-17 07:07:33 +08:00
|
|
|
|
title = strings.Replace(title, "{{ExecuteTime}}", beego.Date(time.Unix(log.CreateTime, 0), "Y-m-d H:i:s"), -1)
|
2019-02-17 01:37:24 +08:00
|
|
|
|
title = strings.Replace(title, "{{ProcessTime}}", strconv.FormatFloat(float64(log.ProcessTime)/1000, 'f', 6, 64), -1)
|
2019-02-17 07:07:33 +08:00
|
|
|
|
title = strings.Replace(title, "{{ExecuteStatus}}", TextStatus[status], -1)
|
|
|
|
|
|
title = strings.Replace(title, "{{TaskOutput}}", log.Error, -1)
|
2019-02-16 20:43:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if content != "" {
|
2019-02-17 01:37:24 +08:00
|
|
|
|
content = strings.Replace(content, "{{TaskId}}", strconv.Itoa(j.task.Id), -1)
|
|
|
|
|
|
content = strings.Replace(content, "{{TaskName}}", j.task.TaskName, -1)
|
2019-02-17 07:07:33 +08:00
|
|
|
|
content = strings.Replace(content, "{{ExecuteTime}}", beego.Date(time.Unix(log.CreateTime, 0), "Y-m-d H:i:s"), -1)
|
2019-02-17 01:37:24 +08:00
|
|
|
|
content = strings.Replace(content, "{{ProcessTime}}", strconv.FormatFloat(float64(log.ProcessTime)/1000, 'f', 6, 64), -1)
|
2019-02-17 07:07:33 +08:00
|
|
|
|
content = strings.Replace(content, "{{ExecuteStatus}}", TextStatus[status], -1)
|
|
|
|
|
|
content = strings.Replace(content, "{{TaskOutput}}", log.Error, -1)
|
2019-02-16 20:43:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-09 11:34:46 +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)
|
2018-08-09 11:34:46 +08:00
|
|
|
|
if !ok {
|
|
|
|
|
|
fmt.Println("发送邮件错误", toEmail)
|
|
|
|
|
|
}
|
2018-08-09 18:47:42 +08:00
|
|
|
|
} else if j.task.NotifyType == 1 && len(phone) > 0 {
|
2018-08-09 11:34:46 +08:00
|
|
|
|
//信息
|
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), ¶m)
|
|
|
|
|
|
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
|
|
|
|
|
2019-02-17 07:07:33 +08:00
|
|
|
|
ok := notify.SendSmsToChan(phone, param)
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
fmt.Println("发送信息错误", phone)
|
|
|
|
|
|
}
|
2019-02-16 20:43:33 +08:00
|
|
|
|
} else if j.task.NotifyType == 2 && len(dingtalk) > 0 {
|
|
|
|
|
|
//钉钉
|
2019-02-17 07:07:33 +08:00
|
|
|
|
ok := notify.SendDingtalkToChan(dingtalk, content)
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
fmt.Println("发送钉钉错误", dingtalk)
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if j.task.NotifyType == 3 && len(wechat) > 0 {
|
|
|
|
|
|
//信息
|
|
|
|
|
|
param := make(map[string]string)
|
|
|
|
|
|
err := json.Unmarshal([]byte(content), ¶m)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Println("发送微信错误", err)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2018-08-09 11:34:46 +08:00
|
|
|
|
|
2019-02-17 07:07:33 +08:00
|
|
|
|
ok := notify.SendWechatToChan(phone, param)
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
fmt.Println("发送微信错误", phone)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-08-09 11:34:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-23 12:24:42 +08:00
|
|
|
|
j.logId, _ = models.TaskLogAdd(log)
|
|
|
|
|
|
|
|
|
|
|
|
// 更新上次执行时间
|
|
|
|
|
|
j.task.PrevTime = t.Unix()
|
|
|
|
|
|
j.task.ExecuteTimes++
|
|
|
|
|
|
j.task.Update("PrevTime", "ExecuteTimes")
|
|
|
|
|
|
}
|
2018-08-09 11:34:46 +08:00
|
|
|
|
|
|
|
|
|
|
//冗余代码
|
|
|
|
|
|
type adminInfo struct {
|
|
|
|
|
|
Id int
|
|
|
|
|
|
Email string
|
|
|
|
|
|
Phone string
|
2019-02-15 11:50:09 +08:00
|
|
|
|
Dingtalk string
|
2019-02-17 07:07:33 +08:00
|
|
|
|
Wechat string
|
2018-08-09 11:34:46 +08:00
|
|
|
|
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,
|
2019-02-17 07:07:33 +08:00
|
|
|
|
Wechat: v.Wechat,
|
2018-08-09 11:34:46 +08:00
|
|
|
|
RealName: v.RealName,
|
|
|
|
|
|
}
|
|
|
|
|
|
adminInfos = append(adminInfos, &ai)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return adminInfos
|
|
|
|
|
|
}
|
2019-02-18 00:03:35 +08:00
|
|
|
|
|
|
|
|
|
|
func gbkAsUtf8(str string) string {
|
|
|
|
|
|
srcDecoder := mahonia.NewDecoder("gbk")
|
|
|
|
|
|
desDecoder := mahonia.NewDecoder("utf-8")
|
|
|
|
|
|
resStr := srcDecoder.ConvertString(str)
|
|
|
|
|
|
_, resBytes, _ := desDecoder.Translate([]byte(resStr), true)
|
|
|
|
|
|
return string(resBytes)
|
|
|
|
|
|
}
|