rig

package module
v2.0.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2024 License: Apache-2.0 Imports: 21 Imported by: 0

README

Note: The main branch contains a work in progress for rig v2. If you are looking for the stable version, please browse the tags of v0.x releases.

Rig

GoDoc Go Report Card Build Status codecov

Rig

A golang package for adding multi-protocol connectivity and multi-os operation functionality to your application's Host objects.

Design goals

Rig's intention is to be easy to use and extend.

It should be easy to add support for new operating systems and to add new components to the multi-os support mechanism without breaking type safety and testability.

Protocols

Currently rig comes with the most common ways to connect to hosts:

  • SSH for connecting to hosts that accept SSH connections. With ssh agent and config support and sane familiar defaults. Pageant or openssh agent can be used on Windows.
  • OpenSSH for connecting to hosts using the system's own openssh "ssh" executable and utilizing session multiplexing for performance.
  • WinRM as an alternative to SSH for windows hosts (SSH works too)
  • Localhost for treating the local host as it was a remote host using go's os/exec.

Usage

TBD - for now see godoc, tests and sources.

Documentation

Overview

Package rig provides an easy way to add multi-protocol connectivity and multi-os operation support to your application's Host objects by embedding or directly using the Client or Connection objects.

Rig's core functionality revolves around providing a unified interface for interacting with remote systems. This includes managing services, file systems, package managers, and getting OS release information, abstracting away the intricacies of different operating systems and communication protocols.

The protocol implementations aim to provide out-of-the-box default behavior similar to what you would expect when using the official clients like openssh "ssh" command instead of having to deal with implementing ssh config parsing, key managemnt, agent forwarding and so on yourself.

To get started, see Client

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrAbort is returned when retrying an action will not yield a different outcome.
	// An alias of protocol.ErrAbort for easier access without importing subpackages.
	ErrAbort = protocol.ErrAbort

	// ErrValidationFailed is returned when a validation check fails.
	// An alias of protocol.ErrValidationFailed for easier access without importing subpackages.
	ErrValidationFailed = protocol.ErrValidationFailed
)

Functions

func DefaultPasswordCallback

func DefaultPasswordCallback() (string, error)

DefaultPasswordCallback is a default implementation for PasswordCallback.

func GetOSRelease

func GetOSRelease(runner cmd.SimpleRunner) (*os.Release, error)

GetOSRelease returns the remote host's operating system information from the default provider.

func GetPackageManager

func GetPackageManager(runner cmd.ContextRunner) (packagemanager.PackageManager, error)

GetPackageManager returns a package manager from the default provider.

func GetRemoteFS

func GetRemoteFS(runner cmd.Runner) (remotefs.FS, error)

GetRemoteFS returns a new remote FS instance from the default remote.FS provider.

func GetServiceManager

func GetServiceManager(runner cmd.ContextRunner) (initsystem.ServiceManager, error)

GetServiceManager returns a ServiceManager for the current system from the default init system providers.

func GetSudoRunner

func GetSudoRunner(runner cmd.Runner) (cmd.Runner, error)

GetSudoRunner returns a new runner that uses sudo to execute commands.

func NewRunner

func NewRunner(conn protocol.Connection) (cmd.Runner, error)

NewRunner returns a new cmd.Runner for the connection. Currently the error is always nil.

Types

type Client

type Client struct {
	cmd.Runner

	log.LoggerInjectable

	*PackageManagerService
	*InitSystemService
	*RemoteFSService
	*OSReleaseService
	*SudoService
	// contains filtered or unexported fields
}

Client is a swiss army knife client that can perform actions and run commands on target hosts running on multiple operating systems and using different protocols for communication.

It provides a consistent interface to the host's init system, package manager, file system, and more, regardless of the protocol or the remote operating system. It also provides a consistent interface to the host's operating system's basic functions in a similar manner as the stdlib's os package does for the local system, for example chmod, stat, and so on.

The easiest way to set up a client instance is through a protocol config struct, like protocol/ssh.Config or the unified CompositeConfig and then use the NewClient function to create a new client.

func NewClient

func NewClient(opts ...ClientOption) (*Client, error)

NewClient returns a new Connection object with the given options.

You must use either WithConnection to provide a pre-configured connection or WithConnectionConfigurer to provide a connection configurer.

An example SSH connection via ssh.Config::

client, err := rig.NewClient(WithConnectionConfigurer(&ssh.Config{Address: "10.0.0.1"}))

Using the CompositeConfig struct:

client, err := rig.NewClient(WithConnectionConfigurer(&rig.CompositeConfig{SSH: &ssh.Config{...}}))

If you want to use a pre-configured connection, you can use WithConnection:

conn, err := ssh.NewConnection(ssh.Config{...})
client, err := rig.NewClient(WithConnection(conn))

Once you have a client, you can use it to interact with the remote host.

err := client.Connect(context.Background())
if err != nil {
    log.Fatal(err)
}
out, err := client.ExecOutput("ls")

To see all of the available ways to run commands, see cmd.Executor.

func (*Client) Address

func (c *Client) Address() string

Address returns the address of the host.

func (*Client) Clone

func (c *Client) Clone(opts ...ClientOption) *Client

Clone returns a copy of the connection with the given additional options applied.

func (*Client) Connect

func (c *Client) Connect(ctx context.Context) error

Connect to the host. The connection is attempted until the context is done or the protocol implementation returns an error indicating that the connection can't be established by retrying. If a context without a deadline is used, a 10 second timeout is used.

func (*Client) Disconnect

func (c *Client) Disconnect()

Disconnect from the host.

func (*Client) ExecInteractive

func (c *Client) ExecInteractive(cmd string, stdin io.Reader, stdout, stderr io.Writer) error

ExecInteractive executes a command on the host and passes stdin/stdout/stderr as-is to the session.

func (*Client) FS

func (c *Client) FS() remotefs.FS

FS returns an fs.FS compatible filesystem interface for accessing files on the host.

If the filesystem can't be accessed, a filesystem that returns an error for all operations is returned instead. If you need to handle the error, you can use c.RemoteFSService.GetFS() directly.

func (*Client) OS

func (c *Client) OS() (*os.Release, error)

OS returns the host's operating system version and release information or an error if it can't be determined.

func (*Client) PackageManager

func (c *Client) PackageManager() packagemanager.PackageManager

PackageManager for the host's operating system. This can be used to install or remove packages.

If a known package manager can't be detected, a PackageManager that returns an error for all operations is returned. If you need to handle the error, you can use client.PackageManagerService.GetPackageManager() (packagemanager.PackageManager, error) directly.

func (*Client) Protocol

func (c *Client) Protocol() string

Protocol returns the protocol used to connect to the host.

func (*Client) Service

func (c *Client) Service(name string) (*Service, error)

Service returns a manager for a named service on the remote host using the host's init system if one can be detected. This can be used to start, stop, restart, and check the status of services.

You most likely need to use this with Sudo:

service, err := client.Sudo().Service("nginx")

func (*Client) String

func (c *Client) String() string

String returns a printable representation of the connection, which will usually look something like: `address:port` or `user@address:port`.

func (*Client) Sudo

func (c *Client) Sudo() *Client

Sudo returns a copy of the connection with a Runner that uses sudo.

type ClientOption

type ClientOption func(*ClientOptions)

ClientOption is a functional option type for the Options struct.

func WithConnection

func WithConnection(conn protocol.Connection) ClientOption

WithConnection is a functional option that sets the client to use for connecting instead of getting it from the ConnectionConfigurer.

func WithConnectionConfigurer

func WithConnectionConfigurer(configurer ConnectionConfigurer) ClientOption

WithConnectionConfigurer is a functional option that sets the client configurer to use for connecting.

func WithInitSystemProvider

func WithInitSystemProvider(provider initsystem.InitSystemProvider) ClientOption

WithInitSystemProvider is a functional option that sets the init system provider to use for the connection's InitSystemService.

func WithLogger

func WithLogger(logger log.Logger) ClientOption

WithLogger is a functional option that sets the logger to use for the connection and its child components.

func WithOSReleaseProvider

func WithOSReleaseProvider(provider os.OSReleaseProvider) ClientOption

WithOSReleaseProvider is a functional option that sets the os release provider to use for the connection's OSReleaseService.

func WithPackageManagerProvider

func WithPackageManagerProvider(provider packagemanager.PackageManagerProvider) ClientOption

WithPackageManagerProvider is a functional option that sets the package manager provider to use for the connection's PackageManagerService.

func WithRemoteFSProvider

func WithRemoteFSProvider(provider remotefs.RemoteFSProvider) ClientOption

WithRemoteFSProvider is a functional option that sets the filesystem provider to use for the connection's RemoteFSService.

func WithRetry

func WithRetry(retry bool) ClientOption

WithRetry is a functional option that toggles the connection retry feature. Default is true.

func WithRunner

func WithRunner(runner cmd.Runner) ClientOption

WithRunner is a functional option that sets the runner to use for executing commands.

func WithSudoProvider

func WithSudoProvider(provider sudo.SudoProvider) ClientOption

WithSudoProvider is a functional option that sets the sudo provider to use for the connection's SudoService.

type ClientOptions

type ClientOptions struct {
	log.LoggerInjectable
	// contains filtered or unexported fields
}

ClientOptions is a struct that holds the variadic options for the rig package.

func DefaultClientOptions

func DefaultClientOptions() *ClientOptions

DefaultClientOptions returns a new Options struct with the default options applied.

func NewClientOptions

func NewClientOptions(opts ...ClientOption) *ClientOptions

NewClientOptions creates a new Options struct with the supplied options applied over the defaults.

func (*ClientOptions) Apply

func (o *ClientOptions) Apply(opts ...ClientOption)

Apply applies the supplied options to the Options struct.

func (*ClientOptions) Clone

func (o *ClientOptions) Clone() *ClientOptions

Clone returns a copy of the Options struct.

func (*ClientOptions) GetConnection

func (o *ClientOptions) GetConnection() (protocol.Connection, error)

GetConnection returns the connection to use for the rig client. If no connection is set, it will use the ConnectionConfigurer to create one.

func (*ClientOptions) GetRunner

func (o *ClientOptions) GetRunner(conn protocol.Connection) cmd.Runner

GetRunner returns the runner to use for the rig client.

func (*ClientOptions) ShouldRetry

func (o *ClientOptions) ShouldRetry() bool

ShouldRetry returns whether the connection should be retried.

func (*ClientOptions) Validate

func (o *ClientOptions) Validate() error

Validate the options.

type ClientWithConfig

type ClientWithConfig struct {
	ConnectionConfig CompositeConfig `yaml:",inline"`
	*Client          `yaml:"-"`
	// contains filtered or unexported fields
}

ClientWithConfig is a Client that is suitable for embedding into a host object that is unmarshalled from YAML configuration.

When embedded into a "host" object like this:

type Host struct {
  rig.ClientWithConfig `yaml:",inline"`
  // ...
}

And having a configuration YAML like this:

hosts:
- ssh:
  address: 10.0.0.1
  user: root

You can unmarshal the configuration and start using the clients on the host objects:

if err := host.Connect(context.Background()); err != nil {
    log.Fatal(err)
}
out, err := host.ExecOutput("ls")

The available protocols are defined in the CompositeConfig struct.

func (*ClientWithConfig) Connect

func (c *ClientWithConfig) Connect(ctx context.Context, opts ...ClientOption) error

Connect to the host. Unlike in Client.Connect, the Connect method here accepts a variadic list of options similar to NewClient. This is to allow configuring the connection before connecting, since you won't be calling NewClient to create the ClientWithConfig instance when unmarshalling from a configuration file.

func (*ClientWithConfig) Setup

func (c *ClientWithConfig) Setup(opts ...ClientOption) error

Setup allows applying options to the connection to configure subcomponents.

func (*ClientWithConfig) UnmarshalYAML

func (c *ClientWithConfig) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements the yaml.Unmarshaler interface, it unmarshals and sets up a connection from a YAML configuration.

type CompositeConfig

type CompositeConfig struct {
	SSH       *ssh.Config     `yaml:"ssh,omitempty"`
	WinRM     *winrm.Config   `yaml:"winRM,omitempty"`
	OpenSSH   *openssh.Config `yaml:"openSSH,omitempty"`
	Localhost bool            `yaml:"localhost,omitempty"`
}

CompositeConfig is a composite configuration of all the protocols supported out of the box by rig. It is intended to be embedded into host structs that are unmarshaled from configuration files.

func (*CompositeConfig) Connection

func (c *CompositeConfig) Connection() (protocol.Connection, error)

Connection returns a connection for the first configured protocol.

func (*CompositeConfig) String

func (c *CompositeConfig) String() string

String returns the string representation of the first configured protocol configuration.

func (*CompositeConfig) UnmarshalYAML

func (c *CompositeConfig) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements the yaml.Unmarshaler interface.

func (*CompositeConfig) Validate

func (c *CompositeConfig) Validate() error

Validate the configuration.

type ConnectionConfigurer

type ConnectionConfigurer interface {
	fmt.Stringer
	Connection() (protocol.Connection, error)
}

ConnectionConfigurer can create connections. When a connection is not given, the configurer is used to build a connection.

type InitSystemService

type InitSystemService = initsystem.Service

InitSystemService is a type alias for initsystem.Service.

type OSReleaseService

type OSReleaseService = os.Service

OSReleaseService is a type alias for os.Service.

type PackageManagerService

type PackageManagerService = packagemanager.Service

PackageManagerService is a type alias for packagemanager.Service.

type RemoteFSService

type RemoteFSService = remotefs.Service

RemoteFSService is a type alias for remotefs.Service.

type Service

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

Service running on a host.

func GetService

func GetService(runner cmd.ContextRunner, name string) (*Service, error)

GetService returns a manager for a single service using an auto-detected service manager implementation from the default providers.

func (*Service) Disable

func (m *Service) Disable(ctx context.Context) error

Disable the service.

func (*Service) Enable

func (m *Service) Enable(ctx context.Context) error

Enable the service.

func (*Service) IsRunning

func (m *Service) IsRunning(ctx context.Context) bool

IsRunning returns true if the service is running.

func (*Service) Logs

func (m *Service) Logs(ctx context.Context, lines int) ([]string, error)

Logs returns latest log lines for the service.

func (*Service) Name

func (m *Service) Name() string

Name returns the name of the service.

func (*Service) Restart

func (m *Service) Restart(ctx context.Context) error

Restart the service.

func (*Service) ScriptPath

func (m *Service) ScriptPath(ctx context.Context) (string, error)

ScriptPath returns the path to the service script.

func (*Service) Start

func (m *Service) Start(ctx context.Context) error

Start the service.

func (*Service) Stop

func (m *Service) Stop(ctx context.Context) error

Stop the service.

func (*Service) String

func (m *Service) String() string

String returns a string representation of the service.

type SudoService

type SudoService = sudo.Service

SudoService is a type alias for sudo.Service.

Directories

Path Synopsis
Package byteslice contains functions for working with byte slices.
Package byteslice contains functions for working with byte slices.
Package cmd defines types and functions for running commands.
Package cmd defines types and functions for running commands.
Package homedir provides functions for expanding paths like ~/.ssh.
Package homedir provides functions for expanding paths like ~/.ssh.
Package initsystem provides a common interface for interacting with init systems like systemd, openrc, sysvinit, etc.
Package initsystem provides a common interface for interacting with init systems like systemd, openrc, sysvinit, etc.
Package iostream contains various io.Reader and io.Writer implementations.
Package iostream contains various io.Reader and io.Writer implementations.
Package kv is for working with key-value pair files and strings often found in configuration files, environment variables, and other sources.
Package kv is for working with key-value pair files and strings often found in configuration files, environment variables, and other sources.
Package log contains rig's logging related types, constants and functions.
Package log contains rig's logging related types, constants and functions.
Package os provides remote OS release information detection
Package os provides remote OS release information detection
Package packagemanager provides a generic interface for package managers.
Package packagemanager provides a generic interface for package managers.
Package plumbing defines generic types for the dependency injection mechanisms in rig.
Package plumbing defines generic types for the dependency injection mechanisms in rig.
Package powershell provides helpers for powershell command generation
Package powershell provides helpers for powershell command generation
Package protocol contains the interfaces for the protocol implementations
Package protocol contains the interfaces for the protocol implementations
localhost
Package localhost provides a rig protocol implementation to the local host using the os/exec package.
Package localhost provides a rig protocol implementation to the local host using the os/exec package.
openssh
Package openssh provides a rig protocol implementation that uses the system's openssh client "ssh" to connect to remote hosts.
Package openssh provides a rig protocol implementation that uses the system's openssh client "ssh" to connect to remote hosts.
ssh
Package ssh provides a rig protocol implementation for SSH connections.
Package ssh provides a rig protocol implementation for SSH connections.
ssh/agent
Package agent provides a client implementation for the SSH agent.
Package agent provides a client implementation for the SSH agent.
ssh/hostkey
Package hostkey implements a callback for the ssh.ClientConfig.HostKeyCallback
Package hostkey implements a callback for the ssh.ClientConfig.HostKeyCallback
winrm
Package winrm provides a rig protocol implementation for WinRM connections
Package winrm provides a rig protocol implementation for WinRM connections
Package redact provides redaction of sensitive information from strings or streams.
Package redact provides redaction of sensitive information from strings or streams.
Package remotefs provides fs.FS implementations for remote filesystems.
Package remotefs provides fs.FS implementations for remote filesystems.
Package retry provides context based retry functionality for functions.
Package retry provides context based retry functionality for functions.
Package rigtest provides testing utilities for mocking functionality of the rig package.
Package rigtest provides testing utilities for mocking functionality of the rig package.
sh
Package sh provides tools to build and manipulate shell commands.
Package sh provides tools to build and manipulate shell commands.
shellescape
Package shellescape provides functions to escape strings for use in posix shell commands.
Package shellescape provides functions to escape strings for use in posix shell commands.
Package stattime provides time comparison functions that work with times up to the finest common precision.
Package stattime provides time comparison functions that work with times up to the finest common precision.
Package sudo provides support for various methods of running commands with elevated privileges.
Package sudo provides support for various methods of running commands with elevated privileges.

Jump to

Keyboard shortcuts

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