mirror of
https://github.com/crazy-max/diun.git
synced 2025-01-12 11:38:11 +00:00
88 lines
2.6 KiB
Go
88 lines
2.6 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path"
|
|
|
|
"github.com/crazy-max/diun/v4/internal/model"
|
|
"github.com/crazy-max/gonfig"
|
|
"github.com/go-playground/validator/v10"
|
|
"github.com/pkg/errors"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
// 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"`
|
|
Defaults *model.Defaults `yaml:"defaults,omitempty" json:"defaults,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"`
|
|
}
|
|
|
|
// Load returns Config struct
|
|
func Load(config string) (*Config, error) {
|
|
cfg := Config{
|
|
Db: (&model.Db{}).GetDefaults(),
|
|
Watch: (&model.Watch{}).GetDefaults(),
|
|
Defaults: (&model.Defaults{}).GetDefaults(),
|
|
}
|
|
|
|
fileLoader := gonfig.NewFileLoader(gonfig.FileLoaderConfig{
|
|
Filename: config,
|
|
Finder: gonfig.Finder{
|
|
BasePaths: []string{"/etc/diun/diun", "$XDG_CONFIG_HOME/diun", "$HOME/.config/diun", "./diun"},
|
|
Extensions: []string{"yaml", "yml"},
|
|
},
|
|
})
|
|
if found, err := fileLoader.Load(&cfg); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode configuration from file")
|
|
} else if !found {
|
|
log.Debug().Msg("No configuration file found")
|
|
} else {
|
|
log.Info().Msgf("Configuration loaded from file: %s", fileLoader.GetFilename())
|
|
}
|
|
|
|
envLoader := gonfig.NewEnvLoader(gonfig.EnvLoaderConfig{
|
|
Prefix: "DIUN_",
|
|
})
|
|
if found, err := envLoader.Load(&cfg); err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode configuration from environment variables")
|
|
} else if !found {
|
|
log.Debug().Msg("No DIUN_* environment variables defined")
|
|
} else {
|
|
log.Info().Msgf("Configuration loaded from %d environment variable(s)", len(envLoader.GetVars()))
|
|
}
|
|
|
|
if err := cfg.validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &cfg, nil
|
|
}
|
|
|
|
func (cfg *Config) validate() error {
|
|
if len(cfg.Db.Path) > 0 {
|
|
if err := os.MkdirAll(path.Dir(cfg.Db.Path), os.ModePerm); err != nil {
|
|
return errors.Wrap(err, "cannot create database destination folder")
|
|
}
|
|
}
|
|
|
|
if cfg.Watch.Healthchecks != nil && len(cfg.Watch.Healthchecks.UUID) == 0 {
|
|
return errors.New("healthchecks UUID is required")
|
|
}
|
|
|
|
if cfg.Providers == nil {
|
|
return errors.New("at least one provider is required")
|
|
}
|
|
|
|
return validator.New().Struct(cfg)
|
|
}
|
|
|
|
// String returns the string representation of configuration
|
|
func (cfg *Config) String() string {
|
|
b, _ := json.MarshalIndent(cfg, "", " ")
|
|
return string(b)
|
|
}
|