@@ -143,7 +143,7 @@ func (s *baseSecurityListManager) updateBackendRules(ctx context.Context, lbSubn
143143
144144// updateLoadBalancerRules handles updating the ingress and egress rules for the load balance subnets.
145145// If the listener is nil, then only egress rules from the load balancer to the backend subnets will be checked.
146- func (s * baseSecurityListManager ) updateLoadBalancerRules (ctx context.Context , lbSubnets []* core.Subnet , nodeSubnets []* core.Subnet , sourceCIDRs []string , ports portSpec ) error {
146+ func (s * baseSecurityListManager ) updateLoadBalancerRules (ctx context.Context , lbSubnets []* core.Subnet , nodeSubnets []* core.Subnet , sourceCIDRs []string , actualPorts * portSpec , desiredPorts portSpec ) error {
147147 for _ , lbSubnet := range lbSubnets {
148148 secList , etag , err := s .getSecurityList (ctx , lbSubnet )
149149 if err != nil {
@@ -152,12 +152,20 @@ func (s *baseSecurityListManager) updateLoadBalancerRules(ctx context.Context, l
152152
153153 logger := s .logger .With ("securityListID" , * secList .Id )
154154
155- lbEgressRules := getLoadBalancerEgressRules (logger , secList .EgressSecurityRules , nodeSubnets , ports .BackendPort , s .serviceLister )
156- lbEgressRules = getLoadBalancerEgressRules (logger , lbEgressRules , nodeSubnets , ports .HealthCheckerPort , s .serviceLister )
155+ // 0 denotes nil ports.
156+ var currentBackEndPort = 0
157+ var currentHealthCheck = 0
158+ if actualPorts != nil {
159+ currentBackEndPort = actualPorts .BackendPort
160+ currentHealthCheck = actualPorts .HealthCheckerPort
161+ }
162+
163+ lbEgressRules := getLoadBalancerEgressRules (logger , secList .EgressSecurityRules , nodeSubnets , currentBackEndPort , desiredPorts .BackendPort , s .serviceLister )
164+ lbEgressRules = getLoadBalancerEgressRules (logger , lbEgressRules , nodeSubnets , currentHealthCheck , desiredPorts .HealthCheckerPort , s .serviceLister )
157165
158166 lbIngressRules := secList .IngressSecurityRules
159- if ports .ListenerPort != 0 {
160- lbIngressRules = getLoadBalancerIngressRules (logger , lbIngressRules , sourceCIDRs , ports .ListenerPort , s .serviceLister )
167+ if desiredPorts .ListenerPort != 0 {
168+ lbIngressRules = getLoadBalancerIngressRules (logger , lbIngressRules , sourceCIDRs , desiredPorts .ListenerPort , s .serviceLister )
161169 }
162170
163171 if ! securityListRulesChanged (secList , lbIngressRules , lbEgressRules ) {
@@ -222,7 +230,7 @@ type defaultSecurityListManager struct {
222230// Egress rules added:
223231// from LB subnets to backend subnets on the backend port
224232func (s * defaultSecurityListManager ) Update (ctx context.Context , lbSubnets []* core.Subnet , backendSubnets []* core.Subnet , sourceCIDRs []string , actualPorts * portSpec , desiredPorts portSpec ) error {
225- if err := s .updateLoadBalancerRules (ctx , lbSubnets , backendSubnets , sourceCIDRs , desiredPorts ); err != nil {
233+ if err := s .updateLoadBalancerRules (ctx , lbSubnets , backendSubnets , sourceCIDRs , actualPorts , desiredPorts ); err != nil {
226234 return err
227235 }
228236
@@ -238,7 +246,7 @@ func (s *defaultSecurityListManager) Delete(ctx context.Context, lbSubnets []*co
238246 noSubnets := []* core.Subnet {}
239247 noSourceCIDRs := []string {}
240248
241- err := s .updateLoadBalancerRules (ctx , lbSubnets , noSubnets , noSourceCIDRs , ports )
249+ err := s .updateLoadBalancerRules (ctx , lbSubnets , noSubnets , noSourceCIDRs , & ports , ports )
242250 if err != nil {
243251 return err
244252 }
@@ -258,14 +266,14 @@ type frontendSecurityListManager struct {
258266// from source cidrs to lb subnets on the listener port
259267func (s * frontendSecurityListManager ) Update (ctx context.Context , lbSubnets []* core.Subnet , _ []* core.Subnet , sourceCIDRs []string , actualPorts * portSpec , desiredPorts portSpec ) error {
260268 noSubnets := []* core.Subnet {}
261- return s .updateLoadBalancerRules (ctx , lbSubnets , noSubnets , sourceCIDRs , desiredPorts )
269+ return s .updateLoadBalancerRules (ctx , lbSubnets , noSubnets , sourceCIDRs , actualPorts , desiredPorts )
262270}
263271
264272// Delete the ingress security list rules associated with the listener.
265273func (s * frontendSecurityListManager ) Delete (ctx context.Context , lbSubnets []* core.Subnet , backendSubnets []* core.Subnet , ports portSpec ) error {
266274 noSubnets := []* core.Subnet {}
267275 noSourceCIDRs := []string {}
268- return s .updateLoadBalancerRules (ctx , lbSubnets , noSubnets , noSourceCIDRs , ports )
276+ return s .updateLoadBalancerRules (ctx , lbSubnets , noSubnets , noSourceCIDRs , & ports , ports )
269277}
270278
271279// securityListManagerNOOP implements the securityListManager interface but does
@@ -352,6 +360,14 @@ func getNodeIngressRules(
352360 desiredPorts portSpec ,
353361 serviceLister listersv1.ServiceLister ,
354362) []core.IngressSecurityRule {
363+ // 0 denotes nil ports.
364+ var currentBackEndPort = 0
365+ var currentHealthCheckPort = 0
366+ if actualPorts != nil {
367+ currentBackEndPort = actualPorts .BackendPort
368+ currentHealthCheckPort = actualPorts .HealthCheckerPort
369+ }
370+
355371 desiredBackend := sets .NewString ()
356372 desiredHealthChecker := sets .NewString ()
357373 for _ , lbSubnet := range lbSubnets {
@@ -362,6 +378,23 @@ func getNodeIngressRules(
362378 ingressRules := []core.IngressSecurityRule {}
363379
364380 for _ , rule := range rules {
381+ // Remove (do not re-add) any rule that represents the old case when
382+ // mutating a single ranged backend port or health check port.
383+ if rule .TcpOptions != nil && rule .TcpOptions .DestinationPortRange != nil &&
384+ * rule .TcpOptions .DestinationPortRange .Min == * rule .TcpOptions .DestinationPortRange .Max &&
385+ * rule .TcpOptions .DestinationPortRange .Min != desiredPorts .BackendPort && * rule .TcpOptions .DestinationPortRange .Max != desiredPorts .BackendPort &&
386+ * rule .TcpOptions .DestinationPortRange .Min != desiredPorts .HealthCheckerPort && * rule .TcpOptions .DestinationPortRange .Max != desiredPorts .HealthCheckerPort {
387+ var rulePort = * rule .TcpOptions .DestinationPortRange .Min
388+ if rulePort == currentBackEndPort || rulePort == currentHealthCheckPort {
389+ logger .With (
390+ "source" , * rule .Source ,
391+ "destinationPortRangeMin" , * rule .TcpOptions .DestinationPortRange .Min ,
392+ "destinationPortRangeMax" , * rule .TcpOptions .DestinationPortRange .Max ,
393+ ).Debug ("Deleting load balancer ingres security rule" )
394+ continue
395+ }
396+ }
397+
365398 if rule .TcpOptions == nil || rule .TcpOptions .SourcePortRange != nil || rule .TcpOptions .DestinationPortRange == nil {
366399 // this rule doesn't apply to this service so nothing to do but keep it
367400 ingressRules = append (ingressRules , rule )
@@ -521,7 +554,7 @@ func getLoadBalancerEgressRules(
521554 logger * zap.SugaredLogger ,
522555 rules []core.EgressSecurityRule ,
523556 nodeSubnets []* core.Subnet ,
524- port int ,
557+ actualPort , desiredPort int ,
525558 serviceLister listersv1.ServiceLister ,
526559) []core.EgressSecurityRule {
527560 nodeCIDRs := sets .NewString ()
@@ -531,8 +564,21 @@ func getLoadBalancerEgressRules(
531564
532565 egressRules := []core.EgressSecurityRule {}
533566 for _ , rule := range rules {
567+ // Remove (do not re-add) any rule that represents the old case when mutating a single ranged port.
568+ if rule .TcpOptions != nil && rule .TcpOptions .DestinationPortRange != nil &&
569+ * rule .TcpOptions .DestinationPortRange .Min == * rule .TcpOptions .DestinationPortRange .Max &&
570+ * rule .TcpOptions .DestinationPortRange .Min != desiredPort && * rule .TcpOptions .DestinationPortRange .Max != desiredPort &&
571+ * rule .TcpOptions .DestinationPortRange .Min == actualPort && * rule .TcpOptions .DestinationPortRange .Max == actualPort {
572+ logger .With (
573+ "destination" , * rule .Destination ,
574+ "destinationPortRangeMin" , * rule .TcpOptions .DestinationPortRange .Min ,
575+ "destinationPortRangeMax" , * rule .TcpOptions .DestinationPortRange .Max ,
576+ ).Debug ("Deleting load balancer ingres security rule" )
577+ continue
578+ }
579+
534580 if rule .TcpOptions == nil || rule .TcpOptions .SourcePortRange != nil || rule .TcpOptions .DestinationPortRange == nil ||
535- * rule .TcpOptions .DestinationPortRange .Min != port || * rule .TcpOptions .DestinationPortRange .Max != port {
581+ * rule .TcpOptions .DestinationPortRange .Min != desiredPort || * rule .TcpOptions .DestinationPortRange .Max != desiredPort {
536582 // this rule doesn't apply to this service so nothing to do but keep it
537583 egressRules = append (egressRules , rule )
538584 continue
@@ -545,19 +591,19 @@ func getLoadBalancerEgressRules(
545591 continue
546592 }
547593
548- inUse , err := healthCheckPortInUse (serviceLister , int32 (port ))
594+ inUse , err := healthCheckPortInUse (serviceLister , int32 (desiredPort ))
549595 if err != nil {
550596 // Unable to determine if this port is in use by another service, so I guess
551597 // we better err on the safe side and keep the rule.
552- logger .With (zap .Error (err ), "port" , port ).Error ("Failed to determine if port is still in use" )
598+ logger .With (zap .Error (err ), "port" , desiredPort ).Error ("Failed to determine if port is still in use" )
553599 egressRules = append (egressRules , rule )
554600 continue
555601 }
556602
557603 if inUse {
558604 // This rule is no longer needed for this service, but is still used
559605 // by another service, so we must still keep it.
560- logger .With ("port" , port ).Debug ("Port still in use by another service." )
606+ logger .With ("port" , desiredPort ).Debug ("Port still in use by another service." )
561607 egressRules = append (egressRules , rule )
562608 continue
563609 }
@@ -579,7 +625,7 @@ func getLoadBalancerEgressRules(
579625 // All the remaining node cidr's are new and don't have a corresponding rule
580626 // so we need to create one for each.
581627 for _ , desired := range nodeCIDRs .List () {
582- rule := makeEgressSecurityRule (desired , port )
628+ rule := makeEgressSecurityRule (desired , desiredPort )
583629 logger .With (
584630 "destination" , * rule .Destination ,
585631 "destinationPortRangeMin" , * rule .TcpOptions .DestinationPortRange .Min ,
0 commit comments