config

package
v0.1.0-alpha.0...-2488347 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2022 License: GPL-3.0 Imports: 16 Imported by: 9

Documentation

Index

Constants

View Source
const (
	// Yaml-extension configuration files.
	ExtYaml = "yaml"
)

Definitions of supported configuration file types.

Variables

View Source
var (
	ErrInvalidTransform = errors.New("invalid transform config: must have only one of: 'apply', 'scale'")
)

Errors for device configuration validation.

Functions

This section is empty.

Types

type CacheSettings

type CacheSettings struct {
	// Enabled determines whether a plugin will use a local in-memory cache
	// to store a small window of readings. It is disabled by default.
	Enabled bool `default:"false" yaml:"enabled,omitempty"`

	// TTL is the time-to-live for a reading in the readings cache. This will
	// only be used if the cache is enabled. Once a reading exceeds this TTL,
	// it is removed from the cache.
	TTL time.Duration `default:"3m" yaml:"ttl,omitempty"`
}

CacheSettings are the settings for an in-memory windowed cache of plugin readings.

func (*CacheSettings) Log

func (conf *CacheSettings) Log()

Log logs out the config at INFO level.

type DeviceAlias

type DeviceAlias struct {
	// Name is the pre-defined, hardcoded name for the alias.
	Name string `yaml:"name,omitempty"`

	// Template is a Go template string that will be rendered into
	// an alias string by the SDK.
	Template string `yaml:"template,omitempty"`
}

DeviceAlias defines the configuration for setting a device alias.

type DeviceInstance

type DeviceInstance struct {
	// Type is the type of device. Device types are not strictly defined and
	// are primarily used as metadata for the high-level consumer to help
	// identify and categorize the device. Example types are: LED, fan,
	// temperature, humidity, power, etc.
	//
	// The type should be descriptive and categorical, but is not well-defined,
	// meaning that devices are free to define their own types.
	Type string `yaml:"type,omitempty"`

	// Info is a string which provides a short human-understandable description
	// or summary of the device instance.
	Info string `yaml:"info,omitempty"`

	// Tags contains the set of tags which apply to the device instance. It
	// is not required to define tags. All devices will get system-generated
	// tags, so these are supplemental.
	Tags []string `yaml:"tags,omitempty"`

	// Context defines any context information which should be associated with
	// the device instance's reading(s). Any values specified here will be
	// applied to the reading context automatically by the SDK.
	Context map[string]string `yaml:"context,omitempty"`

	// Data contains any protocol/plugin/device-specific configuration that
	// is associated with the device instance. It is the responsibility of the
	// plugin to handle these values correctly.
	Data map[string]interface{} `yaml:"data,omitempty"`

	// Output specifies the name of the Output that this device instance
	// will use. This is not needed for all devices/plugins, as many DeviceHandlers
	// will already know which output to use. This field is used in cases of
	// generalized plugins, such as Modbus-IP, where a generalized handler
	// will need to map something (like a set of registers) to a reading output.
	Output string `yaml:"output,omitempty"`

	// SortIndex is a 1-based index that can be used to sort devices in a
	// Synse Server scan. The zero value (0) designates no special sorting
	// for the device.
	SortIndex int32 `yaml:"sortIndex,omitempty"`

	// Handler is the name of the plugin's DeviceHandler that will be used to
	// interface with this device.
	Handler string `yaml:"handler,omitempty"`

	// Alias defines an alias that can be used to reference the device. The
	// alias can either be a pre-defined string, or a template which will
	// be rendered by the SDK.
	//
	// It is up to the configurer to ensure that there are no alias collisions.
	// The SDK can check to ensure no collisions within a single plugin, but
	// can not do so across multiple plugins which may be active in the system.
	Alias *DeviceAlias `yaml:"alias,omitempty"`

	// Transforms define a collection of operations to apply to the device's
	// reading values to transform it. This could be done for scaling, conversion,
	// etc. See the TransformConfig godoc for details on its configuration.
	//
	// Transforms are applied in the order in which they are specified. That is
	// to say, with the transforms [scale, apply], the scale operation would happen
	// before the apply operation.
	//
	// If both the prototype and the instance specify transform, the prototype
	// transforms are applied first in order, followed by the instance
	// transforms in order.
	Transforms []*TransformConfig `yaml:"transforms,omitempty"`

	// WriteTimeout defines a custom write timeout for the device instance. This
	// is the time within which the write transaction will remain valid. If left
	// unspecified, it will fall back to the default value of 30s.
	WriteTimeout time.Duration `yaml:"writeTimeout,omitempty"`

	// DisableInheritance determines whether the device instance should inherit
	// from its device prototype.
	DisableInheritance bool `default:"false" yaml:"disableInheritance,omitempty"`
}

DeviceInstance defines the instance-specific configuration for a device.

type DeviceProto

type DeviceProto struct {
	// Type is the type of device. Device types are not strictly defined and
	// are primarily used as metadata for the high-level consumer to help
	// identify and categorize the device. Example types are: LED, fan,
	// temperature, humidity, power, etc.
	//
	// The type should be descriptive and categorical, but is not well-defined,
	// meaning that devices are free to define their own types.
	Type string `yaml:"type,omitempty"`

	// Tags contains the set of tags to apply to each of the devices that
	// are instances of this prototype. It is not required to define tags.
	// All devices will get system-generated tags, so these are supplemental.
	Tags []string `yaml:"tags,omitempty"`

	// Data is any data that can be applied to each of the devices that are
	// instances of this prototype. If specified, this data will be merged
	// with any instance data, where the instance data will override any
	// conflicting values.
	Data map[string]interface{} `yaml:"data,omitempty"`

	// Handler is the name of the plugin's DeviceHandler that will be used
	// for instances of the device prototype. All instances will inherit
	// this handler, but can override.
	Handler string `yaml:"handler,omitempty"`

	// WriteTimeout defines a custom write timeout for all instances of
	// the device prototype. This is the time within which the write
	// transaction will remain valid. If left unspecified, it will fall
	// back to the default value of 30s.
	WriteTimeout time.Duration `yaml:"writeTimeout,omitempty"`

	// Context defines any context information which should be associated
	// with a device instance's reading(s). If specified here, all prototype
	// instances will inherit the context, unless inheritance is disabled.
	Context map[string]string `yaml:"context,omitempty"`

	// Transforms define a collection of operations to apply to the device's
	// reading values to transform it. This could be done for scaling, conversion,
	// etc. See the TransformConfig godoc for details on its configuration.
	//
	// Transforms are applied in the order in which they are specified. That is
	// to say, with the transforms [scale, apply], the scale operation would happen
	// before the apply operation.
	//
	// The transforms defined here will inherited by all instances, unless
	// inheritance is disabled. If both the prototype and the instance specify
	// transform, the prototype transforms are applied first in order, followed
	// by the instance transforms in order.
	Transforms []*TransformConfig `yaml:"transforms,omitempty"`

	// Instances contains the data for all configured instances of the
	// device prototype.
	Instances []*DeviceInstance `yaml:"instances,omitempty"`
}

DeviceProto defines the "prototype" of a device. It contains some high-level information which applies to each of its device instances.

type Devices

type Devices struct {
	// Version is the major version of the device configuration.
	Version int `yaml:"version,omitempty"`

	// Devices is the collection of devices defined in the configuration.
	Devices []*DeviceProto `yaml:"devices,omitempty"`
}

Devices is the top-level configuration for devices for Synse plugins.

Devices can be specified in a single configuration file, or in multiple configuration files. Each Device config can be merged simply by joining all of their `Devices` fields together.

type DynamicRegistrationSettings

type DynamicRegistrationSettings struct {
	// Config holds the configuration(s) for dynamic device registration. It holds
	// the plugin/protocol/device-specific data which will be used to register
	// devices at runtime, e.g. a server address and port.
	Config []map[string]interface{} `default:"[]" yaml:"config,omitempty"`
}

DynamicRegistrationSettings are the settings for dynamic device registration.

func (*DynamicRegistrationSettings) Log

func (conf *DynamicRegistrationSettings) Log() (err error)

Log logs out the config at INFO level.

type HealthCheckSettings

type HealthCheckSettings struct {
	// DisableDefaults determines whether the default plugin health checks
	// should be disabled.
	DisableDefaults bool `default:"false" yaml:"disableDefaults,omitempty"`
}

HealthCheckSettings are the settings for plugin health checks.

func (*HealthCheckSettings) Log

func (conf *HealthCheckSettings) Log()

Log logs out the config at INFO level.

type HealthSettings

type HealthSettings struct {
	// HealthFile is the fully qualified path to the file that will be used
	// to signal that the plugin is healthy. If not set, this will default to
	// "/etc/synse/plugin/healthy".
	HealthFile string `default:"/etc/synse/plugin/healthy" yaml:"healthFile,omitempty"`

	// UpdateInterval is the frequency with which the health file will be updated
	// to designate the health status of the plugin.
	UpdateInterval time.Duration `default:"30s" yaml:"updateInterval,omitempty"`

	// Checks are the settings for plugin health checks.
	Checks *HealthCheckSettings `default:"{}" yaml:"checks,omitempty"`
}

HealthSettings are the settings for plugin health.

func (*HealthSettings) Log

func (conf *HealthSettings) Log()

Log logs out the config at INFO level.

type IDSettings

type IDSettings struct {
	// UseMachineID determines whether the machine ID should be used as a
	// part of the namespace for the plugin ID.
	//
	// This is disabled by default as it does not work well in containers,
	// the primary environment for plugins.
	UseMachineID bool `default:"false" yaml:"useMachineID,omitempty"`

	// UsePluginTag determines whether the plugin metadata tag should be used
	// as a part of the namespace for the plugin ID.
	UsePluginTag bool `default:"true" yaml:"usePluginTag,omitempty"`

	// UseEnv allows environment variables to be used when generating the namespace
	// for the plugin ID.
	UseEnv []string `yaml:"useEnv,omitempty"`

	// UseCustom allows setting custom identifiers to be used in generating the namespace
	// for the plugin ID.
	UseCustom []string `yaml:"useCustom,omitempty"`
}

IDSettings are the settings around the plugin ID namespace.

func (*IDSettings) Log

func (conf *IDSettings) Log()

Log logs out the config at INFO level.

type LimiterSettings

type LimiterSettings struct {
	// Rate is the limit, or maximum frequency of events. A rate of
	// 0 signifies 'unlimited'.
	Rate int `default:"0" yaml:"rate,omitempty"`

	// Burst defines the bucket size for the limiter, or maximum number
	// of events that can be fulfilled at once. If this is 0, it will take
	// the same value as the rate.
	Burst int `default:"0" yaml:"burst,omitempty"`
}

LimiterSettings are the settings for rate limiting on reads and writes.

func (*LimiterSettings) Log

func (conf *LimiterSettings) Log()

Log logs out the config at INFO level.

type ListenSettings

type ListenSettings struct {
	// Disable can be used to globally disable listening for the plugin.
	// By default, plugin listening is enabled.
	Disable bool `default:"false" yaml:"disable,omitempty"`
}

ListenSettings are the settings for listener behavior.

func (*ListenSettings) Log

func (conf *ListenSettings) Log()

Log logs out the config at INFO level.

type Loader

type Loader struct {
	// Name is the name of the config being loaded. This is optional and is only used
	// when logging messages.
	Name string

	// SearchPaths defines the paths to search for configuration files. These paths
	// are searched for configs in the order in which they are defined until config(s)
	// are found.
	SearchPaths []string

	// Ext is the file extension format of the config files.
	Ext string

	// EnvOverride defines the environment variable which can be used to override
	// the search paths/file name. This env variable will be ignored when searching
	// for variables starting with EnvPrefix, so this is free to also use the
	// EnvPrefix.
	EnvOverride string

	// EnvPrefix is the prefix for configuration environment variables.
	EnvPrefix string

	// FileName is the name of the file to use. If this is set, only this file will
	// be loaded. If this is not set, all files with the specified extension in
	// the specified search paths will be loaded. This can be specified with or
	// without a file extension.
	FileName string
	// contains filtered or unexported fields
}

Loader is used to load configurations from file(s) and environment and unify them all into a singular configuration.

While other configuration solutions exist, such as spf13/viper, micro/go-config, etc..., they lack good support for loading and unifying multiple configuration files, as is needed here since Device configs can be specified across any number of files. Additionally, many of the existing popular solutions contain many features that Synse does not need, which introduces *a lot* of dependency bloat.

This configuration loader is meant to be a simple file & environment only solution. This could be made into its own package, external to the SDK in the future.

func NewYamlLoader

func NewYamlLoader(name string) *Loader

NewYamlLoader creates a new loader which is configured to read YAML configuration file(s).

func (*Loader) AddSearchPaths

func (loader *Loader) AddSearchPaths(paths ...string)

AddSearchPaths adds search paths to the config Loader.

These paths are searched in the order that they are defined.

func (*Loader) Load

func (loader *Loader) Load(pol policy.Policy) (err error)

Load loads the configuration based on the Loader's configurations. The loading process consists of:

1. Checking for environment overrides 2. Searching for the specified config files, if any 3. Reading in any found config files 4. Loading any environmental configuration 5. Merging all found configurations together

Environmental configuration takes precedence, so it will override any values that were set in config files.

This function takes a policy as a parameter. The policy determines whether the configuration file is required or not. In cases where it is required and not found, Load will return an error. If the config is optional and not found, no error will be returned.

func (*Loader) Scan

func (loader *Loader) Scan(out interface{}) error

Scan the merged configuration values into the provided go type. The type passed to Scan should be a pointer to a zero-value struct, e.g.

config := &Config{}
loader.Scan(config)

type MetricsSettings

type MetricsSettings struct {
	// Enabled sets whether the application should report metrics or not.
	Enabled bool `yaml:"enabled,omitempty"`
}

MetricsSettings are the settings around exposing application metrics.

func (*MetricsSettings) Log

func (conf *MetricsSettings) Log()

Log logs out the config at INFO level.

type NetworkSettings

type NetworkSettings struct {
	// Type is the protocol type. Currently, this must be one of: "tcp"
	// (TCP/IP) or "unix" (Unix Socket).
	Type string `yaml:"type,omitempty"`

	// Address is the address that the gRPC server will run on. For
	// "tcp", this would be the host/port (e.g. "0.0.0.0:5001"). For
	// "unix", this would be the name of the socket (e.g. plugin.sock).
	Address string `yaml:"address,omitempty"`

	// TLS contains the TLS/SSL settings for the gRPC server. If this
	// is not set, insecure transport will be used.
	TLS *TLSNetworkSettings `default:"{}" yaml:"tls,omitempty"`
}

NetworkSettings are the settings for a plugin's networking behavior.

func (*NetworkSettings) Log

func (conf *NetworkSettings) Log()

Log logs out the config at INFO level.

type Plugin

type Plugin struct {
	// Version is the major version of the plugin configuration.
	Version int `yaml:"version,omitempty"`

	// Debug is a flag to determine whether the plugin should be run with
	// debug logging or regular logging.
	Debug bool `default:"false" yaml:"debug,omitempty"`

	// ID specifies the options for generating a plugin namespace ID.
	ID *IDSettings `default:"{}" yaml:"id,omitempty"`

	// Metrics specifies the options for exposing application metrics.
	Metrics *MetricsSettings `default:"{}" yaml:"metrics,omitempty"`

	// Settings specifies how the plugin should run.
	Settings *PluginSettings `default:"{}" yaml:"settings,omitempty"`

	// Network specifies the networking configuration for the the plugin.
	Network *NetworkSettings `default:"{}" yaml:"network,omitempty"`

	// DynamicRegistration specifies the settings and data for dynamically
	// registering devices to the plugin.
	DynamicRegistration *DynamicRegistrationSettings `default:"{}" yaml:"dynamicRegistration,omitempty"`

	// Health specifies the health settings for the plugin.
	Health *HealthSettings `default:"{}" yaml:"health,omitempty"`
}

Plugin contains the configuration for a Synse Plugin.

func (*Plugin) Log

func (conf *Plugin) Log()

Log logs out the plugin config at INFO level.

type PluginSettings

type PluginSettings struct {
	// Mode is the run mode of the read and write loops. This can either
	// be "serial" or "parallel".
	Mode string `default:"parallel" yaml:"mode,omitempty"`

	// Listen contains the settings to configure listener behavior.
	Listen *ListenSettings `default:"{}" yaml:"listen,omitempty"`

	// Read contains the settings to configure read behavior.
	Read *ReadSettings `default:"{}" yaml:"read,omitempty"`

	// Write contains the settings to configure write behavior.
	Write *WriteSettings `default:"{}" yaml:"write,omitempty"`

	// Transaction contains the settings to configure transaction
	// handling behavior.
	Transaction *TransactionSettings `default:"{}" yaml:"transaction,omitempty"`

	// Limiter specifies settings for rate limiting for reads/writes.
	Limiter *LimiterSettings `default:"{}" yaml:"limiter,omitempty"`

	// Cache contains the settings to configure local data caching
	// by the plugin.
	Cache *CacheSettings `default:"{}" yaml:"cache,omitempty"`
}

PluginSettings are the settings around the runtime behavior of a plugin.

func (*PluginSettings) Log

func (conf *PluginSettings) Log()

Log logs out the config at INFO level.

type ReadSettings

type ReadSettings struct {
	// Disable can be used to globally disable reading for the plugin.
	// By default, plugin reading is enabled.
	Disable bool `default:"false" yaml:"disable,omitempty"`

	// Interval specifies the duration that the read loop should
	// sleep between iterations. By default, no interval is specified.
	//
	// An interval may be useful for tuning the performance of a plugin. In
	// particular, it can be useful for serial protocols to introduce a
	// bit of a delay so the serial bus is not constantly hammered.
	//
	// It is not recommended to set the interval to 0. This would cause
	// reads to loop unbounded, causing the plugin to consume excessive
	// CPU resources.
	Interval time.Duration `default:"1s" yaml:"interval,omitempty"`

	// Delay specifies a plugin-global delay between successive reads.
	// By default, no delay is specified.
	//
	// A delay can be useful for tuning the performance of a plugin. In
	// particular, it can be useful for serial protocols to introduce a
	// bit of a delay so the serial bus is not constantly hammered.
	Delay time.Duration `default:"0s" yaml:"delay,omitempty"`

	// QueueSize defines the size of the read queue. This will be the
	// size of the channel that queues up and passes along readings as
	// they are collected.
	//
	// Generally this does not need to be set, but can be used to tune
	// performance for read-intensive plugins.
	QueueSize int `default:"128" yaml:"queueSize,omitempty"`
}

ReadSettings are the settings for read behavior.

func (*ReadSettings) Log

func (conf *ReadSettings) Log()

Log logs out the config at INFO level.

type TLSNetworkSettings

type TLSNetworkSettings struct {
	// Cert is the location of the cert file to use for the gRPC server.
	Cert string `yaml:"cert,omitempty"`

	// Key is the location of the cert file to use for the gRPC server.
	Key string `yaml:"key,omitempty"`

	// CACerts are a list of certificate authority certs to use. If none
	// are specified, the OS system-wide TLS certs are used.
	CACerts []string `yaml:"caCerts,omitempty"`

	// SkipVerify is a flag that, when set, will skip certificate checks.
	SkipVerify bool `yaml:"skipVerify,omitempty"`
}

TLSNetworkSettings are the settings for TLS/SSL for the gRPC server.

func (*TLSNetworkSettings) Log

func (conf *TLSNetworkSettings) Log()

Log logs out the config at INFO level.

type TransactionSettings

type TransactionSettings struct {
	// TTL is the time-to-live for a transaction in the transaction cache.
	TTL time.Duration `default:"5m" yaml:"ttl,omitempty"`
}

TransactionSettings are the settings for transaction operations.

func (*TransactionSettings) Log

func (conf *TransactionSettings) Log()

Log logs out the config at INFO level.

type TransformConfig

type TransformConfig struct {
	// Apply defines a function to be applied to the device's reading value(s).
	// The function to apply could be anything, e.g. a unit conversion. The SDK
	// defines built-in functions in the 'funcs' package. A plugin may also register
	// custom functions. Functions are referenced here by name.
	Apply string `yaml:"apply,omitempty"`

	// Scale defines a scaling transformation value to be applied to a device's
	// reading(s). The scaling factor defined here is multiplied with the device
	// reading. This allows it to be scaled up (multiplication, e.g. "* 2"), or
	// scaled down (division, e.g. "/ 2" == "* 0.5").
	//
	// This value is specified as a string, but should resolve to a numeric. By
	// default, it will have a value of 1 (e.g. no-op). Negative values and
	// fractional values are supported. This can be the value itself, e.g. "0.01",
	// or a mathematical representation of the value, e.g. "1e-2".
	Scale string `yaml:"scale,omitempty"`
}

TransformConfig defines the configuration options for transformations to be applied to a device's readings. This is typically used more in general-purpose plugin implementations, where the handler does not bake-in any scaling or conversions.

TransformConfigs are specified as a list of items underneath the 'transforms' key of either the device prototype config or device instance config. Instances of the transform config should only define a single field, e.g.

   transforms:
		- apply: foo
		- scale: 1

It should never specify multiple, as then the order in which the operations should be executed are ambiguous, e.g.

transforms:
  - apply: foo
    scale: 1

The Validate method can be called to ensure that the config adheres to the above requirement.

func (*TransformConfig) Validate

func (c *TransformConfig) Validate() error

Validate that the TransformConfig adheres to its configuration restrictions.

type WriteSettings

type WriteSettings struct {
	// Disable can be used to globally disable writing for the plugin.
	// By default, plugin writing is enabled.
	Disable bool `yaml:"disable,omitempty"`

	// Interval specifies the duration that the write loop should
	// sleep between iterations. By default, no interval is specified.
	//
	// An interval may be useful for tuning the performance of a plugin. In
	// particular, it can be useful for serial protocols to introduce a
	// bit of a delay so the serial bus is not constantly hammered.
	//
	// It is not recommended to set the interval to 0. This would cause
	// writes to loop unbounded, causing the plugin to consume excessive
	// CPU resources.
	Interval time.Duration `default:"1s" yaml:"interval,omitempty"`

	// Delay specifies a plugin-global delay between successive writes.
	// By default, no delay is specified.
	//
	// A delay can be useful for tuning the performance of a plugin. In
	// particular, it can be useful for serial protocols to introduce a
	// bit of a delay so the serial bus is not constantly hammered.
	Delay time.Duration `default:"0s" yaml:"delay,omitempty"`

	// QueueSize defines the size of the write queue. This will be the
	// size of the channel that queues up and passes along write requests.
	//
	// Generally this does not need to be set, but can be used to tune
	// performance for write-intensive plugins.
	QueueSize int `default:"128" yaml:"queueSize,omitempty"`

	// BatchSize defines the maximum number of writes to process in a
	// single batch.
	//
	// Generally, this does not need to be set, but can be used to tune
	// performance particularly for slow writing serial plugins.
	BatchSize int `default:"128" yaml:"batchSize,omitempty"`
}

WriteSettings are the settings for write behavior.

func (*WriteSettings) Log

func (conf *WriteSettings) Log()

Log logs out the config at INFO level.

Jump to

Keyboard shortcuts

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