453 lines
14 KiB
Go
453 lines
14 KiB
Go
package controller
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"be.ems/src/framework/i18n"
|
|
"be.ems/src/framework/reqctx"
|
|
"be.ems/src/framework/resp"
|
|
"be.ems/src/framework/ssh"
|
|
"be.ems/src/framework/utils/file"
|
|
"be.ems/src/framework/utils/generate"
|
|
neService "be.ems/src/modules/network_element/service"
|
|
)
|
|
|
|
// 实例化控制层 NeActionController 结构体
|
|
var NewNeAction = &NeActionController{
|
|
neInfoService: neService.NewNeInfo,
|
|
}
|
|
|
|
// 网元处理请求
|
|
//
|
|
// PATH /action
|
|
type NeActionController struct {
|
|
// 网元信息服务
|
|
neInfoService *neService.NeInfo
|
|
}
|
|
|
|
// 从本地到网元发送文件
|
|
//
|
|
// POST /pushFile
|
|
//
|
|
// @Tags network_element/action
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param data body object true "Request Param"
|
|
// @Success 200 {object} object "Response Results"
|
|
// @Security TokenAuth
|
|
// @Summary Sending files from local to network elements
|
|
// @Description Sending files from local to network elements
|
|
// @Router /ne/action/pushFile [post]
|
|
func (s *NeActionController) PushFile(c *gin.Context) {
|
|
language := reqctx.AcceptLanguage(c)
|
|
var body struct {
|
|
NeType string `json:"neType" binding:"required"`
|
|
NeID string `json:"neId" binding:"required"`
|
|
UploadPath string `json:"uploadPath" binding:"required"`
|
|
DelTemp bool `json:"delTemp"` // 删除本地临时文件
|
|
}
|
|
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
|
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
|
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
|
return
|
|
}
|
|
|
|
// 查询网元获取IP
|
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(body.NeType, body.NeID)
|
|
if neInfo.NeId != body.NeID || neInfo.IP == "" {
|
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
|
return
|
|
}
|
|
|
|
// 网元主机的SSH客户端
|
|
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId)
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sshClient.Close()
|
|
// 网元主机的SSH客户端进行文件传输
|
|
sftpClient, err := sshClient.NewClientSFTP()
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sftpClient.Close()
|
|
|
|
// 本地文件
|
|
localFilePath := file.ParseUploadFileAbsPath(body.UploadPath)
|
|
// 网元端临时目录
|
|
sshClient.RunCMD("sudo mkdir -p /tmp/omc/push && sudo chmod 777 -R /tmp/omc")
|
|
neFilePath := filepath.ToSlash(filepath.Join("/tmp/omc/push", filepath.Base(localFilePath)))
|
|
// 复制到远程
|
|
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
|
c.JSON(200, resp.ErrMsg("Please check if the file exists or if scp is allowed to copy remotely"))
|
|
return
|
|
}
|
|
|
|
defer func() {
|
|
if body.DelTemp {
|
|
_ = os.Remove(localFilePath)
|
|
}
|
|
}()
|
|
c.JSON(200, resp.OkData(filepath.ToSlash(neFilePath)))
|
|
}
|
|
|
|
// 从网元到本地获取文件
|
|
//
|
|
// GET /pullFile
|
|
//
|
|
// @Tags network_element/action
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) default(UPF)
|
|
// @Param neId query string true "NE ID" default(001)
|
|
// @Param path query string true "dir path" default(/var/log)
|
|
// @Param fileName query string true "file name"
|
|
// @Param delTemp query boolean false "Delete Temp File" default(false)
|
|
// @Success 200 {object} object "Response Results"
|
|
// @Security TokenAuth
|
|
// @Summary Getting files from the network element to the local
|
|
// @Description Getting files from the network element to the local
|
|
// @Router /ne/action/pullFile [get]
|
|
func (s *NeActionController) PullFile(c *gin.Context) {
|
|
language := reqctx.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"`
|
|
DelTemp bool `form:"delTemp"` // 删除本地临时文件
|
|
}
|
|
if err := c.ShouldBindQuery(&querys); err != nil {
|
|
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
|
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
|
return
|
|
}
|
|
|
|
// 查询网元获取IP
|
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
|
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
|
return
|
|
}
|
|
|
|
// 网元主机的SSH客户端
|
|
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId)
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sshClient.Close()
|
|
// 网元主机的SSH客户端进行文件传输
|
|
sftpClient, err := sshClient.NewClientSFTP()
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sftpClient.Close()
|
|
|
|
nePath := filepath.ToSlash(filepath.Join(querys.Path, querys.FileName))
|
|
fileName := generate.Code(6) + "_" + querys.FileName
|
|
localFilePath := filepath.Join("/tmp/omc/pull", fileName)
|
|
if runtime.GOOS == "windows" {
|
|
localFilePath = fmt.Sprintf("C:%s", localFilePath)
|
|
}
|
|
// 复制到本地
|
|
if err = sftpClient.CopyFileRemoteToLocal(nePath, localFilePath); err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
|
|
defer func() {
|
|
if querys.DelTemp {
|
|
_ = os.Remove(localFilePath)
|
|
}
|
|
}()
|
|
c.FileAttachment(localFilePath, fileName)
|
|
}
|
|
|
|
// 从网元到本地获取目录压缩为ZIP
|
|
//
|
|
// GET /pullDirZip
|
|
//
|
|
// @Tags network_element/action
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) default(UPF)
|
|
// @Param neId query string true "NE ID" default(001)
|
|
// @Param path query string true "dir path" default(/var/log)
|
|
// @Param delTemp query boolean false "Delete Temp File" default(false)
|
|
// @Success 200 {object} object "Response Results"
|
|
// @Security TokenAuth
|
|
// @Summary Get directories compressed to ZIP from the network element to the local area
|
|
// @Description Get directories compressed to ZIP from the network element to the local area
|
|
// @Router /ne/action/pullDirZip [get]
|
|
func (s *NeActionController) PullDirZip(c *gin.Context) {
|
|
language := reqctx.AcceptLanguage(c)
|
|
var querys struct {
|
|
NeType string `form:"neType" binding:"required"`
|
|
NeID string `form:"neId" binding:"required"`
|
|
Path string `form:"path" binding:"required"`
|
|
DelTemp bool `form:"delTemp"` // 删除本地临时文件
|
|
}
|
|
if err := c.ShouldBindQuery(&querys); err != nil {
|
|
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
|
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
|
return
|
|
}
|
|
|
|
// 查询网元获取IP
|
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
|
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
|
return
|
|
}
|
|
|
|
// 网元主机的SSH客户端
|
|
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId)
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sshClient.Close()
|
|
// 网元主机的SSH客户端进行文件传输
|
|
sftpClient, err := sshClient.NewClientSFTP()
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sftpClient.Close()
|
|
|
|
nePath := querys.Path
|
|
dirName := generate.Code(6)
|
|
localFilePath := filepath.Join("/tmp/omc/pull/", dirName)
|
|
if runtime.GOOS == "windows" {
|
|
localFilePath = fmt.Sprintf("C:%s", localFilePath)
|
|
}
|
|
// 复制到本地
|
|
localDirFilePath := filepath.Join(localFilePath, "zip")
|
|
if err = sftpClient.CopyDirRemoteToLocal(nePath, localDirFilePath); err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
|
|
// 压缩zip文件名
|
|
zipFileName := fmt.Sprintf("%s-%s-%s.zip", neInfo.NeType, neInfo.NeId, dirName)
|
|
zipFilePath := filepath.Join(localFilePath, zipFileName)
|
|
if err := file.CompressZipByDir(zipFilePath, localDirFilePath); err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
|
|
defer func() {
|
|
if querys.DelTemp {
|
|
_ = os.RemoveAll(localFilePath)
|
|
}
|
|
}()
|
|
c.FileAttachment(zipFilePath, zipFileName)
|
|
}
|
|
|
|
// 查看网元端文件内容
|
|
//
|
|
// GET /viewFile
|
|
//
|
|
// @Tags network_element/action
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) default(UPF)
|
|
// @Param neId query string true "NE ID" default(001)
|
|
// @Param path query string true "file path" default(/var/log)
|
|
// @Param fileName query string true "file name"
|
|
// @Success 200 {object} object "Response Results"
|
|
// @Security TokenAuth
|
|
// @Summary Viewing the contents of a file on the network element side
|
|
// @Description Viewing the contents of a file on the network element side
|
|
// @Router /ne/action/viewFile [get]
|
|
func (s *NeActionController) ViewFile(c *gin.Context) {
|
|
language := reqctx.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 {
|
|
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
|
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
|
return
|
|
}
|
|
|
|
// 查询网元获取IP
|
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
|
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
|
return
|
|
}
|
|
|
|
// 网元主机的SSH客户端
|
|
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId)
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sshClient.Close()
|
|
|
|
// 网元端文件
|
|
nePath := filepath.ToSlash(filepath.Join(querys.Path, querys.FileName))
|
|
// 网元端临时目录
|
|
output, err := sshClient.RunCMD(fmt.Sprintf("cat %s", nePath))
|
|
output = strings.TrimSpace(output)
|
|
if err != nil || strings.HasPrefix(output, "ls: ") {
|
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "file view cat error")))
|
|
return
|
|
}
|
|
c.JSON(200, resp.OkData(output))
|
|
}
|
|
|
|
// 网元端文件列表
|
|
//
|
|
// GET /files
|
|
//
|
|
// @Tags network_element/action
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) default(UPF)
|
|
// @Param neId query string true "NE ID" default(001)
|
|
// @Param path query string true "file path" default(/var/log)
|
|
// @Param pageNum query number true "pageNum" default(1)
|
|
// @Param pageSize query number true "pageSize" default(10)
|
|
// @Param search query string false "search prefix" default(upf)
|
|
// @Success 200 {object} object "Response Results"
|
|
// @Security TokenAuth
|
|
// @Summary List of files on the network element side
|
|
// @Description List of files on the network element side
|
|
// @Router /ne/action/files [get]
|
|
func (s *NeActionController) Files(c *gin.Context) {
|
|
language := reqctx.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 {
|
|
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
|
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
|
return
|
|
}
|
|
|
|
// 查询网元获取IP
|
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
|
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
|
return
|
|
}
|
|
|
|
// 网元主机的SSH客户端
|
|
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId)
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
defer sshClient.Close()
|
|
|
|
// 获取文件列表
|
|
rows, err := ssh.FileList(sshClient, querys.Path, querys.Search)
|
|
if err != nil {
|
|
c.JSON(200, resp.OkData(map[string]any{
|
|
"path": querys.Path,
|
|
"total": len(rows),
|
|
"rows": []ssh.FileListRow{},
|
|
}))
|
|
return
|
|
}
|
|
|
|
// 对数组进行切片分页
|
|
lenNum := int64(len(rows))
|
|
start := (querys.PageNum - 1) * querys.PageSize
|
|
end := start + querys.PageSize
|
|
var splitRows []ssh.FileListRow
|
|
if start >= lenNum {
|
|
splitRows = []ssh.FileListRow{}
|
|
} else if end >= lenNum {
|
|
splitRows = rows[start:]
|
|
} else {
|
|
splitRows = rows[start:end]
|
|
}
|
|
|
|
c.JSON(200, resp.OkData(map[string]any{
|
|
"path": querys.Path,
|
|
"total": lenNum,
|
|
"rows": splitRows,
|
|
}))
|
|
}
|
|
|
|
// 网元服务操作
|
|
//
|
|
// PUT /service
|
|
//
|
|
// @Tags network_element/action
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param data body object true "Request Param"
|
|
// @Success 200 {object} object "Response Results"
|
|
// @Security TokenAuth
|
|
// @Summary Network element service operation
|
|
// @Description Network element service operation
|
|
// @Router /ne/action/service [put]
|
|
func (s *NeActionController) Service(c *gin.Context) {
|
|
language := reqctx.AcceptLanguage(c)
|
|
var body struct {
|
|
NeType string `json:"neType" binding:"required"`
|
|
NeID string `json:"neId" binding:"required"`
|
|
Action string `json:"action" binding:"required,oneof=start restart stop reboot poweroff"` // 操作行为
|
|
}
|
|
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
|
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
|
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
|
return
|
|
}
|
|
|
|
// 查询网元获取IP
|
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(body.NeType, body.NeID)
|
|
if neInfo.NeId != body.NeID || neInfo.IP == "" {
|
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
|
return
|
|
}
|
|
|
|
neTypeLower := strings.ToLower(neInfo.NeType)
|
|
cmdStr := fmt.Sprintf("sudo systemctl %s %s", body.Action, neTypeLower)
|
|
if neTypeLower == "omc" {
|
|
cmdStr = fmt.Sprintf("nohup sh -c \"sudo systemctl stop omc && sleep 5s && sudo systemctl %s omc\" > /dev/null 2>&1 &", body.Action)
|
|
} else if neTypeLower == "ims" {
|
|
if body.Action == "restart" {
|
|
cmdStr = "ims-stop || true && ims-start"
|
|
} else {
|
|
cmdStr = fmt.Sprintf("sudo ims-%s", body.Action)
|
|
}
|
|
}
|
|
|
|
if body.Action == "reboot" {
|
|
cmdStr = "sudo shutdown -r now"
|
|
}
|
|
if body.Action == "poweroff" {
|
|
cmdStr = "sudo shutdown -h now"
|
|
}
|
|
|
|
_, err := s.neInfoService.NeRunSSHCmd(body.NeType, body.NeID, cmdStr)
|
|
if err != nil {
|
|
c.JSON(200, resp.ErrMsg(err.Error()))
|
|
return
|
|
}
|
|
c.JSON(200, resp.Ok(nil))
|
|
}
|