Files
diun/internal/config/config.go

84 lines
2.1 KiB
Go

package config
import (
"encoding/json"
"fmt"
"os"
"github.com/containous/traefik/v2/pkg/config/env"
"github.com/containous/traefik/v2/pkg/config/file"
"github.com/crazy-max/diun/v4/internal/model"
"github.com/go-playground/validator/v10"
"github.com/pkg/errors"
)
// Config holds configuration details
type Config struct {
Db *model.Db `yaml:"db,omitempty" json:"db,omitempty"`
Watch *model.Watch `yaml:"watch,omitempty" json:"watch,omitempty"`
Notif *model.Notif `yaml:"notif,omitempty" json:"notif,omitempty"`
RegOpts model.RegOpts `yaml:"regopts,omitempty" json:"regopts,omitempty" validate:"unique=Name,dive"`
Providers *model.Providers `yaml:"providers,omitempty" json:"providers,omitempty" validate:"required"`
}
// Load returns Configuration struct
func Load(cfgfile string) (*Config, error) {
cfg := Config{
Db: (&model.Db{}).GetDefaults(),
Watch: (&model.Watch{}).GetDefaults(),
}
if err := cfg.loadFile(cfgfile, &cfg); err != nil {
return nil, err
}
if err := cfg.loadEnv(&cfg); err != nil {
return nil, err
}
validate := validator.New()
if err := validate.Struct(&cfg); err != nil {
return nil, err
}
return &cfg, nil
}
func (cfg *Config) loadFile(cfgfile string, out interface{}) error {
if len(cfgfile) == 0 {
return nil
}
if _, err := os.Lstat(cfgfile); os.IsNotExist(err) {
return fmt.Errorf("config file %s not found", cfgfile)
}
if err := file.Decode(cfgfile, out); err != nil {
return errors.Wrap(err, "failed to decode configuration from file")
}
return nil
}
func (cfg *Config) loadEnv(out interface{}) error {
var envvars []string
for _, envvar := range env.FindPrefixedEnvVars(os.Environ(), "DIUN_", out) {
envvars = append(envvars, envvar)
}
if len(envvars) == 0 {
return nil
}
if err := env.Decode(envvars, "DIUN_", out); err != nil {
return errors.Wrap(err, "failed to decode configuration from environment variables")
}
return nil
}
// String returns the string representation of configuration
func (cfg *Config) String() string {
b, _ := json.MarshalIndent(cfg, "", " ")
return string(b)
}