Allow service type ExternalName with different port and targetPort (#5141)
This commit is contained in:
parent
7d52174b51
commit
cd94ac7f84
2 changed files with 49 additions and 30 deletions
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue