From 584cbfe26e784bf9d2c1624dcc55327c78be11fe Mon Sep 17 00:00:00 2001 From: Harsh Singh Date: Tue, 4 Aug 2026 15:18:55 +0530 Subject: [PATCH] fix: return ErrEndpointNotFound when PortSelector matches no port GetEndpoint ranged over the service ports and only broke out of the loop on a name match, so a non-empty PortSelector that matched nothing fell through with the last port's values and returned them as if they were the requested port, with a nil error. Callers probing a named port (e.g. the broker/meshsync "monitor" port) then targeted the wrong port and reported a false connectivity status instead of surfacing that the endpoint was not found. Track whether the selector matched and return the existing ErrEndpointNotFound when a non-empty PortSelector matches no port. The empty-selector path is unchanged. Signed-off-by: Harsh Singh --- utils/kubernetes/service.go | 8 ++++++++ utils/kubernetes/service_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/utils/kubernetes/service.go b/utils/kubernetes/service.go index 151e1db09..91196cd90 100644 --- a/utils/kubernetes/service.go +++ b/utils/kubernetes/service.go @@ -33,6 +33,7 @@ func GetServiceEndpoint(ctx context.Context, client kubernetes.Interface, opts * // GetEndpoint returns those endpoints in the given service which match the selector. Eg: service name = "client" func GetEndpoint(ctx context.Context, opts *ServiceOptions, obj *corev1.Service) (*utils.Endpoint, error) { var nodePort, clusterPort int32 + var matched bool endpoint := utils.Endpoint{} if opts.WorkerNodeIP == "" { opts.WorkerNodeIP = "localhost" @@ -41,9 +42,16 @@ func GetEndpoint(ctx context.Context, opts *ServiceOptions, obj *corev1.Service) nodePort = port.NodePort clusterPort = port.Port if opts.PortSelector != "" && port.Name == opts.PortSelector { + matched = true break } } + // A non-empty PortSelector that matched no port would otherwise fall through + // with the last port's values and be returned as if it were the requested + // port; report that the endpoint was not found instead. + if opts.PortSelector != "" && !matched { + return nil, ErrEndpointNotFound + } // get clusterip endpoint endpoint.Internal = &utils.HostPort{ Address: obj.Spec.ClusterIP, diff --git a/utils/kubernetes/service_test.go b/utils/kubernetes/service_test.go index 40da33721..d6e0ba9e2 100644 --- a/utils/kubernetes/service_test.go +++ b/utils/kubernetes/service_test.go @@ -522,6 +522,35 @@ func TestGetEndpoint(t *testing.T) { }, wantErr: false, }, + { + name: "PortSelector matching no port returns ErrEndpointNotFound", + args: args{ + ctx: context.TODO(), + opts: &ServiceOptions{ + PortSelector: "does-not-exist", + Mock: &utils.MockOptions{ + DesiredEndpoint: "1.1.1.1:1001", + }, + }, + obj: &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test_service", + Namespace: "default", + Annotations: map[string]string{}, + }, + Spec: v1.ServiceSpec{ + ClusterIP: "1.1.1.1", + Ports: []v1.ServicePort{ + {Name: "test_port_1", Port: 1000}, + {Name: "test_port_2", Port: 1001}, + }, + Type: v1.ServiceTypeClusterIP, + }, + }, + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests {