package main import ( // Standard "fmt" "slices" "strings" ) type DNSRecord struct { ID string `json:".id"` Disabled string Dynamic string Name string TTL string Type string ParsedValue string // not from RouterOS, here to not having to have the value logics in frontend too. Address string CNAME string } type DNSEntry struct { ID string `json:".id"` Disabled string `json:"disabled"` Name string `json:"name"` TTL string `json:"ttl"` Type string `json:"type"` Address string `json:"address,omitempty"` CNAME string `json:"cname,omitempty"` } type DomainPart struct { Record []DNSRecord Subparts map[string]*DomainPart `json:",omitempty"` } type RecordsTree struct { Children []RecordsTree } func SortDNSRecord(a, b DNSRecord) int { aComponents := strings.Split(a.Name, ".") bComponents := strings.Split(b.Name, ".") slices.Reverse(aComponents) slices.Reverse(bComponents) for i, aComp := range aComponents { if i >= len(bComponents) { return -1 } bComp := bComponents[i] if aComp > bComp { return 1 } if aComp < bComp { return -1 } } return 0 } func (r DNSRecord) String() string { switch r.Type { case "A", "AAAA": return r.Address case "CNAME": return r.CNAME } return fmt.Sprintf("Implement type '%s'", r.Type) } func (r DNSRecord) Parts() int { return len(strings.Split(r.Name, ".")) } func (r DNSRecord) Part(numParts int) string { splitName := strings.Split(r.Name, ".") slices.Reverse(splitName) parts := []string{} for i := range numParts { if i >= len(splitName) { break } parts = append(parts, splitName[i]) } slices.Reverse(parts) return strings.Join(parts, ".") } func (r DNSRecord) NameReversed() string { parts := strings.Split(r.Name, ".") slices.Reverse(parts) return strings.Join(parts, ".") } func (r DNSRecord) toDNSEntry() (e DNSEntry) { e.ID = r.ID e.Disabled = r.Disabled e.Name = r.Name e.TTL = r.TTL e.Type = r.Type switch(r.Type) { case "A", "AAAA": e.Address = r.ParsedValue case "CNAME": e.CNAME = r.ParsedValue } return }