merge: 合并代码20240531
This commit is contained in:
15
src/app.go
15
src/app.go
@@ -8,6 +8,7 @@ import (
|
||||
"be.ems/src/framework/errorcatch"
|
||||
"be.ems/src/framework/middleware"
|
||||
"be.ems/src/framework/middleware/security"
|
||||
"be.ems/src/framework/utils/machine"
|
||||
"be.ems/src/modules/chart"
|
||||
"be.ems/src/modules/common"
|
||||
"be.ems/src/modules/crontask"
|
||||
@@ -18,7 +19,9 @@ import (
|
||||
"be.ems/src/modules/trace"
|
||||
"be.ems/src/modules/ws"
|
||||
|
||||
"github.com/chenjiandongx/ginprom"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
//go:embed assets/*
|
||||
@@ -28,6 +31,13 @@ var assetsDir embed.FS
|
||||
func AppEngine() *gin.Engine {
|
||||
app := initAppEngine()
|
||||
|
||||
// TODO 不建议在主分支中加入
|
||||
// 性能分析监控
|
||||
if promEnabled := config.Get("pprof.enabled"); promEnabled != nil && promEnabled.(bool) {
|
||||
app.Use(ginprom.PromMiddleware(nil))
|
||||
app.GET("/metrics", ginprom.PromHandler(promhttp.Handler()))
|
||||
}
|
||||
|
||||
// 初始全局默认
|
||||
initDefeat(app)
|
||||
|
||||
@@ -37,6 +47,9 @@ func AppEngine() *gin.Engine {
|
||||
// 设置程序内全局资源访问
|
||||
config.SetAssetsDirFS(assetsDir)
|
||||
|
||||
// 首次安装启动记录
|
||||
machine.Launch()
|
||||
|
||||
// 读取服务配置
|
||||
app.ForwardedByClientIP = config.Get("server.proxy").(bool)
|
||||
return app
|
||||
@@ -108,7 +121,7 @@ func initDefeat(app *gin.Engine) {
|
||||
app.NoRoute(func(c *gin.Context) {
|
||||
c.JSON(404, gin.H{
|
||||
"code": 404,
|
||||
"msg": fmt.Sprintf("%s Not Found", c.Request.RequestURI),
|
||||
"msg": fmt.Sprintf("Not Found %s", c.Request.RequestURI),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 项目信息
|
||||
framework:
|
||||
name: "CN EMS"
|
||||
version: "2.2404.6"
|
||||
version: "2.2405.4"
|
||||
|
||||
# 应用服务配置
|
||||
server:
|
||||
@@ -15,7 +15,7 @@ logger:
|
||||
fileDir: "/var/log"
|
||||
fileName: "omc.log"
|
||||
level: 2 # 日志记录的等级 0:silent<1:info<2:warn<3:error
|
||||
maxDay: 180 # 日志会保留 180 天
|
||||
maxDay: 7 # 日志会保留 180 天
|
||||
maxSize: 10 # 调整按 10MB 大小的切割
|
||||
|
||||
# 静态文件配置, 相对项目根路径或填绝对路径
|
||||
|
||||
@@ -19,3 +19,6 @@ const STATUS_NO = "0"
|
||||
|
||||
// 上下文信息-登录用户
|
||||
const CTX_LOGIN_USER = "loginuser"
|
||||
|
||||
// 启动-引导系统初始
|
||||
const LAUNCH_BOOTLOADER = "bootloader"
|
||||
|
||||
@@ -34,7 +34,7 @@ const (
|
||||
// NewLogger 实例日志器对象
|
||||
func NewLogger(env, fileDir, fileName string, level, maxDay, maxSize int) (*Logger, error) {
|
||||
logFilePath := filepath.Join(fileDir, fileName)
|
||||
if err := os.MkdirAll(filepath.Dir(logFilePath), 0750); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(logFilePath), 0775); err != nil {
|
||||
return nil, fmt.Errorf("failed to mkdir logger dir: %v", err)
|
||||
}
|
||||
fileHandle, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
|
||||
@@ -10,21 +10,17 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// aesKey 字符串AES加解密密钥
|
||||
const aesKey = "AGT66VfY4SMaiT97"
|
||||
|
||||
// StringEncryptByAES 字符串AES加密
|
||||
func StringEncryptByAES(text string) (string, error) {
|
||||
if len(text) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
pass := []byte(text)
|
||||
xpass, err := aesEncryptWithSalt([]byte(aesKey), pass)
|
||||
if err == nil {
|
||||
pass64 := base64.StdEncoding.EncodeToString(xpass)
|
||||
return pass64, err
|
||||
xpass, err := aesEncryptWithSalt([]byte(text))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", err
|
||||
pass64 := base64.StdEncoding.EncodeToString(xpass)
|
||||
return pass64, nil
|
||||
}
|
||||
|
||||
// StringDecryptByAES 字符串AES解密
|
||||
@@ -36,53 +32,70 @@ func StringDecryptByAES(text string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var tpass []byte
|
||||
tpass, err = aesDecryptWithSalt([]byte(aesKey), bytesPass)
|
||||
if err == nil {
|
||||
result := string(tpass[:])
|
||||
return result, err
|
||||
|
||||
tpass, err := aesDecryptWithSalt(bytesPass)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", err
|
||||
return string(tpass), nil
|
||||
}
|
||||
|
||||
// aesEncryptWithSalt AES加密
|
||||
func aesEncryptWithSalt(key, plaintext []byte) ([]byte, error) {
|
||||
blockSize := aes.BlockSize
|
||||
padding := blockSize - len(plaintext)%blockSize
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
plaintext = append(plaintext, padtext...)
|
||||
// aesKey 字符串AES加解密密钥
|
||||
const aesKey = "AGT66VfY4SMaiT97a7df0aef1704d5c5"
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
// const aesKey = "AGT66VfY4SMaiT97"
|
||||
// aesEncryptWithSalt AES加密
|
||||
func aesEncryptWithSalt(plaintext []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher([]byte(aesKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockSize := aes.BlockSize
|
||||
|
||||
padding := blockSize - (len(plaintext) % blockSize)
|
||||
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
plaintext = append(plaintext, padtext...)
|
||||
|
||||
ciphertext := make([]byte, blockSize+len(plaintext))
|
||||
iv := ciphertext[0:blockSize]
|
||||
iv := ciphertext[:blockSize]
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cbc := cipher.NewCBCEncrypter(block, iv)
|
||||
cbc.CryptBlocks(ciphertext[blockSize:], plaintext)
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(ciphertext[blockSize:], plaintext)
|
||||
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
||||
// aesDecryptWithSalt AES解密
|
||||
func aesDecryptWithSalt(key, ciphertext []byte) ([]byte, error) {
|
||||
func aesDecryptWithSalt(ciphertext []byte) ([]byte, error) {
|
||||
blockSize := aes.BlockSize
|
||||
var block cipher.Block
|
||||
block, err := aes.NewCipher(key)
|
||||
if len(ciphertext) < blockSize {
|
||||
return nil, fmt.Errorf("ciphertext too short")
|
||||
}
|
||||
|
||||
iv := ciphertext[:blockSize]
|
||||
ciphertext = ciphertext[blockSize:]
|
||||
|
||||
block, err := aes.NewCipher([]byte(aesKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(ciphertext) < blockSize {
|
||||
return nil, fmt.Errorf("iciphertext too short")
|
||||
|
||||
if len(ciphertext)%blockSize != 0 {
|
||||
return nil, fmt.Errorf("ciphertext is not a multiple of the block size")
|
||||
}
|
||||
iv := ciphertext[:blockSize]
|
||||
ciphertext = ciphertext[blockSize:]
|
||||
cbc := cipher.NewCBCDecrypter(block, iv)
|
||||
cbc.CryptBlocks(ciphertext, ciphertext)
|
||||
length := len(ciphertext)
|
||||
unpadding := int(ciphertext[len(ciphertext)-1])
|
||||
ciphertext = ciphertext[:(length - unpadding)]
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(ciphertext, ciphertext)
|
||||
|
||||
// 去除填充
|
||||
padding := int(ciphertext[len(ciphertext)-1])
|
||||
if padding > blockSize || padding == 0 {
|
||||
return nil, fmt.Errorf("invalid padding")
|
||||
}
|
||||
ciphertext = ciphertext[:len(ciphertext)-padding]
|
||||
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func WriterFileCSV(data [][]string, filePath string) error {
|
||||
dirPath := filepath.Dir(filePath)
|
||||
|
||||
// 确保文件夹路径存在
|
||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
||||
err := os.MkdirAll(dirPath, 0775)
|
||||
if err != nil {
|
||||
logger.Errorf("MkdirAll dir %v", err)
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ func WriteSheet(headerCells map[string]string, dataCells []map[string]any, fileN
|
||||
saveFilePath := filepath.Join(dir, filePath, fileName)
|
||||
|
||||
// 创建文件目录
|
||||
if err := os.MkdirAll(filepath.Dir(saveFilePath), 0750); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(saveFilePath), 0775); err != nil {
|
||||
return "", fmt.Errorf("failed to create save file %v", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -177,13 +177,13 @@ func ReadUploadFileStream(filePath, headerRange string) (map[string]any, error)
|
||||
"range": "",
|
||||
"chunkSize": 0,
|
||||
"fileSize": 0,
|
||||
"data": nil,
|
||||
"data": []byte{},
|
||||
}
|
||||
|
||||
// 文件大小
|
||||
fileSize := getFileSize(fileAsbPath)
|
||||
if fileSize <= 0 {
|
||||
return result, nil
|
||||
return result, fmt.Errorf("file does not exist")
|
||||
}
|
||||
result["fileSize"] = fileSize
|
||||
|
||||
@@ -312,12 +312,12 @@ func CopyUploadFile(filePath, dst string) error {
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(dst), 0750); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(dst), 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 如果目标文件已经存在,先将目标文件重命名
|
||||
if _, err := os.Stat(dst); err == nil {
|
||||
if info, err := os.Stat(dst); err == nil && !info.IsDir() {
|
||||
ext := filepath.Ext(dst)
|
||||
name := dst[0 : len(dst)-len(ext)]
|
||||
newName := fmt.Sprintf("%s-%s%s", name, time.Now().Format("20060102_150405"), ext)
|
||||
|
||||
@@ -16,7 +16,7 @@ func WriterFileJSON(data any, filePath string) error {
|
||||
dirPath := filepath.Dir(filePath)
|
||||
|
||||
// 确保文件夹路径存在
|
||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
||||
err := os.MkdirAll(dirPath, 0775)
|
||||
if err != nil {
|
||||
logger.Errorf("CreateFile MkdirAll %v", err)
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func WriterFileJSONLine(data []any, filePath string) error {
|
||||
dirPath := filepath.Dir(filePath)
|
||||
|
||||
// 确保文件夹路径存在
|
||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
||||
err := os.MkdirAll(dirPath, 0775)
|
||||
if err != nil {
|
||||
logger.Errorf("CreateFile MkdirAll %v", err)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func WriterFileTXT(data [][]string, sep string, filePath string) error {
|
||||
dirPath := filepath.Dir(filePath)
|
||||
|
||||
// 确保文件夹路径存在
|
||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
||||
err := os.MkdirAll(dirPath, 0775)
|
||||
if err != nil {
|
||||
logger.Errorf("CreateFile MkdirAll %v", err)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ func transferToNewFile(file *multipart.FileHeader, dst string) error {
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
if err = os.MkdirAll(filepath.Dir(dst), 0750); err != nil {
|
||||
if err = os.MkdirAll(filepath.Dir(dst), 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func mergeToNewFile(dirPath string, writePath string, fileName string) error {
|
||||
|
||||
// 写入到新路径文件
|
||||
newFilePath := filepath.Join(writePath, fileName)
|
||||
if err = os.MkdirAll(filepath.Dir(newFilePath), 0750); err != nil {
|
||||
if err = os.MkdirAll(filepath.Dir(newFilePath), 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
178
src/framework/utils/machine/launch.go
Normal file
178
src/framework/utils/machine/launch.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package machine
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/constants/common"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/cmd"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
)
|
||||
|
||||
// 机器的唯一标识符
|
||||
var Code string
|
||||
|
||||
// 初始信息
|
||||
var LaunchInfo map[string]any
|
||||
|
||||
// codeGenerate 生成机器的唯一标识符
|
||||
func codeGenerate() string {
|
||||
var machineID string
|
||||
|
||||
// 获取主机名
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID += hostname
|
||||
|
||||
// 获取 CPU 信息
|
||||
numCPU := runtime.NumCPU()
|
||||
machineID += fmt.Sprintf("%d", numCPU)
|
||||
|
||||
// 获取操作系统信息
|
||||
osInfo := runtime.GOOS
|
||||
machineID += osInfo
|
||||
|
||||
// 使用哈希函数生成机器码
|
||||
h := fnv.New32a()
|
||||
h.Write([]byte(machineID))
|
||||
machineCode := h.Sum32()
|
||||
|
||||
return fmt.Sprintf("%x", machineCode)
|
||||
}
|
||||
|
||||
// 网管本地路径
|
||||
func filePath() string {
|
||||
filePath := "/usr/local/etc/omc/machine.ini"
|
||||
if runtime.GOOS == "windows" {
|
||||
filePath = fmt.Sprintf("C:%s", filePath)
|
||||
}
|
||||
return filePath
|
||||
}
|
||||
|
||||
// codeFileRead 读取机器保留的信息
|
||||
func codeFileRead() (map[string]any, error) {
|
||||
var mapData map[string]any
|
||||
// 读取文件内容
|
||||
bytes, err := os.ReadFile(filePath())
|
||||
if err != nil {
|
||||
logger.Warnf("CodeFileRead ReadFile => %s", err.Error())
|
||||
return mapData, fmt.Errorf("not file")
|
||||
}
|
||||
content := string(bytes)
|
||||
// 解密
|
||||
contentDe, err := crypto.StringDecryptByAES(content)
|
||||
if err != nil {
|
||||
logger.Errorf("CodeFileRead decrypt: %v", err.Error())
|
||||
return mapData, fmt.Errorf("decrypt fail")
|
||||
}
|
||||
// 序列化Map
|
||||
mapData, err = parse.ConvertConfigToMap("json", string(contentDe))
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfPara5GRead ConvertConfigToMap => %s", err.Error())
|
||||
return mapData, fmt.Errorf("content error")
|
||||
}
|
||||
return mapData, nil
|
||||
}
|
||||
|
||||
// codeFileWrite 写入机器保留的信息
|
||||
func codeFileWrite(data map[string]any) error {
|
||||
jsonByte, _ := json.Marshal(data)
|
||||
// 加密
|
||||
contentEn, err := crypto.StringEncryptByAES(string(jsonByte))
|
||||
if err != nil {
|
||||
logger.Errorf("insert encrypt: %v", err.Error())
|
||||
return fmt.Errorf("encrypt fail")
|
||||
}
|
||||
return parse.ConvertConfigToFile("txt", filePath(), contentEn)
|
||||
}
|
||||
|
||||
// Launch 记录首次安装启动初始信息
|
||||
func Launch() {
|
||||
Code = codeGenerate()
|
||||
// 检查文件是否存在
|
||||
if _, err := os.Stat(filePath()); err != nil {
|
||||
LaunchInfo = map[string]any{
|
||||
"code": Code, // 机器码
|
||||
"useTime": time.Now().UnixMilli(), // 首次使用时间
|
||||
|
||||
common.LAUNCH_BOOTLOADER: true, // 启动引导
|
||||
common.LAUNCH_BOOTLOADER + "Time": 0, // 引导完成时间
|
||||
}
|
||||
codeFileWrite(LaunchInfo)
|
||||
} else {
|
||||
// 读取记录文件
|
||||
data, err := codeFileRead()
|
||||
if err != nil {
|
||||
// 文件异常就重新生成
|
||||
os.Remove(filePath())
|
||||
Launch()
|
||||
return
|
||||
}
|
||||
LaunchInfo = data
|
||||
}
|
||||
}
|
||||
|
||||
// SetLaunchInfo 新增额外的初始信息
|
||||
func SetLaunchInfo(info map[string]any) error {
|
||||
if info == nil {
|
||||
return fmt.Errorf("not info")
|
||||
}
|
||||
|
||||
// 固定值禁止变更
|
||||
constKeys := []string{"code", "useTime"}
|
||||
for k, v := range info {
|
||||
constKey := false
|
||||
for _, ck := range constKeys {
|
||||
if ck == k {
|
||||
constKey = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if constKey {
|
||||
continue
|
||||
} else {
|
||||
LaunchInfo[k] = v
|
||||
}
|
||||
}
|
||||
return codeFileWrite(LaunchInfo)
|
||||
}
|
||||
|
||||
// Bootloader 启动引导标记
|
||||
func Bootloader(flag bool) error {
|
||||
return SetLaunchInfo(map[string]any{
|
||||
common.LAUNCH_BOOTLOADER: flag, // 启动引导 true开 false关
|
||||
common.LAUNCH_BOOTLOADER + "Time": time.Now().UnixMilli(), // 引导完成时间
|
||||
})
|
||||
}
|
||||
|
||||
// Reset 引导数据重置
|
||||
func Reset() error {
|
||||
// 重置数据库
|
||||
if runtime.GOOS == "windows" {
|
||||
// return fmt.Errorf("not support window")
|
||||
} else {
|
||||
// 重置数据库
|
||||
if _, err := cmd.Execf("sudo /usr/local/omc/bin/setomc.sh -m install"); err != nil {
|
||||
return err
|
||||
}
|
||||
// 重启服务
|
||||
if _, err := cmd.Execf("nohup sh -c \"sleep 1s && %s\" > /dev/null 2>&1 &", "sudo systemctl restart restagent"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 重置引导标记
|
||||
if err := Bootloader(true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
package parse
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -10,6 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Number 解析数值型
|
||||
@@ -51,6 +55,8 @@ func Boolean(str any) bool {
|
||||
case float32, float64:
|
||||
num := reflect.ValueOf(str).Float()
|
||||
return num != 0
|
||||
case bool:
|
||||
return str
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -165,3 +171,83 @@ func Color(colorStr string) *color.RGBA {
|
||||
A: 255, // 不透明
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertIPMask 转换IP网络地址掩码 24 -> 255.255.255.0
|
||||
func ConvertIPMask(bits int64) string {
|
||||
if bits < 0 || bits > 32 {
|
||||
return "Invalid Mask Bits"
|
||||
}
|
||||
|
||||
// 构建一个32位的uint32类型掩码,指定前bits位为1,其余为0
|
||||
mask := uint32((1<<bits - 1) << (32 - bits))
|
||||
|
||||
// 将掩码转换为四个八位分组
|
||||
groups := []string{
|
||||
fmt.Sprintf("%d", mask>>24),
|
||||
fmt.Sprintf("%d", (mask>>16)&255),
|
||||
fmt.Sprintf("%d", (mask>>8)&255),
|
||||
fmt.Sprintf("%d", mask&255),
|
||||
}
|
||||
|
||||
// 将分组用点号连接起来形成掩码字符串
|
||||
return strings.Join(groups, ".")
|
||||
}
|
||||
|
||||
// ConvertConfigToMap 将配置内容转换为Map结构数据
|
||||
//
|
||||
// configType 类型支持:txt json yaml yml
|
||||
func ConvertConfigToMap(configType, content string) (map[string]any, error) {
|
||||
// 类型支持:viper.SupportedExts
|
||||
// config := viper.New()
|
||||
// config.SetConfigType(configType)
|
||||
// err := config.ReadConfig(bytes.NewBuffer([]byte(content)))
|
||||
// return config.AllSettings(), err
|
||||
|
||||
var configMap map[string]interface{}
|
||||
var err error
|
||||
if configType == "" || configType == "txt" {
|
||||
configMap = map[string]interface{}{
|
||||
"txt": content,
|
||||
}
|
||||
}
|
||||
if configType == "yaml" || configType == "yml" {
|
||||
err = yaml.Unmarshal([]byte(content), &configMap)
|
||||
}
|
||||
if configType == "json" {
|
||||
err = json.Unmarshal([]byte(content), &configMap)
|
||||
}
|
||||
return configMap, err
|
||||
}
|
||||
|
||||
// ConvertConfigToFile 将数据写入到指定文件内
|
||||
//
|
||||
// configType 类型支持:txt json yaml yml
|
||||
func ConvertConfigToFile(configType, filePath string, data any) error {
|
||||
// viper.SupportedExts
|
||||
// config := viper.New()
|
||||
// config.SetConfigType(configType)
|
||||
// for key, value := range mapData {
|
||||
// config.Set(key, value)
|
||||
// }
|
||||
// return config.WriteConfigAs(filePath)
|
||||
|
||||
var dataByte []byte
|
||||
var err error
|
||||
if configType == "" || configType == "txt" {
|
||||
dataByte = []byte(data.(string))
|
||||
}
|
||||
if configType == "yaml" || configType == "yml" {
|
||||
dataByte, err = yaml.Marshal(data)
|
||||
}
|
||||
if configType == "json" {
|
||||
dataByte, err = json.Marshal(data)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(filePath), 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(filePath, dataByte, 0644)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func PageNumSize(pageNum, pageSize any) (int64, int64) {
|
||||
|
||||
// 显示记录数
|
||||
size := parse.Number(pageSize)
|
||||
if size < 0 {
|
||||
if size < 1 {
|
||||
size = 10
|
||||
}
|
||||
return num - 1, size
|
||||
|
||||
@@ -28,7 +28,7 @@ func FileSCPLocalToNe(neIp, localPath, nePath string) error {
|
||||
// 网元NE 远程文件复制到本地文件
|
||||
func FileSCPNeToLocal(neIp, nePath, localPath string) error {
|
||||
// 确保文件夹路径存在
|
||||
if err := os.MkdirAll(filepath.Dir(localPath), 0750); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(localPath), 0775); err != nil {
|
||||
logger.Errorf("FileSCPNeToLocal MkdirAll err %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,12 +6,14 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/cmd"
|
||||
gosftp "github.com/pkg/sftp"
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
@@ -133,8 +135,12 @@ func (c *ConnSSH) SendToAuthorizedKeys() error {
|
||||
return err
|
||||
}
|
||||
authorizedKeysEntry := fmt.Sprintln(strings.TrimSpace(publicKey))
|
||||
cmdStr := "echo '" + authorizedKeysEntry + "' >> ~/.ssh/authorized_keys"
|
||||
_, err = c.RunCMD(cmdStr)
|
||||
cmdStrArr := []string{
|
||||
fmt.Sprintf("sudo mkdir -p /home/%s/.ssh && sudo chown %s:%s /home/%s/.ssh && sudo chmod 700 /home/%s/.ssh", c.User, c.User, c.User, c.User, c.User),
|
||||
fmt.Sprintf("sudo touch /home/%s/.ssh/authorized_keys && sudo chown %s:%s /home/%s/.ssh/authorized_keys && sudo chmod 600 /home/%s/.ssh/authorized_keys", c.User, c.User, c.User, c.User, c.User),
|
||||
fmt.Sprintf("echo '%s' | sudo tee -a /home/%s/.ssh/authorized_keys", authorizedKeysEntry, c.User),
|
||||
}
|
||||
_, err = c.RunCMD(strings.Join(cmdStrArr, " && "))
|
||||
if err != nil {
|
||||
logger.Errorf("SendAuthorizedKeys echo err %s", err.Error())
|
||||
return err
|
||||
@@ -156,9 +162,8 @@ func (c *ConnSSH) CurrentUserRsaKey(publicKey bool) (string, error) {
|
||||
// 是否存在私钥并创建
|
||||
keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir)
|
||||
if _, err := os.Stat(keyPath); err != nil {
|
||||
_, err2 := cmd.ExecWithCheck("ssh-keygen", "-t", "rsa", "-P", "", "-f", keyPath)
|
||||
if err2 != nil {
|
||||
logger.Errorf("CurrentUserPrivateKey ssh-keygen [%s] rsa => %s", usr.Username, err2.Error())
|
||||
if _, err := cmd.ExecWithCheck("ssh-keygen", "-t", "rsa", "-P", "", "-f", keyPath); err != nil {
|
||||
logger.Errorf("CurrentUserPrivateKey ssh-keygen [%s] rsa => %s", usr.Username, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,12 +244,11 @@ func (s *SSHClientSession) Write(cmd string) (int, error) {
|
||||
return s.Stdin.Write([]byte(cmd))
|
||||
}
|
||||
|
||||
// Read 读取结果 等待一会才有结果
|
||||
// Read 读取结果
|
||||
func (s *SSHClientSession) Read() []byte {
|
||||
if s.Stdout == nil {
|
||||
return []byte{}
|
||||
}
|
||||
// time.Sleep(300 * time.Millisecond)
|
||||
bs := s.Stdout.Bytes()
|
||||
if len(bs) > 0 {
|
||||
s.Stdout.Reset()
|
||||
@@ -253,15 +257,6 @@ func (s *SSHClientSession) Read() []byte {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
// CombinedOutput 发送命令带结果返回
|
||||
func (s *SSHClientSession) CombinedOutput(cmd string) (string, error) {
|
||||
n, err := s.Write(cmd)
|
||||
if n == 0 || err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(s.Read()), nil
|
||||
}
|
||||
|
||||
// singleWriter SSH客户端会话消息
|
||||
type singleWriter struct {
|
||||
b bytes.Buffer
|
||||
@@ -283,3 +278,208 @@ func (w *singleWriter) Reset() {
|
||||
defer w.mu.Unlock()
|
||||
w.b.Reset()
|
||||
}
|
||||
|
||||
// NewClientSFTP 创建SSH客户端SFTP对象
|
||||
func (c *ConnSSH) NewClientSFTP() (*SSHClientSFTP, error) {
|
||||
sftpClient, err := gosftp.NewClient(c.Client)
|
||||
if err != nil {
|
||||
logger.Errorf("NewClientSFTP failed to create sftp: => %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SSHClientSFTP{
|
||||
Client: sftpClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SSHClientSFTP SSH客户端SFTP对象
|
||||
type SSHClientSFTP struct {
|
||||
Client *gosftp.Client
|
||||
}
|
||||
|
||||
// Close 关闭会话
|
||||
func (s *SSHClientSFTP) Close() {
|
||||
if s.Client != nil {
|
||||
s.Client.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// CopyDirRemoteToLocal 复制目录-远程到本地
|
||||
func (s *SSHClientSFTP) CopyDirRemoteToLocal(remoteDir, localDir string) error {
|
||||
// 列出远程目录中的文件和子目录
|
||||
remoteFiles, err := s.Client.ReadDir(remoteDir)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirRemoteToLocal failed to reading remote directory %s: => %s", remoteDir, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建本地目录
|
||||
err = os.MkdirAll(localDir, 0775)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirRemoteToLocal failed to creating local directory %s: => %s", localDir, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// 遍历远程文件和子目录并复制到本地
|
||||
for _, remoteFile := range remoteFiles {
|
||||
remotePath := filepath.Join(remoteDir, remoteFile.Name())
|
||||
localPath := filepath.Join(localDir, remoteFile.Name())
|
||||
|
||||
if remoteFile.IsDir() {
|
||||
// 如果是子目录,则递归复制子目录
|
||||
err = s.CopyDirRemoteToLocal(remotePath, localPath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirRemoteToLocal failed to copying remote directory %s: => %s", remotePath, err.Error())
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
// 如果是文件,则复制文件内容
|
||||
remoteFile, err := s.Client.Open(remotePath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirRemoteToLocal failed to opening remote file %s: => %s", remotePath, err.Error())
|
||||
continue
|
||||
}
|
||||
defer remoteFile.Close()
|
||||
|
||||
localFile, err := os.Create(localPath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirRemoteToLocal failed to creating local file %s: => %s", localPath, err.Error())
|
||||
continue
|
||||
}
|
||||
defer localFile.Close()
|
||||
|
||||
_, err = io.Copy(localFile, remoteFile)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirRemoteToLocal failed to copying file contents from %s to %s: => %s", remotePath, localPath, err.Error())
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyDirRemoteToLocal 复制目录-本地到远程
|
||||
func (s *SSHClientSFTP) CopyDirLocalToRemote(localDir, remoteDir string) error {
|
||||
// 创建远程目录
|
||||
err := s.Client.MkdirAll(remoteDir)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirLocalToRemote failed to creating remote directory %s: => %s", remoteDir, err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// 遍历本地目录中的文件和子目录并复制到远程
|
||||
err = filepath.Walk(localDir, func(localPath string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 生成远程路径
|
||||
remotePath := filepath.Join(remoteDir, localPath[len(localDir):])
|
||||
|
||||
if info.IsDir() {
|
||||
// 如果是子目录,则创建远程目录
|
||||
err := s.Client.MkdirAll(remotePath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirLocalToRemote failed to creating remote directory %s: => %s", remotePath, err.Error())
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
// 如果是文件,则复制文件内容
|
||||
localFile, err := os.Open(localPath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirLocalToRemote failed to opening local file %s: => %s", localPath, err.Error())
|
||||
return nil
|
||||
}
|
||||
defer localFile.Close()
|
||||
|
||||
remoteFile, err := s.Client.Create(remotePath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirLocalToRemote failed to creating remote file %s: => %s", remotePath, err.Error())
|
||||
return nil
|
||||
}
|
||||
defer remoteFile.Close()
|
||||
|
||||
_, err = io.Copy(remoteFile, localFile)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirLocalToRemote failed to copying file contents from %s to %s: => %s", localPath, remotePath, err.Error())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
logger.Errorf("CopyDirLocalToRemote failed to walking local directory: => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyDirRemoteToLocal 复制文件-远程到本地
|
||||
func (s *SSHClientSFTP) CopyFileRemoteToLocal(remotePath, localPath string) error {
|
||||
// 打开远程文件
|
||||
remoteFile, err := s.Client.Open(remotePath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyFileRemoteToLocal failed to opening remote file: => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
defer remoteFile.Close()
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(localPath), 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 如果目标文件已经存在,先将目标文件重命名
|
||||
// if info, err := os.Stat(localPath); err == nil && !info.IsDir() {
|
||||
// ext := filepath.Ext(localPath)
|
||||
// name := localPath[0 : len(localPath)-len(ext)]
|
||||
// newName := fmt.Sprintf("%s-%s%s", name, time.Now().Format("20060102_150405"), ext)
|
||||
// err := os.Rename(localPath, newName)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
|
||||
// 创建本地文件
|
||||
localFile, err := os.Create(localPath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyFileRemoteToLocal failed to creating local file: => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
defer localFile.Close()
|
||||
|
||||
// 复制文件内容
|
||||
_, err = io.Copy(localFile, remoteFile)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyFileRemoteToLocal failed to copying contents: => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyDirRemoteToLocal 复制文件-本地到远程
|
||||
func (s *SSHClientSFTP) CopyFileLocalToRemote(localPath, remotePath string) error {
|
||||
// 打开本地文件
|
||||
localFile, err := os.Open(localPath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyFileLocalToRemote failed to opening local file: => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
defer localFile.Close()
|
||||
|
||||
// 创建远程文件
|
||||
remoteFile, err := s.Client.Create(remotePath)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyFileLocalToRemote failed to creating remote file: => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
defer remoteFile.Close()
|
||||
|
||||
// 复制文件内容
|
||||
_, err = io.Copy(remoteFile, localFile)
|
||||
if err != nil {
|
||||
logger.Errorf("CopyFileLocalToRemote failed to copying contents: => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -50,7 +50,13 @@ func (c *ConnTelnet) NewClient() (*ConnTelnet, error) {
|
||||
// fmt.Fprintln(client, c.User)
|
||||
// fmt.Fprintln(client, c.Password)
|
||||
|
||||
// 需要确保接收方理解并正确处理发送窗口大小设置命令
|
||||
client.Write([]byte{255, 251, 31}) // 发送窗口大小选项
|
||||
client.Write([]byte{255, 250, 31, 0, 128, 0, 120, 255, 240}) // 发送窗口行和列的大小
|
||||
c.Client = &client
|
||||
|
||||
// 排空连接登录的信息
|
||||
c.RunCMD("")
|
||||
return c, nil
|
||||
}
|
||||
|
||||
@@ -70,32 +76,14 @@ func (c *ConnTelnet) RunCMD(cmd string) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
tmp := make([]byte, 1024)
|
||||
|
||||
// 排空连接登录的信息
|
||||
for {
|
||||
// 设置读取超时时间为100毫秒
|
||||
conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||
n, err := conn.Read(tmp)
|
||||
if err != nil {
|
||||
// 判断是否是超时错误
|
||||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
buf.Write(tmp[:n])
|
||||
}
|
||||
buf.Reset()
|
||||
|
||||
// 写入命令
|
||||
_, err := conn.Write([]byte(cmd))
|
||||
if err != nil {
|
||||
return "", err
|
||||
if cmd != "" {
|
||||
if _, err := conn.Write([]byte(cmd)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// 读取本次响应命令消息
|
||||
// 读取命令消息
|
||||
for {
|
||||
// 设置读取超时时间为1000毫秒
|
||||
conn.SetReadDeadline(time.Now().Add(1000 * time.Millisecond))
|
||||
@@ -119,35 +107,12 @@ func (c *ConnTelnet) RunCMD(cmd string) (string, error) {
|
||||
}
|
||||
|
||||
// NewClient 创建Telnet客户端会话对象
|
||||
func (c *ConnTelnet) NewClientSession() (*TelnetClientSession, error) {
|
||||
func (c *ConnTelnet) NewClientSession(cols, rows uint8) (*TelnetClientSession, error) {
|
||||
if c.Client == nil {
|
||||
return nil, fmt.Errorf("telnet client not connected")
|
||||
}
|
||||
conn := *c.Client
|
||||
|
||||
var buf bytes.Buffer
|
||||
tmp := make([]byte, 1024)
|
||||
// 排空连接登录的信息
|
||||
for {
|
||||
// 设置读取超时时间为5毫秒
|
||||
conn.SetReadDeadline(time.Now().Add(5 * time.Millisecond))
|
||||
n, err := conn.Read(tmp)
|
||||
if err != nil {
|
||||
// 判断是否是超时错误
|
||||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
buf.Write(tmp[:n])
|
||||
}
|
||||
buf.Reset()
|
||||
|
||||
return &TelnetClientSession{
|
||||
Client: conn,
|
||||
Client: *c.Client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"be.ems/src/framework/logger"
|
||||
redisCahe "be.ems/src/framework/redis"
|
||||
"be.ems/src/framework/utils/generate"
|
||||
"be.ems/src/framework/utils/machine"
|
||||
"be.ems/src/framework/vo"
|
||||
|
||||
jwt "github.com/golang-jwt/jwt/v5"
|
||||
@@ -74,7 +75,7 @@ func Create(loginUser *vo.LoginUser, ilobArgs ...string) string {
|
||||
|
||||
// 生成令牌设置密钥
|
||||
secret := config.Get("jwt.secret").(string)
|
||||
tokenStr, err := jwtToken.SignedString([]byte(secret))
|
||||
tokenStr, err := jwtToken.SignedString([]byte(machine.Code + "@" + secret))
|
||||
if err != nil {
|
||||
logger.Infof("jwt sign err : %v", err)
|
||||
return ""
|
||||
@@ -118,7 +119,7 @@ func Verify(tokenString string) (jwt.MapClaims, error) {
|
||||
// 判断加密算法是预期的加密算法
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); ok {
|
||||
secret := config.Get("jwt.secret").(string)
|
||||
return []byte(secret), nil
|
||||
return []byte(machine.Code + "@" + secret), nil
|
||||
}
|
||||
return nil, jwt.ErrSignatureInvalid
|
||||
})
|
||||
|
||||
@@ -25,6 +25,14 @@ func Setup(router *gin.Engine) {
|
||||
|
||||
// 系统可暴露的配置信息
|
||||
indexGroup.GET("/sys-conf", controller.NewCommont.SysConfig)
|
||||
// 系统引导初始化
|
||||
guideGroup := router.Group("/bootloader")
|
||||
{
|
||||
guideGroup.POST("", controller.NewBootloader.Start)
|
||||
guideGroup.PUT("", middleware.PreAuthorize(nil), controller.NewBootloader.Done)
|
||||
guideGroup.DELETE("", middleware.PreAuthorize(nil), controller.NewBootloader.Reset)
|
||||
guideGroup.PUT("/account", middleware.PreAuthorize(nil), controller.NewBootloader.Account)
|
||||
}
|
||||
|
||||
// 验证码操作处理
|
||||
indexGroup.GET("/captchaImage",
|
||||
|
||||
181
src/modules/common/controller/bootloader.go
Normal file
181
src/modules/common/controller/bootloader.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
adminConstants "be.ems/src/framework/constants/admin"
|
||||
"be.ems/src/framework/constants/common"
|
||||
tokenConstants "be.ems/src/framework/constants/token"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/ctx"
|
||||
"be.ems/src/framework/utils/machine"
|
||||
"be.ems/src/framework/utils/regular"
|
||||
tokenUtils "be.ems/src/framework/utils/token"
|
||||
"be.ems/src/framework/vo"
|
||||
"be.ems/src/framework/vo/result"
|
||||
commonService "be.ems/src/modules/common/service"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 BootloaderController 结构体
|
||||
var NewBootloader = &BootloaderController{
|
||||
accountService: commonService.NewAccountImpl,
|
||||
sysUserService: systemService.NewSysUserImpl,
|
||||
}
|
||||
|
||||
// 系统引导初始化
|
||||
//
|
||||
// PATH /bootloader
|
||||
type BootloaderController struct {
|
||||
// 账号身份操作服务
|
||||
accountService commonService.IAccount
|
||||
// 用户信息服务
|
||||
sysUserService systemService.ISysUser
|
||||
}
|
||||
|
||||
// 首次引导开始
|
||||
//
|
||||
// POST /
|
||||
func (s *BootloaderController) Start(c *gin.Context) {
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
|
||||
c.JSON(200, result.ErrMsg("bootloader done"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.SelectUserById("1")
|
||||
if sysUser.UserID != "1" {
|
||||
c.JSON(200, result.ErrMsg("not found user data"))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
loginUser := vo.LoginUser{
|
||||
UserID: sysUser.UserID,
|
||||
DeptID: sysUser.DeptID,
|
||||
User: sysUser,
|
||||
Permissions: []string{adminConstants.PERMISSION},
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := ctx.IPAddrLocation(c)
|
||||
os, browser := ctx.UaOsBrowser(c)
|
||||
|
||||
// 生成令牌,创建系统访问记录
|
||||
tokenStr := tokenUtils.Create(&loginUser, ipaddr, location, os, browser)
|
||||
if tokenStr == "" {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
} else {
|
||||
s.accountService.UpdateLoginDateAndIP(&loginUser)
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
tokenConstants.RESPONSE_FIELD: tokenStr,
|
||||
}))
|
||||
}
|
||||
|
||||
// 首次引导完成
|
||||
//
|
||||
// PUT /
|
||||
func (s *BootloaderController) Done(c *gin.Context) {
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
|
||||
c.JSON(200, result.ErrMsg("bootloader done"))
|
||||
return
|
||||
}
|
||||
|
||||
// 标记引导完成
|
||||
if err := machine.Bootloader(false); err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 清除授权信息
|
||||
tokenUtils.Remove(ctx.Authorization(c))
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 引导系统数据重置
|
||||
//
|
||||
// DELETE /
|
||||
func (s *BootloaderController) Reset(c *gin.Context) {
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && v.(bool) {
|
||||
c.JSON(200, result.ErrMsg("bootloader not done"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := machine.Reset(); err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 清除授权信息
|
||||
tokenUtils.Remove(ctx.Authorization(c))
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 账号变更
|
||||
//
|
||||
// PUT /account
|
||||
func (s *BootloaderController) Account(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
UserName string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
if !regular.ValidPassword(body.Password) {
|
||||
// 登录密码至少包含大小写字母、数字、特殊符号,且不少于6位
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.errPasswd")))
|
||||
return
|
||||
}
|
||||
|
||||
// 是否完成引导
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo == nil {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
|
||||
c.JSON(200, result.ErrMsg("bootloader done"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.SelectUserById("2")
|
||||
if sysUser.UserID != "2" {
|
||||
c.JSON(200, result.ErrMsg("not found user data"))
|
||||
return
|
||||
}
|
||||
sysUser.UserName = body.UserName
|
||||
sysUser.NickName = body.UserName
|
||||
sysUser.Password = body.Password
|
||||
sysUser.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysUserService.UpdateUser(sysUser)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
@@ -43,13 +43,6 @@ func (s *FileController) Download(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
routerPath := string(decodedBytes)
|
||||
// 地址文件名截取
|
||||
fileName := routerPath[strings.LastIndex(routerPath, "/")+1:]
|
||||
|
||||
// 响应头
|
||||
c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+url.QueryEscape(fileName)+`"`)
|
||||
c.Writer.Header().Set("Accept-Ranges", "bytes")
|
||||
c.Writer.Header().Set("Content-Type", "application/octet-stream")
|
||||
|
||||
// 断点续传
|
||||
headerRange := c.GetHeader("Range")
|
||||
@@ -58,6 +51,12 @@ func (s *FileController) Download(c *gin.Context) {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 响应头
|
||||
c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+url.QueryEscape(filepath.Base(routerPath))+`"`)
|
||||
c.Writer.Header().Set("Accept-Ranges", "bytes")
|
||||
c.Writer.Header().Set("Content-Type", "application/octet-stream")
|
||||
|
||||
if headerRange != "" {
|
||||
c.Writer.Header().Set("Content-Range", fmt.Sprint(resultMap["range"]))
|
||||
c.Writer.Header().Set("Content-Length", fmt.Sprint(resultMap["chunkSize"]))
|
||||
@@ -65,7 +64,6 @@ func (s *FileController) Download(c *gin.Context) {
|
||||
} else {
|
||||
c.Writer.Header().Set("Content-Length", fmt.Sprint(resultMap["fileSize"]))
|
||||
c.Status(200)
|
||||
|
||||
}
|
||||
c.Writer.Write(resultMap["data"].([]byte))
|
||||
}
|
||||
@@ -222,7 +220,7 @@ func (s *CommontController) TransferStaticFile(c *gin.Context) {
|
||||
|
||||
delPrefix := strings.Replace(body.StaticPath, static["prefix"].(string), "", 1)
|
||||
staticPath := strings.Replace(delPrefix, "{language}", lang, 1)
|
||||
newFile := fmt.Sprintf("%s%s", dir, staticPath)
|
||||
newFile := filepath.ToSlash(fmt.Sprintf("%s%s", dir, staticPath))
|
||||
|
||||
err = file.CopyUploadFile(body.UploadPath, newFile)
|
||||
if err != nil {
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
|
||||
"be.ems/lib/global"
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants/common"
|
||||
"be.ems/src/framework/utils/machine"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
@@ -29,6 +31,17 @@ func (s *CommontImpl) SystemConfigInfo() map[string]string {
|
||||
infoMap["version"] = global.Version
|
||||
infoMap["buildTime"] = global.BuildTime
|
||||
infoMap["goVer"] = global.GoVer
|
||||
// 系统首次使用标记
|
||||
launchInfo := machine.LaunchInfo
|
||||
if launchInfo != nil {
|
||||
if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok {
|
||||
infoMap[common.LAUNCH_BOOTLOADER] = fmt.Sprint(v)
|
||||
} else {
|
||||
infoMap[common.LAUNCH_BOOTLOADER] = "true"
|
||||
}
|
||||
} else {
|
||||
infoMap[common.LAUNCH_BOOTLOADER] = "true"
|
||||
}
|
||||
// 序列号
|
||||
infoMap["serialNum"] = fmt.Sprint(config.Get("omc.sn"))
|
||||
// 获取LOGO类型
|
||||
|
||||
80
src/modules/network_data/controller/smf.go
Normal file
80
src/modules/network_data/controller/smf.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/ctx"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 IMSController 结构体
|
||||
var NewSMFController = &SMFController{
|
||||
neInfoService: neService.NewNeInfoImpl,
|
||||
cdrEventService: neDataService.NewSMFCDREventImpl,
|
||||
}
|
||||
|
||||
// 网元IMS
|
||||
//
|
||||
// PATH /ims
|
||||
type SMFController struct {
|
||||
// 网元信息服务
|
||||
neInfoService neService.INeInfo
|
||||
// SMF CDR会话事件服务
|
||||
cdrEventService neDataService.SMFCDREvent
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
func (s *SMFController) CDRList(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys model.SMFCDREventQuery
|
||||
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
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
data := s.cdrEventService.SelectPage(querys)
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:cdrIds
|
||||
func (s *SMFController) CDRRemove(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
cdrIds := c.Param("cdrIds")
|
||||
if cdrIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(cdrIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.cdrEventService.DeleteByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package model
|
||||
|
||||
import "time"
|
||||
|
||||
// CDREvent CDR会话对象 cdr_event
|
||||
// CDREvent CDR会话对象 cdr_event_ims/cdr_event_smf
|
||||
type CDREvent struct {
|
||||
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
@@ -15,14 +15,16 @@ type CDREvent struct {
|
||||
|
||||
// CDREventQuery CDR会话对象查询参数结构体
|
||||
type CDREventQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required"` // 网元类型, 暂时支持IMS
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
RecordType string `json:"recordType" form:"recordType"` // 记录行为 MOC MTC MOSM MTSM
|
||||
StartTime string `json:"startTime" form:"startTime"`
|
||||
EndTime string `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
NeType string `json:"neType" form:"neType" binding:"required"` // 网元类型
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
RecordType string `json:"recordType" form:"recordType"` // 记录行为 MOC MTC MOSM MTSM
|
||||
CallerParty string `json:"callerParty" form:"callerParty"` // 主叫号码
|
||||
CalledParty string `json:"calledParty" form:"calledParty"` // 被叫号码
|
||||
StartTime string `json:"startTime" form:"startTime"`
|
||||
EndTime string `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
|
||||
35
src/modules/network_data/model/cdr_event_smf.go
Normal file
35
src/modules/network_data/model/cdr_event_smf.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// CDREvent CDR会话对象 cdr_event_smf
|
||||
type CDREventSMF struct {
|
||||
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUID string `json:"rmUID" gorm:"column:rm_uid"`
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"`
|
||||
RecordType string `json:"recordType" gorm:"column:record_type"`
|
||||
ChargingID string `json:"chargingID" gorm:"column:charging_id"`
|
||||
SubscriberID string `json:"subscriberID" gorm:"column:subscriber_id"`
|
||||
Duration string `json:"duration" gorm:"column:duration"`
|
||||
DataVolumeUplink string `json:"dataVolumeUplink" gorm:"column:data_volume_uplink"`
|
||||
DataVolumeDownlink string `json:"dataVolumeDownlink" gorm:"column:data_volume_downlink"`
|
||||
DataTotalVolume string `json:"dataTotalVolume" gorm:"column:data_total_volume"`
|
||||
PDUAddress string `json:"pduAddress" gorm:"column:pdu_address"`
|
||||
CreatedAt time.Time `json:"createdAt" gorm:"column:created_at;default:CURRENT_TIMESTAMP"`
|
||||
}
|
||||
|
||||
type SMFCDREventQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required"` // SMF
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
RecordType string `json:"recordType" form:"recordType"`
|
||||
SubscriberID string `json:"subscriberID" form:"subscriberID"`
|
||||
StartTime string `json:"startTime" form:"startTime"`
|
||||
EndTime string `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
@@ -20,6 +20,7 @@ type UEEventQuery struct {
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
EventType string `json:"eventType" form:"eventType"` // 事件类型 auth-result detach cm-state
|
||||
IMSI string `json:"imsi" form:"imsi"` // imsi
|
||||
StartTime string `json:"startTime" form:"startTime"`
|
||||
EndTime string `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
|
||||
@@ -57,6 +57,22 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 网元SMF
|
||||
smfGroup := neDataGroup.Group("/smf")
|
||||
{
|
||||
// CDR会话事件列表
|
||||
smfGroup.GET("/cdr/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewSMFController.CDRList,
|
||||
)
|
||||
// CDR会话删除
|
||||
smfGroup.DELETE("/cdr/:cdrIds",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSMFController.CDRRemove,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元AMF
|
||||
amfGroup := neDataGroup.Group("/amf")
|
||||
{
|
||||
|
||||
@@ -13,3 +13,15 @@ type ICDREvent interface {
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(cdrIds []string) int64
|
||||
}
|
||||
|
||||
// SMF CDR Event
|
||||
type SMFCDREvent interface {
|
||||
// SelectPage 根据条件分页查询
|
||||
SelectPage(querys model.SMFCDREventQuery) map[string]any
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
SelectByIds(cdrIds []string) []model.CDREventSMF
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(cdrIds []string) int64
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
// 实例化数据层 CDREventImpl 结构体
|
||||
var NewCDREventImpl = &CDREventImpl{
|
||||
selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, cdr_json, created_at from cdr_event`,
|
||||
selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, cdr_json, created_at from cdr_event_ims`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"id": "ID",
|
||||
@@ -35,6 +35,36 @@ type CDREventImpl struct {
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// Instance of SMF CDREventImpl
|
||||
var NewSMFCDREventImpl = &SMFCDREventImpl{
|
||||
selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, JSON_EXTRACT(cdr_json, '$.recordType') AS record_type, JSON_EXTRACT(cdr_json, '$.chargingID') AS charging_id, JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') AS subscriber_id, JSON_EXTRACT(cdr_json, '$.duration') AS duration, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink') AS data_volume_uplink, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink') AS data_volume_downlink, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume') AS data_total_volume, JSON_EXTRACT(cdr_json, '$.pDUSessionChargingInformation.pDUAddress') AS pdu_address, created_at from cdr_event_smf`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"id": "ID",
|
||||
"ne_type": "NeType",
|
||||
"ne_name": "NeName",
|
||||
"rm_uid": "RmUID",
|
||||
"timestamp": "Timestamp",
|
||||
"record_type": "RecordType",
|
||||
"charging_id": "ChargingID",
|
||||
"subscriber_id": "SubscriberID",
|
||||
"duration": "Duration",
|
||||
"data_volume_uplink": "DataVolumeUplink",
|
||||
"data_volume_downlink": "DataVolumeDownlink",
|
||||
"data_total_volume": "DataTotalVolume",
|
||||
"pdu_address": "PDUAddress",
|
||||
"created_at": "CreatedAt",
|
||||
},
|
||||
}
|
||||
|
||||
// CDREventImpl CDR会话事件 数据层处理
|
||||
type SMFCDREventImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *CDREventImpl) convertResultRows(rows []map[string]any) []model.CDREvent {
|
||||
arr := make([]model.CDREvent, 0)
|
||||
@@ -63,10 +93,6 @@ func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any {
|
||||
conditions = append(conditions, "rm_uid = ?")
|
||||
params = append(params, querys.RmUID)
|
||||
}
|
||||
if querys.RmUID != "" {
|
||||
conditions = append(conditions, "rm_uid = ?")
|
||||
params = append(params, querys.RmUID)
|
||||
}
|
||||
if querys.StartTime != "" {
|
||||
conditions = append(conditions, "timestamp >= ?")
|
||||
beginDate := date.ParseStrToDate(querys.StartTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||
@@ -77,6 +103,14 @@ func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any {
|
||||
endDate := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||
params = append(params, endDate.Unix())
|
||||
}
|
||||
if querys.CallerParty != "" {
|
||||
conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.callerParty') = ?")
|
||||
params = append(params, querys.CallerParty)
|
||||
}
|
||||
if querys.CalledParty != "" {
|
||||
conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.calledParty') = ?")
|
||||
params = append(params, querys.CalledParty)
|
||||
}
|
||||
if querys.RecordType != "" {
|
||||
recordTypes := strings.Split(querys.RecordType, ",")
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(recordTypes))
|
||||
@@ -98,7 +132,7 @@ func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any {
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from cdr_event"
|
||||
totalSql := "select count(1) as 'total' from cdr_event_ims"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
@@ -160,7 +194,146 @@ func (r *CDREventImpl) SelectByIds(cdrIds []string) []model.CDREvent {
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventImpl) DeleteByIds(cdrIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(cdrIds))
|
||||
sql := "delete from cdr_event where id in (" + placeholder + ")"
|
||||
sql := "delete from cdr_event_ims where id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(cdrIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SMFCDREventImpl) convertResultRows(rows []map[string]any) []model.CDREventSMF {
|
||||
arr := make([]model.CDREventSMF, 0)
|
||||
for _, row := range rows {
|
||||
item := model.CDREventSMF{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&item, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, item)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r *SMFCDREventImpl) SelectPage(querys model.SMFCDREventQuery) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if querys.NeType != "" {
|
||||
conditions = append(conditions, "ne_type = ?")
|
||||
params = append(params, querys.NeType)
|
||||
}
|
||||
if querys.RmUID != "" {
|
||||
conditions = append(conditions, "rm_uid = ?")
|
||||
params = append(params, querys.RmUID)
|
||||
}
|
||||
if querys.StartTime != "" {
|
||||
conditions = append(conditions, "timestamp >= ?")
|
||||
beginDate := date.ParseStrToDate(querys.StartTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||
params = append(params, beginDate.Unix())
|
||||
}
|
||||
if querys.EndTime != "" {
|
||||
conditions = append(conditions, "timestamp <= ?")
|
||||
endDate := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||
params = append(params, endDate.Unix())
|
||||
}
|
||||
if querys.RecordType != "" {
|
||||
conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.recordType') = ?")
|
||||
params = append(params, querys.RecordType)
|
||||
}
|
||||
if querys.SubscriberID != "" {
|
||||
conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') = ?")
|
||||
params = append(params, querys.SubscriberID)
|
||||
}
|
||||
// if querys.RecordType != "" {
|
||||
// recordTypes := strings.Split(querys.RecordType, ",")
|
||||
// placeholder := repo.KeyPlaceholderByQuery(len(recordTypes))
|
||||
// conditions = append(conditions, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') in (%s)", placeholder))
|
||||
// for _, recordType := range recordTypes {
|
||||
// params = append(params, recordType)
|
||||
// }
|
||||
// }
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
result := map[string]any{
|
||||
"total": 0,
|
||||
"rows": []model.CDREventSMF{},
|
||||
}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
totalSql := "select count(1) as 'total' from cdr_event_smf"
|
||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("total err => %v", err)
|
||||
return result
|
||||
}
|
||||
total := parse.Number(totalRows[0]["total"])
|
||||
if total == 0 {
|
||||
return result
|
||||
} else {
|
||||
result["total"] = total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(querys.PageNum, querys.PageSize)
|
||||
pageSql := " limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
// 排序
|
||||
orderSql := ""
|
||||
if querys.SortField != "" {
|
||||
sortSql := querys.SortField
|
||||
if querys.SortOrder != "" {
|
||||
if querys.SortOrder == "desc" {
|
||||
sortSql += " desc "
|
||||
} else {
|
||||
sortSql += " asc "
|
||||
}
|
||||
}
|
||||
orderSql = fmt.Sprintf(" order by id desc, %s ", sortSql)
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := r.selectSql + whereSql + orderSql + pageSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
result["rows"] = r.convertResultRows(results)
|
||||
return result
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r *SMFCDREventImpl) SelectByIds(cdrIds []string) []model.CDREventSMF {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(cdrIds))
|
||||
querySql := r.selectSql + " where id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(cdrIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.CDREventSMF{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *SMFCDREventImpl) DeleteByIds(cdrIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(cdrIds))
|
||||
sql := "delete from cdr_event_smf where id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(cdrIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
|
||||
@@ -7,9 +7,15 @@ type IPerfKPI interface {
|
||||
// SelectGoldKPI 通过网元指标数据信息
|
||||
SelectGoldKPI(query model.GoldKPIQuery, kpiIds []string) []map[string]any
|
||||
|
||||
// select from new kpi report table, exp. kpi_report_upf
|
||||
SelectKpiReport(query model.GoldKPIQuery, kpiIds []string) []map[string]any
|
||||
|
||||
// SelectGoldKPITitle 网元对应的指标名称
|
||||
SelectGoldKPITitle(neType string) []model.GoldKPITitle
|
||||
|
||||
// SelectUPFTotalFlow 查询UPF总流量 N3上行 N6下行
|
||||
SelectUPFTotalFlow(neType, rmUID, startDate, endDate string) map[string]any
|
||||
|
||||
// select upf throughput from new kpi_report
|
||||
SelectUPFThroughput(neType, rmUID, startDate, endDate string) map[string]any
|
||||
}
|
||||
|
||||
@@ -86,6 +86,79 @@ func (r *PerfKPIImpl) SelectGoldKPI(query model.GoldKPIQuery, kpiIds []string) [
|
||||
return results
|
||||
}
|
||||
|
||||
func (r *PerfKPIImpl) SelectKpiReport(query model.GoldKPIQuery, kpiIds []string) []map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
var tableName string = "kpi_report_"
|
||||
if query.RmUID != "" {
|
||||
conditions = append(conditions, "gk.rm_uid = ?")
|
||||
params = append(params, query.RmUID)
|
||||
}
|
||||
if query.NeType != "" {
|
||||
conditions = append(conditions, "gk.ne_type = ?")
|
||||
params = append(params, query.NeType)
|
||||
tableName += strings.ToLower(query.NeType)
|
||||
}
|
||||
var dateTimeStr string = "CONCAT(gk.`date`, \" \", gk.start_time)"
|
||||
if query.StartTime != "" {
|
||||
conditions = append(conditions, dateTimeStr+" >= ?")
|
||||
params = append(params, query.StartTime)
|
||||
}
|
||||
if query.EndTime != "" {
|
||||
conditions = append(conditions, dateTimeStr+" <= ?")
|
||||
params = append(params, query.EndTime)
|
||||
}
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询字段列
|
||||
timeFormat := "DATE_FORMAT(" + dateTimeStr + ", '%Y-%m-%d %H:%i:')"
|
||||
secondGroup := fmt.Sprintf("LPAD(FLOOR(SECOND(gk.start_time) / %d) * %d, 2, '0')", query.Interval, query.Interval)
|
||||
groupByField := fmt.Sprintf("CONCAT( %s, %s ) AS timeGroup", timeFormat, secondGroup)
|
||||
if query.Interval > 60 {
|
||||
minute := query.Interval / 60
|
||||
timeFormat = "DATE_FORMAT(" + dateTimeStr + ", '%Y-%m-%d %H:')"
|
||||
minuteGroup := fmt.Sprintf("LPAD(FLOOR(MINUTE(gk.start_time) / %d) * %d, 2, '0')", minute, minute)
|
||||
groupByField = fmt.Sprintf("CONCAT( %s, %s ) AS timeGroup", timeFormat, minuteGroup)
|
||||
}
|
||||
var fields = []string{
|
||||
groupByField,
|
||||
"min(CASE WHEN gk.index != '' THEN gk.index ELSE 0 END) AS startIndex",
|
||||
"min(CASE WHEN gk.ne_type != '' THEN gk.ne_type ELSE 0 END) AS neType",
|
||||
"min(CASE WHEN gk.ne_name != '' THEN gk.ne_name ELSE 0 END) AS neName",
|
||||
}
|
||||
for i, kid := range kpiIds {
|
||||
// 特殊字段,只取最后一次收到的非0值
|
||||
if kid == "AMF.01" || kid == "UDM.01" || kid == "UDM.02" || kid == "UDM.03" || kid == "SMF.01" {
|
||||
str := fmt.Sprintf("IFNULL(SUBSTRING_INDEX(GROUP_CONCAT( CASE WHEN JSON_EXTRACT(gk.kpi_values, '$[%d].kpi_id') = '%s' THEN JSON_EXTRACT(gk.kpi_values, '$[%d].value') END ), ',', 1), 0) AS '%s'", i, kid, i, kid)
|
||||
fields = append(fields, str)
|
||||
} else {
|
||||
str := fmt.Sprintf("sum(CASE WHEN JSON_EXTRACT(gk.kpi_values, '$[%d].kpi_id') = '%s' THEN JSON_EXTRACT(gk.kpi_values, '$[%d].value') ELSE 0 END) AS '%s'", i, kid, i, kid)
|
||||
fields = append(fields, str)
|
||||
}
|
||||
}
|
||||
fieldsSql := strings.Join(fields, ",")
|
||||
|
||||
// 查询数据
|
||||
if query.SortField == "" {
|
||||
query.SortField = "timeGroup"
|
||||
}
|
||||
if query.SortOrder == "" {
|
||||
query.SortOrder = "desc"
|
||||
}
|
||||
orderSql := fmt.Sprintf(" order by %s %s", query.SortField, query.SortOrder)
|
||||
querySql := fmt.Sprintf("SELECT %s FROM %s gk %s GROUP BY timeGroup %s", fieldsSql, tableName, whereSql, orderSql)
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// SelectGoldKPITitle 网元对应的指标名称
|
||||
func (r *PerfKPIImpl) SelectGoldKPITitle(neType string) []model.GoldKPITitle {
|
||||
result := []model.GoldKPITitle{}
|
||||
@@ -131,3 +204,39 @@ func (r *PerfKPIImpl) SelectUPFTotalFlow(neType, rmUID, startDate, endDate strin
|
||||
}
|
||||
return results[0]
|
||||
}
|
||||
|
||||
// SelectUPFTotalFlow 查询UPF总流量 N3上行 N6下行
|
||||
func (r *PerfKPIImpl) SelectUPFThroughput(neType, rmUID, startDate, endDate string) map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if neType != "" {
|
||||
conditions = append(conditions, "gk.ne_type = ?")
|
||||
params = append(params, neType)
|
||||
}
|
||||
if rmUID != "" {
|
||||
conditions = append(conditions, "gk.rm_uid = ?")
|
||||
params = append(params, rmUID)
|
||||
}
|
||||
if startDate != "" {
|
||||
conditions = append(conditions, "gk.date >= ?")
|
||||
params = append(params, startDate)
|
||||
}
|
||||
if endDate != "" {
|
||||
conditions = append(conditions, "gk.date <= ?")
|
||||
params = append(params, endDate)
|
||||
}
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := fmt.Sprintf("SELECT sum( CASE WHEN JSON_EXTRACT(gk.kpi_values, '$[2].kpi_id') = 'UPF.03' THEN JSON_EXTRACT(gk.kpi_values, '$[2].value') ELSE 0 END ) AS 'up', sum( CASE WHEN JSON_EXTRACT(gk.kpi_values, '$[5].kpi_id') = 'UPF.06' THEN JSON_EXTRACT(gk.kpi_values, '$[5].value') ELSE 0 END ) AS 'down' FROM kpi_report_upf gk %s", whereSql)
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return results[0]
|
||||
}
|
||||
|
||||
@@ -74,6 +74,10 @@ func (r *UEEventImpl) SelectPage(querys model.UEEventQuery) map[string]any {
|
||||
endDate := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||
params = append(params, endDate.Unix())
|
||||
}
|
||||
if querys.IMSI != "" {
|
||||
conditions = append(conditions, "JSON_EXTRACT(event_json, '$.imsi') = ?")
|
||||
params = append(params, querys.IMSI)
|
||||
}
|
||||
if querys.EventType != "" {
|
||||
eventTypes := strings.Split(querys.EventType, ",")
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(eventTypes))
|
||||
|
||||
@@ -10,3 +10,12 @@ type ICDREvent interface {
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(cdrIds []string) (int64, error)
|
||||
}
|
||||
|
||||
// CDR会话事件 服务层接口
|
||||
type SMFCDREvent interface {
|
||||
// SelectPage 根据条件分页查询
|
||||
SelectPage(querys model.SMFCDREventQuery) map[string]any
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(cdrIds []string) (int64, error)
|
||||
}
|
||||
|
||||
@@ -12,12 +12,21 @@ var NewCDREventImpl = &CDREventImpl{
|
||||
cdrEventRepository: repository.NewCDREventImpl,
|
||||
}
|
||||
|
||||
var NewSMFCDREventImpl = &SMFCDREventImpl{
|
||||
cdrEventRepository: repository.NewSMFCDREventImpl,
|
||||
}
|
||||
|
||||
// CDREventImpl CDR会话事件 服务层处理
|
||||
type CDREventImpl struct {
|
||||
// CDR会话事件数据信息
|
||||
cdrEventRepository repository.ICDREvent
|
||||
}
|
||||
|
||||
type SMFCDREventImpl struct {
|
||||
// CDR会话事件数据信息
|
||||
cdrEventRepository repository.SMFCDREvent
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any {
|
||||
return r.cdrEventRepository.SelectPage(querys)
|
||||
@@ -38,3 +47,23 @@ func (r *CDREventImpl) DeleteByIds(cdrIds []string) (int64, error) {
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
func (r *SMFCDREventImpl) SelectPage(querys model.SMFCDREventQuery) map[string]any {
|
||||
return r.cdrEventRepository.SelectPage(querys)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *SMFCDREventImpl) DeleteByIds(cdrIds []string) (int64, error) {
|
||||
// 检查是否存在
|
||||
ids := r.cdrEventRepository.SelectByIds(cdrIds)
|
||||
if len(ids) <= 0 {
|
||||
return 0, fmt.Errorf("not data")
|
||||
}
|
||||
|
||||
if len(ids) == len(cdrIds) {
|
||||
rows := r.cdrEventRepository.DeleteByIds(cdrIds)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ func (r *PerfKPIImpl) SelectGoldKPI(query model.GoldKPIQuery) []map[string]any {
|
||||
kpiIds = append(kpiIds, kpiId.KPIID)
|
||||
}
|
||||
|
||||
data := r.perfKPIRepository.SelectGoldKPI(query, kpiIds)
|
||||
//data := r.perfKPIRepository.SelectGoldKPI(query, kpiIds)
|
||||
data := r.perfKPIRepository.SelectKpiReport(query, kpiIds)
|
||||
if data == nil {
|
||||
return []map[string]any{}
|
||||
}
|
||||
@@ -66,7 +67,8 @@ func (r *PerfKPIImpl) SelectUPFTotalFlow(neType, rmUID string, day int) map[stri
|
||||
}
|
||||
}
|
||||
|
||||
info = r.perfKPIRepository.SelectUPFTotalFlow(neType, rmUID, startDate, endDate)
|
||||
//info = r.perfKPIRepository.SelectUPFTotalFlow(neType, rmUID, startDate, endDate)
|
||||
info = r.perfKPIRepository.SelectUPFThroughput(neType, rmUID, startDate, endDate)
|
||||
|
||||
// 保存到缓存
|
||||
infoJSON, _ := json.Marshal(info)
|
||||
|
||||
@@ -155,3 +155,52 @@ func (s *NeActionController) Files(c *gin.Context) {
|
||||
"rows": splitRows,
|
||||
}))
|
||||
}
|
||||
|
||||
// 网元服务操作
|
||||
//
|
||||
// PUT /service
|
||||
func (s *NeActionController) Service(c *gin.Context) {
|
||||
language := ctx.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.ShouldBindBodyWith(&body, binding.JSON); 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
|
||||
}
|
||||
|
||||
neTypeLower := strings.ToLower(neInfo.NeType)
|
||||
cmdStr := fmt.Sprintf("sudo service %s %s", neTypeLower, body.Action)
|
||||
if neTypeLower == "omc" {
|
||||
cmdStr = fmt.Sprintf("nohup sh -c \"sudo systemctl stop restagent && sleep 5s && sudo systemctl %s restagent\" > /dev/null 2>&1 &", body.Action)
|
||||
} else if neTypeLower == "ims" {
|
||||
if body.Action == "restart" {
|
||||
cmdStr = "sudo ims-stop || true && sudo 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.NeRunCMD(body.NeType, body.NeID, cmdStr)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
@@ -167,8 +167,7 @@ func (s *NeHostController) Remove(c *gin.Context) {
|
||||
func (s *NeHostController) Test(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeHost
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
@@ -176,8 +175,13 @@ func (s *NeHostController) Test(c *gin.Context) {
|
||||
if body.HostType == "ssh" {
|
||||
var connSSH ssh.ConnSSH
|
||||
body.CopyTo(&connSSH)
|
||||
|
||||
client, err := connSSH.NewClient()
|
||||
var client *ssh.ConnSSH
|
||||
var err error
|
||||
if body.AuthMode == "2" {
|
||||
client, err = connSSH.NewClientByLocalPrivate()
|
||||
} else {
|
||||
client, err = connSSH.NewClient()
|
||||
}
|
||||
if err != nil {
|
||||
// 连接主机失败,请检查连接参数后重试
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
|
||||
@@ -199,7 +203,12 @@ func (s *NeHostController) Test(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
c.JSON(200, result.Ok(nil))
|
||||
if strings.HasSuffix(client.LastResult, ">") || strings.HasSuffix(client.LastResult, "> ") || strings.HasSuffix(client.LastResult, "# ") {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
} else {
|
||||
// 连接主机失败,请检查连接参数后重试
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -213,8 +222,7 @@ func (s *NeHostController) Cmd(c *gin.Context) {
|
||||
HostID string `json:"hostId" binding:"required"` // 主机ID
|
||||
Cmd string `json:"cmd" binding:"required"` // 执行命令
|
||||
}
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
@@ -230,8 +238,13 @@ func (s *NeHostController) Cmd(c *gin.Context) {
|
||||
if neHost.HostType == "ssh" {
|
||||
var connSSH ssh.ConnSSH
|
||||
neHost.CopyTo(&connSSH)
|
||||
|
||||
client, err := connSSH.NewClient()
|
||||
var client *ssh.ConnSSH
|
||||
var err error
|
||||
if neHost.AuthMode == "2" {
|
||||
client, err = connSSH.NewClientByLocalPrivate()
|
||||
} else {
|
||||
client, err = connSSH.NewClient()
|
||||
}
|
||||
if err != nil {
|
||||
// 连接主机失败,请检查连接参数后重试
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
|
||||
@@ -278,17 +291,21 @@ func (s *NeHostController) Cmd(c *gin.Context) {
|
||||
func (s *NeHostController) CheckBySSH(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeHost
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
var connSSH ssh.ConnSSH
|
||||
body.CopyTo(&connSSH)
|
||||
|
||||
// 创建链接SSH客户端
|
||||
client, err := connSSH.NewClient()
|
||||
var client *ssh.ConnSSH
|
||||
var err error
|
||||
if body.AuthMode == "2" {
|
||||
client, err = connSSH.NewClientByLocalPrivate()
|
||||
} else {
|
||||
client, err = connSSH.NewClient()
|
||||
}
|
||||
if err != nil {
|
||||
// 连接主机失败,请检查连接参数后重试
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
|
||||
@@ -339,18 +356,22 @@ func (s *NeHostController) CheckBySSH(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 本地免密创建链接直连
|
||||
lcoalConnSSH := ssh.ConnSSH{
|
||||
User: body.User,
|
||||
Addr: body.Addr,
|
||||
Port: body.Port,
|
||||
}
|
||||
lcoalClient, err := lcoalConnSSH.NewClientByLocalPrivate()
|
||||
if err == nil {
|
||||
if body.AuthMode == "2" {
|
||||
data["sshLink"] = true
|
||||
} else {
|
||||
data["sshLink"] = false
|
||||
lcoalConnSSH := ssh.ConnSSH{
|
||||
User: body.User,
|
||||
Addr: body.Addr,
|
||||
Port: body.Port,
|
||||
}
|
||||
lcoalClient, err := lcoalConnSSH.NewClientByLocalPrivate()
|
||||
if err == nil {
|
||||
data["sshLink"] = true
|
||||
defer lcoalClient.Close()
|
||||
} else {
|
||||
data["sshLink"] = false
|
||||
}
|
||||
}
|
||||
defer lcoalClient.Close()
|
||||
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
@@ -361,8 +382,7 @@ func (s *NeHostController) CheckBySSH(c *gin.Context) {
|
||||
func (s *NeHostController) AuthorizedBySSH(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeHost
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil {
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil || body.AuthMode == "2" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
@@ -377,8 +397,8 @@ func (s *NeHostController) AuthorizedBySSH(c *gin.Context) {
|
||||
lcoalClient, err := lcoalConnSSH.NewClientByLocalPrivate()
|
||||
if err == nil {
|
||||
sshLink = true
|
||||
defer lcoalClient.Close()
|
||||
}
|
||||
defer lcoalClient.Close()
|
||||
if sshLink {
|
||||
// 连接主机成功,无需重复免密授权认证
|
||||
c.JSON(200, result.OkMsg(i18n.TKey(language, "neHost.okBySSHLink")))
|
||||
|
||||
@@ -17,15 +17,21 @@ import (
|
||||
|
||||
// 实例化控制层 NeInfoController 结构体
|
||||
var NewNeInfo = &NeInfoController{
|
||||
neInfoService: neService.NewNeInfoImpl,
|
||||
neInfoService: neService.NewNeInfoImpl,
|
||||
neLicenseService: neService.NewNeLicenseImpl,
|
||||
neVersionService: neService.NewNeVersionImpl,
|
||||
}
|
||||
|
||||
// 网元信息请求
|
||||
//
|
||||
// PATH /
|
||||
// PATH /info
|
||||
type NeInfoController struct {
|
||||
// 网元信息服务
|
||||
neInfoService neService.INeInfo
|
||||
// 网元授权激活信息服务
|
||||
neLicenseService neService.INeLicense
|
||||
// 网元版本信息服务
|
||||
neVersionService neService.INeVersion
|
||||
}
|
||||
|
||||
// neStateCacheMap 网元状态缓存最后一次成功的信息
|
||||
@@ -114,7 +120,8 @@ func (s *NeInfoController) ListAll(c *gin.Context) {
|
||||
var querys struct {
|
||||
NeType string `form:"neType"`
|
||||
NeId string `form:"neId"`
|
||||
BandStatus string `form:"bandStatus"`
|
||||
BandStatus bool `form:"bandStatus"`
|
||||
BandHost bool `form:"bandHost"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
@@ -129,8 +136,7 @@ func (s *NeInfoController) ListAll(c *gin.Context) {
|
||||
if querys.NeId != "" {
|
||||
ne.NeId = querys.NeId
|
||||
}
|
||||
bandStatus := parse.Boolean(querys.BandStatus)
|
||||
neList := s.neInfoService.SelectList(ne, bandStatus)
|
||||
neList := s.neInfoService.SelectList(ne, querys.BandStatus, querys.BandHost)
|
||||
if len(neList) == 0 {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
@@ -138,53 +144,74 @@ func (s *NeInfoController) ListAll(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(neList))
|
||||
}
|
||||
|
||||
// 网元端配置文件读取
|
||||
// 网元端Para5G配置文件读取
|
||||
//
|
||||
// GET /configFile
|
||||
func (s *NeInfoController) ConfigFileRead(c *gin.Context) {
|
||||
// GET /para5GFile
|
||||
func (s *NeInfoController) Para5GFileRead(c *gin.Context) {
|
||||
data, err := s.neInfoService.NeConfPara5GRead()
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 网元端Para5G配置文件写入
|
||||
//
|
||||
// PUT /para5GFile
|
||||
func (s *NeInfoController) Para5GFileWrite(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
Content map[string]any `json:"content" binding:"required"` // 内容
|
||||
SyncNE []string `json:"syncNe"` // 同步到网元
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
err := s.neInfoService.NeConfPara5GWirte(body.Content, body.SyncNE)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
}
|
||||
|
||||
// 网元端OAM配置文件读取
|
||||
//
|
||||
// GET /oamFile
|
||||
func (s *NeInfoController) OAMFileRead(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"` // 不带文件路径时进行复制覆盖本地网元配置目录
|
||||
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
|
||||
}
|
||||
|
||||
// 查询网元获取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")))
|
||||
data, err := s.neInfoService.NeConfOAMRead(querys.NeType, querys.NeID)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
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"))
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 网元端配置文件写入
|
||||
// 网元端OAM配置文件写入
|
||||
//
|
||||
// PUT /configFile
|
||||
func (s *NeInfoController) ConfigFileWrite(c *gin.Context) {
|
||||
// PUT /oamFile
|
||||
func (s *NeInfoController) OAMFileWrite(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"`
|
||||
NeType string `json:"neType" binding:"required"`
|
||||
NeID string `json:"neId" binding:"required"`
|
||||
Content map[string]any `json:"content" binding:"required"` // 内容
|
||||
Sync bool `json:"sync"` // 同步到网元
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
@@ -196,7 +223,7 @@ func (s *NeInfoController) ConfigFileWrite(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
err := s.neInfoService.NeConfigFileWirte(neInfo, body.FilePath, body.Content, body.Sync)
|
||||
err := s.neInfoService.NeConfOAMSync(neInfo, body.Content, body.Sync)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
@@ -260,22 +287,53 @@ func (s *NeInfoController) Add(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 获取网元状态是否正常
|
||||
_, err = neService.NeState(body)
|
||||
body.ServerState, err = neService.NeState(body)
|
||||
if err != nil {
|
||||
body.Status = "1"
|
||||
body.Status = "0"
|
||||
} else {
|
||||
// 下发网管配置信息给网元
|
||||
_, err = neService.NeConfigOMC(body)
|
||||
if err == nil {
|
||||
body.Status = "0"
|
||||
body.Status = "1"
|
||||
} else {
|
||||
body.Status = "3"
|
||||
body.Status = "2"
|
||||
}
|
||||
}
|
||||
|
||||
loginUserName := ctx.LoginUserToUserName(c)
|
||||
// 新增Version信息
|
||||
neVersion := model.NeVersion{
|
||||
NeType: body.NeType,
|
||||
NeId: body.NeId,
|
||||
CreateBy: loginUserName,
|
||||
}
|
||||
// 新增License信息
|
||||
neLicense := model.NeLicense{
|
||||
NeType: body.NeType,
|
||||
NeId: body.NeId,
|
||||
CreateBy: loginUserName,
|
||||
}
|
||||
|
||||
// 已有网元可获取的信息
|
||||
if body.ServerState != nil {
|
||||
if v, ok := body.ServerState["version"]; ok && v != nil {
|
||||
neVersion.Version = v.(string)
|
||||
}
|
||||
if v, ok := body.ServerState["sn"]; ok && v != nil {
|
||||
neLicense.SerialNum = v.(string)
|
||||
}
|
||||
if v, ok := body.ServerState["expire"]; ok && v != nil {
|
||||
neLicense.ExpiryDate = v.(string)
|
||||
neLicense.Status = "1"
|
||||
}
|
||||
}
|
||||
|
||||
s.neVersionService.Insert(neVersion)
|
||||
s.neLicenseService.Insert(neLicense)
|
||||
body.CreateBy = loginUserName
|
||||
insertId := s.neInfoService.Insert(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
c.JSON(200, result.OkData(insertId))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
@@ -294,8 +352,8 @@ func (s *NeInfoController) Edit(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueHostCmd := s.neInfoService.CheckUniqueNeTypeAndNeId(body.NeType, body.NeId, body.ID)
|
||||
if !uniqueHostCmd {
|
||||
uniqueInfo := s.neInfoService.CheckUniqueNeTypeAndNeId(body.NeType, body.NeId, body.ID)
|
||||
if !uniqueInfo {
|
||||
// 网元信息操作【%s】失败,同类型下标识已存在
|
||||
msg := i18n.TTemplate(language, "neInfo.errKeyExists", map[string]any{"key": body.NeId})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
@@ -309,21 +367,64 @@ func (s *NeInfoController) Edit(c *gin.Context) {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neInfo.noData")))
|
||||
return
|
||||
}
|
||||
// 赋予主机ID
|
||||
if neInfo.HostIDs != "" && len(body.Hosts) > 0 {
|
||||
hostIDs := strings.Split(neInfo.HostIDs, ",")
|
||||
for index, id := range hostIDs {
|
||||
body.Hosts[index].HostID = id
|
||||
}
|
||||
}
|
||||
|
||||
// 获取网元状态是否正常
|
||||
_, err = neService.NeState(body)
|
||||
body.ServerState, err = neService.NeState(body)
|
||||
if err != nil {
|
||||
body.Status = "1"
|
||||
body.Status = "0"
|
||||
} else {
|
||||
// 下发网管配置信息给网元
|
||||
_, err = neService.NeConfigOMC(body)
|
||||
if err == nil {
|
||||
body.Status = "0"
|
||||
body.Status = "1"
|
||||
} else {
|
||||
body.Status = "3"
|
||||
body.Status = "2"
|
||||
}
|
||||
}
|
||||
|
||||
loginUserName := ctx.LoginUserToUserName(c)
|
||||
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
neVersion := s.neVersionService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
// 已有网元可获取的信息
|
||||
if body.ServerState != nil {
|
||||
if v, ok := body.ServerState["version"]; ok && v != nil {
|
||||
neVersion.Version = v.(string)
|
||||
neVersion.UpdateBy = loginUserName
|
||||
}
|
||||
if v, ok := body.ServerState["sn"]; ok && v != nil {
|
||||
neLicense.SerialNum = v.(string)
|
||||
}
|
||||
if v, ok := body.ServerState["expire"]; ok && v != nil {
|
||||
neLicense.ExpiryDate = v.(string)
|
||||
neLicense.Status = "1"
|
||||
neLicense.UpdateBy = loginUserName
|
||||
}
|
||||
}
|
||||
|
||||
if neVersion.ID != "" {
|
||||
if neVersion.NeType != body.NeType || neVersion.NeId != body.NeId {
|
||||
neVersion.NeType = body.NeType
|
||||
neVersion.NeId = body.NeId
|
||||
}
|
||||
s.neVersionService.Update(neVersion)
|
||||
}
|
||||
if neLicense.ID != "" {
|
||||
if neLicense.NeType != body.NeType || neLicense.NeId != body.NeId {
|
||||
neLicense.NeType = body.NeType
|
||||
neLicense.NeId = body.NeId
|
||||
}
|
||||
s.neLicenseService.Update(neLicense)
|
||||
}
|
||||
|
||||
body.UpdateBy = loginUserName
|
||||
rows := s.neInfoService.Update(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
|
||||
@@ -2,11 +2,9 @@ package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/ctx"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
@@ -37,6 +35,14 @@ func (s *NeLicenseController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.neLicenseService.SelectPage(querys)
|
||||
|
||||
// 过滤屏蔽授权文件
|
||||
rows := data["rows"].([]model.NeLicense)
|
||||
arr := &rows
|
||||
for i := range *arr {
|
||||
(*arr)[i].ActivationRequestCode = "-"
|
||||
(*arr)[i].LicensePath = "-"
|
||||
}
|
||||
|
||||
c.JSON(200, result.Ok(data))
|
||||
}
|
||||
|
||||
@@ -61,109 +67,28 @@ func (s *NeLicenseController) Info(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(neLicense))
|
||||
}
|
||||
|
||||
// 网元授权激活信息新增
|
||||
// 网元neType和neID查询
|
||||
//
|
||||
// POST /
|
||||
func (s *NeLicenseController) Add(c *gin.Context) {
|
||||
// GET /byTypeAndID
|
||||
func (s *NeLicenseController) NeTypeAndID(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeLicense
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.ID != "" {
|
||||
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
|
||||
}
|
||||
|
||||
// 查询网元获取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
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueInfo := s.neLicenseService.CheckUniqueTypeAndID(neInfo.NeType, neInfo.NeId, "")
|
||||
if !uniqueInfo {
|
||||
// 网元授权激活操作【%s】失败,网元类型信息已存在
|
||||
msg := i18n.TTemplate(language, "neLicense.errKeyExists", map[string]any{"name": neInfo.NeType})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 读取授权码
|
||||
code, _ := s.neLicenseService.ReadLicenseInfo(neInfo)
|
||||
body.ActivationRequestCode = code
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.neLicenseService.Insert(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 网元授权激活信息修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *NeLicenseController) Edit(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeLicense
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.ID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueInfo := s.neLicenseService.CheckUniqueTypeAndID(body.NeType, body.NeId, body.ID)
|
||||
if !uniqueInfo {
|
||||
// 网元授权激活操作【%s】失败,网元类型信息已存在
|
||||
msg := i18n.TTemplate(language, "neLicense.errKeyExists", map[string]any{"name": body.NeType})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
neLicense := s.neLicenseService.SelectById(body.ID)
|
||||
if neLicense.ID != body.ID {
|
||||
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(querys.NeType, querys.NeId)
|
||||
if neLicense.NeId != querys.NeId {
|
||||
// 没有可访问网元授权激活数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.neLicenseService.Update(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 网元授权激活信息删除
|
||||
//
|
||||
// DELETE /:licenseIds
|
||||
func (s *NeLicenseController) Remove(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
licenseIds := c.Param("licenseIds")
|
||||
if licenseIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(licenseIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.neLicenseService.DeleteByIds(uniqueIDs)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
c.JSON(200, result.OkData(neLicense))
|
||||
}
|
||||
|
||||
// 网元授权激活授权申请码
|
||||
@@ -180,15 +105,8 @@ func (s *NeLicenseController) Code(c *gin.Context) {
|
||||
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
|
||||
}
|
||||
|
||||
// 检查是否存在授权记录
|
||||
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(querys.NeType, querys.NeId)
|
||||
if neLicense.NeId != querys.NeId {
|
||||
// 没有可访问网元授权激活数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
|
||||
@@ -196,7 +114,7 @@ func (s *NeLicenseController) Code(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 更新授权码
|
||||
code, licensePath := s.neLicenseService.ReadLicenseInfo(neInfo)
|
||||
code, licensePath := s.neLicenseService.ReadLicenseInfo(neLicense)
|
||||
neLicense.ActivationRequestCode = code
|
||||
if licensePath != "" {
|
||||
neLicense.LicensePath = licensePath
|
||||
@@ -218,7 +136,7 @@ func (s *NeLicenseController) Change(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeLicense
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.HostId == "" {
|
||||
if err != nil || body.LicensePath == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
@@ -226,23 +144,30 @@ func (s *NeLicenseController) Change(c *gin.Context) {
|
||||
// 检查是否存在授权记录
|
||||
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(body.NeType, body.NeId)
|
||||
if neLicense.NeId != body.NeId {
|
||||
body.Status = "0"
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
body.ID = s.neLicenseService.Insert(body)
|
||||
} else {
|
||||
neLicense.LicensePath = body.LicensePath
|
||||
neLicense.Status = "0"
|
||||
neLicense.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
s.neLicenseService.Update(neLicense)
|
||||
}
|
||||
|
||||
// 进行上传替换
|
||||
err = s.neLicenseService.UploadToNeHost(body)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
// 没有可访问网元授权激活数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
|
||||
// 更新授权记录
|
||||
if body.Remark != "" {
|
||||
neLicense.Remark = body.Remark
|
||||
}
|
||||
neLicense.LicensePath = body.LicensePath
|
||||
neLicense.Status = "0"
|
||||
neLicense.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
upRows := s.neLicenseService.Update(neLicense)
|
||||
if upRows > 0 {
|
||||
// 进行上传替换
|
||||
err = s.neLicenseService.UploadLicense(body)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 网元授权激活状态
|
||||
@@ -259,43 +184,41 @@ func (s *NeLicenseController) State(c *gin.Context) {
|
||||
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
|
||||
}
|
||||
|
||||
// 检查是否存在授权记录
|
||||
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
neLicense := s.neLicenseService.SelectByNeTypeAndNeID(querys.NeType, querys.NeId)
|
||||
if neLicense.NeId != querys.NeId {
|
||||
// 没有可访问网元授权激活数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元状态
|
||||
neState, err := neService.NeState(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg("network element service anomaly"))
|
||||
// 查询网元获取IP获取网元状态
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neLicense.NeType, neLicense.NeId)
|
||||
if neInfo.NeId != neLicense.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
if neState, err := neService.NeState(neInfo); err == nil {
|
||||
neLicense.Status = "1"
|
||||
neLicense.SerialNum = fmt.Sprint(neState["sn"])
|
||||
neLicense.ExpiryDate = fmt.Sprint(neState["expire"])
|
||||
code, licensePath := s.neLicenseService.ReadLicenseInfo(neLicense)
|
||||
neLicense.ActivationRequestCode = code
|
||||
neLicense.LicensePath = licensePath
|
||||
} else {
|
||||
neLicense.Status = "0"
|
||||
}
|
||||
|
||||
// 更新授权信息
|
||||
neLicense.SerialNum = fmt.Sprint(neState["sn"])
|
||||
neLicense.ExpiryDate = fmt.Sprint(neState["expire"])
|
||||
code, licensePath := s.neLicenseService.ReadLicenseInfo(neInfo)
|
||||
neLicense.ActivationRequestCode = code
|
||||
neLicense.LicensePath = licensePath
|
||||
neLicense.Status = "1"
|
||||
neLicense.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.neLicenseService.Update(neLicense)
|
||||
if rows > 0 {
|
||||
s.neLicenseService.Update(neLicense)
|
||||
|
||||
if neLicense.Status == "1" {
|
||||
c.JSON(200, result.OkData(map[string]string{
|
||||
"sn": neLicense.SerialNum,
|
||||
"expire": neLicense.ExpiryDate,
|
||||
}))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
c.JSON(200, result.ErrMsg(fmt.Sprintf("%s service status exception", neLicense.NeType)))
|
||||
}
|
||||
|
||||
@@ -69,15 +69,26 @@ func (s *NeSoftwareController) Add(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndNameAndVersion(body.NeType, body.Name, body.Version, "")
|
||||
if !uniqueSoftware {
|
||||
// 网元软件包操作【%s】失败,网元类型与文件名版本已存在
|
||||
msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.Name})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
// 找到已存在的删除后重新添加
|
||||
neSoftwares := s.neSoftwareService.SelectList(model.NeSoftware{
|
||||
NeType: body.NeType,
|
||||
Name: body.Name,
|
||||
Version: body.Version,
|
||||
})
|
||||
if len(neSoftwares) > 0 {
|
||||
neSoftware := neSoftwares[0]
|
||||
s.neSoftwareService.DeleteByIds([]string{neSoftware.ID})
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
// uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndNameAndVersion(body.NeType, body.Name, body.Version, "")
|
||||
// if !uniqueSoftware {
|
||||
// // 网元软件包操作【%s】失败,网元类型与文件名版本已存在
|
||||
// msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.Name})
|
||||
// c.JSON(200, result.ErrMsg(msg))
|
||||
// return
|
||||
// }
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.neSoftwareService.Insert(body)
|
||||
if insertId != "" {
|
||||
@@ -151,40 +162,32 @@ func (s *NeSoftwareController) Remove(c *gin.Context) {
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
}
|
||||
|
||||
// 网元软件包安装检查
|
||||
// 网元软件包设为网元新版本
|
||||
//
|
||||
// POST /checkInstall
|
||||
func (s *NeSoftwareController) CheckInstall(c *gin.Context) {
|
||||
// POST /newNeVersion
|
||||
func (s *NeSoftwareController) NewNeVersion(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeSoftware
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.HostId == "" {
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在软件包记录
|
||||
// 找到已存在的软件包信息
|
||||
neSoftwares := s.neSoftwareService.SelectList(model.NeSoftware{
|
||||
NeType: body.NeType,
|
||||
Name: body.Name,
|
||||
Version: body.Version,
|
||||
})
|
||||
if len(neSoftwares) <= 0 {
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
body.ID = s.neSoftwareService.Insert(body)
|
||||
} else {
|
||||
if len(neSoftwares) > 0 {
|
||||
neSoftware := neSoftwares[0]
|
||||
neSoftware.Path = body.Path
|
||||
neSoftware.Description = body.Description
|
||||
neSoftware.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
s.neSoftwareService.Update(neSoftware)
|
||||
}
|
||||
|
||||
// 进行安装检查
|
||||
cmdStrArr, err := s.neSoftwareService.UploadToNeHost(body)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
s.neSoftwareService.UpdateVersions(neSoftware, model.NeVersion{
|
||||
NeType: neSoftware.NeType,
|
||||
UpdateBy: ctx.LoginUserToUserName(c),
|
||||
})
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.OkData(cmdStrArr))
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/ctx"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
@@ -57,96 +53,34 @@ func (s *NeVersionController) Info(c *gin.Context) {
|
||||
c.JSON(200, result.OkData(neVersion))
|
||||
}
|
||||
|
||||
// 网元版本信息新增
|
||||
// 网元版本操作
|
||||
//
|
||||
// POST /
|
||||
func (s *NeVersionController) Add(c *gin.Context) {
|
||||
// POST /operate
|
||||
func (s *NeVersionController) Operate(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeVersion
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.ID != "" {
|
||||
var body struct {
|
||||
Action string `json:"action" binding:"required,oneof=install upgrade rollback"` // 操作行为
|
||||
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
|
||||
NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID
|
||||
Preinput map[string]string `json:"preinput" ` // 预先输入参数
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueInfo := s.neVersionService.CheckUniqueTypeAndID(body.NeType, body.NeId, "")
|
||||
if !uniqueInfo {
|
||||
// 网元版本操作【%s】失败,网元类型信息已存在
|
||||
msg := i18n.TTemplate(language, "neVersion.errKeyExists", map[string]any{"name": body.NeType})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.neVersionService.Insert(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 网元版本信息修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *NeVersionController) Edit(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.NeVersion
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.ID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查属性值唯一
|
||||
uniqueInfo := s.neVersionService.CheckUniqueTypeAndID(body.NeType, body.NeId, body.ID)
|
||||
if !uniqueInfo {
|
||||
// 网元版本操作【%s】失败,网元类型信息已存在
|
||||
msg := i18n.TTemplate(language, "neVersion.errKeyExists", map[string]any{"name": body.NeType})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
neVersion := s.neVersionService.SelectById(body.ID)
|
||||
if neVersion.ID != body.ID {
|
||||
neVersion := s.neVersionService.SelectByNeTypeAndNeID(body.NeType, body.NeId)
|
||||
if neVersion.NeId != body.NeId {
|
||||
// 没有可访问网元版本数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neVersion.noData")))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.neVersionService.Update(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 网元版本信息删除
|
||||
//
|
||||
// DELETE /:versionIds
|
||||
func (s *NeVersionController) Remove(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
versionIds := c.Param("versionIds")
|
||||
if versionIds == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
// 处理字符转id数组后去重
|
||||
ids := strings.Split(versionIds, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
rows, err := s.neVersionService.DeleteByIds(uniqueIDs)
|
||||
// 进行相关命令操作
|
||||
output, err := s.neVersionService.Operate(body.Action, neVersion, body.Preinput)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
c.JSON(200, result.OkData(output))
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ type NeHost struct {
|
||||
Addr string `json:"addr" gorm:"column:addr" binding:"required"` // 主机地址
|
||||
Port int64 `json:"port" gorm:"column:port" binding:"required,number,max=65535,min=1"` // SSH端口
|
||||
User string `json:"user" gorm:"column:user" binding:"required"` // 主机用户名
|
||||
AuthMode string `json:"authMode" gorm:"column:auth_mode" binding:"oneof=0 1"` // 认证模式(0密码 1主机私钥)
|
||||
AuthMode string `json:"authMode" gorm:"column:auth_mode" binding:"oneof=0 1 2"` // 认证模式(0密码 1主机私钥 2已免密)
|
||||
Password string `json:"password" gorm:"column:password"` // 认证密码
|
||||
PrivateKey string `json:"privateKey" gorm:"column:private_key"` // 认证私钥
|
||||
PassPhrase string `json:"passPhrase" gorm:"column:pass_phrase"` // 认证私钥密码
|
||||
|
||||
@@ -2,21 +2,25 @@ package model
|
||||
|
||||
// NeInfo 网元信息对象 ne_info
|
||||
type NeInfo struct {
|
||||
ID string `json:"id"`
|
||||
NeType string `json:"neType" binding:"required"`
|
||||
NeId string `json:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUid"`
|
||||
NeName string `json:"neName"`
|
||||
IP string `json:"ip" binding:"required"`
|
||||
Port int64 `json:"port" binding:"required,number,max=65535,min=1"`
|
||||
PvFlag string `json:"pvFlag" binding:"oneof=PNF VNF"` // enum('PNF','VNF')
|
||||
Province string `json:"province"`
|
||||
VendorName string `json:"vendorName"`
|
||||
Dn string `json:"dn"`
|
||||
NeAddress string `json:"neAddress"`
|
||||
Status string `json:"status"` // 0: 在线 1: 下线 2: 备用 3: 待下发配置
|
||||
UpdateTime string `json:"updateTime"`
|
||||
HostIDs string `json:"hostIds"` // 网元主机ID组 数据格式(ssh,telnet,telnet)
|
||||
ID string `json:"id" gorm:"id"`
|
||||
NeType string `json:"neType" gorm:"ne_type" binding:"required"`
|
||||
NeId string `json:"neId" gorm:"ne_id" binding:"required"`
|
||||
RmUID string `json:"rmUid" gorm:"rm_uid"`
|
||||
NeName string `json:"neName" gorm:"ne_name"`
|
||||
IP string `json:"ip" gorm:"ip" binding:"required"`
|
||||
Port int64 `json:"port" gorm:"port" binding:"required,number,max=65535,min=1"`
|
||||
PvFlag string `json:"pvFlag" gorm:"pv_flag" binding:"oneof=PNF VNF"` // ''PNF'',''VNF''
|
||||
Province string `json:"province" gorm:"province"` // 省份地域
|
||||
VendorName string `json:"vendorName" gorm:"vendor_name"`
|
||||
Dn string `json:"dn" gorm:"dn"`
|
||||
NeAddress string `json:"neAddress" gorm:"ne_address"` // MAC地址
|
||||
HostIDs string `json:"hostIds" gorm:"host_ids"` // 网元主机ID组 数据格式(ssh,telnet,telnet)
|
||||
Status string `json:"status" gorm:"status"` // 0离线 1在线 2配置待下发
|
||||
Remark string `json:"remark" gorm:"remark"` // 备注
|
||||
CreateBy string `json:"createBy" gorm:"create_by"` // 创建者
|
||||
CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间
|
||||
UpdateBy string `json:"updateBy" gorm:"update_by"` // 更新者
|
||||
UpdateTime int64 `json:"updateTime" gorm:"update_time"` // 更新时间
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ type NeLicense struct {
|
||||
LicensePath string `json:"licensePath" gorm:"license_path"` // 激活授权文件
|
||||
SerialNum string `json:"serialNum" gorm:"serial_num"` // 序列号
|
||||
ExpiryDate string `json:"expiryDate" gorm:"expiry_date"` // 许可证到期日期
|
||||
Status string `json:"status" gorm:"status"` // 状态 ''ACTIVE'',''INACTIVE'',''PENDING''
|
||||
Status string `json:"status" gorm:"status"` // 状态 0无效 1有效
|
||||
Remark string `json:"remark" gorm:"remark"` // 备注
|
||||
CreateBy string `json:"createBy" gorm:"create_by"` // 创建者
|
||||
CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间
|
||||
@@ -18,8 +18,7 @@ type NeLicense struct {
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
Reload bool `json:"reload,omitempty" gorm:"-"` // 刷新重启网元
|
||||
HostId string `json:"hostId,omitempty" gorm:"-"` // 已记录的主机ID
|
||||
Reload bool `json:"reload,omitempty" gorm:"-"` // 刷新重启网元
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
|
||||
@@ -15,7 +15,7 @@ type NeSoftware struct {
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
HostId string `json:"hostId,omitempty" gorm:"-"` // 已记录的主机ID
|
||||
NeId string `json:"neId,omitempty" gorm:"-"` // 网元ID
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
|
||||
@@ -5,13 +5,16 @@ type NeVersion struct {
|
||||
ID string `json:"id" gorm:"id"`
|
||||
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
|
||||
NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID
|
||||
Name string `json:"name" gorm:"name"` // 当前包名
|
||||
Version string `json:"version" gorm:"version" binding:"required"` // 当前版本
|
||||
Path string `json:"path" gorm:"path" binding:"required"` // 当前软件包
|
||||
PreName string `json:"preName" gorm:"pre_name"` // 上一版本包名
|
||||
PreVersion string `json:"preVersion" gorm:"pre_version"` // 上一版本
|
||||
PrePath string `json:"prePath" gorm:"pre_path"` // 上一版本软件包
|
||||
NewVersion string `json:"newVersion" gorm:"new_version"` // 下一版本
|
||||
NewPath string `json:"newPath" gorm:"new_path"` // 下一版本软件包
|
||||
Status string `json:"status" gorm:"status"` // 当前状态 (Uploaded下一版本上传 Inactive下一版本待激活 Active当前已激活)
|
||||
NewName string `json:"newName" gorm:"new_name"` // 新版本包名
|
||||
NewVersion string `json:"newVersion" gorm:"new_version"` // 新版本
|
||||
NewPath string `json:"newPath" gorm:"new_path"` // 新版本软件包
|
||||
Status string `json:"status" gorm:"status"` // 当前状态 1当前版本 2上一版本 3有新版本
|
||||
CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者
|
||||
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
|
||||
UpdateBy string `json:"updateBy" gorm:"column:update_by"` // 更新者
|
||||
|
||||
@@ -36,6 +36,11 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neAction", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewNeAction.PushFile,
|
||||
)
|
||||
neActionGroup.PUT("/service",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neAction", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewNeAction.Service,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元信息
|
||||
@@ -53,13 +58,23 @@ func Setup(router *gin.Engine) {
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewNeInfo.ListAll,
|
||||
)
|
||||
neInfoGroup.GET("/configFile",
|
||||
neInfoGroup.GET("/para5GFile",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewNeInfo.ConfigFileRead,
|
||||
controller.NewNeInfo.Para5GFileRead,
|
||||
)
|
||||
neInfoGroup.PUT("/configFile",
|
||||
neInfoGroup.PUT("/para5GFile",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewNeInfo.ConfigFileWrite,
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neInfo", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewNeInfo.Para5GFileWrite,
|
||||
)
|
||||
neInfoGroup.GET("/oamFile",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewNeInfo.OAMFileRead,
|
||||
)
|
||||
neInfoGroup.PUT("/oamFile",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neInfo", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewNeInfo.OAMFileWrite,
|
||||
)
|
||||
neInfoGroup.GET("/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
@@ -173,20 +188,10 @@ func Setup(router *gin.Engine) {
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewNeVersion.Info,
|
||||
)
|
||||
neVersionGroup.POST("",
|
||||
neVersionGroup.POST("/operate",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neVersion", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewNeVersion.Add,
|
||||
)
|
||||
neVersionGroup.PUT("",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neVersion", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewNeVersion.Edit,
|
||||
)
|
||||
neVersionGroup.DELETE("/:versionIds",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neVersion", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewNeVersion.Remove,
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neVersion", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewNeVersion.Operate,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -216,10 +221,10 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewNeSoftware.Remove,
|
||||
)
|
||||
neSoftwareGroup.POST("/checkInstall",
|
||||
neSoftwareGroup.POST("/newNeVersion",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_OTHER)),
|
||||
controller.NewNeSoftware.CheckInstall,
|
||||
controller.NewNeSoftware.NewNeVersion,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -234,20 +239,9 @@ func Setup(router *gin.Engine) {
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewNeLicense.Info,
|
||||
)
|
||||
neLicenseGroup.POST("",
|
||||
neLicenseGroup.GET("/byTypeAndID",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewNeLicense.Add,
|
||||
)
|
||||
neLicenseGroup.PUT("",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewNeLicense.Edit,
|
||||
)
|
||||
neLicenseGroup.DELETE("/:licenseIds",
|
||||
middleware.PreAuthorize(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewNeLicense.Remove,
|
||||
controller.NewNeLicense.NeTypeAndID,
|
||||
)
|
||||
neLicenseGroup.GET("/code",
|
||||
middleware.PreAuthorize(nil),
|
||||
@@ -378,4 +372,8 @@ func InitLoad() {
|
||||
// 启动时,清除缓存-网元类型
|
||||
service.NewNeInfoImpl.ClearNeCacheByNeType("*")
|
||||
service.NewNeInfoImpl.SelectNeInfoByRmuid("")
|
||||
// 启动时,网元公共参数数据记录到全局变量
|
||||
if para5GMap, err := service.NewNeInfoImpl.NeConfPara5GRead(); para5GMap != nil && err == nil {
|
||||
service.NewNeInfoImpl.NeConfPara5GWirte(para5GMap, nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,21 +175,21 @@ func (r *NeHostImpl) SelectByIds(hostIds []string) []model.NeHost {
|
||||
for i := range *arr {
|
||||
passwordDe, err := crypto.StringDecryptByAES((*arr)[i].Password)
|
||||
if err != nil {
|
||||
logger.Errorf("selectById %s StringDecryptByAES : %v", (*arr)[i].HostID, err.Error())
|
||||
logger.Errorf("selectById %s decrypt: %v", (*arr)[i].HostID, err.Error())
|
||||
(*arr)[i].Password = ""
|
||||
} else {
|
||||
(*arr)[i].Password = passwordDe
|
||||
}
|
||||
privateKeyDe, err := crypto.StringDecryptByAES((*arr)[i].PrivateKey)
|
||||
if err != nil {
|
||||
logger.Errorf("selectById %s StringDecryptByAES : %v", (*arr)[i].HostID, err.Error())
|
||||
logger.Errorf("selectById %s decrypt: %v", (*arr)[i].HostID, err.Error())
|
||||
(*arr)[i].PrivateKey = ""
|
||||
} else {
|
||||
(*arr)[i].PrivateKey = privateKeyDe
|
||||
}
|
||||
passPhraseDe, err := crypto.StringDecryptByAES((*arr)[i].PassPhrase)
|
||||
if err != nil {
|
||||
logger.Errorf("selectById %s StringDecryptByAES : %v", (*arr)[i].HostID, err.Error())
|
||||
logger.Errorf("selectById %s decrypt: %v", (*arr)[i].HostID, err.Error())
|
||||
(*arr)[i].PassPhrase = ""
|
||||
} else {
|
||||
(*arr)[i].PassPhrase = passPhraseDe
|
||||
@@ -265,7 +265,7 @@ func (r *NeHostImpl) Insert(neHost model.NeHost) string {
|
||||
if neHost.Password != "" {
|
||||
passwordEn, err := crypto.StringEncryptByAES(neHost.Password)
|
||||
if err != nil {
|
||||
logger.Errorf("insert StringEncryptByAES : %v", err.Error())
|
||||
logger.Errorf("insert encrypt: %v", err.Error())
|
||||
return ""
|
||||
}
|
||||
params["password"] = passwordEn
|
||||
@@ -273,7 +273,7 @@ func (r *NeHostImpl) Insert(neHost model.NeHost) string {
|
||||
if neHost.PrivateKey != "" {
|
||||
privateKeyEn, err := crypto.StringEncryptByAES(neHost.PrivateKey)
|
||||
if err != nil {
|
||||
logger.Errorf("insert StringEncryptByAES : %v", err.Error())
|
||||
logger.Errorf("insert encrypt: %v", err.Error())
|
||||
return ""
|
||||
}
|
||||
params["private_key"] = privateKeyEn
|
||||
@@ -281,7 +281,7 @@ func (r *NeHostImpl) Insert(neHost model.NeHost) string {
|
||||
if neHost.PassPhrase != "" {
|
||||
passPhraseEn, err := crypto.StringEncryptByAES(neHost.PassPhrase)
|
||||
if err != nil {
|
||||
logger.Errorf("insert StringEncryptByAES : %v", err.Error())
|
||||
logger.Errorf("insert encrypt: %v", err.Error())
|
||||
return ""
|
||||
}
|
||||
params["pass_phrase"] = passPhraseEn
|
||||
@@ -294,6 +294,20 @@ func (r *NeHostImpl) Insert(neHost model.NeHost) string {
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 根据认证模式清除不必要的信息
|
||||
if neHost.AuthMode == "0" {
|
||||
params["private_key"] = ""
|
||||
params["pass_phrase"] = ""
|
||||
}
|
||||
if neHost.AuthMode == "1" {
|
||||
params["password"] = ""
|
||||
}
|
||||
if neHost.AuthMode == "2" {
|
||||
params["password"] = ""
|
||||
params["private_key"] = ""
|
||||
params["pass_phrase"] = ""
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into ne_host (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
@@ -349,7 +363,7 @@ func (r *NeHostImpl) Update(neHost model.NeHost) int64 {
|
||||
if neHost.Password != "" {
|
||||
passwordEn, err := crypto.StringEncryptByAES(neHost.Password)
|
||||
if err != nil {
|
||||
logger.Errorf("update StringEncryptByAES : %v", err.Error())
|
||||
logger.Errorf("update encrypt: %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
params["password"] = passwordEn
|
||||
@@ -357,7 +371,7 @@ func (r *NeHostImpl) Update(neHost model.NeHost) int64 {
|
||||
if neHost.PrivateKey != "" {
|
||||
privateKeyEn, err := crypto.StringEncryptByAES(neHost.PrivateKey)
|
||||
if err != nil {
|
||||
logger.Errorf("update StringEncryptByAES : %v", err.Error())
|
||||
logger.Errorf("update encrypt: %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
params["private_key"] = privateKeyEn
|
||||
@@ -365,7 +379,7 @@ func (r *NeHostImpl) Update(neHost model.NeHost) int64 {
|
||||
if neHost.PassPhrase != "" {
|
||||
passPhraseEn, err := crypto.StringEncryptByAES(neHost.PassPhrase)
|
||||
if err != nil {
|
||||
logger.Errorf("update StringEncryptByAES : %v", err.Error())
|
||||
logger.Errorf("update encrypt: %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
params["pass_phrase"] = passPhraseEn
|
||||
@@ -376,6 +390,20 @@ func (r *NeHostImpl) Update(neHost model.NeHost) int64 {
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 根据认证模式清除不必要的信息
|
||||
if neHost.AuthMode == "0" {
|
||||
params["private_key"] = ""
|
||||
params["pass_phrase"] = ""
|
||||
}
|
||||
if neHost.AuthMode == "1" {
|
||||
params["password"] = ""
|
||||
}
|
||||
if neHost.AuthMode == "2" {
|
||||
params["password"] = ""
|
||||
params["private_key"] = ""
|
||||
params["pass_phrase"] = ""
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update ne_host set " + strings.Join(keys, ",") + " where host_id = ?"
|
||||
|
||||
@@ -16,25 +16,26 @@ import (
|
||||
// neListSort 网元列表预设排序
|
||||
var neListSort = []string{
|
||||
"OMC",
|
||||
"MME",
|
||||
"IMS",
|
||||
"AMF",
|
||||
"AUSF",
|
||||
"UDM",
|
||||
"SMF",
|
||||
"PCF",
|
||||
"UPF",
|
||||
"NRF",
|
||||
"NSSF",
|
||||
"IMS",
|
||||
"N3IWF",
|
||||
"NEF",
|
||||
"NRF",
|
||||
"UPF",
|
||||
"LMF",
|
||||
"NEF",
|
||||
"MME",
|
||||
"N3IWF",
|
||||
"MOCNGW",
|
||||
"SMSC",
|
||||
}
|
||||
|
||||
// 实例化数据层 NeInfoImpl 结构体
|
||||
var NewNeInfoImpl = &NeInfoImpl{
|
||||
selectSql: `select id, ne_type, ne_id, rm_uid, ne_name, ip, port, pv_flag, province, vendor_name, dn, ne_address, status, update_time, host_ids from ne_info`,
|
||||
selectSql: `select id, ne_type, ne_id, rm_uid, ne_name, ip, port, pv_flag, province, vendor_name, dn, ne_address, host_ids, status, remark, create_by, create_time, update_by, update_time from ne_info`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"id": "ID",
|
||||
@@ -49,9 +50,13 @@ var NewNeInfoImpl = &NeInfoImpl{
|
||||
"vendor_name": "VendorName",
|
||||
"dn": "Dn",
|
||||
"ne_address": "NeAddress",
|
||||
"status": "Status",
|
||||
"update_time": "UpdateTime",
|
||||
"host_ids": "HostIDs",
|
||||
"status": "Status",
|
||||
"remark": "Remark",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -298,11 +303,19 @@ func (r *NeInfoImpl) Insert(neInfo model.NeInfo) string {
|
||||
if neInfo.NeAddress != "" {
|
||||
params["ne_address"] = neInfo.NeAddress
|
||||
}
|
||||
params["status"] = neInfo.Status
|
||||
params["update_time"] = time.Now()
|
||||
if neInfo.HostIDs != "" {
|
||||
params["host_ids"] = neInfo.HostIDs
|
||||
}
|
||||
if neInfo.Status != "" {
|
||||
params["status"] = neInfo.Status
|
||||
}
|
||||
if neInfo.Remark != "" {
|
||||
params["remark"] = neInfo.Remark
|
||||
}
|
||||
if neInfo.CreateBy != "" {
|
||||
params["create_by"] = neInfo.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
@@ -360,11 +373,17 @@ func (r *NeInfoImpl) Update(neInfo model.NeInfo) int64 {
|
||||
params["vendor_name"] = neInfo.VendorName
|
||||
params["dn"] = neInfo.Dn
|
||||
params["ne_address"] = neInfo.NeAddress
|
||||
params["status"] = neInfo.Status
|
||||
params["update_time"] = time.Now()
|
||||
if neInfo.HostIDs != "" {
|
||||
params["host_ids"] = neInfo.HostIDs
|
||||
}
|
||||
params["remark"] = neInfo.Remark
|
||||
if neInfo.Status != "" {
|
||||
params["status"] = neInfo.Status
|
||||
}
|
||||
if neInfo.UpdateBy != "" {
|
||||
params["update_by"] = neInfo.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
|
||||
@@ -21,7 +21,4 @@ type INeLicense interface {
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(ids []string) int64
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
CheckUniqueTypeAndID(neLicense model.NeLicense) string
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -177,41 +176,6 @@ func (r *NeLicenseImpl) SelectByIds(cmdIds []string) []model.NeLicense {
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
func (r *NeLicenseImpl) CheckUniqueTypeAndID(neLicense model.NeLicense) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if neLicense.NeType != "" {
|
||||
conditions = append(conditions, "ne_type = ?")
|
||||
params = append(params, neLicense.NeType)
|
||||
}
|
||||
if neLicense.NeId != "" {
|
||||
conditions = append(conditions, "ne_id = ?")
|
||||
params = append(params, neLicense.NeId)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select id as 'str' from ne_license " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprint(results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (r *NeLicenseImpl) Insert(neLicense model.NeLicense) string {
|
||||
// 参数拼接
|
||||
|
||||
@@ -61,8 +61,17 @@ func (r *NeSoftwareImpl) SelectPage(query map[string]any) map[string]any {
|
||||
var conditions []string
|
||||
var params []any
|
||||
if v, ok := query["neType"]; ok && v != "" {
|
||||
conditions = append(conditions, "ne_type = ?")
|
||||
params = append(params, strings.Trim(v.(string), " "))
|
||||
softwareType := v.(string)
|
||||
if strings.Contains(softwareType, ",") {
|
||||
softwareTypeArr := strings.Split(softwareType, ",")
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(softwareTypeArr))
|
||||
conditions = append(conditions, "ne_type in ("+placeholder+")")
|
||||
parameters := repo.ConvertIdsSlice(softwareTypeArr)
|
||||
params = append(params, parameters...)
|
||||
} else {
|
||||
conditions = append(conditions, "ne_type = ?")
|
||||
params = append(params, strings.Trim(softwareType, " "))
|
||||
}
|
||||
}
|
||||
if v, ok := query["name"]; ok && v != "" {
|
||||
conditions = append(conditions, "name like concat(?, '%')")
|
||||
|
||||
@@ -21,7 +21,4 @@ type INeVersion interface {
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(ids []string) int64
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
CheckUniqueTypeAndID(neVersion model.NeVersion) string
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -15,17 +14,20 @@ import (
|
||||
// 实例化数据层 NewNeVersion 结构体
|
||||
var NewNeVersionImpl = &NeVersionImpl{
|
||||
selectSql: `select
|
||||
id, ne_type, ne_id, version, path, pre_version, pre_path, new_version, new_path, status, create_by, create_time, update_by, update_time
|
||||
id, ne_type, ne_id, name, version, path, pre_name, pre_version, pre_path, new_name, new_version, new_path, status, create_by, create_time, update_by, update_time
|
||||
from ne_version`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"id": "ID",
|
||||
"ne_type": "NeType",
|
||||
"ne_id": "NeId",
|
||||
"name": "name",
|
||||
"version": "Version",
|
||||
"path": "Path",
|
||||
"pre_name": "preName",
|
||||
"pre_version": "PreVersion",
|
||||
"pre_path": "PrePath",
|
||||
"new_name": "NewName",
|
||||
"new_version": "NewVersion",
|
||||
"new_path": "NewPath",
|
||||
"status": "Status",
|
||||
@@ -76,8 +78,8 @@ func (r *NeVersionImpl) SelectPage(query map[string]any) map[string]any {
|
||||
conditions = append(conditions, "version like concat(?, '%')")
|
||||
params = append(params, strings.Trim(v.(string), " "))
|
||||
}
|
||||
if v, ok := query["filePath"]; ok && v != "" {
|
||||
conditions = append(conditions, "file_path like concat(?, '%')")
|
||||
if v, ok := query["path"]; ok && v != "" {
|
||||
conditions = append(conditions, "path like concat(?, '%')")
|
||||
params = append(params, strings.Trim(v.(string), " "))
|
||||
}
|
||||
|
||||
@@ -108,7 +110,7 @@ func (r *NeVersionImpl) SelectPage(query map[string]any) map[string]any {
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
pageSql := " limit ?,? "
|
||||
pageSql := " order by update_time desc limit ?,? "
|
||||
params = append(params, pageNum*pageSize)
|
||||
params = append(params, pageSize)
|
||||
|
||||
@@ -146,6 +148,10 @@ func (r *NeVersionImpl) SelectList(neVersion model.NeVersion) []model.NeVersion
|
||||
conditions = append(conditions, "path like concat(?, '%')")
|
||||
params = append(params, neVersion.Path)
|
||||
}
|
||||
if neVersion.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, neVersion.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
@@ -178,41 +184,6 @@ func (r *NeVersionImpl) SelectByIds(cmdIds []string) []model.NeVersion {
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
func (r *NeVersionImpl) CheckUniqueTypeAndID(neVersion model.NeVersion) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if neVersion.NeType != "" {
|
||||
conditions = append(conditions, "ne_type = ?")
|
||||
params = append(params, neVersion.NeType)
|
||||
}
|
||||
if neVersion.NeId != "" {
|
||||
conditions = append(conditions, "ne_id = ?")
|
||||
params = append(params, neVersion.NeId)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select id as 'str' from ne_version " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprint(results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (r *NeVersionImpl) Insert(neVersion model.NeVersion) string {
|
||||
// 参数拼接
|
||||
@@ -223,18 +194,27 @@ func (r *NeVersionImpl) Insert(neVersion model.NeVersion) string {
|
||||
if neVersion.NeId != "" {
|
||||
params["ne_id"] = neVersion.NeId
|
||||
}
|
||||
if neVersion.Name != "" {
|
||||
params["name"] = neVersion.Name
|
||||
}
|
||||
if neVersion.Version != "" {
|
||||
params["version"] = neVersion.Version
|
||||
}
|
||||
if neVersion.Path != "" {
|
||||
params["path"] = neVersion.Path
|
||||
}
|
||||
if neVersion.PreName != "" {
|
||||
params["pre_name"] = neVersion.PreName
|
||||
}
|
||||
if neVersion.PreVersion != "" {
|
||||
params["pre_version"] = neVersion.PreVersion
|
||||
}
|
||||
if neVersion.PrePath != "" {
|
||||
params["pre_path"] = neVersion.PrePath
|
||||
}
|
||||
if neVersion.NewName != "" {
|
||||
params["new_name"] = neVersion.NewName
|
||||
}
|
||||
if neVersion.NewVersion != "" {
|
||||
params["new_version"] = neVersion.NewVersion
|
||||
}
|
||||
@@ -286,18 +266,27 @@ func (r *NeVersionImpl) Update(neVersion model.NeVersion) int64 {
|
||||
if neVersion.NeId != "" {
|
||||
params["ne_id"] = neVersion.NeId
|
||||
}
|
||||
if neVersion.Name != "" {
|
||||
params["name"] = neVersion.Name
|
||||
}
|
||||
if neVersion.Version != "" {
|
||||
params["version"] = neVersion.Version
|
||||
}
|
||||
if neVersion.Path != "" {
|
||||
params["path"] = neVersion.Path
|
||||
}
|
||||
if neVersion.PreName != "" {
|
||||
params["pre_name"] = neVersion.PreName
|
||||
}
|
||||
if neVersion.PreVersion != "" {
|
||||
params["pre_version"] = neVersion.PreVersion
|
||||
}
|
||||
if neVersion.PrePath != "" {
|
||||
params["pre_path"] = neVersion.PrePath
|
||||
}
|
||||
if neVersion.NewName != "" {
|
||||
params["new_name"] = neVersion.NewName
|
||||
}
|
||||
if neVersion.NewVersion != "" {
|
||||
params["new_version"] = neVersion.NewVersion
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
func NeState(neInfo model.NeInfo) (map[string]any, error) {
|
||||
// 网元状态
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/systemState", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType))
|
||||
resBytes, err := fetch.Get(neUrl, nil, 250)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 1000)
|
||||
if err != nil {
|
||||
logger.Warnf("NeState %s", err.Error())
|
||||
return nil, err
|
||||
@@ -62,8 +62,8 @@ func NeConfigOMC(neInfo model.NeInfo) (map[string]any, error) {
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
status := err.Error()
|
||||
logger.Warnf("NeConfigOMC %s", status)
|
||||
if strings.HasPrefix(status, "204") {
|
||||
logger.Warnf("NeConfigOMC %s Put \"%s\"", status, neUrl)
|
||||
if strings.HasPrefix(status, "201") || strings.HasPrefix(status, "204") {
|
||||
return resData, nil
|
||||
}
|
||||
return nil, err
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package service
|
||||
|
||||
import "be.ems/src/modules/network_element/model"
|
||||
import (
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// 网元信息 服务层接口
|
||||
type INeInfo interface {
|
||||
@@ -24,7 +27,8 @@ type INeInfo interface {
|
||||
// SelectList 查询列表
|
||||
//
|
||||
// bandStatus 带状态信息
|
||||
SelectList(ne model.NeInfo, bandStatus bool) []model.NeInfo
|
||||
// bandHost 带主机信息
|
||||
SelectList(ne model.NeInfo, bandStatus bool, bandHost bool) []model.NeInfo
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
//
|
||||
@@ -41,14 +45,23 @@ type INeInfo interface {
|
||||
DeleteByIds(infoIds []string) (int64, error)
|
||||
|
||||
// CheckUniqueNeTypeAndNeId 校验同类型下标识是否唯一
|
||||
CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool
|
||||
CheckUniqueNeTypeAndNeId(neType, neId, id string) bool
|
||||
|
||||
// NeRunSSHclient 网元主机的SSH客户端-为创建相关连接
|
||||
NeRunSSHclient(neType, neId string) (*ssh.ConnSSH, error)
|
||||
|
||||
// NeRunCMD 向网元发送cmd命令
|
||||
NeRunCMD(neType, neId, cmd string) (string, error)
|
||||
|
||||
// NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取
|
||||
NeConfigFileRead(neInfo model.NeInfo, filePath string) []string
|
||||
// neConfOAMRead 网元OAM配置文件读取
|
||||
NeConfOAMRead(neType, neId string) (map[string]any, error)
|
||||
|
||||
// NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端
|
||||
NeConfigFileWirte(neInfo model.NeInfo, filePath, content string, sync bool) error
|
||||
// NeConfOAMSync 网元OAM配置文件生成并同步
|
||||
NeConfOAMSync(neInfo model.NeInfo, content map[string]any, sync bool) error
|
||||
|
||||
// NeConfPara5GRead 网元公共配置文件读取
|
||||
NeConfPara5GRead() (map[string]any, error)
|
||||
|
||||
// NeConfPara5GWirte 网元公共配置文件写入 content内容 syncNE同步到网元端NeType@NeId
|
||||
NeConfPara5GWirte(content map[string]any, syncNE []string) error
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/constants/cachekey"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/redis"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
"be.ems/src/modules/network_element/repository"
|
||||
@@ -18,15 +20,14 @@ import (
|
||||
// 实例化服务层 NeInfoImpl 结构体
|
||||
var NewNeInfoImpl = &NeInfoImpl{
|
||||
neInfoRepository: repository.NewNeInfoImpl,
|
||||
neHostRepository: repository.NewNeHostImpl,
|
||||
Para5GData: map[string]string{},
|
||||
}
|
||||
|
||||
// 网元信息 服务层处理
|
||||
type NeInfoImpl struct {
|
||||
// 网元信息数据信息
|
||||
neInfoRepository repository.INeInfo
|
||||
// 网元主机连接表
|
||||
neHostRepository repository.INeHost
|
||||
Para5GData map[string]string
|
||||
}
|
||||
|
||||
// SelectNeInfoByNeTypeAndNeID 通过ne_type和ne_id查询网元信息
|
||||
@@ -94,7 +95,7 @@ func (r *NeInfoImpl) SelectNeInfoByRmuid(rmUid string) model.NeInfo {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
neInfos := r.SelectList(neInfo, false)
|
||||
neInfos := r.SelectList(neInfo, false, false)
|
||||
for _, v := range neInfos {
|
||||
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, strings.ToUpper(v.NeType), v.NeId)
|
||||
redis.Del("", key)
|
||||
@@ -117,37 +118,7 @@ func (r *NeInfoImpl) SelectPage(query map[string]any, bandStatus bool) map[strin
|
||||
// 网元直连读取网元服务状态
|
||||
if bandStatus {
|
||||
rows := data["rows"].([]model.NeInfo)
|
||||
arr := &rows
|
||||
for i := range *arr {
|
||||
v := (*arr)[i]
|
||||
result, err := NeState(v)
|
||||
if err != nil {
|
||||
(*arr)[i].ServerState = map[string]any{
|
||||
"online": false,
|
||||
}
|
||||
// 网元状态设置为离线
|
||||
if v.Status != "1" {
|
||||
v.Status = "1"
|
||||
(*arr)[i].Status = v.Status
|
||||
r.neInfoRepository.Update(v)
|
||||
}
|
||||
continue
|
||||
}
|
||||
result["online"] = true
|
||||
(*arr)[i].ServerState = result
|
||||
// 网元状态设置为在线
|
||||
if v.Status != "0" {
|
||||
// 下发网管配置信息给网元
|
||||
_, err = NeConfigOMC(v)
|
||||
if err != nil {
|
||||
v.Status = "3"
|
||||
} else {
|
||||
v.Status = "0"
|
||||
}
|
||||
(*arr)[i].Status = v.Status
|
||||
r.neInfoRepository.Update(v)
|
||||
}
|
||||
}
|
||||
r.bandNeStatus(&rows)
|
||||
}
|
||||
|
||||
return data
|
||||
@@ -156,50 +127,70 @@ func (r *NeInfoImpl) SelectPage(query map[string]any, bandStatus bool) map[strin
|
||||
// SelectList 查询列表
|
||||
//
|
||||
// bandStatus 带状态信息
|
||||
func (r *NeInfoImpl) SelectList(ne model.NeInfo, bandStatus bool) []model.NeInfo {
|
||||
// bandHost 带主机信息
|
||||
func (r *NeInfoImpl) SelectList(ne model.NeInfo, bandStatus bool, bandHost bool) []model.NeInfo {
|
||||
list := r.neInfoRepository.SelectList(ne)
|
||||
|
||||
// 网元直连读取网元服务状态
|
||||
if bandStatus {
|
||||
neList := &list
|
||||
for i := range *neList {
|
||||
v := (*neList)[i]
|
||||
result, err := NeState(v)
|
||||
if err != nil {
|
||||
(*neList)[i].ServerState = map[string]any{
|
||||
"online": false,
|
||||
}
|
||||
// 网元状态设置为离线
|
||||
if v.Status != "1" {
|
||||
v.Status = "1"
|
||||
(*neList)[i].Status = v.Status
|
||||
r.neInfoRepository.Update(v)
|
||||
}
|
||||
continue
|
||||
}
|
||||
result["online"] = true
|
||||
(*neList)[i].ServerState = result
|
||||
// 网元状态设置为在线
|
||||
if v.Status != "0" {
|
||||
// 下发网管配置信息给网元
|
||||
_, err = NeConfigOMC(v)
|
||||
if err != nil {
|
||||
v.Status = "3"
|
||||
} else {
|
||||
v.Status = "0"
|
||||
}
|
||||
(*neList)[i].Status = v.Status
|
||||
r.neInfoRepository.Update(v)
|
||||
}
|
||||
}
|
||||
r.bandNeStatus(&list)
|
||||
}
|
||||
|
||||
// 网元主机信息
|
||||
if bandHost {
|
||||
r.bandNeHosts(&list)
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// bandNeStatus 网元列表项数据带网元服务状态
|
||||
func (r *NeInfoImpl) bandNeStatus(arr *[]model.NeInfo) {
|
||||
for i := range *arr {
|
||||
v := (*arr)[i]
|
||||
result, err := NeState(v)
|
||||
if err != nil {
|
||||
(*arr)[i].ServerState = map[string]any{
|
||||
"online": false,
|
||||
}
|
||||
// 网元状态设置为离线
|
||||
if v.Status != "0" {
|
||||
v.Status = "0"
|
||||
(*arr)[i].Status = v.Status
|
||||
r.neInfoRepository.Update(v)
|
||||
}
|
||||
continue
|
||||
}
|
||||
result["online"] = true
|
||||
(*arr)[i].ServerState = result
|
||||
// 网元状态设置为在线
|
||||
if v.Status != "1" {
|
||||
// 下发网管配置信息给网元
|
||||
_, err = NeConfigOMC(v)
|
||||
if err == nil {
|
||||
v.Status = "1"
|
||||
} else {
|
||||
v.Status = "2"
|
||||
}
|
||||
(*arr)[i].Status = v.Status
|
||||
r.neInfoRepository.Update(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bandNeHosts 网元列表项数据带网元主机信息
|
||||
func (r *NeInfoImpl) bandNeHosts(arr *[]model.NeInfo) {
|
||||
for i := range *arr {
|
||||
v := (*arr)[i]
|
||||
if v.HostIDs != "" {
|
||||
(*arr)[i].Hosts = NewNeHostImpl.neHostRepository.SelectByIds(strings.Split(v.HostIDs, ","))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
//
|
||||
// bandStatus 带主机信息
|
||||
// bandHost 带主机信息
|
||||
func (r *NeInfoImpl) SelectById(infoId string, bandHost bool) model.NeInfo {
|
||||
if infoId == "" {
|
||||
return model.NeInfo{}
|
||||
@@ -209,7 +200,7 @@ func (r *NeInfoImpl) SelectById(infoId string, bandHost bool) model.NeInfo {
|
||||
neInfo := neInfos[0]
|
||||
// 带主机信息
|
||||
if neInfo.HostIDs != "" && bandHost {
|
||||
neInfo.Hosts = r.neHostRepository.SelectByIds(strings.Split(neInfo.HostIDs, ","))
|
||||
neInfo.Hosts = NewNeHostImpl.neHostRepository.SelectByIds(strings.Split(neInfo.HostIDs, ","))
|
||||
}
|
||||
return neInfo
|
||||
}
|
||||
@@ -224,7 +215,7 @@ func (r *NeInfoImpl) Insert(neInfo model.NeInfo) string {
|
||||
for _, host := range neInfo.Hosts {
|
||||
host.Title = fmt.Sprintf("%s_%s_%d", strings.ToUpper(neInfo.NeType), neInfo.NeId, host.Port)
|
||||
host.GroupID = "1"
|
||||
hostId := r.neHostRepository.Insert(host)
|
||||
hostId := NewNeHostImpl.Insert(host)
|
||||
if hostId != "" {
|
||||
hostIDs = append(hostIDs, hostId)
|
||||
}
|
||||
@@ -248,7 +239,7 @@ func (r *NeInfoImpl) Update(neInfo model.NeInfo) int64 {
|
||||
if host.HostID != "" {
|
||||
host.Title = fmt.Sprintf("%s_%s_%d", strings.ToUpper(neInfo.NeType), neInfo.NeId, host.Port)
|
||||
host.GroupID = "1"
|
||||
r.neHostRepository.Update(host)
|
||||
NewNeHostImpl.Update(host)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,12 +264,20 @@ func (r *NeInfoImpl) DeleteByIds(infoIds []string) (int64, error) {
|
||||
for _, v := range infos {
|
||||
// 主机信息删除
|
||||
if v.HostIDs != "" {
|
||||
hostIds := strings.Split(v.HostIDs, ",")
|
||||
r.neHostRepository.DeleteByIds(hostIds)
|
||||
NewNeHostImpl.DeleteByIds(strings.Split(v.HostIDs, ","))
|
||||
}
|
||||
// 删除License
|
||||
neLicense := NewNeLicenseImpl.SelectByNeTypeAndNeID(v.NeType, v.NeId)
|
||||
if neLicense.NeId == v.NeId {
|
||||
NewNeLicenseImpl.DeleteByIds([]string{neLicense.ID})
|
||||
}
|
||||
// 删除Version
|
||||
neVersion := NewNeVersionImpl.SelectByNeTypeAndNeID(v.NeType, v.NeId)
|
||||
if neVersion.NeId == v.NeId {
|
||||
NewNeVersionImpl.DeleteByIds([]string{neVersion.ID})
|
||||
}
|
||||
// 缓存信息删除
|
||||
key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, v.NeType, v.NeId)
|
||||
redis.Del("", key)
|
||||
redis.Del("", fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, v.NeType, v.NeId))
|
||||
}
|
||||
rows := r.neInfoRepository.DeleteByIds(infoIds)
|
||||
return rows, nil
|
||||
@@ -288,149 +287,456 @@ func (r *NeInfoImpl) DeleteByIds(infoIds []string) (int64, error) {
|
||||
}
|
||||
|
||||
// CheckUniqueNeTypeAndNeId 校验同类型下标识是否唯一
|
||||
func (r *NeInfoImpl) CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool {
|
||||
func (r *NeInfoImpl) CheckUniqueNeTypeAndNeId(neType, neId, id string) bool {
|
||||
uniqueId := r.neInfoRepository.CheckUniqueNeTypeAndNeId(model.NeInfo{
|
||||
NeType: neType,
|
||||
NeId: neId,
|
||||
})
|
||||
if uniqueId == infoId {
|
||||
if uniqueId == id {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// NeRunCMD 向网元发送cmd命令
|
||||
func (r *NeInfoImpl) NeRunCMD(neType, neId, cmd string) (string, error) {
|
||||
// NeRunSSHclient 网元主机的SSH客户端-为创建相关连接
|
||||
func (r *NeInfoImpl) NeRunSSHclient(neType, neId string) (*ssh.ConnSSH, 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")
|
||||
logger.Errorf("NeRunSSHclient NeType:%s NeID:%s not found", neType, neId)
|
||||
return nil, 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")
|
||||
}
|
||||
// 取主机信息
|
||||
if neInfo.HostIDs == "" {
|
||||
logger.Errorf("NeRunSSHclient NeType:%s NeID:%s hostId not found", neType, neId)
|
||||
return nil, fmt.Errorf("neinfo hostId not found")
|
||||
}
|
||||
neInfo.Hosts = NewNeHostImpl.neHostRepository.SelectByIds(strings.Split(neInfo.HostIDs, ","))
|
||||
if len(neInfo.Hosts) <= 0 {
|
||||
logger.Errorf("NeRunSSHclient Hosts %s not found", neInfo.HostIDs)
|
||||
return nil, 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")
|
||||
logger.Errorf("NeRunSSHclient Hosts first HostType %s not ssh", neHost.HostType)
|
||||
return nil, 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")
|
||||
var client *ssh.ConnSSH
|
||||
var err error
|
||||
if neHost.AuthMode == "2" {
|
||||
client, err = connSSH.NewClientByLocalPrivate()
|
||||
} else {
|
||||
client, err = connSSH.NewClient()
|
||||
}
|
||||
defer client.Close()
|
||||
if err != nil {
|
||||
logger.Errorf("NeRunSSHclient NewClient err => %s", err.Error())
|
||||
return nil, fmt.Errorf("neinfo ssh client new err")
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// NeRunCMD 向网元发送cmd命令
|
||||
func (r *NeInfoImpl) NeRunCMD(neType, neId, cmd string) (string, error) {
|
||||
sshClient, err := r.NeRunSSHclient(neType, neId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer sshClient.Close()
|
||||
|
||||
// 执行命令
|
||||
output, err := client.RunCMD(cmd)
|
||||
output, err := sshClient.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)
|
||||
// neConfOAMData 网元OAM配置文件默认格式数据
|
||||
func (r *NeInfoImpl) neConfOAMData() map[string]any {
|
||||
return map[string]any{
|
||||
"httpManageCfg": map[string]any{
|
||||
"ipType": "ipv4",
|
||||
// 必改
|
||||
"ipv4": "172.60.5.2",
|
||||
"ipv6": "",
|
||||
"port": 33030,
|
||||
"scheme": "http",
|
||||
},
|
||||
"oamConfig": map[string]any{
|
||||
"enable": true,
|
||||
"ipType": "ipv4",
|
||||
"ipv4": "172.60.5.1", // 必改
|
||||
"ipv6": "",
|
||||
"port": 33030,
|
||||
"scheme": "http",
|
||||
"neConfig": map[string]any{ // 必改
|
||||
"neId": "001",
|
||||
"rmUid": "4400HX1XXX001",
|
||||
"neName": "XXX_001",
|
||||
"dn": "-",
|
||||
"vendorName": "GD",
|
||||
"province": "-",
|
||||
"pvFlag": "PNF",
|
||||
},
|
||||
},
|
||||
"snmpConfig": map[string]any{
|
||||
"enable": false,
|
||||
"ipType": "ipv4",
|
||||
"ipv4": "172.60.5.2", // 必改
|
||||
"ipv6": "",
|
||||
"port": 4957,
|
||||
},
|
||||
"kpiConfig": map[string]any{
|
||||
"enable": true,
|
||||
"timer": 60, // 必改
|
||||
},
|
||||
// "pubConfigPath": "/usr/local/etc/conf/para5G.yaml", // 网元只会读一次后续会置空,建议不放
|
||||
}
|
||||
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)
|
||||
|
||||
// neConfOAMRead 网元OAM配置文件读取
|
||||
func (r *NeInfoImpl) NeConfOAMRead(neType, neId string) (map[string]any, error) {
|
||||
neTypeLower := strings.ToLower(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)
|
||||
localFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neId, "oam_manager.yaml")
|
||||
|
||||
err := os.WriteFile(localFilePath, []byte(content), 0644)
|
||||
// 读取文件内容
|
||||
bytes, err := os.ReadFile(localFilePath)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfigFile WriteFile => %s", err.Error())
|
||||
// logger.Warnf("NeConfOAMRead ReadFile => %s", err.Error())
|
||||
// return nil, fmt.Errorf("read file error")
|
||||
// 无保留文件时返回默认文件数据
|
||||
oamData := r.neConfOAMData()
|
||||
r.neConfOAMWirte(neType, neId, oamData, false)
|
||||
return oamData, nil
|
||||
}
|
||||
content := string(bytes)
|
||||
|
||||
// 序列化Map
|
||||
mapData, err := parse.ConvertConfigToMap("yaml", content)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfOAMRead ConvertConfigToMap => %s", err.Error())
|
||||
return nil, fmt.Errorf("content convert type error")
|
||||
}
|
||||
return mapData, nil
|
||||
}
|
||||
|
||||
// neConfOAMWirte 网元OAM配置文件写入 content内容 sync同步到网元端
|
||||
func (r *NeInfoImpl) neConfOAMWirte(neType, neId string, content any, sync bool) error {
|
||||
neTypeLower := strings.ToLower(neType)
|
||||
fileName := "oam_manager.yaml"
|
||||
// 网管本地路径
|
||||
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, neId, fileName)
|
||||
|
||||
// 写入文件
|
||||
if err := parse.ConvertConfigToFile("yaml", localFilePath, content); err != nil {
|
||||
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)
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := r.NeRunSSHclient(neType, neId)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfigFile SyncFile => %s", err.Error())
|
||||
return err
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 网元端配置路径
|
||||
neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, fileName)
|
||||
neFileDir := filepath.ToSlash(filepath.Dir(neFilePath))
|
||||
// 修改网元文件权限
|
||||
sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+w %s", neFileDir, neFileDir, neFilePath, neFilePath))
|
||||
// 复制到网元进行覆盖
|
||||
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||
return fmt.Errorf("please check if scp remote copy is allowed")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NeConfOAMSync 网元OAM配置文件生成并同步
|
||||
func (r *NeInfoImpl) NeConfOAMSync(neInfo model.NeInfo, content map[string]any, sync bool) error {
|
||||
oamData, err := r.NeConfOAMRead(neInfo.NeType, neInfo.NeId)
|
||||
if oamData == nil || err != nil {
|
||||
return fmt.Errorf("error read OAM file info")
|
||||
}
|
||||
// 网元HTTP服务
|
||||
if v, ok := oamData["httpManageCfg"]; ok {
|
||||
item := v.(map[string]any)
|
||||
item["port"] = neInfo.Port
|
||||
if strings.Contains(neInfo.IP, ":") {
|
||||
item["ipType"] = "ipv6"
|
||||
item["ipv6"] = neInfo.IP
|
||||
}
|
||||
if strings.Contains(neInfo.IP, ".") {
|
||||
item["ipType"] = "ipv4"
|
||||
item["ipv4"] = neInfo.IP
|
||||
}
|
||||
|
||||
oamData["httpManageCfg"] = item
|
||||
}
|
||||
// 对网管HTTP配置
|
||||
if v, ok := oamData["oamConfig"]; ok {
|
||||
item := v.(map[string]any)
|
||||
item["neConfig"] = map[string]string{
|
||||
"neId": neInfo.NeId,
|
||||
"rmUid": neInfo.RmUID,
|
||||
"neName": neInfo.NeName,
|
||||
"dn": neInfo.Dn,
|
||||
"vendorName": neInfo.VendorName,
|
||||
"province": neInfo.Province,
|
||||
"pvFlag": neInfo.PvFlag,
|
||||
}
|
||||
|
||||
if omcIP, ok := r.Para5GData["OMC_IP"]; ok && omcIP != "" {
|
||||
if strings.Contains(omcIP, ":") {
|
||||
item["ipType"] = "ipv6"
|
||||
item["ipv6"] = omcIP
|
||||
}
|
||||
if strings.Contains(omcIP, ".") {
|
||||
item["ipType"] = "ipv4"
|
||||
item["ipv4"] = omcIP
|
||||
}
|
||||
}
|
||||
|
||||
if oamEnable, ok := content["oamEnable"]; ok && oamEnable != nil {
|
||||
item["enable"] = parse.Boolean(oamEnable)
|
||||
}
|
||||
if oamPort, ok := content["oamPort"]; ok && oamPort != nil {
|
||||
item["port"] = parse.Number(oamPort)
|
||||
}
|
||||
oamData["oamConfig"] = item
|
||||
}
|
||||
// 对网管SNMP配置
|
||||
if v, ok := oamData["snmpConfig"]; ok {
|
||||
item := v.(map[string]any)
|
||||
if strings.Contains(neInfo.IP, ":") {
|
||||
item["ipType"] = "ipv6"
|
||||
item["ipv6"] = neInfo.IP
|
||||
}
|
||||
if strings.Contains(neInfo.IP, ".") {
|
||||
item["ipType"] = "ipv4"
|
||||
item["ipv4"] = neInfo.IP
|
||||
}
|
||||
|
||||
if snmpEnable, ok := content["snmpEnable"]; ok && snmpEnable != nil {
|
||||
item["enable"] = parse.Boolean(snmpEnable)
|
||||
}
|
||||
if snmpPort, ok := content["snmpPort"]; ok && snmpPort != nil {
|
||||
item["port"] = parse.Number(snmpPort)
|
||||
}
|
||||
oamData["snmpConfig"] = item
|
||||
}
|
||||
// 对网管KPI上报配置
|
||||
if v, ok := oamData["kpiConfig"]; ok {
|
||||
item := v.(map[string]any)
|
||||
if neInfo.NeType == "UPF" {
|
||||
item["timer"] = 5
|
||||
}
|
||||
|
||||
if kpiEnable, ok := content["kpiEnable"]; ok && kpiEnable != nil {
|
||||
item["enable"] = parse.Boolean(kpiEnable)
|
||||
}
|
||||
if kpiTimer, ok := content["kpiTimer"]; ok && kpiTimer != nil {
|
||||
item["timer"] = parse.Number(kpiTimer)
|
||||
}
|
||||
oamData["kpiConfig"] = item
|
||||
}
|
||||
if err := NewNeInfoImpl.neConfOAMWirte(neInfo.NeType, neInfo.NeId, oamData, sync); err != nil {
|
||||
return fmt.Errorf("error wirte OAM file info")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NeConfPara5GRead 网元公共配置文件读取
|
||||
func (r *NeInfoImpl) NeConfPara5GRead() (map[string]any, error) {
|
||||
// 网管本地路径
|
||||
omcFilePath := "/usr/local/etc/omc/para5G.yaml"
|
||||
if runtime.GOOS == "windows" {
|
||||
omcFilePath = fmt.Sprintf("C:%s", omcFilePath)
|
||||
}
|
||||
// 读取文件内容
|
||||
bytes, err := os.ReadFile(omcFilePath)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfPara5GRead ReadFile => %s", err.Error())
|
||||
return nil, fmt.Errorf("read file error")
|
||||
}
|
||||
content := string(bytes)
|
||||
|
||||
// 序列化Map
|
||||
mapData, err := parse.ConvertConfigToMap("yaml", content)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfPara5GRead ConvertConfigToMap => %s", err.Error())
|
||||
return nil, fmt.Errorf("content convert type error")
|
||||
}
|
||||
return mapData, nil
|
||||
}
|
||||
|
||||
// NeConfPara5GWirte 网元公共配置文件写入 content内容 syncNE同步到网元端NeType@NeId
|
||||
func (r *NeInfoImpl) NeConfPara5GWirte(content map[string]any, syncNE []string) error {
|
||||
// 网管本地路径
|
||||
omcFilePath := "/usr/local/etc/omc/para5G.yaml"
|
||||
if runtime.GOOS == "windows" {
|
||||
omcFilePath = fmt.Sprintf("C:%s", omcFilePath)
|
||||
}
|
||||
|
||||
if err := parse.ConvertConfigToFile("yaml", omcFilePath, content); err != nil {
|
||||
return fmt.Errorf("please check if the file exists or write permissions")
|
||||
}
|
||||
|
||||
// 同步到网元端
|
||||
if len(syncNE) > 0 {
|
||||
errMsg := []string{}
|
||||
for _, neTI := range syncNE {
|
||||
ti := strings.SplitN(neTI, "@", 2)
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := r.NeRunSSHclient(ti[0], ti[1])
|
||||
if err != nil {
|
||||
errMsg = append(errMsg, fmt.Sprintf("%s : %s", ti, err.Error()))
|
||||
continue
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
errMsg = append(errMsg, fmt.Sprintf("%s : %s", ti, err.Error()))
|
||||
continue
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 网元端配置路径
|
||||
neFilePath := "/usr/local/etc/conf/para5G.yaml"
|
||||
neFileDir := filepath.ToSlash(filepath.Dir(neFilePath))
|
||||
// 修改网元文件权限
|
||||
sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+rw %s", neFileDir, neFileDir, neFilePath, neFilePath))
|
||||
// 复制到网元进行覆盖
|
||||
if err = sftpClient.CopyFileLocalToRemote(omcFilePath, neFilePath); err != nil {
|
||||
errMsg = append(errMsg, fmt.Sprintf("%s : please check if scp remote copy is allowed", ti))
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(errMsg) > 0 {
|
||||
return fmt.Errorf(strings.Join(errMsg, "\r\n"))
|
||||
}
|
||||
}
|
||||
|
||||
// 转换一份数据到全局
|
||||
r.Para5GData = r.neConfPara5GDataConvert(content)
|
||||
return nil
|
||||
}
|
||||
|
||||
// NeConfPara5GConvert 网元公共配置数据转化 content网元公共配置文件读取内容
|
||||
func (r *NeInfoImpl) neConfPara5GDataConvert(content map[string]any) map[string]string {
|
||||
basic := content["basic"].(map[string]any)
|
||||
external := content["external"].(map[string]any)
|
||||
sbi := content["sbi"].(map[string]any)
|
||||
|
||||
mcc := "460"
|
||||
mnc := "01"
|
||||
mncDomain := "001"
|
||||
if plmnId, plmnIdOk := basic["plmnId"].(map[string]any); plmnIdOk {
|
||||
mcc = plmnId["mcc"].(string)
|
||||
mnc = plmnId["mnc"].(string)
|
||||
// If a user input two digit MNC, add a leading zero
|
||||
if len(mnc) == 2 {
|
||||
mncDomain = fmt.Sprintf("0%s", mnc)
|
||||
} else {
|
||||
mncDomain = mnc
|
||||
}
|
||||
}
|
||||
|
||||
sst := "1"
|
||||
sd := "000001"
|
||||
if plmnId, plmnIdOk := basic["snssai"].(map[string]any); plmnIdOk {
|
||||
sst = plmnId["sst"].(string)
|
||||
sd = plmnId["sd"].(string)
|
||||
}
|
||||
|
||||
n3IPAmdMask := external["upfn3_ip"].(string)
|
||||
n3Arr := strings.Split(n3IPAmdMask, "/")
|
||||
n3IP := n3Arr[0]
|
||||
n3Mask := parse.ConvertIPMask(parse.Number(n3Arr[1]))
|
||||
|
||||
n6IPAmdMask := external["upfn6_ip"].(string)
|
||||
n6Arr := strings.Split(n6IPAmdMask, "/")
|
||||
n6IP := n6Arr[0]
|
||||
n6Mask := parse.ConvertIPMask(parse.Number(n6Arr[1]))
|
||||
|
||||
ueIPAmdMask := external["ue_pool"].(string)
|
||||
ueArr := strings.Split(ueIPAmdMask, "/")
|
||||
ueIP := ueArr[0]
|
||||
ueCicr := ueArr[1]
|
||||
ueMask := parse.ConvertIPMask(parse.Number(ueArr[1]))
|
||||
|
||||
return map[string]string{
|
||||
// basic
|
||||
"TAC": basic["tac"].(string),
|
||||
"MCC": mcc,
|
||||
"MNC": mnc,
|
||||
"MNC_DOMAIN": mncDomain,
|
||||
"SST": sst,
|
||||
"SD": sd,
|
||||
"DNN_DATA": basic["dnn_data"].(string),
|
||||
"DNN_IMS": basic["dnn_ims"].(string),
|
||||
|
||||
// external
|
||||
"N2_IP": external["amfn2_ip"].(string),
|
||||
"UE_POOL": external["ue_pool"].(string),
|
||||
"UE_IP": ueIP,
|
||||
"UE_MASK": ueMask,
|
||||
"UE_CIDR": ueCicr,
|
||||
"UPF_TYPE": external["upf_type"].(string), // StandardUPF LightUPF
|
||||
"N3_IP": n3IP,
|
||||
"N3_MASK": n3Mask,
|
||||
"N3_GW": external["upfn3_gw"].(string),
|
||||
"N3_PCI": external["upfn3_pci"].(string),
|
||||
"N3_MAC": external["upfn3_mac"].(string),
|
||||
"N6_IP": n6IP,
|
||||
"N6_MASK": n6Mask,
|
||||
"N6_GW": external["upfn6_gw"].(string),
|
||||
"N6_PCI": external["upfn6_pci"].(string),
|
||||
"N6_MAC": external["upfn6_mac"].(string),
|
||||
|
||||
"SIP_IP": external["ims_sip_ip"].(string),
|
||||
|
||||
"S1_MMEIP": external["mmes1_ip"].(string),
|
||||
"S11_MMEIP": external["mmes11_ip"].(string),
|
||||
"S10_MMEIP": external["mmes10_ip"].(string),
|
||||
|
||||
// sbi
|
||||
"OMC_IP": sbi["omc_ip"].(string),
|
||||
"IMS_IP": sbi["ims_ip"].(string),
|
||||
"AMF_IP": sbi["amf_ip"].(string),
|
||||
"AUSF_IP": sbi["ausf_ip"].(string),
|
||||
"UDM_IP": sbi["udm_ip"].(string),
|
||||
"ADB_IP": sbi["adb_ip"].(string),
|
||||
"SMF_IP": sbi["smf_ip"].(string),
|
||||
"PCF_IP": sbi["pcf_ip"].(string),
|
||||
"NSSF_IP": sbi["nssf_ip"].(string),
|
||||
"NRF_IP": sbi["nrf_ip"].(string),
|
||||
"UPF_IP": sbi["upf_ip"].(string),
|
||||
"LMF_IP": sbi["lmf_ip"].(string),
|
||||
"NEF_IP": sbi["nef_ip"].(string),
|
||||
"MME_IP": sbi["mme_ip"].(string),
|
||||
"N3IWF_IP": sbi["n3iwf_ip"].(string),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,16 +22,13 @@ type INeLicense interface {
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(ids []string) (int64, error)
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
CheckUniqueTypeAndID(neType, neId, id string) bool
|
||||
|
||||
// SelectByNeTypeAndNeID 通过ne_type和ne_id查询信息
|
||||
SelectByNeTypeAndNeID(neType, neId string) model.NeLicense
|
||||
|
||||
// ReadLicenseInfo 读取授权文件信息
|
||||
// 激活申请码, 激活文件
|
||||
ReadLicenseInfo(neInfo model.NeInfo) (string, string)
|
||||
// 返回激活申请码, 激活文件
|
||||
ReadLicenseInfo(neLicense model.NeLicense) (string, string)
|
||||
|
||||
// UploadToNeHost 授权文件上传到网元主机
|
||||
UploadToNeHost(neLicense model.NeLicense) error
|
||||
// UploadLicense 授权文件上传到网元主机
|
||||
UploadLicense(neLicense model.NeLicense) error
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package service
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
"be.ems/src/modules/network_element/repository"
|
||||
)
|
||||
@@ -84,18 +84,6 @@ func (r *NeLicenseImpl) SelectByTypeAndID(neType, neId string) model.NeLicense {
|
||||
return model.NeLicense{}
|
||||
}
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
func (r *NeLicenseImpl) CheckUniqueTypeAndID(neType, neId, id string) bool {
|
||||
uniqueId := r.neLicenseRepository.CheckUniqueTypeAndID(model.NeLicense{
|
||||
NeType: neType,
|
||||
NeId: neId,
|
||||
})
|
||||
if uniqueId == id {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// SelectByNeTypeAndNeID 通过ne_type和ne_id查询信息
|
||||
func (r *NeLicenseImpl) SelectByNeTypeAndNeID(neType, neId string) model.NeLicense {
|
||||
neLicenses := r.neLicenseRepository.SelectList(model.NeLicense{
|
||||
@@ -109,75 +97,95 @@ func (r *NeLicenseImpl) SelectByNeTypeAndNeID(neType, neId string) model.NeLicen
|
||||
}
|
||||
|
||||
// ReadLicenseInfo 读取授权文件信息
|
||||
// 激活申请码, 激活文件
|
||||
func (r *NeLicenseImpl) ReadLicenseInfo(neInfo model.NeInfo) (string, string) {
|
||||
neTypeLower := strings.ToLower(neInfo.NeType)
|
||||
// 返回激活申请码, 激活文件
|
||||
func (r *NeLicenseImpl) ReadLicenseInfo(neLicense model.NeLicense) (string, string) {
|
||||
neTypeLower := strings.ToLower(neLicense.NeType)
|
||||
// 网管本地路径
|
||||
omcPath := "/usr/local/etc/omc/ne_license"
|
||||
if runtime.GOOS == "windows" {
|
||||
omcPath = fmt.Sprintf("C:%s", omcPath)
|
||||
}
|
||||
omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neInfo.NeId)
|
||||
omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neLicense.NeId)
|
||||
// 网元端授权文件路径
|
||||
nePath := fmt.Sprintf("/usr/local/etc/%s/license", neTypeLower)
|
||||
|
||||
// 复制授权申请码到本地
|
||||
err := ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/Activation_request_code.txt", omcPath+"/Activation_request_code.txt")
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := NewNeInfoImpl.NeRunSSHclient(neLicense.NeType, neLicense.NeId)
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 复制授权申请码到本地
|
||||
if err = sftpClient.CopyFileRemoteToLocal(nePath+"/Activation_request_code.txt", omcPath+"/Activation_request_code.txt"); err != nil {
|
||||
return "", ""
|
||||
}
|
||||
// 读取文件内容
|
||||
bytes, err := os.ReadFile(omcPath + "/Activation_request_code.txt")
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// 激活文件
|
||||
// 复制激活文件到本地
|
||||
licensePath := ""
|
||||
if err = ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/system.ini", omcPath+"/system.ini"); err == nil {
|
||||
if err = sftpClient.CopyFileRemoteToLocal(nePath+"/system.ini", omcPath+"/system.ini"); err == nil {
|
||||
licensePath = omcPath + "/system.ini"
|
||||
}
|
||||
return strings.TrimSpace(string(bytes)), licensePath
|
||||
}
|
||||
|
||||
// UploadToNeHost 授权文件上传到网元主机
|
||||
func (r *NeLicenseImpl) UploadToNeHost(neLicense model.NeLicense) error {
|
||||
|
||||
// UploadLicense 授权文件上传到网元主机
|
||||
func (r *NeLicenseImpl) UploadLicense(neLicense model.NeLicense) error {
|
||||
// 检查文件是否存在
|
||||
omcLicensePath := file.ParseUploadFilePath(neLicense.LicensePath)
|
||||
if _, err := os.Stat(omcLicensePath); err != nil {
|
||||
return fmt.Errorf("file read failure")
|
||||
}
|
||||
|
||||
// 检查网元主机
|
||||
neHostInfo := NewNeHostImpl.SelectById(neLicense.HostId)
|
||||
if neHostInfo.HostType != "ssh" || neHostInfo.HostID != neLicense.HostId {
|
||||
return fmt.Errorf("no found host info")
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := NewNeInfoImpl.NeRunSSHclient(neLicense.NeType, neLicense.NeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 网元端授权文件路径
|
||||
neTypeLower := strings.ToLower(neLicense.NeType)
|
||||
neLicensePath := fmt.Sprintf("/usr/local/etc/%s/license", neTypeLower)
|
||||
// 修改文件夹权限
|
||||
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo chmod o+w %s/", neLicensePath))
|
||||
neLicensePath := fmt.Sprintf("/usr/local/etc/%s/license/system.ini", neTypeLower)
|
||||
neLicenseDir := filepath.ToSlash(filepath.Dir(neLicensePath))
|
||||
// 修改网元文件权限
|
||||
sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+rw %s", neLicenseDir, neLicenseDir, neLicensePath, neLicensePath))
|
||||
|
||||
// 尝试备份授权文件
|
||||
neLicensePathBack := fmt.Sprintf("%s/system_%s.ini", neLicensePath, time.Now().Format("20060102_150405"))
|
||||
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo cp -rf %s/system.ini %s", neLicensePath, neLicensePathBack))
|
||||
sshClient.RunCMD(fmt.Sprintf("sudo cp -rf %s/system.ini %s", neLicensePath, neLicensePathBack))
|
||||
|
||||
// 上传授权文件去覆盖
|
||||
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo chmod o+w %s/system.ini", neLicensePath))
|
||||
if err := ssh.FileSCPLocalToNe(neHostInfo.Addr, omcLicensePath, neLicensePath+"/system.ini"); err != nil {
|
||||
return fmt.Errorf("error uploading license")
|
||||
if err := sftpClient.CopyFileLocalToRemote(omcLicensePath, neLicensePath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 重启服务
|
||||
if neLicense.Reload {
|
||||
cmdStr := fmt.Sprintf("sudo service %s restart", neTypeLower)
|
||||
if neTypeLower == "ims" {
|
||||
cmdStr = "sudo ims-stop && sudo ims-start"
|
||||
cmdStr = "sudo ims-stop || true && sudo ims-start"
|
||||
} else if neTypeLower == "omc" {
|
||||
cmdStr = "sudo /usr/local/omc/bin/omcsvc.sh restart"
|
||||
}
|
||||
NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, cmdStr)
|
||||
sshClient.RunCMD(cmdStr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ type INeSoftware interface {
|
||||
// CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一
|
||||
CheckUniqueTypeAndNameAndVersion(neType, name, version, id string) bool
|
||||
|
||||
// UploadToNeHost 安装包上传到网元主机
|
||||
// 返回执行命令步骤
|
||||
UploadToNeHost(neSoftware model.NeSoftware) ([]string, error)
|
||||
// UpdateVersions 更新软件包对应网元的新版本
|
||||
UpdateVersions(neSoftware model.NeSoftware, neVersion model.NeVersion) int64
|
||||
}
|
||||
|
||||
@@ -3,11 +3,8 @@ package service
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
"be.ems/src/modules/network_element/repository"
|
||||
)
|
||||
@@ -47,26 +44,69 @@ func (r *NeSoftwareImpl) SelectById(id string) model.NeSoftware {
|
||||
|
||||
// Insert 新增信息
|
||||
func (r *NeSoftwareImpl) Insert(neSoftware model.NeSoftware) string {
|
||||
return r.neSoftwareRepository.Insert(neSoftware)
|
||||
inserId := r.neSoftwareRepository.Insert(neSoftware)
|
||||
if inserId != "" {
|
||||
// 更新同类型的新包版本
|
||||
neVersions := NewNeVersionImpl.SelectList(model.NeVersion{NeType: neSoftware.NeType})
|
||||
if len(neVersions) > 0 {
|
||||
for _, neVersion := range neVersions {
|
||||
neVersion.NewName = neSoftware.Name
|
||||
neVersion.NewVersion = neSoftware.Version
|
||||
neVersion.NewPath = neSoftware.Path
|
||||
neVersion.Status = "3"
|
||||
neVersion.UpdateBy = neSoftware.CreateBy
|
||||
NewNeVersionImpl.Update(neVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
return inserId
|
||||
}
|
||||
|
||||
// Update 修改信息
|
||||
func (r *NeSoftwareImpl) Update(neSoftware model.NeSoftware) int64 {
|
||||
return r.neSoftwareRepository.Update(neSoftware)
|
||||
rows := r.neSoftwareRepository.Update(neSoftware)
|
||||
if rows > 0 {
|
||||
// 更新同类型的新包版本
|
||||
neVersions := NewNeVersionImpl.SelectList(model.NeVersion{
|
||||
NeType: neSoftware.NeType,
|
||||
Status: "3",
|
||||
})
|
||||
if len(neVersions) > 0 {
|
||||
for _, neVersion := range neVersions {
|
||||
neVersion.NewName = neSoftware.Name
|
||||
neVersion.NewVersion = neSoftware.Version
|
||||
neVersion.NewPath = neSoftware.Path
|
||||
neVersion.Status = "3"
|
||||
neVersion.UpdateBy = neSoftware.UpdateBy
|
||||
NewNeVersionImpl.Update(neVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *NeSoftwareImpl) DeleteByIds(ids []string) (int64, error) {
|
||||
// 检查是否存在
|
||||
rowIds := r.neSoftwareRepository.SelectByIds(ids)
|
||||
if len(rowIds) <= 0 {
|
||||
rows := r.neSoftwareRepository.SelectByIds(ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("neSoftware.noData")
|
||||
}
|
||||
|
||||
if len(rowIds) == len(ids) {
|
||||
if len(rows) == len(ids) {
|
||||
// 遍历软件包列表进行文件删除
|
||||
for _, row := range rows {
|
||||
// 检查文件是否存在
|
||||
filePath := file.ParseUploadFilePath(row.Path)
|
||||
if _, err := os.Stat(filePath); err != nil {
|
||||
continue
|
||||
}
|
||||
os.Remove(filePath)
|
||||
}
|
||||
rows := r.neSoftwareRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
@@ -84,54 +124,20 @@ func (r *NeSoftwareImpl) CheckUniqueTypeAndNameAndVersion(neType, name, version,
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// UploadToNeHost 安装包上传到网元主机
|
||||
// 返回执行命令步骤
|
||||
func (r *NeSoftwareImpl) UploadToNeHost(neSoftware model.NeSoftware) ([]string, error) {
|
||||
cmdStrArr := []string{}
|
||||
// 检查文件是否存在
|
||||
filePath := file.ParseUploadFilePath(neSoftware.Path)
|
||||
if _, err := os.Stat(filePath); err != nil {
|
||||
return cmdStrArr, fmt.Errorf("file read failure")
|
||||
// UpdateVersions 更新软件包对应网元的新版本
|
||||
func (r *NeSoftwareImpl) UpdateVersions(neSoftware model.NeSoftware, neVersion model.NeVersion) int64 {
|
||||
var rows int64 = 0
|
||||
// 更新同类型的新包版本
|
||||
neVersions := NewNeVersionImpl.SelectList(neVersion)
|
||||
if len(neVersions) > 0 {
|
||||
for _, v := range neVersions {
|
||||
v.NewName = neSoftware.Name
|
||||
v.NewVersion = neSoftware.Version
|
||||
v.NewPath = neSoftware.Path
|
||||
v.Status = "3"
|
||||
v.UpdateBy = neVersion.UpdateBy
|
||||
rows += NewNeVersionImpl.Update(v)
|
||||
}
|
||||
}
|
||||
fileName := filepath.Base(neSoftware.Path)
|
||||
if strings.Contains(fileName, "*") {
|
||||
fileName = strings.ReplaceAll(fileName, "*", "_")
|
||||
}
|
||||
nePath := "/tmp"
|
||||
neFilePath := fmt.Sprintf("%s/%s", nePath, fileName)
|
||||
|
||||
// 检查网元主机
|
||||
neHostInfo := NewNeHostImpl.SelectById(neSoftware.HostId)
|
||||
if neHostInfo.HostType != "ssh" || neHostInfo.HostID != neSoftware.HostId {
|
||||
return cmdStrArr, fmt.Errorf("no found host info")
|
||||
}
|
||||
|
||||
// 上传软件包到 /tmp
|
||||
if err := ssh.FileSCPLocalToNe(neHostInfo.Addr, filePath, neFilePath); err != nil {
|
||||
return cmdStrArr, fmt.Errorf("error uploading package")
|
||||
}
|
||||
|
||||
// 安装软件包
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo dpkg -i %s", neFilePath))
|
||||
|
||||
if neSoftware.NeType == "IMS" {
|
||||
// 公网 PLMN地址
|
||||
cmdStrArr = append(cmdStrArr, "sudo /usr/local/etc/ims/default/tools/modipplmn.sh {PUBIP} {MCC} {MNC}")
|
||||
// 内网 服务地址
|
||||
cmdStrArr = append(cmdStrArr, "sudo /usr/local/etc/ims/default/tools/modintraip.sh {PRIIP}")
|
||||
// 10s后停止服务
|
||||
cmdStrArr = append(cmdStrArr, "sudo ims-start")
|
||||
cmdStrArr = append(cmdStrArr, `nohup sh -c "sleep 10s && sudo ims-stop" > /dev/null 2>&1 &`)
|
||||
} else {
|
||||
// 10s后停止服务
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo service %s restart", strings.ToLower(neSoftware.NeType)))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf(`nohup sh -c "sleep 10s && sudo service %s stop" > /dev/null 2>&1 &`, strings.ToLower(neSoftware.NeType)))
|
||||
}
|
||||
|
||||
// 删除软件包
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo rm %s", neFilePath))
|
||||
|
||||
// 结束
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("echo '%s software install successful!'", neSoftware.NeType))
|
||||
return cmdStrArr, nil
|
||||
return rows
|
||||
}
|
||||
|
||||
@@ -22,9 +22,11 @@ type INeVersion interface {
|
||||
// DeleteByIds 批量删除信息
|
||||
DeleteByIds(ids []string) (int64, error)
|
||||
|
||||
// SelectByTypeAndID 通过网元类型和网元ID查询
|
||||
SelectByTypeAndID(neType, neId string) model.NeVersion
|
||||
// SelectByNeTypeAndNeID 通过网元类型和网元ID查询
|
||||
SelectByNeTypeAndNeID(neType, neId string) model.NeVersion
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
CheckUniqueTypeAndID(neType, neId, id string) bool
|
||||
// Operate 操作版本上传到网元主机执行命令
|
||||
//
|
||||
// action 安装行为:install upgrade rollback
|
||||
Operate(action string, neVersion model.NeVersion, preinput map[string]string) (string, error)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,13 @@ package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/ssh"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
"be.ems/src/modules/network_element/repository"
|
||||
)
|
||||
@@ -66,8 +72,8 @@ func (r *NeVersionImpl) DeleteByIds(ids []string) (int64, error) {
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// SelectByTypeAndID 通过网元类型和网元ID查询
|
||||
func (r *NeVersionImpl) SelectByTypeAndID(neType, neId string) model.NeVersion {
|
||||
// SelectByNeTypeAndNeID 通过网元类型和网元ID查询
|
||||
func (r *NeVersionImpl) SelectByNeTypeAndNeID(neType, neId string) model.NeVersion {
|
||||
neVersions := r.neVersionRepository.SelectList(model.NeVersion{
|
||||
NeType: neType,
|
||||
NeId: neId,
|
||||
@@ -78,14 +84,539 @@ func (r *NeVersionImpl) SelectByTypeAndID(neType, neId string) model.NeVersion {
|
||||
return model.NeVersion{}
|
||||
}
|
||||
|
||||
// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一
|
||||
func (r *NeVersionImpl) CheckUniqueTypeAndID(neType, neId, id string) bool {
|
||||
uniqueId := r.neVersionRepository.CheckUniqueTypeAndID(model.NeVersion{
|
||||
NeType: neType,
|
||||
NeId: neId,
|
||||
})
|
||||
if uniqueId == id {
|
||||
return true
|
||||
// Operate 操作版本上传到网元主机执行命令
|
||||
//
|
||||
// action 安装行为:install upgrade rollback
|
||||
func (r *NeVersionImpl) Operate(action string, neVersion model.NeVersion, preinput map[string]string) (string, error) {
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := NewNeInfoImpl.NeRunSSHclient(neVersion.NeType, neVersion.NeId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return uniqueId == ""
|
||||
defer sshClient.Close()
|
||||
|
||||
// ========= 文件传输阶段 =========
|
||||
softwarePath := neVersion.Path
|
||||
if action == "install" || action == "upgrade" {
|
||||
softwarePath = neVersion.NewPath
|
||||
}
|
||||
if action == "rollback" {
|
||||
softwarePath = neVersion.PrePath
|
||||
}
|
||||
neFilePaths, err := r.operateFile(sshClient, softwarePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// ========= 安装时设置 =========
|
||||
if action == "install" {
|
||||
// 网元公共配置文件
|
||||
para5GMap, err := NewNeInfoImpl.NeConfPara5GRead()
|
||||
if para5GMap == nil || err != nil {
|
||||
return "", fmt.Errorf("error read para5G file info")
|
||||
}
|
||||
if err := NewNeInfoImpl.NeConfPara5GWirte(para5GMap, []string{fmt.Sprintf("%s@%s", neVersion.NeType, neVersion.NeId)}); err != nil {
|
||||
return "", fmt.Errorf("error wirte para5G file info")
|
||||
}
|
||||
}
|
||||
|
||||
// ========= 命令生成阶段 =========
|
||||
okFlagStr, cmdStrArr, err := r.operateCommand(action, neVersion.NeType, neFilePaths)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// 操作自己omc时
|
||||
if neVersion.NeType == "OMC" {
|
||||
return sshClient.RunCMD(fmt.Sprintf("nohup sh -c \"sleep 3s && %s\" > /dev/null 2>&1 & \n", strings.Join(cmdStrArr, " && ")))
|
||||
}
|
||||
|
||||
// ========= 执行阶段 =========
|
||||
commandLine, err := r.operateRun(sshClient, preinput, cmdStrArr, neVersion.NeType, okFlagStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// ========= 完成阶段 =========
|
||||
if strings.LastIndex(commandLine, okFlagStr) > 5 {
|
||||
if err := r.operateDome(action, neVersion); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return commandLine, nil
|
||||
}
|
||||
|
||||
// operateDome 操作版本-文件传输阶段
|
||||
func (r *NeVersionImpl) operateFile(sshClient *ssh.ConnSSH, softwarePath string) ([]string, error) {
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
nePath := "/tmp"
|
||||
copyFileToNeMap := map[string]string{}
|
||||
|
||||
// 统一处理多个文件和单个文件的情况
|
||||
var softwarePaths []string
|
||||
if strings.Contains(softwarePath, ",") {
|
||||
softwarePaths = strings.Split(softwarePath, ",")
|
||||
} else {
|
||||
softwarePaths = []string{softwarePath}
|
||||
}
|
||||
|
||||
for _, path := range softwarePaths {
|
||||
// 检查文件是否存在
|
||||
localFilePath := file.ParseUploadFilePath(path)
|
||||
if _, err := os.Stat(localFilePath); err != nil {
|
||||
return nil, fmt.Errorf("file read failure")
|
||||
}
|
||||
|
||||
fileName := filepath.Base(path)
|
||||
neFilePath := fmt.Sprintf("%s/%s", nePath, fileName)
|
||||
copyFileToNeMap[localFilePath] = neFilePath
|
||||
}
|
||||
|
||||
// 上传软件包到 /tmp
|
||||
neFilePaths := []string{}
|
||||
for k, v := range copyFileToNeMap {
|
||||
if err = sftpClient.CopyFileLocalToRemote(k, v); err != nil {
|
||||
return nil, fmt.Errorf("error uploading package")
|
||||
}
|
||||
neFilePaths = append(neFilePaths, v)
|
||||
}
|
||||
return neFilePaths, nil
|
||||
}
|
||||
|
||||
// operateDome 操作版本-命令生成阶段
|
||||
func (r *NeVersionImpl) operateCommand(action, neType string, neFilePaths []string) (string, []string, error) {
|
||||
neTypeLower := strings.ToLower(neType)
|
||||
// 命令终止结束标记
|
||||
okFlagStr := fmt.Sprintf("%s version %s successful!", neTypeLower, action)
|
||||
// 安装软件包
|
||||
pkgCmdStr := fmt.Sprintf("sudo dpkg -i %s", strings.Join(neFilePaths, " "))
|
||||
fileExt := filepath.Ext(strings.ToLower(neFilePaths[0]))
|
||||
if strings.HasSuffix(fileExt, "rpm") {
|
||||
pkgCmdStr = fmt.Sprintf("sudo rpm -Uvh %s", strings.Join(neFilePaths, " "))
|
||||
}
|
||||
|
||||
// 组合命令输入
|
||||
cmdStrArr := []string{}
|
||||
if neType == "OMC" {
|
||||
cmdStrArr = append(cmdStrArr, pkgCmdStr)
|
||||
if action == "install" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo /usr/local/omc/bin/setomc.sh -m install") // 初始化数据库
|
||||
} else {
|
||||
cmdStrArr = append(cmdStrArr, "sudo /usr/local/omc/bin/omcsvc.sh stop")
|
||||
cmdStrArr = append(cmdStrArr, "sudo /usr/local/omc/bin/setomc.sh -m upgrade") // 升级数据库
|
||||
}
|
||||
cmdStrArr = append(cmdStrArr, "sudo /usr/local/omc/bin/omcsvc.sh restart")
|
||||
} else if neType == "IMS" {
|
||||
if action == "install" {
|
||||
para5GData := NewNeInfoImpl.Para5GData
|
||||
cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n")
|
||||
|
||||
// 公网 PLMN地址
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo /usr/local/etc/ims/default/tools/modipplmn.sh %s %s %s \n", para5GData["SIP_IP"], para5GData["MCC"], para5GData["MNC"]))
|
||||
// 内网 服务地址
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo /usr/local/etc/ims/default/tools/modintraip.sh %s \n", para5GData["IMS_IP"]))
|
||||
// IWF连接PCF服务
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.160/%s/g\" /usr/local/etc/iwf/iwf_conf.yaml \n", para5GData["PCF_IP"]))
|
||||
// 设置 HOST
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s ims' /etc/hosts || echo '%s ims' | sudo tee -a /etc/hosts \n", para5GData["IMS_IP"], para5GData["IMS_IP"]))
|
||||
mnc_mcc := fmt.Sprintf("mnc%s.mcc%s", para5GData["MNC_DOMAIN"], para5GData["MCC"])
|
||||
hssHost := fmt.Sprintf("%s hss.ims.%s.3gppnetwork.org hss", para5GData["UDM_IP"], mnc_mcc)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", hssHost, hssHost))
|
||||
pcrfHost := fmt.Sprintf("%s pcrf.epc.%s.3gppnetwork.org pcrf", para5GData["IMS_IP"], mnc_mcc)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", pcrfHost, pcrfHost))
|
||||
imsOrgHost := fmt.Sprintf("ims.%s.3gppnetwork.org", mnc_mcc)
|
||||
imsHost := fmt.Sprintf("%s %s ims", para5GData["SIP_IP"], imsOrgHost)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", imsHost, imsHost))
|
||||
pcscfHost := fmt.Sprintf("%s pcscf.%s pcscf", para5GData["SIP_IP"], imsOrgHost)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", pcscfHost, pcscfHost))
|
||||
icscfHost := fmt.Sprintf("%s icscf.%s icscf", para5GData["SIP_IP"], imsOrgHost)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", icscfHost, icscfHost))
|
||||
scscfHost := fmt.Sprintf("%s scscf.%s scscf", para5GData["SIP_IP"], imsOrgHost)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", scscfHost, scscfHost))
|
||||
mmtelHost := fmt.Sprintf("%s mmtel.%s mmtel", para5GData["SIP_IP"], imsOrgHost)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", mmtelHost, mmtelHost))
|
||||
mrfcHost := fmt.Sprintf("%s mrfc.%s mrfc", para5GData["SIP_IP"], imsOrgHost)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", mrfcHost, mrfcHost))
|
||||
smsHost := fmt.Sprintf("%s smsc.%s smsc", para5GData["SIP_IP"], imsOrgHost)
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", smsHost, smsHost))
|
||||
// adb
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/adb/default/adb.conf /usr/local/etc/adb/adb.conf \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind %s/g\" /usr/local/etc/adb/adb.conf \n", para5GData["ADB_IP"]))
|
||||
|
||||
cmdStrArr = append(cmdStrArr, "sudo ims-stop || true && sudo ims-start \n")
|
||||
// 30s后停止服务
|
||||
// cmdStrArr = append(cmdStrArr, "nohup sh -c \"sleep 30s && sudo ims-stop\" > /dev/null 2>&1 & \n")
|
||||
} else {
|
||||
cmdStrArr = append(cmdStrArr, "sudo ims-stop \n")
|
||||
cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo ims-start \n")
|
||||
}
|
||||
} else {
|
||||
if action == "install" {
|
||||
para5GData := NewNeInfoImpl.Para5GData
|
||||
cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n")
|
||||
|
||||
// AMF配置修改
|
||||
if neTypeLower == "amf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/amf/default/amfcfg.yaml /usr/local/etc/amf/amfcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.120/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["AMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.8.120/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["N2_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mcc: 001/mcc: %s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc: 01/mnc: %s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/sst: 1/sst: %s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["SST"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/sd: 000001/sd: %s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["SD"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/- 4388/- %s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["TAC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.130/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["AUSF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.140/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["UDM_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.150/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["SMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.160/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["PCF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.200/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["LMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.210/%s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["NEF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/- internet/- %s/g\" /usr/local/etc/amf/amfcfg.yaml \n", para5GData["DNN_DATA"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s n2' /etc/hosts || echo '%s n2' | sudo tee -a /etc/hosts \n", para5GData["N2_IP"], para5GData["N2_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s amf' /etc/hosts || echo '%s amf' | sudo tee -a /etc/hosts \n", para5GData["AMF_IP"], para5GData["AMF_IP"]))
|
||||
}
|
||||
// AUSF配置修改
|
||||
if neTypeLower == "ausf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/ausf/default/ausfcfg.yaml /usr/local/etc/ausf/ausfcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.130/%s/g\" /usr/local/etc/ausf/ausfcfg.yaml \n", para5GData["AUSF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.140/%s/g\" /usr/local/etc/ausf/ausfcfg.yaml \n", para5GData["UDM_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/ausf/ausfcfg.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mcc: 001/mcc: %s/g\" /usr/local/etc/ausf/ausfcfg.yaml \n", para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc: 01/mnc: %s/g\" /usr/local/etc/ausf/ausfcfg.yaml \n", para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s ausf' /etc/hosts || echo '%s ausf' | sudo tee -a /etc/hosts \n", para5GData["AUSF_IP"], para5GData["AUSF_IP"]))
|
||||
}
|
||||
// UDM配置修改
|
||||
if neTypeLower == "udm" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/udm/default/udmcfg.yaml /usr/local/etc/udm/udmcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/udm/default/nssai.yaml /usr/local/etc/udm/nssai.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/udm/default/snssai.yaml /usr/local/etc/udm/snssai.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/udm/default/as.yaml /usr/local/etc/udm/as.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/udm/default/dnn.yaml /usr/local/etc/udm/dnn.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/udm/default/scscfSet.yaml /usr/local/etc/udm/scscfSet.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/udm/udmcfg.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.140/%s/g\" /usr/local/etc/udm/udmcfg.yaml \n", para5GData["UDM_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.130/%s/g\" /usr/local/etc/udm/udmcfg.yaml \n", para5GData["AUSF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.120/%s/g\" /usr/local/etc/udm/udmcfg.yaml \n", para5GData["AMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mcc: 001/mcc: %s/g\" /usr/local/etc/udm/udmcfg.yaml \n", para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc: 01/mnc: %s/g\" /usr/local/etc/udm/udmcfg.yaml \n", para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc001.mcc001/mnc%s.mcc%s/g\" /usr/local/etc/udm/udmcfg.yaml \n", para5GData["MNC_DOMAIN"], para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc001.mcc001/mnc%s.mcc%s/g\" /usr/local/etc/udm/as.yaml \n", para5GData["MNC_DOMAIN"], para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc001.mcc001/mnc%s.mcc%s/g\" /usr/local/etc/udm/scscfSet.yaml \n", para5GData["MNC_DOMAIN"], para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/sst: 1/sst: %s/g\" /usr/local/etc/udm/nssai.yaml \n", para5GData["SST"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/sst: 1/sst: %s/g\" /usr/local/etc/udm/snssai.yaml \n", para5GData["SST"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/sd: 000001/sd: %s/g\" /usr/local/etc/udm/nssai.yaml \n", para5GData["SD"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/sd: 000001/sd: %s/g\" /usr/local/etc/udm/snssai.yaml \n", para5GData["SD"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/dnn: internet/dnn: %s/g\" /usr/local/etc/udm/snssai.yaml \n", para5GData["DNN_DATA"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/dnn: ims/dnn: %s/g\" /usr/local/etc/udm/snssai.yaml \n", para5GData["DNN_IMS"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/serviceSelection: 'internet'/serviceSelection: '%s'/g\" /usr/local/etc/udm/epsApn.yaml \n", para5GData["DNN_DATA"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/serviceSelection: 'ims'/serviceSelection: '%s'/g\" /usr/local/etc/udm/epsApn.yaml \n", para5GData["DNN_IMS"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/dnn: internet/dnn: %s/g\" /usr/local/etc/udm/dnn.yaml \n", para5GData["DNN_DATA"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/dnn: ims/dnn: %s/g\" /usr/local/etc/udm/dnn.yaml \n", para5GData["DNN_IMS"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.18.81/%s/g\" /usr/local/etc/udm/as.yaml \n", para5GData["SIP_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s udm' /etc/hosts || echo '%s udm' | sudo tee -a /etc/hosts \n", para5GData["UDM_IP"], para5GData["UDM_IP"]))
|
||||
// adb
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/adb/default/adb.conf /usr/local/etc/adb/adb.conf \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind %s/g\" /usr/local/etc/adb/adb.conf \n", para5GData["ADB_IP"]))
|
||||
}
|
||||
// SMF配置修改
|
||||
if neTypeLower == "smf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/smf/default/smf_conf.yaml /usr/local/etc/smf/smf_conf.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.8.110/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["SIP_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.120/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["AMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.140/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["UDM_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.150/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["SMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.160/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["PCF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.190/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["UPF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s|10.2.1.0/24|%s|g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["UE_POOL"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/internet/%s/g\" /usr/local/etc/smf/smf_conf.yaml \n", para5GData["DNN_DATA"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s smf' /etc/hosts || echo '%s smf' | sudo tee -a /etc/hosts \n", para5GData["SMF_IP"], para5GData["SMF_IP"]))
|
||||
}
|
||||
// PCF配置修改
|
||||
if neTypeLower == "pcf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/pcf/default/pcfcfg.yaml /usr/local/etc/pcf/pcfcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.120/%s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["AMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.140/%s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["UDM_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.160/%s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["PCF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.210/%s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["NEF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mcc: 001/mcc: %s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc: 01/mnc: %s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc001.mcc001/mnc%s.mcc%s/g\" /usr/local/etc/pcf/pcfcfg.yaml \n", para5GData["MNC_DOMAIN"], para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s pcf' /etc/hosts || echo '%s pcf' | sudo tee -a /etc/hosts \n", para5GData["PCF_IP"], para5GData["PCF_IP"]))
|
||||
}
|
||||
|
||||
// NSSF配置修改
|
||||
if neTypeLower == "nssf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/nssf/default/nssfcfg.yaml /usr/local/etc/nssf/nssfcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.170/%s/g\" /usr/local/etc/nssf/nssfcfg.yaml \n", para5GData["NSSF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/nssf/nssfcfg.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mcc: 001/mcc: %s/g\" /usr/local/etc/nssf/nssfcfg.yaml \n", para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc: 01/mnc: %s/g\" /usr/local/etc/nssf/nssfcfg.yaml \n", para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s nssf' /etc/hosts || echo '%s nssf' | sudo tee -a /etc/hosts \n", para5GData["NSSF_IP"], para5GData["NSSF_IP"]))
|
||||
}
|
||||
// NRF配置修改
|
||||
if neTypeLower == "nrf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/nrf/default/nrfcfg.yaml /usr/local/etc/nrf/nrfcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/nrf/nrfcfg.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mcc: 001/mcc: %s/g\" /usr/local/etc/nrf/nrfcfg.yaml \n", para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc: 01/mnc: %s/g\" /usr/local/etc/nrf/nrfcfg.yaml \n", para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s nrf' /etc/hosts || echo '%s nrf' | sudo tee -a /etc/hosts \n", para5GData["NRF_IP"], para5GData["NRF_IP"]))
|
||||
}
|
||||
|
||||
// UPF配置修改
|
||||
if neTypeLower == "upf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/upf/default/upfcfg.yaml /usr/local/etc/upf/upfcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/upf/default/upfForwarder_1.yaml /usr/local/etc/upf/upfForwarder_1.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.190/%s/g\" /usr/local/etc/upf/upfcfg.yaml \n", para5GData["UPF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/localhost/%s/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["UPF_IP"]))
|
||||
// UE
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/ueIpv4: 10.2.1.0/s/ueIpv4: 10.2.1.0/ueIpv4: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["UE_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/ueIpv4Mask: 255.255.255.0/s/ueIpv4Mask: 255.255.255.0/ueIpv4Mask: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["UE_MASK"]))
|
||||
// N3
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.8.190/%s/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N3_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N3\"/,/ipv4Mask: 255.255.240.0/s/ipv4Mask: 255.255.240.0/ipv4Mask: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N3_MASK"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N3\"/,/gatewayIpv4: 192.168.1.254/s/gatewayIpv4: 192.168.1.254/gatewayIpv4: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N3_GW"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N3\"/,/interfacePCI: \"0000:00:00.0\"/s/interfacePCI: \"0000:00:00.0\"/interfacePCI: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N3_PCI"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N3\"/,/macAddr: \"00:00:00:00:00:00\"/s/macAddr: \"00:00:00:00:00:00\"/macAddr: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N3_MAC"]))
|
||||
// 标准版 N6
|
||||
if para5GData["UPF_TYPE"] == "StandardUPF" {
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.8.191/%s/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/ipv4Mask: 255.255.240.0/s/ipv4Mask: 255.255.240.0/ipv4Mask: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_MASK"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/gatewayIpv4: 192.168.1.254/s/gatewayIpv4: 192.168.1.254/gatewayIpv4: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_GW"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/interfacePCI: \"0000:00:00.0\"/s/interfacePCI: \"0000:00:00.0\"/interfacePCI: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_PCI"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/macAddr: \"00:00:00:00:00:00\"/s/macAddr: \"00:00:00:00:00:00\"/macAddr: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_MAC"]))
|
||||
// 路由
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo ip route add '%s/%s' via '%s' \n", para5GData["UE_IP"], para5GData["UE_CIDR"], para5GData["N6_IP"]))
|
||||
}
|
||||
// 轻量版
|
||||
if para5GData["UPF_TYPE"] == "LightUPF" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo sed -i \"s/192.168.8.191/0.0.0.0/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo sed -i \"s/type: upfd/type: tun/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, "sudo sed -i 's/driverType: vmxnet3/driverType: \"\"/g' /usr/local/etc/upf/upfForwarder_1.yaml \n")
|
||||
}
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s upf' /etc/hosts || echo '%s upf' | sudo tee -a /etc/hosts \n", para5GData["UPF_IP"], para5GData["UPF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s upfn3' /etc/hosts || echo '%s upfn3' | sudo tee -a /etc/hosts \n", para5GData["N3_IP"], para5GData["N3_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s upfn6' /etc/hosts || echo '%s upfn6' | sudo tee -a /etc/hosts \n", para5GData["N6_IP"], para5GData["N6_IP"]))
|
||||
}
|
||||
|
||||
// LMF配置修改 - 已不再维护,导致激活License失败
|
||||
// NEF配置修改 - SNMP无需License
|
||||
if neTypeLower == "nef" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/nef/default/nef_conf.yaml /usr/local/etc/nef/nef_conf.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.110/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["IMS_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.120/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["AMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.130/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["AUSF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.140/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["UDM_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.150/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["SMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.160/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["PCF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.170/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["NSSF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.180/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["NRF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.190/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["UPF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.210/%s/g\" /usr/local/etc/nef/nef_conf.yaml \n", para5GData["NEF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s nef' /etc/hosts || echo '%s nef' | sudo tee -a /etc/hosts \n", para5GData["NEF_IP"], para5GData["NEF_IP"]))
|
||||
}
|
||||
|
||||
// MME配置修改 - 4G
|
||||
if neTypeLower == "mme" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/mme/default/mme.conf /usr/local/etc/mme/mme.conf \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.120/%s/g\" /usr/local/etc/mme/mme.conf \n", para5GData["AMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.150/%s/g\" /usr/local/etc/mme/mme.conf \n", para5GData["SMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s|192.168.8.220/20|%s|g\" /usr/local/etc/mme/mme.conf \n", para5GData["S1_MMEIP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s|172.16.5.220/24|%s|g\" /usr/local/etc/mme/mme.conf \n", para5GData["S11_MMEIP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s|172.16.5.221/24|%s|g\" /usr/local/etc/mme/mme.conf \n", para5GData["S10_MMEIP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/mnc001.mcc001/mnc%s.mcc%s/g\" /usr/local/etc/mme/mme.conf \n", para5GData["MNC_DOMAIN"], para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/\"00101\"/\"%s%s\"/g\" /usr/local/etc/mme/mme.conf \n", para5GData["MCC"], para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/MCC=\"001\" ; MNC=\"01\";/MCC=\"%s\" ; MNC=\"%s\";/g\" /usr/local/etc/mme/mme.conf \n", para5GData["MCC"], para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/TAC = \"1\";/TAC = \"%s\";/g\" /usr/local/etc/mme/mme.conf \n", para5GData["TAC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/TAC = 1;/TAC = %s;/g\" /usr/local/etc/mme/mme.conf \n", para5GData["TAC"]))
|
||||
// SMF开启
|
||||
cmdStrArr = append(cmdStrArr, "sudo sed -i \"/^ *gxcfg:/,/^ *[^ ]/{s/enable: false/enable: true/;b};\" /usr/local/etc/smf/smf_conf.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s mme' /etc/hosts || echo '%s mme' | sudo tee -a /etc/hosts \n", para5GData["S11_MMEIP"], para5GData["S11_MMEIP"]))
|
||||
}
|
||||
// N3IWF配置修改
|
||||
if neTypeLower == "n3iwf" {
|
||||
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/n3iwf/default/n3iwfcfg.yaml /usr/local/etc/n3iwf/n3iwfcfg.yaml \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/MCC: 001/MCC: %s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["MCC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/MNC: 01/MNC: %s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["MNC"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.12.161/%s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["N3IWF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.12.160/%s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["N3IWF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.8.27/%s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["UDM_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.1.239/%s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["SMF_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.8.22/%s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["N2_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.1.161/%s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["N3_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.1.160/%s/g\" /usr/local/etc/n3iwf/n3iwfcfg.yaml \n", para5GData["N6_IP"]))
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s n3iwf' /etc/hosts || echo '%s n3iwf' | sudo tee -a /etc/hosts \n", para5GData["N3IWF_IP"], para5GData["N3IWF_IP"]))
|
||||
}
|
||||
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo service %s restart \n", neTypeLower))
|
||||
// 30s后停止服务
|
||||
// cmdStrArr = append(cmdStrArr, fmt.Sprintf("nohup sh -c \"sleep 30s && sudo service %s stop\" > /dev/null 2>&1 & \n", neTypeLower))
|
||||
} else {
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo service %s stop \n", neTypeLower))
|
||||
cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n")
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo service %s restart \n", neTypeLower))
|
||||
}
|
||||
}
|
||||
|
||||
// 删除软件包
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo rm %s \n", strings.Join(neFilePaths, " ")))
|
||||
// 结束
|
||||
cmdStrArr = append(cmdStrArr, fmt.Sprintf("echo '%s' \n", okFlagStr))
|
||||
|
||||
return okFlagStr, cmdStrArr, nil
|
||||
}
|
||||
|
||||
// operateDome 操作版本-执行阶段
|
||||
func (r *NeVersionImpl) operateRun(sshClient *ssh.ConnSSH, preinput map[string]string, cmdStrArr []string, neType string, okFlagStr string) (string, error) {
|
||||
// ssh连接会话
|
||||
clientSession, err := sshClient.NewClientSession(127, 42)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("neinfo ssh client session new err")
|
||||
}
|
||||
defer clientSession.Close()
|
||||
|
||||
firstRead := true // 首次命令进行记录日志信息
|
||||
commandLineText := "" // 日志信息
|
||||
done := make(chan bool) // 完成信号
|
||||
// 超时退出 120s
|
||||
timeoutTicker := time.NewTicker(120 * time.Second)
|
||||
defer timeoutTicker.Stop()
|
||||
// 实时读取SSH消息直接输出
|
||||
msTicker := time.NewTicker(100 * time.Millisecond)
|
||||
defer msTicker.Stop()
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-timeoutTicker.C:
|
||||
done <- true
|
||||
return
|
||||
case <-msTicker.C:
|
||||
outputByte := clientSession.Read()
|
||||
if len(outputByte) > 0 {
|
||||
outputStr := string(outputByte)
|
||||
// 非首次进行记录命令
|
||||
if !firstRead {
|
||||
commandLineText += outputStr
|
||||
}
|
||||
|
||||
// IMS预输入
|
||||
if neType == "IMS" {
|
||||
// IMS包 P/I/S-CSCF Config 配置覆盖
|
||||
if strings.Contains(outputStr, "(P/I/S-CSCF Config)? <y/n>") {
|
||||
if pisCSCF, ok := preinput["pisCSCF"]; ok && pisCSCF != "" {
|
||||
clientSession.Write(fmt.Sprintf("%s \n", pisCSCF))
|
||||
} else {
|
||||
clientSession.Write("y \n")
|
||||
}
|
||||
continue
|
||||
}
|
||||
// MF包 etc下目录覆盖
|
||||
if strings.Contains(outputStr, "/usr/local/etc/mf directory? (Yes/No, default: No)") {
|
||||
if pisCSCF, ok := preinput["updateMFetc"]; ok && pisCSCF != "" {
|
||||
clientSession.Write(fmt.Sprintf("%s \n", pisCSCF))
|
||||
} else {
|
||||
clientSession.Write("No \n")
|
||||
}
|
||||
continue
|
||||
}
|
||||
// MF包 share下目录覆盖
|
||||
if strings.Contains(outputStr, "/usr/local/share/mf directory? (Yes/No, default: No)") {
|
||||
if pisCSCF, ok := preinput["updateMFshare"]; ok && pisCSCF != "" {
|
||||
clientSession.Write(fmt.Sprintf("%s \n", pisCSCF))
|
||||
} else {
|
||||
clientSession.Write("No \n")
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 命令终止符后继续执行命令
|
||||
if len(cmdStrArr) > 0 && strings.LastIndex(outputStr, "~$ ") > 2 {
|
||||
if firstRead {
|
||||
firstRead = false
|
||||
}
|
||||
shiftElement := cmdStrArr[0] // 获取第一个元素
|
||||
cmdStrArr = cmdStrArr[1:] // 将第一个元素从切片中移除
|
||||
clientSession.Write(shiftElement)
|
||||
continue
|
||||
}
|
||||
// 最后输出的退出标记
|
||||
if strings.LastIndex(outputStr, okFlagStr) > 5 {
|
||||
done <- true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
// 等待写入协程完成
|
||||
<-done
|
||||
|
||||
return commandLineText, nil
|
||||
}
|
||||
|
||||
// operateDome 操作版本-完成阶段
|
||||
func (r *NeVersionImpl) operateDome(action string, neVersion model.NeVersion) error {
|
||||
if action == "install" {
|
||||
// 网元信息
|
||||
neInfo := NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(neVersion.NeType, neVersion.NeId)
|
||||
if neInfo.NeId != neVersion.NeId {
|
||||
return fmt.Errorf("error found neinfo")
|
||||
}
|
||||
// ========= 网元OAM配置文件 start ==========
|
||||
if err := NewNeInfoImpl.NeConfOAMSync(neInfo, nil, true); err != nil {
|
||||
return fmt.Errorf("error wirte OAM file info")
|
||||
}
|
||||
// ========= 网元OAM配置文件 end ===========
|
||||
}
|
||||
|
||||
// 更新Version
|
||||
verInfo := r.SelectByNeTypeAndNeID(neVersion.NeType, neVersion.NeId)
|
||||
if verInfo.NeId == neVersion.NeId {
|
||||
curName := verInfo.Name
|
||||
curVersion := verInfo.Version
|
||||
curPath := verInfo.Path
|
||||
if action == "install" {
|
||||
verInfo.Name = neVersion.NewName
|
||||
verInfo.Version = neVersion.NewVersion
|
||||
verInfo.Path = neVersion.NewPath
|
||||
verInfo.PreName = "-"
|
||||
verInfo.PreVersion = "-"
|
||||
verInfo.PrePath = "-"
|
||||
verInfo.NewName = "-"
|
||||
verInfo.NewVersion = "-"
|
||||
verInfo.NewPath = "-"
|
||||
}
|
||||
if action == "upgrade" {
|
||||
verInfo.Name = neVersion.NewName
|
||||
verInfo.Version = neVersion.NewVersion
|
||||
verInfo.Path = neVersion.NewPath
|
||||
verInfo.PreName = curName
|
||||
verInfo.PreVersion = curVersion
|
||||
verInfo.PrePath = curPath
|
||||
verInfo.NewName = "-"
|
||||
verInfo.NewVersion = "-"
|
||||
verInfo.NewPath = "-"
|
||||
}
|
||||
if action == "rollback" {
|
||||
verInfo.Name = neVersion.PreName
|
||||
verInfo.Version = neVersion.PreVersion
|
||||
verInfo.Path = neVersion.PrePath
|
||||
verInfo.PreName = curName
|
||||
verInfo.PreVersion = curVersion
|
||||
verInfo.PrePath = curPath
|
||||
}
|
||||
|
||||
verInfo.Status = "1"
|
||||
NewNeVersionImpl.Update(verInfo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -144,8 +144,14 @@ func (s *WSController) SSH(c *gin.Context) {
|
||||
// 创建链接SSH客户端
|
||||
var connSSH ssh.ConnSSH
|
||||
neHost.CopyTo(&connSSH)
|
||||
client, err := connSSH.NewClient()
|
||||
if err != nil {
|
||||
var client *ssh.ConnSSH
|
||||
var clientErr error
|
||||
if neHost.AuthMode == "2" {
|
||||
client, clientErr = connSSH.NewClientByLocalPrivate()
|
||||
} else {
|
||||
client, clientErr = connSSH.NewClient()
|
||||
}
|
||||
if clientErr != nil {
|
||||
// 连接主机失败,请检查连接参数后重试
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
|
||||
return
|
||||
@@ -250,8 +256,19 @@ func (s *WSController) Telnet(c *gin.Context) {
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// 终端单行字符数
|
||||
cols, err := strconv.Atoi(c.Query("cols"))
|
||||
if err != nil || cols > 254 {
|
||||
cols = 80
|
||||
}
|
||||
// 终端显示行数
|
||||
rows, err := strconv.Atoi(c.Query("rows"))
|
||||
if err != nil || cols > rows {
|
||||
rows = 40
|
||||
}
|
||||
|
||||
// 创建Telnet客户端会话
|
||||
clientSession, err := client.NewClientSession()
|
||||
clientSession, err := client.NewClientSession(uint8(cols), uint8(rows))
|
||||
if err != nil {
|
||||
// 连接主机失败,请检查连接参数后重试
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
|
||||
|
||||
@@ -27,3 +27,21 @@ func GetCDRConnect(requestID string, data any) ([]byte, error) {
|
||||
}))
|
||||
return resultByte, err
|
||||
}
|
||||
|
||||
// GetCDRConnect 获取CDR会话事件-SMF
|
||||
func GetSMFCDRConnect(requestID string, data any) ([]byte, error) {
|
||||
msgByte, _ := json.Marshal(data)
|
||||
var query neDataModel.SMFCDREventQuery
|
||||
err := json.Unmarshal(msgByte, &query)
|
||||
if err != nil {
|
||||
logger.Warnf("ws processor GetCDRConnect err: %s", err.Error())
|
||||
return nil, fmt.Errorf("query data structure error")
|
||||
}
|
||||
|
||||
dataMap := neDataService.NewSMFCDREventImpl.SelectPage(query)
|
||||
resultByte, err := json.Marshal(result.Ok(map[string]any{
|
||||
"requestId": requestID,
|
||||
"data": dataMap,
|
||||
}))
|
||||
return resultByte, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user