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

其他

参考

相关推荐
程序猿编码1 小时前
工业视觉多任务方案:可编程梯度信息视觉框架,训练评估 + C++ 部署完整实战
开发语言·c++·视觉·推理引擎
言乐62 小时前
Python实现语音审核模型
开发语言·python·django·virtualenv·pygame
朝朝辞暮i2 小时前
C++ 第 21 课:struct —— 把一组相关数据打包在一起
开发语言·c++·算法
SHARK_pssm3 小时前
【C++——类和对象(下)】
开发语言·c++·经验分享·笔记
凯哥Java3 小时前
写代码怎么避免逻辑漏洞?
java·开发语言·人工智能·自动化
Ai-_Man4 小时前
您您这可以把Dola的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。用AI导出鸭,答案是可以的
开发语言·前端·人工智能·小程序
Java后端的Ai之路4 小时前
Python进阶探索23 - Python中的Time与Datetime模块
开发语言·数据库·python·datetime·time
海宇服务4 小时前
零信任架构实战:基于海宇运营商近3个月欠费次数构建自动化履约能力评估管线
运维·人工智能·架构·自动化
沫璃染墨4 小时前
《从零入门Linux系统篇(五十四):线程篇·七——互斥锁底层原理:从原子交换到线程竞争与锁实现》
linux·运维·服务器·开发语言·c++·驱动开发·系统架构
志栋智能4 小时前
超自动化巡检中的异常检测与根因分析
运维·自动化