sshpool

package module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2021 License: MIT Imports: 10 Imported by: 5

README

sshpool

Connection pool for x/crypto/ssh connections

API docs: https://pkg.go.dev/github.com/desops/sshpool

This is a connection pooler for golang.org/x/crypto/ssh. It's good for making hundreds (or thousands) of SSH connections to do a lot of things on a lot of hosts.

The pool itself has no configuration apart from a ClientConfig:

package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/desops/sshpool"
	"golang.org/x/crypto/ssh"
)

func main() {
	if err := run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func run() error {
	buf, err := ioutil.ReadFile("./keys/my_private_ssh_key")
	if err != nil {
		return err
	}

	key, err := ssh.ParsePrivateKey(buf)
	if err != nil {
		return err
	}

	config := &ssh.ClientConfig{
		User: "myuser",
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(key),
		},
	}

	pool := sshpool.New(config, nil)

	for i := 0; i < 100; i++ {
		go func() {
			err := func() error {
				session, err := pool.Get("myhost")
				if err != nil {
					return err
				}
				defer session.Put() // important: this returns it to the pool

				session.Stdout = os.Stdout
				session.Stderr = os.Stderr

				if err := session.Run("sleep 10"); err != nil {
					ee, ok := err.(*ssh.ExitError)
					if ok {
						return fmt.Errorf("remote command exit status %d", ee.ExitStatus())
					}
					return err
				}
				return nil
			}
			if err != nil {
				fmt.Fprintln(os.Stderr, err)
			}
		}()
	}

	return nil
}

Documentation

Index

Constants

View Source
const (
	// DefaultMaxSessions is set to the default /etc/ssh/sshd_config value.
	// Most servers have not set MaxSessions, so they get the default limit of 10.
	DefaultMaxSessions = 10

	// DefaultMaxConnections is a bit arbitrary. It's a tradeoff between how long
	// you wait for dials, and how long you wait for concurrent operations to finish.
	DefaultMaxConnections = 10

	// DefaultSessionCloseDelay was found by testing. 10ms was ALMOST enough. (3 / 1000 would fail)
	DefaultSessionCloseDelay = time.Millisecond * 20
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

func New

func New(config *ssh.ClientConfig, poolconfig *PoolConfig) *Pool

func (*Pool) Close

func (p *Pool) Close()

func (*Pool) ExecCombinedOutput

func (p *Pool) ExecCombinedOutput(host string, command string) ([]byte, error)

func (*Pool) ExecCombinedOutputString

func (p *Pool) ExecCombinedOutputString(host string, command string) (string, error)

func (*Pool) ExecOutput

func (p *Pool) ExecOutput(host string, command string) ([]byte, error)

func (*Pool) ExecOutputString

func (p *Pool) ExecOutputString(host string, command string) (string, error)

func (*Pool) Get

func (p *Pool) Get(host string) (*Session, error)

Get() creates a session to a specific host. If successful, err will be nil and you must call Put() on the returned *ssh.Session to ensure cleanup. If the host connection already has MaxSessions sessions and MaxConnections is met, Get() will block until another connection somewhere calls Put().

func (*Pool) GetSFTP added in v0.0.6

func (p *Pool) GetSFTP(host string) (*SFTPSession, error)

func (*Pool) Tunnel

func (p *Pool) Tunnel(host string, local, remote string) (*Tunnel, error)

Tunnel() creates an SSH tunnel to host. A local TCP socket will listen on local. Any connections will be proxied to remote via host. Be sure to call Close() to clean up.

type PoolConfig

type PoolConfig struct {
	Debug bool

	// MaxSessions defines the maximum sessions per-connection. If left at 0,
	// DefaultMaxSessions is used.
	MaxSessions int

	// MaxConnections limits the number of connections to the same host. If
	// left at 0, DefaultMaxConnections is used. (Note each connection can have up to
	// MaxSessions concurrent things happening on it.) Setting this to 1 is not
	// a bad idea if you want to be gentle to your servers.
	MaxConnections int

	// SSH seems to take a moment to actually clean up a session after you close
	// it. This delay seems to prevent "no more sessions" errors from happening
	// by giving a very slight delay after closing but before allowing another
	// connection. If 0, DefaultSessionCloseDelay is used.
	SessionCloseDelay time.Duration
}

type SFTPSession added in v0.0.6

type SFTPSession struct {
	*sftp.Client
	// contains filtered or unexported fields
}

func (*SFTPSession) Put added in v0.0.6

func (s *SFTPSession) Put()

func (*SFTPSession) String added in v0.0.8

func (s *SFTPSession) String() string

type Session

type Session struct {
	*ssh.Session
	// contains filtered or unexported fields
}

func (*Session) Put added in v0.0.2

func (s *Session) Put()

func (*Session) String added in v0.0.8

func (s *Session) String() string

type Tunnel

type Tunnel struct {
	// contains filtered or unexported fields
}

func (*Tunnel) Addr

func (tunnel *Tunnel) Addr() string

func (*Tunnel) Close

func (tunnel *Tunnel) Close() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL