config

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2024 License: MIT Imports: 9 Imported by: 5

Documentation

Overview

Package config intends to make loading configuration easier (https://github.com/spf13/viper is used under the hood).

Example
package main

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"path"

	"code.cloudfoundry.org/bytefmt"
)

const (
	cfgKeyServerAddr                = "server.addr"
	cfgKeyLogLevel                  = "log.level"
	cfgKeyLogFilePath               = "log.file.path"
	cfgKeyLogFileRotationCompress   = "log.file.rotation.compress"
	cfgKeyLogFileRotationMaxSize    = "log.file.rotation.maxsize"
	cfgKeyLogFileRotationMaxBackups = "log.file.rotation.maxbackups"
)

type serverConfig struct {
	Addr string
}

func (c *serverConfig) UpdateProviderValues(dp DataProvider) {
	dp.Set(cfgKeyServerAddr, c.Addr)
}

func (c *serverConfig) SetProviderDefaults(dp DataProvider) {
	dp.SetDefault(cfgKeyServerAddr, ":8080")
}

func (c *serverConfig) Set(dp DataProvider) error {
	var err error
	if c.Addr, err = dp.GetString(cfgKeyServerAddr); err != nil {
		return err
	}
	return nil
}

type logConfig struct {
	Level string
	File  struct {
		Path     string
		Rotation struct {
			MaxSize    uint64
			MaxBackups int
			Compress   bool
		}
	}
}

func (c *logConfig) SetProviderDefaults(dp DataProvider) {
	dp.SetDefault(cfgKeyLogLevel, "info")
	dp.SetDefault(cfgKeyLogFileRotationCompress, false)
	dp.SetDefault(cfgKeyLogFileRotationMaxSize, bytefmt.ByteSize(100*1024*1024))
	dp.SetDefault(cfgKeyLogFileRotationMaxBackups, 10)
}

func (c *logConfig) Set(dp DataProvider) error {
	var err error

	if c.Level, err = dp.GetStringFromSet(cfgKeyLogLevel, []string{"debug", "info", "warn", "error"}, true); err != nil {
		return err
	}

	if c.File.Path, err = dp.GetString(cfgKeyLogFilePath); err != nil {
		return err
	}
	if c.File.Path == "" {
		return WrapKeyErr(cfgKeyLogFilePath, fmt.Errorf("must not be empty"))
	}

	if c.File.Rotation.MaxSize, err = dp.GetSizeInBytes(cfgKeyLogFileRotationMaxSize); err != nil {
		return err
	}
	if c.File.Rotation.MaxBackups, err = dp.GetInt(cfgKeyLogFileRotationMaxBackups); err != nil {
		return err
	}
	if c.File.Rotation.Compress, err = dp.GetBool(cfgKeyLogFileRotationCompress); err != nil {
		return err
	}

	return nil
}

func main() {
	const envVarsPrefix = "my_service"

	cfgData := bytes.NewBuffer([]byte(`
log:
  level: info
  file:
    path: my-service.log
    rotation:
      maxsize: 100M
      maxbackups: 10
      compress: false
`))

	// Override some configuration values using environment variables.
	if err := os.Setenv("MY_SERVICE_LOG_FILE_ROTATION_COMPRESS", "true"); err != nil {
		log.Fatal(err)
	}
	if err := os.Setenv("MY_SERVICE_LOG_LEVEL", "debug"); err != nil {
		log.Fatal(err)
	}

	serverCfg := serverConfig{}
	logCfg := logConfig{}

	// Load configuration values and set them in serverCfg and logCfg.
	cfgLoader := NewDefaultLoader(envVarsPrefix)
	err := cfgLoader.LoadFromReader(cfgData, DataTypeYAML, &serverCfg, &logCfg) // Use cfgLoader.LoadFromFile() to read from file.
	if err != nil {
		log.Fatal(err)
	}

	// Save a modified config's copy into a file
	fname := path.Join(os.TempDir(), "data.yaml")
	configToModify := serverCfg
	configToModify.Addr = "new.address.com:8888"
	dp := cfgLoader.DataProvider
	UpdateDataProvider(dp, &configToModify)
	err = dp.SaveToFile(fname, DataTypeYAML)
	if err != nil {
		log.Fatal(err)
	}

	// Load config from file
	configFromFile := serverConfig{}
	modifiedConfigLoader := NewDefaultLoader(envVarsPrefix)
	err = modifiedConfigLoader.LoadFromFile(fname, DataTypeYAML, &configFromFile)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(serverCfg.Addr)
	fmt.Printf("%q, %q, %d, %d, %v\n", logCfg.Level, logCfg.File.Path, logCfg.File.Rotation.MaxSize,
		logCfg.File.Rotation.MaxBackups, logCfg.File.Rotation.Compress)
	fmt.Println(configFromFile.Addr)

}
Output:

:8080
"debug", "my-service.log", 104857600, 10, true
new.address.com:8888

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CallSetForFields

func CallSetForFields(obj interface{}, dp DataProvider) error

CallSetForFields finds all initialized (non-nil) fields of the passed object that implement Config interface and calls Set() method for each of them.

func CallSetProviderDefaultsForFields

func CallSetProviderDefaultsForFields(obj interface{}, dp DataProvider)

CallSetProviderDefaultsForFields finds all initialized (non-nil) fields of the passed object that implement Config interface and calls SetProviderDefaults() method for each of them.

func UpdateDataProvider

func UpdateDataProvider(dp DataProvider, obj DataProviderUpdater, objs ...DataProviderUpdater)

UpdateDataProvider changes data provider values from config structures.

func WrapKeyErr

func WrapKeyErr(key string, err error) error

WrapKeyErr wraps error adding information about a key where this error occurs.

func WrapKeyErrIfNeeded

func WrapKeyErrIfNeeded(key string, err error) error

WrapKeyErrIfNeeded wraps error adding information about a key where this error occurs. If error is nil, it does nothing.

Types

type Config

type Config interface {
	SetProviderDefaults(dp DataProvider)
	Set(dp DataProvider) error
}

Config is a common interface for configuration objects that may be used by Loader.

type DataProvider

type DataProvider interface {
	UseEnvVars(prefix string)

	Set(key string, value interface{})
	SetDefault(key string, value interface{})

	SetFromFile(path string, dataType DataType) error
	SetFromReader(reader io.Reader, dataType DataType) error

	SaveToFile(path string, dataType DataType) error

	IsSet(key string) bool

	Get(key string) interface{}
	GetBool(key string) (bool, error)
	GetInt(key string) (int, error)
	GetIntSlice(key string) ([]int, error)
	GetFloat32(key string) (res float32, err error)
	GetFloat64(key string) (res float64, err error)
	GetString(key string) (string, error)
	GetStringFromSet(key string, set []string, ignoreCase bool) (string, error)
	GetStringSlice(key string) ([]string, error)
	GetDuration(key string) (time.Duration, error)
	GetSizeInBytes(key string) (uint64, error)
	GetStringMapString(key string) (map[string]string, error)
	Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error
	UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error

	WrapKeyErr(key string, err error) error
}

DataProvider is an interface for providing configuration data from different sources (files, reader, environment variables).

type DataProviderUpdater

type DataProviderUpdater interface {
	UpdateProviderValues(dp DataProvider)
}

DataProviderUpdater objects can update data providers using their internal values.

type DataType

type DataType string

DataType is a type of data format in which configuration may be described.

const (
	DataTypeYAML DataType = "yaml"
	DataTypeJSON DataType = "json"
)

Supported data formats.

type DecoderConfigOption

type DecoderConfigOption func(*mapstructure.DecoderConfig)

A DecoderConfigOption can be passed to UnmarshalKey to configure mapstructure.DecoderConfig options

type KeyPrefixProvider

type KeyPrefixProvider interface {
	KeyPrefix() string
}

KeyPrefixProvider is an interface for providing key prefix that will be used for configuration parameters.

type KeyPrefixedDataProvider

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

KeyPrefixedDataProvider is a DataProvider implementation that uses a specified key prefix for parsing configuration parameters.

func NewKeyPrefixedDataProvider

func NewKeyPrefixedDataProvider(delegate DataProvider, keyPrefix string) *KeyPrefixedDataProvider

NewKeyPrefixedDataProvider creates a new KeyPrefixedDataProvider.

func (*KeyPrefixedDataProvider) Get

func (kp *KeyPrefixedDataProvider) Get(key string) interface{}

Get retrieves any value given the key to use.

func (*KeyPrefixedDataProvider) GetBool

func (kp *KeyPrefixedDataProvider) GetBool(key string) (res bool, err error)

GetBool tries to retrieve the value associated with the key as a bool.

func (*KeyPrefixedDataProvider) GetDuration

func (kp *KeyPrefixedDataProvider) GetDuration(key string) (res time.Duration, err error)

GetDuration tries to retrieve the value associated with the key as a duration.

func (*KeyPrefixedDataProvider) GetFloat32

func (kp *KeyPrefixedDataProvider) GetFloat32(key string) (res float32, err error)

GetFloat32 tries to retrieve the value associated with the key as an float32.

func (*KeyPrefixedDataProvider) GetFloat64

func (kp *KeyPrefixedDataProvider) GetFloat64(key string) (res float64, err error)

GetFloat64 tries to retrieve the value associated with the key as an float64.

func (*KeyPrefixedDataProvider) GetInt

func (kp *KeyPrefixedDataProvider) GetInt(key string) (res int, err error)

GetInt tries to retrieve the value associated with the key as an integer.

func (*KeyPrefixedDataProvider) GetIntSlice

func (kp *KeyPrefixedDataProvider) GetIntSlice(key string) (res []int, err error)

GetIntSlice tries to retrieve the value associated with the key as a slice of integers.

func (*KeyPrefixedDataProvider) GetSizeInBytes

func (kp *KeyPrefixedDataProvider) GetSizeInBytes(key string) (uint64, error)

GetSizeInBytes tries to retrieve the value associated with the key as a size in bytes.

func (*KeyPrefixedDataProvider) GetString

func (kp *KeyPrefixedDataProvider) GetString(key string) (res string, err error)

GetString tries to retrieve the value associated with the key as a string.

func (*KeyPrefixedDataProvider) GetStringFromSet

func (kp *KeyPrefixedDataProvider) GetStringFromSet(key string, set []string, ignoreCase bool) (string, error)

GetStringFromSet tries to retrieve the value associated with the key as a string from the specified set.

func (*KeyPrefixedDataProvider) GetStringMapString

func (kp *KeyPrefixedDataProvider) GetStringMapString(key string) (res map[string]string, err error)

GetStringMapString tries to retrieve the value associated with the key as an map where key and value are strings.

func (*KeyPrefixedDataProvider) GetStringSlice

func (kp *KeyPrefixedDataProvider) GetStringSlice(key string) (res []string, err error)

GetStringSlice tries to retrieve the value associated with the key as an slice of strings.

func (*KeyPrefixedDataProvider) IsSet

func (kp *KeyPrefixedDataProvider) IsSet(key string) bool

IsSet checks to see if the key has been set in any of the data locations. IsSet is case-insensitive for a key.

func (*KeyPrefixedDataProvider) SaveToFile

func (kp *KeyPrefixedDataProvider) SaveToFile(path string, dataType DataType) error

SaveToFile writes config into file according data type.

func (*KeyPrefixedDataProvider) Set

func (kp *KeyPrefixedDataProvider) Set(key string, value interface{})

Set sets the value for the key in the override register.

func (*KeyPrefixedDataProvider) SetDefault

func (kp *KeyPrefixedDataProvider) SetDefault(key string, value interface{})

SetDefault sets the default value for this key. Default only used when no value is provided by the user via config or ENV.

func (*KeyPrefixedDataProvider) SetFromFile

func (kp *KeyPrefixedDataProvider) SetFromFile(path string, dataType DataType) error

SetFromFile specifies that discovering and loading configuration data will be performed from file.

func (*KeyPrefixedDataProvider) SetFromReader

func (kp *KeyPrefixedDataProvider) SetFromReader(reader io.Reader, dataType DataType) error

SetFromReader specifies that discovering and loading configuration data will be performed from reader.

func (*KeyPrefixedDataProvider) Unmarshal

func (kp *KeyPrefixedDataProvider) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) (err error)

Unmarshal unmarshals the config into a Struct.

func (*KeyPrefixedDataProvider) UnmarshalKey

func (kp *KeyPrefixedDataProvider) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) (err error)

UnmarshalKey takes a single key and unmarshals it into a Struct.

func (*KeyPrefixedDataProvider) UseEnvVars

func (kp *KeyPrefixedDataProvider) UseEnvVars(prefix string)

UseEnvVars enables the ability to use environment variables for configuration parameters. Prefix defines what environment variables will be looked. E.g., if your prefix is "spf", the env registry will look for env variables that start with "SPF_".

func (*KeyPrefixedDataProvider) WrapKeyErr

func (kp *KeyPrefixedDataProvider) WrapKeyErr(key string, err error) error

WrapKeyErr wraps error adding information about a key where this error occurs.

type Loader

type Loader struct {
	DataProvider DataProvider
}

Loader loads configuration values from data provider (with initializing default values before) and sets them in configuration objects.

func NewDefaultLoader

func NewDefaultLoader(envVarsPrefix string) *Loader

NewDefaultLoader creates a new configurations loader with an ability to read values from the environment variables.

func NewLoader

func NewLoader(dp DataProvider) *Loader

NewLoader creates a new configurations' loader.

func (*Loader) LoadFromFile

func (l *Loader) LoadFromFile(path string, dataType DataType, cfg Config, cfgs ...Config) error

LoadFromFile loads configuration values from file and sets them in configuration objects.

func (*Loader) LoadFromReader

func (l *Loader) LoadFromReader(reader io.Reader, dataType DataType, cfg Config, cfgs ...Config) error

LoadFromReader loads configuration values from reader and sets them in configuration objects.

type ViperAdapter

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

ViperAdapter is DataProvider implementation that uses viper library under the hood.

func NewViperAdapter

func NewViperAdapter() *ViperAdapter

NewViperAdapter creates a new ViperAdapter.

func (*ViperAdapter) Get

func (va *ViperAdapter) Get(key string) interface{}

Get retrieves any value given the key to use.

func (*ViperAdapter) GetBool

func (va *ViperAdapter) GetBool(key string) (res bool, err error)

GetBool tries to retrieve the value associated with the key as a bool.

func (*ViperAdapter) GetDuration

func (va *ViperAdapter) GetDuration(key string) (res time.Duration, err error)

GetDuration tries to retrieve the value associated with the key as a duration.

func (*ViperAdapter) GetFloat32

func (va *ViperAdapter) GetFloat32(key string) (res float32, err error)

GetFloat32 tries to retrieve the value associated with the key as an float32.

func (*ViperAdapter) GetFloat64

func (va *ViperAdapter) GetFloat64(key string) (res float64, err error)

GetFloat64 tries to retrieve the value associated with the key as an float64.

func (*ViperAdapter) GetInt

func (va *ViperAdapter) GetInt(key string) (res int, err error)

GetInt tries to retrieve the value associated with the key as an integer.

func (*ViperAdapter) GetIntSlice

func (va *ViperAdapter) GetIntSlice(key string) (res []int, err error)

GetIntSlice tries to retrieve the value associated with the key as a slice of integers.

func (*ViperAdapter) GetSizeInBytes

func (va *ViperAdapter) GetSizeInBytes(key string) (uint64, error)

GetSizeInBytes tries to retrieve the value associated with the key as a size in bytes.

func (*ViperAdapter) GetString

func (va *ViperAdapter) GetString(key string) (res string, err error)

GetString tries to retrieve the value associated with the key as a string.

func (*ViperAdapter) GetStringFromSet

func (va *ViperAdapter) GetStringFromSet(key string, set []string, ignoreCase bool) (string, error)

GetStringFromSet tries to retrieve the value associated with the key as a string from the specified set.

func (*ViperAdapter) GetStringMapString

func (va *ViperAdapter) GetStringMapString(key string) (res map[string]string, err error)

GetStringMapString tries to retrieve the value associated with the key as an map where key and value are strings.

func (*ViperAdapter) GetStringSlice

func (va *ViperAdapter) GetStringSlice(key string) (res []string, err error)

GetStringSlice tries to retrieve the value associated with the key as an slice of strings.

func (*ViperAdapter) IsSet

func (va *ViperAdapter) IsSet(key string) bool

IsSet checks to see if the key has been set in any of the data locations. IsSet is case-insensitive for a key.

func (*ViperAdapter) SaveToFile

func (va *ViperAdapter) SaveToFile(path string, dataType DataType) error

SaveToFile writes config into file according data type.

func (*ViperAdapter) Set

func (va *ViperAdapter) Set(key string, value interface{})

Set sets the value for the key in the override register.

func (*ViperAdapter) SetDefault

func (va *ViperAdapter) SetDefault(key string, value interface{})

SetDefault sets the default value for this key. Default only used when no value is provided by the user via config or ENV.

func (*ViperAdapter) SetFromFile

func (va *ViperAdapter) SetFromFile(path string, dataType DataType) error

SetFromFile specifies that discovering and loading configuration data will be performed from file.

func (*ViperAdapter) SetFromReader

func (va *ViperAdapter) SetFromReader(reader io.Reader, dataType DataType) error

SetFromReader specifies that discovering and loading configuration data will be performed from reader.

func (*ViperAdapter) Unmarshal

func (va *ViperAdapter) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) (err error)

Unmarshal unmarshals the config into a Struct.

func (*ViperAdapter) UnmarshalKey

func (va *ViperAdapter) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) (err error)

UnmarshalKey takes a single key and unmarshals it into a Struct.

func (*ViperAdapter) UseEnvVars

func (va *ViperAdapter) UseEnvVars(prefix string)

UseEnvVars enables the ability to use environment variables for configuration parameters. Prefix defines what environment variables will be looked. E.g., if your prefix is "spf", the env registry will look for env variables that start with "SPF_".

func (*ViperAdapter) WrapKeyErr

func (va *ViperAdapter) WrapKeyErr(key string, err error) error

WrapKeyErr wraps error adding information about a key where this error occurs.

Jump to

Keyboard shortcuts

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