Merge branch 'lichang' into lite

This commit is contained in:
TsMask
2025-05-23 16:05:37 +08:00
195 changed files with 4924 additions and 3996 deletions

View File

@@ -24,7 +24,7 @@ database:
std:
type: "mysql"
host: "127.0.0.1"
port: 3306
port: 33066
username: "root"
password: "1000omc@kp!"
database: "omc_db"
@@ -44,6 +44,6 @@ redis:
port: 6379 # Redis port
host: "127.0.0.1" # Redis host
password: "helloearth"
db: 0 # Redis db_num
db: 10 # Redis db_num
# 多个数据源时可以用这个指定默认的数据源
defaultDataSourceName: "default"

View File

@@ -25,6 +25,6 @@ redis:
port: 6379 # Redis port
host: "127.0.0.1" # Redis host
password: "helloearth"
db: 0 # Redis db_num
db: 10 # Redis db_num
# 多个数据源时可以用这个指定默认的数据源
defaultDataSourceName: "default"

View File

@@ -53,11 +53,11 @@ func initFlag() {
if *pVersion {
buildInfo := fmt.Sprintf("OMC \nBuildVer: %s\nBuildTime: %s\nBuildEnv: %s\n", Version, BuildTime, GoVer)
fmt.Println(buildInfo)
os.Exit(1)
os.Exit(0)
}
if *pHelp {
pflag.Usage()
os.Exit(1)
os.Exit(0)
}
conf.BindPFlags(pflag.CommandLine)
@@ -80,7 +80,7 @@ func initViper(configDir *embed.FS) {
// 当期服务环境运行配置 => local
env := conf.GetString("env")
log.Printf("current service environment configuration => %s \n", env)
// log.Printf("current service environment configuration => %s \n", env)
// 加载运行配置文件合并相同配置
envConfigPath := fmt.Sprintf("config/config.%s.yaml", env)

View File

@@ -60,7 +60,7 @@ func ImportSQL() {
processSQLFile(db, sqlPath)
}
log.Println("process success")
// log.Println("process success")
os.Exit(0)
}
@@ -93,11 +93,17 @@ func processSQLFile(db *gorm.DB, filePath string) {
if strings.HasSuffix(line, ";") {
// 执行 SQL 语句
if err := db.Exec(sqlBuilder.String()).Error; err != nil {
errorStr := err.Error()
if strings.Contains(strings.ToLower(errorStr), "duplicate column") {
// 重复字段错误忽略
// log.Printf("Exec SQL: %s\n", line)
// log.Println(err.Error())
errorStr := strings.ToLower(err.Error())
// log.Printf("Exec SQL: %s\n", line)
// log.Println(err.Error())
if strings.Contains(errorStr, "duplicate column") {
// 忽略重复字段错误 Error 1060 (42S21): Duplicate column name 'field_name'
} else if strings.Contains(errorStr, "duplicate key") {
// 忽略重复索引错误 Error 1061 (42000): Duplicate key name 'key_name'
} else if strings.Contains(errorStr, "unknown column") {
// 忽略未知字段错误 Error 1054 (42S22): Unknown column 'field_name' in 'table'
} else if strings.Contains(errorStr, "check that it exists") {
// 忽略删除字段错误 Error 1091 (42000): Can't DROP COLUMN `field_name`; check that it exists
} else {
// 其他错误终止程序
log.Fatalln(errorStr)

View File

@@ -6,25 +6,23 @@ import (
"os"
"path/filepath"
"strings"
"be.ems/src/framework/logger"
)
// WriterFileTXT 写入txt文件 sep 分割符号 需要转换数据
// WriterFileTXTLine 逐行写入txt文件 sep 分割符号 需要转换数据
//
// 例如:
// data := [][]string{}
// data = append(data, []string{"姓名", "年龄", "城市"})
// data = append(data, []string{"1", "2", "3"})
// err := file.WriterFileTXT(data, filePath)
func WriterFileTXT(data [][]string, sep string, filePath string) error {
func WriterFileTXTLine(data [][]string, sep string, filePath string) error {
// 获取文件所在的目录路径
dirPath := filepath.Dir(filePath)
// 确保文件夹路径存在
err := os.MkdirAll(dirPath, 0775)
if err != nil {
logger.Errorf("CreateFile MkdirAll %v", err)
return err
}
// 创建或打开文件
@@ -44,21 +42,19 @@ func WriterFileTXT(data [][]string, sep string, filePath string) error {
// 将缓冲区中的数据刷新到文件中
err = writer.Flush()
if err != nil {
logger.Errorf("CreateFile Flush %v", err)
return err
}
return nil
}
// ReadFileTXT 读取Txt文件sep 分割符号 转换数组数据
func ReadFileTXT(sep string, filePath string) [][]string {
// ReadFileTXTLine 逐行读取Txt文件sep 分割符号 转换数组数据
func ReadFileTXTLine(sep string, filePath string) [][]string {
// 创建 map 存储数据
arr := make([][]string, 0)
// 打开文本文件
file, err := os.Open(filePath)
if err != nil {
logger.Errorf("OpenFile Open %v", err)
return arr
}
defer file.Close()
@@ -66,7 +62,6 @@ func ReadFileTXT(sep string, filePath string) [][]string {
// 创建一个 Scanner 对象,用于逐行读取文件内容
scanner := bufio.NewScanner(file)
if scanner.Err() != nil {
logger.Errorf("OpenFile NewScanner %v", scanner.Err())
return arr
}
@@ -78,3 +73,32 @@ func ReadFileTXT(sep string, filePath string) [][]string {
return arr
}
// WriterFileTXT 写入txt文件
//
// 例如:
// err := file.WriterFileTXT("", filePath)
func WriterFileTXT(text string, filePath string) error {
// 获取文件所在的目录路径
dirPath := filepath.Dir(filePath)
// 确保文件夹路径存在
err := os.MkdirAll(dirPath, 0775)
if err != nil {
return err
}
// 创建或打开文件
file, err := os.Create(filePath)
if err != nil {
return err
}
defer file.Close()
// 将缓冲区中的数据刷新到文件中
_, err = file.WriteString(text)
if err != nil {
return err
}
return nil
}

View File

@@ -120,7 +120,7 @@ func (s BackupExportUDMProcessor) exportAuth(neId, fileType string) string {
data = append(data, []string{v.IMSI, v.Ki, v.AlgoIndex, v.Amf, opc})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}
@@ -168,7 +168,7 @@ func (s BackupExportUDMProcessor) exportSub(neId, fileType string) string {
data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}
@@ -214,7 +214,7 @@ func (s BackupExportUDMProcessor) exportVOIP(neId, fileType string) string {
data = append(data, []string{v.UserName, v.Password})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}
@@ -260,7 +260,7 @@ func (s BackupExportUDMProcessor) exportVolte(neId, fileType string) string {
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}

View File

@@ -7,6 +7,7 @@ import (
"sort"
"strconv"
"strings"
"sync"
"time"
"be.ems/src/framework/constants"
@@ -20,6 +21,12 @@ import (
wsService "be.ems/src/modules/ws/service"
)
var (
triggerMax int64 = 3 // 阈值:连续触发次数大于该值才会产生告警
triggerCount sync.Map // 阈值连续触发次数,存储每个事件的触发记录
triggerWindow time.Duration = 5 * time.Second // 事件触发的时间窗口
)
var NewProcessor = &NeAlarmStateCheckCMDProcessor{
neConfigBackupService: neService.NewNeConfigBackup,
neInfoService: neService.NewNeInfo,
@@ -27,8 +34,6 @@ var NewProcessor = &NeAlarmStateCheckCMDProcessor{
alarmService: neDataService.NewAlarm,
wsSendService: wsService.NewWSSend,
count: 0,
triggerMax: 4,
triggerCount: 0,
}
// NeAlarmStateCheckCMDProcessor 网元告警内存/CPU/磁盘检查
@@ -39,8 +44,6 @@ type NeAlarmStateCheckCMDProcessor struct {
alarmService *neDataService.Alarm // 告警信息服务
wsSendService *wsService.WSSend // ws发送服务
count int // 执行次数
triggerMax int // 阈值连续触发次数大于才会产生告警
triggerCount int // 阈值连续触发次数
}
// alarmParams 告警参数
@@ -142,7 +145,7 @@ func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) {
// 进行新增
newAlarm, err := s.alarmNew(neInfo, params)
params.AddInfo = addInfo // 恢复附加信息
s.triggerCount = 0 // 重置连续触发次数
triggerCount.Clear() // 重置连续触发次数
if err != nil {
result[neTypeAndId] = err.Error()
continue
@@ -233,8 +236,25 @@ func (s NeAlarmStateCheckCMDProcessor) serverState(state map[string]any, cpuUseG
warnMsg = append(warnMsg, fmt.Sprintf("disk usage %.2f%%", sysDiskUsage))
}
if len(warnMsg) > 0 {
s.triggerCount++
if s.triggerCount > s.triggerMax {
currentTime := time.Now()
neTypeAndId := fmt.Sprintf("%s_%s", neState.NeType, neState.NeId)
validTimes := []time.Time{}
if v, ok := triggerCount.Load(neTypeAndId); ok {
times := v.([]time.Time)
// 清理过期的记录10秒前的触发记录不再计入
for _, t := range times {
if currentTime.Sub(t) <= triggerWindow {
validTimes = append(validTimes, t)
}
}
validTimes = append(validTimes, currentTime)
triggerCount.Store(neTypeAndId, validTimes)
} else {
// 事件第一次触发,初始化记录
validTimes = append(validTimes, currentTime)
triggerCount.Store(neTypeAndId, validTimes)
}
if int64(len(validTimes)) >= triggerMax {
return fmt.Errorf("greater than %s", strings.Join(warnMsg, ", "))
}
}

View File

@@ -146,7 +146,7 @@ func (s *NeAlarmStateCheckLicenseProcessor) Execute(data any) (any, error) {
// serverState 网元状态
func (s NeAlarmStateCheckLicenseProcessor) serverState(state map[string]any, dayLt int64) error {
expire := fmt.Sprint(state["expire"])
if expire == "" || expire == "<nil>" || expire == "2099-12-31" {
if expire == "" || expire == "<nil>" || expire == "-" || expire == "2099-12-31" {
return nil
}

View File

@@ -525,7 +525,7 @@ func (s *UDMAuthController) Export(c *gin.Context) {
data = append(data, []string{v.IMSI, v.Ki, v.AlgoIndex, v.Amf, opc})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, resp.ErrMsg(err.Error()))
return
}
@@ -639,7 +639,7 @@ func (s *UDMAuthController) Import(c *gin.Context) {
go s.udmAuthService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmAuthService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -525,7 +525,7 @@ func (s *UDMSubController) Export(c *gin.Context) {
data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, resp.ErrMsg(err.Error()))
return
}
@@ -623,7 +623,7 @@ func (s *UDMSubController) Import(c *gin.Context) {
go s.udmSubService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmSubService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -455,7 +455,7 @@ func (s *UDMVOIPController) Export(c *gin.Context) {
data = append(data, []string{v.UserName, v.Password})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, resp.ErrMsg(err.Error()))
return
}
@@ -557,7 +557,7 @@ func (s *UDMVOIPController) Import(c *gin.Context) {
go s.udmVOIPService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmVOIPService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -484,7 +484,7 @@ func (s *UDMVolteIMSController) Export(c *gin.Context) {
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, resp.ErrMsg(err.Error()))
return
}
@@ -586,7 +586,7 @@ func (s *UDMVolteIMSController) Import(c *gin.Context) {
go s.udmVolteIMSService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmVolteIMSService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -78,7 +78,7 @@ func (s NeHostController) Add(c *gin.Context) {
c.JSON(422, resp.CodeMsg(422001, errMsgs))
return
}
if body.ID == 0 {
if body.ID != 0 {
c.JSON(422, resp.CodeMsg(422002, "bind err: id not is empty"))
return
}
@@ -169,7 +169,7 @@ func (s NeHostController) Remove(c *gin.Context) {
ids = append(ids, parse.Number(v))
}
rows, err := s.neHostService.DeleteByIds(ids)
rows, err := s.neHostService.DeleteByIds(ids, true)
if err != nil {
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
return

View File

@@ -15,6 +15,7 @@ func AlarmHistory(neInfo model.NeInfo) ([]map[string]any, error) {
// 网元参数配置信息
neUrl := fmt.Sprintf("http://%s:%d/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType))
resBytes, err := fetch.Get(neUrl, nil, 60_000)
var resData []map[string]any
if err != nil {
errStr := err.Error()
logger.Warnf("AlarmHistory Get \"%s\"", neUrl)
@@ -24,8 +25,11 @@ func AlarmHistory(neInfo model.NeInfo) ([]map[string]any, error) {
}
}
if len(resBytes) == 0 {
return resData, nil
}
// 序列化结果
var resData []map[string]any
err = json.Unmarshal(resBytes, &resData)
if err != nil {
logger.Errorf("AlarmHistory Unmarshal %s", err.Error())

View File

@@ -7,7 +7,7 @@ type NeLicense struct {
NeId string `json:"neId" gorm:"column:ne_id" binding:"required"` // 网元ID
ActivationRequestCode string `json:"activationRequestCode" gorm:"column:activation_request_code"` // 激活申请代码
LicensePath string `json:"licensePath" gorm:"column:license_path"` // 激活授权文件
Capability int64 `json:"capability" gorm:"column:capability"` // 用户容量
Capability int64 `json:"capability" gorm:"column:capability"` // 容量
SerialNum string `json:"serialNum" gorm:"column:serial_num"` // 序列号
ExpiryDate string `json:"expiryDate" gorm:"column:expiry_date"` // 许可证到期日期
Status string `json:"status" gorm:"column:status"` // 状态 0无效 1有效

View File

@@ -137,7 +137,8 @@ func (r NeHost) Update(neHost model.NeHost) int64 {
}
// DeleteByIds 批量删除网元主机连接信息
func (r NeHost) DeleteByIds(hostIds []int64) (int64, error) {
// checkNeHost 是否检查网元主机
func (r NeHost) DeleteByIds(hostIds []int64, checkNeHost bool) (int64, error) {
// 检查是否存在
ids := r.neHostRepository.SelectByIds(hostIds)
if len(ids) <= 0 {
@@ -145,7 +146,7 @@ func (r NeHost) DeleteByIds(hostIds []int64) (int64, error) {
}
for _, v := range ids {
if v.GroupID == "1" {
if v.GroupID == "1" && checkNeHost {
// 主机信息操作【%s】失败禁止操作网元
return 0, fmt.Errorf("neHost.banNE")
}

View File

@@ -318,7 +318,7 @@ func (r NeInfo) DeleteByIds(ids []int64) (int64, error) {
for _, hostId := range arr {
hostIds = append(hostIds, parse.Number(hostId))
}
r.neHostService.DeleteByIds(hostIds)
r.neHostService.DeleteByIds(hostIds, false)
}
// 删除License
neLicense := NewNeLicense.FindByNeTypeAndNeID(v.NeType, v.NeId)
@@ -494,47 +494,49 @@ func (r NeInfo) NeConfOAMReadSync(neType, neId string) (map[string]any, error) {
}
// UPF和SMF 全小写的key
if _, ok := oamData["httpmanagecfg"]; ok {
content := map[string]any{}
// 网元HTTP服务
// if v, ok := oamData["httpmanagecfg"]; ok {
// item := v.(map[string]any)
// }
// 对网管HTTP配置
if v, ok := oamData["oamconfig"]; ok {
item := v.(map[string]any)
if v, ok := item["iptype"]; ok && v != "" && v != nil {
ipType := v.(string)
if ipType == "ipv6" {
content["omcIP"] = item["ipv6"]
}
if ipType == "ipv4" {
content["omcIP"] = item["ipv4"]
}
}
content["oamEnable"] = item["enable"]
content["oamPort"] = item["port"]
// 网元HTTP服务
if v, ok := oamData["httpmanagecfg"]; ok && v != nil {
item := v.(map[string]any)
if v, ok := item["iptype"]; ok && v != nil {
item["ipType"] = v
delete(item, "iptype")
}
// 对网管SNMP配置
if v, ok := oamData["snmpconfig"]; ok {
item := v.(map[string]any)
content["snmpEnable"] = item["enable"]
content["snmpPort"] = item["port"]
}
// 对网管KPI上报配置
if v, ok := oamData["kpiconfig"]; ok {
item := v.(map[string]any)
content["kpiEnable"] = item["enable"]
content["kpiTimer"] = item["timer"]
}
oamData := r.neConfOAMData()
oamData["httpManageCfg"] = item
delete(oamData, "httpmanagecfg")
r.neConfOAMWirte(neType, neId, oamData, false)
}
// 对网管HTTP配置
if v, ok := oamData["oamconfig"]; ok && v != nil {
item := v.(map[string]any)
if v, ok := item["iptype"]; ok && v != nil {
item["ipType"] = v
delete(item, "iptype")
}
if v, ok := item["neconfig"]; ok && v != nil {
item["neConfig"] = v
delete(item, "neconfig")
}
oamData["oamConfig"] = item
delete(oamData, "oamconfig")
r.neConfOAMWirte(neType, neId, oamData, false)
}
// 对网管SNMP配置
if v, ok := oamData["snmpconfig"]; ok && v != nil {
item := v.(map[string]any)
if v, ok := item["iptype"]; ok && v != nil {
item["ipType"] = v
delete(item, "iptype")
}
oamData["snmpConfig"] = item
delete(oamData, "snmpconfig")
r.neConfOAMWirte(neType, neId, oamData, false)
}
// 对网管KPI上报配置
if v, ok := oamData["kpiconfig"]; ok && v != nil {
item := v.(map[string]any)
oamData["kpiConfig"] = item
delete(oamData, "kpiconfig")
r.neConfOAMWirte(neType, neId, oamData, false)
r.NeConfOAMWirteSync(model.NeInfo{
NeType: neType,
NeId: neId,
}, content, false)
return r.neConfOAMRead(neType, neId, false)
}
// NSSF和MME 配置KPIconfig名不一致时
@@ -706,101 +708,117 @@ func (r NeInfo) NeConfOAMWirteSync(neInfo model.NeInfo, content map[string]any,
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
httpManageCfg, ok := oamData["httpManageCfg"].(map[string]any)
if !ok {
neConfOAMData := r.neConfOAMData()
httpManageCfg = neConfOAMData["httpManageCfg"].(map[string]any)
}
httpManageCfg["port"] = neInfo.Port
if strings.Contains(neInfo.IP, ":") {
httpManageCfg["ipType"] = "ipv6"
httpManageCfg["ipv6"] = neInfo.IP
}
if strings.Contains(neInfo.IP, ".") {
httpManageCfg["ipType"] = "ipv4"
httpManageCfg["ipv4"] = neInfo.IP
}
delete(httpManageCfg, "iptype")
delete(oamData, "httpmanagecfg")
oamData["httpManageCfg"] = httpManageCfg
// 对网管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,
}
// 公共参数指定的OMC
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 v, ok := content["omcIP"]; ok && v != "" && v != nil {
omcIP := v.(string)
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
oamConfig, ok := oamData["oamConfig"].(map[string]any)
if !ok {
neConfOAMData := r.neConfOAMData()
oamConfig = neConfOAMData["oamConfig"].(map[string]any)
}
delete(oamConfig, "neconfig")
oamConfig["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,
}
// 公共参数指定的OMC
if omcIP, ok := r.Para5GData["OMC_IP"]; ok && omcIP != "" {
if strings.Contains(omcIP, ":") {
oamConfig["ipType"] = "ipv6"
oamConfig["ipv6"] = omcIP
}
if strings.Contains(omcIP, ".") {
oamConfig["ipType"] = "ipv4"
oamConfig["ipv4"] = omcIP
}
}
// 传入的变更
if v, ok := content["omcIP"]; ok && v != "" && v != nil {
omcIP := v.(string)
if strings.Contains(omcIP, ":") {
oamConfig["ipType"] = "ipv6"
oamConfig["ipv6"] = omcIP
}
if strings.Contains(omcIP, ".") {
oamConfig["ipType"] = "ipv4"
oamConfig["ipv4"] = omcIP
}
}
delete(oamConfig, "iptype")
if oamEnable, ok := content["oamEnable"]; ok && oamEnable != nil {
oamConfig["enable"] = parse.Boolean(oamEnable)
}
if oamPort, ok := content["oamPort"]; ok && oamPort != nil {
oamConfig["port"] = parse.Number(oamPort)
}
delete(oamData, "oamconfig")
oamData["oamConfig"] = oamConfig
// 对网管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
snmpConfig, ok := oamData["snmpConfig"].(map[string]any)
if !ok {
neConfOAMData := r.neConfOAMData()
snmpConfig = neConfOAMData["snmpConfig"].(map[string]any)
}
if strings.Contains(neInfo.IP, ":") {
snmpConfig["ipType"] = "ipv6"
snmpConfig["ipv6"] = neInfo.IP
}
if strings.Contains(neInfo.IP, ".") {
snmpConfig["ipType"] = "ipv4"
snmpConfig["ipv4"] = neInfo.IP
}
delete(snmpConfig, "iptype")
if snmpEnable, ok := content["snmpEnable"]; ok && snmpEnable != nil {
snmpConfig["enable"] = parse.Boolean(snmpEnable)
}
if snmpPort, ok := content["snmpPort"]; ok && snmpPort != nil {
snmpConfig["port"] = parse.Number(snmpPort)
}
delete(oamData, "snmpconfig")
oamData["snmpConfig"] = snmpConfig
// 对网管KPI上报配置
if v, ok := oamData["kpiConfig"]; ok {
item := v.(map[string]any)
if neInfo.NeType == "UPF" {
item["timer"] = 5
} else {
item["timer"] = 60
}
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
kpiConfig, ok := oamData["kpiConfig"].(map[string]any)
if !ok {
neConfOAMData := r.neConfOAMData()
kpiConfig = neConfOAMData["kpiConfig"].(map[string]any)
}
if neInfo.NeType == "UPF" {
kpiConfig["timer"] = 5
} else {
kpiConfig["timer"] = 60
}
if kpiEnable, ok := content["kpiEnable"]; ok && kpiEnable != nil {
kpiConfig["enable"] = parse.Boolean(kpiEnable)
}
if kpiTimer, ok := content["kpiTimer"]; ok && kpiTimer != nil {
kpiConfig["timer"] = parse.Number(kpiTimer)
}
delete(oamData, "kpiconfig")
oamData["kpiConfig"] = kpiConfig
if err := r.neConfOAMWirte(neInfo.NeType, neInfo.NeId, oamData, sync); err != nil {
return fmt.Errorf("error wirte OAM file info")
}

View File

@@ -686,7 +686,8 @@ func (r NeVersion) operateRun(preinput map[string]string, cmdStrArr []string, ne
}()
// 等待写入协程完成
<-done
// 将安装升级执行结果写入文件
file.WriterFileTXT(commandLineText, fmt.Sprintf("/tmp/operate_run_%s.out", neType))
return commandLineText, nil
}

View File

@@ -116,11 +116,11 @@ func (r TraceTask) SelectByIds(ids []int64) []model.TraceTask {
}
// SelectByUnstopped 查询未停止的任务补发
func (r TraceTask) SelectByUnstopped() []model.TraceTask {
func (r TraceTask) SelectByUnstopped(neStr string) []model.TraceTask {
rows := []model.TraceTask{}
tx := db.DB("").Model(&model.TraceTask{})
// 构建查询条件
tx = tx.Where("end_time > ?", time.Now().UnixMilli())
tx = tx.Where("end_time > ? and ne_list like ?", time.Now().UnixMilli(), fmt.Sprintf("%%%s%%", neStr))
// 查询数据
if err := tx.Find(&rows).Error; err != nil {
logger.Errorf("query find err => %v", err.Error())

View File

@@ -202,8 +202,9 @@ func (r TraceTask) createTaskToNe(task *model.TraceTask, ignoreErr bool) error {
return fmt.Errorf("ne list is empty")
}
// 生成任务ID
traceId := r.traceTaskRepository.LastID() + 1 // 生成任务ID < 65535
task.TraceId = fmt.Sprint(traceId)
if task.TraceId == "" {
task.TraceId = fmt.Sprint(r.traceTaskRepository.LastID() + 1) // 生成任务ID < 65535
}
// 发送任务给网元
errNe := []string{}
@@ -331,8 +332,9 @@ func (r TraceTask) DeleteByIds(ids []int64) (int64, error) {
}
// RunUnstopped 启动跟踪未停止的任务
func (r TraceTask) RunUnstopped() {
tasks := r.traceTaskRepository.SelectByUnstopped()
func (r TraceTask) RunUnstopped(neType string, neId string) {
neStr := fmt.Sprintf("%s_%s", neType, neId)
tasks := r.traceTaskRepository.SelectByUnstopped(neStr)
for _, task := range tasks {
r.createTaskToNe(&task, true)
}