Progress in chaos (more)
This commit is contained in:
parent
a64423ce00
commit
a290a448ef
77
handler.go
77
handler.go
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
|
"github.com/coredns/coredns/plugin/file"
|
||||||
"github.com/coredns/coredns/request"
|
"github.com/coredns/coredns/request"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
@ -11,69 +12,39 @@ import (
|
|||||||
|
|
||||||
// ServeDNS implements the plugin.Handler interface.
|
// ServeDNS implements the plugin.Handler interface.
|
||||||
func (l Ldap) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
func (l Ldap) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
||||||
opt := plugin.Options{}
|
// opt := plugin.Options{}
|
||||||
state := request.Request{W: w, Req: r}
|
state := request.Request{W: w, Req: r}
|
||||||
|
|
||||||
zone := plugin.Zones(l.Zones).Matches(state.Name())
|
zone := plugin.Zones(l.Zones.Names).Matches(state.Name())
|
||||||
if zone == "" {
|
if zone == "" {
|
||||||
return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r)
|
return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r)
|
||||||
}
|
}
|
||||||
var (
|
Zone, ok := l.Zones.Z[zone]
|
||||||
records []dns.RR
|
if !ok || Zone == nil {
|
||||||
extra []dns.RR
|
return dns.RcodeServerFailure, nil
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
switch state.QType() {
|
|
||||||
case dns.TypeA:
|
|
||||||
records, err = plugin.A(ctx, l, zone, state, nil, opt)
|
|
||||||
case dns.TypeAAAA:
|
|
||||||
records, err = plugin.AAAA(ctx, l, zone, state, nil, opt)
|
|
||||||
case dns.TypeTXT:
|
|
||||||
records, err = plugin.TXT(ctx, l, zone, state, nil, opt)
|
|
||||||
case dns.TypeCNAME:
|
|
||||||
records, err = plugin.CNAME(ctx, l, zone, state, opt)
|
|
||||||
case dns.TypePTR:
|
|
||||||
records, err = plugin.PTR(ctx, l, zone, state, opt)
|
|
||||||
case dns.TypeMX:
|
|
||||||
records, extra, err = plugin.MX(ctx, l, zone, state, opt)
|
|
||||||
case dns.TypeSRV:
|
|
||||||
records, extra, err = plugin.SRV(ctx, l, zone, state, opt)
|
|
||||||
case dns.TypeSOA:
|
|
||||||
records, err = plugin.SOA(ctx, l, zone, state, opt)
|
|
||||||
case dns.TypeNS:
|
|
||||||
if state.Name() == zone {
|
|
||||||
records, extra, err = plugin.NS(ctx, l, zone, state, opt)
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
fallthrough
|
var result file.Result
|
||||||
default:
|
|
||||||
// Do a fake A lookup, so we can distinguish between NODATA and NXDOMAIN
|
|
||||||
_, err = plugin.A(ctx, l, zone, state, nil, opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
if l.IsNameError(err) {
|
|
||||||
if l.Fall.Through(state.Name()) {
|
|
||||||
return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r)
|
|
||||||
}
|
|
||||||
// Make err nil when returning here, so we don't log spam for NXDOMAIN.
|
|
||||||
return plugin.BackendError(ctx, &l, zone, dns.RcodeNameError, state, nil /* err */, opt)
|
|
||||||
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return plugin.BackendError(ctx, &l, zone, dns.RcodeServerFailure, state, err, opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(records) == 0 {
|
|
||||||
return plugin.BackendError(ctx, &l, zone, dns.RcodeSuccess, state, err, opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetReply(r)
|
m.SetReply(r)
|
||||||
m.Authoritative = true
|
m.Authoritative = true
|
||||||
m.Answer = append(m.Answer, records...)
|
l.zMu.RLock()
|
||||||
m.Extra = append(m.Extra, extra...)
|
m.Answer, m.Ns, m.Extra, result = Zone.Lookup(ctx, state, state.Name())
|
||||||
|
l.zMu.RUnlock()
|
||||||
|
|
||||||
|
if len(m.Answer) == 0 && result != file.NoData && l.Fall.Through(state.Name()) {
|
||||||
|
return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case file.Success:
|
||||||
|
case file.NoData:
|
||||||
|
case file.NameError:
|
||||||
|
m.Rcode = dns.RcodeNameError
|
||||||
|
case file.Delegation:
|
||||||
|
m.Authoritative = false
|
||||||
|
case file.ServerFailure:
|
||||||
|
return dns.RcodeServerFailure, nil
|
||||||
|
}
|
||||||
w.WriteMsg(m)
|
w.WriteMsg(m)
|
||||||
return dns.RcodeSuccess, nil
|
return dns.RcodeSuccess, nil
|
||||||
}
|
}
|
||||||
|
77
ldap.go
77
ldap.go
@ -14,9 +14,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"net"
|
||||||
|
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
"github.com/coredns/coredns/plugin/etcd/msg"
|
"github.com/coredns/coredns/plugin/etcd/msg"
|
||||||
|
"github.com/coredns/coredns/plugin/file"
|
||||||
"github.com/coredns/coredns/plugin/pkg/fall"
|
"github.com/coredns/coredns/plugin/pkg/fall"
|
||||||
"github.com/coredns/coredns/plugin/pkg/upstream"
|
"github.com/coredns/coredns/plugin/pkg/upstream"
|
||||||
"github.com/coredns/coredns/request"
|
"github.com/coredns/coredns/request"
|
||||||
@ -25,13 +27,22 @@ import (
|
|||||||
"gopkg.in/ldap.v3"
|
"gopkg.in/ldap.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ldapRecord struct {
|
||||||
|
fqdn string
|
||||||
|
ip net.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ldapRecord) A() (A *dns.A) {
|
||||||
|
return &dns.A{Hdr: dns.RR_Header{Name: r.fqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}, A: r.ip}
|
||||||
|
}
|
||||||
|
|
||||||
// Ldap is an ldap plugin to serve zone entries from a ldap backend.
|
// Ldap is an ldap plugin to serve zone entries from a ldap backend.
|
||||||
type Ldap struct {
|
type Ldap struct {
|
||||||
Next plugin.Handler
|
Next plugin.Handler
|
||||||
Fall fall.F
|
Fall fall.F
|
||||||
Zones []string
|
|
||||||
Upstream *upstream.Upstream
|
Upstream *upstream.Upstream
|
||||||
Client ldap.Client
|
Client ldap.Client
|
||||||
|
Zones file.Zones
|
||||||
|
|
||||||
searchRequest *ldap.SearchRequest
|
searchRequest *ldap.SearchRequest
|
||||||
ldapURL string
|
ldapURL string
|
||||||
@ -40,22 +51,25 @@ type Ldap struct {
|
|||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
sasl bool
|
sasl bool
|
||||||
|
fqdnAttr string
|
||||||
|
ip4Attr string
|
||||||
zMu sync.RWMutex
|
zMu sync.RWMutex
|
||||||
|
ttl time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns an initialized Ldap with defaults.
|
// New returns an initialized Ldap with defaults.
|
||||||
func New(zones []string) *Ldap {
|
func New(zoneNames []string) *Ldap {
|
||||||
k := new(Ldap)
|
l := new(Ldap)
|
||||||
k.Zones = zones
|
l.Zones.Names = zoneNames
|
||||||
k.pagingLimit = 0
|
l.pagingLimit = 0
|
||||||
// SearchRequest defaults
|
// SearchRequest defaults
|
||||||
k.searchRequest = new(ldap.SearchRequest)
|
l.searchRequest = new(ldap.SearchRequest)
|
||||||
k.searchRequest.DerefAliases = ldap.NeverDerefAliases // TODO: Reason
|
l.searchRequest.DerefAliases = ldap.NeverDerefAliases // TODO: Reason
|
||||||
k.searchRequest.Scope = ldap.ScopeWholeSubtree // search whole subtree
|
l.searchRequest.Scope = ldap.ScopeWholeSubtree // search whole subtree
|
||||||
k.searchRequest.SizeLimit = 500 // TODO: Reason
|
l.searchRequest.SizeLimit = 500 // TODO: Reason
|
||||||
k.searchRequest.TimeLimit = 500 // TODO: Reason
|
l.searchRequest.TimeLimit = 500 // TODO: Reason
|
||||||
k.searchRequest.TypesOnly = false // TODO: Reason
|
l.searchRequest.TypesOnly = false // TODO: Reason
|
||||||
return k
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -75,42 +89,3 @@ func (l *Ldap) InitClient() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Services implements the ServiceBackend interface.
|
|
||||||
func (l *Ldap) Services(ctx context.Context, state request.Request, exact bool, opt plugin.Options) (services []msg.Service, err error) {
|
|
||||||
services, err = l.Records(ctx, state, exact)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
services = msg.Group(services)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse implements the ServiceBackend interface.
|
|
||||||
func (l *Ldap) Reverse(ctx context.Context, state request.Request, exact bool, opt plugin.Options) (services []msg.Service, err error) {
|
|
||||||
return l.Services(ctx, state, exact, opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup implements the ServiceBackend interface.
|
|
||||||
func (l *Ldap) Lookup(ctx context.Context, state request.Request, name string, typ uint16) (*dns.Msg, error) {
|
|
||||||
return l.Upstream.Lookup(ctx, state, name, typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNameError implements the ServiceBackend interface.
|
|
||||||
func (l *Ldap) IsNameError(err error) bool {
|
|
||||||
return err == errNoItems || err == errNsNotExposed || err == errInvalidRequest
|
|
||||||
}
|
|
||||||
|
|
||||||
// Records looks up records in ldap. If exact is true, it will lookup just this
|
|
||||||
// name. This is used when find matches when completing SRV lookups for instance.
|
|
||||||
func (l *Ldap) Records(ctx context.Context, state request.Request, exact bool) ([]msg.Service, error) {
|
|
||||||
name := state.Name()
|
|
||||||
|
|
||||||
path, star := msg.PathWithWildcard(name, l.PathPrefix)
|
|
||||||
r, err := l.get(ctx, path, !exact)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
segments := strings.Split(msg.Path(name, l.PathPrefix), "/")
|
|
||||||
return l.loopNodes(r.Kvs, segments, star, state.QType())
|
|
||||||
}
|
|
||||||
|
63
setup.go
63
setup.go
@ -3,6 +3,7 @@ package ldap
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/coredns/coredns/core/dnsserver"
|
"github.com/coredns/coredns/core/dnsserver"
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
@ -79,21 +80,19 @@ func ldapParse(c *caddy.Controller) (*Ldap, error) {
|
|||||||
|
|
||||||
// ParseStanza parses a ldap stanza
|
// ParseStanza parses a ldap stanza
|
||||||
func ParseStanza(c *caddy.Controller) (*Ldap, error) {
|
func ParseStanza(c *caddy.Controller) (*Ldap, error) {
|
||||||
ldap := New([]string{""})
|
zoneNames := c.RemainingArgs()
|
||||||
zones := c.RemainingArgs()
|
if len(zoneNames) != 0 {
|
||||||
|
for i := 0; i < len(zoneNames); i++ {
|
||||||
if len(zones) != 0 {
|
zoneNames[i] = plugin.Host(zoneNames[i]).Normalize()
|
||||||
ldap.Zones = zones
|
|
||||||
for i := 0; i < len(ldap.Zones); i++ {
|
|
||||||
ldap.Zones[i] = plugin.Host(ldap.Zones[i]).Normalize()
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ldap.Zones = make([]string, len(c.ServerBlockKeys))
|
zoneNames = make([]string, len(c.ServerBlockKeys))
|
||||||
for i := 0; i < len(c.ServerBlockKeys); i++ {
|
for i := 0; i < len(zoneNames); i++ {
|
||||||
ldap.Zones[i] = plugin.Host(c.ServerBlockKeys[i]).Normalize()
|
zoneNames[i] = plugin.Host(c.ServerBlockKeys[i]).Normalize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldap := New(zoneNames)
|
||||||
ldap.Upstream = upstream.New()
|
ldap.Upstream = upstream.New()
|
||||||
|
|
||||||
for c.NextBlock() {
|
for c.NextBlock() {
|
||||||
@ -105,39 +104,69 @@ func ParseStanza(c *caddy.Controller) (*Ldap, error) {
|
|||||||
continue
|
continue
|
||||||
case "paging_limit":
|
case "paging_limit":
|
||||||
c.NextArg()
|
c.NextArg()
|
||||||
pagingLimit, err := strconv.Atoi(c.Val())
|
pagingLimit, err := strconv.ParseUint(c.Val(), 10, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
}
|
}
|
||||||
ldap.pagingLimit = pagingLimit
|
ldap.pagingLimit = uint32(pagingLimit)
|
||||||
continue
|
continue
|
||||||
case "search_request":
|
|
||||||
for c.NextBlock() {
|
|
||||||
switch c.Val() {
|
|
||||||
case "base_dn":
|
case "base_dn":
|
||||||
c.NextArg() // ou=ae-dir
|
c.NextArg() // ou=ae-dir
|
||||||
ldap.searchRequest.BaseDN = c.Val()
|
ldap.searchRequest.BaseDN = c.Val()
|
||||||
|
continue
|
||||||
case "filter":
|
case "filter":
|
||||||
c.NextArg() // (objectClass=aeNwDevice)
|
c.NextArg() // (objectClass=aeNwDevice)
|
||||||
ldap.searchRequest.Filter = c.Val()
|
ldap.searchRequest.Filter = c.Val()
|
||||||
|
continue
|
||||||
case "attributes":
|
case "attributes":
|
||||||
ldap.searchRequest.Attributes = c.RemainingArgs() // aeFqdn ipHostNumber
|
for c.NextBlock() {
|
||||||
|
switch c.Val() {
|
||||||
|
case "fqdn":
|
||||||
|
c.NextArg() // aeFqdn
|
||||||
|
ldap.searchRequest.Attributes = append(ldap.searchRequest.Attributes, c.Val())
|
||||||
|
ldap.fqdnAttr = c.Val()
|
||||||
|
continue
|
||||||
|
case "ip4":
|
||||||
|
c.NextArg() // ipHostNumber
|
||||||
|
ldap.searchRequest.Attributes = append(ldap.searchRequest.Attributes, c.Val())
|
||||||
|
ldap.ip4Attr = c.Val()
|
||||||
|
continue
|
||||||
default:
|
default:
|
||||||
return nil, c.Errf("unknown search request property '%s'", c.Val())
|
return nil, c.Errf("unknown attributes property '%s'", c.Val())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
case "username":
|
case "username":
|
||||||
c.NextArg()
|
c.NextArg()
|
||||||
ldap.username = c.Val()
|
ldap.username = c.Val()
|
||||||
|
continue
|
||||||
case "password":
|
case "password":
|
||||||
c.NextArg()
|
c.NextArg()
|
||||||
ldap.password = c.Val()
|
ldap.password = c.Val()
|
||||||
|
continue
|
||||||
case "sasl":
|
case "sasl":
|
||||||
c.NextArg()
|
c.NextArg()
|
||||||
ldap.sasl = true
|
ldap.sasl = true
|
||||||
|
continue
|
||||||
|
case "ttl":
|
||||||
|
c.NextArg()
|
||||||
|
ttl, err := time.ParseDuration(c.Val())
|
||||||
|
if err != nil {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
ldap.ttl = ttl
|
||||||
|
continue
|
||||||
|
case "sync_interval":
|
||||||
|
c.NextArg()
|
||||||
|
syncInterval, err := time.ParseDuration(c.Val())
|
||||||
|
if err != nil {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
ldap.syncInterval = syncInterval
|
||||||
|
continue
|
||||||
case "fallthrough":
|
case "fallthrough":
|
||||||
ldap.Fall.SetZonesFromArgs(c.RemainingArgs())
|
ldap.Fall.SetZonesFromArgs(c.RemainingArgs())
|
||||||
|
continue
|
||||||
default:
|
default:
|
||||||
return nil, c.Errf("unknown property '%s'", c.Val())
|
return nil, c.Errf("unknown property '%s'", c.Val())
|
||||||
}
|
}
|
||||||
|
158
sync.go
158
sync.go
@ -3,15 +3,14 @@ package ldap
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coredns/coredns/plugin"
|
"github.com/coredns/coredns/plugin"
|
||||||
"github.com/coredns/coredns/plugin/file"
|
"github.com/coredns/coredns/plugin/file"
|
||||||
"github.com/coredns/coredns/request"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Run updates the zone from ldap.
|
// Run updates the zone from ldap.
|
||||||
func (l *Ldap) Run(ctx context.Context) error {
|
func (l *Ldap) Run(ctx context.Context) error {
|
||||||
if err := l.updateZones(ctx); err != nil {
|
if err := l.updateZones(ctx); err != nil {
|
||||||
@ -23,7 +22,7 @@ func (l *Ldap) Run(ctx context.Context) error {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
log.Infof("Breaking out of Ldap update loop: %v", ctx.Err())
|
log.Infof("Breaking out of Ldap update loop: %v", ctx.Err())
|
||||||
return
|
return
|
||||||
case <-time.After(l.syncInterval * time.Second):
|
case <-time.After(l.syncInterval):
|
||||||
if err := l.updateZones(ctx); err != nil && ctx.Err() == nil {
|
if err := l.updateZones(ctx); err != nil && ctx.Err() == nil {
|
||||||
log.Errorf("Failed to update zones: %v", err)
|
log.Errorf("Failed to update zones: %v", err)
|
||||||
}
|
}
|
||||||
@ -34,117 +33,62 @@ func (l *Ldap) Run(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Ldap) updateZones(ctx context.Context) error {
|
func (l *Ldap) updateZones(ctx context.Context) error {
|
||||||
var err error
|
zoneFileMap := make(map[string]*file.Zone, len(l.Zones.Names))
|
||||||
var zoneFile file.Zone
|
for _, zn := range l.Zones.Names {
|
||||||
|
zoneFileMap[zn] = nil
|
||||||
valuePairs, err := getValuePairs()
|
|
||||||
for _, z := range l.Zones {
|
|
||||||
zoneFile = file.NewZone(z, "")
|
|
||||||
zoneFile.Upstream = l.Upstream
|
|
||||||
l.zMu.Lock()
|
|
||||||
(*z[i]).z = zoneFile
|
|
||||||
l.zMu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
ldapRecords, err := l.fetchLdapRecords()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error updating zones: %v", err)
|
return fmt.Errorf("updating zones: %w", err)
|
||||||
}
|
}
|
||||||
|
for zn, lrpz := range l.mapLdapRecordsToZone(ldapRecords) {
|
||||||
|
if lrpz == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if zoneFileMap[zn] == nil {
|
||||||
|
zoneFileMap[zn] = file.NewZone(zn, "")
|
||||||
|
zoneFileMap[zn].Upstream = l.Upstream
|
||||||
|
}
|
||||||
|
for _, lr := range lrpz {
|
||||||
|
zoneFileMap[zn].Insert(lr.A())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
l.zMu.Lock()
|
||||||
|
for zn, zf := range zoneFileMap {
|
||||||
|
(*l.Zones.Z[zn]) = *zf
|
||||||
|
}
|
||||||
|
l.zMu.Unlock()
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Ldap) getValuePairs() (valuePairs *[][]string, err error) {
|
func (l *Ldap) mapLdapRecordsToZone(ldapRecords []ldapRecord) (ldapRecordsPerZone map[string][]ldapRecord) {
|
||||||
|
lrpz := make(map[string][]ldapRecord, len(l.Zones.Names))
|
||||||
|
for _, zn := range l.Zones.Names {
|
||||||
|
lrpz[zn] = nil
|
||||||
|
}
|
||||||
|
for _, lr := range ldapRecords {
|
||||||
|
zone := plugin.Zones(l.Zones.Names).Matches(lr.fqdn)
|
||||||
|
if zone != "" {
|
||||||
|
lrpz[zone] = append(lrpz[zone], lr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lrpz
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Ldap) fetchLdapRecords() (ldapRecords []ldapRecord, err error) {
|
||||||
searchResult, err := l.Client.SearchWithPaging(l.searchRequest, l.pagingLimit)
|
searchResult, err := l.Client.SearchWithPaging(l.searchRequest, l.pagingLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error fetching data from ldap server: %w", err)
|
return nil, fmt.Errorf("fetching data from server: %w", err)
|
||||||
|
}
|
||||||
|
ldapRecords = make([]ldapRecord, len(searchResult.Entries))
|
||||||
|
for i, _ := range ldapRecords {
|
||||||
|
ldapRecords[i] = ldapRecord{
|
||||||
|
fqdn: searchResult.Entries[i].GetAttributeValue(l.fqdnAttr),
|
||||||
|
ip: net.ParseIP(searchResult.Entries[i].GetAttributeValue(l.ip4Attr)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ldapRecords, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateZoneFromPublicResourceSet(recordSet publicdns.RecordSetListResultPage, zName string) *file.Zone {
|
|
||||||
zoneFile := file.NewZone(zName, "")
|
|
||||||
|
|
||||||
for _, result := range *(recordSet.Response().Value) {
|
|
||||||
resultFqdn := *(result.RecordSetProperties.Fqdn)
|
|
||||||
resultTTL := uint32(*(result.RecordSetProperties.TTL))
|
|
||||||
if result.RecordSetProperties.ARecords != nil {
|
|
||||||
for _, A := range *(result.RecordSetProperties.ARecords) {
|
|
||||||
a := &dns.A{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
A: net.ParseIP(*(A.Ipv4Address))}
|
|
||||||
zoneFile.Insert(a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.AaaaRecords != nil {
|
|
||||||
for _, AAAA := range *(result.RecordSetProperties.AaaaRecords) {
|
|
||||||
aaaa := &dns.AAAA{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
AAAA: net.ParseIP(*(AAAA.Ipv6Address))}
|
|
||||||
zoneFile.Insert(aaaa)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.MxRecords != nil {
|
|
||||||
for _, MX := range *(result.RecordSetProperties.MxRecords) {
|
|
||||||
mx := &dns.MX{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
Preference: uint16(*(MX.Preference)),
|
|
||||||
Mx: dns.Fqdn(*(MX.Exchange))}
|
|
||||||
zoneFile.Insert(mx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.PtrRecords != nil {
|
|
||||||
for _, PTR := range *(result.RecordSetProperties.PtrRecords) {
|
|
||||||
ptr := &dns.PTR{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
Ptr: dns.Fqdn(*(PTR.Ptrdname))}
|
|
||||||
zoneFile.Insert(ptr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.SrvRecords != nil {
|
|
||||||
for _, SRV := range *(result.RecordSetProperties.SrvRecords) {
|
|
||||||
srv := &dns.SRV{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
Priority: uint16(*(SRV.Priority)),
|
|
||||||
Weight: uint16(*(SRV.Weight)),
|
|
||||||
Port: uint16(*(SRV.Port)),
|
|
||||||
Target: dns.Fqdn(*(SRV.Target))}
|
|
||||||
zoneFile.Insert(srv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.TxtRecords != nil {
|
|
||||||
for _, TXT := range *(result.RecordSetProperties.TxtRecords) {
|
|
||||||
txt := &dns.TXT{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
Txt: *(TXT.Value)}
|
|
||||||
zoneFile.Insert(txt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.NsRecords != nil {
|
|
||||||
for _, NS := range *(result.RecordSetProperties.NsRecords) {
|
|
||||||
ns := &dns.NS{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
Ns: *(NS.Nsdname)}
|
|
||||||
zoneFile.Insert(ns)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.SoaRecord != nil {
|
|
||||||
SOA := result.RecordSetProperties.SoaRecord
|
|
||||||
soa := &dns.SOA{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
Minttl: uint32(*(SOA.MinimumTTL)),
|
|
||||||
Expire: uint32(*(SOA.ExpireTime)),
|
|
||||||
Retry: uint32(*(SOA.RetryTime)),
|
|
||||||
Refresh: uint32(*(SOA.RefreshTime)),
|
|
||||||
Serial: uint32(*(SOA.SerialNumber)),
|
|
||||||
Mbox: dns.Fqdn(*(SOA.Email)),
|
|
||||||
Ns: *(SOA.Host)}
|
|
||||||
zoneFile.Insert(soa)
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RecordSetProperties.CnameRecord != nil {
|
|
||||||
CNAME := result.RecordSetProperties.CnameRecord.Cname
|
|
||||||
cname := &dns.CNAME{Hdr: dns.RR_Header{Name: resultFqdn, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: resultTTL},
|
|
||||||
Target: dns.Fqdn(*CNAME)}
|
|
||||||
zoneFile.Insert(cname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return zoneFile
|
|
||||||
}
|
|
||||||
|
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@ -14,6 +14,9 @@ github.com/coredns/coredns/coremain
|
|||||||
github.com/coredns/coredns/pb
|
github.com/coredns/coredns/pb
|
||||||
github.com/coredns/coredns/plugin
|
github.com/coredns/coredns/plugin
|
||||||
github.com/coredns/coredns/plugin/etcd/msg
|
github.com/coredns/coredns/plugin/etcd/msg
|
||||||
|
github.com/coredns/coredns/plugin/file
|
||||||
|
github.com/coredns/coredns/plugin/file/rrutil
|
||||||
|
github.com/coredns/coredns/plugin/file/tree
|
||||||
github.com/coredns/coredns/plugin/metrics
|
github.com/coredns/coredns/plugin/metrics
|
||||||
github.com/coredns/coredns/plugin/metrics/vars
|
github.com/coredns/coredns/plugin/metrics/vars
|
||||||
github.com/coredns/coredns/plugin/pkg/dnstest
|
github.com/coredns/coredns/plugin/pkg/dnstest
|
||||||
@ -21,6 +24,7 @@ github.com/coredns/coredns/plugin/pkg/dnsutil
|
|||||||
github.com/coredns/coredns/plugin/pkg/doh
|
github.com/coredns/coredns/plugin/pkg/doh
|
||||||
github.com/coredns/coredns/plugin/pkg/edns
|
github.com/coredns/coredns/plugin/pkg/edns
|
||||||
github.com/coredns/coredns/plugin/pkg/fall
|
github.com/coredns/coredns/plugin/pkg/fall
|
||||||
|
github.com/coredns/coredns/plugin/pkg/fuzz
|
||||||
github.com/coredns/coredns/plugin/pkg/log
|
github.com/coredns/coredns/plugin/pkg/log
|
||||||
github.com/coredns/coredns/plugin/pkg/nonwriter
|
github.com/coredns/coredns/plugin/pkg/nonwriter
|
||||||
github.com/coredns/coredns/plugin/pkg/parse
|
github.com/coredns/coredns/plugin/pkg/parse
|
||||||
|
Loading…
Reference in New Issue
Block a user