From 9166a78fb79cb13ea6632ecc38e16d35a9a155b9 Mon Sep 17 00:00:00 2001 From: Bennett Wetters Date: Sun, 14 Jan 2024 04:20:03 +0100 Subject: [PATCH] Add -c flag to specify list of config files - Environment variable also accepts comma-separated list - Overwrites cli arguments --- .gitignore | 5 +++ config/config.go | 85 +++++++++++++++++++++++++++++++++++------------- main.go | 16 +++++++++ 3 files changed, 83 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 8a7f400..bb571c2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,8 @@ spaceapid # Saved state spaceapid-state.json + +# Config shards +credentials.json +dynamic.json +response.json diff --git a/config/config.go b/config/config.go index 20c0419..a5258a1 100644 --- a/config/config.go +++ b/config/config.go @@ -3,10 +3,12 @@ package config import ( "bytes" "encoding/json" + "flag" + "fmt" "log" "os" - "path/filepath" "slices" + "strings" "gitlab.hamburg.ccc.de/ccchh/spaceapid/types" ) @@ -15,36 +17,73 @@ const ( envConfigPath = "CONFIG_PATH" ) -// getConfigPath gets the spaceapid configuration from the respective environment variables -func getConfigPath() string { - // JSON template path +type pathsT []string + +func (p *pathsT) String() string { + return fmt.Sprint(*p) +} + +func (p *pathsT) Set(s string) error { + *p = make(pathsT, 0) + for _, path := range strings.Split(s, ",") { + *p = append(*p, path) + } + return nil +} + +var ( + flagConfigPaths pathsT +) + +func init() { + flag.Var(&flagConfigPaths, "c", "Comma-separated list of config file paths. Parsed in order of appearance. Values get overwritten by files parsed later.") +} + +func getConfigPaths() (paths pathsT) { + // Get paths from env variable and if env var present override cli flags configPath, ok := os.LookupEnv(envConfigPath) - if !ok || configPath == "" { - log.Fatalln("Could not retrieve", envConfigPath, "env variable or variable is empty") + if ok { + if configPath == "" { + log.Fatalln("Env variable", envConfigPath, "is present but empty.") + } + _ = flagConfigPaths.Set(configPath) } - // Save as absolute path - absConfigPath, err := filepath.Abs(configPath) - if err != nil { - log.Fatalln("Failed converting", configPath, "to absolute path:", err) + + for _, path := range flagConfigPaths { + _, err := os.Stat(path) + if err != nil { + log.Fatalln("Config file", path, "doesn't exist or is not accessible, error:", err) + } + paths = append(paths, path) } - return absConfigPath + + // If paths is still empty we are missing something + if len(paths) == 0 { + log.Fatalln("Neither the env variable nor cli flag was specified, we are missing a config file.") + } + return } // ParseConfiguration returns the config from file func ParseConfiguration() (conf SpaceapidConfig) { - log.Println("Parsing configuration file") - // Read file - file, err := os.ReadFile(getConfigPath()) - if err != nil { - log.Fatalln("Failed reading file:", err) - } + log.Println("Parsing configuration files") - // Parse JSON - dec := json.NewDecoder(bytes.NewReader(file)) - dec.DisallowUnknownFields() - err = dec.Decode(&conf) - if err != nil { - log.Fatalln("Could not parse spaceapid config file:", err) + paths := getConfigPaths() + log.Println(paths) + for _, path := range paths { + // Read file + file, err := os.ReadFile(path) + if err != nil { + log.Fatalln("Failed reading file:", err) + } + + // Parse JSON + dec := json.NewDecoder(bytes.NewReader(file)) + dec.DisallowUnknownFields() + err = dec.Decode(&conf) + if err != nil { + log.Fatalln("Could not parse spaceapid config file:", err) + } } // Check if compatible with v14 diff --git a/main.go b/main.go index 5f516ea..7555e84 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "log" "net/http" @@ -15,7 +16,22 @@ import ( "gitlab.hamburg.ccc.de/ccchh/spaceapid/util" ) +var ( + flagHelp bool +) + +func init() { + flag.BoolVar(&flagHelp, "h", false, "Print help output") +} + func main() { + flag.Parse() + + if flagHelp { + flag.PrintDefaults() + os.Exit(0) + } + // Get spaceapid configuration conf := config.ParseConfiguration()