client

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2023 License: GPL-3.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoTeamclient indicates that the client cannot remotely query a server
	// to get its version or user information, because there is no client RPC
	// to do it. Make sure that your team/client.Client has been given one.
	ErrNoTeamclient = errors.New("this teamclient has no client implementation")

	// ErrConfig is an error related to the teamclient connection configuration.
	ErrConfig = errors.New("client config error")

	// ErrNoConfig indicates that no configuration, default or on file system, was found.
	ErrNoConfig = errors.New("no client configuration was selected or parsed")

	// ErrConfigNoUser says that the configuration has no user,
	// which is not possible even if the client is an in-memory one.
	ErrConfigNoUser = errors.New("client config with empty user")

	// ErrClient indicates an error raised by the client when igniting or connecting.
	// Most errors are raised by the underlying transport stack, which can be user-specific,
	// so users of this library should unwrap ErrClient errors to check against their owns.
	ErrClient = errors.New("teamclient dialer")
)

Functions

This section is empty.

Types

type Client

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

Client is the core driver of an application teamclient. It provides the core tools needed by any application/program to be the client of an local/remote/in-memory teamserver.

This client object is by default not connected to any teamserver, and has therefore no way of fulfilling its core duties, on purpose. The client also DOES NOT include any teamserver-side code.

This teamclient core job is to:

  • Fetch, configure and use teamserver endpoint configurations.
  • Drive the process of connecting to & disconnecting from a server.
  • Query a teamserver for its version and users information.

Additionally, this client offers:

  • Pre-configured loggers for all client-side related events.
  • Various options to configure its backends and behaviors.
  • A builtin, abstracted and app-specific filesystem (in memory or on disk).

Various combinations of teamclient/teamserver usage are possible. Please see the Go module example/ directory for a list of them.

func New

func New(app string, client team.Client, options ...Options) (*Client, error)

New is the required constructor of a new application teamclient. Parameters:

  • The name of the application using the teamclient.
  • Variadic options (...Options) which are applied at creation time.
  • A type implementing the team.Client interface.

Depending on constraints and use cases, the client uses different backends and/or RPC implementations providing this functionality:

  • When used in-memory and as a client of teamserver.
  • When being provided a specific dialer/client/RPC backend.

The teamclient will only perform a few init things before being returned:

  • Setup its filesystem, either on-disk (default behavior) or in-memory.
  • Initialize loggers and the files they use, if any.

This may return an error if the teamclient is unable to work with the provided options (or lack thereof), which may happen if the teamclient cannot use and write to its directories and log files. No client is returned if the error is not nil.

func (*Client) Config

func (tc *Client) Config() *Config

Config returns the currently used teamclient server configuration. This configuration might be empty (not nil), if no specific server configuration was loaded by the client yet.

func (*Client) ConfigsDir

func (tc *Client) ConfigsDir() string

ConfigsDir returns the path to the remote teamserver configs directory for this application (~/.app/teamclient/configs), creating the directory if needed, or logging a fatal event if failing to create it.

func (*Client) Connect

func (tc *Client) Connect(options ...Options) (err error)

Connect uses the default client configurations to connect to the teamserver.

This call might be blocking and expect user input: if multiple server configurations are found in the application directory, the application will prompt the user to choose one of them. If the teamclient was created WithConfig() option, or if passed in this call, user input is guaranteed NOT to be needed.

It only connects the teamclient if it has an available dialer. If none is available, this function returns no error, as it is possible that this client has a teamclient implementation ready.

func (*Client) Disconnect

func (tc *Client) Disconnect() error

Disconnect disconnects the client from the server, closing the connection and the client log file. Any errors are logged to this file and returned. If the teamclient has been passed the WithNoDisconnect() option, it won't disconnect.

func (*Client) Filesystem

func (tc *Client) Filesystem() *assets.FS

Filesystem returns an abstract filesystem used by the teamclient. This filesystem can be either of two things:

  • By default, the on-disk filesystem, without any specific bounds.
  • If the teamclient was created with the InMemory() option, a full in-memory filesystem (with root `.app/`).

Use cases for this filesystem might include:

  • The wish to have a fully abstracted filesystem to work for testing
  • Ensuring that the filesystem code in your application remains the same regardless of the underlying, actual filesystem.

The type returned is currently an internal type because it wraps some os.Filesystem methods for working more transparently: this may change in the future if the Go stdlib offers write support to its new io/fs.FS.

func (*Client) GetConfigs

func (tc *Client) GetConfigs() map[string]*Config

GetConfigs returns a list of available configs in the application teamclient remote server configs directory (~/.app/teamclient/configs/).

This uses the on-disk filesystem even if the teamclient is in memory mode.

func (*Client) HomeDir

func (tc *Client) HomeDir() string

HomeDir returns the root application directory (~/.app/ by default). This directory can be set with the environment variable <APP>_ROOT_DIR. This directory is not to be confused with the ~/.app/teamclient directory returned by the client.TeamDir(), which is specific to the app teamclient.

func (*Client) LogsDir

func (tc *Client) LogsDir() string

LogsDir returns the directory of the teamclient logs (~/.app/logs), creating the directory if needed, or logging a fatal event if failing to create it.

func (*Client) Name

func (tc *Client) Name() string

Name returns the name of the client application.

func (*Client) NamedLogger

func (tc *Client) NamedLogger(pkg, stream string) *logrus.Entry

NamedLogger returns a new logging "thread" with two fields (optional) to indicate the package/general domain, and a more precise flow/stream. The events are logged according to the teamclient logging backend setup.

func (*Client) NewTLSConfigFrom

func (tc *Client) NewTLSConfigFrom(caCert string, cert string, key string) (*tls.Config, error)

NewTLSConfigFrom generates a working client TLS configuration prepared for Mutual TLS. It requires the three credential materials presents in any user remote teamserver config.

func (*Client) ReadConfig

func (tc *Client) ReadConfig(confFilePath string) (*Config, error)

ReadConfig loads a client config into a struct. Errors are returned as is: users can check directly for JSON/encoding/filesystem errors.

This uses the on-disk filesystem even if the teamclient is in memory mode.

func (*Client) SaveConfig

func (tc *Client) SaveConfig(config *Config) error

SaveConfig saves a client config to disk.

This uses the on-disk filesystem even if the teamclient is in memory mode.

func (*Client) SelectConfig

func (tc *Client) SelectConfig() *Config

SelectConfig either returns the only configuration found in the app client remote configs directory, or prompts the user to select one. This call might thus be blocking, and expect user input.

This uses the on-disk filesystem even if the teamclient is in memory mode.

func (*Client) SetLogLevel

func (tc *Client) SetLogLevel(level int)

SetLogLevel sets the logging level of all teamclient loggers.

func (*Client) SetLogWriter

func (tc *Client) SetLogWriter(stdout, stderr io.Writer)

SetLogWriter sets the stream to which the stdio logger (not the file logger) should write to. This option is used by the teamclient cobra command tree to synchronize its basic I/O/err with the teamclient backend.

func (*Client) TeamDir

func (tc *Client) TeamDir() string

TeamDir returns the teamclient directory of the app (named ~/.<app>/teamclient/), creating the directory if needed, or logging an error event if failing to create it. This directory is used to store teamclient logs and remote server configs.

func (*Client) Users

func (tc *Client) Users() (users []team.User, err error)

Users returns a list of all users registered to the application server. If the teamclient has no backend, it returns an ErrNoTeamclient error. If the backend returns an error, the latter is returned as is.

func (*Client) VersionClient

func (tc *Client) VersionClient() (ver team.Version, err error)

VersionClient returns the version information of the client, and thus does not require the teamclient to be connected to a teamserver. This function satisfies the VersionClient() function of the team.Client interface, which means that library users are free to reimplement it however they wish.

func (*Client) VersionServer

func (tc *Client) VersionServer() (ver team.Version, err error)

VersionServer returns the version information of the server to which the client is connected. If the teamclient has no backend, it returns an ErrNoTeamclient error. If the backend returns an error, the latter is returned as is.

type Config

type Config struct {
	User          string `json:"user"` // This value is actually ignored for the most part (cert CN is used instead)
	Host          string `json:"host"`
	Port          int    `json:"port"`
	Token         string `json:"token"`
	CACertificate string `json:"ca_certificate"`
	PrivateKey    string `json:"private_key"`
	Certificate   string `json:"certificate"`
}

Config is a JSON client connection configuration. It contains the addresses of a team server, the name of the user allowed to connect to it, and cryptographic material to secure and authenticate the client-server connection (using Mutual TLS).

type Dialer

type Dialer interface {
	// Init is used by any dialer to query the teamclient driving it about:
	//   - The remote teamserver address and transport credentials
	//   - The user registered in this remote teamserver configuration.
	//   - To make use of client-side loggers, filesystem and other utilities.
	Init(c *Client) error

	// Dial should connect to the endpoint available in any
	// of the client remote teamserver configurations.
	Dial() error

	// Close should close the connection or any related component.
	Close() error
}

Dialer represents a type using a teamclient core (and its configured teamserver remote) to setup, initiate and use a connection to this remote teamserver.

The type parameter `clientConn` of this interface is a purely syntactic sugar to indicate that any dialer should/may return a user-defined but specific object from its Dial() method. Library users can register hooks to the teamclient.Client using this dialer, and this clientConn will be provided to these hooks.

Examples of what this clientConn can be:

  • The clientConn is a specific, but non-idiomatic RPC client (ex: a *grpc.ClientConn).
  • A simple net.Conn over which anything can be done further.
  • Nothing: a dialer might not need to use or even create a client connection.

type Options

type Options func(opts *opts)

Options are client options. You can set or modify the behavior of a teamclient at various steps with these options, which are a variadic parameter of several client.Client methods. Note that some options can only be used once, while others can be used multiple times. Examples of the former are log files, while the latter includes dialers/hooks. Each option will specify this in its description.

func WithConfig

func WithConfig(config *Config) Options

WithConfig sets the client to use a given remote teamserver configuration which to connect to, instead of using default on-disk user/application configurations. This function will be very useful to library users who wish to implement specific remote teamserver selection & connection strategies, depending on the domains and and use cases of these tools.

func WithDialer

func WithDialer(dialer Dialer) Options

WithDialer sets a custom dialer to connect to the teamserver. See the Dialer type documentation for implementation/usage details.

It accepts an optional list of hooks to run on the generic clientConn returned by the client.Dialer Dial() method (see Dialer doc for details). This client object can be pretty much any client-side conn/RPC object. You will have to typecast this conn in your hooks, casting it to the type that your teamclient Dialer.Dial() method returns.

This option can be used multiple times, either when using team/client.New() or when using the teamclient.Connect() method.

func WithHomeDirectory

func WithHomeDirectory(path string) Options

WithHomeDirectory sets the default path (~/.app/) of the application directory. This path can still be overridden at the user-level with the env var APP_ROOT_DIR.

This option can only be used once, and must be passed client.New().

func WithInMemory

func WithInMemory() Options

WithInMemory deactivates all interactions of the client with the on-disk filesystem. This will in effect use in-memory files for all file-based logging and database data. This might be useful for testing, or if you happen to embed a teamclient in a program without the intent of using it now, etc.

This option can only be used once, and should be passed client.New().

func WithLogFile

func WithLogFile(filePath string) Options

WithLogFile sets the path to the file where teamclient logging should be done. If not specified, the client log file is ~/.app/teamclient/logs/app.teamclient.log.

This option can only be used once, and should be passed client.New().

func WithLogger

func WithLogger(logger *logrus.Logger) Options

WithLogger sets the teamclient to use a specific logger for logging.

This option can only be used once, and should be passed client.New().

func WithNoDisconnect

func WithNoDisconnect() Options

WithNoDisconnect is meant to be used when the teamclient commands are used in a closed-loop (readline-style) application, where the connection is used more than once in the lifetime of the Go program. If this is the case, this option will ensure that any cobra client command runners produced by this library will not disconnect after each execution.

This option can only be used once, and should be passed client.New().

func WithNoLogs

func WithNoLogs(noLogs bool) Options

WithNoLogs deactivates all logging normally done by the teamclient if noLogs is set to true, or keeps/reestablishes them if false.

This option can only be used once, and should be passed client.New().

func WithTeamDirectory

func WithTeamDirectory(name string) Options

WithTeamDirectory sets the name (not a path) of the teamclient-specific subdirectory. For example, passing "my_team_dir" will make the teamclient use ~/.app/my_team_dir/ instead of ~/.app/teamclient/. If this function is called with an empty string, the teamclient will not use any subdirectory for its own outputs, thus using ~/.app as its teamclient directory.

This option can only be used once, and should be passed client.New().

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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