diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2025-02-06 15:22:34 +0000 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2025-02-06 15:22:34 +0000 |
| commit | 2475f5a8b92ef0dd28e7af5f36d01b25243ed778 (patch) | |
| tree | 12f8931d241db4159f8d30f7bf2b648709a94166 /pkg/config/service.go | |
Initial commit
Diffstat (limited to 'pkg/config/service.go')
| -rw-r--r-- | pkg/config/service.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/pkg/config/service.go b/pkg/config/service.go new file mode 100644 index 0000000..3c9a27e --- /dev/null +++ b/pkg/config/service.go @@ -0,0 +1,99 @@ +package config + +import ( + "fmt" + "net" + "os" + "regexp" + + validate "github.com/go-playground/validator/v10" + "gopkg.in/yaml.v3" +) + +type Config struct { + Hostname string `yaml:"host" validate:"required"` + TLS struct { + Enabled bool `yaml:"enabled"` + Cert string `yaml:"cert"` + Key string `yaml:"key"` + } `yaml:"tls"` + WireGuard struct { + Network string `yaml:"network" validate:"cidr,required"` + Port string `yaml:"port" validate:"required"` + InterfaceName string `yaml:"interfaceName" validate:"required"` + } `yaml:"wireGuard"` + ExpireAfter int `yaml:"expireAfter"` +} + +type Service interface { + InitialiseConfig(paths ...string) error + Config() *Config +} + +type service struct { + config *Config + validator *validate.Validate +} + +const InterfaceRegex = "^[a-zA-Z0-9_=+.-]{1,15}$" + +func NewService() Service { + return &service{ + validator: validate.New(validate.WithRequiredStructEnabled()), + } +} + +func (s *service) InitialiseConfig(paths ...string) error { + for _, p := range paths { + if _, err := os.Stat(p); err != nil { + continue + } + c := &Config{} + err := readConfig(p, c) + if err != nil { + return err + } + s.config = c + break + } + return nil +} + +func (s *service) Config() *Config { + return s.config +} + +func readConfig(configPath string, dst *Config) error { + config, err := os.ReadFile(configPath) + if err != nil { + return err + } + + if err := yaml.Unmarshal(config, dst); err != nil { + return err + } + return nil +} + +func (s *service) validateConfig(c *Config) error { + if err := s.validator.Struct(c); err != nil { + return err + } + + match, _ := regexp.MatchString(InterfaceRegex, c.WireGuard.InterfaceName) + if !match { + return fmt.Errorf("invalid interface name: %s", c.WireGuard.InterfaceName) + } + + ifaces, err := net.Interfaces() + if err != nil { + return fmt.Errorf("could not list network interfaces: %w", err) + } + for _, i := range ifaces { + if i.Name == c.WireGuard.InterfaceName { + return fmt.Errorf("an interface already exists with the name '%s'", i.Name) + } + } + + return nil +} |
