package dns import ( "fmt" "net/netip" "sort" "time" "darvaza.org/core" "github.com/libdns/libdns" ) // SortAddrSlice ... func SortAddrSlice(s []netip.Addr) []netip.Addr { sort.Slice(s, func(i, j int) bool { return s[i].Less(s[j]) }) return s } // AddrRecord represents an A or AAAA record type AddrRecord struct { Name string Addr []netip.Addr } // Sort sorts the addresses of the record func (rr *AddrRecord) Sort() { SortAddrSlice(rr.Addr) } // Export converts the record into libdns.Record func (rr *AddrRecord) Export() []libdns.Record { out := make([]libdns.Record, len(rr.Addr)) for i, addr := range rr.Addr { out[i] = libdns.Record{ Name: rr.Name, TTL: time.Second * 1, Type: core.IIf(addr.Is6(), "AAAA", "A"), Value: addr.String(), } } return out } func (mgr *Manager) genAllAddrRecords() []AddrRecord { var out []AddrRecord cache := make(map[string][]netip.Addr) // zones for _, z := range mgr.zones { // machines s := mgr.genZoneMachineRecords(z) out = append(out, s...) // zone alias addrs := mgr.genZoneAddresses(z) name := z.Name out = append(out, AddrRecord{ Name: name + mgr.suffix, Addr: addrs, }) // and cache for regions cache[name] = addrs } // regions for name, zones := range mgr.regions { var addrs []netip.Addr for _, z := range zones { addrs = append(addrs, cache[z]...) } rec := AddrRecord{ Name: name + mgr.suffix, Addr: addrs, } rec.Sort() out = append(out, rec) } // sort sort.Slice(out, func(i, j int) bool { return out[i].Name < out[j].Name }) return out } func (*Manager) genZoneAddresses(z *Zone) []netip.Addr { var out []netip.Addr for _, p := range z.Machines { if p.Active { out = append(out, p.Addrs...) } } SortAddrSlice(out) return out } func (mgr *Manager) genZoneMachineRecords(z *Zone) []AddrRecord { out := make([]AddrRecord, 0, len(z.Machines)) for _, p := range z.Machines { rec := AddrRecord{ Name: fmt.Sprintf("%s-%v%s", z.Name, p.ID, mgr.suffix), Addr: p.Addrs, } out = append(out, rec) } return out }