diff --git a/.changelog/17525.txt b/.changelog/17525.txt new file mode 100644 index 000000000..66bdcb8d9 --- /dev/null +++ b/.changelog/17525.txt @@ -0,0 +1,3 @@ +```release-note:improvement +http: accept query parameters `datacenter`, `ap` (enterprise-only), and `namespace` (enterprise-only). Both short-hand and long-hand forms of these query params are now supported via the HTTP API (dc/datacenter, ap/partition, ns/namespace). +``` \ No newline at end of file diff --git a/agent/http.go b/agent/http.go index 701674b55..1706794ad 100644 --- a/agent/http.go +++ b/agent/http.go @@ -983,9 +983,12 @@ func parseConsistencyReadRequest(resp http.ResponseWriter, req *http.Request, b } } -// parseDC is used to parse the ?dc query param +// parseDC is used to parse the datacenter from the query params. +// ?datacenter has precedence over ?dc. func (s *HTTPHandlers) parseDC(req *http.Request, dc *string) { - if other := req.URL.Query().Get("dc"); other != "" { + if other := req.URL.Query().Get("datacenter"); other != "" { + *dc = other + } else if other = req.URL.Query().Get("dc"); other != "" { *dc = other } else if *dc == "" { *dc = s.agent.config.Datacenter diff --git a/agent/http_test.go b/agent/http_test.go index 37acc5f8e..967b1b0b4 100644 --- a/agent/http_test.go +++ b/agent/http_test.go @@ -881,6 +881,15 @@ func TestParseSource(t *testing.T) { t.Fatalf("bad: %v", source) } + // We should follow whatever datacenter parameter was given so that the node is + // looked up correctly on the receiving end. + req, _ = http.NewRequest("GET", "/v1/catalog/nodes?near=bob&datacenter=foo", nil) + source = structs.QuerySource{} + a.srv.parseSource(req, &source) + if source.Datacenter != "foo" || source.Node != "bob" { + t.Fatalf("bad: %v", source) + } + // The magic "_agent" node name will use the agent's local node name. req, _ = http.NewRequest("GET", "/v1/catalog/nodes?near=_agent", nil) source = structs.QuerySource{} diff --git a/api/api.go b/api/api.go index e7109141b..1fe0c71b6 100644 --- a/api/api.go +++ b/api/api.go @@ -836,12 +836,21 @@ func (r *request) setQueryOptions(q *QueryOptions) { return } if q.Namespace != "" { + // For backwards-compatibility with existing tests, + // use the short-hand query param name "ns" + // rather than the alternative long-hand "namespace" r.params.Set("ns", q.Namespace) } if q.Partition != "" { + // For backwards-compatibility with existing tests, + // use the long-hand query param name "partition" + // rather than the alternative short-hand "ap" r.params.Set("partition", q.Partition) } if q.Datacenter != "" { + // For backwards-compatibility with existing tests, + // use the short-hand query param name "dc" + // rather than the alternative long-hand "datacenter" r.params.Set("dc", q.Datacenter) } if q.Peer != "" { @@ -949,12 +958,16 @@ func (r *request) setWriteOptions(q *WriteOptions) { if q == nil { return } + // For backwards-compatibility, continue to use the shorthand "ns" + // rather than "namespace" if q.Namespace != "" { r.params.Set("ns", q.Namespace) } if q.Partition != "" { r.params.Set("partition", q.Partition) } + // For backwards-compatibility, continue to use the shorthand "dc" + // rather than "datacenter" if q.Datacenter != "" { r.params.Set("dc", q.Datacenter) } diff --git a/command/connect/envoy/envoy_test.go b/command/connect/envoy/envoy_test.go index d1105df0d..86c48a8e3 100644 --- a/command/connect/envoy/envoy_test.go +++ b/command/connect/envoy/envoy_test.go @@ -1466,6 +1466,9 @@ func testMockAgentGatewayConfig(namespacesEnabled bool) http.HandlerFunc { func namespaceFromQuery(r *http.Request) string { // Use the namespace in the request if there is one, otherwise // use-default. + if queryNamespace := r.URL.Query().Get("namespace"); queryNamespace != "" { + return queryNamespace + } if queryNs := r.URL.Query().Get("ns"); queryNs != "" { return queryNs } @@ -1475,8 +1478,11 @@ func namespaceFromQuery(r *http.Request) string { func partitionFromQuery(r *http.Request) string { // Use the partition in the request if there is one, otherwise // use-default. - if queryAP := r.URL.Query().Get("partition"); queryAP != "" { - return queryAP + if queryPartition := r.URL.Query().Get("partition"); queryPartition != "" { + return queryPartition + } + if queryAp := r.URL.Query().Get("ap"); queryAp != "" { + return queryAp } return "default" }