@@ -94,10 +94,13 @@ func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v
9494 return nil , err
9595 }
9696
97- ports , _ , protocol := getPortsAndProtocol (svc .Spec .Ports )
98- if protocol != v1 .ProtocolTCP && protocol != v1 .ProtocolUDP {
99- return nil , fmt .Errorf ("Invalid protocol %s, only TCP and UDP are supported" , string (protocol ))
97+ groupedPorts := getPortsAndProtocols (svc .Spec .Ports )
98+ for protocol := range groupedPorts {
99+ if protocol != v1 .ProtocolTCP && protocol != v1 .ProtocolUDP {
100+ return nil , fmt .Errorf ("Invalid protocol %s, only TCP and UDP are supported" , string (protocol ))
101+ }
100102 }
103+
101104 scheme := cloud .SchemeInternal
102105 options := getILBOptions (svc )
103106 if g .IsLegacyNetwork () {
@@ -106,7 +109,7 @@ func (g *Cloud) ensureInternalLoadBalancer(clusterName, clusterID string, svc *v
106109 }
107110
108111 sharedBackend := shareBackendService (svc )
109- backendServiceName := makeBackendServiceName (loadBalancerName , clusterID , sharedBackend , scheme , protocol , svc .Spec .SessionAffinity )
112+ backendServiceName := makeBackendServiceName (loadBalancerName , clusterID , sharedBackend , scheme , groupedPorts , svc .Spec .SessionAffinity )
110113 backendServiceLink := g .getBackendServiceLink (backendServiceName )
111114
112115 // Ensure instance groups exist and nodes are assigned to groups
@@ -359,10 +362,10 @@ func (g *Cloud) updateInternalLoadBalancer(clusterName, clusterID string, svc *v
359362 }
360363
361364 // Generate the backend service name
362- _ , _ , protocol := getPortsAndProtocol (svc .Spec .Ports )
365+ groupedPorts := getPortsAndProtocols (svc .Spec .Ports )
363366 scheme := cloud .SchemeInternal
364367 loadBalancerName := g .GetLoadBalancerName (context .TODO (), clusterName , svc )
365- backendServiceName := makeBackendServiceName (loadBalancerName , clusterID , shareBackendService (svc ), scheme , protocol , svc .Spec .SessionAffinity )
368+ backendServiceName := makeBackendServiceName (loadBalancerName , clusterID , shareBackendService (svc ), scheme , groupedPorts , svc .Spec .SessionAffinity )
366369 // Ensure the backend service has the proper backend/instance-group links
367370 return g .ensureInternalBackendServiceGroups (backendServiceName , igLinks )
368371}
@@ -383,7 +386,7 @@ func (g *Cloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID string,
383386
384387 loadBalancerName := g .GetLoadBalancerName (context .TODO (), clusterName , svc )
385388 svcNamespacedName := types.NamespacedName {Name : svc .Name , Namespace : svc .Namespace }
386- _ , _ , protocol := getPortsAndProtocol (svc .Spec .Ports )
389+ groupedPorts := getPortsAndProtocols (svc .Spec .Ports )
387390 scheme := cloud .SchemeInternal
388391 sharedBackend := shareBackendService (svc )
389392 sharedHealthCheck := ! servicehelpers .RequestsOnlyLocalTraffic (svc )
@@ -399,7 +402,7 @@ func (g *Cloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID string,
399402 return err
400403 }
401404
402- backendServiceName := makeBackendServiceName (loadBalancerName , clusterID , sharedBackend , scheme , protocol , svc .Spec .SessionAffinity )
405+ backendServiceName := makeBackendServiceName (loadBalancerName , clusterID , sharedBackend , scheme , groupedPorts , svc .Spec .SessionAffinity )
403406 klog .V (2 ).Infof ("ensureInternalLoadBalancerDeleted(%v): deleting region backend service %v" , loadBalancerName , backendServiceName )
404407 if err := g .teardownInternalBackendService (backendServiceName ); err != nil {
405408 return err
@@ -495,7 +498,7 @@ func (g *Cloud) teardownInternalHealthCheckAndFirewall(svc *v1.Service, hcName s
495498 return nil
496499}
497500
498- func (g * Cloud ) ensureInternalFirewall (svc * v1.Service , fwName , fwDesc , destinationIP string , sourceRanges []string , portRanges [] string , protocol v1.Protocol , nodes []* v1.Node , legacyFwName string ) error {
501+ func (g * Cloud ) ensureInternalFirewall (svc * v1.Service , fwName , fwDesc , destinationIP string , sourceRanges []string , groupedPorts map [ v1.Protocol ] ProtocolPorts , nodes []* v1.Node , legacyFwName string ) error {
499502 klog .V (2 ).Infof ("ensureInternalFirewall(%v): checking existing firewall" , fwName )
500503 targetTags , err := g .GetNodeTags (nodeNames (nodes ))
501504 if err != nil {
@@ -536,12 +539,13 @@ func (g *Cloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc, destinat
536539 Network : g .networkURL ,
537540 SourceRanges : sourceRanges ,
538541 TargetTags : targetTags ,
539- Allowed : []* compute.FirewallAllowed {
540- {
541- IPProtocol : strings .ToLower (string (protocol )),
542- Ports : portRanges ,
543- },
544- },
542+ }
543+
544+ for protocol , protocolPorts := range groupedPorts {
545+ expectedFirewall .Allowed = append (expectedFirewall .Allowed , & compute.FirewallAllowed {
546+ IPProtocol : strings .ToLower (string (protocol )),
547+ Ports : protocolPorts .portRanges ,
548+ })
545549 }
546550
547551 if destinationIP != "" {
@@ -576,12 +580,12 @@ func (g *Cloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc, destinat
576580func (g * Cloud ) ensureInternalFirewalls (loadBalancerName , ipAddress , clusterID string , nm types.NamespacedName , svc * v1.Service , healthCheckPort string , sharedHealthCheck bool , nodes []* v1.Node ) error {
577581 // First firewall is for ingress traffic
578582 fwDesc := makeFirewallDescription (nm .String (), ipAddress )
579- _ , portRanges , protocol := getPortsAndProtocol (svc .Spec .Ports )
583+ groupedPorts := getPortsAndProtocols (svc .Spec .Ports )
580584 sourceRanges , err := servicehelpers .GetLoadBalancerSourceRanges (svc )
581585 if err != nil {
582586 return err
583587 }
584- err = g .ensureInternalFirewall (svc , MakeFirewallName (loadBalancerName ), fwDesc , ipAddress , sourceRanges .StringSlice (), portRanges , protocol , nodes , loadBalancerName )
588+ err = g .ensureInternalFirewall (svc , MakeFirewallName (loadBalancerName ), fwDesc , ipAddress , sourceRanges .StringSlice (), groupedPorts , nodes , loadBalancerName )
585589 if err != nil {
586590 return err
587591 }
@@ -957,20 +961,28 @@ func backendSvcEqual(a, b *compute.BackendService) bool {
957961 backendsListEqual (a .Backends , b .Backends )
958962}
959963
960- func getPortsAndProtocol (svcPorts []v1.ServicePort ) (ports []string , portRanges []string , protocol v1.Protocol ) {
964+ type ProtocolPorts struct {
965+ ports []int
966+ portRanges []string
967+ }
968+
969+ func getPortsAndProtocols (svcPorts []v1.ServicePort ) map [v1.Protocol ]ProtocolPorts {
961970 if len (svcPorts ) == 0 {
962- return [] string {}, [] string {}, v1 . ProtocolUDP
971+ return nil
963972 }
964973
965- // GCP doesn't support multiple protocols for a single load balancer
966- protocol = svcPorts [0 ].Protocol
967- portInts := []int {}
974+ m := make (map [v1.Protocol ]ProtocolPorts )
968975 for _ , p := range svcPorts {
969- ports = append (ports , strconv .Itoa (int (p .Port )))
970- portInts = append (portInts , int (p .Port ))
976+ ports := m [p .Protocol ]
977+ ports .ports = append (ports .ports , int (p .Port ))
978+ }
979+
980+ for protocol , ports := range m {
981+ ports .portRanges = getPortRanges (ports .ports )
982+ m [protocol ] = ports
971983 }
972984
973- return ports , getPortRanges ( portInts ), protocol
985+ return m
974986}
975987
976988func getPortRanges (ports []int ) (ranges []string ) {
0 commit comments