|
|
|
@ -3,6 +3,8 @@ package cluster
|
|
|
|
|
import ( |
|
|
|
|
"bytes" |
|
|
|
|
"path/filepath" |
|
|
|
|
|
|
|
|
|
"git.jpi.io/amery/jpictl/pkg/rings" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
@ -24,10 +26,17 @@ type Region struct {
|
|
|
|
|
zones []*Zone |
|
|
|
|
|
|
|
|
|
Name string |
|
|
|
|
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
|
|
|
|
|
// until instructed to terminate the loop
|
|
|
|
|
func (m *Cluster) ForEachRegion(fn func(r *Region) bool) { |
|
|
|
@ -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] |
|
|
|
|