mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 13:45:06 +00:00
Pass ports as []*api.ServicePort into LoadBalancer provider
Because AWS needs the NodePort; this also paves the way for e.g. UDP balancing
This commit is contained in:
@@ -331,7 +331,7 @@ func (s *ServiceController) persistUpdate(service *api.Service) error {
|
||||
}
|
||||
|
||||
func (s *ServiceController) createExternalLoadBalancer(service *api.Service) error {
|
||||
ports, err := getTCPPorts(service)
|
||||
ports, err := getPortsForLB(service)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -436,7 +436,7 @@ func needsUpdate(oldService *api.Service, newService *api.Service) bool {
|
||||
if wantsExternalLoadBalancer(oldService) != wantsExternalLoadBalancer(newService) {
|
||||
return true
|
||||
}
|
||||
if !portsEqual(oldService, newService) || oldService.Spec.SessionAffinity != newService.Spec.SessionAffinity {
|
||||
if !portsEqualForLB(oldService, newService) || oldService.Spec.SessionAffinity != newService.Spec.SessionAffinity {
|
||||
return true
|
||||
}
|
||||
if len(oldService.Spec.DeprecatedPublicIPs) != len(newService.Spec.DeprecatedPublicIPs) {
|
||||
@@ -454,8 +454,8 @@ func (s *ServiceController) loadBalancerName(service *api.Service) string {
|
||||
return cloudprovider.GetLoadBalancerName(service)
|
||||
}
|
||||
|
||||
func getTCPPorts(service *api.Service) ([]int, error) {
|
||||
ports := []int{}
|
||||
func getPortsForLB(service *api.Service) ([]*api.ServicePort, error) {
|
||||
ports := []*api.ServicePort{}
|
||||
for i := range service.Spec.Ports {
|
||||
// TODO: Support UDP. Remove the check from the API validation package once
|
||||
// it's supported.
|
||||
@@ -463,21 +463,58 @@ func getTCPPorts(service *api.Service) ([]int, error) {
|
||||
if sp.Protocol != api.ProtocolTCP {
|
||||
return nil, fmt.Errorf("external load balancers for non TCP services are not currently supported.")
|
||||
}
|
||||
ports = append(ports, sp.Port)
|
||||
ports = append(ports, sp)
|
||||
}
|
||||
return ports, nil
|
||||
}
|
||||
|
||||
func portsEqual(x, y *api.Service) bool {
|
||||
xPorts, err := getTCPPorts(x)
|
||||
func portsEqualForLB(x, y *api.Service) bool {
|
||||
xPorts, err := getPortsForLB(x)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
yPorts, err := getTCPPorts(y)
|
||||
yPorts, err := getPortsForLB(y)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return intSlicesEqual(xPorts, yPorts)
|
||||
return portSlicesEqualForLB(xPorts, yPorts)
|
||||
}
|
||||
|
||||
func portSlicesEqualForLB(x, y []*api.ServicePort) bool {
|
||||
if len(x) != len(y) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range x {
|
||||
if !portEqualForLB(x[i], y[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func portEqualForLB(x, y *api.ServicePort) bool {
|
||||
// TODO: Should we check name? (In theory, an LB could expose it)
|
||||
if x.Name != y.Name {
|
||||
return false
|
||||
}
|
||||
|
||||
if x.Protocol != y.Protocol {
|
||||
return false
|
||||
}
|
||||
|
||||
if x.Port != y.Port {
|
||||
return false
|
||||
}
|
||||
|
||||
if x.NodePort != y.NodePort {
|
||||
return false
|
||||
}
|
||||
|
||||
// We don't check TargetPort; that is not relevant for load balancing
|
||||
// TODO: Should we blank it out? Or just check it anyway?
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func intSlicesEqual(x, y []int) bool {
|
||||
|
@@ -113,7 +113,7 @@ func TestCreateExternalLoadBalancer(t *testing.T) {
|
||||
t.Errorf("expected one load balancer to be created, got %v", cloud.Balancers)
|
||||
} else if cloud.Balancers[0].Name != controller.loadBalancerName(item.service) ||
|
||||
cloud.Balancers[0].Region != region ||
|
||||
cloud.Balancers[0].Ports[0] != item.service.Spec.Ports[0].Port {
|
||||
cloud.Balancers[0].Ports[0].Port != item.service.Spec.Ports[0].Port {
|
||||
t.Errorf("created load balancer has incorrect parameters: %v", cloud.Balancers[0])
|
||||
}
|
||||
actionFound := false
|
||||
|
Reference in New Issue
Block a user