diff --git a/client.go b/client.go index f60aa62..7ff65f0 100644 --- a/client.go +++ b/client.go @@ -13,12 +13,14 @@ import ( "golang.org/x/crypto/ssh" ) +// A Client represents Goph client. type Client struct { *ssh.Client Config *Config sftp *sftp.Client } +// Config for Client. type Config struct { Auth Auth User string @@ -28,6 +30,7 @@ type Config struct { Callback ssh.HostKeyCallback } +// DefaultTimeout represents connection timeout. var DefaultTimeout = 20 * time.Second // New starts a new ssh connection, the host public key must be in known hosts. @@ -65,7 +68,7 @@ func NewUnknown(user string, addr string, auth Auth) (*Client, error) { }) } -// Get new client connection. +// NewConn returns new client and error if any. func NewConn(config *Config) (c *Client, err error) { c = &Client{ @@ -76,6 +79,7 @@ func NewConn(config *Config) (c *Client, err error) { return } +// Dial starts a client connection to SSH server based on config. func Dial(proto string, c *Config) (*ssh.Client, error) { return ssh.Dial(proto, fmt.Sprintf("%s:%d", c.Addr, c.Port), &ssh.ClientConfig{ User: c.User, @@ -85,7 +89,7 @@ func Dial(proto string, c *Config) (*ssh.Client, error) { }) } -// Run a command over ssh connection +// Run runs a command over client connection. func (c Client) Run(cmd string) ([]byte, error) { var ( @@ -102,6 +106,7 @@ func (c Client) Run(cmd string) ([]byte, error) { return sess.CombinedOutput(cmd) } +// Command returns new Cmd and error if any. func (c Client) Command(name string, args ...string) (*Cmd, error) { var ( @@ -120,6 +125,7 @@ func (c Client) Command(name string, args ...string) (*Cmd, error) { }, nil } +// NewSftp returns new sftp client and error if any. func (c Client) NewSftp(opts ...sftp.ClientOption) (*sftp.Client, error) { return sftp.NewClient(c.Client, opts...) } @@ -134,20 +140,7 @@ func (c Client) Close() error { return c.Client.Close() } -func (c *Client) ftp() *sftp.Client { - - if c.sftp == nil { - sftp, err := c.NewSftp() - if err != nil { - panic(err) - } - c.sftp = sftp - } - - return c.sftp -} - -// Upload a local file to remote machine! +// Upload a local file to remote server! func (c Client) Upload(localPath string, remotePath string) (err error) { local, err := os.Open(localPath) @@ -170,7 +163,7 @@ func (c Client) Upload(localPath string, remotePath string) (err error) { return } -// Download file from remote machine! +// Download file from remote server! func (c Client) Download(remotePath string, localPath string) (err error) { local, err := os.Create(localPath) @@ -195,3 +188,17 @@ func (c Client) Download(remotePath string, localPath string) (err error) { return local.Sync() } + +// get sftp client if not set. +func (c *Client) ftp() *sftp.Client { + + if c.sftp == nil { + sftp, err := c.NewSftp() + if err != nil { + panic(err) + } + c.sftp = sftp + } + + return c.sftp +} diff --git a/cmd.go b/cmd.go index 676a355..0c9a66d 100644 --- a/cmd.go +++ b/cmd.go @@ -10,33 +10,48 @@ import ( "golang.org/x/crypto/ssh" ) +// Cmd it's like os/exec.Cmd but for ssh session. type Cmd struct { + + // Path to command executable filename Path string + + // Command args. Args []string - Env []string + + // Session env vars. + Env []string + + // ssh session. *ssh.Session } +// CombinedOutput runs cmd on the remote host and returns its combined standard output and standard error. func (c *Cmd) CombinedOutput() ([]byte, error) { return c.init().Session.CombinedOutput(c.String()) } +// Output runs cmd on the remote host and returns its standard output. func (c *Cmd) Output() ([]byte, error) { return c.init().Session.Output(c.String()) } +// Run runs cmd on the remote host. func (c *Cmd) Run() error { return c.init().Session.Run(c.String()) } +// Start runs the command on the remote host. func (c *Cmd) Start() error { return c.init().Session.Start(c.String()) } +// String return the command line string. func (c *Cmd) String() string { return fmt.Sprintf("%s %s", c.Path, strings.Join(c.Args, " ")) } +// init inits Cmd.Env vars. func (c *Cmd) init() *Cmd { // Set session env vars diff --git a/hosts.go b/hosts.go index e69251d..592f799 100644 --- a/hosts.go +++ b/hosts.go @@ -12,22 +12,22 @@ import ( "golang.org/x/crypto/ssh/knownhosts" ) +// Default known hosts path. var defaultPath = os.ExpandEnv("$HOME/.ssh/known_hosts") -// Use default known hosts files to verify host public key. +// DefaultKnownHosts returns host key callback from default known hosts path, and error if any. func DefaultKnownHosts() (ssh.HostKeyCallback, error) { return KnownHosts(defaultPath) } -// Get known hosts callback from a custom path. +// KnownHosts returns host key callback from a custom known hosts path. func KnownHosts(file string) (ssh.HostKeyCallback, error) { return knownhosts.New(file) } -// Check is host in known hosts file. -// It returns is the host found in known_hosts file and error, -// If the host found in known_hosts file and error not nil that means public key mismatch, Maybe -// MAN IN THE MIDDLE ATTACK! you should not handshake. +// CheckKnownHost checks is host in known hosts file. +// it returns is the host found in known_hosts file and error, if the host found in +// known_hosts file and error not nil that means public key mismatch, maybe MAN IN THE MIDDLE ATTACK! you should not handshake. func CheckKnownHost(host string, remote net.Addr, key ssh.PublicKey, knownFile string) (found bool, err error) { var keyErr *knownhosts.KeyError @@ -67,7 +67,7 @@ func CheckKnownHost(host string, remote net.Addr, key ssh.PublicKey, knownFile s return false, nil } -// Add a host to knows hosts +// AddKnownHost adda a host to known hosts file. func AddKnownHost(host string, remote net.Addr, key ssh.PublicKey, knownFile string) (err error) { // Fallback to default known_hosts file