From 42ace3a6b5fae1f0af5a6e7bbb63d4a432c6f229 Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Mon, 5 Jan 2015 14:41:19 -0800 Subject: [PATCH] agent: use mapstructure's Metadata.Unused to detect extraneous config --- command/agent/config.go | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/command/agent/config.go b/command/agent/config.go index cecaf7c4a1..e984678664 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -335,13 +335,6 @@ type Config struct { // WatchPlans contains the compiled watches WatchPlans []*watch.WatchPlan `mapstructure:"-" json:"-"` - - // Allow the following fields to be present in configuration files without - // mapstructure erroring on them. - _ interface{} `mapstructure:"services"` - _ interface{} `mapstructure:"checks"` - _ interface{} `mapstructure:"service"` - _ interface{} `mapstructure:"check"` } type dirEnts []os.FileInfo @@ -470,9 +463,8 @@ func DecodeConfig(r io.Reader) (*Config, error) { // Decode var md mapstructure.Metadata msdec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - Metadata: &md, - Result: &result, - ErrorUnused: true, + Metadata: &md, + Result: &result, }) if err != nil { return nil, err @@ -482,6 +474,20 @@ func DecodeConfig(r io.Reader) (*Config, error) { return nil, err } + // Check unused fields and verify that no bad configuration options were + // passed to Consul. There are a few additional fields which don't directly + // use mapstructure decoding, so we need to account for those as well. + allowedKeys := []string{"service", "services", "check", "checks"} + var unused []string + for _, field := range md.Unused { + if !strContains(allowedKeys, field) { + unused = append(unused, field) + } + } + if len(unused) > 0 { + return nil, fmt.Errorf("Config has invalid keys: %s", strings.Join(unused, ",")) + } + // Handle time conversions if raw := result.DNSConfig.NodeTTLRaw; raw != "" { dur, err := time.ParseDuration(raw)