Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "os"
- "strings"
- "golang.org/x/crypto/ssh"
- "golang.org/x/crypto/ssh/agent"
- )
- type SSHCommand struct {
- Path string
- Env []string
- Stdin io.Reader
- Stdout io.Writer
- Stderr io.Writer
- }
- type SSHClient struct {
- Config *ssh.ClientConfig
- Host string
- Port int
- }
- func (client *SSHClient) RunCommand(cmd *SSHCommand) error {
- var (
- session *ssh.Session
- err error
- )
- if session, err = client.newSession(); err != nil {
- return err
- }
- defer session.Close()
- if err = client.prepareCommand(session, cmd); err != nil {
- return err
- }
- err = session.Run(cmd.Path)
- return err
- }
- func (client *SSHClient) prepareCommand(session *ssh.Session, cmd *SSHCommand) error {
- for _, env := range cmd.Env {
- variable := strings.Split(env, "=")
- if len(variable) != 2 {
- continue
- }
- if err := session.Setenv(variable[0], variable[1]); err != nil {
- return err
- }
- }
- if cmd.Stdin != nil {
- stdin, err := session.StdinPipe()
- if err != nil {
- return fmt.Errorf("Unable to setup stdin for session: %v", err)
- }
- go io.Copy(stdin, cmd.Stdin)
- }
- if cmd.Stdout != nil {
- stdout, err := session.StdoutPipe()
- if err != nil {
- return fmt.Errorf("Unable to setup stdout for session: %v", err)
- }
- go io.Copy(cmd.Stdout, stdout)
- }
- if cmd.Stderr != nil {
- stderr, err := session.StderrPipe()
- if err != nil {
- return fmt.Errorf("Unable to setup stderr for session: %v", err)
- }
- go io.Copy(cmd.Stderr, stderr)
- }
- return nil
- }
- func (client *SSHClient) newSession() (*ssh.Session, error) {
- connection, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", client.Host, client.Port), client.Config)
- if err != nil {
- return nil, fmt.Errorf("Failed to dial: %s", err)
- }
- session, err := connection.NewSession()
- if err != nil {
- return nil, fmt.Errorf("Failed to create session: %s", err)
- }
- modes := ssh.TerminalModes{
- // ssh.ECHO: 0, // disable echoing
- ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
- ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
- }
- if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
- session.Close()
- return nil, fmt.Errorf("request for pseudo terminal failed: %s", err)
- }
- return session, nil
- }
- func PublicKeyFile(file string) ssh.AuthMethod {
- buffer, err := ioutil.ReadFile(file)
- if err != nil {
- return nil
- }
- key, err := ssh.ParsePrivateKey(buffer)
- if err != nil {
- return nil
- }
- return ssh.PublicKeys(key)
- }
- func SSHAgent() ssh.AuthMethod {
- if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
- return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)
- }
- return nil
- }
- func main() {
- // ssh.Password("your_password")
- sshConfig := &ssh.ClientConfig{
- User: "jsmith",
- Auth: []ssh.AuthMethod{
- SSHAgent(),
- },
- }
- client := &SSHClient{
- Config: sshConfig,
- Host: "example.com",
- Port: 22,
- }
- cmd := &SSHCommand{
- Path: "ls -l $LC_DIR",
- Env: []string{"LC_DIR=/"},
- Stdin: os.Stdin,
- Stdout: os.Stdout,
- Stderr: os.Stderr,
- }
- fmt.Printf("Running command: %s\n", cmd.Path)
- if err := client.RunCommand(cmd); err != nil {
- fmt.Fprintf(os.Stderr, "command run error: %s\n", err)
- os.Exit(1)
- }
- }
Add Comment
Please, Sign In to add comment