feat: 添加系统备份功能,权限控制分配

This commit is contained in:
TsMask
2025-09-19 16:11:57 +08:00
parent 1a475c6b35
commit ced1477938
12 changed files with 368 additions and 81 deletions

View File

@@ -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))
}

View File

@@ -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 签约用户信息

View File

@@ -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
}