feat(tmpl): {{domain_name}} placeholder — materialize on diff/apply, parameterize on snapshot
Adds internal/tmpl with Materialize (template placeholder -> zone name) and Parameterize (zone name -> placeholder, the inverse used by the template-from-zone snapshot). service.resolve now materializes the template against DomainRef.ZoneName before diffing, so one template can be reused across domains. LoadDomainFull (source query + hand-edited sqlc output, since sqlc is not installed) now also selects zone_name to populate it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwxdSt4reTm7Dj1oxRvpP3
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package tmpl_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/vasyakrg/dns-autoresolver/internal/model"
|
||||
"github.com/vasyakrg/dns-autoresolver/internal/store/dto"
|
||||
"github.com/vasyakrg/dns-autoresolver/internal/tmpl"
|
||||
)
|
||||
|
||||
func TestMaterializeReplacesInNameAndValues(t *testing.T) {
|
||||
doc := dto.TemplateDoc{Records: []dto.RecordDTO{
|
||||
{Type: "TXT", Name: "_dmarc.{{domain_name}}.", TTL: 600, Values: []string{"v=DMARC1; p=quarantine"}},
|
||||
{Type: "MX", Name: "{{domain_name}}.", TTL: 600, Values: []string{"0 pmg2-mail.{{domain_name}}."}},
|
||||
{Type: "TXT", Name: "{{domain_name}}.", TTL: 600, Values: []string{"v=spf1 a:mail.{{domain_name}} ~all"}},
|
||||
}}
|
||||
recs := tmpl.Materialize(doc, "reconops.ru.") // trailing dot stripped
|
||||
if recs[0].Name != "_dmarc.reconops.ru." {
|
||||
t.Fatalf("name: %q", recs[0].Name)
|
||||
}
|
||||
if recs[1].Values[0] != "0 pmg2-mail.reconops.ru." {
|
||||
t.Fatalf("mx value: %q", recs[1].Values[0])
|
||||
}
|
||||
if recs[2].Values[0] != "v=spf1 a:mail.reconops.ru ~all" {
|
||||
t.Fatalf("spf value: %q", recs[2].Values[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestParameterizeIsInverseForZoneOccurrences(t *testing.T) {
|
||||
recs := []model.Record{
|
||||
{Type: "TXT", Name: "_dmarc.reconops.ru.", TTL: 600, Values: []string{"v=DMARC1"}},
|
||||
{Type: "TXT", Name: "reconops.ru.", TTL: 600, Values: []string{"v=spf1 a:mail.reconops.ru ~all"}},
|
||||
{Type: "CNAME", Name: "mail.reconops.ru.", TTL: 600, Values: []string{"amail.amega.kz."}}, // external host untouched
|
||||
}
|
||||
doc := tmpl.Parameterize(recs, "reconops.ru.")
|
||||
if doc.Records[0].Name != "_dmarc.{{domain_name}}." {
|
||||
t.Fatalf("name: %q", doc.Records[0].Name)
|
||||
}
|
||||
if doc.Records[1].Values[0] != "v=spf1 a:mail.{{domain_name}} ~all" {
|
||||
t.Fatalf("spf: %q", doc.Records[1].Values[0])
|
||||
}
|
||||
if doc.Records[2].Values[0] != "amail.amega.kz." {
|
||||
t.Fatalf("external cname value must be untouched: %q", doc.Records[2].Values[0])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user