// Package zones contains information about the cluster package zones import ( "io/fs" "os" "darvaza.org/resolver" ) // Zone represents one zone in a cluster type Zone struct { zones *Zones ID int Name string Machines []*Machine `toml:"machines"` } func (z *Zone) String() string { return z.Name } // ForEachMachine calls a function for each Machine in the zone // until instructed to terminate the loop func (z *Zone) ForEachMachine(fn func(*Machine) bool) { for _, p := range z.Machines { if fn(p) { return } } } // Zones represents all zones in a cluster type Zones struct { dir fs.FS resolver resolver.Resolver domain string Zones []*Zone `toml:"zones"` } // 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 } // NewFS builds a [Zones] tree using the given directory func NewFS(dir fs.FS, domain string) (*Zones, error) { lockuper := resolver.NewCloudflareLookuper() z := &Zones{ dir: dir, resolver: resolver.NewResolver(lockuper), domain: domain, } if err := z.scan(); err != nil { return nil, err } return z, nil } // New builds a [Zones] tree using the given directory func New(dir, domain string) (*Zones, error) { return NewFS(os.DirFS(dir), domain) }