简介
基于上篇 Golang实现一个批量自动化执行树莓派指令的软件(4)上传 已经实现了ssh的基本操作模块了,这里我们将这些模块进行整合。
环境描述
运行环境: Windows, 基于Golang, 暂时没有使用什么不可跨平台接口, 理论上支持Linux/MacOS
目标终端:树莓派DebianOS(主要做用它测试)
实现
接口定义
/* SFTPClient接口,整合Downloader和Uploader */
type ISFTPClient interface {IDownloaderIUploaderCancel() errorDestroy() error
}/* 整合所有ssh的基本操作模块 */
type ISSHUtil interface {Commander() ICommanderSFTFClient() ISFTPClientCancel() errorDestroy() error
}
接口实现
sftpclient.go
package sshutilimport ("fmt""github.com/pkg/sftp""golang.org/x/crypto/ssh"
)type SFTPClient struct {IDownloaderIUploadersftpClient *sftp.Client
}func NewSFTPClient(sshClient *ssh.Client) (*SFTPClient, error) {var (sftpClient = &SFTPClient{}err error)sftpClient.sftpClient, err = sftp.NewClient(sshClient)if nil != err {return nil, err}if sftpClient.IDownloader, err = newDownloader(sftpClient.sftpClient); nil != err {sftpClient.Destroy()return nil, err}if sftpClient.IUploader, err = newUploader(sftpClient.sftpClient); nil != err {sftpClient.Destroy()return nil, err}return sftpClient, nil
}func (s *SFTPClient) Cancel() (err error) {if nil != s.IDownloader {if err = s.IDownloader.(*downloader).Cancel(); nil != err {fmt.Println("downloader cancel fail, ", err.Error())}}if nil != s.IUploader {if err = s.IUploader.(*uploader).Cancel(); nil != err {fmt.Println("uploader cancel fail, ", err.Error())}}err = nilreturn
}func (s *SFTPClient) Destroy() (err error) {if nil != s.IDownloader {if err = s.IDownloader.(*downloader).Destroy(); nil != err {fmt.Println("downloader cancel fail, ", err.Error())}s.IDownloader = nil}if nil != s.IUploader {if err = s.IUploader.(*uploader).Destroy(); nil != err {fmt.Println("uploader destroy fail, ", err.Error())}s.IUploader = nil}if nil != s.sftpClient {if err = s.sftpClient.Close(); nil != err {fmt.Println("sftp client destroy fail, ", err.Error())}s.sftpClient = nil}err = nilreturn
}
sshutil.go
package sshutilimport ("fmt""golang.org/x/crypto/ssh""net""time"
)type SSHUtil struct {commander *CommandersftpClient *SFTPClientcfg SSHConfig
}func NewSSHUtil(cfg SSHConfig) (*SSHUtil, error) {var (sshUtil = &SSHUtil{}err error)sshUtil.cfg = cfgsshUtil.cfg.sshClientConfig = &ssh.ClientConfig{User: cfg.User,Auth: []ssh.AuthMethod{ssh.Password(cfg.Password)}, // 密码HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {return nil},Timeout: time.Duration(cfg.Timeout) * time.Second,}sshUtil.commander, err = NewCommander(sshUtil.cfg)if nil != err {sshUtil.Destroy()return nil, err}sshUtil.sftpClient, err = NewSFTPClient(sshUtil.commander.sshClient)if nil != err {sshUtil.Destroy()return nil, err}return sshUtil, err
}func (s *SSHUtil) Commander() ICommander {return s.commander
}func (s *SSHUtil) SFTFClient() ISFTPClient {return s.sftpClient
}func (s *SSHUtil) Cancel() (err error) {if nil != s.commander {if err = s.commander.Cancel(); nil != err {fmt.Println("commander cancel fail, ", err.Error())}}if nil != s.sftpClient {if err = s.sftpClient.Cancel(); nil != err {fmt.Println("sftp client cancel fail, ", err.Error())}}err = nilreturn
}func (s *SSHUtil) Destroy() (err error) {if nil != s.sftpClient {if err = s.sftpClient.Destroy(); nil != err {fmt.Println("sftp client destroy fail, ", err.Error())}s.sftpClient = nil}if nil != s.commander {if err = s.commander.Destroy(); nil != err {fmt.Println("commander destroy fail, ", err.Error())}s.commander = nil}err = nilreturn
}
测试用例
代码源
https://gitee.com/grayhsu/ssh_remote_access