Golang实现一个批量自动化执行树莓派指令的软件(5)模块整合

简介

基于上篇 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

其他

参考

相关推荐
就改了2 分钟前
JUC小册——公平锁和非公平锁
java·开发语言
真智AI37 分钟前
AI智能体时代来临:数据分析的变革与自动化之路
人工智能·数据分析·自动化
一粒沙白猫42 分钟前
Java综合练习04
java·开发语言·算法
哎呦你好1 小时前
【CSS】Grid 布局基础知识及实例展示
开发语言·前端·css·css3
一入JAVA毁终身1 小时前
处理Lombok的一个小BUG
java·开发语言·bug
Hellyc1 小时前
JAVA八股文:异常有哪些种类,可以举几个例子吗?Throwable类有哪些常见方法?
java·开发语言
电脑能手1 小时前
遇到该问题:kex_exchange_identification: read: Connection reset`的解决办法
linux·ubuntu·ssh
2301_803554522 小时前
c++中的绑定器
开发语言·c++·算法
海棠蚀omo2 小时前
C++笔记-位图和布隆过滤器
开发语言·c++·笔记
杰哥技术分享2 小时前
Yii2 安装-yii2-imagine
开发语言·yii