From 14e1c447c90a63913e9435e4cb09c2d44bfc46ba Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sun, 2 Jun 2024 23:20:56 +0000 Subject: [PATCH] cluster: assign valid rings.RegionID to each primary region Signed-off-by: Alejandro Mery --- pkg/cluster/env.go | 4 +-- pkg/cluster/regions.go | 71 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/pkg/cluster/env.go b/pkg/cluster/env.go index 0600dab..8af53fb 100644 --- a/pkg/cluster/env.go +++ b/pkg/cluster/env.go @@ -53,7 +53,7 @@ func (m *Env) Regions() []string { var regions []string m.ForEachRegion(func(r *Region) bool { - if r.Cluster != nil { + if r.IsPrimary() { regions = append(regions, r.Name) } @@ -166,7 +166,7 @@ func genEnvZoneRegion(z *Zone) string { var region string z.ForEachRegion(func(r *Region) bool { - if r.Cluster != nil { + if r.IsPrimary() { region = r.Name return true } diff --git a/pkg/cluster/regions.go b/pkg/cluster/regions.go index bf29137..d960e73 100644 --- a/pkg/cluster/regions.go +++ b/pkg/cluster/regions.go @@ -3,6 +3,8 @@ package cluster import ( "bytes" "path/filepath" + + "git.jpi.io/amery/jpictl/pkg/rings" ) var ( @@ -24,8 +26,15 @@ type Region struct { zones []*Zone Name string - Cluster *string `json:",omitempty" yaml:",omitempty"` - Regions []string `json:",omitempty" yaml:",omitempty"` + ID rings.RegionID `json:",omitempty" yaml:",omitempty"` + Cluster *string `json:",omitempty" yaml:",omitempty"` + Regions []string `json:",omitempty" yaml:",omitempty"` +} + +// IsPrimary indicates the region is primary and corresponds +// to a kubernetes cluster. +func (r *Region) IsPrimary() bool { + return r != nil && r.Cluster != nil } // ForEachRegion calls a function for each Region of the cluster @@ -92,6 +101,7 @@ func (m *Cluster) initRegions(_ *ScanOptions) error { } m.sortRegions() + m.scanRegionID() return nil } @@ -210,6 +220,63 @@ func (m *Cluster) finishRegion(r *Region) { r.Regions = sub } +// revive:disable:cognitive-complexity +func (m *Cluster) scanRegionID() { + // revive:enable:cognitive-complexity + var max rings.RegionID + var missing bool + + // check IDs + ids := make(map[rings.RegionID]bool) + fn := func(r *Region) bool { + var term bool + + switch { + case !r.IsPrimary(): + // secondary, no ID. + r.ID = 0 + case !r.ID.Valid(): + // primary without ID + missing = true + case ids[r.ID]: + // duplicate + m.error(nil).WithField("region", r.Name).Print("duplicate ID") + missing = true + r.ID = 0 + default: + ids[r.ID] = true + + if r.ID > max { + max = r.ID + } + } + + return term + } + m.ForEachRegion(fn) + + if missing { + // assign missing IDs + fn := func(r *Region) bool { + var term bool + + switch { + case !r.IsPrimary(): + // ignore secondary + case r.ID.Valid(): + // already has an ID + default: + r.ID = max + 1 + max = r.ID + } + + return term + } + + m.ForEachRegion(fn) + } +} + func (m *Cluster) getRegion(name string) (*Region, bool) { for i := range m.Regions { r := &m.Regions[i]