Documentation ¶
Overview ¶
Package cfg manages config for outreach go services
Every go app or package that needs config should define a strongly typed struct for it
Example
type OtelConfig struct { Disable bool `yaml:"Disable"` Dataset string `yaml:"Dataset"` Endpoint string `yaml:"APIHost"` SampleRate float64 `yaml:"SampleRate"` Key cfg.Secret `yaml:"Key"` } func (x someComponent) someFunc(ctx context.Context) error { var otelConfig OtelConfig if err := cfg.Load("trace.yaml", &hcConfig); err != nil { return err } ... now use the config... }
All config structs should typically implement their own `Load()` method so that the config location is specified in one spot:
func (c *OtelConfig) Load() error { return cfg.Load("trace.yaml", &c) }
Dev environment overrides ¶
The default directory prefix for config will be chosen to be compatible with our k8s deployment strategy.
For dev environments, the preferred path is ~/.outreach/ and this can be configured by app init using the following override:
import env "github.com/getoutreach/gobox/pkg/env" func init() { env.ApplyOverrides() }
To build with this override, the build tag or_dev should be used.
Dev environments may also need command line or environment overrides. The suggested mechanism is to add the override as part of the individual `Load()` method on the struct. At some point, we will add code generators for config (based on struct tags such as `env:OUTREACH_HONEYCOMB_KEY` or some such mechanism) and the `Load()` methods will be automatically generated with the specified overrides.
Secrets ¶
While secrets can be accessed in an adhoc way using the secrets package, the recommended way is to fetch fixed secrets (i.e. not things like oauth tokens) via the `cfg.Secret` type. For the example above, the API key can be accessed via:
secretData, err := hcConfig.Key.Data(ctx)
Note that SecretData cannot be serialized to JSON or YAML. While it can be converted to string using an explicit conversion, the converted value should not be cached or passed to internal functions.
Description: Exposes prod configurations
Description: Implements secrets handling mechanisms for configurations
Example ¶
package main import ( "context" "fmt" "github.com/getoutreach/gobox/pkg/cfg" "github.com/getoutreach/gobox/pkg/env" "github.com/getoutreach/gobox/pkg/secrets/secretstest" ) func main() { type OtelConfig struct { Disable bool Dataset string Endpoint string SampleRate float64 Key cfg.Secret } expected := OtelConfig{ Disable: true, Dataset: "boo", Endpoint: "hoo", SampleRate: 5.3, Key: cfg.Secret{Path: "someSecretPath"}, } deleteFunc, _ := env.FakeTestConfigWithError("trace.yaml", expected) defer deleteFunc() defer secretstest.Fake("someSecretPath", "someSecretData")() var hcConfig OtelConfig if err := cfg.Load("trace.yaml", &hcConfig); err != nil { fmt.Println("Unexpected error", err) } if hcConfig != expected { fmt.Println("Unexpected differences") } data, err := hcConfig.Key.Data(context.Background()) if err != nil { fmt.Println("Error fetching data") } if string(data) != "someSecretData" { fmt.Println("Unexpected secret data", data) } fmt.Println(data) }
Output: redacted
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SetDefaultReader ¶
func SetDefaultReader(f Reader)
SetDefaultReader sets the default reader. Only meant for tests and dev environment overrides
Types ¶
type Reader ¶
Reader reads the config from the provided file
func DefaultReader ¶
func DefaultReader() Reader
DefaultReader returns the current default reader. Only meant for tests and dev environment overrides
type Secret ¶
type Secret struct {
Path string `yaml:"Path"`
}
Secret provides access to secret config.
The actual secret should be fetched via Data() which returns a SecretData.
This type can be embedded within Config
type SecretData ¶
type SecretData string
SecretData just wraps strings so we don't accidentally log secret data.
Do not store SecretData -- it is only meant to be kept in scope variables and as arguments.
Do not pass the raw converted string as arguments to any outreach code, use the strong type SecretData instead
func (SecretData) Format ¶
func (s SecretData) Format(f fmt.State, c rune)
Format implements fmt.Formatter
func (SecretData) GoString ¶
func (s SecretData) GoString() string
GoString implements the GoStringer interface
func (SecretData) MarshalJSON ¶
func (s SecretData) MarshalJSON() ([]byte, error)
MarshalJSON implements a dummy json.Marshaler
func (SecretData) MarshalYAML ¶
func (s SecretData) MarshalYAML() (interface{}, error)
MarshalYAML implements a dummy yaml.Marshaler