@@ -13,7 +13,6 @@ import (
13
13
corev1 "k8s.io/api/core/v1"
14
14
networkingv1 "k8s.io/api/networking/v1"
15
15
"k8s.io/apimachinery/pkg/types"
16
- "k8s.io/apimachinery/pkg/util/intstr"
17
16
"sigs.k8s.io/controller-runtime/pkg/log"
18
17
19
18
pb "github.com/pomerium/pomerium/pkg/grpc/config"
@@ -327,26 +326,43 @@ func getEndpointsURLs(ingressServicePort networkingv1.ServiceBackendPort, servic
327
326
}
328
327
329
328
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.
330
350
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.
337
353
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
342
355
}
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
+ }
350
366
}
351
367
}
352
368
}
0 commit comments