diff --git a/database/install/sys_dict_data1_i18n_zh.sql b/database/install/sys_dict_data1_i18n_zh.sql index 11cfe2b9..a35c46ca 100644 --- a/database/install/sys_dict_data1_i18n_zh.sql +++ b/database/install/sys_dict_data1_i18n_zh.sql @@ -769,6 +769,9 @@ INSERT INTO `sys_dict_data` VALUES (2258, 2258, 'job.ne_alarm_state_check_udmdb_ INSERT INTO `sys_dict_data` VALUES (2259, 2259, 'job.ne_alarm_state_check_udmdb_sync_remark', '检查网元UDM的DB是否同步状态是否正常,在出现过关闭时发出警报。非master模式下有效', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (2260, 2260, 'job.backup_export_kpi', '备份-KPI数据定期导出', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (2261, 2261, 'job.backup_export_kpi_remark', 'dataType: 类型支持 ims/smf/sgwc/smsc\nfileType: 文件类型 csv/xlsx\nhour: 数据时间从任务执行时间前的小时数', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2262, 2262, 'menu.system.setting.homeSet', '主页设置', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2263, 2263, 'menu.system.setting.reset', '重置', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2264, 2264, 'menu.system.setting.backup', '备份还原', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- multi-tenancy INSERT INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); diff --git a/database/install/sys_dict_data2_i18n_en.sql b/database/install/sys_dict_data2_i18n_en.sql index d8f52e40..f9bebbc7 100644 --- a/database/install/sys_dict_data2_i18n_en.sql +++ b/database/install/sys_dict_data2_i18n_en.sql @@ -769,6 +769,9 @@ INSERT INTO `sys_dict_data` VALUES (4258, 4258, 'job.ne_alarm_state_check_udmdb_ INSERT INTO `sys_dict_data` VALUES (4259, 4259, 'job.ne_alarm_state_check_udmdb_sync_remark', 'Check whether the UDM network element is database is in a normal synchronized state and issue an alert if it has been shut down. Effective in non-master mode.', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (4260, 4260, 'job.backup_export_kpi', 'Backup-Periodic export of KPI Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (4261, 4261, 'job.backup_export_kpi_remark', 'dataType: type support ims/smf/sgwc/smsc\nfileType: file type csv/xlsx\nhour: data time from the hour before the task execution time', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4262, 4262, 'menu.system.setting.homeSet', 'Home Set', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4263, 4263, 'menu.system.setting.reset', 'Reset', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4264, 4264, 'menu.system.setting.backup', 'Backup Restore', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- 多租户 INSERT INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); diff --git a/database/install/sys_menu.sql b/database/install/sys_menu.sql index 289a0bf7..f6f0742b 100644 --- a/database/install/sys_menu.sql +++ b/database/install/sys_menu.sql @@ -303,6 +303,9 @@ INSERT INTO `sys_menu` VALUES (2166, 'menu.dashboard.overview.smfUeNum', 2132, 2 INSERT INTO `sys_menu` VALUES (2167, 'menu.dashboard.overview.imsUeNum', 2132, 4, '#', '', '1', '1', 'B', '1', '1', 'dashboard:overview:imsUeNum', '#', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_menu` VALUES (2168, 'menu.dashboard.overview.gnbBase', 2132, 6, '#', '', '1', '1', 'B', '1', '1', 'dashboard:overview:gnbBase', '#', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_menu` VALUES (2169, 'menu.dashboard.overview.enbBase', 2132, 8, '#', '', '1', '1', 'B', '1', '1', 'dashboard:overview:enbBase', '#', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_menu` VALUES (2170, 'menu.system.setting.homeSet', 2114, 7, '#', '', '1', '1', 'B', '1', '1', 'system:setting:homeSet', '#', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_menu` VALUES (2171, 'menu.system.setting.backup', 2114, 8, '#', '', '1', '1', 'B', '1', '1', 'system:setting:backup', '#', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_menu` VALUES (2172, 'menu.system.setting.reset', 2114, 9, '#', '', '1', '1', 'B', '1', '1', 'system:setting:reset', '#', 'supervisor', 1721902269805, '', 0, ''); -- tenant management for admin user INSERT INTO `sys_menu` VALUES (10000, 'menu.security.tenant', 2113, 5, 'tenant', 'system/tenant/index', '1', '1', 'M', '1', '1', 'system:tenant:list', 'icon-yuzhanghao1', 'supervisor', 1700000000000, NULL, 0, 'menu.security.tenantRemark'); diff --git a/database/install/sys_role_menu.sql b/database/install/sys_role_menu.sql index 4b468873..100684b1 100644 --- a/database/install/sys_role_menu.sql +++ b/database/install/sys_role_menu.sql @@ -199,6 +199,8 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2166); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2167); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2168); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2169); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2171); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2172); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 10000); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 4); diff --git a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql index 3233be1b..40ac3f3b 100644 --- a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql +++ b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql @@ -776,6 +776,9 @@ REPLACE INTO `sys_dict_data` VALUES (2258, 2258, 'job.ne_alarm_state_check_udmdb REPLACE INTO `sys_dict_data` VALUES (2259, 2259, 'job.ne_alarm_state_check_udmdb_sync_remark', '检查网元UDM的DB是否同步状态是否正常,在出现过关闭时发出警报。非master模式下有效', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2260, 2260, 'job.backup_export_kpi', '备份-KPI数据定期导出', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2261, 2261, 'job.backup_export_kpi_remark', 'dataType: 类型支持 ims/smf/sgwc/smsc\nfileType: 文件类型 csv/xlsx\nhour: 数据时间从任务执行时间前的小时数', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2262, 2262, 'menu.system.setting.homeSet', '主页设置', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2263, 2263, 'menu.system.setting.reset', '重置', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2264, 2264, 'menu.system.setting.backup', '备份还原', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- multi-tenancy REPLACE INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); diff --git a/database/upgrade/upg_sys_dict_data2_i18n_en.sql b/database/upgrade/upg_sys_dict_data2_i18n_en.sql index 9074d5aa..50f321ff 100644 --- a/database/upgrade/upg_sys_dict_data2_i18n_en.sql +++ b/database/upgrade/upg_sys_dict_data2_i18n_en.sql @@ -777,6 +777,9 @@ REPLACE INTO `sys_dict_data` VALUES (4258, 4258, 'job.ne_alarm_state_check_udmdb REPLACE INTO `sys_dict_data` VALUES (4259, 4259, 'job.ne_alarm_state_check_udmdb_sync_remark', 'Check whether the UDM network element is database is in a normal synchronized state and issue an alert if it has been shut down. Effective in non-master mode.', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4260, 4260, 'job.backup_export_kpi', 'Backup-Periodic export of KPI Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4261, 4261, 'job.backup_export_kpi_remark', 'dataType: type support ims/smf/sgwc/smsc\nfileType: file type csv/xlsx\nhour: data time from the hour before the task execution time', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4262, 4262, 'menu.system.setting.homeSet', 'Home Set', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4263, 4263, 'menu.system.setting.reset', 'Reset', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4264, 4264, 'menu.system.setting.backup', 'Backup Restore', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- 多租户 REPLACE INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); diff --git a/database/upgrade/upg_sys_menu.sql b/database/upgrade/upg_sys_menu.sql index 89244bff..bcd7c918 100644 --- a/database/upgrade/upg_sys_menu.sql +++ b/database/upgrade/upg_sys_menu.sql @@ -286,6 +286,9 @@ REPLACE INTO `sys_menu` VALUES (2166, 'menu.dashboard.overview.smfUeNum', 2132, REPLACE INTO `sys_menu` VALUES (2167, 'menu.dashboard.overview.imsUeNum', 2132, 4, '#', '', '1', '1', 'B', '1', '1', 'dashboard:overview:imsUeNum', '#', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_menu` VALUES (2168, 'menu.dashboard.overview.gnbBase', 2132, 6, '#', '', '1', '1', 'B', '1', '1', 'dashboard:overview:gnbBase', '#', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_menu` VALUES (2169, 'menu.dashboard.overview.enbBase', 2132, 8, '#', '', '1', '1', 'B', '1', '1', 'dashboard:overview:enbBase', '#', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_menu` VALUES (2170, 'menu.system.setting.homeSet', 2114, 7, '#', '', '1', '1', 'B', '1', '1', 'system:setting:homeSet', '#', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_menu` VALUES (2171, 'menu.system.setting.backup', 2114, 8, '#', '', '1', '1', 'B', '1', '1', 'system:setting:backup', '#', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_menu` VALUES (2172, 'menu.system.setting.reset', 2114, 9, '#', '', '1', '1', 'B', '1', '1', 'system:setting:reset', '#', 'supervisor', 1721902269805, '', 0, ''); -- multi-tenancy -- tenant management for admin user diff --git a/database/upgrade/upg_sys_role_menu.sql b/database/upgrade/upg_sys_role_menu.sql index 951f8086..29472f85 100644 --- a/database/upgrade/upg_sys_role_menu.sql +++ b/database/upgrade/upg_sys_role_menu.sql @@ -200,6 +200,8 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2166); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2167); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2168); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2169); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2171); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2172); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 10000); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 4); diff --git a/src/modules/network_data/controller/all_backup.go b/src/modules/network_data/controller/all_backup.go index ac40f36e..3fbfd08e 100644 --- a/src/modules/network_data/controller/all_backup.go +++ b/src/modules/network_data/controller/all_backup.go @@ -10,6 +10,7 @@ import ( "be.ems/src/framework/reqctx" "be.ems/src/framework/resp" + "be.ems/src/framework/utils/file" "be.ems/src/modules/network_data/model" "be.ems/src/modules/network_data/service" @@ -99,3 +100,42 @@ func (s BackupController) FTPPush(c *gin.Context) { } c.JSON(200, resp.Ok(nil)) } + +// 备份文件-导入OMC +// +// POST /import-omc +func (s BackupController) ImportOMC(c *gin.Context) { + var body struct { + NeType string `json:"neType" binding:"required,oneof=OMC"` + Path string `json:"path" binding:"required"` // 文件路径 + } + if err := c.ShouldBindBodyWithJSON(&body); err != nil { + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) + return + } + if !strings.HasSuffix(body.Path, ".zip") { + c.JSON(200, resp.ErrMsg("Only supports decompression of zip files")) + return + } + + // 将zip文件解压到本地后复制到网元端 + localFilePath := file.ParseUploadFilePath(body.Path) + if err := s.backupService.BackupOMCImport(localFilePath); err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + c.JSON(200, resp.Ok(nil)) +} + +// 备份文件-导出OMC +// +// POST /export-omc +func (s BackupController) ExportOMC(c *gin.Context) { + zipFilePath, err := s.backupService.BackupOMCExport() + if err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + c.FileAttachment(zipFilePath, filepath.Base(zipFilePath)) +} diff --git a/src/modules/network_data/network_data.go b/src/modules/network_data/network_data.go index 9bbe784e..7252051d 100644 --- a/src/modules/network_data/network_data.go +++ b/src/modules/network_data/network_data.go @@ -274,6 +274,14 @@ func Setup(router *gin.Engine) { middleware.PreAuthorize(nil), controller.NewBackup.FTPPush, ) + backupGroup.POST("/import-omc", + middleware.PreAuthorize(nil), + controller.NewBackup.ImportOMC, + ) + backupGroup.POST("/export-omc", + middleware.PreAuthorize(nil), + controller.NewBackup.ExportOMC, + ) } // 网元UDM 签约用户信息 diff --git a/src/modules/network_data/service/backup.go b/src/modules/network_data/service/backup.go index a85744c2..8255c6b9 100644 --- a/src/modules/network_data/service/backup.go +++ b/src/modules/network_data/service/backup.go @@ -3,11 +3,17 @@ package service import ( "encoding/json" "fmt" + "os" "path/filepath" + "runtime" "strings" + "time" + "be.ems/src/framework/cmd" "be.ems/src/framework/ssh" + "be.ems/src/framework/utils/file" "be.ems/src/modules/network_data/model" + neModel "be.ems/src/modules/network_element/model" neService "be.ems/src/modules/network_element/service" systemService "be.ems/src/modules/system/service" ) @@ -15,14 +21,12 @@ import ( // 实例化数据层 Backup 结构体 var NewBackup = &Backup{ BACKUP_DIR: "/usr/local/omc/backup", - neInfoService: neService.NewNeInfo, sysConfigService: systemService.NewSysConfigImpl, } // Backup 备份相关 服务层处理 type Backup struct { BACKUP_DIR string // 备份目录 - neInfoService *neService.NeInfo // 网元信息服务 sysConfigService *systemService.SysConfigImpl // 参数配置服务 } @@ -84,3 +88,193 @@ func (r Backup) FTPPushFile(localFilePath, tag string) error { } return nil } + +// BackupOMCImport 网元配置文件复制到网元端覆盖 +func (r Backup) BackupOMCImport(localZipFile string) error { + neInfoService := neService.NewNeInfo + neVersionService := neService.NewNeVersion + neLicenseService := neService.NewNeLicense + neConfigBackupService := neService.NewNeConfigBackup + + // 网管本地路径 + omcPath := "/usr/local/omc/backup_omc" + if runtime.GOOS == "windows" { + omcPath = fmt.Sprintf("C:%s", omcPath) + } + // 解压到临时目录 + omcPathTmp := fmt.Sprintf("%s/import", omcPath) + if err := file.UnZip(localZipFile, omcPathTmp); err != nil { + return fmt.Errorf("unzip err") + } + defer os.RemoveAll(omcPathTmp) // 删除本地临时目录 + + // 还原OMC-网元信息 + neInfos := make([]neModel.NeInfo, 0) // 网元信息列表 + neVersions := make([]neModel.NeVersion, 0) // 网元版本列表 + neLicenses := make([]neModel.NeLicense, 0) // 网元许可证列表 + neHosts := make([]neModel.NeHost, 0) // 网元主机列表 + localDirPath := fmt.Sprintf("%s/omc/db", omcPathTmp) + neInfoStrArr := file.ReadFileJSONLine(fmt.Sprintf("%s/ne_info.json", localDirPath)) + for _, str := range neInfoStrArr { + var neInfo neModel.NeInfo + if err := json.Unmarshal([]byte(str), &neInfo); err != nil { + continue + } + neInfos = append(neInfos, neInfo) + } + neVersionStrArr := file.ReadFileJSONLine(fmt.Sprintf("%s/ne_version.json", localDirPath)) + for _, str := range neVersionStrArr { + var neVersion neModel.NeVersion + if err := json.Unmarshal([]byte(str), &neVersion); err != nil { + continue + } + neVersions = append(neVersions, neVersion) + } + neLicenseStrArr := file.ReadFileJSONLine(fmt.Sprintf("%s/ne_license.json", localDirPath)) + for _, str := range neLicenseStrArr { + var neLicense neModel.NeLicense + if err := json.Unmarshal([]byte(str), &neLicense); err != nil { + continue + } + neLicenses = append(neLicenses, neLicense) + } + neHostStrArr := file.ReadFileJSONLine(fmt.Sprintf("%s/ne_host.json", localDirPath)) + for _, str := range neHostStrArr { + var neHost neModel.NeHost + if err := json.Unmarshal([]byte(str), &neHost); err != nil { + continue + } + neHosts = append(neHosts, neHost) + } + // 新增网元信息 + for _, neInfo := range neInfos { + if neInfo.NeId == "" || neInfo.NeType == "OMC" { + continue + } + // 删除网元信息 + neInfoService.FindByNeTypeAndNeID(neInfo.NeType, neInfo.NeId) + if neInfo.ID != "" { + neInfoService.DeleteByIds([]string{neInfo.ID}) + } + + neVersion := neModel.NeVersion{} + for _, v := range neVersions { + if v.NeId == neInfo.NeId && v.NeType == neInfo.NeType { + v.ID = "" + neVersion = v + break + } + } + neLicense := neModel.NeLicense{} + for _, v := range neLicenses { + if v.NeId == neInfo.NeId && v.NeType == neInfo.NeType { + v.ID = "" + neLicense = v + break + } + } + neHostArr := make([]neModel.NeHost, 0) // 网元主机列表 + neHostIDs := strings.Split(neInfo.HostIDs, ",") + for _, hostID := range neHostIDs { + for _, v := range neHosts { + if v.HostID == hostID { + v.HostID = "" + neHostArr = append(neHostArr, v) + } + } + } + + neVersionService.Insert(neVersion) + neLicenseService.Insert(neLicense) + neInfo.Hosts = neHostArr + neInfo.CreateBy = "system" + neInfoService.Insert(neInfo) + } + + // 还原网元备份文件 + neList := neInfoService.SelectList(neModel.NeInfo{}, false, false) + for _, neInfo := range neList { + if neInfo.NeType == "OMC" { + continue + } + neTypeLower := strings.ToLower(neInfo.NeType) + // 配置文件-本地复制到网元端 + localDirPath := fmt.Sprintf("%s/ne_config/%s/%s", omcPathTmp, neTypeLower, neInfo.NeId) + if err := neConfigBackupService.FileLocalToNePath(neInfo, localDirPath); err != nil { + continue + } + } + + return nil +} + +// BackupOMCExport 备份OMC数据导出 +func (r Backup) BackupOMCExport() (string, error) { + neInfoService := neService.NewNeInfo + neVersionService := neService.NewNeVersion + neLicenseService := neService.NewNeLicense + neHostService := neService.NewNeHost + neConfigBackupService := neService.NewNeConfigBackup + + // 网管本地路径 + omcPath := "/usr/local/omc/backup_omc" + if runtime.GOOS == "windows" { + omcPath = fmt.Sprintf("C:%s", omcPath) + } + omcPathTmp := fmt.Sprintf("%s/tmp", omcPath) + defer os.RemoveAll(omcPathTmp) // 删除本地临时目录 + + // 备份网元配置文件 + neList := neInfoService.SelectList(neModel.NeInfo{}, false, false) + for _, neInfo := range neList { + if neInfo.NeType == "OMC" { + continue + } + neTypeLower := strings.ToLower(neInfo.NeType) + // 配置文件-网元端复制到本地 + localDirPath := fmt.Sprintf("%s/ne_config/%s/%s", omcPathTmp, neTypeLower, neInfo.NeId) + cmd.Execf("sudo mkdir -p %s", localDirPath) + if err := neConfigBackupService.FileNeToLocalPath(neInfo, localDirPath); err != nil { + continue + } + } + + // 备份OMC + neInfos := make([]any, 0) // 网元信息列表 + neVersions := make([]any, 0) // 网元版本列表 + neLicenses := make([]any, 0) // 网元许可证列表 + neHosts := make([]any, 0) // 网元主机列表 + for _, neInfo := range neList { + neVersion := neVersionService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId) + if neVersion.ID != "" { + neVersions = append(neVersions, neVersion) + } + neLicense := neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId) + if neLicense.ID != "" { + neLicenses = append(neLicenses, neLicense) + } + neHostIDs := strings.Split(neInfo.HostIDs, ",") + for _, hostID := range neHostIDs { + neHost := neHostService.SelectById(hostID) + if neHost.HostID != "" { + neHosts = append(neHosts, neHost) + } + } + neInfos = append(neInfos, neInfo) + } + localDirPath := fmt.Sprintf("%s/omc/db", omcPathTmp) + cmd.Execf("sudo mkdir -p %s", localDirPath) + file.WriterFileJSONLine(neInfos, fmt.Sprintf("%s/ne_info.json", localDirPath)) + file.WriterFileJSONLine(neVersions, fmt.Sprintf("%s/ne_version.json", localDirPath)) + file.WriterFileJSONLine(neLicenses, fmt.Sprintf("%s/ne_license.json", localDirPath)) + file.WriterFileJSONLine(neHosts, fmt.Sprintf("%s/ne_host.json", localDirPath)) + + // 压缩zip文件名 + zipFileName := fmt.Sprintf("BackupOMC-%s.zip", time.Now().Format("20060102150405")) + zipFilePath := fmt.Sprintf("%s/%s", omcPath, zipFileName) + if err := file.CompressZipByDir(zipFilePath, omcPathTmp); err != nil { + return "", fmt.Errorf("compress zip err") + } + + return zipFilePath, nil +} diff --git a/src/modules/network_element/service/ne_config_backup.go b/src/modules/network_element/service/ne_config_backup.go index efd2a6ad..2ff41fdd 100644 --- a/src/modules/network_element/service/ne_config_backup.go +++ b/src/modules/network_element/service/ne_config_backup.go @@ -84,6 +84,43 @@ func (s NeConfigBackup) FileLocalToNe(neInfo model.NeInfo, localFile string) err return fmt.Errorf("unzip err") } + // 本地复制到网元端 + if err := s.FileLocalToNePath(neInfo, localDirPath); err != nil { + return err + } + + _ = os.RemoveAll(localDirPath) // 删除本地临时目录 + return nil +} + +// FileNeToLocal 网元备份文件网元端复制到本地 +func (s NeConfigBackup) FileNeToLocal(neInfo model.NeInfo) (string, error) { + neTypeLower := strings.ToLower(neInfo.NeType) + // 网管本地路径 + omcPath := "/usr/local/omc/backup/ne_config" + if runtime.GOOS == "windows" { + omcPath = fmt.Sprintf("C:%s", omcPath) + } + localDirPath := fmt.Sprintf("%s/%s/%s/from_ne_tmp", omcPath, neTypeLower, neInfo.NeId) + + // 网元端复制到本地 + if err := s.FileNeToLocalPath(neInfo, localDirPath); err != nil { + return "", err + } + + // 压缩zip文件名 + zipFileName := fmt.Sprintf("%s-%s-etc-%s.zip", neTypeLower, neInfo.NeId, date.ParseDateToStr(time.Now(), date.YYYYMMDDHHMMSS)) + zipFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neInfo.NeId, zipFileName) + if err := file.CompressZipByDir(zipFilePath, localDirPath); err != nil { + return "", fmt.Errorf("compress zip err") + } + + _ = os.RemoveAll(localDirPath) // 删除本地临时目录 + return zipFilePath, nil +} + +// FileNeToLocalPath 网元备份文件网元端复制到本地路径 +func (s NeConfigBackup) FileNeToLocalPath(neInfo model.NeInfo, localDirPath string) error { // 网元主机的SSH客户端 sshClient, err := NewNeInfo.NeRunSSHClient(neInfo.NeType, neInfo.NeId) if err != nil { @@ -97,9 +134,73 @@ func (s NeConfigBackup) FileLocalToNe(neInfo model.NeInfo, localFile string) err } defer sftpClient.Close() + neTypeLower := strings.ToLower(neInfo.NeType) + + // 网元配置文件先复制到临时目录 + sshClient.RunCMD("sudo mkdir -p /tmp/omc/ne_config && sudo chmod 777 -R /tmp/omc") + neDirTemp := fmt.Sprintf("/tmp/omc/ne_config/%s/%s", neTypeLower, neInfo.NeId) + switch neTypeLower { + case "ims": + // ims目录 + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/ims", neDirTemp)) + imsDirArr := [...]string{"bgcf", "icscf", "ismc", "mmtel", "mrf", "oam_manages.yaml", "pcscf", "scscf", "vars.cfg", "zlog"} + for _, v := range imsDirArr { + sshClient.RunCMD(fmt.Sprintf("sudo cp -rf /usr/local/etc/ims/%s %s/ims", v, neDirTemp)) + } + // mf目录 + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/mf && sudo cp -rf /usr/local/etc/mf %s", neDirTemp, neDirTemp)) + // rtproxy目录 + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/rtproxy && sudo cp -rf /usr/local/etc/rtproxy/rtproxy.conf %s/rtproxy", neDirTemp, neDirTemp)) + // iwf目录 + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/iwf && sudo cp -rf /usr/local/etc/iwf/*.yaml %s/iwf", neDirTemp, neDirTemp)) + case "udm": + // udm目录 + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo cp -rf /usr/local/etc/udm/*.yaml %s", neDirTemp, neDirTemp)) + // kvdb目录 + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/kvdb && sudo cp -rf /usr/local/etc/kvdb/*.{rdb,conf} %s/kvdb", neDirTemp, neDirTemp)) + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/kvdb && sudo cp -rf /usr/local/etc/kvdb/log %s/kvdb", neDirTemp, neDirTemp)) + case "smsc": + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo cp -rf /usr/local/etc/smsc/{*.yaml,*.conf,*conf.txt} %s", neDirTemp, neDirTemp)) + sshClient.RunCMD(fmt.Sprintf("sudo cp -rf /usr/local/etc/smsc/conf %s/conf", neDirTemp)) + default: + nePath := fmt.Sprintf("/usr/local/etc/%s/*.yaml", neTypeLower) + if neTypeLower == "amf" { + nePath = fmt.Sprintf("/usr/local/etc/%s/*.{yaml,csv}", neTypeLower) + } + if neTypeLower == "mme" { + nePath = fmt.Sprintf("/usr/local/etc/%s/*.{yaml,conf,csv}", neTypeLower) + } + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo cp -rf %s %s", neDirTemp, nePath, neDirTemp)) + } + + // 网元端复制到本地 + if err = sftpClient.CopyDirRemoteToLocal(neDirTemp, localDirPath); err != nil { + return fmt.Errorf("copy config to ne err") + } + sshClient.RunCMD(fmt.Sprintf("sudo rm -rf %s", neDirTemp)) // 删除临时目录 + return nil +} + +// FileLocalToNePath 网元备份文件本地路径复制到网元端 +func (s NeConfigBackup) FileLocalToNePath(neInfo model.NeInfo, localDirPath string) error { + // 网元主机的SSH客户端 + sshClient, err := NewNeInfo.NeRunSSHClient(neInfo.NeType, neInfo.NeId) + if err != nil { + return fmt.Errorf("ne info ssh client err") + } + defer sshClient.Close() + // 网元主机的SSH客户端进行文件传输 + sftpClient, err := sshClient.NewClientSFTP() + if err != nil { + return fmt.Errorf("ne info sftp client err") + } + defer sftpClient.Close() + + neTypeLower := strings.ToLower(neInfo.NeType) + // 网元配置端上的临时目录 neDirTemp := fmt.Sprintf("/tmp/omc/ne_config/%s/%s", neTypeLower, neInfo.NeId) - sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p /tmp/omc/ne_config && sudo chmod 777 -R /tmp/omc && sudo rm -rf %s", neDirTemp)) + sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 777 -R /tmp/omc && sudo rm -rf %s", neDirTemp, neDirTemp)) // 复制到网元端 if err = sftpClient.CopyDirLocalToRemote(localDirPath, neDirTemp); err != nil { return fmt.Errorf("copy config to ne err") @@ -140,84 +241,6 @@ func (s NeConfigBackup) FileLocalToNe(neInfo model.NeInfo, localFile string) err sshClient.RunCMD(fmt.Sprintf("sudo cp -rf %s/* %s && %s", neDirTemp, neEtcPath, chmodFile)) } - _ = os.RemoveAll(localDirPath) // 删除本地临时目录 sshClient.RunCMD(fmt.Sprintf("sudo rm -rf %s", neDirTemp)) // 删除临时目录 return nil } - -// FileNeToLocal 网元备份文件网元端复制到本地 -func (s NeConfigBackup) FileNeToLocal(neInfo model.NeInfo) (string, error) { - // 网元主机的SSH客户端 - sshClient, err := NewNeInfo.NeRunSSHClient(neInfo.NeType, neInfo.NeId) - if err != nil { - return "", fmt.Errorf("ne info ssh client err") - } - defer sshClient.Close() - // 网元主机的SSH客户端进行文件传输 - sftpClient, err := sshClient.NewClientSFTP() - if err != nil { - return "", fmt.Errorf("ne info sftp client err") - } - defer sftpClient.Close() - - neTypeLower := strings.ToLower(neInfo.NeType) - // 网管本地路径 - omcPath := "/usr/local/omc/backup/ne_config" - if runtime.GOOS == "windows" { - omcPath = fmt.Sprintf("C:%s", omcPath) - } - localDirPath := fmt.Sprintf("%s/%s/%s/from_ne_tmp", omcPath, neTypeLower, neInfo.NeId) - - // 网元配置文件先复制到临时目录 - sshClient.RunCMD("sudo mkdir -p /tmp/omc/ne_config && sudo chmod 777 -R /tmp/omc") - neDirTemp := fmt.Sprintf("/tmp/omc/ne_config/%s/%s", neTypeLower, neInfo.NeId) - switch neTypeLower { - case "ims": - // ims目录 - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/ims", neDirTemp)) - imsDirArr := [...]string{"bgcf", "icscf", "ismc", "mmtel", "mrf", "oam_manager.yaml", "pcscf", "scscf", "vars.cfg", "zlog"} - for _, v := range imsDirArr { - sshClient.RunCMD(fmt.Sprintf("sudo cp -rf /usr/local/etc/ims/%s %s/ims", v, neDirTemp)) - } - // mf目录 - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/mf && sudo cp -rf /usr/local/etc/mf %s", neDirTemp, neDirTemp)) - // rtproxy目录 - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/rtproxy && sudo cp -rf /usr/local/etc/rtproxy/rtproxy.conf %s/rtproxy", neDirTemp, neDirTemp)) - // iwf目录 - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/iwf && sudo cp -rf /usr/local/etc/iwf/*.yaml %s/iwf", neDirTemp, neDirTemp)) - case "smsc": - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo cp -rf /usr/local/etc/smsc/{*.yaml,*.conf,*conf.txt} %s", neDirTemp, neDirTemp)) - sshClient.RunCMD(fmt.Sprintf("sudo cp -rf /usr/local/etc/smsc/conf %s/conf", neDirTemp)) - case "udm": - // udm目录 - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo cp -rf /usr/local/etc/udm/*.yaml %s", neDirTemp, neDirTemp)) - // kvdb目录 - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/kvdb && sudo cp -rf /usr/local/etc/kvdb/*.{rdb,conf} %s/kvdb", neDirTemp, neDirTemp)) - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s/kvdb && sudo cp -rf /usr/local/etc/kvdb/log %s/kvdb", neDirTemp, neDirTemp)) - default: - nePath := fmt.Sprintf("/usr/local/etc/%s/*.yaml", neTypeLower) - if neTypeLower == "amf" { - nePath = fmt.Sprintf("/usr/local/etc/%s/*.{yaml,csv}", neTypeLower) - } - if neTypeLower == "mme" { - nePath = fmt.Sprintf("/usr/local/etc/%s/*.{yaml,conf,csv}", neTypeLower) - } - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo cp -rf %s %s", neDirTemp, nePath, neDirTemp)) - } - - // 网元端复制到本地 - if err = sftpClient.CopyDirRemoteToLocal(neDirTemp, localDirPath); err != nil { - return "", fmt.Errorf("copy config err") - } - - // 压缩zip文件名 - zipFileName := fmt.Sprintf("%s-%s-etc-%s.zip", neTypeLower, neInfo.NeId, date.ParseDateToStr(time.Now(), date.YYYYMMDDHHMMSS)) - zipFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neInfo.NeId, zipFileName) - if err := file.CompressZipByDir(zipFilePath, localDirPath); err != nil { - return "", fmt.Errorf("compress zip err") - } - - _ = os.RemoveAll(localDirPath) // 删除本地临时目录 - sshClient.RunCMD(fmt.Sprintf("sudo rm -rf %s", neDirTemp)) // 删除临时目录 - return zipFilePath, nil -}