diff --git a/database/install/sys_config.sql b/database/install/sys_config.sql index 96140ba8..8a3b1147 100644 --- a/database/install/sys_config.sql +++ b/database/install/sys_config.sql @@ -42,7 +42,7 @@ INSERT INTO `sys_config` VALUES (108, 'config.sys.i18nOpen', 'sys.i18n.open', 't INSERT INTO `sys_config` VALUES (109, 'config.sys.i18nDefault', 'sys.i18n.default', 'en_US', 'Y', 'supervisor', 1700000000000, NULL, 0, 'config.sys.i18nDefaultRemark'); INSERT INTO `sys_config` VALUES (110, 'config.sys.lockTime', 'sys.lockTime', '0', 'Y', 'supervisor', 1704960008300, 'admin', 1706838764703, 'config.sys.lockTimeRemark'); INSERT INTO `sys_config` VALUES (111, 'config.sys.homePage', 'sys.homePage', 'configManage/neOverview/index', 'Y', 'supervisor', 1704960008300, 'admin', 1706838764703, 'config.sys.homePageRemark'); -INSERT INTO `sys_config` VALUES (112, 'config.sys.exportTable', 'sys.exportTable', '43t6VAMQmdnt9ynWGJIR1ufeQOvr1doHDsjWUFT8JVzxTVEYgZ1Xvrk47JaPeCHMPKk9zLhJCU9MmA7JAWslQyWBLHzVOMUmA1ppIL1sVIkWGrdDiw0XuMdvXpUu/adrXHhqo42NP3hxcvwXvkWvgedezzCnUsvqfMt+Yw1Wick=', 'Y', 'supervisor', 1737355823940, 'supervisor', 1737363302083, 'config.sys.exportTableRemark'); +INSERT INTO `sys_config` VALUES (112, 'config.sys.exportTable', 'sys.exportTable', 'B1n9hW6Z2S2wZw4MVPAX6Q4wCuyWKdMk+qH1ZKqpLJxwvq2FBRgAT6WWw+j6O+ExHIJhpJ3XCpMBoiNN/RkW6EPurmqM82gnXWUIf/s6gk7OWrhdvQDD2jjNVBkLCmPLEH3ZLdgnQOZOePA7WyUdXA==', 'Y', 'supervisor', 1737355823940, 'supervisor', 1737363302083, 'config.sys.exportTableRemark'); UNLOCK TABLES; diff --git a/database/upgrade/upg_sys_config.sql b/database/upgrade/upg_sys_config.sql index b4dce56a..b1c3b8f5 100644 --- a/database/upgrade/upg_sys_config.sql +++ b/database/upgrade/upg_sys_config.sql @@ -37,6 +37,6 @@ INSERT IGNORE INTO `sys_config` VALUES (108, 'config.sys.i18nOpen', 'sys.i18n.op INSERT IGNORE INTO `sys_config` VALUES (109, 'config.sys.i18nDefault', 'sys.i18n.default', 'en_US', 'Y', 'supervisor', 1700000000000, NULL, 0, 'config.sys.i18nDefaultRemark'); INSERT IGNORE INTO `sys_config` VALUES (110, 'config.sys.lockTime', 'sys.lockTime', '0', 'Y', 'supervisor', 1704960008300, 'admin', 1706838764703, 'config.sys.lockTimeRemark'); INSERT IGNORE INTO `sys_config` VALUES (111, 'config.sys.homePage', 'sys.homePage', 'configManage/neOverview/index', 'Y', 'supervisor', 1704960008300, 'admin', 1706838764703, 'config.sys.homePageRemark'); -INSERT IGNORE INTO `sys_config` VALUES (112, 'config.sys.exportTable', 'sys.exportTable', '43t6VAMQmdnt9ynWGJIR1ufeQOvr1doHDsjWUFT8JVzxTVEYgZ1Xvrk47JaPeCHMPKk9zLhJCU9MmA7JAWslQyWBLHzVOMUmA1ppIL1sVIkWGrdDiw0XuMdvXpUu/adrXHhqo42NP3hxcvwXvkWvgedezzCnUsvqfMt+Yw1Wick=', 'Y', 'supervisor', 1737355823940, 'supervisor', 1737363302083, 'config.sys.exportTableRemark'); +INSERT IGNORE INTO `sys_config` VALUES (112, 'config.sys.exportTable', 'sys.exportTable', 'B1n9hW6Z2S2wZw4MVPAX6Q4wCuyWKdMk+qH1ZKqpLJxwvq2FBRgAT6WWw+j6O+ExHIJhpJ3XCpMBoiNN/RkW6EPurmqM82gnXWUIf/s6gk7OWrhdvQDD2jjNVBkLCmPLEH3ZLdgnQOZOePA7WyUdXA==', 'Y', 'supervisor', 1737355823940, 'supervisor', 1737363302083, 'config.sys.exportTableRemark'); SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file diff --git a/features/lm/file_export/controller.go b/features/lm/file_export/controller.go index 060efa65..3ec578a2 100644 --- a/features/lm/file_export/controller.go +++ b/features/lm/file_export/controller.go @@ -2,14 +2,10 @@ package file_export import ( "encoding/json" - "fmt" "net/http" "os" "path" "path/filepath" - "time" - - "github.com/jlaffaye/ftp" "be.ems/lib/file" "be.ems/lib/log" @@ -160,7 +156,7 @@ func (m *SysJob) SetFTPConfig(c *gin.Context) { Username string `json:"username" binding:"required"` ToIp string `json:"toIp" binding:"required"` ToPort int64 `json:"toPort" binding:"required"` - Protocol string `json:"protocol" binding:"required,oneof=ssh ftp"` + Enable bool `json:"enable"` Dir string `json:"dir" binding:"required"` } if err := c.ShouldBindBodyWithJSON(&body); err != nil { @@ -191,7 +187,7 @@ func (m *SysJob) SetFTPConfig(c *gin.Context) { c.JSON(200, result.Ok(nil)) } -// 设置FTP配置 +// 获取FTP配置 // GET /table/ftp func (m *SysJob) GetFTPConfig(c *gin.Context) { // 获取配置 @@ -209,7 +205,7 @@ func (m *SysJob) GetFTPConfig(c *gin.Context) { Username string `json:"username" binding:"required"` ToIp string `json:"toIp" binding:"required"` ToPort int64 `json:"toPort" binding:"required"` - Protocol string `json:"protocol" binding:"required,oneof=ssh ftp"` + Enable bool `json:"enable"` Dir string `json:"dir" binding:"required"` } err = json.Unmarshal([]byte(bodyDe), &body) @@ -251,7 +247,7 @@ func (m *SysJob) PutFTP(c *gin.Context) { Username string `json:"username" binding:"required"` ToIp string `json:"toIp" binding:"required"` ToPort int64 `json:"toPort" binding:"required"` - Protocol string `json:"protocol" binding:"required,oneof=ssh ftp"` + Enable bool `json:"enable"` Dir string `json:"dir" binding:"required"` } cfg := systemService.NewSysConfigImpl.SelectConfigByKey("sys.exportTable") @@ -269,70 +265,37 @@ func (m *SysJob) PutFTP(c *gin.Context) { return } } - - if cfgData.Protocol == "ssh" { - 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, result.ErrMsg(err.Error())) - return - } - defer sshClient.Close() - // 网元主机的SSH客户端进行文件传输 - sftpClient, err := sshClient.NewClientSFTP() - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) - return - } - defer sftpClient.Close() - // 远程文件 - remotePath := filepath.Join(cfgData.Dir, path.Base(body.FilePath), body.FileName) - // 复制到远程 - if err = sftpClient.CopyFileLocalToRemote(localFilePath, remotePath); err != nil { - c.JSON(200, result.ErrMsg("error uploading file")) - return - } - c.JSON(200, result.Ok(nil)) + if !cfgData.Enable { + c.JSON(200, result.ErrMsg("Setting Remote Backup is disabled")) return } - if cfgData.Protocol == "ftp" { - // 连接到 FTP 服务器 - addr := fmt.Sprintf("%s:%d", cfgData.ToIp, cfgData.ToPort) - ftpComm, err := ftp.Dial(addr, ftp.DialWithTimeout(15*time.Second)) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) - return - } - // 登录到 FTP 服务器 - err = ftpComm.Login(cfgData.Username, cfgData.Password) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) - return - } - defer ftpComm.Quit() - // 打开本地文件 - file, err := os.Open(localFilePath) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) - return - } - defer file.Close() - // 远程文件 - remotePath := filepath.Join(cfgData.Dir, path.Base(body.FilePath), body.FileName) - // 上传文件到 FTP 服务器 - err = ftpComm.Stor(remotePath, file) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) - return - } + connSSH := ssh.ConnSSH{ + User: cfgData.Username, + Password: cfgData.Password, + Addr: cfgData.ToIp, + Port: cfgData.ToPort, + AuthMode: "0", } - - c.JSON(200, result.Err(nil)) + sshClient, err := connSSH.NewClient() + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + defer sshClient.Close() + // 网元主机的SSH客户端进行文件传输 + sftpClient, err := sshClient.NewClientSFTP() + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + defer sftpClient.Close() + // 远程文件 + remotePath := filepath.Join(cfgData.Dir, path.Base(body.FilePath), body.FileName) + // 复制到远程 + if err = sftpClient.CopyFileLocalToRemote(localFilePath, remotePath); err != nil { + c.JSON(200, result.ErrMsg("error uploading file")) + return + } + c.JSON(200, result.Ok(nil)) } diff --git a/features/lm/file_export/route.go b/features/lm/file_export/route.go index eb3567c6..d0f618f5 100644 --- a/features/lm/file_export/route.go +++ b/features/lm/file_export/route.go @@ -17,10 +17,12 @@ func Register(r *gin.RouterGroup) { ) lmTable.POST("/ftp", middleware.PreAuthorize(nil), + middleware.CryptoApi(true, false), m.SetFTPConfig, ) lmTable.GET("/ftp", middleware.PreAuthorize(nil), + middleware.CryptoApi(false, true), m.GetFTPConfig, ) lmTable.PUT("/ftp", diff --git a/go.mod b/go.mod index 9f078861..a013be2c 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.22.0 require ( github.com/dlclark/regexp2 v1.11.4 - github.com/dustin/go-humanize v1.0.0 github.com/gin-gonic/gin v1.10.0 github.com/go-resty/resty/v2 v2.14.0 github.com/go-sql-driver/mysql v1.8.1 @@ -13,7 +12,6 @@ require ( github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.3 github.com/gosnmp/gosnmp v1.38.0 - github.com/jlaffaye/ftp v0.2.0 github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f github.com/linxGnu/gosmpp v0.3.0 github.com/matoous/go-nanoid/v2 v2.1.0 @@ -46,8 +44,6 @@ require ( ) require ( - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/go.sum b/go.sum index 364d3101..e013b378 100644 --- a/go.sum +++ b/go.sum @@ -117,11 +117,6 @@ github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gosnmp/gosnmp v1.36.2-0.20231009064202-d306ed5aa998/go.mod h1:O938QjIS4vpSag1UTcnnBq9MfNmimuOGtvQsT1NbErc= github.com/gosnmp/gosnmp v1.38.0 h1:I5ZOMR8kb0DXAFg/88ACurnuwGwYkXWq3eLpJPHMEYc= github.com/gosnmp/gosnmp v1.38.0/go.mod h1:FE+PEZvKrFz9afP9ii1W3cprXuVZ17ypCcyyfYuu5LY= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -131,8 +126,6 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jlaffaye/ftp v0.2.0 h1:lXNvW7cBu7R/68bknOX3MrRIIqZ61zELs1P2RAiA3lg= -github.com/jlaffaye/ftp v0.2.0/go.mod h1:is2Ds5qkhceAPy2xD6RLI6hmp/qysSoymZ+Z2uTnspI= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= diff --git a/lib/file/file_linux.go b/lib/file/file_linux.go index 4d934618..e8936bb9 100644 --- a/lib/file/file_linux.go +++ b/lib/file/file_linux.go @@ -8,21 +8,19 @@ import ( "os" "os/user" "path/filepath" - "strings" "syscall" - - "github.com/dustin/go-humanize" ) type FileInfo struct { - FileType string `json:"fileType"` // 文件类型 - FileMode string `json:"fileMode"` // 文件的权限 - LinkCount int64 `json:"linkCount"` // 硬链接数目 - Owner string `json:"owner"` // 所属用户 - Group string `json:"group"` // 所属组 - Size string `json:"size"` // 文件的大小 - ModifiedTime int64 `json:"modifiedTime"` // 最后修改时间,单位为秒 - FileName string `json:"fileName"` // 文件的名称 + FileType string `json:"fileType"` // file type: file/directory + FileMode string `json:"fileMode"` // file mode + LinkCount int64 `json:"linkCount"` // link count + Owner string `json:"owner"` // owner + Group string `json:"group"` // group + Size int64 `json:"size"` // size: xx byte + ModifiedTime int64 `json:"modifiedTime"` // last modified time:seconds + FilePath string `json:"filePath"` // file path + FileName string `json:"fileName"` // file name } func GetFileInfo(dir, suffix string) ([]FileInfo, error) { @@ -58,15 +56,15 @@ func GetFileInfo(dir, suffix string) ([]FileInfo, error) { if err != nil { return err } - humanReadableSize := humanize.Bytes(uint64(info.Size())) fileInfo := FileInfo{ FileType: fileType, FileMode: info.Mode().String(), LinkCount: int64(info.Sys().(*syscall.Stat_t).Nlink), Owner: userInfo.Username, Group: groupInfo.Name, - Size: strings.ToUpper(humanReadableSize), + Size: info.Size(), ModifiedTime: info.ModTime().Unix(), + FilePath: dir, FileName: info.Name(), } files = append(files, fileInfo) diff --git a/src/modules/crontask/processor/exportTable/exportTable.go b/src/modules/crontask/processor/exportTable/exportTable.go index 9f407c61..10eded08 100644 --- a/src/modules/crontask/processor/exportTable/exportTable.go +++ b/src/modules/crontask/processor/exportTable/exportTable.go @@ -18,7 +18,6 @@ import ( "be.ems/src/framework/utils/crypto" "be.ems/src/framework/utils/ssh" systemService "be.ems/src/modules/system/service" - "github.com/jlaffaye/ftp" ) var NewProcessor = &BarProcessor{ @@ -177,7 +176,7 @@ func (s BarProcessor) putFTP(filePath, fileName string) { Username string `json:"username" binding:"required"` ToIp string `json:"toIp" binding:"required"` ToPort int64 `json:"toPort" binding:"required"` - Protocol string `json:"protocol" binding:"required,oneof=ssh ftp"` + Enable bool `json:"enable"` Dir string `json:"dir" binding:"required"` } cfg := systemService.NewSysConfigImpl.SelectConfigByKey("sys.exportTable") @@ -195,68 +194,37 @@ func (s BarProcessor) putFTP(filePath, fileName string) { return } } + if !cfgData.Enable { + return + } localFilePath := filepath.Join(filePath, fileName) - if cfgData.Protocol == "ssh" { - connSSH := ssh.ConnSSH{ - User: cfgData.Username, - Password: cfgData.Password, - Addr: cfgData.ToIp, - Port: cfgData.ToPort, - AuthMode: "0", - } - sshClient, err := connSSH.NewClient() - if err != nil { - logger.Errorf("putFTP ssh error: %v", err) - return - } - defer sshClient.Close() - // 网元主机的SSH客户端进行文件传输 - sftpClient, err := sshClient.NewClientSFTP() - if err != nil { - logger.Errorf("putFTP sftp error: %v", err) - return - } - defer sftpClient.Close() - // 远程文件 - remotePath := filepath.Join(cfgData.Dir, path.Base(filePath), fileName) - // 复制到远程 - if err = sftpClient.CopyFileLocalToRemote(localFilePath, remotePath); err != nil { - logger.Errorf("putFTP uploading error: %v", err) - return - } + connSSH := ssh.ConnSSH{ + User: cfgData.Username, + Password: cfgData.Password, + Addr: cfgData.ToIp, + Port: cfgData.ToPort, + AuthMode: "0", } - - if cfgData.Protocol == "ftp" { - // 连接到 FTP 服务器 - addr := fmt.Sprintf("%s:%d", cfgData.ToIp, cfgData.ToPort) - ftpComm, err := ftp.Dial(addr, ftp.DialWithTimeout(15*time.Second)) - if err != nil { - logger.Errorf("putFTP ftp error: %v", err) - return - } - // 登录到 FTP 服务器 - err = ftpComm.Login(cfgData.Username, cfgData.Password) - if err != nil { - logger.Errorf("putFTP login error: %v", err) - return - } - defer ftpComm.Quit() - // 打开本地文件 - file, err := os.Open(localFilePath) - if err != nil { - logger.Errorf("putFTP open error: %v", err) - return - } - defer file.Close() - // 远程文件 - remotePath := filepath.Join(cfgData.Dir, path.Base(filePath), fileName) - // 上传文件到 FTP 服务器 - err = ftpComm.Stor(remotePath, file) - if err != nil { - logger.Errorf("putFTP uploading error: %v", err) - return - } + sshClient, err := connSSH.NewClient() + if err != nil { + logger.Errorf("putFTP ssh error: %v", err) + return + } + defer sshClient.Close() + // 网元主机的SSH客户端进行文件传输 + sftpClient, err := sshClient.NewClientSFTP() + if err != nil { + logger.Errorf("putFTP sftp error: %v", err) + return + } + defer sftpClient.Close() + // 远程文件 + remotePath := filepath.Join(cfgData.Dir, path.Base(filePath), fileName) + // 复制到远程 + if err = sftpClient.CopyFileLocalToRemote(localFilePath, remotePath); err != nil { + logger.Errorf("putFTP uploading error: %v", err) + return } }