package trace import ( "fmt" "net/http" "time" "ems.agt/lib/core/cmd" "ems.agt/lib/core/conf" "ems.agt/lib/core/file" "ems.agt/lib/core/utils/ctx" "ems.agt/lib/core/vo/result" "ems.agt/lib/dborm" "ems.agt/lib/log" "ems.agt/restagent/config" ) var ( UriTcpdumpTask = config.DefaultUriPrefix + "/traceManagement/{apiVersion}/tcpdumpNeTask" CustomUriTcpdumpTask = config.UriPrefix + "/traceManagement/{apiVersion}/tcpdumpNeTask" // decode message api UriTcpdumpPcapDownload = config.DefaultUriPrefix + "/traceManagement/{apiVersion}/tcpdumpPcapDownload" CustomUriTcpdumpPcapDownload = config.UriPrefix + "/traceManagement/{apiVersion}/tcpdumpPcapDownload" // decode message api ) // NeInfo 网元信息 func NeInfo(neType, neId string) (*dborm.NeInfo, error) { neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { log.Error("dborm.XormGetNeInfo is failed:", err) return nil, err } if neInfo == nil || neInfo.Ip == "" { return nil, fmt.Errorf("not ne_info or not IP") } return neInfo, nil } // TcpdumpNeTask 网元发送执行 pcap func TcpdumpNeTask(w http.ResponseWriter, r *http.Request) { var body struct { NeType string `json:"neType"` // 网元类型 NeId string `json:"neId"` // 网元ID Timeout int `json:"timeout"` // 超时时间 Cmd string `json:"cmd"` // 命令 } err := ctx.ShouldBindJSON(r, &body) if err != nil || body.NeType == "" || body.NeId == "" || body.Timeout < 5 || body.Cmd == "" { ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) return } neInfo, err := NeInfo(body.NeType, body.NeId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } filePcapName := fmt.Sprintf("tmp_%s_%s_%d.pcap", body.NeType, body.NeId, time.Now().UnixMilli()) fileLogName := fmt.Sprintf("tmp_%s_%s_%d.log", body.NeType, body.NeId, time.Now().UnixMilli()) cmdStr := fmt.Sprintf("cd /tmp \n timeout %d tcpdump -i any %s -s0 -w %s >> %s 2>&1 \n cat %s", body.Timeout, body.Cmd, filePcapName, fileLogName, fileLogName) usernameNe := conf.Get("ne.user").(string) // 网元统一用户 sshHost := fmt.Sprintf("%s@%s", usernameNe, neInfo.Ip) msg, err := cmd.ExecWithCheck("ssh", sshHost, cmdStr) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } ctx.JSON(w, 200, result.OkData(map[string]any{ "msg": msg, "fileName": filePcapName, })) } // TcpdumpPcapDownload 网元抓包pcap文件下载 func TcpdumpPcapDownload(w http.ResponseWriter, r *http.Request) { var body struct { NeType string `json:"neType"` // 网元类型 NeId string `json:"neId"` // 网元ID FileName string `json:"fileName"` // 文件名 } err := ctx.ShouldBindJSON(r, &body) if err != nil || body.NeType == "" || body.NeId == "" || body.FileName == "" { ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) return } neInfo, err := NeInfo(body.NeType, body.NeId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } nePath := fmt.Sprintf("/tmp/%s", body.FileName) localPath := fmt.Sprintf("%s/tcpdump/pcap/%s", conf.Get("ne.omcdir"), body.FileName) err = file.FileSCPNeToLocal(neInfo.Ip, nePath, localPath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } ctx.FileAttachment(w, r, localPath, body.FileName) }