diff --git a/handler.go b/handler.go index 2cc7b5f..9f369a5 100644 --- a/handler.go +++ b/handler.go @@ -51,3 +51,4 @@ func (l Ldap) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i // Name implements the Handler interface. func (l Ldap) Name() string { return "ldap" } + diff --git a/handler_test.go b/handler_test.go new file mode 100644 index 0000000..1c0e6f6 --- /dev/null +++ b/handler_test.go @@ -0,0 +1,67 @@ +package ldap + +import ( + "context" + "testing" + + "github.com/coredns/coredns/plugin/file" + "github.com/coredns/coredns/plugin/pkg/dnstest" + "github.com/coredns/coredns/plugin/pkg/fall" + "github.com/coredns/coredns/plugin/test" + + "github.com/miekg/dns" +) + +var ldapTestCases = []test.Case{ + { + // Simple case + Qname: "a.example.org.", Qtype: dns.TypeA, + Answer: []dns.RR{ + test.A("a.example.org." + defaultA), + }, + }, +} + +// Create a new Ldap Plugin. Use the test.ErrorHandler as the next plugin. +func newTestLdap() *Ldap { + ldap := New([]string{"example.org.", "www.example.org.", "example.org.", "sample.example.org."}) + ldap.Zones.Z = newTestLdapZones() + ldap.Fall = fall.Zero + ldap.Next = test.ErrorHandler() + return ldap +} + +func newTestLdapZones() map[string]*file.Zone { + Zone := file.NewZone("example.org.", "") + Zone.Insert(SOA("example.org.")) + for _, rr := range []string{"example.org. " + defaultA} { + r, _ := dns.NewRR(rr) + Zone.Insert(r) + } + zones := make(map[string]*file.Zone) + zones["example.org."] = Zone + return zones +} + +func TestServeDNS(t *testing.T) { + ldap := newTestLdap() + for i, tc := range ldapTestCases { + req := tc.Msg() + rec := dnstest.NewRecorder(&test.ResponseWriter{}) + _, err := ldap.ServeDNS(context.Background(), rec, req) + if err != nil { + t.Errorf("Expected no error, got %v", err) + continue + } + resp := rec.Msg + if resp == nil { + t.Fatalf("Test %d, got nil message and no error for %q", i, req.Question[0].Name) + } + if err := test.SortAndCheck(resp, tc); err != nil { + t.Error(err) + + } + } +} + +const defaultA = " 3600 IN A 1.2.3.4" diff --git a/ldap.go b/ldap.go index 6cffd3c..ace5be4 100644 --- a/ldap.go +++ b/ldap.go @@ -85,3 +85,27 @@ func (l *Ldap) InitClient() (err error) { return nil } + +// SOA returns a syntetic SOA record for a zone. +func SOA(zone string) (dns.RR) { + ttl := uint32(300) + header := dns.RR_Header{Name: zone, Rrtype: dns.TypeSOA, Ttl: ttl, Class: dns.ClassINET} + + Mbox := hostmaster + "." + Ns := "ns.dns." + if zone[0] != '.' { + Mbox += zone + Ns += zone + } + + return &dns.SOA{Hdr: header, + Mbox: Mbox, + Ns: Ns, + Serial: 12345, + Refresh: 7200, + Retry: 1800, + Expire: 86400, + Minttl: ttl, + } +} +const hostmaster = "hostmaster" diff --git a/ldap_test.go b/ldap_test.go deleted file mode 100644 index 66215d1..0000000 --- a/ldap_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package ldap - -import ( - "bytes" - "context" - "testing" - - "github.com/coredns/coredns/plugin/pkg/dnstest" - "github.com/coredns/coredns/plugin/test" - - "github.com/miekg/dns" -) - -func TestLdap(t *testing.T) { - // Create a new Ldap Plugin. Use the test.ErrorHandler as the next plugin. - x := Ldap{Next: test.ErrorHandler()} - - // Setup a new output buffer that is *not* standard output, so we can check if - // ldap is really being printed. - b := &bytes.Buffer{} - out = b - - ctx := context.TODO() - r := new(dns.Msg) - r.SetQuestion("ldap.org.", dns.TypeA) - // Create a new Recorder that captures the result, this isn't actually used in this test - // as it just serves as something that implements the dns.ResponseWriter interface. - rec := dnstest.NewRecorder(&test.ResponseWriter{}) - - // Call our plugin directly, and check the result. - x.ServeDNS(ctx, rec, r) - if a := b.String(); a != "ldap\n" { - t.Errorf("Failed to print '%s', got %s", ldap, a) - } -} diff --git a/setup_test.go b/setup_test.go index b20f09d..2779d73 100644 --- a/setup_test.go +++ b/setup_test.go @@ -9,13 +9,24 @@ import ( // TestSetup tests the various things that should be parsed by setup. // Make sure you also test for parse errors. func TestSetup(t *testing.T) { - c := caddy.NewTestController("dns", `ldap`) - if err := setup(c); err != nil { - t.Fatalf("Expected no errors, but got: %v", err) + tests := []struct { + body string + expectedError bool + }{ + {`ldap`, false}, + {`ldap :`, true}, + {`ldap { + ldap_url ldap://example.com + base_dn ou=ae-dir + filter (objectClass=aeNwDevice) + attributes aeFqdn ipHostNumber + sasl +}`, false}, } - - c = caddy.NewTestController("dns", `ldap more`) - if err := setup(c); err == nil { - t.Fatalf("Expected errors, but got: %v", err) + for i, test := range tests { + c := caddy.NewTestController("dns", test.body) + if _, err := ldapParse(c); (err == nil) == test.expectedError { + t.Fatalf("Unexpected errors: %v in test: %d\n\t%s", err, i, test.body) + } } } diff --git a/sync.go b/sync.go index 8e1cb85..5985d27 100644 --- a/sync.go +++ b/sync.go @@ -48,6 +48,7 @@ func (l *Ldap) updateZones(ctx context.Context) error { if zoneFileMap[zn] == nil { zoneFileMap[zn] = file.NewZone(zn, "") zoneFileMap[zn].Upstream = l.Upstream + zoneFileMap[zn].Insert(SOA(zn)) } for _, lr := range lrpz { zoneFileMap[zn].Insert(lr.A()) diff --git a/vendor/github.com/coredns/coredns/plugin/test/helpers.go b/vendor/github.com/coredns/coredns/plugin/test/helpers.go index eff5ed5..dddba0c 100644 --- a/vendor/github.com/coredns/coredns/plugin/test/helpers.go +++ b/vendor/github.com/coredns/coredns/plugin/test/helpers.go @@ -266,7 +266,7 @@ func CNAMEOrder(res *dns.Msg) error { // SortAndCheck sorts resp and the checks the header and three sections against the testcase in tc. func SortAndCheck(resp *dns.Msg, tc Case) error { - sort.Sort(RRSet(resp.Answer)) + sort.Sort(RRSet(resp.Answer)) sort.Sort(RRSet(resp.Ns)) sort.Sort(RRSet(resp.Extra))