refactor: decompose Analyzer into recordPool and serviceAccumulator
Restructure the service analyzer architecture to improve maintainability: - Extract recordPool (zone records + mark-delete claiming) and serviceAccumulator (service registry + domain normalization) as embedded structs in Analyzer - Replace swap-delete with mark-delete to eliminate mutation-during-iteration - Centralize domain normalization using helpers.DomainRelative - Make Comment/NbResources lazy via Service.MarshalJSON instead of eager assignment at three separate call sites - Extract SPF merging from usecase layer into services.CollectAndMergeSPF - Add GetDefaultTTL accessor and comprehensive Analyzer doc comments - Add round-trip test infrastructure covering MX, CNAME, CAA, TXT, SPF, DMARC, GSuite, Origin, Server and more
This commit is contained in:
parent
6de814a247
commit
f4bcb1c9cf
10 changed files with 797 additions and 167 deletions
|
|
@ -23,7 +23,6 @@ package zone
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
|
|
@ -62,13 +61,6 @@ func (uc *ListRecordsUsecase) ToZoneFile(domain *happydns.Domain, zone *happydns
|
|||
func (uc *ListRecordsUsecase) List(domain *happydns.Domain, zone *happydns.Zone) (rrs []happydns.Record, err error) {
|
||||
var svc_rrs []happydns.Record
|
||||
|
||||
// Collect SPF contributions keyed by absolute domain name.
|
||||
type spfContrib struct {
|
||||
directives [][]string
|
||||
policies []string
|
||||
}
|
||||
spfContribs := map[string]*spfContrib{}
|
||||
|
||||
for _, services := range zone.Services {
|
||||
for _, svc := range services {
|
||||
svc_rrs, err = uc.serviceListRecordsUC.List(svc, domain.DomainName, zone.DefaultTTL)
|
||||
|
|
@ -76,45 +68,6 @@ func (uc *ListRecordsUsecase) List(domain *happydns.Domain, zone *happydns.Zone)
|
|||
return
|
||||
}
|
||||
|
||||
// If the service is an SPF contributor, collect its directives
|
||||
// and filter out any SPF TXT records it emits (they'll be
|
||||
// replaced by the merged record).
|
||||
if contributor, ok := svc.Service.(happydns.SPFContributor); ok {
|
||||
directives := contributor.GetSPFDirectives()
|
||||
policy := contributor.GetSPFAllPolicy()
|
||||
|
||||
// Compute the absolute domain for this service.
|
||||
absDomain := svc.Domain
|
||||
if domain.DomainName != "" {
|
||||
if absDomain == "" {
|
||||
absDomain = domain.DomainName
|
||||
} else {
|
||||
absDomain = absDomain + "." + domain.DomainName
|
||||
}
|
||||
}
|
||||
if !strings.HasSuffix(absDomain, ".") {
|
||||
absDomain += "."
|
||||
}
|
||||
|
||||
if spfContribs[absDomain] == nil {
|
||||
spfContribs[absDomain] = &spfContrib{}
|
||||
}
|
||||
spfContribs[absDomain].directives = append(spfContribs[absDomain].directives, directives)
|
||||
if policy != "" {
|
||||
spfContribs[absDomain].policies = append(spfContribs[absDomain].policies, policy)
|
||||
}
|
||||
|
||||
// Drop SPF TXT records from this service's output.
|
||||
filtered := svc_rrs[:0]
|
||||
for _, rr := range svc_rrs {
|
||||
if txt, ok := rr.(*happydns.TXT); ok && strings.HasPrefix(txt.Txt, "v=spf1") {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, rr)
|
||||
}
|
||||
svc_rrs = filtered
|
||||
}
|
||||
|
||||
rrs = append(rrs, svc_rrs...)
|
||||
}
|
||||
|
||||
|
|
@ -127,28 +80,8 @@ func (uc *ListRecordsUsecase) List(domain *happydns.Domain, zone *happydns.Zone)
|
|||
}
|
||||
}
|
||||
|
||||
// Emit one merged SPF TXT record per domain that has SPF contributions.
|
||||
for absDomain, contrib := range spfContribs {
|
||||
merged := svcs.MergeSPFDirectives(contrib.directives...)
|
||||
policy := svcs.ResolveSPFAllPolicy(contrib.policies)
|
||||
merged = append(merged, policy)
|
||||
|
||||
spfFields := svcs.SPFFields{
|
||||
Version: 1,
|
||||
Directives: merged,
|
||||
}
|
||||
|
||||
rr := &happydns.TXT{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: absDomain,
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: zone.DefaultTTL,
|
||||
},
|
||||
Txt: spfFields.String(),
|
||||
}
|
||||
rrs = append(rrs, rr)
|
||||
}
|
||||
// Collect SPF contributions and merge into single records per domain.
|
||||
rrs = svcs.CollectAndMergeSPF(domain.DomainName, zone, rrs, zone.DefaultTTL)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ func (uc *AddToZoneUsecase) AddService(zone *happydns.Zone, subdomain happydns.S
|
|||
|
||||
service.Id = hash
|
||||
service.Domain = string(subdomain)
|
||||
service.NbResources = service.Service.GetNbResources()
|
||||
service.Comment = service.Service.GenComment()
|
||||
|
||||
zone.Services[subdomain] = append(zone.Services[subdomain], service)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue