diff --git a/src/modules/network_element/controller/ne_info.go b/src/modules/network_element/controller/ne_info.go index 9c89d192..6ac3da24 100644 --- a/src/modules/network_element/controller/ne_info.go +++ b/src/modules/network_element/controller/ne_info.go @@ -144,119 +144,6 @@ func (s *NeInfoController) ListAll(c *gin.Context) { c.JSON(200, result.OkData(neList)) } -// 网元端配置文件读取 -// -// GET /configFile -func (s *NeInfoController) ConfigFileRead(c *gin.Context) { - language := ctx.AcceptLanguage(c) - var querys struct { - NeType string `form:"neType" binding:"required"` - NeID string `form:"neId" binding:"required"` - FilePath string `form:"filePath"` // 不带文件路径时进行复制覆盖本地网元配置目录 - FileType string `form:"fileType" binding:"oneof='' txt json yaml yml"` // 根据指定文件类型进行解析序列出map->json - } - if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) - return - } - - // 查询网元获取IP - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) - if neInfo.NeId != querys.NeID || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) - return - } - - data := s.neInfoService.NeConfigFileRead(neInfo, querys.FilePath, querys.FileType) - c.JSON(200, result.OkData(data)) -} - -// 网元端配置文件写入 -// -// PUT /configFile -func (s *NeInfoController) ConfigFileWrite(c *gin.Context) { - language := ctx.AcceptLanguage(c) - var body struct { - NeType string `json:"neType" binding:"required"` - NeID string `json:"neId" binding:"required"` - FilePath string `json:"filePath" binding:"required"` - FileType string `json:"fileType" binding:"oneof='' txt json yaml yml"` // 解析内容数据到对应文件类型 - Content any `json:"content" binding:"required"` // 内容 - Sync bool `json:"sync"` // 同步到网元 - } - 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 - } - - err := s.neInfoService.NeConfigFileWirte(neInfo, body.FilePath, body.FileType, body.Content, body.Sync) - 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"` - } - if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) - return - } - - data, err := s.neInfoService.NeConfOAMRead(querys.NeType, querys.NeID) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) - return - } - c.JSON(200, result.OkData(data)) -} - -// 网元端OAM配置文件写入 -// -// 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"` - Content map[string]any `json:"content" binding:"required"` // 内容 - Sync bool `json:"sync"` // 同步到网元 - } - 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 - } - - err := s.neInfoService.NeConfOAMWirte(body.NeType, body.NeID, body.Content, body.Sync) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) - return - } - c.JSON(200, result.Ok(nil)) -} - // 网元端Para5G配置文件读取 // // GET /para5GFile @@ -412,8 +299,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)) @@ -462,18 +349,18 @@ func (s *NeInfoController) Edit(c *gin.Context) { } } - if neVersion.NeType != body.NeType || neVersion.NeId != body.NeId { - neVersion.NeType = body.NeType - neVersion.NeId = body.NeId - } 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.NeType != body.NeType || neLicense.NeId != body.NeId { - neVersion.NeType = body.NeType - neVersion.NeId = body.NeId - } if neLicense.ID != "" { + if neLicense.NeType != body.NeType || neLicense.NeId != body.NeId { + neVersion.NeType = body.NeType + neVersion.NeId = body.NeId + } s.neLicenseService.Update(neLicense) } diff --git a/src/modules/network_element/service/ne_info.go b/src/modules/network_element/service/ne_info.go index ad265734..6209a290 100644 --- a/src/modules/network_element/service/ne_info.go +++ b/src/modules/network_element/service/ne_info.go @@ -45,7 +45,7 @@ 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) @@ -53,26 +53,12 @@ type INeInfo interface { // NeRunCMD 向网元发送cmd命令 NeRunCMD(neType, neId, cmd string) (string, error) - // NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取 - // - // 返回 string string[] map[string]any - NeConfigFileRead(neInfo model.NeInfo, filePath, fileType string) any - - // NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端 - NeConfigFileWirte(neInfo model.NeInfo, filePath, fileType string, content any, sync bool) error - - // NeConfOAMRead 网元OAM配置文件读取 - NeConfOAMRead(neType, neId string) (map[string]any, error) - - // NeConfOAMWirte 网元OAM配置文件写入 content内容 sync同步到网元端 - NeConfOAMWirte(neType, neId string, content any, sync bool) error + // NeConfOAMSync 网元OAM配置文件生成并同步 + NeConfOAMSync(neInfo model.NeInfo, sync bool) error // NeConfPara5GRead 网元公共配置文件读取 NeConfPara5GRead() (map[string]any, error) // NeConfPara5GWirte 网元公共配置文件写入 content内容 syncNE同步到网元端NeType@NeId NeConfPara5GWirte(content map[string]any, syncNE []string) error - - // NeConfPara5GConvert 网元公共配置数据转化 content网元公共配置文件读取内容 - NeConfPara5GDataConvert(content map[string]any) map[string]string } diff --git a/src/modules/network_element/service/ne_info.impl.go b/src/modules/network_element/service/ne_info.impl.go index 9956a87f..883cd17f 100644 --- a/src/modules/network_element/service/ne_info.impl.go +++ b/src/modules/network_element/service/ne_info.impl.go @@ -20,12 +20,14 @@ import ( // 实例化服务层 NeInfoImpl 结构体 var NewNeInfoImpl = &NeInfoImpl{ neInfoRepository: repository.NewNeInfoImpl, + Para5GData: map[string]string{}, } // 网元信息 服务层处理 type NeInfoImpl struct { // 网元信息数据信息 neInfoRepository repository.INeInfo + Para5GData map[string]string } // SelectNeInfoByNeTypeAndNeID 通过ne_type和ne_id查询网元信息 @@ -262,8 +264,7 @@ func (r *NeInfoImpl) DeleteByIds(infoIds []string) (int64, error) { for _, v := range infos { // 主机信息删除 if v.HostIDs != "" { - hostIds := strings.Split(v.HostIDs, ",") - NewNeHostImpl.DeleteByIds(hostIds) + NewNeHostImpl.DeleteByIds(strings.Split(v.HostIDs, ",")) } // 删除License neLicense := NewNeLicenseImpl.SelectByNeTypeAndNeID(v.NeType, v.NeId) @@ -276,8 +277,7 @@ func (r *NeInfoImpl) DeleteByIds(infoIds []string) (int64, error) { 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 @@ -287,12 +287,12 @@ 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 == "" @@ -354,138 +354,6 @@ func (r *NeInfoImpl) NeRunCMD(neType, neId, cmd string) (string, error) { return output, nil } -// NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取 -// -// 返回 string string[] map[string]any -func (r *NeInfoImpl) NeConfigFileRead(neInfo model.NeInfo, filePath, fileType string) any { - neTypeLower := strings.ToLower(neInfo.NeType) - - // 网管本地路径 - omcPath := "/usr/local/etc/omc/ne_config" - if runtime.GOOS == "windows" { - omcPath = fmt.Sprintf("C:%s", omcPath) - } - omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neInfo.NeId) - - // 读取文件内容 - if filePath != "" { - bytes, err := os.ReadFile(fmt.Sprintf("%s/%s", omcPath, filePath)) - if err != nil { - logger.Warnf("NeConfigFile ReadFile => %s", err.Error()) - return "read file error" - } - content := string(bytes) - if fileType == "" || fileType == "txt" { - return content - } - // 序列化Map - mapData, err := parse.ConvertConfigToMap(fileType, content) - if err != nil { - logger.Warnf("NeConfigFile ConvertConfigToMap => %s", err.Error()) - return "content convert type error" - } - return mapData - } - - // 文件列表 - files := []string{} - // 删除原有配置文件 - // 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) - - // 网元主机的SSH客户端 - sshClient, err := r.NeRunSSHclient(neInfo.NeType, neInfo.NeId) - if err != nil { - return err.Error() - } - defer sshClient.Close() - // 网元主机的SSH客户端进行文件传输 - sftpClient, err := sshClient.NewClientSFTP() - if err != nil { - return err.Error() - } - defer sftpClient.Close() - - // 各个网元与网管间约定配置文件 - if err = sftpClient.CopyFileRemoteToLocal(nePath+"/oam_manager.yaml", omcPath+"/oam_manager.yaml"); err == nil { - files = append(files, "oam_manager.yaml") - } - - // 根据情况复制网元特殊配置 - switch neTypeLower { - case "ausf": - cfgFile := "ausfcfg.yaml" - if err = sftpClient.CopyFileRemoteToLocal(fmt.Sprintf("%s/%s", nePath, cfgFile), fmt.Sprintf("%s/%s", omcPath, cfgFile)); err == nil { - files = append(files, cfgFile) - } - case "smf": - cfgFile := "smf_conf.yaml" - if err = sftpClient.CopyFileRemoteToLocal(fmt.Sprintf("%s/%s", nePath, cfgFile), fmt.Sprintf("%s/%s", omcPath, cfgFile)); err == nil { - files = append(files, cfgFile) - } - case "ims": - } - - return files -} - -// NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端 -func (r *NeInfoImpl) NeConfigFileWirte(neInfo model.NeInfo, filePath, fileType string, content any, sync bool) error { - neTypeLower := strings.ToLower(neInfo.NeType) - - // 网管本地路径 - omcPath := "/usr/local/etc/omc/ne_config" - if runtime.GOOS == "windows" { - omcPath = fmt.Sprintf("C:%s", omcPath) - } - localFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neInfo.NeId, filePath) - - var err error - if fileType == "" || fileType == "txt" { - err = parse.ConvertConfigToFile(fileType, localFilePath, content) - } - if fileType == "json" || fileType == "yaml" || fileType == "yml" { - err = parse.ConvertConfigToFile(fileType, localFilePath, content) - } - if err != nil { - return fmt.Errorf("please check if the file exists or write permissions") - } - - // 同步到网元端 - if sync { - // 网元主机的SSH客户端 - sshClient, err := r.NeRunSSHclient(neInfo.NeType, neInfo.NeId) - if err != nil { - 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, filePath) - // 修改网元文件权限 - sshClient.RunCMD(fmt.Sprintf("sudo chmod o+w %s", neFilePath)) - // 复制到网元进行覆盖 - if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil { - return fmt.Errorf("please check if scp remote copy is allowed") - } - } - - return nil -} - // neConfOAMData 网元OAM配置文件默认格式数据 func (r *NeInfoImpl) neConfOAMData() map[string]any { return map[string]any{ @@ -529,11 +397,12 @@ func (r *NeInfoImpl) neConfOAMData() map[string]any { // 必改 "timer": 60, }, + "pubConfigPath": "/usr/local/etc/conf/para5G.yaml", } } -// NeConfOAMRead 网元OAM配置文件读取 -func (r *NeInfoImpl) NeConfOAMRead(neType, neId string) (map[string]any, error) { +// neConfOAMRead 网元OAM配置文件读取 +func (r *NeInfoImpl) neConfOAMRead(neType, neId string) (map[string]any, error) { neTypeLower := strings.ToLower(neType) // 网管本地路径 omcPath := "/usr/local/etc/omc/ne_config" @@ -549,7 +418,7 @@ func (r *NeInfoImpl) NeConfOAMRead(neType, neId string) (map[string]any, error) // return nil, fmt.Errorf("read file error") // 无保留文件时返回默认文件数据 oamData := r.neConfOAMData() - r.NeConfOAMWirte(neType, neId, oamData, false) + r.neConfOAMWirte(neType, neId, oamData, false) return oamData, nil } content := string(bytes) @@ -563,8 +432,8 @@ func (r *NeInfoImpl) NeConfOAMRead(neType, neId string) (map[string]any, error) return mapData, nil } -// NeConfOAMWirte 网元OAM配置文件写入 content内容 sync同步到网元端 -func (r *NeInfoImpl) NeConfOAMWirte(neType, neId string, content any, sync bool) error { +// neConfOAMWirte 网元OAM配置文件写入 content内容 sync同步到网元端 +func (r *NeInfoImpl) neConfOAMWirte(neType, neId string, content any, sync bool) error { neTypeLower := strings.ToLower(neType) fileName := "oam_manager.yaml" // 网管本地路径 @@ -608,6 +477,55 @@ func (r *NeInfoImpl) NeConfOAMWirte(neType, neId string, content any, sync bool) return nil } +// NeConfOAMSync 网元OAM配置文件生成并同步 +func (r *NeInfoImpl) NeConfOAMSync(neInfo model.NeInfo, 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["ipv4"] = neInfo.IP + item["port"] = neInfo.Port + oamData["httpManageCfg"] = item + } + // 对网管HTTP配置 + if v, ok := oamData["oamConfig"]; ok { + item := v.(map[string]any) + item["enable"] = true + if omcIP, ok := r.Para5GData["OMCIP"]; ok && omcIP != "" { + item["ipv4"] = omcIP + } + 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, + } + oamData["oamConfig"] = item + } + // 对网管SNMP配置 + if v, ok := oamData["snmpConfig"]; ok { + item := v.(map[string]any) + item["ipv4"] = neInfo.IP + oamData["snmpConfig"] = item + } + // 对网管KPI上报配置 + if v, ok := oamData["kpiConfig"]; ok { + item := v.(map[string]any) + item["enable"] = true + 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) { // 网管本地路径 @@ -680,11 +598,13 @@ func (r *NeInfoImpl) NeConfPara5GWirte(content map[string]any, syncNE []string) } } + // 转换一份数据到全局 + r.Para5GData = r.neConfPara5GDataConvert(content) return nil } // NeConfPara5GConvert 网元公共配置数据转化 content网元公共配置文件读取内容 -func (r *NeInfoImpl) NeConfPara5GDataConvert(content map[string]any) map[string]string { +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)