sshwctl

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2020 License: MIT Imports: 33 Imported by: 0

Documentation

Overview

* Reference https://github.com/bramvdbogaerde/go-scp/blob/master/protocol.go

Index

Constants

View Source
const (
	WalkIndexFlag = "$index"
	WalkOtherFlag = "$other"
)
View Source
const (
	TypeStr   = "str"
	TypeParam = "param"
)
View Source
const (
	ApplicationName = "sshw"
)

Variables

View Source
var (
	DefaultCiphers = []string{
		"aes128-ctr",
		"aes192-ctr",
		"aes256-ctr",
		"aes128-gcm@openssh.com",
		"chacha20-poly1305@openssh.com",
		"arcfour256",
		"arcfour128",
		"arcfour",
		"aes128-cbc",
		"3des-cbc",
		"blowfish-cbc",
		"cast128-cbc",
		"aes192-cbc",
		"aes256-cbc",
	}
)
View Source
var (
	ErrorInterrupt = errors.New("interrupt")
)

Functions

func AbsPath

func AbsPath(p string) string

func ExecNode

func ExecNode(node *Node) error

local

func ExtractBinary

func ExtractBinary(name string, needClose bool) (*os.File, error)

func FieldEmpty

func FieldEmpty(t reflect.Type, v reflect.Value) bool

func FieldsNotEmpty

func FieldsNotEmpty(v interface{}, ignoreKeys []string) ([]string, error)

search not empty field in v if key in ignoreKeys, skip validation

func IsBookmark

func IsBookmark(n *Node) bool

only name and children have value etc.

  • name: foo children:
  • name: bar
  • name: zoo

func LoadConfigBytes

func LoadConfigBytes(names ...string) (string, []byte, error)

func MergeNodes

func MergeNodes(dstPtr *[]*Node, src []*Node)

merge srcNode to dstNode only compare name and override, otherwise it is complex.

func PrepareConfig

func PrepareConfig(config interface{}) error

render template into nodes

func RegisterLifecycle

func RegisterLifecycle(lifecycle Lifecycle)

func WalkInterface

func WalkInterface(v reflect.Value, walked bool, solver ValueSolver) error

Types

type Client

type Client interface {
	// -----local
	// run pre commands
	ExecsPre() error
	CanConnect() bool
	// terminal makeRaw and store width height
	InitTerminal() error
	// run post commands
	ExecsPost() error
	WatchWindowChange(windowChange func(ch, cw int) error)

	// -----local or remote
	Connect() error
	Scp() error
	Shell() error
	Close() error

	// -----remote
	GetClient() *ssh.Client
	SetClient(client *ssh.Client)
	// send keepalive to ssh server
	Ping() error
}

func NewClient

func NewClient(node *Node) Client

type CommonLifecycle

type CommonLifecycle struct {
	Name                     string
	PriorityFunc             func() int
	PostInitClientConfigFunc func(node *Node, clientConfig *ssh.ClientConfig) error
	PostSSHDialFunc          func(node *Node, client *ssh.Client) error
	PostNewSessionFunc       func(node *Node, session *ssh.Session) error
	PostShellFunc            func(node *Node, stdin io.WriteCloser) error
	OnStdoutFunc             func(node *Node, line []byte) error
	OnStderrFunc             func(node *Node, line []byte) error
	PostSessionWaitFunc      func(node *Node) error
}

CommonLifecycle is used to build Lifecycle quickly

func (*CommonLifecycle) OnStderr

func (d *CommonLifecycle) OnStderr(node *Node, line []byte) error

func (*CommonLifecycle) OnStdout

func (d *CommonLifecycle) OnStdout(node *Node, line []byte) error

func (*CommonLifecycle) PostInitClientConfig

func (d *CommonLifecycle) PostInitClientConfig(node *Node, clientConfig *ssh.ClientConfig) error

func (*CommonLifecycle) PostNewSession

func (d *CommonLifecycle) PostNewSession(node *Node, session *ssh.Session) error

func (*CommonLifecycle) PostSSHDial

func (d *CommonLifecycle) PostSSHDial(node *Node, client *ssh.Client) error

func (*CommonLifecycle) PostSessionWait

func (d *CommonLifecycle) PostSessionWait(node *Node) error

func (*CommonLifecycle) PostShell

func (d *CommonLifecycle) PostShell(node *Node, stdin io.WriteCloser) error

func (*CommonLifecycle) Priority

func (d *CommonLifecycle) Priority() int

type CustomTemplate

type CustomTemplate struct {
	Templates []*TemplateNode
}

func ParseSshwTemplate

func ParseSshwTemplate(src string) *CustomTemplate

Read string to Template For example: INPUT: ParseSshwTemplate("Foo${foo:a}bar") OUTPUT: []{{Type: TypeStr, Value: "Foo"}, {Type: TypeParam}, Value: "${foo:a}"}, {Type: TypeStr, Value: "bar"}}

func (*CustomTemplate) Execute

func (c *CustomTemplate) Execute() string

type GithubRepository

type GithubRepository struct {
	Url      string
	Username string
	Name     string
}

func (*GithubRepository) Download

func (g *GithubRepository) Download(versionMeta *VersionMeta) (*os.File, error)

Using version and filename to generate a remote url that is used to download file. Download it to file tmp. Then backup original file and replace it with Downloaded file.

func (*GithubRepository) LatestVersion

func (g *GithubRepository) LatestVersion() (*VersionMeta, error)

type KeyboardInteractive

type KeyboardInteractive struct {
	Question   string
	Answer     string
	GoogleAuth bool `yaml:"google-auth"`
}

when it have KeyboardInteractive sshw will answer question if question contains content that we set. if AnswerAll is true, it will don't match question

type Lifecycle

type Lifecycle interface {
	PostInitClientConfig(node *Node, clientConfig *ssh.ClientConfig) error

	PostSSHDial(node *Node, client *ssh.Client) error

	PostNewSession(node *Node, session *ssh.Session) error

	PostShell(node *Node, stdin io.WriteCloser) error

	OnStdout(node *Node, line []byte) error

	OnStderr(node *Node, line []byte) error

	PostSessionWait(node *Node) error

	Priority() int
}

type LifecycleAgent

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

func (*LifecycleAgent) PostInitClientConfig

func (l *LifecycleAgent) PostInitClientConfig(node *Node, clientConfig *ssh.ClientConfig) error

func (*LifecycleAgent) PostNewSession

func (l *LifecycleAgent) PostNewSession(node *Node, session *ssh.Session) error

func (*LifecycleAgent) PostSSHDial

func (l *LifecycleAgent) PostSSHDial(node *Node, client *ssh.Client) error

func (*LifecycleAgent) Priority

func (l *LifecycleAgent) Priority() int

type LifecycleCallback

type LifecycleCallback struct {
	IsError bool
	Index   int
	Mutex   *sync.Mutex
	Cond    *sync.Cond
}

func (*LifecycleCallback) OnStdout

func (l *LifecycleCallback) OnStdout(node *Node, line []byte) error

func (*LifecycleCallback) PostShell

func (l *LifecycleCallback) PostShell(node *Node, stdin io.WriteCloser) error

type LifecycleComposite

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

func NewLifeCycleComposite

func NewLifeCycleComposite() *LifecycleComposite

func (*LifecycleComposite) OnStderr

func (l *LifecycleComposite) OnStderr(node *Node, line []byte) error

func (*LifecycleComposite) OnStdout

func (l *LifecycleComposite) OnStdout(node *Node, line []byte) error

func (*LifecycleComposite) PostInitClientConfig

func (l *LifecycleComposite) PostInitClientConfig(node *Node, clientConfig *ssh.ClientConfig) error

func (*LifecycleComposite) PostNewSession

func (l *LifecycleComposite) PostNewSession(node *Node, session *ssh.Session) error

func (*LifecycleComposite) PostSSHDial

func (l *LifecycleComposite) PostSSHDial(node *Node, client *ssh.Client) error

func (*LifecycleComposite) PostSessionWait

func (l *LifecycleComposite) PostSessionWait(node *Node) error

func (*LifecycleComposite) PostShell

func (l *LifecycleComposite) PostShell(node *Node, stdin io.WriteCloser) error

func (*LifecycleComposite) Priority

func (l *LifecycleComposite) Priority() int

type LifecycleIO

type LifecycleIO struct {
}

func (*LifecycleIO) OnStderr

func (*LifecycleIO) OnStderr(node *Node, bytes []byte) error

func (*LifecycleIO) OnStdout

func (*LifecycleIO) OnStdout(node *Node, bytes []byte) error

func (*LifecycleIO) Priority

func (*LifecycleIO) Priority() int

type LifecyclePassword

type LifecyclePassword struct {
}

func (*LifecyclePassword) PostInitClientConfig

func (*LifecyclePassword) PostInitClientConfig(node *Node, clientConfig *ssh.ClientConfig) error

if set password, auto auth password if set KeyboardInteractions, match question and then auto auth interaction

type LifecyclePem

type LifecyclePem struct {
}

func (*LifecyclePem) PostInitClientConfig

func (*LifecyclePem) PostInitClientConfig(node *Node, clientConfig *ssh.ClientConfig) error

type LifecycleQueue

type LifecycleQueue []Lifecycle

func (*LifecycleQueue) Len

func (l *LifecycleQueue) Len() int

func (*LifecycleQueue) Less

func (l *LifecycleQueue) Less(i, j int) bool

func (*LifecycleQueue) Pop

func (l *LifecycleQueue) Pop() interface{}

func (*LifecycleQueue) Push

func (l *LifecycleQueue) Push(x interface{})

func (*LifecycleQueue) Swap

func (l *LifecycleQueue) Swap(i, j int)

type Node

type Node struct {
	Name                 string                `yaml:"name"`
	Alias                string                `yaml:"alias,omitempty"`
	ExecsPre             []*NodeExec           `yaml:"execs-pre,omitempty"`
	ExecsStop            []*NodeExec           `yaml:"execs-stop,omitempty"`
	Host                 string                `yaml:"host,omitempty"`
	User                 string                `yaml:"user,omitempty"`
	Port                 int                   `yaml:"port,omitempty"`
	KeyPath              string                `yaml:"keypath,omitempty"`
	Passphrase           string                `yaml:"passphrase,omitempty"`
	Password             string                `yaml:"password,omitempty"`
	CallbackShells       []*NodeCallbackShell  `yaml:"callback-shells,omitempty"`
	Scps                 []*NodeCp             `yaml:"scps"`
	Children             []*Node               `yaml:"children,omitempty"`
	Jump                 []*Node               `yaml:"jump,omitempty"`
	MergeIgnore          bool                  `yaml:"merge-ignore,omitempty"`
	KeyboardInteractions []KeyboardInteractive `yaml:"keyboard-interactions"`
	ControlMaster        *bool                 `yaml:"control-master"`

	Stdin   io.Reader       `yaml:"-"`
	Stdout  io.Writer       `yaml:"-"`
	Stderr  io.Writer       `yaml:"-"`
	Width   int             `yaml:"-"`
	Height  int             `yaml:"-"`
	State   *terminal.State `yaml:"-"`
	Session *ssh.Session    `yaml:"-"`
}

func LoadSshConfig

func LoadSshConfig() ([]*Node, error)

func LoadYamlConfig

func LoadYamlConfig(filename string) (string, []*Node, error)

func (*Node) Error

func (n *Node) Error(err error)

func (*Node) Print

func (n *Node) Print(message string)

func (*Node) Println

func (n *Node) Println(message string)

func (*Node) String

func (n *Node) String() string

type NodeCallbackShell

type NodeCallbackShell struct {
	Cmd          string        `yaml:"cmd"`
	CpShell      NodeCp        `yaml:"cp,omitempty"`
	Delay        time.Duration `yaml:"delay,omitempty"`
	ErrorPattern string        `yaml:"error-pattern,omitempty"`
	Wait         time.Duration `yaml:"wait,omitempty"`
}

type NodeCp

type NodeCp struct {
	Src string `yaml:"src" sshw:"path"`
	Tgt string `yaml:"tgt"`
	// seconds
	Timeout int64
}

type NodeExec

type NodeExec struct {
	Cmd string `yaml:"cmd"`
	Var string `yaml:"var"`
}

type Repository

type Repository interface {
	// get remote version
	LatestVersion() (*VersionMeta, error)

	// download remote file to specified path
	Download(versionMeta *VersionMeta) (*os.File, error)
}

type Response

type Response struct {
	Type    ResponseType
	Message string
}

There are tree types of responses that the remote can send back: ok, warning and error

The difference between warning and error is that the connection is not closed by the remote, however, a warning can indicate a file transfer failure (such as invalid destination directory) and such be handled as such.

All responses except for the `Ok` type always have a message (although these can be empty)

The remote sends a confirmation after every SCP command, because a failure can occur after every command, the response should be read and checked after sending them.

func ParseResponse

func ParseResponse(reader io.Reader) (Response, error)

Reads from the given reader (assuming it is the output of the remote) and parses it into a Response structure

func (*Response) GetMessage

func (r *Response) GetMessage() string

Returns the message the remote sent back

func (*Response) IsError

func (r *Response) IsError() bool

Returns true when the remote responded with an error

func (*Response) IsFailure

func (r *Response) IsFailure() bool

Returns true when the remote answered with a warning or an error

func (*Response) IsOk

func (r *Response) IsOk() bool

func (*Response) IsWarning

func (r *Response) IsWarning() bool

type ResponseType

type ResponseType = uint8
const (
	Ok      ResponseType = 0
	Warning ResponseType = 1
	Error   ResponseType = 2
)

type RuntimeSystem

type RuntimeSystem struct {
	GOOS        string
	GOOSAlias   string
	GOARCH      string
	GOARCHAlias string
}

type TemplateNode

type TemplateNode struct {
	Type  string
	Value string
}

func NewParamNode

func NewParamNode(v string) *TemplateNode

func NewStrNode

func NewStrNode(v string) *TemplateNode

type ValueSolver

type ValueSolver func(k string, t reflect.Type, v reflect.Value, structField *reflect.StructField) (skipSearch bool)

if t.kind() in array or slice, name is $index return true, if would skip deepSearching type like slice or array or map

type VersionMeta

type VersionMeta struct {
	// version
	// e.t. v1.4.1
	Version string

	// file suffix
	// e.t. sshw-v1.4.1-darwin-osx-amd64.zip
	Filename string
}

type WriteCounter

type WriteCounter struct {
	Total            uint64
	ProgressTemplate string
}

WriteCounter counts the number of bytes written to it. It implements to the io.Writer interface and we can pass this into io.TeeReader() which will report progress on each write cycle.

func NewWriteCounter

func NewWriteCounter() *WriteCounter

func (WriteCounter) PrintProgress

func (wc WriteCounter) PrintProgress()

func (*WriteCounter) Write

func (wc *WriteCounter) Write(p []byte) (int, error)

Jump to

Keyboard shortcuts

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