diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index 8634e5e07..ff8557004 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -877,30 +877,8 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string) ([]ingres // Ingress with an ExternalName Service and no port defined for that Service if svc.Spec.Type == apiv1.ServiceTypeExternalName { - externalPort, err := strconv.Atoi(backendPort) - if err != nil { - // check if the service ports have one with backendPort as name - found := false - for _, port := range svc.Spec.Ports { - if port.Name == backendPort { - externalPort = int(port.Port) - found = true - break - } - } - - if !found { - klog.Errorf("service %v/%v does not have a port with name %v", svc.Namespace, svc.Namespace, backendPort) - return upstreams, nil - } - } - - servicePort := apiv1.ServicePort{ - Protocol: "TCP", - Port: int32(externalPort), - TargetPort: intstr.FromInt(externalPort), - } - endps := getEndpoints(svc, &servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpoints) + servicePort := externalNamePorts(backendPort, svc) + endps := getEndpoints(svc, servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpoints) if len(endps) == 0 { klog.Warningf("Service %q does not have any active Endpoint.", svcKey) return upstreams, nil @@ -1448,3 +1426,50 @@ func shouldCreateUpstreamForLocationDefaultBackend(upstream *ingress.Backend, lo (len(upstream.Endpoints) == 0 || len(location.CustomHTTPErrors) != 0) && location.DefaultBackend != nil } + +func externalNamePorts(name string, svc *apiv1.Service) *apiv1.ServicePort { + port, err := strconv.Atoi(name) + if err != nil { + // not a number. check port names. + for _, svcPort := range svc.Spec.Ports { + if svcPort.Name != name { + continue + } + + tp := svcPort.TargetPort + if tp.IntValue() == 0 { + tp = intstr.FromInt(int(svcPort.Port)) + } + + return &apiv1.ServicePort{ + Protocol: "TCP", + Port: svcPort.Port, + TargetPort: tp, + } + } + } + + for _, svcPort := range svc.Spec.Ports { + if svcPort.Port != int32(port) { + continue + } + + tp := svcPort.TargetPort + if tp.IntValue() == 0 { + tp = intstr.FromInt(port) + } + + return &apiv1.ServicePort{ + Protocol: "TCP", + Port: svcPort.Port, + TargetPort: svcPort.TargetPort, + } + } + + // ExternalName without port + return &apiv1.ServicePort{ + Protocol: "TCP", + Port: int32(port), + TargetPort: intstr.FromInt(port), + } +} diff --git a/internal/ingress/controller/endpoints.go b/internal/ingress/controller/endpoints.go index c98bcc12a..01af48888 100644 --- a/internal/ingress/controller/endpoints.go +++ b/internal/ingress/controller/endpoints.go @@ -50,13 +50,7 @@ func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Prot // ExternalName services if s.Spec.Type == corev1.ServiceTypeExternalName { klog.V(3).Infof("Ingress using Service %q of type ExternalName.", svcKey) - targetPort := port.TargetPort.IntValue() - if targetPort <= 0 { - klog.Errorf("ExternalName Service %q has an invalid port (%v)", svcKey, targetPort) - return upsServers - } - // if the externalName is not an IP address we need to validate is a valid FQDN if net.ParseIP(s.Spec.ExternalName) == nil { if errs := validation.IsDNS1123Subdomain(s.Spec.ExternalName); len(errs) > 0 {