diff --git a/agent/structs/config_entry.go b/agent/structs/config_entry.go index a958609f8..d377f83a7 100644 --- a/agent/structs/config_entry.go +++ b/agent/structs/config_entry.go @@ -10,7 +10,6 @@ import ( "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/decode" "github.com/hashicorp/go-msgpack/codec" - "github.com/hashicorp/go-multierror" "github.com/mitchellh/hashstructure" "github.com/mitchellh/mapstructure" ) @@ -305,16 +304,7 @@ func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) { return nil, err } - for _, k := range md.Unused { - switch { - case k == "CreateIndex" || k == "ModifyIndex": - case strings.HasSuffix(strings.ToLower(k), "namespace"): - err = multierror.Append(err, fmt.Errorf("invalid config key %q, namespaces are a consul enterprise feature", k)) - default: - err = multierror.Append(err, fmt.Errorf("invalid config key %q", k)) - } - } - if err != nil { + if err := validateUnusedKeys(md.Unused); err != nil { return nil, err } return entry, nil diff --git a/agent/structs/config_entry_oss.go b/agent/structs/config_entry_oss.go index 9e313c6e3..a3ca07c1b 100644 --- a/agent/structs/config_entry_oss.go +++ b/agent/structs/config_entry_oss.go @@ -2,6 +2,28 @@ package structs +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-multierror" +) + func (e *ProxyConfigEntry) validateEnterpriseMeta() error { return nil } + +func validateUnusedKeys(unused []string) error { + var err error + + for _, k := range unused { + switch { + case k == "CreateIndex" || k == "ModifyIndex": + case strings.HasSuffix(strings.ToLower(k), "namespace"): + err = multierror.Append(err, fmt.Errorf("invalid config key %q, namespaces are a consul enterprise feature", k)) + default: + err = multierror.Append(err, fmt.Errorf("invalid config key %q", k)) + } + } + return err +} diff --git a/agent/structs/config_entry_oss_test.go b/agent/structs/config_entry_oss_test.go new file mode 100644 index 000000000..8e2cc13e7 --- /dev/null +++ b/agent/structs/config_entry_oss_test.go @@ -0,0 +1,99 @@ +// +build !consulent + +package structs + +import ( + "github.com/hashicorp/hcl" + "github.com/stretchr/testify/require" + "testing" +) + +func TestDecodeConfigEntry_OSS(t *testing.T) { + + for _, tc := range []struct { + name string + camel string + snake string + expect ConfigEntry + expectErr string + }{ + { + name: "namespaces invalid top level", + snake: ` + kind = "terminating-gateway" + name = "terminating-gateway" + namespace = "foo" + `, + camel: ` + Kind = "terminating-gateway" + Name = "terminating-gateway" + Namespace = "foo" + `, + expectErr: `invalid config key "namespace", namespaces are a consul enterprise feature`, + }, + { + name: "namespaces invalid deep", + snake: ` + kind = "ingress-gateway" + name = "ingress-web" + listeners = [ + { + port = 8080 + protocol = "http" + services = [ + { + name = "web" + hosts = ["test.example.com", "test2.example.com"] + namespace = "frontend" + }, + ] + } + ] + `, + camel: ` + Kind = "ingress-gateway" + Name = "ingress-web" + Namespace = "blah" + Listeners = [ + { + Port = 8080 + Protocol = "http" + Services = [ + { + Name = "web" + Hosts = ["test.example.com", "test2.example.com"] + Namespace = "frontend" + }, + ] + }, + ] + `, + expectErr: `* invalid config key "listeners[0].services[0].namespace", namespaces are a consul enterprise feature`, + }, + } { + tc := tc + + testbody := func(t *testing.T, body string) { + var raw map[string]interface{} + err := hcl.Decode(&raw, body) + require.NoError(t, err) + + got, err := DecodeConfigEntry(raw) + if tc.expectErr != "" { + require.Nil(t, got) + require.Error(t, err) + requireContainsLower(t, err.Error(), tc.expectErr) + } else { + require.NoError(t, err) + require.Equal(t, tc.expect, got) + } + } + + t.Run(tc.name+" (snake case)", func(t *testing.T) { + testbody(t, tc.snake) + }) + t.Run(tc.name+" (camel case)", func(t *testing.T) { + testbody(t, tc.camel) + }) + } +} diff --git a/agent/structs/config_entry_test.go b/agent/structs/config_entry_test.go index c37430e50..34ccfbaf4 100644 --- a/agent/structs/config_entry_test.go +++ b/agent/structs/config_entry_test.go @@ -86,59 +86,6 @@ func TestDecodeConfigEntry(t *testing.T) { }, }, }, - { - name: "namespaces invalid top level", - snake: ` - kind = "terminating-gateway" - name = "terminating-gateway" - namespace = "foo" - `, - camel: ` - Kind = "terminating-gateway" - Name = "terminating-gateway" - Namespace = "foo" - `, - expectErr: `invalid config key "namespace", namespaces are a consul enterprise feature`, - }, - { - name: "namespaces invalid deep", - snake: ` - kind = "ingress-gateway" - name = "ingress-web" - listeners = [ - { - port = 8080 - protocol = "http" - services = [ - { - name = "web" - hosts = ["test.example.com", "test2.example.com"] - namespace = "frontend" - }, - ] - } - ] - `, - camel: ` - Kind = "ingress-gateway" - Name = "ingress-web" - Namespace = "blah" - Listeners = [ - { - Port = 8080 - Protocol = "http" - Services = [ - { - Name = "web" - Hosts = ["test.example.com", "test2.example.com"] - Namespace = "frontend" - }, - ] - }, - ] - `, - expectErr: `invalid config key "listeners[0].services[0].namespace", namespaces are a consul enterprise feature`, - }, { name: "service-defaults", snake: ` @@ -776,8 +723,6 @@ func TestDecodeConfigEntry(t *testing.T) { tc := tc testbody := func(t *testing.T, body string) { - t.Helper() - var raw map[string]interface{} err := hcl.Decode(&raw, body) require.NoError(t, err)