diff --git a/src/framework/utils/ssh/files.go b/src/framework/utils/ssh/files.go new file mode 100644 index 00000000..03b46c4c --- /dev/null +++ b/src/framework/utils/ssh/files.go @@ -0,0 +1,83 @@ +package ssh + +import ( + "fmt" + "strings" + + "ems.agt/src/framework/cmd" + "ems.agt/src/framework/config" + "ems.agt/src/framework/utils/parse" +) + +// FileListRow 文件列表行数据 +type FileListRow struct { + FileMode string `json:"fileMode"` // 文件的权限 + LinkCount int64 `json:"linkCount"` // 硬链接数目 + Owner string `json:"owner"` // 所属用户 + Group string `json:"group"` // 所属组 + Size string `json:"size"` // 文件的大小 + ModifiedTime int64 `json:"modifiedTime"` // 最后修改时间,单位为秒 + FileName string `json:"fileName"` // 文件的名称 +} + +// 文件列表 +// neIp 网元IP空字符串为本地 +// search 文件名后模糊* +// +// return 目录大小,行记录,异常 +func FileList(path, neIp, search string) (string, []FileListRow, error) { + total := "" + var rows []FileListRow + rowStr := "" + + // 发送命令 + searchStr := "" + if search != "" { + searchStr = search + "*" + } + pathStr := fmt.Sprintf("cd %s \n", path) + cmdStr := fmt.Sprintf("ls -lht --time-style=+%%s %s \n", searchStr) + + // 是否远程读取 + if neIp != "" { + usernameNe := config.Get("ne.user").(string) // 网元统一用户 + sshHost := fmt.Sprintf("%s@%s", usernameNe, neIp) + resultStr, err := cmd.ExecWithCheck("ssh", sshHost, pathStr, cmdStr) + if err != nil { + return total, rows, err + } + rowStr = resultStr + } else { + resultStr, err := cmd.Execf(pathStr, cmdStr) + if err != nil { + return total, rows, err + } + rowStr = resultStr + } + + // 遍历组装 + rowStrList := strings.Split(rowStr, "\n") + for i, rowStr := range rowStrList { + if rowStr == "" { + continue + } + // 使用空格对字符串进行切割 + fields := strings.Fields(rowStr) + + if i == 0 { + total = fields[1] + continue + } + // 提取各个字段的值 + rows = append(rows, FileListRow{ + FileMode: fields[0], + LinkCount: parse.Number(fields[1]), + Owner: fields[2], + Group: fields[3], + Size: fields[4], + ModifiedTime: parse.Number(fields[5]), + FileName: fields[6], + }) + } + return total, rows, nil +} diff --git a/src/framework/utils/ssh/scp.go b/src/framework/utils/ssh/scp.go index b303a9d5..2a50d786 100644 --- a/src/framework/utils/ssh/scp.go +++ b/src/framework/utils/ssh/scp.go @@ -6,44 +6,39 @@ import ( "os/exec" "path/filepath" - "ems.agt/lib/core/conf" - "ems.agt/lib/log" + "ems.agt/src/framework/config" + "ems.agt/src/framework/logger" ) // 网元NE 文件复制到远程文件 func FileSCPLocalToNe(neIp, localPath, nePath string) error { - usernameNe := conf.Get("ne.user").(string) + usernameNe := config.Get("ne.user").(string) // scp /path/to/local/file.txt user@remote-server:/path/to/remote/directory/ neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath) cmd := exec.Command("scp", "-r", localPath, neDir) - out, err := cmd.CombinedOutput() + _, err := cmd.CombinedOutput() if err != nil { + logger.Errorf("FileSCPLocalToNe %s", err.Error()) return err } - 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("FileSCPNeToLocal MkdirAll err %v", err) + if err := os.MkdirAll(filepath.Dir(localPath), 0750); err != nil { + logger.Errorf("FileSCPNeToLocal MkdirAll err %v", err) return err } - - usernameNe := conf.Get("ne.user").(string) + usernameNe := config.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() + _, err := cmd.CombinedOutput() if err != nil { + logger.Errorf("FileSCPNeToLocal %s", err.Error()) return err } - log.Infof("FileSCPNeToLocal %s", string(out)) return nil } diff --git a/src/modules/network_element/controller/ne_action.go b/src/modules/network_element/controller/ne_action.go index f001b631..55af9d17 100644 --- a/src/modules/network_element/controller/ne_action.go +++ b/src/modules/network_element/controller/ne_action.go @@ -66,3 +66,73 @@ func (s *NeActionController) PushFile(c *gin.Context) { neFilePath := fmt.Sprintf("%s/%s", nePath, fileName) c.JSON(200, result.OkData(filepath.ToSlash(neFilePath))) } + +// 从网元端获取文件 +// +// GET /pullFile +func (s *NeActionController) PullFile(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` + NeID string `form:"neId" binding:"required"` + Path string `form:"path" binding:"required"` + FileName string `form:"fileName" binding:"required"` + } + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) + if neInfo.NeId != querys.NeID || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + nePath := fmt.Sprintf("%s/%s", querys.Path, querys.FileName) + localPath := fmt.Sprintf("/tmp/omc/pullFile/%s", querys.FileName) + err := ssh.FileSCPNeToLocal(neInfo.IP, nePath, localPath) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.FileAttachment(localPath, querys.FileName) +} + +// 网元端文件列表 +// +// GET /files +func (s *NeActionController) Files(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` + NeID string `form:"neId" binding:"required"` + Path string `form:"path" binding:"required"` + PageNum int64 `form:"pageNum" binding:"required"` + PageSize int64 `form:"pageSize" binding:"required"` + Search string `form:"search"` + } + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) + if neInfo.NeId != querys.NeID || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + total, rows, err := ssh.FileList(querys.Path, neInfo.IP, querys.Search) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(map[string]any{ + "path": querys.Path, + "total": total, + "rows": rows, + })) +} diff --git a/src/modules/network_element/network_element.go b/src/modules/network_element/network_element.go index d156c50d..866095ec 100644 --- a/src/modules/network_element/network_element.go +++ b/src/modules/network_element/network_element.go @@ -25,7 +25,14 @@ func Setup(router *gin.Engine) { // 网元处理 neActionGroup := neGroup.Group("/action") { - // 发送文件到网元服务器 + neActionGroup.GET("/files", + middleware.PreAuthorize(nil), + controller.NewNeAction.Files, + ) + neActionGroup.GET("/pullFile", + middleware.PreAuthorize(nil), + controller.NewNeAction.PullFile, + ) neActionGroup.POST("/pushFile", middleware.PreAuthorize(nil), collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neAction", collectlogs.BUSINESS_TYPE_IMPORT)),