From e315c350bea3e651aff75cb336617d5d533f3dab Mon Sep 17 00:00:00 2001 From: Kashif Saadat Date: Tue, 16 Jan 2018 15:43:30 +0000 Subject: [PATCH] Implement ability to update Load Balancer subnets --- hack/.packages | 1 + upup/pkg/fi/cloudup/awstasks/load_balancer.go | 25 +++++++++++- util/pkg/slice/slice.go | 40 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 util/pkg/slice/slice.go diff --git a/hack/.packages b/hack/.packages index e66581f4e4..038ec84fda 100644 --- a/hack/.packages +++ b/hack/.packages @@ -160,6 +160,7 @@ k8s.io/kops/upup/pkg/kutil k8s.io/kops/upup/tools/generators/fitask k8s.io/kops/upup/tools/generators/pkg/codegen k8s.io/kops/util/pkg/hashing +k8s.io/kops/util/pkg/slice k8s.io/kops/util/pkg/tables k8s.io/kops/util/pkg/ui k8s.io/kops/util/pkg/vfs diff --git a/upup/pkg/fi/cloudup/awstasks/load_balancer.go b/upup/pkg/fi/cloudup/awstasks/load_balancer.go index a39de1c61c..0292267b6b 100644 --- a/upup/pkg/fi/cloudup/awstasks/load_balancer.go +++ b/upup/pkg/fi/cloudup/awstasks/load_balancer.go @@ -31,6 +31,7 @@ import ( "k8s.io/kops/upup/pkg/fi/cloudup/awsup" "k8s.io/kops/upup/pkg/fi/cloudup/cloudformation" "k8s.io/kops/upup/pkg/fi/cloudup/terraform" + "k8s.io/kops/util/pkg/slice" ) // LoadBalancer manages an ELB. We find the existing ELB using the Name tag. @@ -527,7 +528,29 @@ func (_ *LoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *LoadBalan actualSubnets = append(actualSubnets, fi.StringValue(s.ID)) } - return fmt.Errorf("subnet changes on LoadBalancer not yet implemented: actual=%s -> expected=%s", actualSubnets, expectedSubnets) + oldSubnetIDs := slice.GetUniqueStrings(expectedSubnets, actualSubnets) + if len(oldSubnetIDs) > 0 { + request := &elb.DetachLoadBalancerFromSubnetsInput{} + request.SetLoadBalancerName(loadBalancerName) + request.SetSubnets(aws.StringSlice(oldSubnetIDs)) + + glog.V(2).Infof("Detaching Load Balancer from old subnets") + if _, err := t.Cloud.ELB().DetachLoadBalancerFromSubnets(request); err != nil { + return fmt.Errorf("Error detaching Load Balancer from old subnets: %v", err) + } + } + + newSubnetIDs := slice.GetUniqueStrings(actualSubnets, expectedSubnets) + if len(newSubnetIDs) > 0 { + request := &elb.AttachLoadBalancerToSubnetsInput{} + request.SetLoadBalancerName(loadBalancerName) + request.SetSubnets(aws.StringSlice(newSubnetIDs)) + + glog.V(2).Infof("Attaching Load Balancer to new subnets") + if _, err := t.Cloud.ELB().AttachLoadBalancerToSubnets(request); err != nil { + return fmt.Errorf("Error attaching Load Balancer to new subnets: %v", err) + } + } } if changes.Listeners != nil { diff --git a/util/pkg/slice/slice.go b/util/pkg/slice/slice.go new file mode 100644 index 0000000000..9d9c709cd9 --- /dev/null +++ b/util/pkg/slice/slice.go @@ -0,0 +1,40 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package slice provides utility methods for common operations on slices. +package slice + +// GetUniqueStrings returns a slice of strings in the extra slice that are not +// present in the main slice +func GetUniqueStrings(main, extra []string) []string { + unique := []string{} + + for _, item := range extra { + found := false + + for _, s := range main { + if item == s { + found = true + } + } + + if !found { + unique = append(unique, item) + } + } + + return unique +}