You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
1.5 KiB
89 lines
1.5 KiB
1 year ago
|
package cluster
|
||
|
|
||
|
// Region represents a group of zones geographically related
|
||
|
type Region struct {
|
||
|
m *Cluster
|
||
|
zones []*Zone
|
||
|
|
||
|
Name string
|
||
|
Regions []string `json:",omitempty" yaml:",omitempty"`
|
||
|
}
|
||
|
|
||
|
func (m *Cluster) initRegions(_ *ScanOptions) error {
|
||
|
regions := make(map[string][]*Zone)
|
||
|
|
||
|
// first regions defined by zones
|
||
|
m.ForEachZone(func(z *Zone) bool {
|
||
|
for _, region := range z.Regions {
|
||
|
regions[region] = append(regions[region], z)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
|
||
|
// bind first level regions and their zones
|
||
|
for name, zones := range regions {
|
||
|
m.syncRegions(name, zones...)
|
||
|
}
|
||
|
|
||
|
// and combine zones to produce larger regions
|
||
|
for i := range m.Regions {
|
||
|
r := &m.Regions[i]
|
||
|
m.finishRegion(r)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (m *Cluster) syncRegions(name string, zones ...*Zone) {
|
||
|
for _, r := range m.Regions {
|
||
|
if r.Name == name {
|
||
|
// found
|
||
|
r.m = m
|
||
|
r.zones = zones
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// new
|
||
|
m.Regions = append(m.Regions, Region{
|
||
|
m: m,
|
||
|
zones: zones,
|
||
|
Name: name,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func (m *Cluster) finishRegion(r *Region) {
|
||
|
if r.m != nil {
|
||
|
// ready
|
||
|
return
|
||
|
}
|
||
|
|
||
|
r.m = m
|
||
|
sub := []string{}
|
||
|
for _, name := range r.Regions {
|
||
|
r2, ok := m.getRegion(name)
|
||
|
if !ok {
|
||
|
m.warn(nil).WithField("region", name).Print("unknown region")
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
sub = append(sub, r2.Name)
|
||
|
r.zones = append(r.zones, r2.zones...)
|
||
|
}
|
||
|
r.Regions = sub
|
||
|
}
|
||
|
|
||
|
func (m *Cluster) getRegion(name string) (*Region, bool) {
|
||
|
for i := range m.Regions {
|
||
|
r := &m.Regions[i]
|
||
|
|
||
|
if name == r.Name {
|
||
|
m.finishRegion(r)
|
||
|
return r, true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil, false
|
||
|
}
|