简介
基于上篇 Golang实现一个批量自动化执行树莓派指令的软件(4)上传 已经实现了ssh的基本操作模块了,这里我们将这些模块进行整合。
环境描述
运行环境 : Windows, 基于Golang, 暂时没有使用什么不可跨平台接口, 理论上支持Linux/MacOS
目标终端:树莓派DebianOS(主要做用它测试)
实现
接口定义
go
/* SFTPClient接口,整合Downloader和Uploader */
type ISFTPClient interface {
IDownloader
IUploader
Cancel() error
Destroy() error
}
/* 整合所有ssh的基本操作模块 */
type ISSHUtil interface {
Commander() ICommander
SFTFClient() ISFTPClient
Cancel() error
Destroy() error
}
接口实现
sftpclient.go
go
package sshutil
import (
"fmt"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
)
type SFTPClient struct {
IDownloader
IUploader
sftpClient *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 = nil
return
}
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 = nil
return
}
sshutil.go
go
package sshutil
import (
"fmt"
"golang.org/x/crypto/ssh"
"net"
"time"
)
type SSHUtil struct {
commander *Commander
sftpClient *SFTPClient
cfg SSHConfig
}
func NewSSHUtil(cfg SSHConfig) (*SSHUtil, error) {
var (
sshUtil = &SSHUtil{}
err error
)
sshUtil.cfg = cfg
sshUtil.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 = nil
return
}
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 = nil
return
}
测试用例
代码源
https://gitee.com/grayhsu/ssh_remote_access