feat: 新增工具模块 iperf

This commit is contained in:
TsMask
2024-10-09 17:38:32 +08:00
parent 7aae060f2e
commit e3b55c38e5
10 changed files with 221 additions and 0 deletions

View File

@@ -16,6 +16,7 @@ import (
networkdata "be.ems/src/modules/network_data"
networkelement "be.ems/src/modules/network_element"
"be.ems/src/modules/system"
"be.ems/src/modules/tool"
"be.ems/src/modules/trace"
"be.ems/src/modules/ws"
@@ -143,6 +144,8 @@ func initModulesRoute(app *gin.Engine) {
trace.Setup(app)
// 图表模块
chart.Setup(app)
// 工具模块
tool.Setup(app)
// ws 模块
ws.Setup(app)
// 调度任务模块--暂无接口

View File

@@ -0,0 +1,71 @@
package controller
// https://iperf.fr/iperf-download.php
// https://launchpad.net/ubuntu/jammy/amd64/libsctp1/1.0.19+dfsg-1build1
import (
"strings"
"be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/tool/service"
"github.com/gin-gonic/gin"
)
// 实例化控制层 IPerfController 结构体
var NewIPerf = &IPerfController{
iperfService: service.NewIPerf,
}
// iperf 网络性能测试工具
//
// PATH /tool/iperf
type IPerfController struct {
// IPerf3 网络性能测试工具服务
iperfService *service.IPerf
}
// iperf 版本信息
//
// GET /v
func (s *IPerfController) Version(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var query struct {
NeType string `form:"neType" binding:"required"` // 网元类型
NeID string `form:"neId" binding:"required"` // 网元ID
}
if err := c.ShouldBindQuery(&query); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
output, err := s.iperfService.Version(query.NeType, query.NeID)
if err != nil {
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
return
}
data := strings.Split(output, "\n")
c.JSON(200, result.OkData(data))
}
// iperf 软件安装
//
// GET /i
func (s *IPerfController) Install(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body struct {
NeType string `json:"neType" binding:"required"` // 网元类型
NeID string `json:"neId" binding:"required"` // 网元ID
}
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
if err := s.iperfService.Install(body.NeType, body.NeID); err != nil {
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
return
}
c.JSON(200, result.OkData(nil))
}

View File

@@ -0,0 +1,8 @@
package model
// IPerf G6关系图数据对象 chart_graph
type IPerf struct {
RowID int64 `json:"rowId,omitempty" gorm:"column:row_id;primaryKey;autoIncrement"` // 记录ID
RowType string `json:"rowType,omitempty" gorm:"column:row_type"` // 记录类型(node/edge/combo)
RowGroup string `json:"rowGroup,omitempty" gorm:"column:row_group"` // 记录组名
}

View File

@@ -0,0 +1,110 @@
package service
import (
"fmt"
"io"
"strings"
"be.ems/src/framework/config"
neService "be.ems/src/modules/network_element/service"
)
// 实例化服务层 IPerf 结构体
var NewIPerf = &IPerf{
neInfoService: neService.NewNeInfoImpl,
}
// IPerf 网络性能测试工具 服务层处理
type IPerf struct {
// 网元信息服务
neInfoService neService.INeInfo
}
// Version 查询版本信息
func (s *IPerf) Version(meType, neId string) (string, error) {
// 网元主机的SSH客户端
sshClient, err := s.neInfoService.NeRunSSHClient(meType, neId)
if err != nil {
return "", err
}
defer sshClient.Close()
// 检查是否安装iperf3
output, err := sshClient.RunCMD("iperf3 --version")
if err != nil {
return "", fmt.Errorf("iperf3 not installed")
}
return strings.TrimSpace(output), err
}
// Install 安装iperf3
func (s *IPerf) Install(meType, neId string) error {
// 网元主机的SSH客户端
sshClient, err := s.neInfoService.NeRunSSHClient(meType, neId)
if err != nil {
return err
}
defer sshClient.Close()
// 网元主机的SSH客户端进行文件传输
sftpClient, err := sshClient.NewClientSFTP()
if err != nil {
return err
}
defer sftpClient.Close()
nePath := "/tmp"
depPkg := "sudo dpkg -i"
depDir := "assets/dependency/iperf3/deb"
// 检查平台类型
if _, err := sshClient.RunCMD("sudo dpkg --version"); err == nil {
depPkg = "sudo dpkg -i"
depDir = "assets/dependency/iperf3/deb"
// sudo apt remove iperf3 libiperf0 libsctp1 libsctp-dev lksctp-tools
} else if _, err := sshClient.RunCMD("sudo yum --version"); err == nil {
depPkg = "sudo rpm -Uvh --force"
depDir = "assets/dependency/iperf3/rpm"
// yum remove iperf3 iperf3-help.noarch
}
// 从 embed.FS 中读取默认配置文件内容
assetsDir := config.GetAssetsDirFS()
fsDirEntrys, err := assetsDir.ReadDir(depDir)
if err != nil {
return err
}
neFilePaths := []string{}
for _, d := range fsDirEntrys {
// 打开本地文件
localFile, err := assetsDir.Open(fmt.Sprintf("%s/%s", depDir, d.Name()))
if err != nil {
return fmt.Errorf("iperf3 file local error")
}
defer localFile.Close()
// 创建远程文件
remotePath := fmt.Sprintf("%s/%s", nePath, d.Name())
remoteFile, err := sftpClient.Client.Create(remotePath)
if err != nil {
return fmt.Errorf("iperf3 file remote error")
}
defer remoteFile.Close()
// 使用 io.Copy 将嵌入的文件内容复制到目标文件
if _, err := io.Copy(remoteFile, localFile); err != nil {
return fmt.Errorf("iperf3 file copy error")
}
neFilePaths = append(neFilePaths, remotePath)
}
// 删除软件包
defer func() {
pkgRemove := fmt.Sprintf("sudo rm %s", strings.Join(neFilePaths, " "))
sshClient.RunCMD(pkgRemove)
}()
// 安装软件包
pkgInstall := fmt.Sprintf("%s %s", depPkg, strings.Join(neFilePaths, " "))
if _, err := sshClient.RunCMD(pkgInstall); err != nil {
return fmt.Errorf("iperf3 install error")
}
return err
}

29
src/modules/tool/tool.go Normal file
View File

@@ -0,0 +1,29 @@
package tool
import (
"be.ems/src/framework/logger"
"be.ems/src/framework/middleware"
"be.ems/src/framework/middleware/collectlogs"
"be.ems/src/modules/tool/controller"
"github.com/gin-gonic/gin"
)
// 模块路由注册
func Setup(router *gin.Engine) {
logger.Infof("开始加载 ====> tool 模块路由")
// iperf 网络性能测试工具
iperfGroup := router.Group("/tool/iperf")
{
iperfGroup.GET("/v",
middleware.PreAuthorize(nil),
controller.NewIPerf.Version,
)
iperfGroup.POST("/i",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.iperf", collectlogs.BUSINESS_TYPE_OTHER)),
controller.NewIPerf.Install,
)
}
}