socker

package module
v0.0.0-...-cd193be Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2020 License: MIT Imports: 18 Imported by: 0

README

Socker

Socker is a library for Go to simplify the use of SSH, support keepalive and multiplexing. Inspired by Fabric for Python.

Documentation

Documentation can be found at Godoc

Example

var sshConfig = (&Auth{User: "root", Password: "root"}).MustSSHConfig()

func TestGate(t *testing.T) {
	gate, err := Dial("10.0.1.1", sshConfig)
	if err != nil {
		t.Error("dial agent failed:", err)
	}
	defer gate.Close()

	testSSH(t, gate)
}

func TestSSH(t *testing.T) {
	testSSH(t, nil)
}

func testSSH(t *testing.T, gate *SSH) {
	agent, err := Dial("192.168.1.1", sshConfig, gate)
	if err != nil {
		t.Error("dial agent failed:", err)
	}
	defer agent.Close()

	testAgent(t, agent)
}

func testAgent(t *testing.T, agent *SSH) {
	agent.Rcmd("ls -al ~/")
	agent.Put("~/local", "~/remote")
	agent.Get("~/remote", "~/local")

	agent.RcmdBg("sleep 30", "sleep.out", "sleep.err")

	t.Log(string(agent.Output()))
	err := agent.Error()
	if err != nil {
		t.Error(err)
	}
}

func TestMux(t *testing.T) {
	var (
		netFoo  = "netFoo"
		gateFoo = "10.0.1.1"
		authFoo = &Auth{User: "foo", Password: "foo"}
		netBar  = "netBar"
		authBar = &Auth{User: "bar", Password: "bar"}
		gateBar = "10.0.2.1"
	)

	auth := MuxAuth{
		AuthMethods: map[string]*Auth{
			netFoo: authFoo,
			netBar: authBar,
		},

		DefaultAuth: netFoo,
		AgentGates: map[string]string{
			"ipnet:192.168.1.0/24": gateFoo + ":22",
			"ipnet:192.168.2.0/24": gateBar + ":22",
		},
		AgentAuths: map[string]string{
			"plain:" + gateFoo:     netFoo,
			"ipnet:192.168.1.0/24": netFoo,
			"plain:" + gateBar:     netBar,
			"ipnet:192.168.2.0/24": netBar,
		},
		KeepAliveSeconds: 30,
	}

	mux, err := NewMux(auth)
	if err != nil {
		t.Fatal(err)
	}

	type testCase struct {
		Addr  string
		Gate  string
		Auth  *Auth
		Error error
	}
	cases := []testCase{
		{Addr: gateFoo, Gate: "", Auth: authFoo},
		{Addr: "192.168.1.1", Gate: gateFoo, Auth: authFoo},
		{Addr: "192.168.1.255", Gate: gateFoo, Auth: authFoo},

		{Addr: gateBar, Gate: "", Auth: authBar},
		{Addr: "192.168.2.1", Gate: gateBar, Auth: authBar},
		{Addr: "192.168.2.255", Gate: gateBar, Auth: authBar},

		{Addr: "192.168.3.1", Gate: "", Auth: authFoo, Error: nil},
	}

	for _, c := range cases {
		if got := mux.AgentGate(c.Addr); got != c.Gate {
			t.Errorf("gate match failed %s: expect %s, got %s", c.Addr, c.Gate, got)
		}
		got, gotError := mux.AgentAuth(c.Addr)
		if got != c.Auth {
			t.Errorf("auth match failed %s", c.Addr)
		}
		if gotError != c.Error {
			t.Errorf("auth error match failed %s: expect %v, got %v", c.Addr, c.Error, gotError)
		}
	}
	defer mux.Close()

	var wg sync.WaitGroup
	for _, addr := range []string{"192.168.1.2:22", "192.168.2.2:22"} {
		agent, err := mux.Dial(addr)
		if err != nil {
			t.Error("dial agent failed:", err)
			break
		}

		wg.Add(1)
		go func() {
			defer agent.Close()
			defer wg.Done()

			testAgent(t, agent)
		}()
	}

	wg.Wait()
}

LICENSE

MIT.

Documentation

Index

Constants

View Source
const (
	RulePlain  = "plain"
	RuleRegexp = "regexp"
	RuleIpnet  = "ipnet"
)

Variables

View Source
var (
	ErrIsDir = errors.New("destination is directory")

	CopyBufferSize int64 = 1024 * 1024
	CmdSeperator         = "&&" // or ;
)
View Source
var (
	ErrMuxClosed    = errors.New("mux has been closed")
	ErrNoAuthMethod = errors.New("no auth method can be applied to agent")
)
View Source
var ErrConnClosed = errors.New("connection closed")

Functions

func JoinRuleAndAddr

func JoinRuleAndAddr(rule, addr string) string

func RegisterMatchRule

func RegisterMatchRule(name string, rule MatchRule, priority int) (replaced bool)

func ResetRulePriority

func ResetRulePriority(name string, priority int)

func SplitRuleAndAddr

func SplitRuleAndAddr(s string) (rule, addr string)

Types

type Auth

type Auth struct {
	User           string
	Password       string
	PrivateKey     string
	PrivateKeyFile string

	HostKeyCheck ssh.HostKeyCallback

	TimeoutMs  int
	MaxSession int
	// contains filtered or unexported fields
}

func (*Auth) MustSSHConfig

func (a *Auth) MustSSHConfig() *ssh.ClientConfig

func (*Auth) SSHConfig

func (a *Auth) SSHConfig() (*ssh.ClientConfig, error)

type File

type File interface {
	io.Closer
	Chmod(mode os.FileMode) error
	Chown(uid, gid int) error
	Name() string
	Read(b []byte) (n int, err error)
	Readdir(n int) ([]os.FileInfo, error)
	Readdirnames(n int) (names []string, err error)
	Seek(offset int64, whence int) (ret int64, err error)
	Stat() (os.FileInfo, error)
	Truncate(size int64) error
	Write(b []byte) (n int, err error)
	WriteString(s string) (n int, err error)
}

File is the abstract interface for local and sftp file

type Filepath

type Filepath interface {
	Separator() uint8
	ListSeparator() uint8
	IsPathSeparator(c uint8) bool
	Clean(path string) string
	ToSlash(path string) string
	FromSlash(path string) string
	SplitList(path string) []string
	Split(path string) (dir, file string)
	Join(elem ...string) string
	Ext(path string) string
	Rel(basepath, targpath string) (string, error)
	Base(path string) string
	Dir(path string) string
	VolumeName(path string) string
	IsAbs(path string) bool
}

type Fs

type Fs interface {
	Filepath() Filepath

	Chmod(name string, mode os.FileMode) error
	Chown(name string, uid, gid int) error
	Chtimes(name string, atime time.Time, mtime time.Time) error

	IsExist(err error) bool
	IsNotExist(err error) bool

	IsPermission(err error) bool
	Mkdir(name string, perm os.FileMode) error
	MkdirAll(path string, perm os.FileMode) error
	Readlink(name string) (string, error)
	Remove(name string) error
	RemoveAll(path string) error
	Rename(oldpath, newpath string) error
	SameFile(fi1, fi2 os.FileInfo) bool
	Symlink(oldname, newname string) error
	Truncate(name string, size int64) error

	Create(name string) (File, error)
	Open(name string) (File, error)
	OpenFile(name string, flag int, perm os.FileMode) (File, error)

	Lstat(name string) (os.FileInfo, error)
	Stat(name string) (os.FileInfo, error)

	io.Closer
}

Fs is the abstract interface for local and sftp filesystem

func NewFsSftp

func NewFsSftp(sftp *sftp.Client) Fs

type FsLocal

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

FsLocal is the wrapper for package os

func (FsLocal) Base

func (FsLocal) Base(path string) string

func (FsLocal) Chmod

func (FsLocal) Chmod(name string, mode os.FileMode) error

func (FsLocal) Chown

func (FsLocal) Chown(name string, uid, gid int) error

func (FsLocal) Chtimes

func (FsLocal) Chtimes(name string, atime time.Time, mtime time.Time) error

func (FsLocal) Clean

func (FsLocal) Clean(path string) string

func (FsLocal) Close

func (FsLocal) Close() error

func (FsLocal) Create

func (FsLocal) Create(name string) (File, error)

func (FsLocal) Dir

func (FsLocal) Dir(path string) string

func (FsLocal) Ext

func (FsLocal) Ext(path string) string

func (FsLocal) Filepath

func (f FsLocal) Filepath() Filepath

func (FsLocal) FromSlash

func (FsLocal) FromSlash(path string) string

func (FsLocal) Getwd

func (FsLocal) Getwd() (dir string, err error)

func (FsLocal) IsAbs

func (FsLocal) IsAbs(path string) bool

func (FsLocal) IsExist

func (FsLocal) IsExist(err error) bool

func (FsLocal) IsNotExist

func (FsLocal) IsNotExist(err error) bool

func (FsLocal) IsPathSeparator

func (FsLocal) IsPathSeparator(c uint8) bool

func (FsLocal) IsPermission

func (FsLocal) IsPermission(err error) bool

func (FsLocal) Join

func (FsLocal) Join(elem ...string) string

func (FsLocal) ListSeparator

func (FsLocal) ListSeparator() uint8

func (FsLocal) Lstat

func (FsLocal) Lstat(name string) (os.FileInfo, error)

func (FsLocal) Mkdir

func (FsLocal) Mkdir(name string, perm os.FileMode) error

func (FsLocal) MkdirAll

func (FsLocal) MkdirAll(path string, perm os.FileMode) error

func (FsLocal) Open

func (FsLocal) Open(name string) (File, error)

func (FsLocal) OpenFile

func (FsLocal) OpenFile(name string, flag int, perm os.FileMode) (File, error)
func (FsLocal) Readlink(name string) (string, error)

func (FsLocal) Rel

func (FsLocal) Rel(basepath, targpath string) (string, error)

func (FsLocal) Remove

func (FsLocal) Remove(name string) error

func (FsLocal) RemoveAll

func (FsLocal) RemoveAll(path string) error

func (FsLocal) Rename

func (FsLocal) Rename(oldpath, newpath string) error

func (FsLocal) SameFile

func (FsLocal) SameFile(fi1, fi2 os.FileInfo) bool

func (FsLocal) Separator

func (FsLocal) Separator() uint8

func (FsLocal) Split

func (FsLocal) Split(path string) (dir, file string)

func (FsLocal) SplitList

func (FsLocal) SplitList(path string) []string

func (FsLocal) Stat

func (FsLocal) Stat(name string) (os.FileInfo, error)
func (FsLocal) Symlink(oldname, newname string) error

func (FsLocal) ToSlash

func (FsLocal) ToSlash(path string) string

func (FsLocal) Truncate

func (FsLocal) Truncate(name string, size int64) error

func (FsLocal) VolumeName

func (FsLocal) VolumeName(path string) string

type FsSftp

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

func (FsSftp) Chmod

func (s FsSftp) Chmod(name string, mode os.FileMode) error

func (FsSftp) Chown

func (s FsSftp) Chown(name string, uid, gid int) error

func (FsSftp) Chtimes

func (s FsSftp) Chtimes(name string, atime time.Time, mtime time.Time) error

func (FsSftp) Close

func (s FsSftp) Close() error

func (FsSftp) Create

func (s FsSftp) Create(name string) (File, error)

func (FsSftp) Filepath

func (s FsSftp) Filepath() Filepath

func (FsSftp) Getwd

func (s FsSftp) Getwd() (dir string, err error)

func (FsSftp) IsExist

func (s FsSftp) IsExist(err error) bool

func (FsSftp) IsNotExist

func (s FsSftp) IsNotExist(err error) bool

func (FsSftp) IsPermission

func (s FsSftp) IsPermission(err error) bool

func (FsSftp) Lstat

func (s FsSftp) Lstat(name string) (os.FileInfo, error)

func (FsSftp) Mkdir

func (s FsSftp) Mkdir(name string, perm os.FileMode) error

func (FsSftp) MkdirAll

func (s FsSftp) MkdirAll(path string, perm os.FileMode) error

func (FsSftp) Open

func (s FsSftp) Open(name string) (File, error)

func (FsSftp) OpenFile

func (s FsSftp) OpenFile(name string, flag int, perm os.FileMode) (File, error)
func (s FsSftp) Readlink(name string) (string, error)

func (FsSftp) Remove

func (s FsSftp) Remove(name string) error

func (FsSftp) RemoveAll

func (s FsSftp) RemoveAll(path string) error

func (FsSftp) Rename

func (s FsSftp) Rename(oldpath, newpath string) error

func (FsSftp) SameFile

func (s FsSftp) SameFile(fi1, fi2 os.FileInfo) bool

func (FsSftp) Stat

func (s FsSftp) Stat(name string) (os.FileInfo, error)
func (s FsSftp) Symlink(oldname, newname string) error

func (FsSftp) Truncate

func (s FsSftp) Truncate(name string, size int64) error

type MatchRule

type MatchRule func(string) (Matcher, error)

type Matcher

type Matcher func(addr string) bool

type Mux

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

func NewMux

func NewMux(auth MuxAuth) (*Mux, error)

func (*Mux) AgentAuth

func (m *Mux) AgentAuth(addr string) (*Auth, error)

func (*Mux) AgentGate

func (m *Mux) AgentGate(addr string) string

func (*Mux) Close

func (m *Mux) Close() error

func (*Mux) Dial

func (m *Mux) Dial(addr string) (*SSH, error)

type MuxAuth

type MuxAuth struct {
	// AuthMethods holds all auth methods to destination host. The key can be any
	// string.
	AuthMethods map[string]*Auth

	// DefaultAuth is the default auth method, it must be a key in AuthMethods field,
	// only used if no auth method is matched for destination, can be empty.
	DefaultAuth string
	// AgentAuths define the rule which auth method is used to connect to destination host.
	// The key is the format of "matcher:matchor", the value must be a key in
	// AuthMethods field.
	AgentAuths map[string]string
	// AgentGates define the rule which gate is used to connect to destination host.
	// The key is the format of "matcher:matchor", the value must be an valid "host:port"
	// like string.
	AgentGates map[string]string

	// KeepAliveSeconds limit the lifetime of idle ssh connection, default is 300.
	KeepAliveSeconds int
}

MuxAuth holds auth and gate configs

func (*MuxAuth) ApplyDefaultHostCheck

func (a *MuxAuth) ApplyDefaultHostCheck(check ssh.HostKeyCallback)

ApplyDefaultHostCheck apply the checking function or ssh.InsecureIgnoreHostKey to each Auth instance.

func (*MuxAuth) Validate

func (a *MuxAuth) Validate() error

type SSH

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

func Dial

func Dial(addr string, auth *Auth, gate ...*SSH) (*SSH, error)

Dial create a SSH instance, only first gate was used if it exist and isn't nil

func LocalOnly

func LocalOnly() *SSH

func NewSSH

func NewSSH(client *ssh.Client, maxSession int, gate *SSH) (*SSH, error)

func (*SSH) ClearError

func (s *SSH) ClearError()

func (*SSH) Close

func (s *SSH) Close()

Closed should be called only if reference count is zero or it's Cloned by NopClose

func (*SSH) Dial

func (s *SSH) Dial(addr string, auth *Auth) (*SSH, error)

func (*SSH) DialConn

func (s *SSH) DialConn(net, addr string) (net.Conn, error)

func (*SSH) Error

func (s *SSH) Error() error

func (*SSH) Get

func (s *SSH) Get(remotePath, path string)

func (*SSH) Lcd

func (s *SSH) Lcd(cwd string)

Lcd do the same thing as Rcd but for local host

func (*SSH) Lcmd

func (s *SSH) Lcmd(cmd string, env ...string)

func (*SSH) LcmdBg

func (s *SSH) LcmdBg(cmd, stdout, stderr string, env ...string)

func (*SSH) Lcwd

func (s *SSH) Lcwd() string

Lcwd return current local working directory

func (*SSH) Lexists

func (s *SSH) Lexists(path string) bool

func (*SSH) Lfs

func (s *SSH) Lfs() Fs

func (*SSH) LocalPipeInput

func (s *SSH) LocalPipeInput(stdin io.Reader)

func (*SSH) LocalPipeOutput

func (s *SSH) LocalPipeOutput(stdout, stderr io.Writer)

func (*SSH) LreadFile

func (s *SSH) LreadFile(path string) []byte

func (*SSH) Lreaddir

func (s *SSH) Lreaddir(path string, n int) []os.FileInfo

func (*SSH) Lremove

func (s *SSH) Lremove(path string, recursive bool)

func (*SSH) LwriteFile

func (s *SSH) LwriteFile(path string, data []byte)

func (*SSH) NopClose

func (s *SSH) NopClose() *SSH

NopClose create a clone of current SSH instance and increase the reference count. The Close method of returned instance will do nothing but decrease parent reference count.

func (*SSH) Output

func (s *SSH) Output() []byte

func (*SSH) Put

func (s *SSH) Put(path, remotePath string)

func (*SSH) Rcd

func (s *SSH) Rcd(cwd string)

Rcd will change the base path of relative path applied to remote host

func (*SSH) Rcmd

func (s *SSH) Rcmd(cmd string, env ...string)

func (*SSH) RcmdBg

func (s *SSH) RcmdBg(cmd, stdout, stderr string, env ...string)

func (*SSH) Rcwd

func (s *SSH) Rcwd() string

Rcwd return current remote working directory

func (*SSH) RemotePipeInput

func (s *SSH) RemotePipeInput(stdin io.Reader)

func (*SSH) RemotePipeOutput

func (s *SSH) RemotePipeOutput(stdout, stderr io.Writer)

func (*SSH) Rexists

func (s *SSH) Rexists(path string) bool

func (*SSH) Rfs

func (s *SSH) Rfs() Fs

func (*SSH) RreadFile

func (s *SSH) RreadFile(path string) []byte

func (*SSH) Rreaddir

func (s *SSH) Rreaddir(path string, n int) []os.FileInfo

func (*SSH) Rremove

func (s *SSH) Rremove(path string, recursive bool)

func (*SSH) RwriteFile

func (s *SSH) RwriteFile(path string, data []byte)

func (*SSH) SetError

func (s *SSH) SetError(err error)

save error state from external, such as fs op

func (*SSH) Status

func (s *SSH) Status() (openAt time.Time, refs int32)

func (*SSH) TmpLcd

func (s *SSH) TmpLcd(cwd string) *SSH

TmpLcd do the same thing as TmpLcd but for local host

func (*SSH) TmpRcd

func (s *SSH) TmpRcd(cwd string) *SSH

TmpRcd will create an copy of current instance but doesn't change reference count, then call Rcd on it. It should only used for temporary change directory and be quickly destroyed.

Jump to

Keyboard shortcuts

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