diff --git a/src/controller/work_order_manage.go b/src/controller/work_order_manage.go index 7cae6367d21c31526d32134085eff643f023536c..0fbb35a566d603273d9b307838b95f7e66c46563 100644 --- a/src/controller/work_order_manage.go +++ b/src/controller/work_order_manage.go @@ -243,15 +243,3 @@ func ListWorkOrderMe(c *gin.Context) { } SendJsonPageResponse(c, resp.OK, list, total) } - -// WorkOrderPushNoteMsg 推送短信 -func WorkOrderPushNoteMsg(c *gin.Context) { - phone := c.Query("phone") - - err := service.WorkOrderPushNoteMsg(phone) - if err != nil { - SendJsonResponse(c, err, nil) - return - } - SendJsonResponse(c, resp.OK, nil) -} diff --git a/src/service/host_manage.go b/src/service/host_manage.go index 4a3f508448bb6b2a0f871d8b72c339dd3347b06e..3a3f5ebedd00dbf77159035af6f000c649278790 100644 --- a/src/service/host_manage.go +++ b/src/service/host_manage.go @@ -10,8 +10,10 @@ import ( "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/tools" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "go.uber.org/zap" "os/exec" "strings" "sync" @@ -463,7 +465,7 @@ func (h *HostManageSvc) ListStateHostManage(req request.StateHostManageReq) (err for i := 0; i < len(hostManageList); i++ { go func(i int) { //检测ip连通性 - connStatus := StatusDetection(hostManageList[i].Ip) + connStatus := StatusDetection(cast.ToString(hostManageList[i].Id)) if connStatus == 1 { lock.Lock() fail = append(fail, hostManageList[i].Id) @@ -679,11 +681,10 @@ func StatusDetection(ip string) (ipConn int) { cmd = exec.Command("ansible", fmt.Sprintf("%s", AnsibleIp+ip), "-m", "ping") output, err := cmd.Output() if err != nil { - fmt.Println("ping:", string(output)) - fmt.Println("err:", err) + conf.Logger.Error("测试 "+ip+" 连通性失败", zap.Error(err)) return 1 } - fmt.Println("ping:", string(output)) + conf.Logger.Debug("测试 "+ip+" 连通性成功", zap.String("output", string(output))) return 0 } @@ -812,6 +813,44 @@ func CronStatusDetection() { return } + //读取hosts中的主机组 + hosts, err := tools.HostsToJson() + if err != nil { + fmt.Println("CronStatusDetection err:", err.Error()) + return + } + if _, ok := hosts["["+AnsibleGroup+"]"]; !ok { + // 不存在 + hosts["["+AnsibleGroup+"]"] = nil + } + + for _, v := range hostManageList { + + hostsIp := "" + if v.VoucherType == 0 { + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\" ansible_host_key_checking=false", + AnsibleIp+v.Ip, v.Ip, v.Port, v.UserName, v.Password) + } else { + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_private_key_file=/root/.ssh/id_rsa ansible_host_key_checking=false", + AnsibleIp+v.Ip, v.Ip, v.Port, v.UserName) + } + flag := 0 + for _, v1 := range hosts["["+AnsibleGroup+"]"] { + if v1 == hostsIp { + flag = 1 + } + } + if flag == 0 { + hosts["["+AnsibleGroup+"]"] = append(hosts["["+AnsibleGroup+"]"], hostsIp) + } + } + //写入hosts + err = tools.MapToSaveHosts(hosts) + if err != nil { + fmt.Println("CronStatusDetection err:", err.Error()) + return + } + for _, v := range hostManageList { connStatus := StatusDetection(v.Ip) //修改状态 diff --git a/src/service/task_manage.go b/src/service/task_manage.go index 74883dabec889a592a20ca92d20acb0045bbf8f4..09c9f0e458f2d7f219ee875192918d4a49c7ceca 100644 --- a/src/service/task_manage.go +++ b/src/service/task_manage.go @@ -8,7 +8,9 @@ import ( "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "go.uber.org/zap" "io" "os" "os/exec" @@ -268,31 +270,118 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq, script string) (id if err != nil { return } + go ExecAnsible(id, req.TaskId, req.Value) + ////执行ansible命令 + //var cmd *exec.Cmd + //if req.Value != "" { + // cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", req.TaskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", req.TaskId)+".yml", "--extra-vars", req.Value) + //} else { + // cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", req.TaskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", req.TaskId)+".yml") + //} + ////ansible-playbook -i /tmp/hosts --list-hosts debug.yml + ////捕获正常日志 + //stdout, err := cmd.StdoutPipe() + //if err != nil { + // err = resp.CmdExecError.WithError(err) + // return + //} + ////捕获异常日志 + //stderr, err := cmd.StderrPipe() + //if err != nil { + // err = resp.CmdExecError.WithError(err) + // return + //} + ////执行cmd命令 + //if err = cmd.Start(); err != nil { + // err = resp.CmdExecError.WithError(err) + // return + //} + ////获取 正常/异常 输出流 + //outputBuf := bufio.NewReader(stdout) + //readerr := bufio.NewReader(stderr) + // + //var out, outErr int + //var execLog string + //for { + // + // //逐行输出日志 + // lineOut, err1 := outputBuf.ReadString('\n') + // if (err1 != nil || io.EOF == err1) && out == 0 { + // out = 1 + // } else if out == 0 { + // //存储执行日志 + // execLog = execLog + lineOut + " \n " + // UpdateExecHistory(request.UpdateExecHistory{ + // TaskHistoryId: id, + // ExecLog: execLog, + // }) + // } + // + // lineErr, err2 := readerr.ReadString('\n') + // if (err2 != nil || io.EOF == err2) && outErr == 0 { + // outErr = 1 + // } else if outErr == 0 { + // //存储异常执行日志 + // execLog = execLog + lineErr + " \n " + // UpdateExecHistory(request.UpdateExecHistory{ + // TaskHistoryId: id, + // ExecLog: execLog, + // }) + // } + // + // if out == 1 && outErr == 1 { + // break + // } + //} + //cmd.Wait() + // + //if cmd.ProcessState.Success() { + // //任务执行成功 + // UpdateExecHistory(request.UpdateExecHistory{ + // TaskHistoryId: id, + // ExecLog: execLog, + // State: 1, + // }) + //} else { + // //任务执行失败 + // UpdateExecHistory(request.UpdateExecHistory{ + // TaskHistoryId: id, + // ExecLog: execLog, + // State: 2, + // }) + //} + return +} +// 执行脚本 +func ExecAnsible(id, taskId int, value string) { //执行ansible命令 var cmd *exec.Cmd - if req.Value != "" { - cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", req.TaskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", req.TaskId)+".yml", "--extra-vars", req.Value) + if value != "" { + cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", taskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", taskId)+".yml", "--extra-vars", value) } else { - cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", req.TaskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", req.TaskId)+".yml") + cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts_"+fmt.Sprintf("%d", taskId), "/etc/ansible/ansible_"+fmt.Sprintf("%d", taskId)+".yml") } //ansible-playbook -i /tmp/hosts --list-hosts debug.yml //捕获正常日志 stdout, err := cmd.StdoutPipe() if err != nil { err = resp.CmdExecError.WithError(err) - return + conf.Logger.Error("Capture normal logs", zap.Error(err)) + //return } //捕获异常日志 stderr, err := cmd.StderrPipe() if err != nil { err = resp.CmdExecError.WithError(err) - return + conf.Logger.Error("Capture exception logs", zap.Error(err)) + //return } //执行cmd命令 if err = cmd.Start(); err != nil { err = resp.CmdExecError.WithError(err) - return + conf.Logger.Error("Execute cmd command", zap.Error(err)) + //return } //获取 正常/异常 输出流 outputBuf := bufio.NewReader(stdout) @@ -309,11 +398,14 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq, script string) (id } else if out == 0 { //存储执行日志 execLog = execLog + lineOut + " \n " - UpdateExecHistory(request.UpdateExecHistory{ + err = UpdateExecHistory(request.UpdateExecHistory{ TaskHistoryId: id, ExecLog: execLog, }) - + if err != nil { + conf.Logger.Error("Store Execution Log", zap.Error(err)) + //return + } } lineErr, err2 := readerr.ReadString('\n') @@ -322,10 +414,14 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq, script string) (id } else if outErr == 0 { //存储异常执行日志 execLog = execLog + lineErr + " \n " - UpdateExecHistory(request.UpdateExecHistory{ + err = UpdateExecHistory(request.UpdateExecHistory{ TaskHistoryId: id, ExecLog: execLog, }) + if err != nil { + conf.Logger.Error("Store abnormal execution logs", zap.Error(err)) + //return + } } if out == 1 && outErr == 1 { @@ -336,18 +432,26 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq, script string) (id if cmd.ProcessState.Success() { //任务执行成功 - UpdateExecHistory(request.UpdateExecHistory{ + err = UpdateExecHistory(request.UpdateExecHistory{ TaskHistoryId: id, ExecLog: execLog, State: 1, }) + if err != nil { + conf.Logger.Error("Modify Execution Status", zap.Error(err)) + //return + } } else { //任务执行失败 - UpdateExecHistory(request.UpdateExecHistory{ + err = UpdateExecHistory(request.UpdateExecHistory{ TaskHistoryId: id, ExecLog: execLog, State: 2, }) + if err != nil { + conf.Logger.Error("Modify Execution Status", zap.Error(err)) + //return + } } - return + //return } diff --git a/src/service/work_order.go b/src/service/work_order.go index 1d15df7697cd65958e13e63e637a326199f22d3a..dbac0a829ac0ed47c028952740f69df31ee4475d 100644 --- a/src/service/work_order.go +++ b/src/service/work_order.go @@ -3,7 +3,6 @@ package service import ( "errors" "fmt" - "github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi" json "github.com/json-iterator/go" "github.com/wanghuiyt/ding" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" @@ -12,8 +11,6 @@ import ( "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" - "gitlab.wodcloud.com/smart-operation/so-operation-api/src/util" - "go.uber.org/zap" "time" ) @@ -301,11 +298,13 @@ func (w *WorkOrderManageSvc) PushWorkOrderManage(req request.PushWorkOrderReq) ( session := db.NewSession() defer session.Close() session.Begin() + var workOrder entity.WorkOrder + _, err = session.Table("work_order_manage").Where("id = ?", req.Id).Get(&workOrder) + if err != nil { + err = resp.FAIL.WithError(err) + return + } - //pushObj := req.PushObj.UserObj[0].UserName - //for i := 1; i < len(req.PushObj.UserObj); i++ { - // pushObj = pushObj + "、" + req.PushObj.UserObj[i].UserName - //} pushObj, err := json.Marshal(req.PushObj) if err != nil { err = resp.FAIL.WithError(err) @@ -342,8 +341,6 @@ func (w *WorkOrderManageSvc) PushWorkOrderManage(req request.PushWorkOrderReq) ( } } - //发消息通知 czl.. - //修改库表实例工单数 _, err = session.Table("work_order_manage").Where("id = ?", req.Id).Incr("order_cnt").Update(&entity.WorkOrder{}) if err != nil { @@ -351,6 +348,37 @@ func (w *WorkOrderManageSvc) PushWorkOrderManage(req request.PushWorkOrderReq) ( session.Rollback() return } + + var phones []string + for _, v := range req.PushObj.UserObj { + phones = append(phones, v.Phone) + } + switch req.PushObj.PushMethod { + case 1: + //发送钉钉消息 + err = WorkOrderPushDingTalkMsg(workOrder.OrderName, workOrder.OrderLevel, phones) + if err != nil { + return + } + case 2: + //发送短信 + err = WorkOrderPushNoteMsg(workOrder.OrderName, workOrder.OrderLevel, phones) + if err != nil { + return + } + case 3: + //发送钉钉消息 + err = WorkOrderPushDingTalkMsg(workOrder.OrderName, workOrder.OrderLevel, phones) + if err != nil { + return + } + //发送短信 + err = WorkOrderPushNoteMsg(workOrder.OrderName, workOrder.OrderLevel, phones) + if err != nil { + return + } + } + session.Commit() return } @@ -613,7 +641,7 @@ func (w *WorkOrderManageSvc) ListWorkOrderMe(req request.ListWorkOrderReq) (tota } // WorkOrderPushDingTalkMsg 推送钉钉消息 -func WorkOrderPushDingTalkMsg(orderName, phone string, orderLevel int) (err error) { +func WorkOrderPushDingTalkMsg(orderName string, orderLevel int, phones []string) (err error) { d := ding.Webhook{ AccessToken: conf.Options.OrderDingTalkAccessToken, //"203fe1644b446bba0a34e6e622c523d39ee9916fdad94b9c64224449f659e20b", Secret: conf.Options.OrderDingTalkSecret, //"SECa73d8372e336451c9daf29a99f750ee1bdd170c1dab910eab9cd06d729a831b7", @@ -630,34 +658,16 @@ func WorkOrderPushDingTalkMsg(orderName, phone string, orderLevel int) (err erro } //有一条工单需要您处理:工单类型:【业务工单】 工单名称:【$工单名称】 工单等级:【$工单等级】 - err = d.SendMessageText("有一条工单需要您处理:\n工单类型:【业务工单】\n工单名称:【"+orderName+"】\n工单等级:【"+orderLevels+"】", phone) + err = d.SendMessageText("有一条工单需要您处理:\n工单类型:【业务工单】\n工单名称:【"+orderName+"】\n工单等级:【"+orderLevels+"】", phones...) + if err != nil { + return + } + return } // WorkOrderPushNoteMsg 推送短信消息 -func WorkOrderPushNoteMsg(phone string) (err error) { - smsClient, err := dysmsapi.NewClientWithAccessKey("cn-hangzhou", conf.Options.SmsAccessKeyId, conf.Options.SmsAccessSecret) - if err != nil { - conf.Logger.Error("dysmsapi client error", zap.Error(err)) - return resp.FAIL.ErrorDetail(err) - } - code := util.Rand6() - params := map[string]interface{}{"code": code} - templateParam, err := json.Marshal(params) - if err != nil { - conf.Logger.Error("序列化模板失败!", zap.Error(err)) - return resp.FAIL.ErrorDetail(err) - } - request := dysmsapi.CreateSendSmsRequest() - request.Scheme = "https" - request.PhoneNumbers = phone - request.TemplateCode = conf.Options.SmsTemplateLogin - request.SignName = conf.Options.SmsSignName - request.TemplateParam = string(templateParam) - req, err := smsClient.SendSms(request) - if err != nil { - return resp.FAIL.ErrorDetail(err) - } - fmt.Printf("response is %#v\n", req) +func WorkOrderPushNoteMsg(orderName string, orderLevel int, phone []string) (err error) { + return nil }