sshwctl

package
v1.10.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: May 6, 2020 License: MIT Imports: 35 Imported by: 0

Documentation

Overview

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

Index

Constants

View Source
const (
	PostInitClientConfig = "PostInitClientConfig"
	PostSSHDial          = "PostSSHDial"
	PostNewSession       = "PostNewSession"
	OnStdout             = "OnStdout"
	OnStderr             = "OnStderr"
	PostShell            = "PostShell"
)
View Source
const (
	WalkIndexFlag = "$index"
	WalkOtherFlag = "$other"
)
View Source
const (
	TypeStr   = "str"
	TypeParam = "param"
)
View Source
const (
	ApplicationName = "sshw"
)
View Source
const (
	KeyAgent = "agent"
)
View Source
const (
	KeyCallback = "callback"
)

Variables

View Source
var (
	SshPath              = path.Join(homeDir, ".ssh/config")
	SshwDir              = path.Join(homeDir, ".config/sshw")
	SshwGlobalConfigPath = path.Join(SshwDir, "config.yaml")
)
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",
	}
)

Functions

func AbsPath

func AbsPath(input string) string

AbsPath returns absolute path and match wild path if match multiple path, return first

func AgentPostInitClientConfig added in v1.8.2

func AgentPostInitClientConfig(ctx *EventContext, clientConfig *ssh.ClientConfig)

func AgentPostNewSession added in v1.8.2

func AgentPostNewSession(ctx *EventContext, session *ssh.Session) error

func AgentPostSSHDial added in v1.8.2

func AgentPostSSHDial(ctx *EventContext, client *ssh.Client) error

func AuthPemPostInitClientConfig added in v1.8.2

func AuthPemPostInitClientConfig(ctx *EventContext, clientConfig *ssh.ClientConfig)

func AuthPwdPostInitClientConfig added in v1.8.2

func AuthPwdPostInitClientConfig(ctx *EventContext, clientConfig *ssh.ClientConfig)

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

func AutoSSHAgent added in v1.8.1

func AutoSSHAgent() error

auto ssh-add .ssh/id_rsa

func CallbackOnStdout added in v1.8.2

func CallbackOnStdout(ctx *EventContext, line []byte) error

func CallbackPostShell added in v1.8.2

func CallbackPostShell(ctx *EventContext, stdin io.WriteCloser) error

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 IOOnStderr added in v1.8.2

func IOOnStderr(ctx *EventContext, bytes []byte) error

func IOOnStdout added in v1.8.2

func IOOnStdout(ctx *EventContext, bytes []byte) error

func InitConfig added in v1.10.0

func InitConfig(config interface{}) error

render template into nodes 1. Parse template ${Env_Variable} 2. solve path.convert '*' to absPath

func InitNodes added in v1.10.0

func InitNodes(nodes []*Node) error

1. load global yaml 2. render template 3. load .ssh/config

func InitNodesWithSshwConfig

func InitNodesWithSshwConfig(nodes []*Node)

update nodes with global config if host is equal, update node only iterate first level

func IsBookmark

func IsBookmark(n *Node) bool

only name and children have value etc.

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

func IsEAGAIN added in v1.9.3

func IsEAGAIN(err error) bool

func MergeNodes

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

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

func MergeSshConfig added in v1.10.0

func MergeSshConfig(nodes []*Node, sshNodes []*Node) error

match .ssh/config Pattern if Node.Host == config.Host set config.HostName to Node.Host same set config.User and config.Port

func ReadConfigBytes added in v1.9.1

func ReadConfigBytes(filename string) (string, []byte, error)

return filepath and bytes of config

func ReadDefaultConfigBytes added in v1.9.1

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

func Shell added in v1.9.0

func Shell() string

func UserIdRsaIsNotExist added in v1.8.1

func UserIdRsaIsNotExist() bool

func WalkInterface

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

Types

type CallbackInfo added in v1.8.2

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

func NewCallbackInfo added in v1.8.2

func NewCallbackInfo() *CallbackInfo

type Client

type Client interface {
	// -----local
	// run pre commands
	ExecsPre() error
	CanConnect() bool
	// terminal makeRaw and store width height
	InitTerminal() error
	RecoverTerminal()
	// 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 ConfigLoader added in v1.10.0

type ConfigLoader interface {
	Decode(nodes *[]*Node) error
}

func NewSshConfigLoader added in v1.10.0

func NewSshConfigLoader(r io.Reader) ConfigLoader

func NewYamlConfigLoader added in v1.10.0

func NewYamlConfigLoader(bs []byte) ConfigLoader

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 EventContext added in v1.8.2

type EventContext struct {
	Node       *Node
	Attachment map[string]interface{}
}

func NewEventContext added in v1.8.2

func NewEventContext(node *Node) *EventContext

func (*EventContext) Get added in v1.8.2

func (e *EventContext) Get(key string) (interface{}, bool)

func (*EventContext) Put added in v1.8.2

func (e *EventContext) Put(key string, value interface{})

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 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.ReadCloser   `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)

return config of .ssh/config

func LoadYamlConfig

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

return filepath and nodes, load config in filename

func LoadYamlConfig0 added in v1.10.0

func LoadYamlConfig0(bs []byte) ([]*Node, error)

return yaml config

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"`
	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"`
	Tgt       string `yaml:"tgt"`
	IsReceive bool   `yaml:"is-receive"`
	// seconds
	Timeout int64
}

type NodeExec

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

type NonblockReader added in v1.9.3

type NonblockReader struct {
	Ctx        context.Context
	CancelFunc context.CancelFunc
	R          *os.File
}

func NewNonblockReader added in v1.9.3

func NewNonblockReader(r *os.File) (*NonblockReader, error)

func (*NonblockReader) Close added in v1.9.3

func (n2 *NonblockReader) Close() error

func (*NonblockReader) Read added in v1.9.3

func (n2 *NonblockReader) Read(p []byte) (n int, err error)

type ReaderFunc added in v1.9.3

type ReaderFunc func(p []byte) (n int, err error)

func (ReaderFunc) Read added in v1.9.3

func (r ReaderFunc) Read(p []byte) (n int, err error)

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 SshConfigLoader added in v1.10.0

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

func (*SshConfigLoader) Decode added in v1.10.0

func (s *SshConfigLoader) Decode(nodes *[]*Node) error

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
	W                io.Writer
}

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)

type WriterFunc added in v1.9.3

type WriterFunc func(p []byte) (n int, err error)

func (WriterFunc) Write added in v1.9.3

func (w WriterFunc) Write(p []byte) (n int, err error)

type YamlConfigLoader added in v1.10.0

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

func (*YamlConfigLoader) Decode added in v1.10.0

func (y *YamlConfigLoader) Decode(nodes *[]*Node) error

Jump to

Keyboard shortcuts

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