katyusha

package module
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2022 License: MIT Imports: 35 Imported by: 0

README

Katyusha - Lightning-fast parallel ssh client

Katyusha is a massively parallel ssh client that will replace all your hacky for loops, pssh, xargs and gnu parallel oneliners with something that is faster, more flexible and simply more awesome!

Katyusha can find your hosts in you known_hosts file, in consul and many other places. Using a powerful query syntax, you select the hosts you want and run any command in parallel on all of them. Output can be streamed as it happens, or shown at the end for easy inspection. On top of that, Katyusha is chock full of helpful features:

  • It can query your inventory systems and display information and statistics about your hosts
  • Timeouts, parallelism and delays are all configurable for very flexible ways of running commands
  • A variety of output modes show exactly what you need. Be it timestamps at the start of all lines, output separated by host or one big river of output. It can do all that and more.
  • Output is also stored in a machine-readable way so you can post process it as much as you want
  • An interactive shell is available that even lets you create host lists based on the result of running commands on hosts

Examples

Here are some examples to get you going. The full documentation can be found on https://katyusha.seveas.net

  • List all hosts in a specific domain

    katyusha list *.example.com

  • Run a command on all of them

    katyusha run *.example.com -- uptime

  • Run a long-running command, with output appearing immediately and reduced parallelism

    katyusha run *.example.com --parallel 10 --host-timeout 5m --timeout 1h -- sudo puppet agent -t

  • Show some information about hosts in an inventory system

    katyusha list site=site-5 --attributes ip_address,os,memory

  • Rolling restart of a service registered in consul

    katyusha run --splay 1m --parallel 1 consul_service=smtpd -- sudo systemctl restart postfix

Installing

There are pre-built binaries on the download page. If you prefer to install from source, install go, clone this repository and just run make.

Documentation

Index

Constants

View Source
const (
	Queued = iota
	Waiting
	Running
	Finished
)
View Source
const (
	MAJOR_VERSION = 0
	MINOR_VERSION = 8
	PATCH_VERSION = 0
)

Variables

This section is empty.

Functions

func NewLineWriterBuffer added in v0.8.0

func NewLineWriterBuffer(host *Host, stderr bool, oc chan OutputLine) *lineWriterBuffer

func Providers

func Providers() []string

func RegisterProvider

func RegisterProvider(name string, constructor func(string) HostProvider, magic func() HostProvider)

func Version

func Version() string

Types

type ByteWriter added in v0.8.0

type ByteWriter interface {
	Write([]byte) (int, error)
	Bytes() []byte
}

type Cache

type Cache interface {
	Source() HostProvider
	Invalidate()
	SetCacheDir(string)
}

type Connection added in v0.8.0

type Connection interface {
	Close()
}

type DataLoader

type DataLoader interface {
	SetDataDir(string) error
}

type Executor added in v0.8.0

type Executor interface {
	Run(ctx context.Context, host *Host, cmd string, oc chan OutputLine) *Result
	SetConnectTimeout(time.Duration)
}

type History

type History []*HistoryItem

func (History) Save

func (h History) Save(path string) error

type HistoryItem

type HistoryItem struct {
	Hosts   Hosts
	Command string
	Results map[string]*Result
	Summary struct {
		Ok   int
		Fail int
		Err  int
	}
	StartTime   time.Time
	EndTime     time.Time
	ElapsedTime float64
}

func (*HistoryItem) MarshalJSON

func (h *HistoryItem) MarshalJSON() ([]byte, error)

type Host

type Host struct {
	Name       string
	Address    string
	Attributes HostAttributes
	Connection io.Closer
	// contains filtered or unexported fields
}

A host represents a remote host. It can be instantiated manually, but is usually fetched from one or more Providers, which can all contribute to the hosts attributes.

func NewHost

func NewHost(name, address string, attributes HostAttributes) *Host

Hosts should be initialized with this function, which also initializes any internal data, without which SSH connections will not be possible.

func (*Host) AddPublicKey

func (h *Host) AddPublicKey(k ssh.PublicKey)

Adds a public key to a host. Used by the ssh know hosts provider, but can be used by any other code as well.

func (*Host) Amend

func (h *Host) Amend(h2 *Host)

func (*Host) GetAttribute

func (h *Host) GetAttribute(key string) (interface{}, bool)

func (*Host) Match

func (h *Host) Match(hostnameGlob string, attributes MatchAttributes) bool

func (*Host) PublicKeys

func (h *Host) PublicKeys() []ssh.PublicKey

func (Host) String

func (host Host) String() string

func (*Host) UnmarshalJSON

func (h *Host) UnmarshalJSON(data []byte) error

type HostAttributes

type HostAttributes map[string]interface{}

Hosts can have attributes of any types, but querying is limited to strings, booleans, numbers, nil and slices of these values.

type HostListOptions

type HostListOptions struct {
	OneLine       bool
	Separator     string
	Csv           bool
	Attributes    []string
	AllAttributes bool
	Align         bool
	Header        bool
	Template      string
	Count         []string
	SortByCount   bool
}

type HostProvider

type HostProvider interface {
	Name() string
	Prefix() string
	ParseViper(v *viper.Viper) error
	Load(ctx context.Context, l LoadingMessage) (Hosts, error)
	Equivalent(p HostProvider) bool
}

func NewProvider

func NewProvider(pname, name string) (HostProvider, error)

type Hosts

type Hosts []*Host

func (Hosts) Sample added in v0.7.0

func (h Hosts) Sample(attributes []string, count int) Hosts

func (Hosts) Sort

func (h Hosts) Sort(fields []string)

func (Hosts) String

func (hosts Hosts) String() string

func (Hosts) Uniq

func (h Hosts) Uniq() Hosts

type LoadingMessage

type LoadingMessage func(string, bool, error)

type MatchAttribute

type MatchAttribute struct {
	Name        string
	FuzzyTyping bool
	Negate      bool
	Regex       bool
	Value       interface{}
}

func (MatchAttribute) Match

func (m MatchAttribute) Match(value interface{}) (matches bool)

func (MatchAttribute) String

func (m MatchAttribute) String() string

type MatchAttributes

type MatchAttributes []MatchAttribute

type MultiError

type MultiError struct {
	Subject string
	// contains filtered or unexported fields
}

func (*MultiError) Add

func (m *MultiError) Add(e error)

func (*MultiError) Error

func (m *MultiError) Error() string

func (*MultiError) HasErrors

func (m *MultiError) HasErrors() bool

type OutputLine

type OutputLine struct {
	Host   *Host
	Stderr bool
	Data   []byte
}

type OutputMode

type OutputMode int
const (
	OutputTail OutputMode = iota
	OutputPerhost
	OutputInline
	OutputAll
)

type ProgressMessage

type ProgressMessage struct {
	Host   *Host
	State  ProgressState
	Result *Result
}

type ProgressState

type ProgressState int

type Registry

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

func NewRegistry

func NewRegistry(dataDir, cacheDir string) *Registry

func (*Registry) AddMagicProvider

func (r *Registry) AddMagicProvider(p HostProvider)

func (*Registry) AddProvider

func (r *Registry) AddProvider(p HostProvider)

func (*Registry) GetHosts

func (r *Registry) GetHosts(hostnameGlob string, attributes MatchAttributes, sampled []string, count int) Hosts

func (*Registry) InvalidateCache

func (r *Registry) InvalidateCache()

func (*Registry) LoadHosts

func (r *Registry) LoadHosts(ctx context.Context, lm LoadingMessage) error

func (*Registry) LoadMagicProviders

func (r *Registry) LoadMagicProviders()

func (*Registry) LoadProviders

func (r *Registry) LoadProviders(c *viper.Viper) error

func (*Registry) Settings added in v0.8.0

func (r *Registry) Settings() (string, map[string]interface{})

type Result

type Result struct {
	Host        *Host
	ExitStatus  int
	Stdout      []byte
	Stderr      []byte
	Err         error
	StartTime   time.Time
	EndTime     time.Time
	ElapsedTime float64
}

func (Result) MarshalJSON

func (r Result) MarshalJSON() ([]byte, error)

func (Result) String

func (r Result) String() string

type Runner

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

func NewRunner

func NewRunner(executor Executor) *Runner

func (*Runner) AddHosts

func (r *Runner) AddHosts(hosts Hosts)

func (*Runner) End

func (r *Runner) End()

func (*Runner) GetHosts

func (r *Runner) GetHosts() Hosts

func (*Runner) RemoveHosts

func (r *Runner) RemoveHosts(glob string, attrs MatchAttributes)

func (*Runner) Run

func (r *Runner) Run(command string, pc chan ProgressMessage, oc chan OutputLine) (*HistoryItem, error)

func (*Runner) SetConnectTimeout

func (r *Runner) SetConnectTimeout(t time.Duration)

FIXME

func (*Runner) SetHostTimeout

func (r *Runner) SetHostTimeout(t time.Duration)

func (*Runner) SetParallel

func (r *Runner) SetParallel(p int)

func (*Runner) SetSortFields added in v0.8.0

func (r *Runner) SetSortFields(s []string)

func (*Runner) SetSplay

func (r *Runner) SetSplay(t time.Duration)

func (*Runner) SetTimeout

func (r *Runner) SetTimeout(t time.Duration)

func (*Runner) Settings added in v0.8.0

func (r *Runner) Settings() (string, map[string]interface{})

type SettingsFunc added in v0.8.0

type SettingsFunc func() (string, map[string]interface{})

type SimpleUI

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

func NewSimpleUI

func NewSimpleUI() *SimpleUI

func (*SimpleUI) BindLogrus

func (ui *SimpleUI) BindLogrus()

func (*SimpleUI) End

func (ui *SimpleUI) End()

func (*SimpleUI) LoadingMessage

func (ui *SimpleUI) LoadingMessage(what string, done bool, err error)

func (*SimpleUI) OutputChannel

func (ui *SimpleUI) OutputChannel(r *Runner) chan OutputLine

func (*SimpleUI) PrintHistoryItem

func (ui *SimpleUI) PrintHistoryItem(hi *HistoryItem)

func (*SimpleUI) PrintHostList

func (ui *SimpleUI) PrintHostList(hosts Hosts, opts HostListOptions)

func (*SimpleUI) PrintSettings

func (ui *SimpleUI) PrintSettings(funcs ...SettingsFunc)

func (*SimpleUI) ProgressChannel

func (ui *SimpleUI) ProgressChannel(r *Runner) chan ProgressMessage

func (*SimpleUI) SetOutputMode

func (ui *SimpleUI) SetOutputMode(o OutputMode)

func (*SimpleUI) SetOutputTimestamp

func (ui *SimpleUI) SetOutputTimestamp(e bool)

func (*SimpleUI) SetPagerEnabled

func (ui *SimpleUI) SetPagerEnabled(e bool)

func (*SimpleUI) Settings added in v0.8.0

func (ui *SimpleUI) Settings() (string, map[string]interface{})

func (*SimpleUI) Sync

func (ui *SimpleUI) Sync()

func (*SimpleUI) Write

func (ui *SimpleUI) Write(msg []byte) (int, error)

type TimeoutError

type TimeoutError struct {
	Message string
}

func (TimeoutError) Error

func (e TimeoutError) Error() string

type UI

type UI interface {
	PrintHistoryItem(hi *HistoryItem)
	PrintHostList(hosts Hosts, opts HostListOptions)
	PrintSettings(...SettingsFunc)
	SetOutputMode(OutputMode)
	SetOutputTimestamp(bool)
	SetPagerEnabled(bool)
	Write([]byte) (int, error)
	Sync()
	End()
	LoadingMessage(what string, done bool, err error)
	OutputChannel(r *Runner) chan OutputLine
	ProgressChannel(r *Runner) chan ProgressMessage
	BindLogrus()
	Settings() (string, map[string]interface{})
}

Jump to

Keyboard shortcuts

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