aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/config/service.go
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.com>2025-02-06 15:22:34 +0000
committerLeonardo Bishop <me@leonardobishop.com>2025-02-06 15:22:34 +0000
commit2475f5a8b92ef0dd28e7af5f36d01b25243ed778 (patch)
tree12f8931d241db4159f8d30f7bf2b648709a94166 /pkg/config/service.go
Initial commit
Diffstat (limited to 'pkg/config/service.go')
-rw-r--r--pkg/config/service.go99
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
+}