diff --git a/command/agent/config.go b/command/agent/config.go index cecaf7c4a..e98467866 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)