From 107c23a29da0c1b3f71a0cff4f7a39d4bbc8a9a2 Mon Sep 17 00:00:00 2001 From: henk Date: Fri, 15 May 2026 14:22:16 +0200 Subject: [PATCH] package config --- go.mod | 5 ++- go.sum | 4 ++ internal/config/config.go | 58 +++++++++++++++++++++++++++ internal/config/yamlloader.go | 29 ++++++++++++++ internal/server/gethandlers.go | 11 ++++++ internal/server/server.go | 72 ++++++++++++++++++++++++++++++++++ main.go | 3 +- 7 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 internal/config/config.go create mode 100644 internal/config/yamlloader.go create mode 100644 internal/server/gethandlers.go create mode 100644 internal/server/server.go diff --git a/go.mod b/go.mod index e60b441..0f3fcc0 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module git.systemact.nl/henk/mars-terraform-registry go 1.26.2 -require gopkg.in/natefinch/lumberjack.v2 v2.2.1 +require ( + gopkg.in/natefinch/lumberjack.v2 v2.2.1 + gopkg.in/yaml.v3 v3.0.1 +) diff --git a/go.sum b/go.sum index 96b0a10..53a5689 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,6 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..e75bd6d --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,58 @@ +package config + +import ( + "time" +) + +type Config struct { + Server ServerConfig `yaml:"server"` + Auth AuthConfig `yaml:"auth"` + TLS TLSConfig `yaml:"tls"` +} + +type ServerConfig struct { + BindAddress string `yaml:"bind_address"` + ReadTimeout time.Duration `yaml:"read_timeout"` + WriteTimeout time.Duration `yaml:"write_timeout"` +} + +type AuthConfig struct { + Mode string `yaml:"mode"` + Token string `yaml:"token,omitempty"` +} + +type TLSConfig struct { + Enabled bool `yaml:"enabled"` + CertFile string `yaml:"cert_file"` + KeyFile string `yaml:"key_file"` +} + +type ConfigLoader interface { + LoadConfig() (*Config, error) +} + +func DefaultConfig() *Config { + return &Config{ + Server: ServerConfig{ + BindAddress: ":8080", + ReadTimeout: 15 * time.Second, + WriteTimeout: 15 * time.Second, + }, + Auth: AuthConfig{ + Mode: "none", + }, + TLS: TLSConfig{ + Enabled: false, + }, + } +} + +func (c Config) applyDefaults() *Config { + if c.Server.BindAddress == "" { + c.Server.BindAddress = ":8080" + } + if c.Auth.Mode == "" { + c.Auth.Mode = "none" + } + return &c +} diff --git a/internal/config/yamlloader.go b/internal/config/yamlloader.go new file mode 100644 index 0000000..1a53425 --- /dev/null +++ b/internal/config/yamlloader.go @@ -0,0 +1,29 @@ +package config + +import ( + "fmt" + "os" + + "gopkg.in/yaml.v3" +) + +type YamlConfigLoader struct { + FilePath string +} + +func (l *YamlConfigLoader) LoadConfig() (*Config, error) { + data, err := os.ReadFile(l.FilePath) + if err != nil { + if os.IsNotExist(err) { + return DefaultConfig(), nil + } + return nil, fmt.Errorf("reading config file: %w", err) + } + + var cfg Config + if err := yaml.Unmarshal(data, &cfg); err != nil { + return nil, fmt.Errorf("parsing config file: %w", err) + } + + return cfg.applyDefaults(), nil +} diff --git a/internal/server/gethandlers.go b/internal/server/gethandlers.go new file mode 100644 index 0000000..5424b0e --- /dev/null +++ b/internal/server/gethandlers.go @@ -0,0 +1,11 @@ +package server + +import ( + "net/http" +) + +func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(`{"status":"ok"}`)) +} diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..2b6762a --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,72 @@ +package server + +import ( + "context" + "fmt" + "log/slog" + "net/http" + + "git.systemact.nl/henk/mars-terraform-registry/internal/config" +) + +type Server struct { + httpServer *http.Server + cfg *config.Config +} + +func NewServer(ctx context.Context, cfgLoader config.ConfigLoader) (*Server, error) { + cfg, err := cfgLoader.LoadConfig() + if err != nil { + return nil, fmt.Errorf("failed to load config: %w", err) + } + + srv := &Server{ + cfg: cfg, + } + err = srv.setup() + return srv, err +} + +func (s *Server) setup() error { + mux := http.NewServeMux() + + mux.HandleFunc("/health", s.handleHealth) + s.httpServer = &http.Server{ + Handler: mux, + } + return nil +} + +func (s *Server) Run(ctx context.Context) error { + slog.Info("Starting AgentGopher gateway", "address", s.cfg.Server.BindAddress) + + errCh := make(chan error, 1) + go func() { + if s.cfg.TLS.Enabled { + errCh <- s.httpServer.ListenAndServeTLS(s.cfg.TLS.CertFile, s.cfg.TLS.KeyFile) + } else { + errCh <- s.httpServer.ListenAndServe() + } + }() + + select { + case <-ctx.Done(): + slog.Info("Shutdown signal received") + return s.Shutdown(context.Background()) + case err := <-errCh: + return err + } +} + +func (s *Server) Shutdown(ctx context.Context) error { + var errs []error + + if err := s.httpServer.Shutdown(ctx); err != nil { + errs = append(errs, fmt.Errorf("http server shutdown: %w", err)) + } + + if len(errs) > 0 { + return fmt.Errorf("shutdown errors: %v", errs) + } + return nil +} diff --git a/main.go b/main.go index aa29198..d419817 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "io" "log/slog" "os" + "path/filepath" "gopkg.in/natefinch/lumberjack.v2" ) @@ -13,7 +14,7 @@ func main() { if err != nil { panic("Can't determine home directory") } - logFilePath := logBaseDir + "/.local/share/mars_terraform_registry/logs" + logFilePath := filepath.Join(logBaseDir, ".local", "share", "mars_terraform_registry", "logs") if err := os.MkdirAll(logFilePath, 0755); err != nil { panic("Can't create log directory") }