feat: 网元信息配置读写,cmd命令直发函数
This commit is contained in:
@@ -39,15 +39,15 @@ func (s *NeInfoController) State(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
NeType string `form:"neType" binding:"required"`
|
||||
NeID string `form:"neId" binding:"required"`
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.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
|
||||
}
|
||||
@@ -84,17 +84,26 @@ func (s *NeInfoController) State(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(resData))
|
||||
}
|
||||
|
||||
// 网元信息列表
|
||||
// 网元neType和neID查询
|
||||
//
|
||||
// GET /list
|
||||
func (s *NeInfoController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
bandStatus := false
|
||||
if v, ok := querys["bandStatus"]; ok && v != nil {
|
||||
bandStatus = parse.Boolean(v)
|
||||
// GET /byTypeAndID
|
||||
func (s *NeInfoController) NeTypeAndID(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
NeType string `form:"neType" binding:"required"`
|
||||
NeID string `form:"neId" binding:"required"`
|
||||
}
|
||||
data := s.neInfoService.SelectPage(querys, bandStatus)
|
||||
c.JSON(200, result.Ok(data))
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
c.JSON(200, result.OkData(neInfo))
|
||||
}
|
||||
|
||||
// 网元信息列表全部无分页
|
||||
@@ -129,6 +138,85 @@ func (s *NeInfoController) ListAll(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(neList))
|
||||
}
|
||||
|
||||
// 网元端配置文件读取
|
||||
//
|
||||
// GET /configFile
|
||||
func (s *NeInfoController) ConfigFileRead(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
NeType string `form:"neType" binding:"required"`
|
||||
NeID string `form:"neId" binding:"required"`
|
||||
FilePath string `form:"filePath"` // 不带文件路径时进行复制覆盖本地网元配置目录
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
data := s.neInfoService.NeConfigFileRead(neInfo, querys.FilePath)
|
||||
if querys.FilePath == "" {
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
if len(data) > 0 {
|
||||
c.JSON(200, result.OkData(data[0]))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.ErrMsg("no data"))
|
||||
}
|
||||
|
||||
// 网元端配置文件写入
|
||||
//
|
||||
// PUT /configFile
|
||||
func (s *NeInfoController) ConfigFileWrite(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
NeType string `json:"neType" binding:"required"`
|
||||
NeID string `json:"neId" binding:"required"`
|
||||
FilePath string `json:"filePath" binding:"required"`
|
||||
Content string `json:"content" binding:"required"`
|
||||
Sync bool `json:"sync"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeID)
|
||||
if neInfo.NeId != body.NeID || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
err := s.neInfoService.NeConfigFileWirte(neInfo, body.FilePath, body.Content, body.Sync)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 网元信息列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *NeInfoController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
bandStatus := false
|
||||
if v, ok := querys["bandStatus"]; ok && v != nil {
|
||||
bandStatus = parse.Boolean(v)
|
||||
}
|
||||
data := s.neInfoService.SelectPage(querys, bandStatus)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// 网元信息
|
||||
//
|
||||
// GET /:infoId
|
||||
@@ -150,28 +238,6 @@ func (s *NeInfoController) Info(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(neHost))
|
||||
}
|
||||
|
||||
// 网元neType和neID查询
|
||||
//
|
||||
// GET /
|
||||
func (s *NeInfoController) NeTypeAndID(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
NeType string `form:"neType" binding:"required"`
|
||||
NeID string `form:"neId" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
c.JSON(200, result.OkData(neInfo))
|
||||
}
|
||||
|
||||
// 网元信息新增
|
||||
//
|
||||
// POST /
|
||||
|
||||
@@ -42,4 +42,13 @@ type INeInfo interface {
|
||||
|
||||
// CheckUniqueNeTypeAndNeId 校验同类型下标识是否唯一
|
||||
CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool
|
||||
|
||||
// NeRunCMD 向网元发送cmd命令
|
||||
NeRunCMD(neType, neId, cmd string) (string, error)
|
||||
|
||||
// NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取
|
||||
NeConfigFileRead(neInfo model.NeInfo, filePath string) []string
|
||||
|
||||
// NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端
|
||||
NeConfigFileWirte(neInfo model.NeInfo, filePath, content string, sync bool) error
|
||||
}
|
||||
|
||||
@@ -3,10 +3,14 @@ package service
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/constants/cachekey"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/redis"
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
"be.ems/src/modules/network_element/repository"
|
||||
)
|
||||
@@ -294,3 +298,139 @@ func (r *NeInfoImpl) CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// NeRunCMD 向网元发送cmd命令
|
||||
func (r *NeInfoImpl) NeRunCMD(neType, neId, cmd string) (string, error) {
|
||||
neInfo := r.SelectNeInfoByNeTypeAndNeID(neType, neId)
|
||||
if neInfo.NeId != neId {
|
||||
logger.Errorf("NeRunCMD NeType:%s NeID:%s not found", neType, neId)
|
||||
return "", fmt.Errorf("neinfo not found")
|
||||
}
|
||||
// 带主机信息
|
||||
if neInfo.HostIDs != "" {
|
||||
neInfo.Hosts = r.neHostRepository.SelectByIds(strings.Split(neInfo.HostIDs, ","))
|
||||
if len(neInfo.Hosts) <= 0 {
|
||||
logger.Errorf("NeRunCMD Hosts %s not found", neInfo.HostIDs)
|
||||
return "", fmt.Errorf("neinfo host not found")
|
||||
}
|
||||
}
|
||||
|
||||
neHost := neInfo.Hosts[0]
|
||||
if neHost.HostType != "ssh" {
|
||||
logger.Errorf("NeRunCMD Hosts first HostType %s not ssh", neHost.HostType)
|
||||
return "", fmt.Errorf("neinfo host type not ssh")
|
||||
}
|
||||
var connSSH ssh.ConnSSH
|
||||
neHost.CopyTo(&connSSH)
|
||||
client, err := connSSH.NewClient()
|
||||
if err != nil {
|
||||
logger.Errorf("NeRunCMD NewClient err => %s", err.Error())
|
||||
return "", fmt.Errorf("neinfo ssh client new err")
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// 执行命令
|
||||
output, err := client.RunCMD(cmd)
|
||||
if err != nil {
|
||||
logger.Errorf("NeRunCMD RunCMD %s err => %s", output, err.Error())
|
||||
return "", fmt.Errorf("neinfo ssh run cmd err")
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取
|
||||
func (r *NeInfoImpl) NeConfigFileRead(neInfo model.NeInfo, filePath string) []string {
|
||||
files := []string{}
|
||||
neTypeLower := strings.ToLower(neInfo.NeType)
|
||||
|
||||
// 网管本地路径
|
||||
omcPath := "/usr/local/etc/omc/ne_config"
|
||||
if runtime.GOOS == "windows" {
|
||||
omcPath = fmt.Sprintf("C:%s", omcPath)
|
||||
}
|
||||
omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neInfo.NeId)
|
||||
|
||||
// 读取文件内容
|
||||
if filePath != "" {
|
||||
bytes, err := os.ReadFile(fmt.Sprintf("%s/%s", omcPath, filePath))
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfigFile ReadFile => %s", err.Error())
|
||||
return files
|
||||
}
|
||||
files = append(files, string(bytes))
|
||||
return files
|
||||
}
|
||||
|
||||
// 删除原有配置文件
|
||||
// err := os.RemoveAll(omcPath)
|
||||
// if err != nil {
|
||||
// logger.Warnf("NeConfigFile Remove => %s", err.Error())
|
||||
// return files
|
||||
// }
|
||||
|
||||
// 网元端配置路径
|
||||
nePath := "/usr/local/etc"
|
||||
nePath = fmt.Sprintf("%s/%s", nePath, neTypeLower)
|
||||
|
||||
// 各个网元与网元间约定配置文件
|
||||
err := ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/oam_manager.yaml", omcPath+"/oam_manager.yaml")
|
||||
if err == nil {
|
||||
files = append(files, "oam_manager.yaml")
|
||||
}
|
||||
|
||||
// 根据情况复制网元特殊配置
|
||||
switch neTypeLower {
|
||||
case "ausf":
|
||||
err = ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/ausfcfg.yaml", omcPath+"/ausfcfg.yaml")
|
||||
if err == nil {
|
||||
files = append(files, "ausfcfg.yaml")
|
||||
}
|
||||
case "smf":
|
||||
ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/smf_conf.yaml", omcPath+"/smf_conf.yaml")
|
||||
if err == nil {
|
||||
files = append(files, "smf_conf.yaml")
|
||||
}
|
||||
ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/smf_policy.yaml", omcPath+"/smf_policy.yaml")
|
||||
if err == nil {
|
||||
files = append(files, "smf_policy.yaml")
|
||||
}
|
||||
case "ims":
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
// NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端
|
||||
func (r *NeInfoImpl) NeConfigFileWirte(neInfo model.NeInfo, filePath, content string, sync bool) error {
|
||||
neTypeLower := strings.ToLower(neInfo.NeType)
|
||||
|
||||
// 网管本地路径
|
||||
omcPath := "/usr/local/etc/omc/ne_config"
|
||||
if runtime.GOOS == "windows" {
|
||||
omcPath = fmt.Sprintf("C:%s", omcPath)
|
||||
}
|
||||
localFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neInfo.NeId, filePath)
|
||||
|
||||
err := os.WriteFile(localFilePath, []byte(content), 0644)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfigFile WriteFile => %s", err.Error())
|
||||
return fmt.Errorf("please check if the file exists or write permissions")
|
||||
}
|
||||
|
||||
// 同步到网元端
|
||||
if sync {
|
||||
// 网元端配置路径
|
||||
neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, filePath)
|
||||
// 修改网元文件权限
|
||||
r.NeRunCMD(neInfo.NeType, neInfo.NeId, fmt.Sprintf("sudo chmod o+w %s", neFilePath))
|
||||
// 复制到网元进行覆盖
|
||||
err = ssh.FileSCPLocalToNe(neInfo.IP, localFilePath, neFilePath)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfigFile SyncFile => %s", err.Error())
|
||||
return fmt.Errorf("please check if scp remote copy is allowed")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user