From 5a08cb18c8b6ab1bbebdd2d14ac5240615feff7a Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 22 Mar 2024 10:47:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=92=8C=E4=BF=AE=E6=94=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/nms_cxy/controller/system.go | 52 +- src/modules/nms_cxy/service/config.go | 10 + src/modules/nms_cxy/service/config.impl.go | 526 ++++++++++++++++++++- 3 files changed, 571 insertions(+), 17 deletions(-) diff --git a/src/modules/nms_cxy/controller/system.go b/src/modules/nms_cxy/controller/system.go index 4169d3e..0ce57bb 100644 --- a/src/modules/nms_cxy/controller/system.go +++ b/src/modules/nms_cxy/controller/system.go @@ -25,6 +25,7 @@ var NewSystem = &SystemController{ neSoftwareService: neService.NewNeSoftwareImpl, alarmService: service.NewAlarmImpl, logService: service.NewLogImpl, + configService: service.NewConfigImpl, } // 系统管理接口 @@ -41,6 +42,8 @@ type SystemController struct { alarmService service.IAlarm // 日志数据服务 logService service.ILog + // 配置数据处理服务 + configService service.IConfig } // 软件版本查询接口 @@ -357,10 +360,10 @@ func (s *SystemController) ReinitiateState(c *gin.Context) { func (s *SystemController) ConfigApp(c *gin.Context) { language := ctx.AcceptLanguage(c) var body struct { - RequestId string `json:"requestId" binding:"required"` - Ruid string `json:"ruid" binding:"required"` - OperType string `json:"operType" binding:"required"` - OperPara any `json:"operPara" binding:"required"` + RequestId string `json:"requestId" binding:"required"` + Ruid string `json:"ruid" binding:"required"` + OperType string `json:"operType" binding:"required"` + OperPara map[string]any `json:"operPara" binding:"required"` } if err := c.ShouldBindJSON(&body); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -376,10 +379,19 @@ func (s *SystemController) ConfigApp(c *gin.Context) { return } + failPara := s.configService.ConfigParamModify(neInfo, body.OperType, body.OperPara) + if len(failPara) > 0 { + c.JSON(200, map[string]any{ + "requestId": body.RequestId, + "status": "partialsuccess", + "failPara": failPara, + }) + return + } + c.JSON(200, map[string]any{ "requestId": body.RequestId, - "status": "partialsuccess", - "failPara": []string{"PhyCellID", "TAC"}, + "status": "success", }) } @@ -407,14 +419,28 @@ func (s *SystemController) ConfigInfo(c *gin.Context) { return } + successPara := s.configService.ConfigParamQuery(neInfo, body.QueryPara) + if len(successPara) == 0 { + c.JSON(500, map[string]any{ + "requestId": body.RequestId, + "errorInfo": "Invalid queryPara value", + }) + return + } + + if len(successPara) == len(body.QueryPara) { + c.JSON(200, map[string]any{ + "requestId": body.RequestId, + "status": "success", + "successPara": successPara, + }) + return + } + c.JSON(200, map[string]any{ - "requestId": body.RequestId, - "status": "partialsuccess", - "successPara": map[string]any{ - "cellIdentity": "1234567890", - "PhyCellID": "12345", - "TAC": "12345", - }, + "requestId": body.RequestId, + "status": "partialsuccess", + "successPara": successPara, }) } diff --git a/src/modules/nms_cxy/service/config.go b/src/modules/nms_cxy/service/config.go index 76fa01e..697c31e 100644 --- a/src/modules/nms_cxy/service/config.go +++ b/src/modules/nms_cxy/service/config.go @@ -1,7 +1,17 @@ package service +import ( + neModel "nms_cxy/src/modules/network_element/model" +) + // 配置数据处理服务 服务层接口 type IConfig interface { // ConfigUploadOSS 配置数据上报 ConfigUploadOSS(neType string) error + + // ConfigParamQuery 配置参数查询 + ConfigParamQuery(neInfo neModel.NeInfo, operPara []string) map[string]any + + // ConfigParamModify 配置参数修改 + ConfigParamModify(neInfo neModel.NeInfo, operType string, operPara map[string]any) []string } diff --git a/src/modules/nms_cxy/service/config.impl.go b/src/modules/nms_cxy/service/config.impl.go index 1e25c76..e752614 100644 --- a/src/modules/nms_cxy/service/config.impl.go +++ b/src/modules/nms_cxy/service/config.impl.go @@ -3,30 +3,548 @@ package service import ( "fmt" "nms_cxy/src/framework/constants/uploadsubpath" + "nms_cxy/src/framework/logger" + "nms_cxy/src/framework/utils/cmd" "nms_cxy/src/framework/utils/file" + "nms_cxy/src/framework/utils/ssh" + neModel "nms_cxy/src/modules/network_element/model" + neService "nms_cxy/src/modules/network_element/service" "nms_cxy/src/modules/nms_cxy/utils/common" + "path/filepath" + "strings" ) // 实例化数据层 ConfigImpl 结构体 -var NewConfigImpl = &ConfigImpl{} +var NewConfigImpl = &ConfigImpl{ + neInfoService: neService.NewNeInfoImpl, + neVersionService: neService.NewNeVersionImpl, +} // 配置数据处理服务 服务层处理 -type ConfigImpl struct{} +type ConfigImpl struct { + // 网元信息服务 + neInfoService neService.INeInfo + // 网元版本信息服务 + neVersionService neService.INeVersion +} // ConfigUploadOSS 配置数据上报 +// 配置数据上报时间为每日的0时及12时, func (s *ConfigImpl) ConfigUploadOSS(neType string) error { + // 查网元 + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, "001") + if neInfo.NeType != neType { + logger.Errorf("ConfigUploadOSS ne info not fount") + return fmt.Errorf("no ne info") + } + // 配置文件目录 - dir := "/usr/local/omc/etc" + nePath := fmt.Sprintf("/usr/local/etc/%s/*.yaml", strings.ToLower(neType)) + localPath := fmt.Sprintf("/usr/local/omc/etc/%s/", strings.ToLower(neType)) + err := ssh.FileSCPNeToLocal(neInfo.IP, nePath, localPath) + if err != nil { + logger.Errorf("ConfigUploadOSS scp err %s", err.Error()) + return err + } // 文件名 dataSaveFileName := common.DataSaveFileName{} fileName := dataSaveFileName.ZIP() filePath := fmt.Sprintf("%s/%s", file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName) - err := file.CompressZipByDir(filePath, dir) + err = file.CompressZipByDir(filePath, localPath) if err != nil { + logger.Errorf("ConfigUploadOSS zip err %s", err.Error()) return err } return common.UploadOSSByZip(filePath, neType, "CM") } + +// ConfigParamQuery 配置参数查询 +// +// 请参考NRM数据模型规范中类型为“R”的参数。 +func (s *ConfigImpl) ConfigParamQuery(neInfo neModel.NeInfo, operPara []string) map[string]any { + fmt.Println(neInfo) + fmt.Println(operPara) + resultMap := map[string]any{} + for _, key := range operPara { + // 网络设备的全网唯一标识 RW + if key == "Ruid" { + resultMap["Ruid"] = neInfo.RmUID + } + // 用户友好名 RW + if key == "UserLabel" { + resultMap["UserLabel"] = neInfo.NeName + } + // 制造商名称 + if key == "Manufacturer" { + resultMap["Manufacturer"] = neInfo.VendorName + } + // 设备型号 + if key == "Model" { + resultMap["Model"] = neInfo.NeType + } + // 设备序列号 + if key == "SerialNumber" { + resultMap["SerialNumber"] = "-" + } + // 硬件版本 + if key == "HardwareVersion" { + resultMap["HardwareVersion"] = "-" + } + // 运行时长 + if key == "RunTime" { + resultMap["RunTime"] = 0 + } + // 首次使用日期 + if key == "FirstUseDate" { + resultMap["FirstUseDate"] = "2024" + } + // 设备侧管理口IP地址列表 RW + if key == "ManagementIpAddress" { + resultMap["ManagementIpAddress"] = []string{neInfo.IP} + } + // 设备运行状态 health,warning,fault + if key == "Status" { + if neInfo.Status == "0" { + resultMap["Status"] = "health" + } + if neInfo.Status == "1" { + resultMap["Status"] = "fault" + } + resultMap["Status"] = "warning" + } + // 设备重启 RW + if key == "Reboot" { + resultMap["Reboot"] = false + } + // 激活备份版本使能开关 RW + if key == "BackupSoftwareActivateEnable" { + resultMap["BackupSoftwareActivateEnable"] = false + } + // 系统当前版本 + if key == "CurrentSoftwareVersion" { + resultMap["CurrentSoftwareVersion"] = "-" + } + // 系统备份版本 + if key == "BackupSoftwareVersion" { + resultMap["BackupSoftwareVersion"] = "-" + } + + // FQDN + if key == "Fqdn" { + resultMap["Fqdn"] = "-" + } + // 服务列表 + if key == "SbiServiceList" { + resultMap["SbiServiceList"] = []string{} + } + + // ============ AMF + // 全球AMF唯一标识列表 + if key == "GuamiList" { + resultMap["GuamiList"] = []string{} + } + // 网络切片列表 RW + if key == "SnssaiList" { + resultMap["SnssaiList"] = []string{} + } + // 最大注册用户数 + if key == "MaxUser" { + resultMap["MaxUser"] = 0 + } + // 相对容量 + if key == "RelativeCapacity" { + resultMap["RelativeCapacity"] = 0 + } + // 最大支持基站数 + if key == "MaxGnbNum" { + resultMap["MaxGnbNum"] = 0 + } + // 位置更新区域半径 RW + if key == "Delta" { + resultMap["Delta"] = 0 + } + // N8接口本端IP地址列表 RW + if key == "N8LocIpAddrList" { + resultMap["N8LocIpAddrList"] = 0 + } + // N8接口远端IP子网列表 RW + if key == "N8FarIpSubnetworkList" { + resultMap["N8FarIpSubnetworkList"] = 0 + } + // N11接口本端IP地址列表 RW + if key == "N11LocIpAddrList" { + resultMap["N11LocIpAddrList"] = 0 + } + // N11接口远端IP子网列表 RW + if key == "N11FarIpSubnetworkList" { + resultMap["N11FarIpSubnetworkList"] = 0 + } + // N12接口本端IP地址列表 RW + if key == "N12LocIpAddrList" { + resultMap["N12LocIpAddrList"] = 0 + } + // N12接口远端IP子网列表 RW + if key == "N12FarIpSubnetworkList" { + resultMap["N12FarIpSubnetworkList"] = 0 + } + + // ============ UDM + // 最大可存储的IMSI个数 + if key == "MaxNumImsi" { + resultMap["MaxNumImsi"] = 0 + } + // 最大可存储的MSISDN个数 + if key == "MaxNumMsisdn" { + resultMap["MaxNumMsisdn"] = 0 + } + + // ============ PCF + // 最大签约用户数 RW + if key == "MaxUe" { + resultMap["MaxUe"] = 0 + } + + // ============ UPF + // 最大QoS流数 + if key == "MaxQosFlows" { + resultMap["MaxQosFlows"] = 0 + } + // 最大数据吞吐率 + if key == "MaxThroughput" { + resultMap["MaxThroughput"] = "-" + } + // N9接口本端IP地址列表 RW + if key == "N9LocIpAddrList" { + resultMap["N9LocIpAddrList"] = []string{} + } + // N9接口远端IP子网列表 RW + if key == "N9FarIpSubnetworkList" { + resultMap["N9FarIpSubnetworkList"] = []string{} + } + // N3接口本端IP地址列表 RW + if key == "N3LocIpAddrList" { + resultMap["N3LocIpAddrList"] = []string{} + } + // N3接口远端IP子网列表 RW + if key == "N3FarIpSubnetworkList" { + resultMap["N3FarIpSubnetworkList"] = []string{} + } + + // ============ SMF + // 最大PDU会话数 + if key == "MaxPduSessions" { + resultMap["MaxPduSessions"] = 0 + } + // 最大QFI数 + if key == "MaxQfi" { + resultMap["MaxQfi"] = 0 + } + // 地址类型 RW + if key == "AddrType" { + resultMap["AddrType"] = "-" + } + // IP版本 RW + if key == "IpVersion" { + resultMap["IpVersion"] = "-" + } + // IP地址分段列表 RW + if key == "AddrList" { + resultMap["AddrList"] = []string{} + } + // N7接口本端IP地址列表 RW + if key == "N7LocIpAddrList" { + resultMap["N7LocIpAddrList"] = []string{} + } + // N7接口远端IP子网列表 RW + if key == "N7FarIpSubnetworkList" { + resultMap["N7FarIpSubnetworkList"] = []string{} + } + // N10接口本端IP地址列表 RW + if key == "N10LocIpAddrList" { + resultMap["N10LocIpAddrList"] = []string{} + } + // N10接口远端IP子网列表 RW + if key == "N10FarIpSubnetworkList" { + resultMap["N10FarIpSubnetworkList"] = []string{} + } + // N11接口本端IP地址列表 RW + if key == "N11LocIpAddrList" { + resultMap["N11LocIpAddrList"] = []string{} + } + // N11接口远端IP子网列表 RW + if key == "N11FarIpSubnetworkList" { + resultMap["N11FarIpSubnetworkList"] = []string{} + } + } + + return resultMap +} + +// ConfigParamModify 配置参数修改 +// operType 配置执行类型字符串 add:新增,mod:修改,del:删除 +// operPara 配置参数列表对象 具体可修改参数,请参考NRM数据模型规范中类型为“RW”的参数。 +func (s *ConfigImpl) ConfigParamModify(neInfo neModel.NeInfo, operType string, operPara map[string]any) []string { + failPara := []string{} + operParaSupport := []string{ + "Ruid", // 网络设备的全网唯一标识 RW + "UserLabel", // 用户友好名 RW + "ManagementIpAddress", // 设备侧管理口IP地址列表 RW + "Reboot", // 设备重启 RW + "BackupSoftwareActivateEnable", // 激活备份版本使能开关 RW + // ============ AMF + "SnssaiList", // 网络切片列表 RW + "Delta", // 位置更新区域半径 RW + "N8LocIpAddrList", // N8接口本端IP地址列表 RW + "N8FarIpSubnetworkList", // N8接口远端IP子网列表 RW + "N11LocIpAddrList", // N11接口本端IP地址列表 RW + "N11FarIpSubnetworkList", // N11接口远端IP子网列表 RW + "N12LocIpAddrList", // N12接口本端IP地址列表 RW + "N12FarIpSubnetworkList", // N12接口远端IP子网列表 RW + // ============ PCF + "MaxUe", // 最大签约用户数 RW + // ============ UPF + "N9LocIpAddrList", // N9接口本端IP地址列表 RW + "N9FarIpSubnetworkList", // N9接口远端IP子网列表 RW + "N3LocIpAddrList", // N3接口本端IP地址列表 RW + "N3FarIpSubnetworkList", // N3接口远端IP子网列表 RW + // ============ SMF + "AddrType", // 地址类型 RW + "IpVersion", // IP版本 RW + "AddrList", // IP地址分段列表 RW + "N7LocIpAddrList", // N7接口本端IP地址列表 RW + "N7FarIpSubnetworkList", // N7接口远端IP子网列表 RW + "N10LocIpAddrList", // N10接口本端IP地址列表 RW + "N10FarIpSubnetworkList", // N10接口远端IP子网列表 RW + } + + // 检查是否支持 + for k := range operPara { + hasKey := false + for _, key := range operParaSupport { + if k == key { + hasKey = true + break + } + } + if !hasKey { + failPara = append(failPara, k) + } + } + + // 网络设备的全网唯一标识 RW + _, okRuid := operPara["Ruid"] + // 用户友好名 RW + _, okUserLabel := operPara["UserLabel"] + // 设备侧管理口IP地址列表 RW + _, okManagementIpAddress := operPara["ManagementIpAddress"] + // 设备重启 RW + _, okReboot := operPara["Reboot"] + + _, okBackupSoftwareActivateEnable := operPara["BackupSoftwareActivateEnable"] + + // 修改 + if operType == "mod" { + if okRuid || okUserLabel || okManagementIpAddress || okReboot || okBackupSoftwareActivateEnable { + s.paramModifyBase(neInfo, operPara) + } + } + + // ============ AMF + // 网络切片列表 RW + _, okBackupSnssaiList := operPara["SnssaiList"] + // 位置更新区域半径 RW + _, okDelta := operPara["Delta"] + // N8接口本端IP地址列表 RW + _, okN8LocIpAddrList := operPara["N8LocIpAddrList"] + // N8接口远端IP子网列表 RW + _, okN8FarIpSubnetworkList := operPara["N8FarIpSubnetworkList"] + // N11接口本端IP地址列表 RW + _, okN11LocIpAddrList := operPara["N11LocIpAddrList"] + // N11接口远端IP子网列表 RW + _, okN11FarIpSubnetworkList := operPara["N11FarIpSubnetworkList"] + // N12接口本端IP地址列表 RW + _, okN12LocIpAddrList := operPara["N12LocIpAddrList"] + // N12接口远端IP子网列表 RW + _, okN12FarIpSubnetworkList := operPara["N12FarIpSubnetworkList"] + + // 修改 + if neInfo.NeType == "AMF" { + if okBackupSnssaiList || okDelta || okN8LocIpAddrList || okN8FarIpSubnetworkList || okN11LocIpAddrList || okN11FarIpSubnetworkList || okN12LocIpAddrList || okN12FarIpSubnetworkList { + rs := s.paramModifyAMF(neInfo, operPara) + failPara = append(failPara, rs...) + } + } + + // ============ PCF + // 最大签约用户数 RW + _, okMaxUe := operPara["MaxUe"] + + // 修改 + if neInfo.NeType == "PCF" { + if okMaxUe { + rs := s.paramModifyPCF(neInfo, operPara) + failPara = append(failPara, rs...) + } + } + + // ============ UPF + // N9接口本端IP地址列表 RW + _, okN9LocIpAddrList := operPara["N9LocIpAddrList"] + // N9接口远端IP子网列表 RW + _, okN9FarIpSubnetworkList := operPara["N9FarIpSubnetworkList"] + // N3接口本端IP地址列表 RW + _, okN3LocIpAddrList := operPara["N3LocIpAddrList"] + // N3接口远端IP子网列表 RW + _, okN3FarIpSubnetworkList := operPara["N3FarIpSubnetworkList"] + + // 修改 + if neInfo.NeType == "UPF" { + if okN9LocIpAddrList || okN9FarIpSubnetworkList || okN3LocIpAddrList || okN3FarIpSubnetworkList { + rs := s.paramModifyUPF(neInfo, operPara) + failPara = append(failPara, rs...) + } + } + + // ============ SMF + // 地址类型 RW + _, okAddrType := operPara["AddrType"] + // IP版本 RW + _, okIpVersion := operPara["IpVersion"] + // IP地址分段列表 RW + _, okAddrList := operPara["AddrList"] + // N7接口本端IP地址列表 RW + _, okN7LocIpAddrList := operPara["N7LocIpAddrList"] + // N7接口远端IP子网列表 RW + _, okN7FarIpSubnetworkList := operPara["N7FarIpSubnetworkList"] + // N10接口本端IP地址列表 RW + _, okN10LocIpAddrList := operPara["N10LocIpAddrList"] + // N10接口远端IP子网列表 RW + _, okN10FarIpSubnetworkList := operPara["N10FarIpSubnetworkList"] + + // 修改 + if neInfo.NeType == "SMF" { + if okAddrType || okIpVersion || okAddrList || okN7LocIpAddrList || okN7FarIpSubnetworkList || okN10LocIpAddrList || okN10FarIpSubnetworkList || okN11LocIpAddrList || okN11FarIpSubnetworkList { + rs := s.paramModifySMF(neInfo, operPara) + failPara = append(failPara, rs...) + } + } + + // 删除 + // if operType == "del" {} + + // 新增 + // if operType == "add" {} + + return failPara +} + +// paramModifyBase 修改基本 +func (s *ConfigImpl) paramModifyBase(neInfo neModel.NeInfo, operPara map[string]any) { + if v, ok := operPara["Ruid"]; ok && v != nil { + neInfo.RmUID = v.(string) + } + if v, ok := operPara["UserLabel"]; ok && v != nil { + neInfo.NeName = v.(string) + } + if v, ok := operPara["ManagementIpAddress"]; ok && v != nil { + managementIpAddress := v.([]string) + if len(managementIpAddress) > 0 { + neInfo.IP = managementIpAddress[0] + } + } + + // 重启 + if v, ok := operPara["Reboot"]; ok && v != nil { + if v.(bool) { + cmdStr := fmt.Sprintf("sleep 5s && sudo service %s restart", strings.ToLower(neInfo.NeType)) + if neInfo.NeType == "IMS" { + cmdStr = "sleep 5s && sudo ims-start restart" + } + go func() { + _, err := cmd.ExecWithCheck("nohup", "sh", "-c", cmdStr, "> /dev/null 2>&1 &\n") + if err != nil { + logger.Errorf("NE service reboot error %s \n", err.Error()) + } + }() + } + } + + // 回退 + if v, ok := operPara["BackupSoftwareActivateEnable"]; ok && v != nil { + if v.(bool) { + neVersion := s.neVersionService.SelectByTypeAndID(neInfo.NeType, neInfo.NeId) + if neVersion.NeId == neInfo.NeId { + ssh.FileSCPLocalToNe(neInfo.IP, "/usr/local/omc/bin/rbkpkg.sh", "/tmp/") + ssh.FileSCPLocalToNe(neInfo.IP, neVersion.PreFile, "/tmp/") + cmdStr := fmt.Sprintf("chmod +x /tmp/rbkpkg.sh \n sudo /tmp/rbkpkg.sh '/tmp/%s' %s", filepath.Base(neVersion.PreFile), neInfo.NeType) + _, err := cmd.ExecWithCheck("ssh", cmdStr) + if err != nil { + logger.Errorf("NE service backupSoftwareActivateEnable error %s \n", err.Error()) + } + } + } + } + + // 获取网元状态是否正常 + _, err := neService.NeState(neInfo) + if err != nil { + neInfo.Status = "1" + } else { + // 下发网管配置信息给网元 + _, err = neService.NeConfigOMC(neInfo) + if err == nil { + neInfo.Status = "0" + } else { + neInfo.Status = "3" + } + } + s.neInfoService.Update(neInfo) +} + +// paramModifyAMF 修改AMF +func (s *ConfigImpl) paramModifyAMF(neInfo neModel.NeInfo, operPara map[string]any) []string { + failPara := []string{} + + fmt.Println(neInfo.NeType) + for k, v := range operPara { + fmt.Println(k, v) + failPara = append(failPara, k) + } + return failPara +} + +// paramModifyPCF 修改PCF +func (s *ConfigImpl) paramModifyPCF(neInfo neModel.NeInfo, operPara map[string]any) []string { + failPara := []string{} + fmt.Println(neInfo.NeType) + for k, v := range operPara { + fmt.Println(k, v) + failPara = append(failPara, k) + } + return failPara +} + +// paramModifyUPF 修改UPF +func (s *ConfigImpl) paramModifyUPF(neInfo neModel.NeInfo, operPara map[string]any) []string { + failPara := []string{} + fmt.Println(neInfo.NeType) + for k, v := range operPara { + fmt.Println(k, v) + failPara = append(failPara, k) + } + return failPara +} + +// paramModifySMF 修改SMF +func (s *ConfigImpl) paramModifySMF(neInfo neModel.NeInfo, operPara map[string]any) []string { + failPara := []string{} + fmt.Println(neInfo.NeType) + for k, v := range operPara { + fmt.Println(k, v) + failPara = append(failPara, k) + } + return failPara +}