Merge branch 'main' of http://192.168.0.229:3180/OMC/ems_backend
This commit is contained in:
104
features/trace/tcpdump.go
Normal file
104
features/trace/tcpdump.go
Normal file
@@ -0,0 +1,104 @@
|
||||
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)
|
||||
}
|
||||
@@ -561,23 +561,23 @@ func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 文件名
|
||||
fileName := fmt.Sprintf("OMC_AUTH_USER_IMPORT_%s_%d_%s", neId, time.Now().UnixMilli(), fileHeader.Filename)
|
||||
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
||||
dstPath := conf.Get("mml.upload").(string)
|
||||
localPath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
||||
nePath := conf.Get("mml.upload").(string)
|
||||
// 输出保存文件
|
||||
err = ctx.SaveUploadedFile(r, filePath)
|
||||
err = ctx.SaveUploadedFile(r, localPath)
|
||||
if err != nil {
|
||||
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 复制到远程
|
||||
err = file.FileNeSCP(neInfo.Ip, filePath, dstPath)
|
||||
err = file.FileSCPLocalToNe(neInfo.Ip, localPath, nePath)
|
||||
if err != nil {
|
||||
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("import authdat:path=%s", fmt.Sprintf("%s/%s", dstPath, fileName))
|
||||
msg := fmt.Sprintf("import authdat:path=%s", fmt.Sprintf("%s/%s", nePath, fileName))
|
||||
|
||||
// 发送MML
|
||||
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
||||
@@ -589,12 +589,12 @@ func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) {
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
if strings.HasSuffix(fileHeader.Filename, ".csv") {
|
||||
data := file.ReadCSVFile(filePath)
|
||||
data := file.ReadCSVFile(localPath)
|
||||
neId = "-"
|
||||
s.authUser.InsertCSV(neId, data)
|
||||
}
|
||||
if strings.HasSuffix(fileHeader.Filename, ".txt") {
|
||||
data := file.ReadTxtFile(filePath)
|
||||
data := file.ReadTxtFile(localPath)
|
||||
neId = "-"
|
||||
s.authUser.InsertTxt(neId, data)
|
||||
}
|
||||
@@ -1125,23 +1125,23 @@ func (s *UdmUserApi) UdmSubUserImport(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 文件名
|
||||
fileName := fmt.Sprintf("OMC_SUB_USER_IMPORT_%s_%d_%s", neId, time.Now().UnixMilli(), fileHeader.Filename)
|
||||
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
||||
dstPath := conf.Get("mml.upload").(string)
|
||||
localPath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
||||
nePath := conf.Get("mml.upload").(string)
|
||||
// 输出保存文件
|
||||
err = ctx.SaveUploadedFile(r, filePath)
|
||||
err = ctx.SaveUploadedFile(r, localPath)
|
||||
if err != nil {
|
||||
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 复制到远程
|
||||
err = file.FileNeSCP(neInfo.Ip, filePath, dstPath)
|
||||
err = file.FileSCPLocalToNe(neInfo.Ip, localPath, nePath)
|
||||
if err != nil {
|
||||
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("import udmuser:path=%s", fmt.Sprintf("%s/%s", dstPath, fileName))
|
||||
msg := fmt.Sprintf("import udmuser:path=%s", fmt.Sprintf("%s/%s", nePath, fileName))
|
||||
|
||||
// 发送MML
|
||||
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
||||
@@ -1152,12 +1152,12 @@ func (s *UdmUserApi) UdmSubUserImport(w http.ResponseWriter, r *http.Request) {
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
if strings.HasSuffix(fileHeader.Filename, ".csv") {
|
||||
data := file.ReadCSVFile(filePath)
|
||||
data := file.ReadCSVFile(localPath)
|
||||
neId = "-"
|
||||
s.subUser.InsertCSV(neId, data)
|
||||
}
|
||||
if strings.HasSuffix(fileHeader.Filename, ".txt") {
|
||||
data := file.ReadTxtFile(filePath)
|
||||
data := file.ReadTxtFile(localPath)
|
||||
neId = "-"
|
||||
s.subUser.InsertTxt(neId, data)
|
||||
}
|
||||
|
||||
@@ -2,22 +2,48 @@ package file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"ems.agt/lib/core/conf"
|
||||
"ems.agt/lib/log"
|
||||
)
|
||||
|
||||
// 网元NE 文件复制到远程文件夹
|
||||
func FileNeSCP(neIp, filePath, dstPath string) error {
|
||||
// 网元NE 文件复制到远程文件
|
||||
func FileSCPLocalToNe(neIp, localPath, nePath string) error {
|
||||
usernameNe := conf.Get("ne.user").(string)
|
||||
// scp /path/to/local/file.txt user@remote-server:/path/to/remote/directory/
|
||||
dstDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, dstPath)
|
||||
cmd := exec.Command("scp", "-r", filePath, dstDir)
|
||||
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
||||
cmd := exec.Command("scp", "-r", localPath, neDir)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("FileNeSCP %s", string(out))
|
||||
log.Infof("FileSCPLocalToNe %s", string(out))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 网元NE 远程文件复制到本地文件
|
||||
func FileSCPNeToLocal(neIp, nePath, localPath string) error {
|
||||
// 获取文件所在的目录路径
|
||||
dirPath := filepath.Dir(localPath)
|
||||
|
||||
// 确保文件夹路径存在
|
||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Errorf("创建文件夹失败 CreateFile %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
usernameNe := conf.Get("ne.user").(string)
|
||||
// scp user@remote-server:/path/to/remote/directory/ /path/to/local/file.txt
|
||||
neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath)
|
||||
cmd := exec.Command("scp", "-r", neDir, localPath)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("FileSCPNeToLocal %s", string(out))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -239,6 +239,13 @@ func init() {
|
||||
Register("PUT", trace.CustomUriTraceTask, trace.PutTraceTaskToNF, nil)
|
||||
Register("DELETE", trace.CustomUriTraceTask, trace.DeleteTraceTaskToNF, nil)
|
||||
|
||||
// 网元发送执行 pcap抓包
|
||||
Register("POST", trace.UriTcpdumpTask, trace.TcpdumpNeTask, nil)
|
||||
Register("POST", trace.CustomUriTcpdumpTask, trace.TcpdumpNeTask, nil)
|
||||
// 网元发送执行 抓包下载pcap文件
|
||||
Register("POST", trace.UriTcpdumpPcapDownload, trace.TcpdumpPcapDownload, nil)
|
||||
Register("POST", trace.CustomUriTcpdumpPcapDownload, trace.TcpdumpPcapDownload, nil)
|
||||
|
||||
// file management
|
||||
Register("POST", file.UriFile, file.UploadFile, nil)
|
||||
Register("GET", file.UriFile, file.DownloadFile, nil)
|
||||
|
||||
Reference in New Issue
Block a user