4 changed files with 94 additions and 3 deletions
			
			
		@ -0,0 +1,88 @@
					 | 
				
			||||
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 | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue