Repository: hashicorp/consul
Pull request #22189: Fix catalog service endpoint when querying for a peer service
Author: login: jorgemarey
Labels: name: type/docs
description: Documentation needs to be created/updated/clarified
name: pr/no-metrics-test
name: backport/1.21
description: This release series is longer active on CE, use backport/ent/1.21
name: backport/ent/1.21
description: changes are backported to 1.21 ent
Created: 2025-02-25T22:15:13Z | Merged: 2025-04-16T16:35:57Z

When calling `/catalog/service/<service>?peer=<peer-name>` no services are returned even when they are configured as exported in the peer and shown correctly in the UI.

Making the same call on health `/health/service/<service>?peer=<peer-name>` works fine.

This fixes #20792 



Linked issue #20792: /catalog/service/:service_name returns [] for a service in a peered cluster
#### Overview of the Issue

/catalog/service/:service_name returns [] for a service in a peered cluster 

#### Reproduction Steps

Establish a cluster peering connection and call the /catalog/service/:service_name endpoint with the service name being a service in the peered cluster
Linked issue comments: user: login: kubatyszko
created_at: 2024-08-21T16:40:41Z
body: Assuming you're running this API query against the "peer", say the service is defined in cluster A and peered INTO cluster B - if you're issuing that API against cluster B, then you will NOT get the information you need, not the way you do issuing it against cluster A.
I'm trying to find the same solution, and the only one I found is to use different API query: 

`curl --request GET http://CLUSTER_A:8500/v1/health/service/:service_name?peer=A
`
author_association: CONTRIBUTOR

Diff:
diff --git a/.changelog/22189.txt b/.changelog/22189.txt
new file mode 100644
index 00000000000..f7936e2a1b8
--- /dev/null
+++ b/.changelog/22189.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+http: Add peer query param on catalog service API
+```
diff --git a/agent/catalog_endpoint.go b/agent/catalog_endpoint.go
index 8af4654b90f..4847f052c8a 100644
--- a/agent/catalog_endpoint.go
+++ b/agent/catalog_endpoint.go
@@ -354,6 +354,8 @@ func (s *HTTPHandlers) catalogServiceNodes(resp http.ResponseWriter, req *http.R
 		return nil, nil
 	}
 
+	s.parsePeerName(req, &args)
+
 	// Check for a tag
 	params := req.URL.Query()
 	if _, ok := params["tag"]; ok {
diff --git a/agent/catalog_endpoint_test.go b/agent/catalog_endpoint_test.go
index af1f2d36e30..c5a61f3d64a 100644
--- a/agent/catalog_endpoint_test.go
+++ b/agent/catalog_endpoint_test.go
@@ -964,6 +964,76 @@ func TestCatalogServiceNodes_Filter(t *testing.T) {
 	require.Len(t, nodes, 1)
 }
 
+func TestCatalogServiceNodes_PeerFilter(t *testing.T) {
+	if testing.Short() {
+		t.Skip("too slow for testing.Short")
+	}
+
+	t.Parallel()
+	a := StartTestAgent(t, TestAgent{HCL: "", Overrides: `peering = { test_allow_peer_registrations = true }`})
+	defer a.Shutdown()
+
+	peerName := "test"
+	queryPath := "/v1/catalog/service/api?filter=" + url.QueryEscape("ServiceMeta.somekey == somevalue") + peerQuerySuffix(peerName)
+
+	// Make sure an empty list is returned, not a nil
+	{
+		req, _ := http.NewRequest("GET", queryPath, nil)
+		resp := httptest.NewRecorder()
+		obj, err := a.srv.CatalogServiceNodes(resp, req)
+		require.NoError(t, err)
+
+		assertIndex(t, resp)
+
+		nodes := obj.(structs.ServiceNodes)
+		require.Empty(t, nodes)
+	}
+
+	// Register node
+	args := &structs.RegisterRequest{
+		Datacenter: "dc1",
+		Node:       "foo",
+		Address:    "127.0.0.1",
+		PeerName:   peerName,
+		Service: &structs.NodeService{
+			Service: "api",
+			Meta: map[string]string{
+				"somekey": "somevalue",
+			},
+		},
+	}
+
+	var out struct{}
+	require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out))
+
+	// Register a second service for the node
+	args = &structs.RegisterRequest{
+		Datacenter: "dc1",
+		Node:       "foo",
+		Address:    "127.0.0.1",
+		PeerName:   peerName,
+		Service: &structs.NodeService{
+			ID:      "api2",
+			Service: "api",
+			Meta: map[string]string{
+				"somekey": "notvalue",
+			},
+		},
+		SkipNodeUpdate: true,
+	}
+
+	require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out))
+
+	req, _ := http.NewRequest("GET", queryPath, nil)
+	resp := httptest.NewRecorder()
+	obj, err := a.srv.CatalogServiceNodes(resp, req)
+	require.NoError(t, err)
+	assertIndex(t, resp)
+
+	nodes := obj.(structs.ServiceNodes)
+	require.Len(t, nodes, 1)
+}
+
 func TestCatalogServiceNodes_WanTranslation(t *testing.T) {
 	if testing.Short() {
 		t.Skip("too slow for testing.Short")
diff --git a/website/content/api-docs/catalog.mdx b/website/content/api-docs/catalog.mdx
index f773353483a..5a505967d15 100644
--- a/website/content/api-docs/catalog.mdx
+++ b/website/content/api-docs/catalog.mdx
@@ -551,6 +551,8 @@ The table below shows this endpoint's support for
 - `filter` `(string: "")` - Specifies the expression used to filter the
   queries results prior to returning the data.
 
+- `peer` `(string: "")` - Specifies the name of the peer that exported the service. Does not apply when no cluster peering connections exist.
+
 - `merge-central-config` - Include this flag in a request for `connect-proxy` kind or `*-gateway` kind
   services to return a fully resolved service definition that includes merged values from the
   [proxy-defaults/global](/consul/docs/connect/config-entries/proxy-defaults) and 


Reviews:
user: login: sreeram77
body: - test cases are missing for the new filter and needs to be added.
- docs are required to be updated with the new query param [here](https://github.com/hashicorp/consul/blob/main/website/content/api-docs/catalog.mdx)
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T06:05:36Z
user: login: sreeram77
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T06:42:02Z
user: login: jorgemarey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T09:47:22Z
user: login: sreeram77
body: LGTM! Thank you for your contribution.
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T07:55:18Z
user: login: boruszak
body: I left a suggestion for the docs portion ti implement. Otherwise LGTM on behalf of consul-docs.
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T21:21:08Z
user: login: jorgemarey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T07:32:41Z
user: login: sreeram77
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T09:02:03Z
user: login: gnrlprsn
state: APPROVED
author_association: NONE
submitted_at: 2025-05-24T16:32:24Z

Review comments:
diff_hunk: @@ -354,6 +354,12 @@ func (s *HTTPHandlers) catalogServiceNodes(resp http.ResponseWriter, req *http.R
 		return nil, nil
 	}
 
+	s.parsePeerName(req, &args)
+	s.parseSamenessGroup(req, &args)
path: agent/catalog_endpoint.go
user: login: sreeram77
body: SamenessGroup doesn't seem to have any relevance to this handler.
created_at: 2025-04-11T05:59:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,4 @@
+```release-note:bug
path: .changelog/22189.txt
user: login: sreeram77
body: In my opinion, this should be tagged as an `improvement` instead of a `bug` since this filter was non-existent in the catalog API and you are adding this as an enhancement.
created_at: 2025-04-11T06:02:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,4 @@
+```release-note:bug
+api: Correctly use peer query param on catalog service API
path: .changelog/22189.txt
user: login: sreeram77
body: The tag should be http instead of api [ref](https://github.com/hashicorp/consul/blob/main/docs/contributing/add-a-changelog-entry.md?plain=1#L35).
created_at: 2025-04-11T06:42:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -354,6 +354,12 @@ func (s *HTTPHandlers) catalogServiceNodes(resp http.ResponseWriter, req *http.R
 		return nil, nil
 	}
 
+	s.parsePeerName(req, &args)
+	s.parseSamenessGroup(req, &args)
path: agent/catalog_endpoint.go
user: login: jorgemarey
body: I add it because I thought it was the same as for the [heatlh endpoint](https://github.com/hashicorp/consul/blob/616de6455b2861a731a5fa52d0af0848f8bbc00b/agent/health_endpoint.go#L191).
created_at: 2025-04-11T09:47:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -551,6 +551,8 @@ The table below shows this endpoint's support for
 - `filter` `(string: "")` - Specifies the expression used to filter the
   queries results prior to returning the data.
 
+- `peer` `(string: "")` - Specifies the imported service's peer. Applies only to imported services.
path: website/content/api-docs/catalog.mdx
user: login: boruszak
body: ```suggestion
- `peer` `(string: "")` - Specifies the name of the peer that exported the service. Does not apply when no cluster peering connections exist.
```
We use the "exported service" configuration entry, so I'd suggest avoiding the inverse term "imported." 
created_at: 2025-04-15T21:20:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -551,6 +551,8 @@ The table below shows this endpoint's support for
 - `filter` `(string: "")` - Specifies the expression used to filter the
   queries results prior to returning the data.
 
+- `peer` `(string: "")` - Specifies the imported service's peer. Applies only to imported services.
path: website/content/api-docs/catalog.mdx
user: login: jorgemarey
body: Hi @boruszak I copied the description from [here](https://github.com/hashicorp/consul/blob/6cdaef235356f6ec61fdd690f55eaf4bb844c67b/website/content/api-docs/health.mdx?plain=1#L264). Should I change that too?
created_at: 2025-04-16T07:32:40Z
author_association: CONTRIBUTOR

PR comments:
user: login: jorgemarey
created_at: 2025-04-08T16:07:52Z
body: @jkirschner-hashicorp sorry to ping you directly, can someone take a look at this? It should be pretty straightforward, and it's being a problem for us.
author_association: CONTRIBUTOR
user: login: jorgemarey
created_at: 2025-04-11T09:45:43Z
body: Hi @sreeram77, thank you for taking the time and review this. I'll made the suggested changes.
author_association: CONTRIBUTOR
user: login: nitin-sachdev-29
created_at: 2025-04-16T07:31:57Z
body: @sreeram77 and @boruszak can you please review and approve.
author_association: CONTRIBUTOR
user: login: hc-github-team-consul-core
created_at: 2025-04-17T09:15:59Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-18T09:16:12Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: jorgemarey
created_at: 2025-04-18T21:25:46Z
body: @nitin-sachdev-29 should I do something about this last comments for backport? I see that a PR is already open for backport to 1.20 in [here](https://github.com/hashicorp/consul/pull/22261)
author_association: CONTRIBUTOR
user: login: hc-github-team-consul-core
created_at: 2025-04-19T09:15:00Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-20T09:15:08Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-21T09:16:51Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-22T09:17:05Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-23T07:22:46Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-23T09:17:37Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-24T09:17:14Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-25T09:16:49Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-26T09:15:21Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-27T09:15:20Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-28T09:57:09Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-04-30T09:17:13Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-01T09:16:41Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-02T09:16:56Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-03T09:15:36Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-04T09:15:37Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-05T09:17:24Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-06T09:17:25Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-07T09:17:49Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-08T09:17:25Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-09T09:17:15Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-10T09:15:29Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-11T09:15:55Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR
user: login: hc-github-team-consul-core
created_at: 2025-05-12T09:17:53Z
body: :mega: Hi @jorgemarey! a backport is missing for this PR [22189] for versions [1.20] please perform the backport manually and add the following snippet to your backport PR description:
```
<details>
	<summary> Overview of commits </summary>
		- <<backport commit 1>>
		- <<backport commit 2>>
		...
</details>
```
author_association: COLLABORATOR