feat: 新增工具模块 iperf
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
|||||||
networkdata "be.ems/src/modules/network_data"
|
networkdata "be.ems/src/modules/network_data"
|
||||||
networkelement "be.ems/src/modules/network_element"
|
networkelement "be.ems/src/modules/network_element"
|
||||||
"be.ems/src/modules/system"
|
"be.ems/src/modules/system"
|
||||||
|
"be.ems/src/modules/tool"
|
||||||
"be.ems/src/modules/trace"
|
"be.ems/src/modules/trace"
|
||||||
"be.ems/src/modules/ws"
|
"be.ems/src/modules/ws"
|
||||||
|
|
||||||
@@ -143,6 +144,8 @@ func initModulesRoute(app *gin.Engine) {
|
|||||||
trace.Setup(app)
|
trace.Setup(app)
|
||||||
// 图表模块
|
// 图表模块
|
||||||
chart.Setup(app)
|
chart.Setup(app)
|
||||||
|
// 工具模块
|
||||||
|
tool.Setup(app)
|
||||||
// ws 模块
|
// ws 模块
|
||||||
ws.Setup(app)
|
ws.Setup(app)
|
||||||
// 调度任务模块--暂无接口
|
// 调度任务模块--暂无接口
|
||||||
|
|||||||
BIN
src/assets/dependency/iperf3/deb/iperf3_3.1.3-1_amd64.deb
Normal file
BIN
src/assets/dependency/iperf3/deb/iperf3_3.1.3-1_amd64.deb
Normal file
Binary file not shown.
BIN
src/assets/dependency/iperf3/deb/libiperf0_3.1.3-1_amd64.deb
Normal file
BIN
src/assets/dependency/iperf3/deb/libiperf0_3.1.3-1_amd64.deb
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/assets/dependency/iperf3/rpm/iperf3-3.6-6.ky10.aarch64.rpm
Normal file
BIN
src/assets/dependency/iperf3/rpm/iperf3-3.6-6.ky10.aarch64.rpm
Normal file
Binary file not shown.
Binary file not shown.
71
src/modules/tool/controller/iperf.go
Normal file
71
src/modules/tool/controller/iperf.go
Normal 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))
|
||||||
|
}
|
||||||
8
src/modules/tool/model/iperf.go
Normal file
8
src/modules/tool/model/iperf.go
Normal 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"` // 记录组名
|
||||||
|
}
|
||||||
110
src/modules/tool/service/iperf.go
Normal file
110
src/modules/tool/service/iperf.go
Normal 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
29
src/modules/tool/tool.go
Normal 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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user