github.com/HXSecurity/DongTai-agent-go@v0.4.2/service/engine.go (about) 1 package service 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "encoding/json" 7 "fmt" 8 "os/exec" 9 "regexp" 10 "strconv" 11 "strings" 12 "time" 13 14 "github.com/HXSecurity/DongTai-agent-go/api" 15 "github.com/HXSecurity/DongTai-agent-go/global" 16 "github.com/HXSecurity/DongTai-agent-go/hook" 17 "github.com/HXSecurity/DongTai-agent-go/utils" 18 "net" 19 "os" 20 "runtime" 21 22 // "github.com/HXSecurity/DongTai-agent-go/api" 23 "github.com/HXSecurity/DongTai-agent-go/model/request" 24 ) 25 26 var live bool 27 28 func CreateCircuitBreaker() func() (err error) { 29 var count int 30 var circuit bool 31 return func() (err error) { 32 limit := api.Limit() 33 cpuLimit, ferr := strconv.ParseFloat(limit["cpu_limit"], 32) 34 if ferr != nil || cpuLimit == 0 { 35 cpuLimit = 100 36 return 37 } 38 s, err := getServerInfo() 39 var cpuNum float64 40 cpus := s.Cpu.Cpus 41 for _, k := range cpus { 42 cpuNum += k 43 } 44 cpu := cpuNum / float64(len(cpus)) 45 if cpu > cpuLimit { 46 if count >= 5 { 47 circuit = true 48 count = 0 49 StopAgent() 50 return 51 } 52 count++ 53 } 54 if cpu <= cpuLimit { 55 count = 0 56 if circuit { 57 RunAgent() 58 } 59 } 60 return nil 61 } 62 } 63 64 func StopAgent() { 65 live = false 66 hook.HookAll(global.AllHooks...) 67 } 68 69 func RunAgent() { 70 live = true 71 hook.UnHookAll(global.AllHooks...) 72 } 73 74 func AgentRegister() (err error) { 75 max := 6 76 breaker := CreateCircuitBreaker() 77 live = true 78 OS := runtime.GOOS 79 hostname, _ := os.Hostname() 80 version := "1.0.0" 81 packages, agentVersion := GetMod() 82 if global.Config.DongtaiGoProjectVersion != "" { 83 version = global.Config.DongtaiGoProjectVersion 84 } 85 projectName := "project Name" 86 if global.Config.DongtaiGoProjectVersion != "" { 87 projectName = global.Config.DongtaiGoProjectName 88 } 89 name := OS + "-" + hostname + "-" + version 90 interfaces, err := net.Interfaces() 91 if err != nil { 92 return 93 } 94 95 ips := "" 96 97 for _, i := range interfaces { 98 byName, err := net.InterfaceByName(i.Name) 99 if err != nil { 100 return err 101 } 102 addresses, err := byName.Addrs() 103 for _, v := range addresses { 104 if ips == "" { 105 ips = "{\"name\":" + byName.Name + ",\"ip\":" + v.String() + "}" 106 } else { 107 ips += ",{\"name\":" + byName.Name + ",\"ip\":" + v.String() + "}" 108 } 109 } 110 } 111 pid := os.Getpid() 112 envMap := make(map[string]string) 113 envs := os.Environ() 114 for _, v := range envs { 115 parts := strings.SplitN(v, "=", 2) 116 if len(parts) != 2 { 117 continue 118 } else { 119 envMap[parts[0]] = parts[1] 120 } 121 } 122 envB, err := json.Marshal(envMap) 123 if err != nil { 124 return err 125 } 126 encodeEnv := base64.StdEncoding.EncodeToString(envB) 127 128 filePath, err := getCurrentPath() 129 if err != nil { 130 return err 131 } 132 req := request.AgentRegisterReq{ 133 AutoCreateProject: global.Config.DongtaiGoProjectCreate, 134 Name: name, 135 Language: "GO", 136 Version: agentVersion, 137 ProjectVersion: version, 138 ProjectName: projectName, 139 Hostname: hostname, 140 Network: ips, 141 ContainerName: "GO", 142 ContainerVersion: "GO", 143 ServerAddr: "", 144 ServerPort: "", 145 ServerPath: filePath, 146 ServerEnv: encodeEnv, 147 Pid: strconv.Itoa(pid), 148 } 149 go func() { 150 for { 151 max = max - 1 152 fmt.Printf("等待当前程序当前程序启动完成,剩余%d次", max) 153 time.Sleep(1 * time.Second) 154 ip, err := utils.ExternalIP() 155 if err != nil { 156 fmt.Println(err) 157 } 158 var cmd *exec.Cmd 159 var strErr bytes.Buffer 160 var out bytes.Buffer 161 if OS == "windows" { 162 cmd = exec.Command("netstat", "-ano") 163 cmd.Stderr = &strErr 164 cmd.Stdout = &out 165 } else { 166 cmd = exec.Command("netstat", "-antup", "|grep", req.Pid) 167 cmd.Stderr = &strErr 168 cmd.Stdout = &out 169 } 170 fmt.Println("等待当前程序端口返回") 171 err = cmd.Run() 172 fmt.Println("等待当前程序端口返回成功") 173 output := out.String() 174 if err != nil { 175 return 176 } 177 var matches [][]string 178 if OS == "windows" { 179 str := "" 180 for { 181 line, setErr := out.ReadBytes('\n') 182 if setErr != nil { 183 break 184 } 185 if strings.Index(string(line), " "+req.Pid) > -1 { 186 str += string(line) + "\n" 187 } 188 } 189 r := regexp.MustCompile(`0.0.0.0:\s*(.*?)\s* `) 190 matches = r.FindAllStringSubmatch(str, -1) 191 } else { 192 r := regexp.MustCompile(`:::\s*(.*?)\s* `) 193 matches = r.FindAllStringSubmatch(output, -1) 194 } 195 if matches != nil || max == 0 { 196 if matches[0] != nil || max == 0 { 197 if matches[0][1] != "" || max == 0 { 198 fmt.Println("当前程序启动完成") 199 if max == 0 { 200 req.ServerPort = "" 201 } else { 202 req.ServerPort = matches[0][1] 203 } 204 req.ServerAddr = ip.String() 205 agentId, err := api.AgentRegister(req) 206 if err != nil { 207 fmt.Println(err) 208 break 209 } 210 global.AgentId = agentId 211 UploadSca(packages) 212 go func() { 213 for { 214 time.Sleep(10 * time.Second) 215 PingPang() 216 breaker() 217 } 218 }() 219 break 220 } 221 } 222 } 223 224 } 225 }() 226 return nil 227 } 228 229 func PingPang() { 230 s, err := getServerInfo() 231 if err != nil { 232 return 233 } 234 var req request.UploadReq 235 cpuMap := make(map[string]string) 236 memoryMap := make(map[string]string) 237 var cpus float64 = 0 238 for _, v := range s.Cpu.Cpus { 239 cpus += v 240 } 241 cpuRate := fmt.Sprintf("%.2f", cpus/float64(len(s.Cpu.Cpus))) 242 memoryRate := fmt.Sprintf("%.2f", float64(s.Rrm.UsedMB)/float64(s.Rrm.TotalMB)) 243 total := strconv.Itoa(s.Rrm.TotalMB) + "MB" 244 use := strconv.Itoa(s.Rrm.UsedMB) + "MB" 245 cpuMap["rate"] = cpuRate 246 memoryMap["total"] = total 247 memoryMap["use"] = use 248 memoryMap["rate"] = memoryRate 249 cpuByte, _ := json.Marshal(cpuMap) 250 memoryByte, _ := json.Marshal(memoryMap) 251 252 req.Type = 1 253 req.Detail.Pant.Disk = "{}" 254 req.Detail.Pant.Cpu = string(cpuByte) 255 req.Detail.Pant.Memory = string(memoryByte) 256 req.Detail.Pant.IsCoreRunning = 1 257 req.Detail.Pant.IsCoreInstalled = 1 258 req.Detail.AgentId = global.AgentId 259 api.ReportUpload(req) 260 } 261 func UploadSca(packages []request.Component) { 262 var req request.UploadReq 263 req.Type = 18 264 req.Detail.AgentId = global.AgentId 265 req.Detail.Packages = packages 266 api.ReportUpload(req) 267 }