diff --git a/config/locales/i18n_data.xlsx b/config/locales/i18n_data.xlsx index 5ea03cbb..442153a0 100644 Binary files a/config/locales/i18n_data.xlsx and b/config/locales/i18n_data.xlsx differ diff --git a/config/locales/i18n_table.xlsx b/config/locales/i18n_table.xlsx index fec507fe..9cf560d4 100644 Binary files a/config/locales/i18n_table.xlsx and b/config/locales/i18n_table.xlsx differ diff --git a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql index e62e1a73..d66cbb86 100644 --- a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql +++ b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql @@ -636,7 +636,7 @@ REPLACE INTO `sys_dict_data` VALUES (2112, 2112, 'dictData.ne_info_status.1', ' REPLACE INTO `sys_dict_data` VALUES (2113, 2113, 'dictData.ne_info_status.2', '-', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2114, 2114, 'dictData.ne_info_status.3', '同步配置', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2115, 2115, 'dictType.ne_info_status', '网元信息状态', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); -REPLACE INTO `sys_dict_data` VALUES (2116, 2116, 'menu.tools.neQuickSetup', '网元快速安装', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2116, 2116, 'menu.ne.neQuickSetup', '网元快速安装', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2117, 2117, 'log.operate.title.neConfig', '网元参数配置', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2118, 2118, 'menu.config.neLicense', '网元授权', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2119, 2119, 'log.operate.title.neLicense', '网元授权', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); @@ -651,5 +651,6 @@ REPLACE INTO `sys_dict_data` VALUES (2127, 2127, 'menu.dashboard.mocn', 'MOCN', REPLACE INTO `sys_dict_data` VALUES (2128, 2128, 'menu.monitor.cdr', '话单', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2129, 2129, 'menu.monitor.event', '事件', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2130, 2130, 'dictData.ne_host_authMode.2', '免密认证', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2131, 2131, 'menu.ne.neConfPara5G', '网元公共配置', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_sys_dict_data2_i18n_en.sql b/database/upgrade/upg_sys_dict_data2_i18n_en.sql index 9fc92cad..3f051b4d 100644 --- a/database/upgrade/upg_sys_dict_data2_i18n_en.sql +++ b/database/upgrade/upg_sys_dict_data2_i18n_en.sql @@ -636,7 +636,7 @@ REPLACE INTO `sys_dict_data` VALUES (4112, 4112, 'dictData.ne_info_status.1', 'O REPLACE INTO `sys_dict_data` VALUES (4113, 4113, 'dictData.ne_info_status.2', '-', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4114, 4114, 'dictData.ne_info_status.3', 'Sync Config', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4115, 4115, 'dictType.ne_info_status', 'NE Info State', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); -REPLACE INTO `sys_dict_data` VALUES (4116, 4116, 'menu.tools.neQuickSetup', 'NE Quick Setup', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4116, 4116, 'menu.ne.neQuickSetup', 'NE Quick Setup', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4117, 4117, 'log.operate.title.neConfig', 'NE Parameter Configuration', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4118, 4118, 'menu.config.neLicense', 'NE License', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4119, 4119, 'log.operate.title.neLicense', 'NE License', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); @@ -651,5 +651,6 @@ REPLACE INTO `sys_dict_data` VALUES (4127, 4127, 'menu.dashboard.mocn', 'MOCN', REPLACE INTO `sys_dict_data` VALUES (4128, 4128, 'menu.monitor.cdr', 'CDR', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4129, 4129, 'menu.monitor.event', 'Event', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4130, 4130, 'dictData.ne_host_authMode.2', 'Confidentiality Auth Mode', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4131, 4131, 'menu.ne.neConfPara5G', 'NE Config Public 5G', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_sys_menu.sql b/database/upgrade/upg_sys_menu.sql index f3097974..2e27cf73 100644 --- a/database/upgrade/upg_sys_menu.sql +++ b/database/upgrade/upg_sys_menu.sql @@ -259,11 +259,12 @@ INSERT IGNORE INTO `sys_menu` VALUES (2135, 'menu.config.neHost', 4, 15, 'neHost INSERT IGNORE INTO `sys_menu` VALUES (2136, 'menu.config.neHostCommand', 4, 18, 'neHostCommand', 'ne/neHostCommand/index', '1', '0', 'M', '1', '1', 'ne:neHostCommand:list', 'icon-fuzhidaima', 'supervisor', 1708583596871, '', 0, ''); INSERT IGNORE INTO `sys_menu` VALUES (2137, 'menu.config.neInfo', 4, 14, 'neInfo', 'ne/neInfo/index', '1', '0', 'M', '1', '1', 'ne:neInfo:list', 'icon-fuzhidaima', 'supervisor', 1708583596871, '', 0, ''); INSERT IGNORE INTO `sys_menu` VALUES (2138, 'menu.dashboard.amfUE', 2131, 6, 'amfUE', 'dashboard/amfUE/index', '1', '0', 'M', '1', '1', 'dashboard:amfUE:index', 'icon-paixu', 'supervisor', 1705550000000, '', 0, ''); -INSERT IGNORE INTO `sys_menu` VALUES (2139, 'menu.tools.neQuickSetup', 3, 6, 'neQuickSetup', 'tool/neQuickSetup/index', '1', '1', 'M', '1', '1', 'ne:neHost:list', 'icon-wofaqi', 'supervisor', 1708580000000, '', 0, ''); +INSERT IGNORE INTO `sys_menu` VALUES (2139, 'menu.ne.neQuickSetup', 4, 10, 'neQuickSetup', 'ne/neQuickSetup/index', '1', '1', 'M', '1', '1', 'ne:neQuickSetup:list', 'icon-wofaqi', 'supervisor', 1708580000000, '', 0, ''); INSERT IGNORE INTO `sys_menu` VALUES (2140, 'menu.config.neLicense', 4, 20, 'neLicense', 'ne/neLicense/index', '1', '0', 'M', '1', '1', 'ne:neLicense:list', 'icon-fuzhidaima', 'supervisor', 1708580000000, '', 0, ''); INSERT IGNORE INTO `sys_menu` VALUES (2141, 'menu.config.neSoftware', 4, 23, 'neSoftware', 'ne/neSoftware/index', '1', '0', 'M', '1', '1', 'ne:neSoftware:list', 'icon-fuzhidaima', 'supervisor', 1708580000000, '', 0, ''); INSERT IGNORE INTO `sys_menu` VALUES (2142, 'menu.config.neVersion', 4, 26, 'neVersion', 'ne/neVersion/index', '1', '0', 'M', '1', '1', 'ne:neVersion:list', 'icon-fuzhidaima', 'supervisor', 1708580000000, '', 0, ''); INSERT IGNORE INTO `sys_menu` VALUES (2143, 'menu.dashboard.mocn', 2131, 9, 'mocn', 'dashboard/mocn/index', '1', '0', 'M', '1', '1', 'dashboard:mocn:index', 'icon-paixu', 'supervisor', 1705550000000, '', 0, ''); +INSERT IGNORE INTO `sys_menu` VALUES (2144, 'menu.ne.neConfPara5G', 4, 11, 'neConfPara5G', 'ne/neConfPara5G/index', '1', '0', 'M', '1', '1', 'ne:neConfPara5G:list', 'icon-wofaqi', 'supervisor', 1708580000000, '', 0, ''); -- 指定记录条件更新 diff --git a/src/modules/network_element/controller/ne_info.go b/src/modules/network_element/controller/ne_info.go index a204572e..0b448e24 100644 --- a/src/modules/network_element/controller/ne_info.go +++ b/src/modules/network_element/controller/ne_info.go @@ -184,7 +184,7 @@ func (s *NeInfoController) ConfigFileWrite(c *gin.Context) { Content 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 } @@ -204,6 +204,38 @@ func (s *NeInfoController) ConfigFileWrite(c *gin.Context) { c.JSON(200, result.Ok(nil)) } +// 网元端公共配置文件读取 +// +// GET /para5GFile +func (s *NeInfoController) Para5GFileRead(c *gin.Context) { + fileType := c.Query("fileType") + data := s.neInfoService.NeConfPara5GRead(fileType) + c.JSON(200, result.OkData(data)) +} + +// 网元端公共配置文件写入 +// +// PUT /para5GFile +func (s *NeInfoController) Para5GFileWrite(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body struct { + FileType string `json:"fileType" binding:"oneof='' txt json yaml yml"` // 解析内容数据到对应文件类型 + Content 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.FileType, body.Content, body.SyncNE) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.Ok(nil)) +} + // 网元信息列表 // // GET /list diff --git a/src/modules/network_element/network_element.go b/src/modules/network_element/network_element.go index a803dc88..11d8b9e9 100644 --- a/src/modules/network_element/network_element.go +++ b/src/modules/network_element/network_element.go @@ -64,8 +64,18 @@ func Setup(router *gin.Engine) { ) neInfoGroup.PUT("/configFile", middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neInfo", collectlogs.BUSINESS_TYPE_OTHER)), controller.NewNeInfo.ConfigFileWrite, ) + neInfoGroup.GET("/para5GFile", + middleware.PreAuthorize(nil), + controller.NewNeInfo.Para5GFileRead, + ) + neInfoGroup.PUT("/para5GFile", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neInfo", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeInfo.Para5GFileWrite, + ) neInfoGroup.GET("/list", middleware.PreAuthorize(nil), controller.NewNeInfo.List, diff --git a/src/modules/network_element/service/ne_info.go b/src/modules/network_element/service/ne_info.go index 705dbd86..ffbc2253 100644 --- a/src/modules/network_element/service/ne_info.go +++ b/src/modules/network_element/service/ne_info.go @@ -59,4 +59,12 @@ type INeInfo interface { // NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端 NeConfigFileWirte(neInfo model.NeInfo, filePath, fileType string, content any, sync bool) error + + // NeConfPara5GRead 网元公共配置文件读取 + // + // 返回 string map[string]any + NeConfPara5GRead(fileType string) any + + // NeConfPara5GWirte 网元公共配置文件写入 content内容 syncNE同步到网元端NeType@NeId + NeConfPara5GWirte(fileType string, content any, syncNE []string) error } diff --git a/src/modules/network_element/service/ne_info.impl.go b/src/modules/network_element/service/ne_info.impl.go index 95eafb07..47796819 100644 --- a/src/modules/network_element/service/ne_info.impl.go +++ b/src/modules/network_element/service/ne_info.impl.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "path/filepath" "runtime" "strings" @@ -470,7 +471,7 @@ func (r *NeInfoImpl) NeConfigFileWirte(neInfo model.NeInfo, filePath, fileType s // 同步到网元端 if sync { // 网元主机的SSH客户端 - sshClient, err := NewNeInfoImpl.NeRunSSHclient(neInfo.NeType, neInfo.NeId) + sshClient, err := r.NeRunSSHclient(neInfo.NeType, neInfo.NeId) if err != nil { return err } @@ -494,3 +495,89 @@ func (r *NeInfoImpl) NeConfigFileWirte(neInfo model.NeInfo, filePath, fileType s return nil } + +// NeConfPara5GRead 网元公共配置文件读取 +// +// 返回 string map[string]any +func (r *NeInfoImpl) NeConfPara5GRead(fileType string) any { + // 网管本地路径 + omcFilePath := "/usr/local/omc/etc/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 "read file error" + } + content := string(bytes) + if fileType == "" || fileType == "txt" { + return content + } + // 序列化Map + mapData, err := parse.ConvertConfigToMap(fileType, content) + if err != nil { + logger.Warnf("NeConfPara5GRead ConvertConfigToMap => %s", err.Error()) + return "content convert type error" + } + return mapData +} + +// NeConfPara5GWirte 网元公共配置文件写入 content内容 syncNE同步到网元端NeType@NeId +func (r *NeInfoImpl) NeConfPara5GWirte(fileType string, content any, syncNE []string) error { + // 网管本地路径 + omcFilePath := "/usr/local/omc/etc/para5G.yaml" + if runtime.GOOS == "windows" { + omcFilePath = fmt.Sprintf("C:%s", omcFilePath) + } + + var err error + if fileType == "" || fileType == "txt" { + err = parse.ConvertConfigToFile(fileType, omcFilePath, content) + } + if fileType == "json" || fileType == "yaml" || fileType == "yml" { + err = parse.ConvertConfigToFile(fileType, omcFilePath, content) + } + if 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.Dir(neFilePath) + // 修改网元文件权限 + sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod o+w %s && sudo chmod o+w %s", neFileDir, neFileDir, 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")) + } + } + + return nil +}