if duration == 0 config refresh loop will not been started
duration validation is not provided, so this is entirely your responsibility, keep in mind that too small an interval can lead to unforeseen consequences
// turn on logging, by default turned off
libConfig.Verbose = true
// refresh interval
duration := 1 * time.Minute
// get service instance
service := libConfig.NewConfigService(duration)
// start service
valid, err := service.Start(&cfg, cb, reader)
import (
"time"
libConfig "github.com/MiG-21/go-lib-config"
)
func main() {
var cfg Config
// refresh config per 1 minute
service := libConfig.NewConfigService(1 * time.Minute)
reader := libConfig.NewEnvReader()
// this callback will be called on every config update
cb = func(err error) {
// some error handler
}
if valid, err := service.Start(&cfg, cb, reader); err != nil {
// some error handler
}
defer service.Stop()
}
import (
"time"
libConfig "github.com/MiG-21/go-lib-config"
)
func defaultPathFormatter(secret string) string {
parts := []string{"secret", "data"}
parts = append(parts, strings.Trim(secret, "/"))
return strings.Join(parts, "/")
}
func main() {
var cfg Config
service := libConfig.NewConfigService(1 * time.Minute)
vaultConfig := libConfig.NewVaultApiConfig(vaultAddress, false)
auth := libConfig.NewVaultTokenAuth("token", vaultConfig)
vault := libConfig.NewStorageVault(auth, "data")
reader := libConfig.NewVaultReaderWithFormatter(vault, defaultPathFormatter)
if valid, err := service.Start(&cfg, nil, reader); err != nil {
// some error handler
}
defer service.Stop()
}
import (
"time"
libConfig "github.com/MiG-21/go-lib-config"
)
func defaultPathFormatter(secret string) string {
parts := []string{"secret", "data"}
parts = append(parts, strings.Trim(secret, "/"))
return strings.Join(parts, "/")
}
func main() {
var cfg Config
service := libConfig.NewConfigService(1 * time.Minute)
vaultConfig := libConfig.NewVaultApiConfig(vaultAddress, false)
auth := libConfig.NewVaultK8sAuth("vault address", "auth endpoint", "token path", "role", vaultConfig)
vault := libConfig.NewStorageVault(auth, "data")
reader := libConfig.NewVaultReaderWithFormatter(vault, defaultPathFormatter)
if valid, err := service.Start(&cfg, nil, reader); err != nil {
// some error handler
}
defer service.Stop()
}
Validator should implement interface
type Validator interface {
Validate(i interface{}) error
}
import (
"github.com/go-playground/validator/v10"
libConfig "github.com/MiG-21/go-lib-config"
)
// Validator wrapper example
type Validator struct {
validator *validator.Validate
}
func (cv *Validator) Validate(i interface{}) error {
return cv.validator.Struct(i)
}
func main() {
var cfg Config
service := libConfig.NewConfigService(1 * time.Minute)
// assign validator
service.Validator = &Validator{validator: validator.New()}
// ....
}
the priority of the readers is related to the order, each next is higher than the previous one, the last one has the highest priority
func main() {
var cfg Config
service := libConfig.NewConfigService(1 * time.Minute)
reader1 := Reader1{}
reader2 := Reader2{}
if valid, err := service.Start(&cfg, nil, reader1, reader2); err != nil {
// some error handler
}
}
Custom reader can be implemented in accordance with interface Reader
type Reader interface {
Read(metas []StructMeta) error
Stop()
}
type CustomReader struct {
}
func (r *CustomReader) Read(metas []StructMeta) error {
// some implementation
}
func (r *CustomReader) Stop() {
// some implementation
}
func main() {
var cfg Config
service := libConfig.NewConfigService(1 * time.Minute)
reader := CustomReader{}
if valid, err := service.Start(&cfg, nil, reader); err != nil {
// some error handler
}
defer service.Stop()
}
LibLogger = func(i ...interface{}) {
// custom implementation
}
To implement a custom value setter you need to add a SetValue function to your type that will receive a string raw value
type Setter interface {
SetValue(string) error
}
type (
Foo int
)
func (f *Foo) SetValue(value string) error {
v, err := strconv.ParseInt(value, 10, 32)
if err != nil {
return err
}
*f = Foo(v * 3)
return nil
}
func main() {
cfg := &struct {
F Foo `env:"SOME_VAR"`
}{}
}