diff --git a/command/agent/config.go b/command/agent/config.go index 707cd43ade76..e9846786644b 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -474,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) diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 13e8634ce44f..f0bbd9e61c3d 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "testing" "time" ) @@ -591,6 +592,14 @@ func TestDecodeConfig(t *testing.T) { } } +func TestDecodeConfig_invalidKeys(t *testing.T) { + input := `{"bad": "no way jose"}` + _, err := DecodeConfig(bytes.NewReader([]byte(input))) + if err == nil || !strings.Contains(err.Error(), "invalid keys") { + t.Fatalf("should have rejected invalid config keys") + } +} + func TestDecodeConfig_Services(t *testing.T) { input := `{ "services": [