From d63feacd91ad23c61c53c0465559ae9ad7c573e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Taneli=20Lepp=C3=A4?= Date: Fri, 6 Aug 2021 15:25:08 +0200 Subject: [PATCH] Added support for regional -flag in addition to region parameter, as suggested in #41. --- controllers/autoneg.go | 38 ++++++++++++++++++++++++------------- controllers/autoneg_test.go | 11 ++++++----- controllers/types.go | 6 ++++-- main.go | 20 ++++++++++++++++++- 4 files changed, 54 insertions(+), 21 deletions(-) diff --git a/controllers/autoneg.go b/controllers/autoneg.go index d6ed654..282e1d0 100644 --- a/controllers/autoneg.go +++ b/controllers/autoneg.go @@ -76,10 +76,11 @@ func (s AutonegStatus) Backend(name string, port string, group string) compute.B } // NewBackendController takes the project name and an initialized *compute.Service -func NewBackendController(project string, s *compute.Service) *BackendController { +func NewBackendController(project string, location string, s *compute.Service) *BackendController { return &BackendController{ - project: project, - s: s, + project: project, + location: location, + s: s, } } @@ -167,7 +168,7 @@ func checkOperation(op *compute.Operation) error { // ReconcileBackends takes the actual and intended AutonegStatus // and attempts to apply the intended status or return an error func (b *BackendController) ReconcileBackends(actual, intended AutonegStatus) (err error) { - removes, upserts := ReconcileStatus(b.project, actual, intended) + removes, upserts := ReconcileStatus(b.project, b.location, actual, intended) for port, _removes := range removes { for idx, remove := range _removes { @@ -242,7 +243,7 @@ func sortBackends(backends *[]compute.Backend) { // ReconcileStatus takes the actual and intended AutonegStatus // and returns sets of backends to remove, and to upsert -func ReconcileStatus(project string, actual AutonegStatus, intended AutonegStatus) (removes, upserts map[string]map[string]Backends) { +func ReconcileStatus(project string, location string, actual AutonegStatus, intended AutonegStatus) (removes, upserts map[string]map[string]Backends) { upserts = make(map[string]map[string]Backends, 0) removes = make(map[string]map[string]Backends, 0) @@ -279,7 +280,11 @@ func ReconcileStatus(project string, actual AutonegStatus, intended AutonegStatu groups := intendedBE[port] for bname, be := range intended.BackendServices[port] { - upsert := Backends{name: be.Name, region: be.Region} + region := be.Region + if be.Regional != nil && *be.Regional && region == "" { + region = location + } + upsert := Backends{name: be.Name, region: region} var groupsKeys []string for k := range groups { @@ -294,7 +299,7 @@ func ReconcileStatus(project string, actual AutonegStatus, intended AutonegStatu sortBackends(&upsert.backends) upserts[port][bname] = upsert - remove := Backends{name: be.Name, region: be.Region} + remove := Backends{name: be.Name, region: region} // test to see if we are changing backend services if _, ok := actual.BackendServices[port][bname]; ok { if actual.BackendServices[port][bname].Name == be.Name || actual.BackendServices[port][bname].Name == "" { @@ -309,8 +314,13 @@ func ReconcileStatus(project string, actual AutonegStatus, intended AutonegStatu removes[port][bname] = remove } else { // moving to a different backend service means removing all actual backends + aregion := actual.BackendServices[port][bname].Region + if actual.BackendServices[port][bname].Regional != nil && *actual.BackendServices[port][bname].Regional && aregion == "" { + aregion = location + } + remove.name = actual.BackendServices[port][bname].Name - remove.region = actual.BackendServices[port][bname].Region + remove.region = aregion for a := range actualBE[port] { rbe := actual.Backend(bname, port, a) remove.backends = append(remove.backends, rbe) @@ -321,7 +331,7 @@ func ReconcileStatus(project string, actual AutonegStatus, intended AutonegStatu } else { // add empty remove if adding to a mint backend service remove.name = intended.BackendServices[port][bname].Name - remove.region = intended.BackendServices[port][bname].Region + remove.region = region removes[port][bname] = remove } } @@ -330,9 +340,11 @@ func ReconcileStatus(project string, actual AutonegStatus, intended AutonegStatu for aname := range actual.BackendServices[port] { if _, ok := intended.BackendServices[port][aname]; !ok { be := actual.BackendServices[port][aname] - remove := Backends{name: be.Name, region: be.Region} - remove.name = actual.BackendServices[port][aname].Name - remove.region = actual.BackendServices[port][aname].Region + bregion := be.Region + if be.Regional != nil && *be.Regional && bregion == "" { + bregion = location + } + remove := Backends{name: be.Name, region: bregion} for a := range actualBE[port] { rbe := actual.Backend(aname, port, a) remove.backends = append(remove.backends, rbe) @@ -340,7 +352,7 @@ func ReconcileStatus(project string, actual AutonegStatus, intended AutonegStatu sortBackends(&remove.backends) removes[port][aname] = remove - upsert := Backends{name: be.Name, region: be.Region} + upsert := Backends{name: be.Name, region: bregion} upserts[port][aname] = upsert } } diff --git a/controllers/autoneg_test.go b/controllers/autoneg_test.go index ad3875a..37dda40 100644 --- a/controllers/autoneg_test.go +++ b/controllers/autoneg_test.go @@ -281,10 +281,11 @@ func (b Backends) isEqual(ob Backends) bool { } var ( - fakeNeg = "neg_name" - fakeNeg2 = "neg_name2" - fakeProject = "project" - negStatus = NEGStatus{ + fakeNeg = "neg_name" + fakeNeg2 = "neg_name2" + fakeProject = "project" + fakeLocation = "europe-west4-c" + negStatus = NEGStatus{ NEGs: map[string]string{"80": fakeNeg}, Zones: []string{"zone1", "zone2"}, } @@ -494,7 +495,7 @@ var reconcileTests = []struct { func TestReconcileStatuses(t *testing.T) { for _, rt := range reconcileTests { - removes, upserts := ReconcileStatus(fakeProject, rt.actual, rt.intended) + removes, upserts := ReconcileStatus(fakeProject, fakeLocation, rt.actual, rt.intended) for port := range rt.removes { if _, ok := removes[port]; !ok { t.Errorf("Set %q: Removed port %s backends: expected:\n%+v\n got missing key %+v", rt.name, port, rt.removes[port], port) diff --git a/controllers/types.go b/controllers/types.go index 290ef21..00540cc 100644 --- a/controllers/types.go +++ b/controllers/types.go @@ -47,6 +47,7 @@ type AutonegConfigTemp struct { type AutonegNEGConfig struct { Name string `json:"name,omitempty"` Region string `json:"region,omitempty"` + Regional *bool `json:"regional,omitempty"` Rate float64 `json:"max_rate_per_endpoint,omitempty"` Connections float64 `json:"max_connections_per_endpoint,omitempty"` } @@ -85,8 +86,9 @@ type Backends struct { // BackendController manages operations on a GCLB backend service type BackendController struct { - project string - s *compute.Service + project string + location string + s *compute.Service } // NEGConfig specifies the configuration stored in diff --git a/main.go b/main.go index 0a695e5..86f12f2 100644 --- a/main.go +++ b/main.go @@ -73,6 +73,12 @@ func main() { os.Exit(1) } + location := getLocation() + if location == "" { + setupLog.Error(err, "can't determine cluster location") + os.Exit(1) + } + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsAddr, @@ -85,7 +91,7 @@ func main() { if err = (&controllers.ServiceReconciler{ Client: mgr.GetClient(), - BackendController: controllers.NewBackendController(project, s), + BackendController: controllers.NewBackendController(project, location, s), Recorder: mgr.GetEventRecorderFor("autoneg-controller"), Log: ctrl.Log.WithName("controllers").WithName("Service"), }).SetupWithManager(mgr); err != nil { @@ -109,3 +115,15 @@ func getProject() string { } return os.Getenv("PROJECT_ID") } + +func getLocation() string { + // probe metadata service for cluster location, or return empty + p, err := metadata.InstanceAttributeValue("cluster-location") + if err == nil { + if p[len(p)-2] == '-' { // zonal cluster + return p[0 : len(p)-2] + } + return p + } + return "" +}