provider

package module
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2024 License: MPL-2.0 Imports: 24 Imported by: 7

README

HCP SCADA Provider build badge

SCADA is an internal component of the infrastructure of the Hashicorp Cloud Platform control plane and it stands for Supervisory Control And Data Acquisition. It provides HCP with access to functions and data on HCP-managed clusters.

The provider package establishes and maintains a long-lived connection to allow incoming requests to be served by components running in relative network isolation.

SCADA is a variation on a NAT traversal technique.

Who uses it

It's in use internally at Hashicorp.

License

Mozilla Public License v2.0

Documentation

Index

Constants

View Source
const (
	// SessionStatusDisconnected is the state of the SCADA session if the
	// provider has not been started or has been stopped.
	SessionStatusDisconnected = SessionStatus("disconnected")

	// SessionStatusConnecting is the initial state of the SCADA connection
	// as well as the state it will be in if the connection got disrupted and
	// the library is trying to reconnect.
	//
	// The connection will transition to connected once the SCADA session is
	// established.
	SessionStatusConnecting = SessionStatus("connecting")

	// SessionStatusConnected is the state of the SCADA session if the
	// session is established and active.
	SessionStatusConnected = SessionStatus("connected")

	// SessionStatusRetrying is the state of a SCADA session that was
	// previous connected and is now in a wait-connect cycle
	SessionStatusWaiting = SessionStatus("waiting")
)

Variables

View Source
var (
	// these are provider side errors
	ErrProviderNotStarted = errors.New("the provider is not started")                            // the provider is not started
	ErrInvalidCredentials = errors.New("could not obtain a token with the supplied credentials") // could not obtain a token with the configured credentials
	// this is a broker side error
	ErrPermissionDenied = errors.New("principal does not have the permision to register as a provider") // the principal behind the creds does not have permission to register as provider.
)
View Source
var ErrorPrefixes = map[error]string{
	ErrProviderNotStarted: "ErrProviderNotStarted",
	ErrInvalidCredentials: "ErrInvalidCredentials",
	ErrPermissionDenied:   "ErrPermissionDenied",
}

ErrorPrefixes maintains a mapping between error types and their variable names. The broker is using those to return error codes over RPC connections. RPC calls provide only the type returned by errors.New().

Functions

func NewTimeError

func NewTimeError(err error) timeError

NewTimeError tries to map err to one of the known error values in ErrorPrefixes and it returns a timeError value set to either the error it found in ErrorPrefixes, or set to the caller's err. Time is always set to Now().

Its used to return error codes over RPC connections because RPC calls provide only the type returned by errors.New().

We encode the type that is meant to be returned in the error string as the first value, followed with a ":'.

return fmt.Errorf("%s: a problem happened with a function: %v", provider.ErrorPrefixes[ErrPermissionDenied], errors.New("a IO problem"))

func PrefixError added in v0.1.1

func PrefixError(text string, err error) error

PrefixError prefixes a known err error with prefixes from ErrorPrefixes, depending on the type of err. It then adds text. If it does not find a prefix in err, it will just process text and err into fmt.Errorf("%s: %w", text, err). If text is not specified, it will return the equivalent of just err.

Supported error to prefix maps are:

  • *oauth2.RetrieveError maps to ErrInvalidCredentials if RetrieveError.StatusCode == 401
  • grpc *status.Status maps to ErrPermissionDenied if Status.Code == codes.PermissionDenied

A classic example would look like this:

func Prefix() {
	err := PrefixError("failed to get access token", &oauth2.RetrieveError{})
	fmt.Printf("%v", err) // "ErrInvalidCredentials: failed to get access token: %w"
}

Types

type Config

type Config struct {
	// Service is the name to identify the client.
	Service string

	// Resource contains information about the Resource the provider will
	// register as.
	Resource cloud.HashicorpCloudLocationLink

	// HCPConfig is the HCP specific configuration, it provides information
	// necessary to talk to HCP APIs.
	HCPConfig sdk.HCPConfig

	// Logger is the Logger to use for logs.
	Logger hclog.Logger

	// TestBackoff is used to force the provider to retry more aggressively.
	TestBackoff time.Duration
}

Config is used to parameterize a provider

func (*Config) Validate

func (c *Config) Validate() error

type ConnectRequest

type ConnectRequest struct {
	Capability string
	Meta       map[string]string

	Severity string
	Message  string
}

ConnectRequest holds parameters for the broker RPC Connect call to the provider.

type ConnectResponse

type ConnectResponse struct {
	Success bool
}

ConnectResponse is the response to a Connect RPC call.

type DisconnectRequest

type DisconnectRequest struct {
	NoRetry bool          // Should the client retry
	Backoff time.Duration // Minimum backoff
	Reason  string
}

DisconnectRequest holds parameters for the broker RPC Disconnect call to the provider.

type DisconnectResponse

type DisconnectResponse struct {
}

DisconnectResponse is the response to a Disconnect RPC call.

type Meta added in v0.2.2

type Meta struct {
	Key, Value string
}

type Provider

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

Provider is a high-level interface to SCADA by which instances declare themselves as a Service providing capabilities. Provider manages the client/server interactions required, making it simpler to integrate.

func (*Provider) AddMeta added in v0.2.2

func (p *Provider) AddMeta(metas ...Meta)

AddMeta upserts keys and values in the internal map of meta-data and performs a re-handshake to update the remote broker.

func (*Provider) DeleteMeta added in v0.2.2

func (p *Provider) DeleteMeta(keys ...string)

DeleteMeta delete keys from the meta-date values and then perform a re-handshake to update the remote broker.

func (*Provider) GetMeta

func (p *Provider) GetMeta() map[string]string

GetMeta returns the provider's current meta-data. The returned map is a copy and can be updated or modified.

func (*Provider) LastError

func (p *Provider) LastError() (time.Time, error)

LastError returns the last error recorded in the provider connection state engine as well as the time at which the error occured. That record is erased at each occasion when the provider achieves a new connection.

A few common internal error will return a known type:

  • ErrProviderNotStarted: the provider is not started
  • ErrInvalidCredentials: could not obtain a token with the supplied credentials
  • ErrPermissionDenied: principal does not have the permision to register as a provider

Any other internal error will be returned directly and unchanged.

func (*Provider) Listen

func (p *Provider) Listen(capability string) (net.Listener, error)

Listen will expose the provided capability and make new connections available through the returned listener. Closing the listener will stop exposing the provided capability.

The method will return an existing listener if the capability already existed. Listeners can be retrieved even when the provider is stopped (e.g. before it is started). New capabilities and new meta data can be added at any time.

The listener will only be closed, if it is closed explicitly by calling Close(). The listener will not be closed due to errors or when the provider is stopped. The listener can hence be used after a restart of the provider.

func (*Provider) SessionStatus

func (p *Provider) SessionStatus() SessionStatus

SessionStatus returns the status of the SCADA connection.

The possibles statuses are:

  • SessionStatusDisconnected: the provider is stopped
  • SessionStatusConnecting: in the connect/handshake cycle
  • SessionStatusConnected: connected and serving scada consumers
  • SessionStatusWaiting: disconnected and waiting to retry a connection to the broker

The full lifecycle is: connecting -> connected -> waiting -> connecting -> ... -> disconnected.

func (*Provider) Start

func (p *Provider) Start() error

Start will register the provider on the SCADA broker and expose the registered capabilities.

func (*Provider) Stop

func (p *Provider) Stop() error

Stop will gracefully close the currently active SCADA session. This will not close the capability listeners.

func (*Provider) UpdateConfig added in v0.2.4

func (p *Provider) UpdateConfig(config *Config) error

UpdateConfig overwrites the provider's configuration with the given configuration.

func (*Provider) UpdateMeta

func (p *Provider) UpdateMeta(m map[string]string)

UpdateMeta overwrites the internal map of meta-data values and performs a re-handshake to update the remote broker.

type SCADAProvider

type SCADAProvider interface {
	// UpdateMeta overwrites the internal map of meta-data values
	// and performs a re-handshake to update the remote broker.
	UpdateMeta(map[string]string)

	// AddMeta upserts keys and values in the internal map of meta-data
	// and performs a re-handshake to update the remote broker.
	AddMeta(...Meta)

	// DeleteMeta delete keys from the meta-date values and then perform a
	// re-handshake to update the remote broker.
	DeleteMeta(...string)

	// GetMeta returns the provider's current meta-data.
	GetMeta() map[string]string

	// Listen will expose the provided capability and make new connections
	// available through the returned listener. Closing the listener will stop
	// exposing the provided capability.
	//
	// The method will return an existing listener if the capability already existed.
	// Listeners can be retrieved even when the provider is stopped (e.g. before it is
	// started). New capabilities and new-meta data can be added at any time.
	//
	// The listener will only be closed, if it is closed explicitly by calling Close().
	// The listener will not be closed due to errors or when the provider is stopped.
	// The listener can hence be used after a restart of the provider.
	Listen(capability string) (net.Listener, error)

	// Start will register the provider on the SCADA broker and expose the
	// registered capabilities.
	Start() error

	// Stop will try to gracefully close the currently active SCADA session. This will
	// not close the capability listeners.
	Stop() error

	// SessionStatus returns the status of the SCADA connection.
	//
	// The possibles statuses are:
	//   - SessionStatusDisconnected: the provider is stopped
	//   - SessionStatusConnecting:   in the connect/handshake cycle
	//   - SessionStatusConnected:    connected and serving scada consumers
	//   - SessionStatusWaiting:      disconnected and waiting to retry a connection to the broker
	//
	// The full lifecycle is: connecting -> connected -> waiting -> connecting -> ... -> disconnected.
	SessionStatus() SessionStatus

	// LastError returns the last error recorded in the provider
	// connection state engine as well as the time at which the error occured.
	// That record is erased at each occasion when the provider achieves a new connection.
	//
	// A few common internal error will return a known type:
	//   - ErrProviderNotStarted: the provider is not started
	//   - ErrInvalidCredentials: could not obtain a token with the supplied credentials
	//   - ErrPermissionDenied:   principal does not have the permision to register as a provider
	//
	// Any other internal error will be returned directly and unchanged.
	LastError() (time.Time, error)

	// UpdateConfig overwrites the provider's configuration with the given configuration.
	UpdateConfig(config *Config) error
}

SCADAProvider allows to expose services via SCADA capabilities.

func New

func New(config *Config) (SCADAProvider, error)

New creates a new SCADA provider instance using the configuration in config.

type SessionStatus

type SessionStatus = string

SessionStatus is used to express the current status of the SCADA session.

Directories

Path Synopsis
internal
listener
listener is a capability that pushes the received connection into a net.Listener.
listener is a capability that pushes the received connection into a net.Listener.

Jump to

Keyboard shortcuts

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