git » gofer » commit cb5dcb8

config: Warn about undecoded keys

author Alberto Bertogli
2017-08-07 21:16:25 UTC
committer Alberto Bertogli
2017-08-07 21:16:25 UTC
parent b06f6e4a648c2b9d6f25c37c1ace6daec53941aa

config: Warn about undecoded keys

This patch makes gofer warn about undecoded keys, as otherwise it's easy
to miss configuration errors due to typos in optional keys.

config/config.go +15 -1
config/config_test.go +10 -0
gofer.go +4 -0

diff --git a/config/config.go b/config/config.go
index 3fc3c8d..8f47736 100644
--- a/config/config.go
+++ b/config/config.go
@@ -5,6 +5,7 @@ import (
 	"bytes"
 	"fmt"
 	"io/ioutil"
+	"strings"
 
 	"github.com/BurntSushi/toml"
 )
@@ -18,6 +19,9 @@ type Config struct {
 
 	// Map of name -> routes for HTTP(S).
 	Routes map[string]RouteTable
+
+	// Undecoded fields - private so we don't serialize them.
+	undecoded []string
 }
 
 type HTTP struct {
@@ -50,6 +54,10 @@ func mergeRoutes(src, dst RouteTable) {
 	}
 }
 
+func (c Config) Undecoded() []string {
+	return c.undecoded
+}
+
 func (c Config) String() string {
 	s, err := c.ToString()
 	if err != nil {
@@ -77,11 +85,17 @@ func Load(filename string) (*Config, error) {
 
 func LoadString(contents string) (*Config, error) {
 	conf := &Config{}
-	_, err := toml.Decode(contents, conf)
+	md, err := toml.Decode(contents, conf)
 	if err != nil {
 		return nil, fmt.Errorf("error parsing config: %v", err)
 	}
 
+	// Save undecoded keys so they can be accessed later (e.g. for debugging
+	// or checking).
+	for _, key := range md.Undecoded() {
+		conf.undecoded = append(conf.undecoded, strings.Join(key, "."))
+	}
+
 	// Link routes.
 	for _, https := range conf.HTTPS {
 		if https.RouteTable == nil {
diff --git a/config/config_test.go b/config/config_test.go
index f9bb769..1ec9782 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -27,6 +27,7 @@ base_routes = "default"
 addr = ":https"
 certs = "/etc/letsencrypt/live/"
 base_routes = "default"
+unknown_field = "x"
 
   [https.routes]
     "/" = "http://tlsoverrides/"
@@ -78,6 +79,8 @@ base_routes = "default"
 				"/common": "http://common/",
 			},
 		},
+
+		undecoded: []string{"https.unknown_field"},
 	}
 
 	conf, err := LoadString(contents)
@@ -90,4 +93,11 @@ base_routes = "default"
 		t.Errorf("  expected: %v", expected.String())
 		t.Errorf("  got:      %v", conf.String())
 	}
+
+	if !reflect.DeepEqual(conf.Undecoded(), expected.Undecoded()) {
+		t.Errorf("undecoded is not as expected")
+		t.Errorf("  expected: %q", expected.Undecoded())
+		t.Errorf("  got:      %q", conf.Undecoded())
+	}
+
 }
diff --git a/gofer.go b/gofer.go
index f625877..3fa8364 100644
--- a/gofer.go
+++ b/gofer.go
@@ -26,6 +26,10 @@ func main() {
 		util.Log.Fatalf("error reading config file: %v", err)
 	}
 
+	for _, k := range conf.Undecoded() {
+		util.Log.Printf("warning: undecoded config key: %q", k)
+	}
+
 	for _, https := range conf.HTTPS {
 		go proxy.HTTPS(*https)
 	}