diff --git a/agent/http_oss.go b/agent/http_oss.go index 415a8eeaf..e36148319 100644 --- a/agent/http_oss.go +++ b/agent/http_oss.go @@ -12,10 +12,10 @@ import ( func (s *HTTPServer) parseEntMeta(req *http.Request, entMeta *structs.EnterpriseMeta) error { if headerNS := req.Header.Get("X-Consul-Namespace"); headerNS != "" { - return BadRequestError{Reason: "Invalid header: \"X-Consul-Namespace\" - Namespaces is a Consul Enterprise feature"} + return BadRequestError{Reason: "Invalid header: \"X-Consul-Namespace\" - Namespaces are a Consul Enterprise feature"} } if queryNS := req.URL.Query().Get("ns"); queryNS != "" { - return BadRequestError{Reason: "Invalid query parameter: \"ns\" - Namespaces is a Consul Enterprise feature"} + return BadRequestError{Reason: "Invalid query parameter: \"ns\" - Namespaces are a Consul Enterprise feature"} } return nil } @@ -36,7 +36,7 @@ func (s *HTTPServer) rewordUnknownEnterpriseFieldError(err error) error { switch quotedField { case `"Namespace"`: - return fmt.Errorf("%v - Namespaces is a Consul Enterprise feature", err) + return fmt.Errorf("%v - Namespaces are a Consul Enterprise feature", err) } } @@ -47,7 +47,7 @@ func (s *HTTPServer) addEnterpriseHTMLTemplateVars(vars map[string]interface{}) func parseACLAuthMethodEnterpriseMeta(req *http.Request, _ *structs.ACLAuthMethodEnterpriseMeta) error { if methodNS := req.URL.Query().Get("authmethod-ns"); methodNS != "" { - return BadRequestError{Reason: "Invalid query parameter: \"authmethod-ns\" - Namespaces is a Consul Enterprise feature"} + return BadRequestError{Reason: "Invalid query parameter: \"authmethod-ns\" - Namespaces are a Consul Enterprise feature"} } return nil diff --git a/agent/structs/config_entry.go b/agent/structs/config_entry.go index 922076a82..a958609f8 100644 --- a/agent/structs/config_entry.go +++ b/agent/structs/config_entry.go @@ -306,8 +306,10 @@ func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) { } for _, k := range md.Unused { - switch k { - case "CreateIndex", "ModifyIndex": + 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)) } diff --git a/agent/structs/config_entry_test.go b/agent/structs/config_entry_test.go index 9f699aa2c..c37430e50 100644 --- a/agent/structs/config_entry_test.go +++ b/agent/structs/config_entry_test.go @@ -86,6 +86,59 @@ 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: ` diff --git a/api/acl.go b/api/acl.go index aa4411b24..7453feb8a 100644 --- a/api/acl.go +++ b/api/acl.go @@ -50,7 +50,7 @@ type ACLToken struct { Rules string `json:",omitempty"` // Namespace is the namespace the ACLToken is associated with. - // Namespaces is a Consul Enterprise feature. + // Namespaces are a Consul Enterprise feature. Namespace string `json:",omitempty"` } diff --git a/command/flags/http.go b/command/flags/http.go index ae2a33113..732852642 100644 --- a/command/flags/http.go +++ b/command/flags/http.go @@ -79,7 +79,7 @@ func (f *HTTPFlags) NamespaceFlags() *flag.FlagSet { fs.Var(&f.namespace, "namespace", "Specifies the namespace to query. If not provided, the namespace will be inferred "+ "from the request's ACL token, or will default to the `default` namespace. "+ - "Namespaces is a Consul Enterprise feature.") + "Namespaces are a Consul Enterprise feature.") return fs } diff --git a/website/pages/partials/http_api_namespace_options.mdx b/website/pages/partials/http_api_namespace_options.mdx index 08c7dbf75..cf29537ba 100644 --- a/website/pages/partials/http_api_namespace_options.mdx +++ b/website/pages/partials/http_api_namespace_options.mdx @@ -1 +1 @@ -- `-namespace=` - Specifies the namespace to query. If not provided, the namespace will be inferred from the request's ACL token, or will default to the `default` namespace. Namespaces is a Consul Enterprise feature added in v1.7.0. +- `-namespace=` - Specifies the namespace to query. If not provided, the namespace will be inferred from the request's ACL token, or will default to the `default` namespace. Namespaces are a Consul Enterprise feature added in v1.7.0.