in pkg/appgw/backendhttpsettings.go [112:223]
func (c *appGwConfigBuilder) resolveBackendPort(backendID backendIdentifier) (Port, error) {
var e error
service := c.k8sContext.GetService(backendID.serviceKey())
if service == nil {
// This should never happen since newBackendIdsFiltered() already filters out backends for non-existent Services
e = controllererrors.NewErrorf(
controllererrors.ErrorServiceNotFound,
"Service not found %s",
backendID.serviceKey())
backendPort := Port(80)
if backendID.Backend.Service.Port.Name == "" && backendID.Backend.Service.Port.Number < 65536 {
backendPort = Port(backendID.Backend.Service.Port.Number)
}
return backendPort, e
}
// find the target port number for service port specified in the ingress manifest
servicePortInIngress := fmt.Sprint(backendID.Backend.Service.Port.Number)
if backendID.Backend.Service.Port.Name != "" {
servicePortInIngress = fmt.Sprint(backendID.Backend.Service.Port.Name)
}
resolvedBackendPorts := make(map[serviceBackendPortPair]interface{})
for _, servicePort := range service.Spec.Ports {
// ignore UDP ports
if servicePort.Protocol != v1.ProtocolTCP {
continue
}
// match service by either port, port name or target port
if fmt.Sprint(servicePort.Port) != servicePortInIngress &&
servicePort.Name != servicePortInIngress &&
servicePort.TargetPort.String() != servicePortInIngress {
continue
}
// if target port is not specified, use the service port as backend port
if servicePort.TargetPort.String() == "" {
// targetPort is not defined, by default targetPort == port
pair := serviceBackendPortPair{
ServicePort: Port(servicePort.Port),
BackendPort: Port(servicePort.Port),
}
resolvedBackendPorts[pair] = nil
continue
}
// if target port is an int, use it as backend port
if servicePort.TargetPort.Type == intstr.Int {
// port is defined as port number
pair := serviceBackendPortPair{
ServicePort: Port(servicePort.Port),
BackendPort: Port(servicePort.TargetPort.IntVal),
}
resolvedBackendPorts[pair] = nil
continue
}
// if target port is port name, then resolve the port number for the port name
// k8s matches service port name against endpoints port name retrieved by passing backendID service key to endpoint api.
klog.V(3).Infof("resolving port name '%s' for service '%s' and service port '%s' for Ingress '%s'", servicePort.Name, backendID.serviceKey(), serviceBackendPortToStr(backendID.Backend.Service.Port), backendID.Ingress.Name)
targetPortsResolved := c.resolvePortName(servicePort.Name, &backendID)
for targetPort := range targetPortsResolved {
pair := serviceBackendPortPair{
ServicePort: Port(servicePort.Port),
BackendPort: Port(targetPort),
}
resolvedBackendPorts[pair] = nil
}
}
backendPort := Port(65536)
if len(resolvedBackendPorts) == 0 {
e = controllererrors.NewErrorf(
controllererrors.ErrorUnableToResolveBackendPortFromServicePort,
"No port matched %s",
backendID.serviceKey())
if backendID.Backend.Service.Port.Name == "" {
backendPort = Port(backendID.Backend.Service.Port.Number)
}
} else {
var ports []string
for k := range resolvedBackendPorts {
ports = append(ports, string(k.BackendPort))
if k.BackendPort <= backendPort {
backendPort = k.BackendPort
}
}
if len(resolvedBackendPorts) > 1 {
// found more than 1 backend port for the service port which is a conflicting scenario
e = controllererrors.NewErrorf(
controllererrors.ErrorMultipleServiceBackendPortBinding,
"service %s and service port %s has more than one service-backend port binding which is not an ideal scenario, choosing the smallest service-backend port %d. Ports found %s.",
backendID.serviceKey(), serviceBackendPortToStr(backendID.Backend.Service.Port), backendPort, strings.Join(ports, ","),
)
}
}
if backendPort >= Port(65536) {
e = controllererrors.NewErrorf(
controllererrors.ErrorServiceResolvedToInvalidPort,
"service %s and service port %s was resolved to an invalid service-backend port %d, defaulting to port 80",
backendID.serviceKey(), serviceBackendPortToStr(backendID.Backend.Service.Port), backendPort,
)
backendPort = Port(80)
}
return backendPort, e
}