rpi-relay/config/config.go

66 lines
1.5 KiB
Go

package config
import (
"errors"
"github.com/go-playground/validator"
"github.com/imdario/mergo"
confLoader "github.com/otakukaze/config-loader"
)
type Config struct {
Server Server `yaml:"server"`
}
type Server struct {
Port int `yaml:"port" env:"SERVER_PORT" default:"10230" validate:"gte=1,lte=65535"`
Secret string `yaml:"secret" env:"SERVER_SECRET" default:"lawsnote-rpi" validate:"required,min=1"`
RelayPin int `yaml:"relay_pin" env:"SERVER_RELAY_PIN" validate:"required,gte=1,lte=255"`
}
func Load(cfgPath ...string) (*Config, error) {
cfg := &Config{}
// load config from env and default value
if err := confLoader.Load(cfg, &confLoader.LoadOptions{FromEnv: true}); err != nil {
return nil, err
}
validate := validator.New()
if len(cfgPath) > 0 {
for _, v := range cfgPath {
fileOpts := &confLoader.ConfigFile{Type: confLoader.ConfigFileTypeYAML, Path: v}
loadOpts := &confLoader.LoadOptions{ConfigFile: fileOpts, FromEnv: false}
c := &Config{}
if err := confLoader.Load(c, loadOpts); err != nil {
return nil, err
}
// validate struct fields
if err := validate.Struct(c); err != nil {
return nil, err
}
// merge new config to prev config withOverride
if err := mergo.Merge(&cfg, c, mergo.WithOverride); err != nil {
return nil, err
}
}
}
if cfg.Server.RelayPin < 1 || cfg.Server.RelayPin > 255 {
return nil, errors.New("gpio pin range wrong (1 <= x <= 255)")
}
if cfg.Server.Secret == "" {
return nil, errors.New("secret empty")
}
return cfg, nil
}