From 73ffe271484207f7da864c492b705791e831e287 Mon Sep 17 00:00:00 2001 From: Nick Sardo Date: Fri, 7 Apr 2017 17:16:51 -0700 Subject: [PATCH] safety checks --- controllers/gce/cmd/mode-updater/README.md | 8 +- controllers/gce/cmd/mode-updater/main.go | 92 +++++++++++++++++++--- 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/controllers/gce/cmd/mode-updater/README.md b/controllers/gce/cmd/mode-updater/README.md index c1540febe..025804ea6 100644 --- a/controllers/gce/cmd/mode-updater/README.md +++ b/controllers/gce/cmd/mode-updater/README.md @@ -56,10 +56,10 @@ go run main.go my-project us-central1 UTILIZATION - [ ] An active GLBC does not negatively interfere with this updater #### TODO -- [ ] If only one backend-service exists, just update it in place. -- [ ] If all backend-services are already the target balancing mode, early return. -- [ ] Use GCE CloudProvider package in order to utilize the `waitForOp` functionality in order to remove some sleeps. -- [ ] Adjust/remove warning +- [x] If only one backend-service exists, just update it in place. +- [x] If all backend-services are already the target balancing mode, early return. +- [ ] Wait for op completion instead of sleeping +- [ ] Adjust warning #### Warning This tool hasn't been fully tested. Use at your own risk. diff --git a/controllers/gce/cmd/mode-updater/main.go b/controllers/gce/cmd/mode-updater/main.go index 692d7f308..68166deb9 100644 --- a/controllers/gce/cmd/mode-updater/main.go +++ b/controllers/gce/cmd/mode-updater/main.go @@ -13,8 +13,6 @@ import ( "golang.org/x/oauth2/google" compute "google.golang.org/api/compute/v1" - "k8s.io/kubernetes/pkg/cloudprovider" - "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" ) var ( @@ -25,7 +23,6 @@ var ( instanceGroupName string s *compute.Service - g *gce.GCECloud zones []*compute.Zone igs map[string]*compute.InstanceGroup instances []*compute.Instance @@ -40,7 +37,7 @@ const ( ) func main() { - fmt.Println("Backend-Service BalancingMode Updater", "version:", version) + fmt.Println("Backend-Service BalancingMode Updater", version) //flag.Usage flag.Parse() @@ -78,12 +75,6 @@ func main() { panic(err) } - cloudInterface, err := cloudprovider.GetCloudProvider("gce", nil) - if err != nil { - panic(err) - } - g = cloudInterface.(*gce.GCECloud) - // Get Zones zoneFilter := fmt.Sprintf("(region eq %s)", createRegionLink(regionName)) zoneList, err := s.Zones.List(projectID).Filter(zoneFilter).Do() @@ -136,9 +127,41 @@ func main() { fmt.Println("Backend Services:", len(bs)) fmt.Println("Instance Groups:", len(igs)) + // Early return for special cases + switch len(bs) { + case 0: + fmt.Println("There are 0 backend services - no action necessary") + return + case 1: + updateSingleBackend(bs[0]) + return + } + + // Check there's work to be done + if typeOfBackends(bs) == targetBalancingMode { + fmt.Println("Backends are already set to target mode") + return + } + + // Check no orphan instance groups will throw us off + clusters := getIGClusterIds() + if len(clusters) != 1 { + fmt.Println("Expecting only cluster of instance groups in GCE, found", clusters) + return + } + + if true { + return + } + + // Performing update for 2+ backend services + updateMultipleBackends() +} + +func updateMultipleBackends() { // Create temoprary instance groups for zone, ig := range igs { - _, err = s.InstanceGroups.Get(projectID, zone, instanceGroupTemp).Do() + _, err := s.InstanceGroups.Get(projectID, zone, instanceGroupTemp).Do() if err != nil { newIg := &compute.InstanceGroup{ Name: instanceGroupTemp, @@ -153,6 +176,8 @@ func main() { } } + sleep(10 * time.Second) + // Straddle both groups fmt.Println("Straddle both groups in backend services") setBackendsTo(true, balancingModeInverse(targetBalancingMode), true, balancingModeInverse(targetBalancingMode)) @@ -186,7 +211,7 @@ func main() { fmt.Println("Delete temporary instance groups") for z := range igs { - _, err = s.InstanceGroups.Delete(projectID, z, instanceGroupTemp).Do() + _, err := s.InstanceGroups.Delete(projectID, z, instanceGroupTemp).Do() if err != nil { fmt.Println("Couldn't delete temporary instance group", instanceGroupTemp) } @@ -256,6 +281,13 @@ func getBackendServices() (bs []*compute.BackendService) { return bs } +func typeOfBackends(bs []*compute.BackendService) string { + if len(bs) == 0 { + return "" + } + return bs[0].Backends[0].BalancingMode +} + func migrateInstances(fromIG, toIG string) error { wg := sync.WaitGroup{} for _, i := range instances { @@ -305,3 +337,39 @@ func getResourceName(link string, resourceType string) string { } return "" } + +func updateSingleBackend(bs *compute.BackendService) { + needsUpdate := false + for _, b := range bs.Backends { + if b.BalancingMode != targetBalancingMode { + needsUpdate = true + b.BalancingMode = targetBalancingMode + } + } + + if !needsUpdate { + fmt.Println("Single backend had all targetBalancingMode - no change necessary") + return + } + + if _, err := s.BackendServices.Update(projectID, bs.Name, bs).Do(); err != nil { + panic(err) + } + fmt.Println("Updated single backend service to target balancing mode.") +} + +func getIGClusterIds() []string { + clusterIds := make(map[string]struct{}) + for _, ig := range igs { + s := strings.Split(ig.Name, "--") + if len(s) > 2 { + panic(fmt.Errorf("Expected two parts to instance group name, got %v", s)) + } + clusterIds[s[1]] = struct{}{} + } + var ids []string + for v, _ := range clusterIds { + ids = append(ids, v) + } + return ids +}