package service import ( "bufio" "context" "errors" "fmt" "github.com/minio/minio-go/v7" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "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" "io" "os" "os/exec" "time" ) type TaskManageSvc struct { User *entity.SystemUser } // AddTaskManage 新增任务 func (t *TaskManageSvc) AddTaskManage(req request.AddTaskManageReq) (err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return } // 校验 任务名称 是否重复 has, err := db.Table("task_manage").Where("is_delete = 0 AND task_name = ?", req.TaskName).Exist() if has { err = resp.DbDataCheckError.WithError(errors.New("任务名称重复")) return } if err != nil { err = resp.DbSelectError.WithError(err) return } taskManage := entity.TaskManage{ TaskName: req.TaskName, TaskDesc: req.TaskDesc, YamlDesc: req.YamlDesc, YamlUrl: req.YamlUrl, HostGroupId: req.HostGroupId, CreateUser: "", CreateTime: time.Now(), UpdateUser: "", UpdateTime: time.Now(), } _, err = db.Table("task_manage").Insert(&taskManage) if err != nil { err = resp.DbInsertError.WithError(err) return } return } // EditTaskManage 编辑任务 func (t *TaskManageSvc) EditTaskManage(req request.EditTaskManageReq) (err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return } taskManage := entity.TaskManage{ TaskDesc: req.TaskDesc, YamlDesc: req.YamlDesc, YamlUrl: req.YamlUrl, HostGroupId: req.HostGroupId, UpdateUser: "", UpdateTime: time.Now(), } //编辑任务 _, err = db.Table("task_manage").Where("is_delete = 0 AND id = ?", req.Id). Cols("task_desc,yaml_desc,yaml_url,host_group_id,update_user,update_time").Update(&taskManage) if err != nil { err = resp.DbUpdateError.WithError(err) return } return } // DelTaskManage 删除任务 func (t *TaskManageSvc) DelTaskManage(req request.DelTaskManageReq) (err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return } //编辑任务 _, err = db.Table("task_manage").In("id", req.Id).Cols("is_delete").Update(&entity.TaskManage{ IsDelete: 1, }) if err != nil { err = resp.DbDeleteError.WithError(err) return } return } // DetailsTaskManage 任务详情 func (t *TaskManageSvc) DetailsTaskManage(id int) (taskManageRes response.TaskManageRes, err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return } //查询任务详情 finder := db.Table("task_manage").Alias("tm"). Where("is_delete = 0 AND id = ?", id) _, err = finder.Select("tm.id,tm.task_name,tm.task_desc,tm.yaml_desc,tm.yaml_url,tm.create_user,tm.create_time,tm.host_group_id," + "(select count(1) from task_history th where th.task_id = tm.id) as exec_cnt," + "(select count(1) from task_history th where th.task_id = tm.id and th.state = 1) as success_cnt," + "(select count(1) from task_history th where th.task_id = tm.id and th.state = 2) as fail_cnt").Get(&taskManageRes) if err != nil { err = resp.DbSelectError.WithError(err) return } //查询主机列表 hostList := make([]response.HostList, 0) err = db.Table("host_manage_list").Where("is_delete = 0 AND host_group_id = ?", taskManageRes.HostGroupId). Select("string_agg(ip,',') as ip,port,voucher_type,user_name,password,host_file_url"). GroupBy("ip_group,port,voucher_type,user_name,PASSWORD,host_file_url").Find(&hostList) if err != nil { err = resp.DbSelectError.WithError(err) return } //err = db.Table("host_manage_list").Where("is_delete = 0 AND host_group_id = ?", id).Find(&hostList) //if err != nil { // err = resp.DbSelectError.WithError(err) // return //} for _, v := range hostList { if v.HostFileUrl != "" { taskManageRes.HostFileUrl = v.HostFileUrl } } if taskManageRes.HostFileUrl == "" { taskManageRes.HostList = hostList } return } // ListTaskManage 任务列表 func (t *TaskManageSvc) ListTaskManage(req request.ListTaskManageReq) (total int64, taskManageListRes []response.TaskManageListRes, err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return } finder := db.Table("task_manage").Alias("tm").Where("tm.is_delete = 0") if req.Search != "" { finder.Where(fmt.Sprintf("(tm.task_name LIKE '%s' OR tm.task_desc LIKE '%s' OR tm.create_user LIKE '%s')", "%"+req.Search+"%", "%"+req.Search+"%", "%"+req.Search+"%")) } if req.CreateDateFrom != "" { finder.Where("tm.create_time >= ?", req.CreateDateFrom) } if req.CreateDateTo != "" { finder.Where("tm.create_time <= ?", req.CreateDateTo) } if req.HostGroupId != 0 { finder.Where("tm.host_group_id = ?", req.HostGroupId) } finder.OrderBy("tm.id") //查询任务 total, err = finder.Select("tm.id,tm.task_name,tm.task_desc,(select count(*) from task_history th "+ "where th.task_id = tm.id group by th.task_id) as exec_cnt,tm.create_user,tm.create_time"). Limit(req.PageSize, (req.Page-1)*req.PageSize).FindAndCount(&taskManageListRes) if err != nil { err = resp.DbSelectError.WithError(err) return } return } func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq) (err error) { if req.ScriptUrl != "" { minioClient, err := client.GetMinioConnect() if err != nil { return resp.DbConnectError.WithError(err) } object, err := minioClient.GetObject(context.Background(), conf.Options.MinioBucket, req.ScriptUrl, minio.GetObjectOptions{}) if err != nil { return resp.FileExecError.WithError(err) } obj, err := io.ReadAll(object) if err != nil { return resp.FileExecError.WithError(err) } req.Script = string(obj) } //var scripts []map[string]interface{} //var script map[string]interface{} //j2, err := yaml.YAMLToJSON([]byte(req.Script)) //if err != nil { // return nil, resp.YamlAnalysisError.WithError(err) //} //err = json.Unmarshal(j2, &scripts) //if err != nil { // return nil, resp.MarshalError.WithError(errors.New("yaml格式错误")) //} //script = scripts[0] //script["host"] = fmt.Sprintf("%s%d", AnsibleGroup, req.HostGroupId) //j, err := json.Marshal(script) //if err != nil { // return nil, resp.MarshalError.WithError(err) //} //y, err := yaml.JSONToYAML(j) //if err != nil { // return nil, resp.YamlAnalysisError.WithError(err) //} //req.Script = string(y) //写入执行脚本 fmt.Println("1111111111111111111111") f2, err := os.Create("/etc/ansible/ansible.yml") if err != nil { return resp.FileExecError.WithError(err) } defer f2.Close() _, err = f2.Write([]byte(req.Script)) if err != nil { return resp.FileExecError.WithError(err) } fmt.Println("2222222222222") //写入额外yml参数 if req.Type == 1 { //写入执行脚本 f3, err := os.Create("/etc/ansible/ansible_extra.yml") if err != nil { return resp.FileExecError.WithError(err) } defer f3.Close() _, err = f3.Write([]byte(req.Value)) if err != nil { return resp.FileExecError.WithError(err) } req.Value = fmt.Sprintf("@/etc/ansible/ansible_extra.yml") } var cmd *exec.Cmd if req.Value != "" { cmd = exec.Command("ansible-playbook", "/etc/ansible/ansible.yml", "--extra-vars", req.Value) } else { cmd = exec.Command("ansible-playbook", "/etc/ansible/ansible.yml") } fmt.Println("333333333333333") //捕获正常日志 stdout, err := cmd.StdoutPipe() if err != nil { return resp.CmdExecError.WithError(err) } //捕获异常日志 stderr, err := cmd.StderrPipe() if err != nil { return resp.CmdExecError.WithError(err) } //执行cmd命令 if err = cmd.Start(); err != nil { return resp.CmdExecError.WithError(err) } fmt.Println("4444444444444444444") //获取正常/异常 输出流 outputBuf := bufio.NewReader(stdout) readerr := bufio.NewReader(stderr) var out, outErr int for { fmt.Println("666666666666666") //逐行打印日志 lineOut, err1 := outputBuf.ReadString('\n') if (err1 != nil || io.EOF == err1) && out == 0 { fmt.Println("捕获标准输出line:", lineOut) fmt.Println("捕获标准输出err:", err1) out = 1 //break } else if out == 0 { fmt.Println("输出正常日志:", lineOut) } lineErr, err2 := readerr.ReadString('\n') if (err2 != nil || io.EOF == err2) && outErr == 0 { fmt.Println("捕获标准错误line:", lineErr) fmt.Println("捕获标准错误err:", err) outErr = 1 //break } else if outErr == 0 { fmt.Println("输出错误日志:", lineErr) } if out == 1 && outErr == 1 { break } } fmt.Println("55555555555555") cmd.Wait() fmt.Println("执行结束") return nil }