diff options
| author | Paul Buetow <paul@buetow.org> | 2024-05-11 12:52:28 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-05-11 12:52:28 +0300 |
| commit | 653057ac9d2ba6783233bc0f59a6a7ca111ad11c (patch) | |
| tree | e5be6be1f6df5066885b73bf20d06acb42acc718 | |
| parent | 248e4919501a472b90505c0ada6a47113acd6688 (diff) | |
refactor server
refactor config
| -rw-r--r-- | cmd/gosd/main.go | 50 | ||||
| -rw-r--r-- | internal/config/config.go | 66 | ||||
| -rw-r--r-- | internal/config/config_test.go | 8 |
3 files changed, 74 insertions, 50 deletions
diff --git a/cmd/gosd/main.go b/cmd/gosd/main.go index de5a129..f0ad096 100644 --- a/cmd/gosd/main.go +++ b/cmd/gosd/main.go @@ -6,18 +6,21 @@ import ( "log" "net/http" + "codeberg.org/snonux/gos/internal/config" "codeberg.org/snonux/gos/internal/server/handle" "codeberg.org/snonux/gos/internal/server/health" ) -const apiKey = "banana" // for dev purposes only, will be changed to something else const healthHandlerName = `healthHandler` -var hs = health.NewStatus() +type server struct { + hs health.Status + conf config.Config +} type handlerFuncWithError func(http.ResponseWriter, *http.Request) error -func httpHandle(name string, handler handlerFuncWithError) { +func (s server) httpHandle(name string, handler handlerFuncWithError) { var ( handlerPath = fmt.Sprintf("/%s", name) handlerName = fmt.Sprintf("%sHandler", name) @@ -27,43 +30,52 @@ func httpHandle(name string, handler handlerFuncWithError) { log.Println("Someone requested", handlerName) // The health endpoint doesn't require an API key - if handlerName != healthHandlerName && r.Header.Get("X-API-KEY") != apiKey { + if handlerName != healthHandlerName && r.Header.Get("X-API-KEY") != s.conf.ApiKey { http.Error(w, "Invalid API key", http.StatusUnauthorized) log.Println("Unauthorized access attempt to", handlerName) return } if err := handler(w, r); err != nil { - hs.Set(health.Critical, handlerName, err.Error()) + s.hs.Set(health.Critical, handlerName, err.Error()) return } - hs.Clear(handlerName) + s.hs.Clear(handlerName) }) } func main() { - listenAddr := flag.String("listenAddr", "localhost:8080", "The listen address") - dataDir := flag.String("dataDir", "data", "The data directory") + configFile := flag.String("cfg", "/etc/gos.json", "The configuration file") + + conf, err := config.New(*configFile) + if err != nil { + log.Fatal("error building config:", err) + } + + serv := server{ + conf: conf, + hs: health.NewStatus(), + } - httpHandle("health", func(w http.ResponseWriter, r *http.Request) error { - fmt.Fprint(w, hs.String()) + serv.httpHandle("health", func(w http.ResponseWriter, r *http.Request) error { + fmt.Fprint(w, serv.hs.String()) return nil }) - httpHandle("submit", func(w http.ResponseWriter, r *http.Request) error { - return handle.Submit(w, r, *dataDir) + serv.httpHandle("submit", func(w http.ResponseWriter, r *http.Request) error { + return handle.Submit(w, r, serv.conf.DataDir) }) - httpHandle("list", func(w http.ResponseWriter, r *http.Request) error { - return handle.List(w, r, *dataDir) + serv.httpHandle("list", func(w http.ResponseWriter, r *http.Request) error { + return handle.List(w, r, serv.conf.DataDir) }) - httpHandle("get", func(w http.ResponseWriter, r *http.Request) error { - return handle.Get(w, r, *dataDir) + serv.httpHandle("get", func(w http.ResponseWriter, r *http.Request) error { + return handle.Get(w, r, serv.conf.DataDir) }) - log.Println("Server is starting on", *listenAddr) - if err := http.ListenAndServe(*listenAddr, nil); err != err { - log.Fatal("Error starting server: ", err) + log.Println("Server is starting on", serv.conf.ListenAddr) + if err := http.ListenAndServe(serv.conf.ListenAddr, nil); err != err { + log.Fatal("error starting server:", err) } } diff --git a/internal/config/config.go b/internal/config/config.go index ab9ee7a..ad82b15 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -10,23 +10,41 @@ import ( "unicode" ) -type config struct { +type Config struct { + ListenAddr string `json:"ListenAddr,omitempty"` + Partner string `json:"Partner,omitempty"` + ApiKey string `json:"ApiKey,omitempty"` + DataDir string `json:"StateDir,omitempty"` EmailTo string `json:"EmailTo,omitempty"` EmailFrom string `json:"EmailFrom,omitempty"` SMTPServer string `json:"SMTPServer,omitempty"` - DataDir string `json:"StateDir,omitempty"` - Partner string `json:"Partner,omitempty"` } -func newConfig(configFile string) (config, error) { - conf := config{ - EmailTo: fromEnv("EmailTo"), - EmailFrom: fromEnv("EmailFrom"), - SMTPServer: fromEnv("SMTPServer"), - DataDir: fromEnv("DataDir", "data"), - Partner: fromEnv("Partner"), +func New(configFile string) (Config, error) { + conf, _ := newFromConfigFile(configFile) + conf.ListenAddr = fromEnv("ListenAddr", conf.ListenAddr, "localhost:8080") + conf.Partner = fromEnv("Partner", conf.Partner) + conf.ApiKey = fromEnv("ApiKey", conf.ApiKey) + conf.DataDir = fromEnv("DataDir", conf.DataDir, "data") + conf.EmailTo = fromEnv("EmailTo", conf.EmailTo) + conf.EmailFrom = fromEnv("EmailFrom", conf.EmailFrom) + conf.SMTPServer = fromEnv("SMTPServer", conf.SMTPServer) + + if conf.SMTPServer == "" { + hostname, err := os.Hostname() + if err != nil { + log.Fatal(err) + } + conf.SMTPServer = fmt.Sprintf("%s:25", hostname) + log.Println("Set SMTPServer to " + conf.SMTPServer) } + return conf, nil +} + +func newFromConfigFile(configFile string) (Config, error) { + var conf Config + file, err := os.Open(configFile) if err != nil { return conf, err @@ -39,25 +57,7 @@ func newConfig(configFile string) (config, error) { } err = json.Unmarshal(bytes, &conf) - if err != nil { - return conf, err - } - - if conf.SMTPServer == "" { - hostname, err := os.Hostname() - if err != nil { - log.Fatal(err) - } - conf.SMTPServer = fmt.Sprintf("%s:25", hostname) - log.Println("Set SMTPServer to " + conf.SMTPServer) - } - - if conf.DataDir == "" { - conf.DataDir = "data" - log.Println("Set data dir to " + conf.DataDir) - } - - return conf, nil + return conf, err } // Set config from envoronment variable if present, e.g. hansWurst from GOS_HANS_WURST @@ -67,9 +67,13 @@ func fromEnv(configKey string, defaultValue ...string) string { return value } - if len(defaultValue) > 0 { - return defaultValue[0] + // Use first non-empty default value. + for _, value := range defaultValue { + if value != "" { + return value + } } + return "" } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 5c429c9..1b133bd 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -49,4 +49,12 @@ func TestFromEnv(t *testing.T) { return } t.Logf("got empty string as expected") + + expected = "casio g-shock" + got = fromEnv("watch", "", "", "", expected, "") + if got != expected { + t.Errorf("got '%s' but expected '%s'", got, expected) + return + } + t.Logf("got '%s' as expected", expected) } |
