From 6617cbcb0ae187d76964707b2f7f888ad8181bd0 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Thu, 10 Apr 2025 16:09:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=BD=91=E5=85=83?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E5=A4=87=E4=BB=BD=E7=9A=84?= =?UTF-8?q?FTP=E9=85=8D=E7=BD=AE=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/lm/file_export/controller.go | 41 ++---- .../processor/exportTable/exportTable.go | 14 +- .../controller/ne_config_backup.go | 135 ++++++++++++++++++ .../network_element/network_element.go | 14 ++ src/modules/system/service/sys_config.go | 28 ++++ 5 files changed, 187 insertions(+), 45 deletions(-) diff --git a/features/lm/file_export/controller.go b/features/lm/file_export/controller.go index ab2f506f..60c09fbf 100644 --- a/features/lm/file_export/controller.go +++ b/features/lm/file_export/controller.go @@ -10,13 +10,11 @@ import ( "be.ems/lib/file" "be.ems/lib/log" "be.ems/lib/services" - "be.ems/src/framework/config" "be.ems/src/framework/database/db" "be.ems/src/framework/i18n" "be.ems/src/framework/reqctx" "be.ems/src/framework/resp" "be.ems/src/framework/ssh" - "be.ems/src/framework/utils/crypto" systemService "be.ems/src/modules/system/service" "github.com/gin-gonic/gin" ) @@ -161,23 +159,16 @@ func (m *SysJob) SetFTPConfig(c *gin.Context) { } // 获取配置 - cfg := systemService.NewSysConfig.FindByKey("sys.exportTable") + cfg := systemService.NewSysConfig.FindByKey("neData.exportTableFTP") if cfg.ConfigId > 0 { - // 加密body - appKey := config.Get("aes.appKey").(string) byteData, err := json.Marshal(body) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } - bodyEn, err := crypto.AESEncryptBase64(string(byteData), appKey) - if err != nil { - c.JSON(200, resp.ErrMsg(err.Error())) - return - } - // 更新 - cfg.ConfigValue = bodyEn - systemService.NewSysConfig.Update(cfg) + cfg.ConfigValue = string(byteData) + cfg.UpdateBy = reqctx.LoginUserToUserName(c) + systemService.NewSysConfig.UpdateEncryptValue(cfg) } c.JSON(200, resp.Ok(nil)) @@ -187,15 +178,8 @@ func (m *SysJob) SetFTPConfig(c *gin.Context) { // GET /table/ftp func (m *SysJob) GetFTPConfig(c *gin.Context) { // 获取配置 - cfg := systemService.NewSysConfig.FindByKey("sys.exportTable") + cfg := systemService.NewSysConfig.FindByKeyDecryptValue("neData.exportTableFTP") if cfg.ConfigId > 0 { - // 解密body - appKey := config.Get("aes.appKey").(string) - bodyDe, err := crypto.AESDecryptBase64(cfg.ConfigValue, appKey) - if err != nil { - c.JSON(200, resp.ErrMsg(err.Error())) - return - } var body struct { Password string `json:"password" ` Username string `json:"username" binding:"required"` @@ -204,8 +188,7 @@ func (m *SysJob) GetFTPConfig(c *gin.Context) { Enable bool `json:"enable"` Dir string `json:"dir" binding:"required"` } - err = json.Unmarshal([]byte(bodyDe), &body) - if err != nil { + if err := json.Unmarshal([]byte(cfg.ConfigValue), &body); err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } @@ -246,17 +229,9 @@ func (m *SysJob) PutFTP(c *gin.Context) { Enable bool `json:"enable"` Dir string `json:"dir" binding:"required"` } - cfg := systemService.NewSysConfig.FindByKey("sys.exportTable") + cfg := systemService.NewSysConfig.FindByKeyDecryptValue("neData.exportTableFTP") if cfg.ConfigId > 0 { - // 解密body - appKey := config.Get("aes.appKey").(string) - bodyDe, err := crypto.AESDecryptBase64(cfg.ConfigValue, appKey) - if err != nil { - c.JSON(200, resp.ErrMsg(err.Error())) - return - } - err = json.Unmarshal([]byte(bodyDe), &cfgData) - if err != nil { + if err := json.Unmarshal([]byte(cfg.ConfigValue), &cfgData); err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } diff --git a/src/modules/crontask/processor/exportTable/exportTable.go b/src/modules/crontask/processor/exportTable/exportTable.go index 51a3a7d8..af2f001d 100644 --- a/src/modules/crontask/processor/exportTable/exportTable.go +++ b/src/modules/crontask/processor/exportTable/exportTable.go @@ -8,13 +8,11 @@ import ( "strings" "time" - "be.ems/src/framework/config" "be.ems/src/framework/cron" "be.ems/src/framework/database/db" "be.ems/src/framework/i18n" "be.ems/src/framework/logger" "be.ems/src/framework/ssh" - "be.ems/src/framework/utils/crypto" "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" @@ -927,17 +925,9 @@ func (s BarProcessor) putFTP(localFilePath string) { Enable bool `json:"enable"` Dir string `json:"dir" binding:"required"` } - cfg := systemService.NewSysConfig.FindByKey("sys.exportTable") + cfg := systemService.NewSysConfig.FindByKeyDecryptValue("neData.exportTableFTP") if cfg.ConfigId > 0 { - // 解密body - appKey := config.Get("aes.appKey").(string) - bodyDe, err := crypto.AESDecryptBase64(cfg.ConfigValue, appKey) - if err != nil { - logger.Errorf("putFTP decrypt error: %v", err) - return - } - err = json.Unmarshal([]byte(bodyDe), &cfgData) - if err != nil { + if err := json.Unmarshal([]byte(cfg.ConfigValue), &cfgData); err != nil { logger.Errorf("putFTP unmarshal error: %v", err) return } diff --git a/src/modules/network_element/controller/ne_config_backup.go b/src/modules/network_element/controller/ne_config_backup.go index be1577cc..fa42f7be 100644 --- a/src/modules/network_element/controller/ne_config_backup.go +++ b/src/modules/network_element/controller/ne_config_backup.go @@ -1,6 +1,7 @@ package controller import ( + "encoding/json" "fmt" "os" "path/filepath" @@ -9,10 +10,12 @@ import ( "be.ems/src/framework/i18n" "be.ems/src/framework/reqctx" "be.ems/src/framework/resp" + "be.ems/src/framework/ssh" "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" "be.ems/src/modules/network_element/model" neService "be.ems/src/modules/network_element/service" + systemService "be.ems/src/modules/system/service" "github.com/gin-gonic/gin" ) @@ -21,6 +24,7 @@ import ( var NewNeConfigBackup = &NeConfigBackupController{ neConfigBackupService: neService.NewNeConfigBackup, neInfoService: neService.NewNeInfo, + sysConfigService: systemService.NewSysConfig, } // 网元配置文件备份记录 @@ -29,6 +33,7 @@ var NewNeConfigBackup = &NeConfigBackupController{ type NeConfigBackupController struct { neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务 neInfoService *neService.NeInfo // 网元信息服务 + sysConfigService *systemService.SysConfig // 参数配置服务 } // 网元配置文件备份记录列表 @@ -204,3 +209,133 @@ func (s NeConfigBackupController) Export(c *gin.Context) { s.neConfigBackupService.Insert(item) c.FileAttachment(item.Path, item.Name) } + +// 网元配置文件备份-设置FTP配置 +// +// POST /ftp +func (s NeConfigBackupController) SetFTP(c *gin.Context) { + var body struct { + Password string `json:"password" ` + Username string `json:"username" binding:"required"` + ToIp string `json:"toIp" binding:"required"` + ToPort int64 `json:"toPort" binding:"required"` + Enable bool `json:"enable"` + Dir string `json:"dir" binding:"required"` + } + if err := c.ShouldBindBodyWithJSON(&body); err != nil { + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(40422, errMsgs)) + return + } + + // 获取配置 + cfg := s.sysConfigService.FindByKey("ne.neConfigBackupFTP") + if cfg.ConfigId > 0 { + byteData, err := json.Marshal(body) + if err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + cfg.ConfigValue = string(byteData) + cfg.UpdateBy = reqctx.LoginUserToUserName(c) + systemService.NewSysConfig.UpdateEncryptValue(cfg) + } + + c.JSON(200, resp.Ok(nil)) +} + +// 网元配置文件备份-获取FTP配置 +// +// GET /ftp +func (s NeConfigBackupController) GetFTP(c *gin.Context) { + // 获取配置 + cfg := s.sysConfigService.FindByKeyDecryptValue("ne.neConfigBackupFTP") + if cfg.ConfigId > 0 { + var body struct { + Password string `json:"password" ` + Username string `json:"username" binding:"required"` + ToIp string `json:"toIp" binding:"required"` + ToPort int64 `json:"toPort" binding:"required"` + Enable bool `json:"enable"` + Dir string `json:"dir" binding:"required"` + } + if err := json.Unmarshal([]byte(cfg.ConfigValue), &body); err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + c.JSON(200, resp.OkData(body)) + return + } + + c.JSON(200, resp.Ok(nil)) +} + +// 网元配置文件备份-文件FTP发送 +// +// PUT /ftp +func (s NeConfigBackupController) PutFTP(c *gin.Context) { + var body struct { + FilePath 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(40422, errMsgs)) + return + } + + // 判断文件是否存在 + if _, err := os.Stat(body.FilePath); os.IsNotExist(err) { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + + // 获取配置 + var cfgData struct { + Password string `json:"password" ` + Username string `json:"username" binding:"required"` + ToIp string `json:"toIp" binding:"required"` + ToPort int64 `json:"toPort" binding:"required"` + Enable bool `json:"enable"` + Dir string `json:"dir" binding:"required"` + } + cfg := s.sysConfigService.FindByKeyDecryptValue("ne.neConfigBackupFTP") + if cfg.ConfigId > 0 { + if err := json.Unmarshal([]byte(cfg.ConfigValue), &cfgData); err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + } + if !cfgData.Enable { + c.JSON(200, resp.ErrMsg("Setting Remote Backup is disabled")) + return + } + + connSSH := ssh.ConnSSH{ + User: cfgData.Username, + Password: cfgData.Password, + Addr: cfgData.ToIp, + Port: cfgData.ToPort, + AuthMode: "0", + } + sshClient, err := connSSH.NewClient() + if err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + defer sshClient.Close() + // 网元主机的SSH客户端进行文件传输 + sftpClient, err := sshClient.NewClientSFTP() + if err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + defer sftpClient.Close() + // 远程文件 + remotePath := filepath.Join(cfgData.Dir, "/ne_config", filepath.Base(body.FilePath)) + // 复制到远程 + if err = sftpClient.CopyFileLocalToRemote(body.FilePath, remotePath); err != nil { + c.JSON(200, resp.ErrMsg("error uploading file")) + return + } + c.JSON(200, resp.Ok(nil)) +} diff --git a/src/modules/network_element/network_element.go b/src/modules/network_element/network_element.go index 78a9787a..b2b5249e 100644 --- a/src/modules/network_element/network_element.go +++ b/src/modules/network_element/network_element.go @@ -351,6 +351,20 @@ func Setup(router *gin.Engine) { collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigBackup", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewNeConfigBackup.Export, ) + neConfigBackupGroup.GET("/ftp", + middleware.PreAuthorize(nil), + controller.NewNeConfigBackup.GetFTP, + ) + neConfigBackupGroup.POST("/ftp", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigBackup", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeConfigBackup.SetFTP, + ) + neConfigBackupGroup.PUT("/ftp", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigBackup", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeConfigBackup.PutFTP, + ) } } diff --git a/src/modules/system/service/sys_config.go b/src/modules/system/service/sys_config.go index bc3664e2..3d06f8a5 100644 --- a/src/modules/system/service/sys_config.go +++ b/src/modules/system/service/sys_config.go @@ -4,8 +4,10 @@ import ( "fmt" "strconv" + "be.ems/src/framework/config" "be.ems/src/framework/constants" "be.ems/src/framework/database/redis" + "be.ems/src/framework/utils/crypto" "be.ems/src/framework/utils/file" "be.ems/src/modules/system/model" "be.ems/src/modules/system/repository" @@ -145,6 +147,32 @@ func (s SysConfig) FindByKey(configKey string) model.SysConfig { return model.SysConfig{} } +// UpdateEncryptValue 更新并加密配置值信息 +func (s SysConfig) UpdateEncryptValue(sysConfig model.SysConfig) int64 { + appKey := config.Get("aes.appKey").(string) + bodyEn, err := crypto.AESEncryptBase64(sysConfig.ConfigValue, appKey) + if err != nil { + return 0 + } + sysConfig.ConfigValue = bodyEn + return s.Update(sysConfig) +} + +// FindByKeyDecryptValue 获取并解密配置值信息 +func (s SysConfig) FindByKeyDecryptValue(configKey string) model.SysConfig { + item := s.FindByKey(configKey) + if item.ConfigKey != configKey { + return item + } + appKey := config.Get("aes.appKey").(string) + bodyDe, err := crypto.AESDecryptBase64(item.ConfigValue, appKey) + if err != nil { + return item + } + item.ConfigValue = bodyDe + return item +} + // ExportData 导出数据表格 func (s SysConfig) ExportData(rows []model.SysConfig, fileName string) (string, error) { // 第一行表头标题