Repository: linkerd/linkerd2
Pull request #13584 (2025-01-22 02:18:04)

fix(policy): Update outbound policy routes even when parent ref has no port
The `parent_ref` of an xRoute resource can optionally specify a port.  If no port is specified, the route applies to all ports.  These routes with `parent_ref` which do not specify a port are stored differently than routes which do, since these routes need to be applied for to all watches on any port on the parent.  When services are updated/created, we perform a reindex to ensure that all routes have the correct information about their backends.  However, routes which are stored in the separate way were not being updated in this case.  This means that routes with a `parent_ref` with no port can, depending on the sequence of operations, have stale information about their backend services.

We update these routes during the reindex operation to ensure they have up to date information about their backends and add a test for this behavior.

<!--  Thanks for sending a pull request!

If you already have a well-structured git commit message, chances are GitHub
set the title and description of this PR to the git commit message subject and
body, respectively. If so, you may delete these instructions and submit your PR.

If this is your first time, please read our contributor guide:
https://github.com/linkerd/linkerd2/blob/main/CONTRIBUTING.md

The title and description of your Pull Request should match the git commit
subject and body, respectively. Git commit messages are structured as follows:

```
Subject

Problem

Solution

Validation

Fixes #[GitHub issue ID]

DCO Sign off
```

Example git commit message:

```
Introduce Pull Request Template

GitHub's community guidelines recommend a pull request template, the repo was
lacking one.

Introduce a `PULL_REQUEST_TEMPLATE.md` file.

Once merged, the
[Community profile checklist](https://github.com/linkerd/linkerd2/community)
should indicate the repo now provides a pull request template.

Fixes #3321

Signed-off-by: Jane Smith <jane.smith@example.com>
```

Note the git commit message subject becomes the pull request title.

For more details around git commits, see the section on Committing in our
contributor guide:
https://github.com/linkerd/linkerd2/blob/main/CONTRIBUTING.md#committing
-->



Patch:
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index 055096d68..6bc1608ee 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -19,7 +19,7 @@ jobs:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
       - run: go install gotest.tools/gotestsum@v0.4.2
       - run: gotestsum -- -cover -coverprofile=coverage.out -v -mod=readonly ./...
-      - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303
+      - uses: codecov/codecov-action@5a605bd92782ce0810fa3b8acc235c921b497052
         with:
           files: ./coverage.out
           flags: unittests,golang
@@ -41,7 +41,7 @@ jobs:
           export NODE_ENV=test
           bin/web --frozen-lockfile
           bin/web test --reporters="jest-progress-bar-reporter" --reporters="./gh_ann_reporter.js" --coverage
-      - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303
+      - uses: codecov/codecov-action@5a605bd92782ce0810fa3b8acc235c921b497052
         with:
           directory: ./web/app/coverage
           flags: unittests,javascript
@@ -58,6 +58,6 @@ jobs:
       - shell: bash
         run: mkdir -p target && cd target && bin/scurl -v https://github.com/xd009642/tarpaulin/releases/download/0.27.3/cargo-tarpaulin-x86_64-unknown-linux-musl.tar.gz | tar zxvf - && chmod 755 cargo-tarpaulin
       - run: target/cargo-tarpaulin tarpaulin --workspace --out Xml
-      - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303
+      - uses: codecov/codecov-action@5a605bd92782ce0810fa3b8acc235c921b497052
         with:
           flags: unittests,rust
diff --git a/.proxy-version b/.proxy-version
index e1a7ad8a9..49d502f4d 100644
--- a/.proxy-version
+++ b/.proxy-version
@@ -1,1 +1,1 @@
-v2.271.0
+v2.276.0
diff --git a/controller/k8s/api.go b/controller/k8s/api.go
index e3e90fb02..73056e04b 100644
--- a/controller/k8s/api.go
+++ b/controller/k8s/api.go
@@ -12,6 +12,7 @@ import (
 	l5dcrdclient "github.com/linkerd/linkerd2/controller/gen/client/clientset/versioned"
 	l5dcrdinformer "github.com/linkerd/linkerd2/controller/gen/client/informers/externalversions"
 	ewinformers "github.com/linkerd/linkerd2/controller/gen/client/informers/externalversions/externalworkload/v1beta1"
+	linkinformers "github.com/linkerd/linkerd2/controller/gen/client/informers/externalversions/link/v1alpha2"
 	srvinformers "github.com/linkerd/linkerd2/controller/gen/client/informers/externalversions/server/v1beta3"
 	spinformers "github.com/linkerd/linkerd2/controller/gen/client/informers/externalversions/serviceprofile/v1alpha2"
 	"github.com/linkerd/linkerd2/pkg/k8s"
@@ -52,6 +53,7 @@ type API struct {
 	es       discoveryinformers.EndpointSliceInformer
 	ew       ewinformers.ExternalWorkloadInformer
 	job      batchv1informers.JobInformer
+	link     linkinformers.LinkInformer
 	mwc      arinformers.MutatingWebhookConfigurationInformer
 	ns       coreinformers.NamespaceInformer
 	pod      coreinformers.PodInformer
@@ -248,6 +250,13 @@ func newAPI(
 			api.job = sharedInformers.Batch().V1().Jobs()
 			api.syncChecks = append(api.syncChecks, api.job.Informer().HasSynced)
 			api.promGauges.addInformerSize(k8s.Job, informerLabels, api.job.Informer())
+		case Link:
+			if l5dCrdSharedInformers == nil {
+				panic("Linkerd CRD shared informer not configured")
+			}
+			api.link = l5dCrdSharedInformers.Link().V1alpha2().Links()
+			api.syncChecks = append(api.syncChecks, api.link.Informer().HasSynced)
+			api.promGauges.addInformerSize(k8s.Link, informerLabels, api.link.Informer())
 		case MWC:
 			api.mwc = sharedInformers.Admissionregistration().V1().MutatingWebhookConfigurations()
 			api.syncChecks = append(api.syncChecks, api.mwc.Informer().HasSynced)
diff --git a/controller/k8s/api_resource.go b/controller/k8s/api_resource.go
index ee4ef760a..c3cb4b1d6 100644
--- a/controller/k8s/api_resource.go
+++ b/controller/k8s/api_resource.go
@@ -32,6 +32,7 @@ const (
 	ES // EndpointSlice resource
 	ExtWorkload
 	Job
+	Link
 	MWC
 	NS
 	Pod
diff --git a/multicluster/charts/linkerd-multicluster/templates/link-crd.yaml b/multicluster/charts/linkerd-multicluster/templates/link-crd.yaml
index e2b8a0c7a..d24eb02d1 100644
--- a/multicluster/charts/linkerd-multicluster/templates/link-crd.yaml
+++ b/multicluster/charts/linkerd-multicluster/templates/link-crd.yaml
@@ -158,6 +158,7 @@ spec:
                     type: string
                   period:
                     description: Interval in between probe requests
+                    format: duration
                     type: string
                   port:
                     description: Port of remote gateway health endpoint
diff --git a/multicluster/cmd/link.go b/multicluster/cmd/link.go
index 045d2d507..117af4cb9 100644
--- a/multicluster/cmd/link.go
+++ b/multicluster/cmd/link.go
@@ -7,7 +7,9 @@ import (
 	"fmt"
 	"os"
 	"path"
+	"strconv"
 	"strings"
+	"time"
 
 	"github.com/linkerd/linkerd2/controller/gen/apis/link/v1alpha2"
 	"github.com/linkerd/linkerd2/multicluster/static"
@@ -599,10 +601,21 @@ func extractProbeSpec(gateway *corev1.Service) (v1alpha2.ProbeSpec, error) {
 		return v1alpha2.ProbeSpec{}, err
 	}
 
+	// the `mirror.linkerd.io/probe-period` annotation is initialized with a
+	// default value of "3", but we require a duration-formatted string. So we
+	// perform the conversion, if required.
+	period := gateway.Annotations[k8s.GatewayProbePeriod]
+	if secs, err := strconv.ParseInt(period, 10, 64); err == nil {
+		dur := time.Duration(secs) * time.Second
+		period = dur.String()
+	} else if _, err := time.ParseDuration(period); err != nil {
+		return v1alpha2.ProbeSpec{}, fmt.Errorf("could not parse probe period: %w", err)
+	}
+
 	return v1alpha2.ProbeSpec{
 		Path:   path,
 		Port:   fmt.Sprintf("%d", port),
-		Period: gateway.Annotations[k8s.GatewayProbePeriod],
+		Period: period,
 	}, nil
 }
 
diff --git a/multicluster/cmd/service-mirror/main.go b/multicluster/cmd/service-mirror/main.go
index 39a094d2d..0cc976e7e 100644
--- a/multicluster/cmd/service-mirror/main.go
+++ b/multicluster/cmd/service-mirror/main.go
@@ -21,7 +21,6 @@ import (
 	log "github.com/sirupsen/logrus"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
-	"k8s.io/client-go/tools/cache"
 	"k8s.io/client-go/tools/clientcmd"
 	"k8s.io/client-go/tools/leaderelection"
 	"k8s.io/client-go/tools/leaderelection/resourcelock"
@@ -149,58 +148,7 @@ func Main(args []string) {
 			log.Infof("Starting Link informer")
 			informerFactory.Start(ctx.Done())
 
-			_, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
-				AddFunc: func(obj interface{}) {
-					link, ok := obj.(*v1alpha2.Link)
-					if !ok {
-						log.Errorf("object is not a Link: %+v", obj)
-						return
-					}
-					if link.GetName() == linkName {
-						select {
-						case results <- link:
-						default:
-							log.Errorf("Link update dropped (queue full): %s", link.GetName())
-						}
-					}
-				},
-				UpdateFunc: func(_, obj interface{}) {
-					link, ok := obj.(*v1alpha2.Link)
-					if !ok {
-						log.Errorf("object is not a Link: %+v", obj)
-						return
-					}
-					if link.GetName() == linkName {
-						select {
-						case results <- link:
-						default:
-							log.Errorf("Link update dropped (queue full): %s", link.GetName())
-						}
-					}
-				},
-				DeleteFunc: func(obj interface{}) {
-					link, ok := obj.(*v1alpha2.Link)
-					if !ok {
-						tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
-						if !ok {
-							log.Errorf("couldn't get object from DeletedFinalStateUnknown %#v", obj)
-							return
-						}
-						link, ok = tombstone.Obj.(*v1alpha2.Link)
-						if !ok {
-							log.Errorf("DeletedFinalStateUnknown contained object that is not a Link %#v", obj)
-							return
-						}
-					}
-					if link.GetName() == linkName {
-						select {
-						case results <- nil: // nil indicates the link was deleted
-						default:
-							log.Errorf("Link delete dropped (queue full): %s", link.GetName())
-						}
-					}
-				},
-			})
+			_, err := informer.AddEventHandler(servicemirror.GetLinkHandlers(results, linkName))
 			if err != nil {
 				log.Fatalf("Failed to add event handler to Link informer: %s", err)
 			}
diff --git a/multicluster/service-mirror/cluster_watcher.go b/multicluster/service-mirror/cluster_watcher.go
index 29a6d4d23..99251e761 100644
--- a/multicluster/service-mirror/cluster_watcher.go
+++ b/multicluster/service-mirror/cluster_watcher.go
@@ -289,6 +289,16 @@ func (rcsw *RemoteClusterServiceWatcher) getMirrorServiceLabels(remoteService *c
 	return labels
 }
 
+// Provides labels for mirror endpoint. Copies all labels from the exported
+// service to the mirror endpoint (except labels with the "SvcMirrorPrefix").
+func (rcsw *RemoteClusterServiceWatcher) getMirrorEndpointLabels(exportedService *corev1.Service) map[string]string {
+	labels := rcsw.getCommonServiceLabels(exportedService)
+
+	labels[consts.RemoteClusterNameLabel] = rcsw.link.Spec.TargetClusterName
+
+	return labels
+}
+
 // Provides labels for federated services. Copies all labels from the remote
 // service to the federated service (except labels with the "SvcMirrorPrefix").
 func (rcsw *RemoteClusterServiceWatcher) getFederatedServiceLabels(remoteService *corev1.Service) map[string]string {
@@ -1000,10 +1010,7 @@ func (rcsw *RemoteClusterServiceWatcher) createGatewayEndpoints(ctx context.Cont
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      localServiceName,
 			Namespace: exportedService.Namespace,
-			Labels: map[string]string{
-				consts.MirroredResourceLabel:  "true",
-				consts.RemoteClusterNameLabel: rcsw.link.Spec.TargetClusterName,
-			},
+			Labels:    rcsw.getMirrorEndpointLabels(exportedService),
 			Annotations: map[string]string{
 				consts.RemoteServiceFqName: fmt.Sprintf("%s.%s.svc.%s", exportedService.Name, exportedService.Namespace, rcsw.link.Spec.TargetClusterDomain),
 			},
diff --git a/multicluster/service-mirror/cluster_watcher_headless.go b/multicluster/service-mirror/cluster_watcher_headless.go
index cfbc80cbc..3722ea7a6 100644
--- a/multicluster/service-mirror/cluster_watcher_headless.go
+++ b/multicluster/service-mirror/cluster_watcher_headless.go
@@ -290,10 +290,7 @@ func (rcsw *RemoteClusterServiceWatcher) createHeadlessMirrorEndpoints(ctx conte
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      headlessMirrorServiceName,
 			Namespace: exportedService.Namespace,
-			Labels: map[string]string{
-				consts.MirroredResourceLabel:  "true",
-				consts.RemoteClusterNameLabel: rcsw.link.Spec.TargetClusterName,
-			},
+			Labels:    rcsw.getMirrorEndpointLabels(exportedService),
 			Annotations: map[string]string{
 				consts.RemoteServiceFqName: fmt.Sprintf("%s.%s.svc.%s", exportedService.Name, exportedService.Namespace, rcsw.link.Spec.TargetClusterDomain),
 			},
diff --git a/multicluster/service-mirror/link_handlers.go b/multicluster/service-mirror/link_handlers.go
new file mode 100644
index 000000000..512379172
--- /dev/null
+++ b/multicluster/service-mirror/link_handlers.go
@@ -0,0 +1,73 @@
+package servicemirror
+
+import (
+	"reflect"
+
+	"github.com/linkerd/linkerd2/controller/gen/apis/link/v1alpha2"
+	log "github.com/sirupsen/logrus"
+	"k8s.io/client-go/tools/cache"
+)
+
+func GetLinkHandlers(results chan<- *v1alpha2.Link, linkName string) cache.ResourceEventHandlerFuncs {
+	return cache.ResourceEventHandlerFuncs{
+		AddFunc: func(obj interface{}) {
+			link, ok := obj.(*v1alpha2.Link)
+			if !ok {
+				log.Errorf("object is not a Link: %+v", obj)
+				return
+			}
+			if link.GetName() == linkName {
+				select {
+				case results <- link:
+				default:
+					log.Errorf("Link update dropped (queue full): %s", link.GetName())
+				}
+			}
+		},
+		UpdateFunc: func(oldObj, currentObj interface{}) {
+			oldLink, ok := oldObj.(*v1alpha2.Link)
+			if !ok {
+				log.Errorf("object is not a Link: %+v", oldObj)
+				return
+			}
+			currentLink, ok := currentObj.(*v1alpha2.Link)
+			if !ok {
+				log.Errorf("object is not a Link: %+v", currentObj)
+				return
+			}
+			if reflect.DeepEqual(oldLink.Spec, currentLink.Spec) {
+				log.Debugf("Link update ignored (only status changed): %s", currentLink.GetName())
+				return
+			}
+			if currentLink.GetName() == linkName {
+				select {
+				case results <- currentLink:
+				default:
+					log.Errorf("Link update dropped (queue full): %s", currentLink.GetName())
+				}
+			}
+		},
+		DeleteFunc: func(obj interface{}) {
+			link, ok := obj.(*v1alpha2.Link)
+			if !ok {
+				tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
+				if !ok {
+					log.Errorf("couldn't get object from DeletedFinalStateUnknown %#v", obj)
+					return
+				}
+				link, ok = tombstone.Obj.(*v1alpha2.Link)
+				if !ok {
+					log.Errorf("DeletedFinalStateUnknown contained object that is not a Link %#v", obj)
+					return
+				}
+			}
+			if link.GetName() == linkName {
+				select {
+				case results <- nil: // nil indicates the link was deleted
+				default:
+					log.Errorf("Link delete dropped (queue full): %s", link.GetName())
+				}
+			}
+		},
+	}
+}
diff --git a/multicluster/service-mirror/probe_worker.go b/multicluster/service-mirror/probe_worker.go
index 42e9989f1..09f10940a 100644
--- a/multicluster/service-mirror/probe_worker.go
+++ b/multicluster/service-mirror/probe_worker.go
@@ -70,12 +70,11 @@ func (pw *ProbeWorker) run() {
 		pw.log.Error("Probe spec is nil")
 		return
 	}
-	probeTickerPeriodSeconds, err := strconv.ParseInt(pw.probeSpec.Period, 10, 64)
+	probeTickerPeriod, err := time.ParseDuration(pw.probeSpec.Period)
 	if err != nil {
 		pw.log.Errorf("could not parse probe period: %s", err)
 		return
 	}
-	probeTickerPeriod := time.Duration(probeTickerPeriodSeconds) * time.Second
 	maxJitter := probeTickerPeriod / 10 // max jitter is 10% of period
 	probeTicker := NewTicker(probeTickerPeriod, maxJitter)
 	defer probeTicker.Stop()
diff --git a/pkg/k8s/k8s.go b/pkg/k8s/k8s.go
index 8f4dafb68..df713c321 100644
--- a/pkg/k8s/k8s.go
+++ b/pkg/k8s/k8s.go
@@ -12,7 +12,6 @@ import (
 // These constants are string representations of Kubernetes resource types.
 const (
 	All                   = "all"
-	Authority             = "authority"
 	ConfigMap             = "configmap"
 	CronJob               = "cronjob"
 	DaemonSet             = "daemonset"
@@ -21,6 +20,7 @@ const (
 	EndpointSlices        = "endpointslices"
 	ExtWorkload           = "externalworkload"
 	Job                   = "job"
+	Link                  = "link"
 	MeshTLSAuthentication = "meshtlsauthentication"
 	MutatingWebhookConfig = "mutatingwebhookconfig"
 	Namespace             = "namespace"
@@ -72,7 +72,6 @@ type resourceName struct {
 
 // AllResources is a sorted list of all resources defined as constants above.
 var AllResources = []string{
-	Authority,
 	AuthorizationPolicy,
 	CronJob,
 	DaemonSet,
@@ -99,7 +98,6 @@ var StatAllResourceTypes = []string{
 	ReplicationController,
 	Pod,
 	Service,
-	Authority,
 	CronJob,
 	ReplicaSet,
 }
@@ -114,13 +112,11 @@ var CompletionResourceTypes = []string{
 	ReplicationController,
 	Pod,
 	Service,
-	Authority,
 	CronJob,
 	ReplicaSet,
 }
 
 var resourceNames = []resourceName{
-	{"au", "authority", "authorities"},
 	{"cj", "cronjob", "cronjobs"},
 	{"ds", "daemonset", "daemonsets"},
 	{"deploy", "deployment", "deployments"},
@@ -189,8 +185,6 @@ func PluralResourceNameFromFriendlyName(friendlyName string) (string, error) {
 // Essentially the reverse of CanonicalResourceNameFromFriendlyName
 func ShortNameFromCanonicalResourceName(canonicalName string) string {
 	switch canonicalName {
-	case Authority:
-		return "au"
 	case CronJob:
 		return "cj"
 	case DaemonSet:
diff --git a/policy-controller/k8s/index/src/outbound/index.rs b/policy-controller/k8s/index/src/outbound/index.rs
index 910128e63..eb1281be5 100644
--- a/policy-controller/k8s/index/src/outbound/index.rs
+++ b/policy-controller/k8s/index/src/outbound/index.rs
@@ -1103,6 +1103,35 @@ impl Namespace {
                 watch.send_if_modified();
             }
         }
+
+        let http_backends = self
+            .service_http_routes
+            .values_mut()
+            .flat_map(|routes| routes.values_mut())
+            .flat_map(|route| route.rules.iter_mut())
+            .flat_map(|rule| rule.backends.iter_mut());
+        let grpc_backends = self
+            .service_grpc_routes
+            .values_mut()
+            .flat_map(|routes| routes.values_mut())
+            .flat_map(|route| route.rules.iter_mut())
+            .flat_map(|rule| rule.backends.iter_mut());
+        let tls_backends = self
+            .service_tls_routes
+            .values_mut()
+            .flat_map(|routes| routes.values_mut())
+            .flat_map(|route| route.rule.backends.iter_mut());
+        let tcp_backends = self
+            .service_tcp_routes
+            .values_mut()
+            .flat_map(|routes| routes.values_mut())
+            .flat_map(|route| route.rule.backends.iter_mut());
+
+        http_backends
+            .chain(grpc_backends)
+            .chain(tls_backends)
+            .chain(tcp_backends)
+            .for_each(update_backend);
     }
 
     fn reinitialize_egress_watches(&mut self) {
diff --git a/viz/cmd/routes.go b/viz/cmd/routes.go
index eab03eca9..75ee0ea79 100644
--- a/viz/cmd/routes.go
+++ b/viz/cmd/routes.go
@@ -14,7 +14,6 @@ import (
 
 	pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
 	"github.com/linkerd/linkerd2/pkg/healthcheck"
-	"github.com/linkerd/linkerd2/pkg/k8s"
 	pb "github.com/linkerd/linkerd2/viz/metrics-api/gen/viz"
 	"github.com/linkerd/linkerd2/viz/metrics-api/util"
 	"github.com/linkerd/linkerd2/viz/pkg/api"
@@ -379,7 +378,7 @@ func buildTopRoutesRequest(resource string, options *routesOptions) (*pb.TopRout
 		LabelSelector: options.labelSelector,
 	}
 
-	options.dstIsService = target.GetType() != k8s.Authority
+	options.dstIsService = true
 
 	if options.toResource != "" {
 		if options.toNamespace == "" {
@@ -390,7 +389,7 @@ func buildTopRoutesRequest(resource string, options *routesOptions) (*pb.TopRout
 			return nil, err
 		}
 
-		options.dstIsService = toRes.GetType() != k8s.Authority
+		options.dstIsService = true
 
 		requestParams.ToName = toRes.Name
 		requestParams.ToNamespace = toRes.Namespace
diff --git a/viz/cmd/stat.go b/viz/cmd/stat.go
index 88d931010..a2abb0f4e 100644
--- a/viz/cmd/stat.go
+++ b/viz/cmd/stat.go
@@ -372,7 +372,7 @@ func statHasRequestData(stat *pb.BasicStats) bool {
 }
 
 func isPodOwnerResource(typ string) bool {
-	return typ != k8s.Authority && typ != k8s.Service && typ != k8s.Server && typ != k8s.ServerAuthorization && typ != k8s.AuthorizationPolicy && typ != k8s.HTTPRoute
+	return typ != k8s.Service && typ != k8s.Server && typ != k8s.ServerAuthorization && typ != k8s.AuthorizationPolicy && typ != k8s.HTTPRoute
 }
 
 func writeStatsToBuffer(rows []*pb.StatTable_PodGroup_Row, w *tabwriter.Writer, options *statOptions) {
@@ -433,7 +433,7 @@ func writeStatsToBuffer(rows []*pb.StatTable_PodGroup_Row, w *tabwriter.Writer,
 		statTables[resourceKey][key] = &row{}
 		if resourceKey != k8s.Server && resourceKey != k8s.ServerAuthorization {
 			meshedCount := fmt.Sprintf("%d/%d", r.MeshedPodCount, r.RunningPodCount)
-			if resourceKey == k8s.Authority || resourceKey == k8s.Service {
+			if resourceKey == k8s.Service {
 				meshedCount = "-"
 			}
 			statTables[resourceKey][key] = &row{
@@ -503,7 +503,7 @@ func showTCPBytes(options *statOptions, resourceType string) bool {
 }
 
 func showTCPConns(resourceType string) bool {
-	return resourceType != k8s.Authority && resourceType != k8s.ServerAuthorization && resourceType != k8s.AuthorizationPolicy && resourceType != k8s.HTTPRoute
+	return resourceType != k8s.ServerAuthorization && resourceType != k8s.AuthorizationPolicy && resourceType != k8s.HTTPRoute
 }
 
 func printSingleStatTable(stats map[string]*row, resourceTypeLabel, resourceType string, w *tabwriter.Writer, maxNameLength, maxNamespaceLength, maxLeafLength, maxApexLength, maxDstLength, maxWeightLength int, options *statOptions) {
diff --git a/viz/metrics-api/stat_summary.go b/viz/metrics-api/stat_summary.go
index f434afa92..bf7c06e01 100644
--- a/viz/metrics-api/stat_summary.go
+++ b/viz/metrics-api/stat_summary.go
@@ -125,9 +125,7 @@ func (s *grpcServer) StatSummary(ctx context.Context, req *pb.StatSummaryRequest
 		statReq.Selector.Resource.Type = resource
 
 		go func() {
-			if prometheus.IsNonK8sResourceQuery(statReq.GetSelector().GetResource().GetType()) {
-				resultChan <- s.nonK8sResourceQuery(ctx, statReq)
-			} else if statReq.GetSelector().GetResource().GetType() == k8s.Service {
+			if statReq.GetSelector().GetResource().GetType() == k8s.Service {
 				resultChan <- s.serviceResourceQuery(ctx, statReq)
 			} else if isPolicyResource(statReq.GetSelector().GetResource()) {
 				resultChan <- s.policyResourceQuery(ctx, statReq)
@@ -362,42 +360,6 @@ func sortTrafficSplitRows(rows []*pb.StatTable_PodGroup_Row) []*pb.StatTable_Pod
 	return rows
 }
 
-func (s *grpcServer) nonK8sResourceQuery(ctx context.Context, req *pb.StatSummaryRequest) resourceResult {
-	var requestMetrics map[rKey]*pb.BasicStats
-	if !req.SkipStats {
-		var err error
-		requestMetrics, _, err = s.getStatMetrics(ctx, req, req.TimeWindow)
-		if err != nil {
-			return resourceResult{res: nil, err: err}
-		}
-	}
-	rows := make([]*pb.StatTable_PodGroup_Row, 0)
-
-	for rkey, metrics := range requestMetrics {
-		rkey.Type = req.GetSelector().GetResource().GetType()
-
-		row := pb.StatTable_PodGroup_Row{
-			Resource: &pb.Resource{
-				Type:      rkey.Type,
-				Namespace: rkey.Namespace,
-				Name:      rkey.Name,
-			},
-			TimeWindow: req.TimeWindow,
-			Stats:      metrics,
-		}
-		rows = append(rows, &row)
-	}
-
-	rsp := pb.StatTable{
-		Table: &pb.StatTable_PodGroup_{
-			PodGroup: &pb.StatTable_PodGroup{
-				Rows: rows,
-			},
-		},
-	}
-	return resourceResult{res: &rsp, err: nil}
-}
-
 // get the list of objects for which we want to return results
 func getResultKeys(
 	req *pb.StatSummaryRequest,
diff --git a/viz/metrics-api/top_routes.go b/viz/metrics-api/top_routes.go
index d08753e06..b5572280e 100644
--- a/viz/metrics-api/top_routes.go
+++ b/viz/metrics-api/top_routes.go
@@ -2,7 +2,6 @@ package api
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"sort"
 	"strings"
@@ -58,11 +57,6 @@ func (s *grpcServer) TopRoutes(ctx context.Context, req *pb.TopRoutesRequest) (*
 	if err != nil {
 		return nil, err
 	}
-	if targetResource.GetType() == k8s.Authority {
-		// Authority cannot be the target because authorities don't have namespaces,
-		// therefore there is no namespace in which to look for a service profile.
-		return topRoutesError(req, "Authority cannot be the target of a routes query; try using an authority in the --to flag instead"), nil
-	}
 
 	err = s.validateTimeWindow(ctx, req.TimeWindow)
 	if err != nil {
@@ -139,31 +133,22 @@ func (s *grpcServer) topRoutesFor(ctx context.Context, req *pb.TopRoutesRequest,
 
 	profiles := make(map[string]*sp.ServiceProfile)
 
-	if requestedResource.GetType() == k8s.Authority {
-		// Authorities may not be a source, so we know this is a ToResource.
-		profiles, err = s.getProfilesForAuthority(requestedResource.GetName(), clientNs, labelSelector)
-		if err != nil {
-			return nil, err
-		}
-	} else {
-		// Non-authority resource.
-		// Lookup individual resource objects.
-		objects, err := s.k8sAPI.GetObjects(requestedResource.Namespace, requestedResource.Type, requestedResource.Name, labelSelector)
+	// Lookup individual resource objects.
+	objects, err := s.k8sAPI.GetObjects(requestedResource.Namespace, requestedResource.Type, requestedResource.Name, labelSelector)
+	if err != nil {
+		return nil, err
+	}
+	// Find service profiles for all services in all objects in the resource.
+	for _, obj := range objects {
+		// Lookup services for each object.
+		services, err := s.k8sAPI.GetServicesFor(obj, false)
 		if err != nil {
 			return nil, err
 		}
-		// Find service profiles for all services in all objects in the resource.
-		for _, obj := range objects {
-			// Lookup services for each object.
-			services, err := s.k8sAPI.GetServicesFor(obj, false)
-			if err != nil {
-				return nil, err
-			}
 
-			for _, svc := range services {
-				p := s.k8sAPI.GetServiceProfileFor(svc, clientNs, s.clusterDomain)
-				profiles[svc.GetName()] = p
-			}
+		for _, svc := range services {
+			p := s.k8sAPI.GetServiceProfileFor(svc, clientNs, s.clusterDomain)
+			profiles[svc.GetName()] = p
 		}
 	}
 
@@ -197,43 +182,13 @@ func validateRequest(req *pb.TopRoutesRequest) *pb.TopRoutesResponse {
 	if req.GetNone() == nil {
 		// This is an outbound (--to) request.
 		targetType := req.GetSelector().GetResource().GetType()
-		if targetType == k8s.Service || targetType == k8s.Authority {
+		if targetType == k8s.Service {
 			return topRoutesError(req, fmt.Sprintf("The %s resource type is not supported with 'to' queries", targetType))
 		}
 	}
 	return nil
 }
 
-func (s *grpcServer) getProfilesForAuthority(authority string, clientNs string, labelSelector labels.Selector) (map[string]*sp.ServiceProfile, error) {
-	if authority == "" {
-		// All authorities
-		ps, err := s.k8sAPI.SP().Lister().ServiceProfiles(clientNs).List(labelSelector)
-		if err != nil {
-			return nil, err
-		}
-
-		if len(ps) == 0 {
-			return nil, errors.New("No ServiceProfiles found")
-		}
-
-		profiles := make(map[string]*sp.ServiceProfile)
-
-		for _, p := range ps {
-			profiles[p.Name] = p
-		}
-
-		return profiles, nil
-	}
-	// Specific authority
-	p, err := s.k8sAPI.SP().Lister().ServiceProfiles(clientNs).Get(authority)
-	if err != nil {
-		return nil, err
-	}
-	return map[string]*sp.ServiceProfile{
-		p.Name: p,
-	}, nil
-}
-
 func (s *grpcServer) getRouteMetrics(ctx context.Context, req *pb.TopRoutesRequest, profiles map[string]*sp.ServiceProfile, resource *pb.Resource) (indexedTable, error) {
 	timeWindow := req.TimeWindow
 
diff --git a/viz/metrics-api/util/api_utils.go b/viz/metrics-api/util/api_utils.go
index ddfccbe10..df64ee3b2 100644
--- a/viz/metrics-api/util/api_utils.go
+++ b/viz/metrics-api/util/api_utils.go
@@ -274,9 +274,7 @@ func validateFromResourceType(resourceType string) (string, error) {
 	if err != nil {
 		return "", err
 	}
-	if name == k8s.Authority {
-		return "", errors.New("cannot query traffic --from an authority")
-	}
+
 	return name, nil
 }
 
diff --git a/viz/pkg/prometheus/prometheus.go b/viz/pkg/prometheus/prometheus.go
index 6cbe13135..38051e924 100644
--- a/viz/pkg/prometheus/prometheus.go
+++ b/viz/pkg/prometheus/prometheus.go
@@ -63,10 +63,7 @@ func QueryLabels(resource *pb.Resource) model.LabelSet {
 // note that metricToKey assumes the label ordering (namespace, name)
 func DstGroupByLabelNames(resource *pb.Resource) model.LabelNames {
 	names := model.LabelNames{DstNamespaceLabel}
-
-	if IsNonK8sResourceQuery(resource.GetType()) {
-		names = append(names, ResourceType(resource))
-	} else if resource.Type != k8s.Namespace {
+	if resource.Type != k8s.Namespace {
 		names = append(names, "dst_"+ResourceType(resource))
 	}
 	return names
@@ -76,14 +73,11 @@ func DstGroupByLabelNames(resource *pb.Resource) model.LabelNames {
 func DstQueryLabels(resource *pb.Resource) model.LabelSet {
 	set := model.LabelSet{}
 	if resource.Name != "" {
-		if IsNonK8sResourceQuery(resource.GetType()) {
-			set[ResourceType(resource)] = model.LabelValue(resource.Name)
-		} else {
-			set["dst_"+ResourceType(resource)] = model.LabelValue(resource.Name)
-			if shouldAddNamespaceLabel(resource) {
-				set[DstNamespaceLabel] = model.LabelValue(resource.Namespace)
-			}
+		set["dst_"+ResourceType(resource)] = model.LabelValue(resource.Name)
+		if shouldAddNamespaceLabel(resource) {
+			set[DstNamespaceLabel] = model.LabelValue(resource.Namespace)
 		}
+
 	}
 
 	return set
@@ -98,7 +92,3 @@ func ResourceType(resource *pb.Resource) model.LabelName {
 func shouldAddNamespaceLabel(resource *pb.Resource) bool {
 	return resource.Type != k8s.Namespace && resource.Namespace != ""
 }
-
-func IsNonK8sResourceQuery(resourceType string) bool {
-	return resourceType == k8s.Authority
-}
diff --git a/viz/pkg/util/util.go b/viz/pkg/util/util.go
index c6679b767..590d5d939 100644
--- a/viz/pkg/util/util.go
+++ b/viz/pkg/util/util.go
@@ -18,7 +18,6 @@ import (
 // - target resource on an outbound 'to' query
 // - destination resource on an outbound 'from' query
 var ValidTargets = []string{
-	k8s.Authority,
 	k8s.CronJob,
 	k8s.DaemonSet,
 	k8s.Deployment,


Test patch:
diff --git a/controller/k8s/test_helper.go b/controller/k8s/test_helper.go
index b34da0c2f..7b2298689 100644
--- a/controller/k8s/test_helper.go
+++ b/controller/k8s/test_helper.go
@@ -57,6 +57,7 @@ func NewFakeClusterScopedAPI(clientSet kubernetes.Interface, l5dClientSet l5dcrd
 		DS,
 		Endpoint,
 		Job,
+		Link,
 		MWC,
 		NS,
 		Pod,
diff --git a/multicluster/cmd/testdata/install_default.golden b/multicluster/cmd/testdata/install_default.golden
index 32b4e1aea..ec7610c0a 100644
--- a/multicluster/cmd/testdata/install_default.golden
+++ b/multicluster/cmd/testdata/install_default.golden
@@ -396,6 +396,7 @@ spec:
                     type: string
                   period:
                     description: Interval in between probe requests
+                    format: duration
                     type: string
                   port:
                     description: Port of remote gateway health endpoint
diff --git a/multicluster/cmd/testdata/install_ha.golden b/multicluster/cmd/testdata/install_ha.golden
index 88488f787..cb2a4b747 100644
--- a/multicluster/cmd/testdata/install_ha.golden
+++ b/multicluster/cmd/testdata/install_ha.golden
@@ -468,6 +468,7 @@ spec:
                     type: string
                   period:
                     description: Interval in between probe requests
+                    format: duration
                     type: string
                   port:
                     description: Port of remote gateway health endpoint
diff --git a/multicluster/cmd/testdata/install_psp.golden b/multicluster/cmd/testdata/install_psp.golden
index 7a91e393f..0542a4033 100644
--- a/multicluster/cmd/testdata/install_psp.golden
+++ b/multicluster/cmd/testdata/install_psp.golden
@@ -430,6 +430,7 @@ spec:
                     type: string
                   period:
                     description: Interval in between probe requests
+                    format: duration
                     type: string
                   port:
                     description: Port of remote gateway health endpoint
diff --git a/multicluster/service-mirror/cluster_watcher_mirroring_test.go b/multicluster/service-mirror/cluster_watcher_mirroring_test.go
index 8d2af3074..90ab06471 100644
--- a/multicluster/service-mirror/cluster_watcher_mirroring_test.go
+++ b/multicluster/service-mirror/cluster_watcher_mirroring_test.go
@@ -26,7 +26,9 @@ type mirroringTestCase struct {
 }
 
 func (tc *mirroringTestCase) run(t *testing.T) {
+	t.Helper()
 	t.Run(tc.description, func(t *testing.T) {
+		t.Helper()
 
 		q := workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[any]())
 		localAPI, err := tc.environment.runEnvironment(q)
@@ -52,7 +54,7 @@ func (tc *mirroringTestCase) run(t *testing.T) {
 				}
 
 				if err := diffServices(expected, actual); err != nil {
-					t.Fatal(err)
+					t.Fatalf("service %s/%s: %v", expected.Namespace, expected.Name, err)
 				}
 			}
 		}
@@ -68,7 +70,7 @@ func (tc *mirroringTestCase) run(t *testing.T) {
 				}
 
 				if err := diffEndpoints(expected, actual); err != nil {
-					t.Fatal(err)
+					t.Fatalf("endpoint %s/%s: %v", expected.Namespace, expected.Name, err)
 				}
 			}
 		}
@@ -99,6 +101,7 @@ func TestRemoteServiceCreatedMirroring(t *testing.T) {
 					"service-one-remote",
 					"ns1",
 					"111",
+					map[string]string{"lk": "lv"},
 					[]corev1.ServicePort{
 						{
 							Name:     "port1",
@@ -113,7 +116,7 @@ func TestRemoteServiceCreatedMirroring(t *testing.T) {
 					}),
 			},
 			expectedLocalEndpoints: []*corev1.Endpoints{
-				endpoints("service-one-remote", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{
+				endpoints("service-one-remote", "ns1", map[string]string{"lk": "lv"}, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{
 					{
 						Name:     "port1",
 						Port:     888,
@@ -135,6 +138,7 @@ func TestRemoteServiceCreatedMirroring(t *testing.T) {
 					"service-one-remote",
 					"ns2",
 					"111",
+					map[string]string{"lk": "lv"},
 					[]corev1.ServicePort{
 						{
 							Name:     "port1",
@@ -152,6 +156,7 @@ func TestRemoteServiceCreatedMirroring(t *testing.T) {
 					"service-one-remote",
 					"ns2",
 					"112",
+					map[string]string{"lk": "lv"},
 					[]corev1.ServicePort{
 						{
 							Name:     "port1",
@@ -167,7 +172,7 @@ func TestRemoteServiceCreatedMirroring(t *testing.T) {
 				),
 			},
 			expectedLocalEndpoints: []*corev1.Endpoints{
-				headlessMirrorEndpoints("service-one-remote", "ns2", "gateway-identity", []corev1.EndpointPort{
+				headlessMirrorEndpoints("service-one-remote", "ns2", map[string]string{"lk": "lv"}, "gateway-identity", []corev1.EndpointPort{
 					{
 						Name:     "port1",
 						Port:     555,
@@ -182,6 +187,7 @@ func TestRemoteServiceCreatedMirroring(t *testing.T) {
 				endpointMirrorEndpoints(
 					"service-one-remote",
 					"ns2",
+					map[string]string{"lk": "lv"},
 					"pod-0",
 					"192.0.2.129",
 					"gateway-identity",
@@ -388,7 +394,7 @@ func TestLocalNamespaceCreatedAfterServiceExport(t *testing.T) {
 	remoteAPI, err := k8s.NewFakeAPI(
 		asYaml(gateway("existing-gateway", "existing-namespace", "222", "192.0.2.127", "mc-gateway", 888, "gateway-identity", defaultProbePort, defaultProbePath, defaultProbePeriod)),
 		asYaml(remoteService("service-one", "ns1", "111", map[string]string{consts.DefaultExportedServiceSelector: "true"}, []corev1.ServicePort{})),
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 	)
 	if err != nil {
 		t.Fatal(err)
@@ -480,7 +486,7 @@ func TestServiceCreatedGatewayAlive(t *testing.T) {
 	remoteAPI, err := k8s.NewFakeAPI(
 		asYaml(gateway("gateway", "gateway-ns", "1", "192.0.0.1", "gateway", 888, "gateway-identity", defaultProbePort, defaultProbePath, defaultProbePeriod)),
 		asYaml(remoteService("svc", "ns", "1", map[string]string{consts.DefaultExportedServiceSelector: "true"}, []corev1.ServicePort{})),
-		asYaml(endpoints("svc", "ns", "192.0.0.1", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("svc", "ns", nil, "192.0.0.1", "gateway-identity", []corev1.EndpointPort{})),
 	)
 	if err != nil {
 		t.Fatal(err)
@@ -631,7 +637,7 @@ func TestServiceCreatedGatewayDown(t *testing.T) {
 	remoteAPI, err := k8s.NewFakeAPI(
 		asYaml(gateway("gateway", "gateway-ns", "1", "192.0.0.1", "gateway", 888, "gateway-identity", defaultProbePort, defaultProbePath, defaultProbePeriod)),
 		asYaml(remoteService("svc", "ns", "1", map[string]string{consts.DefaultExportedServiceSelector: "true"}, []corev1.ServicePort{})),
-		asYaml(endpoints("svc", "ns", "192.0.0.1", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("svc", "ns", nil, "192.0.0.1", "gateway-identity", []corev1.EndpointPort{})),
 	)
 	if err != nil {
 		t.Fatal(err)
@@ -747,7 +753,7 @@ func TestRemoteServiceUpdatedMirroring(t *testing.T) {
 			description: "updates service ports on both service and endpoints",
 			environment: updateServiceWithChangedPorts,
 			expectedLocalServices: []*corev1.Service{
-				mirrorService("test-service-remote", "test-namespace", "currentServiceResVersion",
+				mirrorService("test-service-remote", "test-namespace", "currentServiceResVersion", nil,
 					[]corev1.ServicePort{
 						{
 							Name:     "port1",
@@ -763,7 +769,7 @@ func TestRemoteServiceUpdatedMirroring(t *testing.T) {
 			},
 
 			expectedLocalEndpoints: []*corev1.Endpoints{
-				endpoints("test-service-remote", "test-namespace", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{
+				endpoints("test-service-remote", "test-namespace", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{
 					{
 						Name:     "port1",
 						Port:     888,
@@ -847,7 +853,7 @@ func TestRemoteEndpointsUpdatedMirroring(t *testing.T) {
 			description: "updates headless mirror service with new remote Endpoints hosts",
 			environment: updateEndpointsWithChangedHosts,
 			expectedLocalServices: []*corev1.Service{
-				headlessMirrorService("service-two-remote", "eptest", "222", []corev1.ServicePort{
+				headlessMirrorService("service-two-remote", "eptest", "222", nil, []corev1.ServicePort{
 					{
 						Name:     "port1",
 						Protocol: "TCP",
@@ -859,7 +865,7 @@ func TestRemoteEndpointsUpdatedMirroring(t *testing.T) {
 						Port:     666,
 					},
 				}),
-				endpointMirrorService("pod-0", "service-two-remote", "eptest", "333", []corev1.ServicePort{
+				endpointMirrorService("pod-0", "service-two-remote", "eptest", "333", nil, []corev1.ServicePort{
 					{
 						Name:     "port1",
 						Protocol: "TCP",
@@ -871,7 +877,7 @@ func TestRemoteEndpointsUpdatedMirroring(t *testing.T) {
 						Port:     666,
 					},
 				}),
-				endpointMirrorService("pod-1", "service-two-remote", "eptest", "112", []corev1.ServicePort{
+				endpointMirrorService("pod-1", "service-two-remote", "eptest", "112", nil, []corev1.ServicePort{
 					{
 						Name:     "port1",
 						Protocol: "TCP",
@@ -906,6 +912,7 @@ func TestRemoteEndpointsUpdatedMirroring(t *testing.T) {
 				endpointMirrorEndpoints(
 					"service-two-remote",
 					"eptest",
+					nil,
 					"pod-0",
 					"192.0.2.127",
 					"gateway-identity",
@@ -924,6 +931,7 @@ func TestRemoteEndpointsUpdatedMirroring(t *testing.T) {
 				endpointMirrorEndpoints(
 					"service-two-remote",
 					"eptest",
+					nil,
 					"pod-1",
 					"192.0.2.127",
 					"gateway-identity",
@@ -965,15 +973,15 @@ func TestGcOrphanedServicesMirroring(t *testing.T) {
 			description: "deletes mirrored resources that are no longer present on the remote cluster",
 			environment: gcTriggered,
 			expectedLocalServices: []*corev1.Service{
-				mirrorService("test-service-1-remote", "test-namespace", "", nil),
-				headlessMirrorService("test-headless-service-remote", "test-namespace", "", nil),
-				endpointMirrorService("pod-0", "test-headless-service-remote", "test-namespace", "", nil),
+				mirrorService("test-service-1-remote", "test-namespace", "", nil, nil),
+				headlessMirrorService("test-headless-service-remote", "test-namespace", "", nil, nil),
+				endpointMirrorService("pod-0", "test-headless-service-remote", "test-namespace", "", nil, nil),
 			},
 
 			expectedLocalEndpoints: []*corev1.Endpoints{
-				endpoints("test-service-1-remote", "test-namespace", "", "", nil),
-				headlessMirrorEndpoints("test-headless-service-remote", "test-namespace", "", nil),
-				endpointMirrorEndpoints("test-headless-service-remote", "test-namespace", "pod-0", "", "", nil),
+				endpoints("test-service-1-remote", "test-namespace", nil, "", "", nil),
+				headlessMirrorEndpoints("test-headless-service-remote", "test-namespace", nil, "", nil),
+				endpointMirrorEndpoints("test-headless-service-remote", "test-namespace", nil, "pod-0", "", "", nil),
 			},
 		},
 	} {
@@ -1003,27 +1011,27 @@ func onAddOrUpdateTestCases(isAdd bool) []mirroringTestCase {
 			description: fmt.Sprintf("enqueue a RemoteServiceUpdated event if this is a service that we have already mirrored and its res version is different (%s)", testType),
 			environment: onAddOrUpdateRemoteServiceUpdated(isAdd),
 			expectedEventsInQueue: []interface{}{&RemoteExportedServiceUpdated{
-				localService:   mirrorService("test-service-remote", "test-namespace", "pastResourceVersion", nil),
-				localEndpoints: endpoints("test-service-remote", "test-namespace", "0.0.0.0", "", nil),
+				localService:   mirrorService("test-service-remote", "test-namespace", "pastResourceVersion", nil, nil),
+				localEndpoints: endpoints("test-service-remote", "test-namespace", nil, "0.0.0.0", "", nil),
 				remoteUpdate: remoteService("test-service", "test-namespace", "currentResVersion", map[string]string{
 					consts.DefaultExportedServiceSelector: "true",
 				}, nil),
 			}},
 			expectedLocalServices: []*corev1.Service{
-				mirrorService("test-service-remote", "test-namespace", "pastResourceVersion", nil),
+				mirrorService("test-service-remote", "test-namespace", "pastResourceVersion", nil, nil),
 			},
 			expectedLocalEndpoints: []*corev1.Endpoints{
-				endpoints("test-service-remote", "test-namespace", "0.0.0.0", "", nil),
+				endpoints("test-service-remote", "test-namespace", nil, "0.0.0.0", "", nil),
 			},
 		},
 		{
 			description: fmt.Sprintf("not enqueue any events as this update does not really tell us anything new (res version is the same...) (%s)", testType),
 			environment: onAddOrUpdateSameResVersion(isAdd),
 			expectedLocalServices: []*corev1.Service{
-				mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil),
+				mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil, nil),
 			},
 			expectedLocalEndpoints: []*corev1.Endpoints{
-				endpoints("test-service-remote", "test-namespace", "0.0.0.0", "", nil),
+				endpoints("test-service-remote", "test-namespace", nil, "0.0.0.0", "", nil),
 			},
 		},
 		{
@@ -1035,10 +1043,10 @@ func onAddOrUpdateTestCases(isAdd bool) []mirroringTestCase {
 			}},
 
 			expectedLocalServices: []*corev1.Service{
-				mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil),
+				mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil, nil),
 			},
 			expectedLocalEndpoints: []*corev1.Endpoints{
-				endpoints("test-service-remote", "test-namespace", "0.0.0.0", "", nil),
+				endpoints("test-service-remote", "test-namespace", nil, "0.0.0.0", "", nil),
 			},
 		},
 	}
diff --git a/multicluster/service-mirror/cluster_watcher_test_util.go b/multicluster/service-mirror/cluster_watcher_test_util.go
index 339e67d48..30ba27067 100644
--- a/multicluster/service-mirror/cluster_watcher_test_util.go
+++ b/multicluster/service-mirror/cluster_watcher_test_util.go
@@ -86,6 +86,7 @@ var createExportedService = &testEnvironment{
 		&RemoteServiceExported{
 			service: remoteService("service-one", "ns1", "111", map[string]string{
 				consts.DefaultExportedServiceSelector: "true",
+				"lk":                                  "lv",
 			}, []corev1.ServicePort{
 				{
 					Name:     "port1",
@@ -102,7 +103,7 @@ var createExportedService = &testEnvironment{
 	},
 	remoteResources: []string{
 		asYaml(gateway("existing-gateway", "existing-namespace", "222", "192.0.2.127", "mc-gateway", 888, "gateway-identity", defaultProbePort, defaultProbePath, defaultProbePeriod)),
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 	},
 	localResources: []string{
 		asYaml(namespace("ns1")),
@@ -141,7 +142,7 @@ var createRemoteDiscoveryService = &testEnvironment{
 		},
 	},
 	remoteResources: []string{
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 	},
 	localResources: []string{
 		asYaml(namespace("ns1")),
@@ -180,7 +181,7 @@ var createFederatedService = &testEnvironment{
 		},
 	},
 	remoteResources: []string{
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 	},
 	localResources: []string{
 		asYaml(namespace("ns1")),
@@ -233,7 +234,7 @@ func joinFederatedService() *testEnvironment {
 			},
 		},
 		remoteResources: []string{
-			asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+			asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 		},
 		localResources: []string{
 			asYaml(namespace("ns1")),
@@ -262,7 +263,7 @@ var leftFederatedService = &testEnvironment{
 		},
 	},
 	remoteResources: []string{
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 	},
 	localResources: []string{
 		asYaml(namespace("ns1")),
@@ -313,7 +314,7 @@ var createLocalFederatedService = &testEnvironment{
 		},
 	},
 	remoteResources: []string{
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 	},
 	localResources: []string{
 		asYaml(namespace("ns1")),
@@ -366,7 +367,7 @@ func joinLocalFederatedService() *testEnvironment {
 			},
 		},
 		remoteResources: []string{
-			asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+			asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 		},
 		localResources: []string{
 			asYaml(namespace("ns1")),
@@ -395,7 +396,7 @@ var leftLocalFederatedService = &testEnvironment{
 		},
 	},
 	remoteResources: []string{
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
 	},
 	localResources: []string{
 		asYaml(namespace("ns1")),
@@ -431,6 +432,7 @@ var createExportedHeadlessService = &testEnvironment{
 		&RemoteServiceExported{
 			service: remoteHeadlessService("service-one", "ns2", "111", map[string]string{
 				consts.DefaultExportedServiceSelector: "true",
+				"lk":                                  "lv",
 			}, []corev1.ServicePort{
 				{
 					Name:     "port1",
@@ -461,7 +463,7 @@ var createExportedHeadlessService = &testEnvironment{
 	},
 	remoteResources: []string{
 		asYaml(gateway("existing-gateway", "existing-namespace", "222", "192.0.2.129", "gateway", 889, "gateway-identity", 123456, "/probe1", "120s")),
-		asYaml(remoteHeadlessService("service-one", "ns2", "111", nil,
+		asYaml(remoteHeadlessService("service-one", "ns2", "111", map[string]string{"lk": "lv"},
 			[]corev1.ServicePort{
 				{
 					Name:     "port1",
@@ -516,8 +518,8 @@ var deleteMirrorService = &testEnvironment{
 		},
 	},
 	localResources: []string{
-		asYaml(mirrorService("test-service-remote-to-delete-remote", "test-namespace-to-delete", "", nil)),
-		asYaml(endpoints("test-service-remote-to-delete-remote", "test-namespace-to-delete", "", "gateway-identity", nil)),
+		asYaml(mirrorService("test-service-remote-to-delete-remote", "test-namespace-to-delete", "", nil, nil)),
+		asYaml(endpoints("test-service-remote-to-delete-remote", "test-namespace-to-delete", nil, "", "gateway-identity", nil)),
 	},
 	link: v1alpha2.Link{
 		Spec: v1alpha2.LinkSpec{
@@ -550,7 +552,7 @@ var updateServiceWithChangedPorts = &testEnvironment{
 					Port:     333,
 				},
 			}),
-			localService: mirrorService("test-service-remote", "test-namespace", "pastServiceResVersion", []corev1.ServicePort{
+			localService: mirrorService("test-service-remote", "test-namespace", "pastServiceResVersion", nil, []corev1.ServicePort{
 				{
 					Name:     "port1",
 					Protocol: "TCP",
@@ -562,7 +564,7 @@ var updateServiceWithChangedPorts = &testEnvironment{
 					Port:     222,
 				},
 			}),
-			localEndpoints: endpoints("test-service-remote", "test-namespace", "192.0.2.127", "", []corev1.EndpointPort{
+			localEndpoints: endpoints("test-service-remote", "test-namespace", nil, "192.0.2.127", "", []corev1.EndpointPort{
 				{
 					Name:     "port1",
 					Port:     888,
@@ -580,7 +582,7 @@ var updateServiceWithChangedPorts = &testEnvironment{
 		asYaml(gateway("gateway", "gateway-ns", "currentGatewayResVersion", "192.0.2.127", "mc-gateway", 888, "", defaultProbePort, defaultProbePath, defaultProbePeriod)),
 	},
 	localResources: []string{
-		asYaml(mirrorService("test-service-remote", "test-namespace", "past", []corev1.ServicePort{
+		asYaml(mirrorService("test-service-remote", "test-namespace", "past", nil, []corev1.ServicePort{
 			{
 				Name:     "port1",
 				Protocol: "TCP",
@@ -597,7 +599,7 @@ var updateServiceWithChangedPorts = &testEnvironment{
 				Port:     333,
 			},
 		})),
-		asYaml(endpoints("test-service-remote", "test-namespace", "192.0.2.127", "", []corev1.EndpointPort{
+		asYaml(endpoints("test-service-remote", "test-namespace", nil, "192.0.2.127", "", []corev1.EndpointPort{
 			{
 				Name:     "port1",
 				Port:     888,
@@ -664,7 +666,7 @@ var updateEndpointsWithChangedHosts = &testEnvironment{
 			})),
 	},
 	localResources: []string{
-		asYaml(headlessMirrorService("service-two-remote", "eptest", "222",
+		asYaml(headlessMirrorService("service-two-remote", "eptest", "222", nil,
 			[]corev1.ServicePort{
 				{
 					Name:     "port1",
@@ -677,7 +679,7 @@ var updateEndpointsWithChangedHosts = &testEnvironment{
 					Port:     666,
 				},
 			})),
-		asYaml(endpointMirrorService("pod-0", "service-two-remote", "eptest", "333", []corev1.ServicePort{
+		asYaml(endpointMirrorService("pod-0", "service-two-remote", "eptest", "333", nil, []corev1.ServicePort{
 			{
 				Name:     "port1",
 				Protocol: "TCP",
@@ -692,6 +694,7 @@ var updateEndpointsWithChangedHosts = &testEnvironment{
 		asYaml(headlessMirrorEndpoints(
 			"service-two-remote",
 			"eptest",
+			nil,
 			"gateway-identity",
 			[]corev1.EndpointPort{
 				{
@@ -708,6 +711,7 @@ var updateEndpointsWithChangedHosts = &testEnvironment{
 		asYaml(endpointMirrorEndpoints(
 			"service-two-remote",
 			"eptest",
+			nil,
 			"pod-0",
 			"192.0.2.127",
 			"gateway-identity",
@@ -742,10 +746,10 @@ var clusterUnregistered = &testEnvironment{
 		&ClusterUnregistered{},
 	},
 	localResources: []string{
-		asYaml(mirrorService("test-service-1-remote", "test-namespace", "", nil)),
-		asYaml(endpoints("test-service-1-remote", "test-namespace", "", "", nil)),
-		asYaml(mirrorService("test-service-2-remote", "test-namespace", "", nil)),
-		asYaml(endpoints("test-service-2-remote", "test-namespace", "", "", nil)),
+		asYaml(mirrorService("test-service-1-remote", "test-namespace", "", nil, nil)),
+		asYaml(endpoints("test-service-1-remote", "test-namespace", nil, "", "", nil)),
+		asYaml(mirrorService("test-service-2-remote", "test-namespace", "", nil, nil)),
+		asYaml(endpoints("test-service-2-remote", "test-namespace", nil, "", "", nil)),
 	},
 	link: v1alpha2.Link{
 		Spec: v1alpha2.LinkSpec{
@@ -759,14 +763,14 @@ var gcTriggered = &testEnvironment{
 		&OrphanedServicesGcTriggered{},
 	},
 	localResources: []string{
-		asYaml(mirrorService("test-service-1-remote", "test-namespace", "", nil)),
-		asYaml(endpoints("test-service-1-remote", "test-namespace", "", "", nil)),
-		asYaml(mirrorService("test-service-2-remote", "test-namespace", "", nil)),
-		asYaml(endpoints("test-service-2-remote", "test-namespace", "", "", nil)),
-		asYaml(headlessMirrorService("test-headless-service-remote", "test-namespace", "", nil)),
-		asYaml(endpointMirrorService("pod-0", "test-headless-service-remote", "test-namespace", "", nil)),
-		asYaml(headlessMirrorEndpoints("test-headless-service-remote", "test-namespace", "", nil)),
-		asYaml(endpointMirrorEndpoints("test-headless-service-remote", "test-namespace", "pod-0", "", "", nil)),
+		asYaml(mirrorService("test-service-1-remote", "test-namespace", "", nil, nil)),
+		asYaml(endpoints("test-service-1-remote", "test-namespace", nil, "", "", nil)),
+		asYaml(mirrorService("test-service-2-remote", "test-namespace", "", nil, nil)),
+		asYaml(endpoints("test-service-2-remote", "test-namespace", nil, "", "", nil)),
+		asYaml(headlessMirrorService("test-headless-service-remote", "test-namespace", "", nil, nil)),
+		asYaml(endpointMirrorService("pod-0", "test-headless-service-remote", "test-namespace", "", nil, nil)),
+		asYaml(headlessMirrorEndpoints("test-headless-service-remote", "test-namespace", nil, "", nil)),
+		asYaml(endpointMirrorEndpoints("test-headless-service-remote", "test-namespace", nil, "pod-0", "", "", nil)),
 	},
 	remoteResources: []string{
 		asYaml(remoteService("test-service-1", "test-namespace", "", map[string]string{consts.DefaultExportedServiceSelector: "true"}, nil)),
@@ -818,8 +822,8 @@ var noGatewayLink = &testEnvironment{
 		asYaml(namespace("ns1")),
 	},
 	remoteResources: []string{
-		asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
-		asYaml(endpoints("service-two", "ns1", "192.0.2.128", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+		asYaml(endpoints("service-two", "ns1", nil, "192.0.2.128", "gateway-identity", []corev1.EndpointPort{})),
 	},
 	link: v1alpha2.Link{
 		Spec: v1alpha2.LinkSpec{
@@ -862,8 +866,8 @@ func onAddOrUpdateRemoteServiceUpdated(isAdd bool) *testEnvironment {
 			}, nil)),
 		},
 		localResources: []string{
-			asYaml(mirrorService("test-service-remote", "test-namespace", "pastResourceVersion", nil)),
-			asYaml(endpoints("test-service-remote", "test-namespace", "0.0.0.0", "", nil)),
+			asYaml(mirrorService("test-service-remote", "test-namespace", "pastResourceVersion", nil, nil)),
+			asYaml(endpoints("test-service-remote", "test-namespace", nil, "0.0.0.0", "", nil)),
 		},
 		link: v1alpha2.Link{
 			Spec: v1alpha2.LinkSpec{
@@ -888,8 +892,8 @@ func onAddOrUpdateSameResVersion(isAdd bool) *testEnvironment {
 			}, nil)),
 		},
 		localResources: []string{
-			asYaml(mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil)),
-			asYaml(endpoints("test-service-remote", "test-namespace", "0.0.0.0", "", nil)),
+			asYaml(mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil, nil)),
+			asYaml(endpoints("test-service-remote", "test-namespace", nil, "0.0.0.0", "", nil)),
 		},
 		link: v1alpha2.Link{
 			Spec: v1alpha2.LinkSpec{
@@ -912,8 +916,8 @@ func serviceNotExportedAnymore(isAdd bool) *testEnvironment {
 			onAddOrUpdateEvent(isAdd, remoteService("test-service", "test-namespace", "currentResVersion", map[string]string{}, nil)),
 		},
 		localResources: []string{
-			asYaml(mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil)),
-			asYaml(endpoints("test-service-remote", "test-namespace", "0.0.0.0", "", nil)),
+			asYaml(mirrorService("test-service-remote", "test-namespace", "currentResVersion", nil, nil)),
+			asYaml(endpoints("test-service-remote", "test-namespace", nil, "0.0.0.0", "", nil)),
 		},
 		link: v1alpha2.Link{
 			Spec: v1alpha2.LinkSpec{
@@ -1137,23 +1141,26 @@ func remoteHeadlessEndpointsUpdate(name, namespace, resourceVersion, address str
 	}
 }
 
-func mirrorService(name, namespace, resourceVersion string, ports []corev1.ServicePort) *corev1.Service {
+func mirrorService(name, namespace, resourceVersion string, labels map[string]string, ports []corev1.ServicePort) *corev1.Service {
 	annotations := make(map[string]string)
 	annotations[consts.RemoteResourceVersionAnnotation] = resourceVersion
 	annotations[consts.RemoteServiceFqName] = fmt.Sprintf("%s.%s.svc.cluster.local", strings.Replace(name, "-remote", "", 1), namespace)
 
+	if labels == nil {
+		labels = make(map[string]string)
+	}
+	labels[consts.RemoteClusterNameLabel] = clusterName
+	labels[consts.MirroredResourceLabel] = "true"
+
 	return &corev1.Service{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Service",
 			APIVersion: "v1",
 		},
 		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: namespace,
-			Labels: map[string]string{
-				consts.RemoteClusterNameLabel: clusterName,
-				consts.MirroredResourceLabel:  "true",
-			},
+			Name:        name,
+			Namespace:   namespace,
+			Labels:      labels,
 			Annotations: annotations,
 		},
 		Spec: corev1.ServiceSpec{
@@ -1162,31 +1169,33 @@ func mirrorService(name, namespace, resourceVersion string, ports []corev1.Servi
 	}
 }
 
-func headlessMirrorService(name, namespace, resourceVersion string, ports []corev1.ServicePort) *corev1.Service {
-	svc := mirrorService(name, namespace, resourceVersion, ports)
+func headlessMirrorService(name, namespace, resourceVersion string, labels map[string]string, ports []corev1.ServicePort) *corev1.Service {
+	svc := mirrorService(name, namespace, resourceVersion, labels, ports)
 	svc.Spec.ClusterIP = "None"
 	return svc
 }
 
-func endpointMirrorService(hostname, rootName, namespace, resourceVersion string, ports []corev1.ServicePort) *corev1.Service {
+func endpointMirrorService(hostname, rootName, namespace, resourceVersion string, labels map[string]string, ports []corev1.ServicePort) *corev1.Service {
 	annotations := make(map[string]string)
 	annotations[consts.RemoteResourceVersionAnnotation] = resourceVersion
 	annotations[consts.RemoteServiceFqName] = fmt.Sprintf("%s.%s.%s.svc.cluster.local", hostname, strings.Replace(rootName, "-remote", "", 1), namespace)
 
+	if labels == nil {
+		labels = make(map[string]string)
+	}
+	labels[consts.MirroredHeadlessSvcNameLabel] = rootName
+	labels[consts.RemoteClusterNameLabel] = clusterName
+	labels[consts.MirroredResourceLabel] = "true"
+
 	return &corev1.Service{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Service",
 			APIVersion: "v1",
 		},
 		ObjectMeta: metav1.ObjectMeta{
-			Name:      fmt.Sprintf("%s-%s", hostname, clusterName),
-			Namespace: namespace,
-			Labels: map[string]string{
-
-				consts.MirroredHeadlessSvcNameLabel: rootName,
-				consts.RemoteClusterNameLabel:       clusterName,
-				consts.MirroredResourceLabel:        "true",
-			},
+			Name:        fmt.Sprintf("%s-%s", hostname, clusterName),
+			Namespace:   namespace,
+			Labels:      labels,
 			Annotations: annotations,
 		},
 		Spec: corev1.ServiceSpec{
@@ -1297,7 +1306,7 @@ func gateway(name, namespace, resourceVersion, ip, portName string, port int32,
 	return &svc
 }
 
-func endpoints(name, namespace, gatewayIP string, gatewayIdentity string, ports []corev1.EndpointPort) *corev1.Endpoints {
+func endpoints(name, namespace string, labels map[string]string, gatewayIP string, gatewayIdentity string, ports []corev1.EndpointPort) *corev1.Endpoints {
 	var subsets []corev1.EndpointSubset
 	if gatewayIP != "" {
 		subsets = []corev1.EndpointSubset{
@@ -1312,6 +1321,12 @@ func endpoints(name, namespace, gatewayIP string, gatewayIdentity string, ports
 		}
 	}
 
+	if labels == nil {
+		labels = make(map[string]string)
+	}
+	labels[consts.RemoteClusterNameLabel] = clusterName
+	labels[consts.MirroredResourceLabel] = "true"
+
 	endpoints := &corev1.Endpoints{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Endpoints",
@@ -1320,10 +1335,7 @@ func endpoints(name, namespace, gatewayIP string, gatewayIdentity string, ports
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      name,
 			Namespace: namespace,
-			Labels: map[string]string{
-				consts.RemoteClusterNameLabel: clusterName,
-				consts.MirroredResourceLabel:  "true",
-			},
+			Labels:    labels,
 			Annotations: map[string]string{
 				consts.RemoteServiceFqName: fmt.Sprintf("%s.%s.svc.cluster.local", strings.Replace(name, "-remote", "", 1), namespace),
 			},
@@ -1338,9 +1350,9 @@ func endpoints(name, namespace, gatewayIP string, gatewayIdentity string, ports
 	return endpoints
 }
 
-func endpointMirrorEndpoints(rootName, namespace, hostname, gatewayIP, gatewayIdentity string, ports []corev1.EndpointPort) *corev1.Endpoints {
+func endpointMirrorEndpoints(rootName, namespace string, labels map[string]string, hostname, gatewayIP, gatewayIdentity string, ports []corev1.EndpointPort) *corev1.Endpoints {
 	localName := fmt.Sprintf("%s-%s", hostname, clusterName)
-	ep := endpoints(localName, namespace, gatewayIP, gatewayIdentity, ports)
+	ep := endpoints(localName, namespace, labels, gatewayIP, gatewayIdentity, ports)
 
 	ep.Annotations[consts.RemoteServiceFqName] = fmt.Sprintf("%s.%s.%s.svc.cluster.local", hostname, strings.Replace(rootName, "-remote", "", 1), namespace)
 	ep.Labels[consts.MirroredHeadlessSvcNameLabel] = rootName
@@ -1348,7 +1360,12 @@ func endpointMirrorEndpoints(rootName, namespace, hostname, gatewayIP, gatewayId
 	return ep
 }
 
-func headlessMirrorEndpoints(name, namespace, gatewayIdentity string, ports []corev1.EndpointPort) *corev1.Endpoints {
+func headlessMirrorEndpoints(name, namespace string, labels map[string]string, gatewayIdentity string, ports []corev1.EndpointPort) *corev1.Endpoints {
+	if labels == nil {
+		labels = make(map[string]string)
+	}
+	labels[consts.RemoteClusterNameLabel] = clusterName
+	labels[consts.MirroredResourceLabel] = "true"
 	endpoints := &corev1.Endpoints{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "Endpoints",
@@ -1357,10 +1374,7 @@ func headlessMirrorEndpoints(name, namespace, gatewayIdentity string, ports []co
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      name,
 			Namespace: namespace,
-			Labels: map[string]string{
-				consts.RemoteClusterNameLabel: clusterName,
-				consts.MirroredResourceLabel:  "true",
-			},
+			Labels:    labels,
 			Annotations: map[string]string{
 				consts.RemoteServiceFqName: fmt.Sprintf("%s.%s.svc.cluster.local", strings.Replace(name, "-remote", "", 1), namespace),
 			},
@@ -1482,8 +1496,8 @@ func createEnvWithSelector(defaultSelector, remoteSelector *metav1.LabelSelector
 			asYaml(namespace("ns1")),
 		},
 		remoteResources: []string{
-			asYaml(endpoints("service-one", "ns1", "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
-			asYaml(endpoints("service-two", "ns1", "192.0.3.127", "gateway-identity", []corev1.EndpointPort{})),
+			asYaml(endpoints("service-one", "ns1", nil, "192.0.2.127", "gateway-identity", []corev1.EndpointPort{})),
+			asYaml(endpoints("service-two", "ns1", nil, "192.0.3.127", "gateway-identity", []corev1.EndpointPort{})),
 		},
 		link: v1alpha2.Link{
 			Spec: v1alpha2.LinkSpec{
diff --git a/multicluster/service-mirror/link_handlers_test.go b/multicluster/service-mirror/link_handlers_test.go
new file mode 100644
index 000000000..61eef5e33
--- /dev/null
+++ b/multicluster/service-mirror/link_handlers_test.go
@@ -0,0 +1,141 @@
+package servicemirror
+
+import (
+	"context"
+	"encoding/json"
+	"log"
+	"testing"
+	"time"
+
+	"github.com/linkerd/linkerd2/controller/gen/apis/link/v1alpha2"
+	l5dcrdinformer "github.com/linkerd/linkerd2/controller/gen/client/informers/externalversions"
+	"github.com/linkerd/linkerd2/controller/k8s"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+)
+
+const nsName = "ns1"
+const linkName = "linkName"
+
+func TestLinkHandlers(t *testing.T) {
+	k8sAPI, l5dAPI, err := k8s.NewFakeAPIWithL5dClient()
+	if err != nil {
+		t.Fatal(err)
+	}
+	k8sAPI.Sync(nil)
+
+	informerFactory := l5dcrdinformer.NewSharedInformerFactoryWithOptions(
+		l5dAPI,
+		k8s.ResyncTime,
+		l5dcrdinformer.WithNamespace(nsName),
+	)
+	informer := informerFactory.Link().V1alpha2().Links().Informer()
+	informerFactory.Start(context.Background().Done())
+
+	results := make(chan *v1alpha2.Link, 100)
+	_, err = informer.AddEventHandler(GetLinkHandlers(results, linkName))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// test that a message is received when a link is created
+	_, err = k8sAPI.Client.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName}}, metav1.CreateOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	link := &v1alpha2.Link{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      linkName,
+			Namespace: nsName,
+		},
+		Spec: v1alpha2.LinkSpec{ProbeSpec: v1alpha2.ProbeSpec{Timeout: "30s"}},
+	}
+	_, err = l5dAPI.LinkV1alpha2().Links(nsName).Create(context.Background(), link, metav1.CreateOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	select {
+	case link := <-results:
+		if link.GetName() != linkName {
+			t.Fatalf("Expected LinkName, got %s", link.GetName())
+		}
+	case <-time.After(time.Second):
+		t.Fatal("Timed out waiting for message")
+	}
+
+	// test that a message is received when a link spec is updated
+	patch := map[string]any{
+		"spec": map[string]any{
+			"probeSpec": map[string]any{
+				"timeout": "60s",
+			},
+		},
+	}
+	patchBytes, err := json.Marshal(patch)
+	if err != nil {
+		log.Fatalf("Failed to marshal patch: %v", err)
+	}
+	_, err = l5dAPI.LinkV1alpha2().Links(nsName).Patch(
+		context.Background(),
+		linkName,
+		types.MergePatchType,
+		patchBytes,
+		metav1.PatchOptions{},
+	)
+	if err != nil {
+		t.Fatalf("Failed to patch link: %s", err)
+	}
+
+	select {
+	case link := <-results:
+		if link.GetName() != linkName {
+			t.Fatalf("Expected LinkName, got %s", link.GetName())
+		}
+	case <-time.After(time.Second):
+		t.Fatal("Timed out waiting for message")
+	}
+
+	// test that a message is _not_ received when a link status is updated
+	patch = map[string]any{
+		"status": map[string]any{
+			"foo": "bar",
+		},
+	}
+	patchBytes, err = json.Marshal(patch)
+	if err != nil {
+		log.Fatalf("Failed to marshal patch: %v", err)
+	}
+	_, err = l5dAPI.LinkV1alpha2().Links(nsName).Patch(
+		context.Background(),
+		linkName,
+		types.MergePatchType,
+		patchBytes,
+		metav1.PatchOptions{},
+		"status",
+	)
+	if err != nil {
+		t.Fatalf("Failed to patch link: %s", err)
+	}
+
+	select {
+	case link := <-results:
+		t.Fatalf("Received unexpected message: %v", link)
+	case <-time.After(time.Second):
+	}
+
+	// test that a nil message is received when a link is deleted
+	if err := l5dAPI.LinkV1alpha2().Links(nsName).Delete(context.Background(), linkName, metav1.DeleteOptions{}); err != nil {
+		t.Fatalf("Failed to delete link: %s", err)
+	}
+	select {
+	case link := <-results:
+		if link != nil {
+			t.Fatalf("Expected nil, got %v", link)
+		}
+	case <-time.After(time.Second):
+		t.Fatal("Timed out waiting for message")
+	}
+}
diff --git a/pkg/k8s/k8s_test.go b/pkg/k8s/k8s_test.go
index a4a0eec9c..472d8a398 100644
--- a/pkg/k8s/k8s_test.go
+++ b/pkg/k8s/k8s_test.go
@@ -32,8 +32,6 @@ func TestCanonicalResourceNameFromFriendlyName(t *testing.T) {
 			"pod":          Pod,
 			"deployment":   Deployment,
 			"deployments":  Deployment,
-			"au":           Authority,
-			"authorities":  Authority,
 			"cj":           CronJob,
 			"cronjob":      CronJob,
 			"serverauthz":  ServerAuthorization,
diff --git a/policy-controller/k8s/index/src/outbound/tests.rs b/policy-controller/k8s/index/src/outbound/tests.rs
index 83ef6937d..5b6fab35f 100644
--- a/policy-controller/k8s/index/src/outbound/tests.rs
+++ b/policy-controller/k8s/index/src/outbound/tests.rs
@@ -7,10 +7,13 @@ use crate::{
 };
 use k8s_openapi::chrono::Utc;
 use kubert::index::IndexNamespacedResource;
-use linkerd_policy_controller_core::outbound::{Kind, ResourceTarget};
-use linkerd_policy_controller_core::IpNet;
+use linkerd_policy_controller_core::{outbound, IpNet};
+use linkerd_policy_controller_core::{
+    outbound::{Kind, ResourceTarget},
+    POLICY_CONTROLLER_NAME,
+};
 use linkerd_policy_controller_k8s_api::{
-    self as k8s,
+    self as k8s, gateway,
     policy::{self, EgressNetwork},
 };
 use tokio::time;
@@ -215,3 +218,146 @@ fn fallback_rx_closed_when_egress_net_deleted() {
 
     assert!(fallback_rx.has_changed().is_err());
 }
+
+#[test]
+fn update_backend_on_route_with_no_port() {
+    tracing_subscriber::fmt()
+        .with_max_level(Level::TRACE)
+        .try_init()
+        .ok();
+
+    let test = TestConfig::default();
+    let ns = "ns";
+
+    let parent = k8s::Service {
+        metadata: k8s::ObjectMeta {
+            namespace: Some(ns.to_string()),
+            name: Some("parent-svc".to_string()),
+            ..Default::default()
+        },
+        spec: Some(k8s::ServiceSpec {
+            cluster_ip: Some("1.1.1.1".to_string()),
+            cluster_ips: Some(vec!["1.1.1.1".to_string()]),
+            type_: Some("ClusterIP".to_string()),
+            ..Default::default()
+        }),
+        status: None,
+    };
+
+    test.index.write().apply(parent);
+
+    let parent_ref = gateway::ParentReference {
+        name: "parent-svc".to_string(),
+        namespace: Some(ns.to_string()),
+        kind: Some("Service".to_string()),
+        group: Some("core".to_string()),
+        section_name: None,
+        port: None, // Route is attached to parent without specifying port.
+    };
+
+    let route = gateway::HttpRoute {
+        metadata: k8s::ObjectMeta {
+            namespace: Some(ns.to_string()),
+            name: Some("foo-route".to_string()),
+            ..Default::default()
+        },
+        spec: gateway::HttpRouteSpec {
+            inner: gateway::CommonRouteSpec {
+                parent_refs: Some(vec![parent_ref.clone()]),
+            },
+            hostnames: None,
+            rules: Some(vec![gateway::HttpRouteRule {
+                matches: None,
+                filters: None,
+                // Reference to a backend that doesn't exist yet.
+                backend_refs: Some(vec![gateway::HttpBackendRef {
+                    backend_ref: Some(gateway::BackendRef {
+                        weight: Some(1),
+                        inner: gateway::BackendObjectReference {
+                            group: Some("core".to_string()),
+                            kind: Some("Service".to_string()),
+                            name: "backend-svc".to_string(),
+                            namespace: Some(ns.to_string()),
+                            port: Some(8080),
+                        },
+                    }),
+                    filters: None,
+                }]),
+            }]),
+        },
+        status: Some(gateway::HttpRouteStatus {
+            inner: gateway::RouteStatus {
+                parents: vec![gateway::RouteParentStatus {
+                    parent_ref,
+                    controller_name: POLICY_CONTROLLER_NAME.to_string(),
+                    conditions: vec![k8s::Condition {
+                        last_transition_time: k8s::Time(Utc::now()),
+                        message: "".to_string(),
+                        observed_generation: None,
+                        reason: "Accepted".to_string(),
+                        status: "True".to_string(),
+                        type_: "Accepted".to_string(),
+                    }],
+                }],
+            },
+        }),
+    };
+
+    test.index.write().apply(route);
+
+    // Create the backend.
+    let backend = k8s::Service {
+        metadata: k8s::ObjectMeta {
+            namespace: Some(ns.to_string()),
+            name: Some("backend-svc".to_string()),
+            ..Default::default()
+        },
+        spec: Some(k8s::ServiceSpec {
+            cluster_ip: Some("1.1.1.2".to_string()),
+            cluster_ips: Some(vec!["1.1.1.2".to_string()]),
+            type_: Some("ClusterIP".to_string()),
+            ..Default::default()
+        }),
+        status: None,
+    };
+    test.index.write().apply(backend);
+
+    let mut rx = test
+        .index
+        .write()
+        .outbound_policy_rx(ResourceTarget {
+            name: "parent-svc".to_string(),
+            namespace: ns.to_string(),
+            port: 8080.try_into().unwrap(),
+            source_namespace: ns.to_string(),
+            kind: Kind::Service,
+        })
+        .expect("parent-svc should exist");
+
+    // Backend should be valid.
+    let policy = rx.borrow_and_update();
+    assert_eq!(policy.parent_namespace(), "ns");
+    assert_eq!(policy.parent_name(), "parent-svc");
+    let (gknn, outbound_route) = policy.http_routes.iter().next().unwrap();
+    assert_eq!(gknn.name, "foo-route");
+    assert_eq!(gknn.namespace, ns);
+    let rule = outbound_route.rules.first().unwrap();
+    let backend = rule.backends.first().unwrap();
+    if let outbound::Backend::Service(outbound::WeightedService {
+        weight: _,
+        authority: _,
+        name,
+        namespace,
+        port: _,
+        filters: _,
+        exists,
+    }) = backend
+    {
+        assert_eq!(name, "backend-svc");
+        assert_eq!(namespace, ns);
+        assert!(exists);
+    } else {
+        panic!("expected outbound::Backend::Service");
+    }
+    drop(policy);
+}
diff --git a/test/integration/external/stat/stat_test.go b/test/integration/external/stat/stat_test.go
index f0c6b96b9..029b3de6c 100644
--- a/test/integration/external/stat/stat_test.go
+++ b/test/integration/external/stat/stat_test.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"fmt"
 	"os"
-	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -37,7 +36,7 @@ func TestMain(m *testing.M) {
 // requesting, and the test will pass.
 func TestCliStatForLinkerdNamespace(t *testing.T) {
 	ctx := context.Background()
-	var prometheusPod, prometheusAuthority, prometheusNamespace, prometheusDeployment, metricsPod string
+	var prometheusPod, prometheusNamespace, prometheusDeployment, metricsPod string
 	// Get Metrics Pod
 	pods, err := TestHelper.GetPodNamesForDeployment(ctx, TestHelper.GetVizNamespace(), "metrics-api")
 	if err != nil {
@@ -62,13 +61,11 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 		testutil.Fatalf(t, "expected 1 pod for prometheus, got %d", len(pods))
 	}
 	prometheusPod = pods[0]
-	prometheusAuthority = prometheusDeployment + "." + prometheusNamespace + ".svc.cluster.local:9090"
 
 	testCases := []struct {
 		args         []string
 		expectedRows map[string]string
 		status       string
-		isAuthority  bool
 	}{
 		{
 			args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetLinkerdNamespace()},
@@ -103,27 +100,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 				"metrics-api": "1/1",
 			},
 		},
-		{
-			args: []string{"viz", "stat", "po", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("au/%s", prometheusAuthority), "--to-namespace", prometheusNamespace},
-			expectedRows: map[string]string{
-				metricsPod: "1/1",
-			},
-			status: "Running",
-		},
-		{
-			args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
-			expectedRows: map[string]string{
-				prometheusAuthority: "-",
-			},
-			isAuthority: true,
-		},
-		{
-			args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
-			expectedRows: map[string]string{
-				prometheusAuthority: "-",
-			},
-			isAuthority: true,
-		},
 	}
 
 	if !TestHelper.ExternalPrometheus() {
@@ -131,7 +107,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 			args         []string
 			expectedRows map[string]string
 			status       string
-			isAuthority  bool
 		}{
 			{
 				args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
@@ -162,7 +137,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 			args         []string
 			expectedRows map[string]string
 			status       string
-			isAuthority  bool
 		}{
 			{
 				args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
@@ -212,7 +186,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 			args         []string
 			expectedRows map[string]string
 			status       string
-			isAuthority  bool
 		}{
 			{
 				args: []string{"viz", "stat", "svc", "-n", prefixedNs},
@@ -244,9 +217,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 					}
 
 					expectedColumnCount := 8
-					if tt.isAuthority {
-						expectedColumnCount = 7
-					}
 					if tt.status != "" {
 						expectedColumnCount++
 					}
@@ -256,7 +226,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 					}
 
 					for name, meshed := range tt.expectedRows {
-						if err := validateRowStats(name, meshed, tt.status, rowStats, tt.isAuthority); err != nil {
+						if err := validateRowStats(name, meshed, tt.status, rowStats); err != nil {
 							return err
 						}
 					}
@@ -271,7 +241,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 	})
 }
 
-func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat, isAuthority bool) error {
+func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat) error {
 	stat, ok := rowStats[name]
 	if !ok {
 		return fmt.Errorf("no stats found for [%s]", name)
@@ -313,12 +283,5 @@ func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats m
 			name, stat.P99Latency)
 	}
 
-	if stat.TCPOpenConnections != "-" && !isAuthority {
-		_, err := strconv.Atoi(stat.TCPOpenConnections)
-		if err != nil {
-			return fmt.Errorf("error parsing number of TCP connections [%s]: %w", stat.TCPOpenConnections, err)
-		}
-	}
-
 	return nil
 }
diff --git a/test/integration/viz/stat/stat_test.go b/test/integration/viz/stat/stat_test.go
index de23b0cbe..2434f6e68 100644
--- a/test/integration/viz/stat/stat_test.go
+++ b/test/integration/viz/stat/stat_test.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"fmt"
 	"os"
-	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -37,7 +36,7 @@ func TestMain(m *testing.M) {
 // requesting, and the test will pass.
 func TestCliStatForLinkerdNamespace(t *testing.T) {
 	ctx := context.Background()
-	var prometheusPod, prometheusAuthority, prometheusNamespace, prometheusDeployment, metricsPod string
+	var prometheusPod, prometheusNamespace, prometheusDeployment, metricsPod string
 	// Get Metrics Pod
 	pods, err := TestHelper.GetPodNamesForDeployment(ctx, TestHelper.GetVizNamespace(), "metrics-api")
 	if err != nil {
@@ -62,13 +61,11 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 		testutil.Fatalf(t, "expected 1 pod for prometheus, got %d", len(pods))
 	}
 	prometheusPod = pods[0]
-	prometheusAuthority = prometheusDeployment + "." + prometheusNamespace + ".svc.cluster.local:9090"
 
 	testCases := []struct {
 		args         []string
 		expectedRows map[string]string
 		status       string
-		isAuthority  bool
 	}{
 		{
 			args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetLinkerdNamespace()},
@@ -103,27 +100,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 				"metrics-api": "1/1",
 			},
 		},
-		{
-			args: []string{"viz", "stat", "po", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("au/%s", prometheusAuthority), "--to-namespace", prometheusNamespace},
-			expectedRows: map[string]string{
-				metricsPod: "1/1",
-			},
-			status: "Running",
-		},
-		{
-			args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
-			expectedRows: map[string]string{
-				prometheusAuthority: "-",
-			},
-			isAuthority: true,
-		},
-		{
-			args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
-			expectedRows: map[string]string{
-				prometheusAuthority: "-",
-			},
-			isAuthority: true,
-		},
 	}
 
 	if !TestHelper.ExternalPrometheus() {
@@ -131,7 +107,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 			args         []string
 			expectedRows map[string]string
 			status       string
-			isAuthority  bool
 		}{
 			{
 				args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
@@ -162,7 +137,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 			args         []string
 			expectedRows map[string]string
 			status       string
-			isAuthority  bool
 		}{
 			{
 				args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
@@ -212,7 +186,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 			args         []string
 			expectedRows map[string]string
 			status       string
-			isAuthority  bool
 		}{
 			{
 				args: []string{"viz", "stat", "svc", "-n", prefixedNs},
@@ -244,9 +217,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 					}
 
 					expectedColumnCount := 8
-					if tt.isAuthority {
-						expectedColumnCount = 7
-					}
 					if tt.status != "" {
 						expectedColumnCount++
 					}
@@ -256,7 +226,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 					}
 
 					for name, meshed := range tt.expectedRows {
-						if err := validateRowStats(name, meshed, tt.status, rowStats, tt.isAuthority); err != nil {
+						if err := validateRowStats(name, meshed, tt.status, rowStats); err != nil {
 							return err
 						}
 					}
@@ -271,7 +241,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
 	})
 }
 
-func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat, isAuthority bool) error {
+func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat) error {
 	stat, ok := rowStats[name]
 	if !ok {
 		return fmt.Errorf("No stats found for [%s]", name)
@@ -313,12 +283,5 @@ func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats m
 			name, stat.P99Latency)
 	}
 
-	if stat.TCPOpenConnections != "-" && !isAuthority {
-		_, err := strconv.Atoi(stat.TCPOpenConnections)
-		if err != nil {
-			return fmt.Errorf("Error parsing number of TCP connections [%s]: %w", stat.TCPOpenConnections, err)
-		}
-	}
-
 	return nil
 }
diff --git a/viz/cmd/edges_test.go b/viz/cmd/edges_test.go
index e9312b9ba..906df672f 100644
--- a/viz/cmd/edges_test.go
+++ b/viz/cmd/edges_test.go
@@ -67,7 +67,7 @@ func TestEdges(t *testing.T) {
 	t.Run("Returns an error if request is for authority", func(t *testing.T) {
 		options.outputFormat = tableOutput
 		args := []string{"authority"}
-		expectedError := "Resource type is not supported: authority"
+		expectedError := "cannot find Kubernetes canonical name from friendly name [authority]"
 
 		_, err := buildEdgesRequests(args, options)
 		if err == nil || err.Error() != expectedError {
diff --git a/viz/metrics-api/stat_summary_test.go b/viz/metrics-api/stat_summary_test.go
index c7a9206fd..ca6874454 100644
--- a/viz/metrics-api/stat_summary_test.go
+++ b/viz/metrics-api/stat_summary_test.go
@@ -22,11 +22,11 @@ type statSumExpected struct {
 
 func prometheusMetric(resName string, resType string) model.Vector {
 	return model.Vector{
-		genPromSample(resName, resType, "emojivoto", false),
+		genPromSample(resName, resType, false),
 	}
 }
 
-func genPromSample(resName string, resType string, resNs string, isDst bool) *model.Sample {
+func genPromSample(resName string, resType string, isDst bool) *model.Sample {
 	labelName := model.LabelName(resType)
 	namespaceLabel := model.LabelName("namespace")
 
@@ -38,7 +38,7 @@ func genPromSample(resName string, resType string, resNs string, isDst bool) *mo
 	return &model.Sample{
 		Metric: model.Metric{
 			labelName:        model.LabelValue(resName),
-			namespaceLabel:   model.LabelValue(resNs),
+			namespaceLabel:   model.LabelValue("emojivoto"),
 			"classification": model.LabelValue("success"),
 			"tls":            model.LabelValue("true"),
 		},
@@ -865,7 +865,7 @@ status:
 `,
 					},
 					mockPromResponse: model.Vector{
-						genPromSample("emojivoto-1", "pod", "emojivoto", false),
+						genPromSample("emojivoto-1", "pod", false),
 					},
 					expectedPrometheusQueries: []string{
 						`histogram_quantile(0.5, sum(irate(response_latency_ms_bucket{direction="outbound", dst_namespace="emojivoto", dst_pod="emojivoto-2", namespace="emojivoto", pod="emojivoto-1"}[1m])) by (le, namespace, pod))`,
@@ -922,7 +922,7 @@ status:
 `,
 					},
 					mockPromResponse: model.Vector{
-						genPromSample("emojivoto-1", "pod", "emojivoto", false),
+						genPromSample("emojivoto-1", "pod", false),
 					},
 					expectedPrometheusQueries: []string{
 						`histogram_quantile(0.5, sum(irate(response_latency_ms_bucket{direction="outbound", dst_namespace="totallydifferent", dst_pod="emojivoto-2", namespace="emojivoto", pod="emojivoto-1"}[1m])) by (le, namespace, pod))`,
@@ -990,7 +990,7 @@ status:
 `,
 					},
 					mockPromResponse: model.Vector{
-						genPromSample("emojivoto-1", "pod", "emojivoto", true),
+						genPromSample("emojivoto-1", "pod", true),
 					},
 					expectedPrometheusQueries: []string{
 						`histogram_quantile(0.5, sum(irate(response_latency_ms_bucket{direction="outbound", pod="emojivoto-2"}[1m])) by (le, dst_namespace, dst_pod))`,
@@ -1058,7 +1058,7 @@ status:
 `,
 					},
 					mockPromResponse: model.Vector{
-						genPromSample("emojivoto-1", "pod", "emojivoto", true),
+						genPromSample("emojivoto-1", "pod", true),
 					},
 					expectedPrometheusQueries: []string{
 						`histogram_quantile(0.5, sum(irate(response_latency_ms_bucket{direction="outbound", dst_namespace="emojivoto", dst_pod="emojivoto-1", namespace="totallydifferent", pod="emojivoto-2"}[1m])) by (le, dst_namespace, dst_pod))`,
@@ -1226,28 +1226,6 @@ status:
 										},
 									},
 								},
-								{
-									Table: &pb.StatTable_PodGroup_{
-										PodGroup: &pb.StatTable_PodGroup{
-											Rows: []*pb.StatTable_PodGroup_Row{
-												{
-													Resource: &pb.Resource{
-														Namespace: "emojivoto",
-														Type:      pkgK8s.Authority,
-													},
-													TimeWindow: "1m",
-													Stats: &pb.BasicStats{
-														SuccessCount: 123,
-														FailureCount: 0,
-														LatencyMsP50: 123,
-														LatencyMsP95: 123,
-														LatencyMsP99: 123,
-													},
-												},
-											},
-										},
-									},
-								},
 								{
 									Table: &pb.StatTable_PodGroup_{
 										PodGroup: &pb.StatTable_PodGroup{
@@ -1686,146 +1664,6 @@ status:
 		})
 	})
 
-	t.Run("Queries prometheus for authority stats", func(t *testing.T) {
-		expectations := []statSumExpected{
-			{
-				expectedStatRPC: expectedStatRPC{
-					err: nil,
-					k8sConfigs: []string{`
-apiVersion: v1
-kind: Pod
-metadata:
-  name: emojivoto-1
-  namespace: emojivoto
-  labels:
-    app: emoji-svc
-    linkerd.io/control-plane-ns: linkerd
-status:
-  phase: Running
-`,
-					},
-					mockPromResponse: model.Vector{
-						genPromSample("10.1.1.239:9995", "authority", "linkerd", false),
-					},
-					expectedPrometheusQueries: []string{
-						`histogram_quantile(0.5, sum(irate(response_latency_ms_bucket{direction="inbound", namespace="linkerd"}[1m])) by (le, namespace, authority))`,
-						`histogram_quantile(0.95, sum(irate(response_latency_ms_bucket{direction="inbound", namespace="linkerd"}[1m])) by (le, namespace, authority))`,
-						`histogram_quantile(0.99, sum(irate(response_latency_ms_bucket{direction="inbound", namespace="linkerd"}[1m])) by (le, namespace, authority))`,
-						`sum(increase(response_total{direction="inbound", namespace="linkerd"}[1m])) by (namespace, authority, classification, tls)`,
-					},
-				},
-				req: &pb.StatSummaryRequest{
-					Selector: &pb.ResourceSelection{
-						Resource: &pb.Resource{
-							Namespace: "linkerd",
-							Type:      pkgK8s.Authority,
-						},
-					},
-					TimeWindow: "1m",
-				},
-				expectedResponse: GenStatSummaryResponse("10.1.1.239:9995", pkgK8s.Authority, []string{"linkerd"}, nil, true, false),
-			},
-		}
-
-		testStatSummary(t, expectations)
-	})
-
-	t.Run("Queries prometheus for authority stats when --from deployment is used", func(t *testing.T) {
-		expectations := []statSumExpected{
-			{
-				expectedStatRPC: expectedStatRPC{
-					err: nil,
-					k8sConfigs: []string{`
-apiVersion: v1
-kind: Pod
-metadata:
-  name: emojivoto-1
-  namespace: emojivoto
-  labels:
-    app: emoji-svc
-    linkerd.io/control-plane-ns: linkerd
-status:
-  phase: Running
-`,
-					},
-					mockPromResponse: model.Vector{
-						genPromSample("10.1.1.239:9995", "authority", "linkerd", false),
-					},
-					expectedPrometheusQueries: []string{
-						`histogram_quantile(0.5, sum(irate(response_latency_ms_bucket{deployment="emojivoto", direction="outbound"}[1m])) by (le, dst_namespace, authority))`,
-						`histogram_quantile(0.95, sum(irate(response_latency_ms_bucket{deployment="emojivoto", direction="outbound"}[1m])) by (le, dst_namespace, authority))`,
-						`histogram_quantile(0.99, sum(irate(response_latency_ms_bucket{deployment="emojivoto", direction="outbound"}[1m])) by (le, dst_namespace, authority))`,
-						`sum(increase(response_total{deployment="emojivoto", direction="outbound"}[1m])) by (dst_namespace, authority, classification, tls)`,
-					},
-				},
-				req: &pb.StatSummaryRequest{
-					Selector: &pb.ResourceSelection{
-						Resource: &pb.Resource{
-							Namespace: "linkerd",
-							Type:      pkgK8s.Authority,
-						},
-					},
-					TimeWindow: "1m",
-					Outbound: &pb.StatSummaryRequest_FromResource{
-						FromResource: &pb.Resource{
-							Name:      "emojivoto",
-							Namespace: "",
-							Type:      pkgK8s.Deployment,
-						},
-					},
-				},
-				expectedResponse: GenStatSummaryResponse("10.1.1.239:9995", pkgK8s.Authority, []string{""}, nil, true, false),
-			},
-		}
-
-		testStatSummary(t, expectations)
-	})
-
-	t.Run("Queries prometheus for a named authority", func(t *testing.T) {
-		expectations := []statSumExpected{
-			{
-				expectedStatRPC: expectedStatRPC{
-					err: nil,
-					k8sConfigs: []string{`
-apiVersion: v1
-kind: Pod
-metadata:
-  name: emojivoto-1
-  namespace: emojivoto
-  labels:
-    app: emoji-svc
-    linkerd.io/control-plane-ns: linkerd
-status:
-  phase: Running
-`,
-					},
-					mockPromResponse: model.Vector{
-						genPromSample("10.1.1.239:9995", "authority", "linkerd", false),
-					},
-					expectedPrometheusQueries: []string{
-						`histogram_quantile(0.5, sum(irate(response_latency_ms_bucket{authority="10.1.1.239:9995", direction="inbound", namespace="linkerd"}[1m])) by (le, namespace, authority))`,
-						`histogram_quantile(0.95, sum(irate(response_latency_ms_bucket{authority="10.1.1.239:9995", direction="inbound", namespace="linkerd"}[1m])) by (le, namespace, authority))`,
-						`histogram_quantile(0.99, sum(irate(response_latency_ms_bucket{authority="10.1.1.239:9995", direction="inbound", namespace="linkerd"}[1m])) by (le, namespace, authority))`,
-						`sum(increase(response_total{authority="10.1.1.239:9995", direction="inbound", namespace="linkerd"}[1m])) by (namespace, authority, classification, tls)`,
-					},
-				},
-				req: &pb.StatSummaryRequest{
-					Selector: &pb.ResourceSelection{
-						Resource: &pb.Resource{
-							Namespace: "linkerd",
-							Type:      pkgK8s.Authority,
-							Name:      "10.1.1.239:9995",
-						},
-					},
-					TimeWindow: "1m",
-				},
-				expectedResponse: GenStatSummaryResponse("10.1.1.239:9995", pkgK8s.Authority, []string{"linkerd"}, nil, true, false),
-			},
-		}
-
-		testStatSummary(t, expectations)
-	})
-
 	t.Run("Stats returned are nil when SkipStats is true", func(t *testing.T) {
 		expectations := []statSumExpected{
 			{
diff --git a/viz/metrics-api/top_routes_test.go b/viz/metrics-api/top_routes_test.go
index 4dc5fe979..4a7d75cc5 100644
--- a/viz/metrics-api/top_routes_test.go
+++ b/viz/metrics-api/top_routes_test.go
@@ -460,44 +460,4 @@ func TestTopRoutes(t *testing.T) {
 
 		testTopRoutes(t, expectations)
 	})
-
-	t.Run("Successfully performs an outbound authority query", func(t *testing.T) {
-		routes := []string{"/a"}
-		counts := []uint64{123}
-		expectations := []topRoutesExpected{
-			{
-				expectedStatRPC: expectedStatRPC{
-					err:              nil,
-					mockPromResponse: routesMetric([]string{"/a"}),
-					expectedPrometheusQueries: []string{
-						`histogram_quantile(0.5, sum(irate(route_response_latency_ms_bucket{deployment="books", direction="outbound", dst=~"(books.default.svc.cluster.local)(:\\d+)?", namespace="default"}[1m])) by (le, dst, rt_route))`,
-						`histogram_quantile(0.95, sum(irate(route_response_latency_ms_bucket{deployment="books", direction="outbound", dst=~"(books.default.svc.cluster.local)(:\\d+)?", namespace="default"}[1m])) by (le, dst, rt_route))`,
-						`histogram_quantile(0.99, sum(irate(route_response_latency_ms_bucket{deployment="books", direction="outbound", dst=~"(books.default.svc.cluster.local)(:\\d+)?", namespace="default"}[1m])) by (le, dst, rt_route))`,
-						`sum(increase(route_response_total{deployment="books", direction="outbound", dst=~"(books.default.svc.cluster.local)(:\\d+)?", namespace="default"}[1m])) by (rt_route, dst, classification)`,
-						`sum(increase(route_actual_response_total{deployment="books", direction="outbound", dst=~"(books.default.svc.cluster.local)(:\\d+)?", namespace="default"}[1m])) by (rt_route, dst, classification)`,
-					},
-					k8sConfigs: booksConfig,
-				},
-				req: &pb.TopRoutesRequest{
-					Selector: &pb.ResourceSelection{
-						Resource: &pb.Resource{
-							Namespace: "default",
-							Type:      pkgK8s.Deployment,
-							Name:      "books",
-						},
-					},
-					Outbound: &pb.TopRoutesRequest_ToResource{
-						ToResource: &pb.Resource{
-							Type: pkgK8s.Authority,
-							Name: "books.default.svc.cluster.local",
-						},
-					},
-					TimeWindow: "1m",
-				},
-				expectedResponse: GenTopRoutesResponse(routes, counts, true, "books.default.svc.cluster.local"),
-			},
-		}
-
-		testTopRoutes(t, expectations)
-	})
 }