From 5e6d865794e91d2d2cf22d4e9ce5a346b913dd6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCrbach?= Date: Mon, 12 Mar 2018 22:03:01 +0100 Subject: [PATCH] AWS NLB: Support cross-zone load balancing annotation AWS Network Load Balancer recently got support for cross-zone load balancing. Use the existing `service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled` annotation to configure it. --- .../providers/aws/aws_loadbalancer.go | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go index 3242a057bc3..351088312b8 100644 --- a/pkg/cloudprovider/providers/aws/aws_loadbalancer.go +++ b/pkg/cloudprovider/providers/aws/aws_loadbalancer.go @@ -313,6 +313,64 @@ func (c *Cloud) ensureLoadBalancerv2(namespacedName types.NamespacedName, loadBa } } + desiredLoadBalancerAttributes := map[string]string{} + // Default values to ensured a remove annotation reverts back to the default + desiredLoadBalancerAttributes["load_balancing.cross_zone.enabled"] = "false" + + // Determine if cross zone load balancing enabled/disabled has been specified + crossZoneLoadBalancingEnabledAnnotation := annotations[ServiceAnnotationLoadBalancerCrossZoneLoadBalancingEnabled] + if crossZoneLoadBalancingEnabledAnnotation != "" { + crossZoneEnabled, err := strconv.ParseBool(crossZoneLoadBalancingEnabledAnnotation) + if err != nil { + return nil, fmt.Errorf("error parsing service annotation: %s=%s", + ServiceAnnotationLoadBalancerCrossZoneLoadBalancingEnabled, + crossZoneLoadBalancingEnabledAnnotation, + ) + } + + if crossZoneEnabled { + desiredLoadBalancerAttributes["load_balancing.cross_zone.enabled"] = "true" + } + } + + // Whether the ELB was new or existing, sync attributes regardless. This accounts for things + // that cannot be specified at the time of creation and can only be modified after the fact, + // e.g. idle connection timeout. + describeAttributesRequest := &elbv2.DescribeLoadBalancerAttributesInput{ + LoadBalancerArn: loadBalancer.LoadBalancerArn, + } + describeAttributesOutput, err := c.elbv2.DescribeLoadBalancerAttributes(describeAttributesRequest) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve load balancer attributes during attribute sync: %q", err) + } + + changedAttributes := []*elbv2.LoadBalancerAttribute{} + + // Identify to be changed attributes + for _, foundAttribute := range describeAttributesOutput.Attributes { + if targetValue, ok := desiredLoadBalancerAttributes[*foundAttribute.Key]; ok { + if targetValue != *foundAttribute.Value { + changedAttributes = append(changedAttributes, &elbv2.LoadBalancerAttribute{ + Key: foundAttribute.Key, + Value: aws.String(targetValue), + }) + } + } + } + + // Update attributes requiring changes + if len(changedAttributes) > 0 { + klog.V(2).Infof("Updating load-balancer attributes for %q", loadBalancerName) + + _, err = c.elbv2.ModifyLoadBalancerAttributes(&elbv2.ModifyLoadBalancerAttributesInput{ + LoadBalancerArn: loadBalancer.LoadBalancerArn, + Attributes: changedAttributes, + }) + if err != nil { + return nil, fmt.Errorf("Unable to update load balancer attributes during attribute sync: %q", err) + } + } + // Subnets cannot be modified on NLBs if dirty { loadBalancers, err := c.elbv2.DescribeLoadBalancers(