package
package sshplus
import (
"fmt"
"golang.org/x/crypto/ssh"
"io/ioutil"
)
func NewConfig(keyFile, user string) (config *ssh.ClientConfig, err error) {
key, err := ioutil.ReadFile(keyFile)
if err != nil {
err = fmt.Errorf("unable to read private key: %v", err)
return
}
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
err = fmt.Errorf("unable to parse private key: %v", err)
return
}
config = &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
return
}
func Run(config *ssh.ClientConfig, host, command string, port int) (outPut []byte, err error) {
client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", host, port), config)
if err != nil {
err = fmt.Errorf("unable to connect: %s error %v", host, err)
return
}
defer client.Close()
session, err := client.NewSession()
if err != nil{
err = fmt.Errorf("ssh new session error %v", err)
return
}
defer session.Close()
outPut, err = session.Output(command)
if err != nil{
err = fmt.Errorf("run command %s on host %s error %v", command, host, err)
}
return
}
测试
package sshplus
import (
"golang.org/x/crypto/ssh"
"reflect"
"testing"
)
func TestRun(t *testing.T) {
type args struct {
config *ssh.ClientConfig
host string
command string
port int
}
config, _ := NewConfig("/home/whz/.ssh/id_rsa", "whz")
tests := []struct {
name string
args args
wantOutPut []byte
wantErr bool
}{
{
name: "test1",
args: args{
config: config,
host: "127.0.0.1",
command: "ls $HOME/tmp/a.go",
port: 22,
},
wantOutPut: []byte("/home/whz/tmp/a.go\n"),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotOutPut, err := Run(tt.args.config, tt.args.host, tt.args.command, tt.args.port)
if (err != nil) != tt.wantErr {
t.Errorf("Run() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotOutPut, tt.wantOutPut) {
t.Errorf("Run() = %v, want %v", gotOutPut, tt.wantOutPut)
}
})
}
}