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:
@@ -66,7 +66,7 @@ func setup(t *testing.T, actual []model.Record, tmpl dto.TemplateDoc) (*DomainSe
|
||||
reg.Register(fp)
|
||||
cipher := testCipher(t)
|
||||
enc, _ := cipher.Encrypt([]byte("secret"))
|
||||
loader := fakeLoader{ref: DomainRef{ZoneID: "z1", Provider: "selectel", SecretEnc: enc, Template: tmpl}}
|
||||
loader := fakeLoader{ref: DomainRef{ZoneID: "z1", ZoneName: "example.com.", Provider: "selectel", SecretEnc: enc, Template: tmpl}}
|
||||
return New(loader, nopRecorder{}, reg, cipher), fp
|
||||
}
|
||||
|
||||
@@ -85,6 +85,28 @@ func TestCheckProducesDiff(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCheckMaterializesDomainNamePlaceholder covers the tmpl.Materialize
|
||||
// wiring in resolve: a template record using {{domain_name}} in its name and
|
||||
// values must be diffed against the zone using the actual zone name (without
|
||||
// trailing dot) substituted in, so a template reused across domains reports
|
||||
// in-sync rather than spurious add/delete pairs.
|
||||
func TestCheckMaterializesDomainNamePlaceholder(t *testing.T) {
|
||||
actual := []model.Record{
|
||||
{Type: model.TXT, Name: "_dmarc.example.com.", TTL: 600, Values: []string{"v=DMARC1; p=quarantine"}},
|
||||
}
|
||||
tmpl := dto.TemplateDoc{Records: []dto.RecordDTO{
|
||||
{Type: "TXT", Name: "_dmarc.{{domain_name}}.", TTL: 600, Values: []string{"v=DMARC1; p=quarantine"}},
|
||||
}}
|
||||
svc, _ := setup(t, actual, tmpl)
|
||||
cs, err := svc.Check(context.Background(), uuid.New(), uuid.New())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(cs.Updates()) != 0 || len(cs.Prunes()) != 0 {
|
||||
t.Fatalf("expected placeholder materialized against zone name to be in sync, got updates=%+v prunes=%+v", cs.Updates(), cs.Prunes())
|
||||
}
|
||||
}
|
||||
|
||||
// TestZoneRecordsReadsProviderDirectly covers the no-template zone-viewing
|
||||
// path: ZoneRecords must return the provider's live records with no diff
|
||||
// and no template involved (loader's Template field is left zero-valued).
|
||||
|
||||
Reference in New Issue
Block a user