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
|
// Ingress with an ExternalName Service and no port defined for that Service
|
||||||
if svc.Spec.Type == apiv1.ServiceTypeExternalName {
|
if svc.Spec.Type == apiv1.ServiceTypeExternalName {
|
||||||
externalPort, err := strconv.Atoi(backendPort)
|
servicePort := externalNamePorts(backendPort, svc)
|
||||||
if err != nil {
|
endps := getEndpoints(svc, servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpoints)
|
||||||
// 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)
|
|
||||||
if len(endps) == 0 {
|
if len(endps) == 0 {
|
||||||
klog.Warningf("Service %q does not have any active Endpoint.", svcKey)
|
klog.Warningf("Service %q does not have any active Endpoint.", svcKey)
|
||||||
return upstreams, nil
|
return upstreams, nil
|
||||||
|
@ -1448,3 +1426,50 @@ func shouldCreateUpstreamForLocationDefaultBackend(upstream *ingress.Backend, lo
|
||||||
(len(upstream.Endpoints) == 0 || len(location.CustomHTTPErrors) != 0) &&
|
(len(upstream.Endpoints) == 0 || len(location.CustomHTTPErrors) != 0) &&
|
||||||
location.DefaultBackend != nil
|
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
|
// ExternalName services
|
||||||
if s.Spec.Type == corev1.ServiceTypeExternalName {
|
if s.Spec.Type == corev1.ServiceTypeExternalName {
|
||||||
klog.V(3).Infof("Ingress using Service %q of type ExternalName.", svcKey)
|
klog.V(3).Infof("Ingress using Service %q of type ExternalName.", svcKey)
|
||||||
|
|
||||||
targetPort := port.TargetPort.IntValue()
|
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 the externalName is not an IP address we need to validate is a valid FQDN
|
||||||
if net.ParseIP(s.Spec.ExternalName) == nil {
|
if net.ParseIP(s.Spec.ExternalName) == nil {
|
||||||
if errs := validation.IsDNS1123Subdomain(s.Spec.ExternalName); len(errs) > 0 {
|
if errs := validation.IsDNS1123Subdomain(s.Spec.ExternalName); len(errs) > 0 {
|
||||||
|
|
Loading…
Reference in a new issue