package cluster import ( "io/fs" "darvaza.org/resolver" "darvaza.org/slog" "github.com/gofrs/uuid/v5" ) var ( _ MachineIterator = (*Zone)(nil) _ MachineIterator = (*Zones)(nil) _ ZoneIterator = (*Zones)(nil) ) // A ZoneIterator is a set of Zones we can iterate on type ZoneIterator interface { ForEachZone(func(*Zone) bool) } // Zone represents one zone in a cluster type Zone struct { zones *Zones logger `json:"-" yaml:"-"` ID int Name string 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 int, 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() ([]int, int) { var out []int z.ForEachMachine(func(p *Machine) bool { if p.IsGateway() { out = append(out, p.ID) } return false }) return out, len(out) } // revive:disable:line-length-limit // Zones represents all zones in a cluster type Zones struct { dir fs.FS log slog.Logger resolver resolver.Resolver domain string CephFSID uuid.UUID `json:"ceph_fsid,omitempty" yaml:"ceph_fsid,omitempty"` Zones []*Zone } // revive:enable:line-length-limit // ForEachMachine calls a function for each Machine in the cluster // until instructed to terminate the loop func (m *Zones) ForEachMachine(fn func(*Machine) bool) { m.ForEachZone(func(z *Zone) bool { var term bool z.ForEachMachine(func(p *Machine) bool { term = fn(p) return term }) return term }) } // ForEachZone calls a function for each Zone in the cluster // until instructed to terminate the loop func (m *Zones) ForEachZone(fn func(*Zone) bool) { for _, p := range m.Zones { if fn(p) { // terminate return } } } // GetMachineByName looks for a machine with the specified // name on any zone func (m *Zones) GetMachineByName(name string) (*Machine, bool) { var out *Machine if name != "" { m.ForEachMachine(func(p *Machine) bool { if p.Name == name { out = p } return out != nil }) } return out, out != nil }