|
|
|
package cluster
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io/fs"
|
|
|
|
|
|
|
|
"git.jpi.io/amery/jpictl/pkg/rings"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ MachineIterator = (*Zone)(nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
// A ZoneIterator is a set of Zones we can iterate on
|
|
|
|
type ZoneIterator interface {
|
|
|
|
ForEachZone(func(*Zone) bool)
|
|
|
|
}
|
|
|
|
|
|
|
|
// A Zone is a set of machines in close proximity and strong
|
|
|
|
// affinity.
|
|
|
|
type Zone struct {
|
|
|
|
zones *Cluster
|
|
|
|
region *Region
|
|
|
|
logger `json:"-" yaml:"-"`
|
|
|
|
|
|
|
|
ID rings.ZoneID
|
|
|
|
Name string
|
|
|
|
Regions []string `json:",omitempty" yaml:",omitempty"`
|
|
|
|
|
|
|
|
Machines
|
|
|
|
}
|
|
|
|
|
|
|
|
func (z *Zone) String() string {
|
|
|
|
return z.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetGateway configures a machine to be the zone's ring0 gateway
|
|
|
|
func (z *Zone) SetGateway(gatewayID rings.NodeID, enabled bool) error {
|
|
|
|
var err error
|
|
|
|
var found bool
|
|
|
|
|
|
|
|
z.ForEachMachine(func(p *Machine) bool {
|
|
|
|
if p.ID == gatewayID {
|
|
|
|
found = true
|
|
|
|
err = p.SetGateway(enabled)
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case err != nil:
|
|
|
|
return err
|
|
|
|
case !found:
|
|
|
|
return fs.ErrNotExist
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GatewayIDs returns the list of IDs of machines that act as ring0 gateways
|
|
|
|
func (z *Zone) GatewayIDs() ([]rings.NodeID, int) {
|
|
|
|
var out []rings.NodeID
|
|
|
|
z.ForEachMachine(func(p *Machine) bool {
|
|
|
|
if p.IsGateway() {
|
|
|
|
out = append(out, p.ID)
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
|
|
|
return out, len(out)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegionID returns the primary [Region] of a [Zone].
|
|
|
|
func (z *Zone) RegionID() rings.RegionID {
|
|
|
|
if z != nil && z.region != nil {
|
|
|
|
return z.region.ID
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Is checks if the given [rings.RegionID] and [rings.ZoneID] match
|
|
|
|
// the [Zone].
|
|
|
|
func (z *Zone) Is(regionID rings.RegionID, zoneID rings.ZoneID) bool {
|
|
|
|
switch {
|
|
|
|
case z.ID != zoneID:
|
|
|
|
return false
|
|
|
|
case z.RegionID() != regionID:
|
|
|
|
return false
|
|
|
|
default:
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Eq checks if two [Zone]s are the same.
|
|
|
|
func (z *Zone) Eq(z2 *Zone) bool {
|
|
|
|
switch {
|
|
|
|
case z == nil, z2 == nil:
|
|
|
|
return false
|
|
|
|
case z.ID != z2.ID:
|
|
|
|
return false
|
|
|
|
case z.RegionID() != z2.RegionID():
|
|
|
|
return false
|
|
|
|
default:
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|