Skip to content

Commit f0ff23e

Browse files
committed
pomerium: Fix Enpoints port mapping
When trying to determine which Endpoints port to use based on a named Service port, we weren't finding the right one when the Service `spec.ports[].name` didn't match the Service `spec.ports[].targetPort` name. This commit simplifies the mapping logic, and ensure the extended test from the previous commit all succeed. Signed-off-by: Benoît Knecht <[email protected]>
1 parent e4ec61e commit f0ff23e

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

pomerium/ingress_to_route.go

+34-18
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
corev1 "k8s.io/api/core/v1"
1414
networkingv1 "k8s.io/api/networking/v1"
1515
"k8s.io/apimachinery/pkg/types"
16-
"k8s.io/apimachinery/pkg/util/intstr"
1716
"sigs.k8s.io/controller-runtime/pkg/log"
1817

1918
pb "github.com/pomerium/pomerium/pkg/grpc/config"
@@ -327,26 +326,43 @@ func getEndpointsURLs(ingressServicePort networkingv1.ServiceBackendPort, servic
327326
}
328327

329328
func getEndpointPortMatcher(ingressServicePort networkingv1.ServiceBackendPort, servicePorts []corev1.ServicePort) func(port corev1.EndpointPort) bool {
329+
// Here's an example of a Service and its associated Endpoints:
330+
//
331+
// kind: Service
332+
// spec:
333+
// ports:
334+
// - name: grafana
335+
// port: 80
336+
// targetPort: grafana-http
337+
//
338+
// kind: Endpoints
339+
// subsets:
340+
// - ports:
341+
// - name: grafana
342+
// port: 3000
343+
//
344+
// An Ingress refers to the Service by name, and to a specific port either by
345+
// name or by number.
346+
// If by name (`grafana` in the example above), then it's always the same as
347+
// the port name on the Endpoints.
348+
// But if by number (`80` in the example above), then we need to find the
349+
// correct Endpoints port by matching the Service targetPort.
330350
if ingressServicePort.Name != "" {
331-
ports := make(map[intstr.IntOrString]bool)
332-
for _, sp := range servicePorts {
333-
if sp.Name == ingressServicePort.Name {
334-
ports[sp.TargetPort] = true
335-
}
336-
}
351+
// If the Ingress specifies the Service port by name, then simply match the
352+
// Endpoint port by name.
337353
return func(port corev1.EndpointPort) bool {
338-
pName := intstr.FromString(port.Name)
339-
pNumber := intstr.FromInt(int(port.Port))
340-
341-
return port.Name == ingressServicePort.Name && (ports[pName] || ports[pNumber])
354+
return port.Name == ingressServicePort.Name
342355
}
343-
}
344-
345-
// match by port number
346-
for _, sp := range servicePorts {
347-
if sp.Port == ingressServicePort.Number {
348-
return func(port corev1.EndpointPort) bool {
349-
return sp.TargetPort.IntVal == port.Port
356+
} else {
357+
// Otherwise, the Ingress specifies the Service port number, which doesn't
358+
// correspond to the Endpoint port number directly. We need to lookup the
359+
// list of ports on the Service, and get the matching _targetPort_ from
360+
// there, which must correspond to the Endpoint port number.
361+
for _, servicePort := range servicePorts {
362+
if ingressServicePort.Number == servicePort.Port {
363+
return func(port corev1.EndpointPort) bool {
364+
return port.Port == servicePort.TargetPort.IntVal
365+
}
350366
}
351367
}
352368
}

0 commit comments

Comments
 (0)