diff --git a/cmd/config.go b/cmd/config.go deleted file mode 100644 index 2a8d936..0000000 --- a/cmd/config.go +++ /dev/null @@ -1,30 +0,0 @@ -package cmd - -import ( - "fmt" - "log" - - "gitea.nehmer.net/torben/dyndns/service" - "gitea.nehmer.net/torben/dyndns/webapi" - "github.com/spf13/viper" -) - -func InitializeViper() { - viper.SetConfigName("conf.yml") - viper.SetConfigType("yaml") - viper.AddConfigPath("/etc/dyndns") - viper.AddConfigPath(".") - - if err := viper.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - log.Println("Could not find configfile, using defaults") - } else { - log.Fatalln(fmt.Sprintf("configuration is invalid: %s", err)) - } - } -} - -func setAllConfigDefaults() { - service.SetConfigDefaults() - webapi.SetConfigDefaults() -} diff --git a/cmd/dns-update.go b/cmd/dns-update.go index 83c517c..1e345bc 100644 --- a/cmd/dns-update.go +++ b/cmd/dns-update.go @@ -5,7 +5,6 @@ import ( "gitea.nehmer.net/torben/dyndns/service" "github.com/spf13/cobra" - "github.com/spf13/viper" ) var cmdDNSUpdate = &cobra.Command{ @@ -26,7 +25,6 @@ func init() { cmdDNSUpdate.MarkFlagRequired("domain") cmdDNSUpdate.Run = func(cmd *cobra.Command, args []string) { - log.Printf("Configuration in use: %v", viper.AllSettings()) service.LoadConfig() err := service.DNSUpdateEntry(*domain, *name, *ip4, *ip6) diff --git a/cmd/hash-password.go b/cmd/hash-password.go index be71751..a02748d 100644 --- a/cmd/hash-password.go +++ b/cmd/hash-password.go @@ -8,7 +8,6 @@ import ( "gitea.nehmer.net/torben/dyndns/service" "github.com/spf13/cobra" - "github.com/spf13/viper" "golang.org/x/crypto/ssh/terminal" ) @@ -18,7 +17,6 @@ var cmdHashPassword = &cobra.Command{ Long: `Creates a salted hash using bcrypt for use in userconfig files, so that we don't have to store a plaintext password.`, Run: func(cmd *cobra.Command, args []string) { - log.Printf("Configuration in use: %v", viper.AllSettings()) service.LoadConfig() fmt.Println("Enter password:") diff --git a/cmd/nft-update.go b/cmd/nft-update.go index 2a994d4..5e8945a 100644 --- a/cmd/nft-update.go +++ b/cmd/nft-update.go @@ -5,7 +5,6 @@ import ( "gitea.nehmer.net/torben/dyndns/service" "github.com/spf13/cobra" - "github.com/spf13/viper" ) var cmdNFTUpdate = &cobra.Command{ @@ -27,7 +26,6 @@ func init() { set6 := cmdNFTUpdate.Flags().StringP("set6", "r", "", "The IPv6 NFT Set name in the given table.") cmdNFTUpdate.Run = func(cmd *cobra.Command, args []string) { - log.Printf("Configuration in use: %v", viper.AllSettings()) service.LoadConfig() err := service.NFTUpdateSetsCmd(*table, *set4, *ip4, *set6, *ip6) diff --git a/cmd/root.go b/cmd/root.go index 140ef32..bc8b403 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,11 +2,18 @@ package cmd import ( "fmt" + "log" "os" + "path/filepath" + "gitea.nehmer.net/torben/dyndns/service" + "gitea.nehmer.net/torben/dyndns/webapi" "github.com/spf13/cobra" + "github.com/spf13/viper" ) +var ConfigDir string + var rootCmd = &cobra.Command{ Use: "dyndns", Short: "Go DynDNS Server", @@ -14,10 +21,50 @@ var rootCmd = &cobra.Command{ NFTable Firewall and a properly configured Bind DNS Server.`, } +func init() { + cobra.OnInitialize(initConfig) + + rootCmd.PersistentFlags().StringVarP(&ConfigDir, "config-dir", "c", ".", "base configuration directory, defaults to .") +} + func Exec() { - err := rootCmd.Execute() - if err != nil { - fmt.Println(err) - os.Exit(1) + if err := os.Chdir(ConfigDir); err != nil { + log.Fatalf("Could not change to directory %s: %v", ConfigDir, err) + } + if err := rootCmd.Execute(); err != nil { + log.Fatalf("Failed to execute command: %v", err) } } + +func sanitizeConfigDir() { + var err error + if ConfigDir, err = filepath.Abs(ConfigDir); err != nil { + cobra.CheckErr(fmt.Sprintf("path is invalid: %v", err)) + } + log.Printf("Using configuration directory %s", ConfigDir) +} + +func initConfig() { + sanitizeConfigDir() + + viper.SetConfigName("conf.yml") + viper.SetConfigType("yaml") + viper.AddConfigPath(ConfigDir) + + if err := viper.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + log.Println("Could not find configfile, using defaults") + } else { + cobra.CheckErr(fmt.Sprintf("configuration is invalid: %s", err)) + } + } + + viper.Set("ConfigDir", ConfigDir) + + log.Printf("Configuration in use: %v", viper.AllSettings()) +} + +func setAllConfigDefaults() { + service.SetConfigDefaults() + webapi.SetConfigDefaults() +} diff --git a/cmd/serve.go b/cmd/serve.go index ec3da57..ce2ebaf 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -1,8 +1,6 @@ package cmd import ( - "log" - "gitea.nehmer.net/torben/dyndns/service" "gitea.nehmer.net/torben/dyndns/webapi" "github.com/spf13/cobra" @@ -14,7 +12,6 @@ var cmdServe = &cobra.Command{ Short: "Start webserver", Long: ``, Run: func(cmd *cobra.Command, args []string) { - log.Printf("Configuration in use: %v", viper.AllSettings()) webapi.LoadConfig() service.LoadConfig() webapi.Server() diff --git a/main.go b/main.go index feb9fc1..fbeb6ad 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,5 @@ import ( ) func main() { - cmd.InitializeViper() cmd.Exec() } diff --git a/service/config.go b/service/config.go index 7c23ca1..91c5116 100644 --- a/service/config.go +++ b/service/config.go @@ -3,6 +3,7 @@ package service import ( "encoding/json" "log" + "path/filepath" "github.com/spf13/viper" ) @@ -40,7 +41,12 @@ func LoadConfig() { // viper.UnmarshalKey("Service", &C) C.DNS.Server = viper.GetString("Service.DNS.Server") C.DNS.DefaultTTL = viper.GetUint32("Service.DNS.DefaultTTL") - C.Users.ConfigDir = viper.GetString("Service.Users.ConfigDir") + path := viper.GetString("Service.Users.ConfigDir") + if filepath.IsAbs(path) { + C.Users.ConfigDir = filepath.Clean(path) + } else { + C.Users.ConfigDir = filepath.Join(viper.GetString("ConfigDir"), path) + } } func (obj *config) PrettyPrint() string {