diff --git a/src/bean/vo/request/task_manage.go b/src/bean/vo/request/task_manage.go index b030dde441b69c5d892723e29d29de0cd6e4b33a..bc5e27555df5b98b18601deaed747b7b5393c6ac 100644 --- a/src/bean/vo/request/task_manage.go +++ b/src/bean/vo/request/task_manage.go @@ -37,4 +37,5 @@ type ExecScriptReq struct { Type int `form:"type"` //脚本额外变量类型1yaml 2json Value string `form:"value"` //脚本额外变量值 Script string `form:"script"` //执行脚本 + ScriptUrl string `form:"script_url"` //执行脚本url } diff --git a/src/common/tools/hosts b/src/common/tools/hosts new file mode 100644 index 0000000000000000000000000000000000000000..2d3faefd5924c63ae482dc9f83627c6b733dbd5b --- /dev/null +++ b/src/common/tools/hosts @@ -0,0 +1,16 @@ +[HostGroup] +HostIp192.168.0.1 ansible_ssh_host=192.168.0.1 ansible_ssh_port=22 ansible_ssh_user="admin" ansible_ssh_pass="123456" +HostIp192.186.10.1 ansible_ssh_host=192.186.10.1 ansible_ssh_port=22 ansible_ssh_user="admin" ansible_ssh_pass="123456" +HostIp101.168.0.1 ansible_ssh_host=101.168.0.1 ansible_ssh_port=22 ansible_ssh_user="root" ansible_ssh_pass="" +HostIp101.186.10.1 ansible_ssh_host=101.186.10.1 ansible_ssh_port=22 ansible_ssh_user="root" ansible_ssh_pass="" +[webGroup1] +192.168.0.11 ansible_ssh_host=192.168.0.11 ansible_ssh_user=root ansible_ssh_pass=123.com ansible_ssh_port=3333 +192.168.0.12 ansible_ssh_host=192.168.0.12 ansible_ssh_user=root ansible_ssh_pass=1234.com ansible_ssh_port=2222 +[webGroup2] +192.168.1.11 ansible_ssh_host=192.168.1.11 ansible_ssh_user=admin ansible_ssh_pass=ccc.com ansible_ssh_port=11 +192.168.1.12 ansible_ssh_host=192.168.1.12 ansible_ssh_user=admin ansible_ssh_pass=111.com ansible_ssh_port=22 +[HostGroup15] +HostIp22 ansible_ssh_host=192.168.0.1 ansible_ssh_port=22 ansible_ssh_user="admin" ansible_ssh_pass="123456" +HostIp23 ansible_ssh_host=192.186.10.1 ansible_ssh_port=22 ansible_ssh_user="admin" ansible_ssh_pass="123456" +HostIp24 ansible_ssh_host=101.168.0.1 ansible_ssh_port=22 ansible_ssh_user="root" ansible_ssh_pass="" +HostIp25 ansible_ssh_host=101.186.10.1 ansible_ssh_port=22 ansible_ssh_user="root" ansible_ssh_pass="" diff --git a/src/common/tools/hosts.go b/src/common/tools/hosts.go new file mode 100644 index 0000000000000000000000000000000000000000..c526acc85f00e8ac100f6718ed7f4896b15db96a --- /dev/null +++ b/src/common/tools/hosts.go @@ -0,0 +1,62 @@ +package tools + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +func HostsToJson() (data map[string][]string, err error) { + f, err := os.Open(`/etc/ansible/hosts`) + //f, err := os.Open(`D:\work\goWork\智能运维平台\so-operation-api\src\common\tools\hosts`) + + if err != nil { + return nil, err + } + defer f.Close() + data = make(map[string][]string) + // 以这个文件为参数,创建一个 scanner + s := bufio.NewScanner(f) + var key string + var per []string + // 扫描每行文件,按行读取 + for s.Scan() { + if strings.HasPrefix(s.Text(), "[") && strings.HasSuffix(s.Text(), "]") { + key = s.Text() + per = []string{} + data[key] = per + } else { + data[key] = append(data[key], s.Text()) + } + } + if s.Err() != nil { + return nil, s.Err() + } + return data, nil +} + +func MapToSaveHosts(data map[string][]string) error { + f, err := os.OpenFile("/etc/ansible/hosts", os.O_APPEND|os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777) + //f, err := os.OpenFile("D:/work/goWork/智能运维平台/so-operation-api/src/common/tools/hosts", os.O_APPEND|os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777) + + if err != nil { + return err + } + defer f.Close() + for k, v := range data { + _, err = f.Write([]byte(fmt.Sprintf("%s\n", k))) + if err != nil { + return err + } + _, err = f.Write([]byte(strings.Join(v, "\n"))) + if err != nil { + return err + } + _, err = f.Write([]byte("\n")) + if err != nil { + return err + } + } + return nil +} diff --git a/src/controller/task_manage.go b/src/controller/task_manage.go index 39036024025a0b36bcebece9f91995a241a27014..2dfda13135e6e67484855efc297160e778d63581 100644 --- a/src/controller/task_manage.go +++ b/src/controller/task_manage.go @@ -123,6 +123,7 @@ func ExecScript(c *gin.Context) { SendJsonResponse(c, resp.InvalidParam.WithError(err), nil) return } + taskManageSvc := service.TaskManageSvc{} data, err := taskManageSvc.ExecScript(req) if err != nil { diff --git a/src/service/host_manage.go b/src/service/host_manage.go index 5d23cf4ead3e12ba947cfa3f7ad6b63c205edfa3..39a647e917332d5eb78325227dadafd22064c37a 100644 --- a/src/service/host_manage.go +++ b/src/service/host_manage.go @@ -11,8 +11,8 @@ import ( "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" - "os" "os/exec" "strings" "time" @@ -22,7 +22,8 @@ type HostManageSvc struct { User *entity.SystemUser } -const AnsibleGroup string = "HostManage" +const AnsibleGroup string = "HostGroup" +const AnsibleIp string = "HostIp" // AddHostManage 新增主机 func (h *HostManageSvc) AddHostManage(req request.AddHostManageReq) (err error) { @@ -84,12 +85,22 @@ func (h *HostManageSvc) AddHostManage(req request.AddHostManageReq) (err error) return } + //读取hosts中的主机组 + hosts, err := tools.HostsToJson() + if err != nil { + err = resp.MarshalError.WithError(err) + session.Rollback() + return + } + hosts["["+AnsibleGroup+fmt.Sprintf("%d", hostManage.Id)+"]"] = nil + //新增主机分组列表 for _, v := range hostManageLists { port := "22" if v.Port != "" { port = v.Port } + hostManageList := entity.HostManageList{ Ip: v.Ip, Port: port, @@ -106,6 +117,18 @@ func (h *HostManageSvc) AddHostManage(req request.AddHostManageReq) (err error) session.Rollback() return } + + hostsIp := fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"", + AnsibleIp+fmt.Sprintf("%d", hostManageList.Id), v.Ip, v.Port, v.UserName, v.Password) + hosts["["+AnsibleGroup+fmt.Sprintf("%d", hostManage.Id)+"]"] = append(hosts["["+AnsibleGroup+fmt.Sprintf("%d", hostManage.Id)+"]"], hostsIp) + } + + //写入hosts + err = tools.MapToSaveHosts(hosts) + if err != nil { + err = resp.MarshalError.WithError(err) + session.Rollback() + return } session.Commit() @@ -166,6 +189,14 @@ func (h *HostManageSvc) EditHostManage(req request.EditHostManageReq) (err error return } + //读取hosts中的主机组 + hosts, err := tools.HostsToJson() + if err != nil { + err = resp.MarshalError.WithError(err) + return + } + hosts["["+AnsibleGroup+fmt.Sprintf("%d", req.Id)+"]"] = nil + //新增主机分组列表 for _, v := range hostManageLists { port := "22" @@ -188,8 +219,19 @@ func (h *HostManageSvc) EditHostManage(req request.EditHostManageReq) (err error session.Rollback() return } + + hostsIp := fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"", + AnsibleIp+fmt.Sprintf("%d", hostManageList.Id), v.Ip, v.Port, v.UserName, v.Password) + hosts["["+AnsibleGroup+fmt.Sprintf("%d", req.Id)+"]"] = append(hosts["["+AnsibleGroup+fmt.Sprintf("%d", req.Id)+"]"], hostsIp) + } + //写入hosts + err = tools.MapToSaveHosts(hosts) + if err != nil { + err = resp.MarshalError.WithError(err) + return + } session.Commit() return } @@ -352,22 +394,22 @@ func (h *HostManageSvc) ListStateHostManage(req request.StateHostManageReq) (err } //往hosts文件中写入主机组ip - f, err := os.OpenFile("/etc/ansible/hosts", os.O_APPEND|os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777) - if err != nil { - err = resp.FileExecError.WithError(err) - return - } - defer f.Close() - _, err = f.Write([]byte(fmt.Sprintf("%s%d\n", AnsibleGroup, req.Id))) - if err != nil { - return resp.FileExecError.WithError(err) - } - for _, v := range hostManageList { - _, err = f.Write([]byte(fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"\n", v.Ip, v.Ip, v.Port, v.UserName, v.Password))) - if err != nil { - return resp.FileExecError.WithError(err) - } - } + //f, err := os.OpenFile("/etc/ansible/hosts", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0777) + //if err != nil { + // err = resp.FileExecError.WithError(err) + // return + //} + //defer f.Close() + //_, err = f.Write([]byte(fmt.Sprintf("%s%d\n", AnsibleGroup, req.Id))) + //if err != nil { + // return resp.FileExecError.WithError(err) + //} + //for _, v := range hostManageList { + // _, err = f.Write([]byte(fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"\n", v.Ip, v.Ip, v.Port, v.UserName, v.Password))) + // if err != nil { + // return resp.FileExecError.WithError(err) + // } + //} for _, v := range hostManageList { //修改状态 _, err = session.Table("host_manage_list").Where("is_delete = 0 AND id = ?", v.Id). @@ -393,7 +435,7 @@ func (h *HostManageSvc) SaveStateHostManage(hostManageList []request.HostManageL } //处理ip列表 ipGroup := 1 - HostManageListCaches := make([]entity.HostManageListCache, 0) + hostManageListCaches := make([]entity.HostManageListCache, 0) for _, v := range hostManageList { port := "22" if v.Port != "" { @@ -410,40 +452,52 @@ func (h *HostManageSvc) SaveStateHostManage(hostManageList []request.HostManageL Password: v.Password, IpGroup: ipGroup, } - HostManageListCaches = append(HostManageListCaches, HostManageListCache) + hostManageListCaches = append(hostManageListCaches, HostManageListCache) } ipGroup += 1 } - //往hosts文件中写入主机组ip - f, err := os.OpenFile("/etc/ansible/hosts", os.O_APPEND|os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777) + //读取hosts中的主机组 + hosts, err := tools.HostsToJson() if err != nil { - err = resp.FileExecError.WithError(err) + err = resp.MarshalError.WithError(err) return } - defer f.Close() - for _, v := range hostManageList { - _, err = f.Write([]byte(fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"\n", v.Ip, v.Ip, v.Port, v.UserName, v.Password))) - if err != nil { - err = resp.FileExecError.WithError(err) - return - } + if _, ok := hosts["["+AnsibleGroup+"]"]; !ok { + // 不存在 + hosts["["+AnsibleGroup+"]"] = nil } - //状态检测 - id = uuid.New().String() + for _, v := range hostManageListCaches { + + hostsIp := fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"", AnsibleIp+v.Ip, v.Ip, v.Port, v.UserName, v.Password) + 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 { - err = resp.FAIL.WithError(err) + err = resp.MarshalError.WithError(err) return } - for k, v := range HostManageListCaches { + + //状态检测 + id = uuid.New().String() + for k, v := range hostManageListCaches { //调用状态检测函数 - HostManageListCaches[k].ConnStatus = StatusDetection(v.Ip) - HostManageListCaches[k].Id = id + hostManageListCaches[k].ConnStatus = StatusDetection(v.Ip) + hostManageListCaches[k].Id = id } //存入数据库 - _, err = db.Table("host_manage_list_cache").Insert(&HostManageListCaches) + _, err = db.Table("host_manage_list_cache").Insert(&hostManageListCaches) if err != nil { err = resp.DbInsertError.WithError(err) return @@ -509,7 +563,7 @@ func (h *HostManageSvc) SaveIpExceptionList(req request.HostIpExceptionListReq) // StatusDetection 状态检测 func StatusDetection(ip string) (ipConn int) { var cmd *exec.Cmd - cmd = exec.Command("ansible", fmt.Sprintf("%s", ip), "-m", "ping") + cmd = exec.Command("ansible", fmt.Sprintf("%s", AnsibleIp+ip), "-m", "ping") output, err := cmd.Output() if err != nil { fmt.Println("ping:", string(output)) diff --git a/src/service/task_manage.go b/src/service/task_manage.go index 2c7edbede10e0155c5e534caa339e4912999e927..a82f5427f34835fe01fd65ba476dda72f33dcf5b 100644 --- a/src/service/task_manage.go +++ b/src/service/task_manage.go @@ -1,15 +1,19 @@ package service import ( + "context" "errors" "fmt" "github.com/ghodss/yaml" json "github.com/json-iterator/go" + "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" @@ -174,6 +178,21 @@ func (t *TaskManageSvc) ListTaskManage(req request.ListTaskManageReq) (total int } func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq) (data interface{}, err error) { + if req.ScriptUrl != "" { + minioClient, err := client.GetMinioConnect() + if err != nil { + return nil, resp.DbConnectError.WithError(err) + } + object, err := minioClient.GetObject(context.Background(), conf.Options.MinioBucket, req.ScriptUrl, minio.GetObjectOptions{}) + if err != nil { + return nil, resp.FileExecError.WithError(err) + } + obj, err := io.ReadAll(object) + if err != nil { + return nil, resp.FileExecError.WithError(err) + } + req.Script = string(obj) + } var script map[string]interface{} j2, err := yaml.YAMLToJSON([]byte(req.Script)) if err != nil { @@ -181,7 +200,7 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq) (data interface{}, } err = json.Unmarshal(j2, &script) if err != nil { - return nil, resp.MarshalError.WithError(err) + return nil, resp.MarshalError.WithError(errors.New("yaml格式错误")) } if script["host"] == "all" { script["host"] = fmt.Sprintf("%s%d", AnsibleGroup, req.HostGroupId)