Progress in chaos
This commit is contained in:
parent
6c50f9fae5
commit
5a413a0cb4
36
ldap.go
36
ldap.go
@ -10,14 +10,15 @@ package ldap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"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/pkg/fall"
|
"github.com/coredns/coredns/plugin/pkg/fall"
|
||||||
|
"github.com/coredns/coredns/plugin/pkg/upstream"
|
||||||
"github.com/coredns/coredns/request"
|
"github.com/coredns/coredns/request"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
@ -29,14 +30,31 @@ type Ldap struct {
|
|||||||
Next plugin.Handler
|
Next plugin.Handler
|
||||||
Fall fall.F
|
Fall fall.F
|
||||||
Zones []string
|
Zones []string
|
||||||
Client *ldap.Client
|
Upstream *upstream.Upstream
|
||||||
clientConfig map[string]
|
Client ldap.Client
|
||||||
|
|
||||||
|
searchRequest *ldap.SearchRequest
|
||||||
|
ldapURL string
|
||||||
|
pagingLimit uint32
|
||||||
|
syncInterval time.Duration
|
||||||
|
username string
|
||||||
|
password string
|
||||||
|
sasl bool
|
||||||
|
zMu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns an initialized Ldap with defaults.
|
// New returns an initialized Ldap with defaults.
|
||||||
func New(zones []string) *Ldap {
|
func New(zones []string) *Ldap {
|
||||||
k := new(Ldap)
|
k := new(Ldap)
|
||||||
k.Zones = zones
|
k.Zones = zones
|
||||||
|
k.pagingLimit = 0
|
||||||
|
// SearchRequest defaults
|
||||||
|
k.searchRequest = new(ldap.SearchRequest)
|
||||||
|
k.searchRequest.DerefAliases = ldap.NeverDerefAliases // TODO: Reason
|
||||||
|
k.searchRequest.Scope = ldap.ScopeWholeSubtree // search whole subtree
|
||||||
|
k.searchRequest.SizeLimit = 500 // TODO: Reason
|
||||||
|
k.searchRequest.TimeLimit = 500 // TODO: Reason
|
||||||
|
k.searchRequest.TypesOnly = false // TODO: Reason
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,17 +66,13 @@ var (
|
|||||||
|
|
||||||
// InitClient initializes a Ldap client.
|
// InitClient initializes a Ldap client.
|
||||||
func (l *Ldap) InitClient() (err error) {
|
func (l *Ldap) InitClient() (err error) {
|
||||||
l.Client, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", "ldap.example.com", 389))
|
l.Client, err = ldap.DialURL(l.ldapURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
defer l.Client.Close()
|
defer l.Client.Close()
|
||||||
|
return nil
|
||||||
// Reconnect with TLS
|
|
||||||
err = l.Client.StartTLS(&tls.Config{InsecureSkipVerify: true})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Services implements the ServiceBackend interface.
|
// Services implements the ServiceBackend interface.
|
||||||
|
231
setup.go
231
setup.go
@ -1,20 +1,13 @@
|
|||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"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"
|
||||||
"github.com/coredns/coredns/plugin/metrics"
|
"github.com/coredns/coredns/plugin/metrics"
|
||||||
"github.com/coredns/coredns/plugin/pkg/dnsutil"
|
|
||||||
clog "github.com/coredns/coredns/plugin/pkg/log"
|
clog "github.com/coredns/coredns/plugin/pkg/log"
|
||||||
"github.com/coredns/coredns/plugin/pkg/parse"
|
|
||||||
"github.com/coredns/coredns/plugin/pkg/upstream"
|
"github.com/coredns/coredns/plugin/pkg/upstream"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy"
|
"github.com/caddyserver/caddy"
|
||||||
@ -38,13 +31,11 @@ func setup(c *caddy.Controller) error {
|
|||||||
return plugin.Error(pluginName, err)
|
return plugin.Error(pluginName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.InitLdapCache(context.Background())
|
err = l.InitClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return plugin.Error(pluginName, err)
|
return plugin.Error(pluginName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
l.RegisterLdapCache(c)
|
|
||||||
|
|
||||||
// add prometheus metrics on startup
|
// add prometheus metrics on startup
|
||||||
c.OnStartup(func() error {
|
c.OnStartup(func() error {
|
||||||
// add plugin-global metric once
|
// add plugin-global metric once
|
||||||
@ -65,30 +56,6 @@ func setup(c *caddy.Controller) error {
|
|||||||
|
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
|
|
||||||
// RegisterLdapCache registers LdapCache start and stop functions with Caddy
|
|
||||||
func (l *Ldap) RegisterLdapCache(c *caddy.Controller) {
|
|
||||||
c.OnStartup(func() error {
|
|
||||||
go l.APIConn.Run()
|
|
||||||
|
|
||||||
timeout := time.After(5 * time.Second)
|
|
||||||
ticker := time.NewTicker(100 * time.Millisecond)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ticker.C:
|
|
||||||
if k.APIConn.HasSynced() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
case <-timeout:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
c.OnShutdown(func() error {
|
|
||||||
return l.APIConn.Stop()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ldapParse(c *caddy.Controller) (*Ldap, error) {
|
func ldapParse(c *caddy.Controller) (*Ldap, error) {
|
||||||
var (
|
var (
|
||||||
ldap *Ldap
|
ldap *Ldap
|
||||||
@ -102,7 +69,7 @@ func ldapParse(c *caddy.Controller) (*Ldap, error) {
|
|||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
|
|
||||||
l, err = ParseStanza(c)
|
ldap, err = ParseStanza(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ldap, err
|
return ldap, err
|
||||||
}
|
}
|
||||||
@ -112,16 +79,7 @@ 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{""})
|
ldap := New([]string{""})
|
||||||
ldap.autoPathSearch = searchFromResolvConf()
|
|
||||||
|
|
||||||
opts := dnsControlOpts{
|
|
||||||
initEndpointsCache: true,
|
|
||||||
ignoreEmptyService: false,
|
|
||||||
}
|
|
||||||
ldap.opts = opts
|
|
||||||
|
|
||||||
zones := c.RemainingArgs()
|
zones := c.RemainingArgs()
|
||||||
|
|
||||||
if len(zones) != 0 {
|
if len(zones) != 0 {
|
||||||
@ -136,153 +94,78 @@ func ParseStanza(c *caddy.Controller) (*Ldap, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ldap.primaryZoneIndex = -1
|
|
||||||
for i, z := range ldap.Zones {
|
|
||||||
if dnsutil.IsReverse(z) > 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ldap.primaryZoneIndex = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if ldap.primaryZoneIndex == -1 {
|
|
||||||
return nil, errors.New("non-reverse zone name must be used")
|
|
||||||
}
|
|
||||||
|
|
||||||
ldap.Upstream = upstream.New()
|
ldap.Upstream = upstream.New()
|
||||||
|
|
||||||
for c.NextBlock() {
|
for c.NextBlock() {
|
||||||
switch c.Val() {
|
switch c.Val() {
|
||||||
// RFC 4516 URL
|
// RFC 4516 URL
|
||||||
case "endpoint_pod_names":
|
case "ldap_url":
|
||||||
args := c.RemainingArgs()
|
c.NextArg()
|
||||||
if len(args) > 0 {
|
ldap.ldapURL = c.Val()
|
||||||
|
continue
|
||||||
|
case "paging_limit":
|
||||||
|
c.NextArg()
|
||||||
|
pagingLimit, err := strconv.Atoi(c.Val())
|
||||||
|
if err != nil {
|
||||||
return nil, c.ArgErr()
|
return nil, c.ArgErr()
|
||||||
}
|
}
|
||||||
ldap.endpointNameMode = true
|
ldap.pagingLimit = pagingLimit
|
||||||
continue
|
continue
|
||||||
case "pods":
|
case "search_request":
|
||||||
args := c.RemainingArgs()
|
for c.NextBlock() {
|
||||||
if len(args) == 1 {
|
switch c.Val() {
|
||||||
switch args[0] {
|
case "base_dn":
|
||||||
case podModeDisabled, podModeInsecure, podModeVerified:
|
c.NextArg() // ou=ae-dir
|
||||||
ldap.podMode = args[0]
|
ldap.searchRequest.BaseDN = c.Val()
|
||||||
|
case "filter":
|
||||||
|
c.NextArg() // (objectClass=aeNwDevice)
|
||||||
|
ldap.searchRequest.Filter = c.Val()
|
||||||
|
case "attributes":
|
||||||
|
ldap.searchRequest.Attributes = c.RemainingArgs() // aeFqdn ipHostNumber
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("wrong value for pods: %s, must be one of: disabled, verified, insecure", args[0])
|
return nil, c.Errf("unknown search request property '%s'", c.Val())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
case "username":
|
||||||
return nil, c.ArgErr()
|
c.NextArg()
|
||||||
case "namespaces":
|
ldap.username = c.Val()
|
||||||
args := c.RemainingArgs()
|
case "password":
|
||||||
if len(args) > 0 {
|
c.NextArg()
|
||||||
for _, a := range args {
|
ldap.password = c.Val()
|
||||||
ldap.Namespaces[a] = struct{}{}
|
case "sasl":
|
||||||
}
|
c.NextArg()
|
||||||
continue
|
ldap.sasl = true
|
||||||
}
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
case "endpoint":
|
|
||||||
args := c.RemainingArgs()
|
|
||||||
if len(args) > 0 {
|
|
||||||
// Multiple endpoints are deprecated but still could be specified,
|
|
||||||
// only the first one be used, though
|
|
||||||
ldap.APIServerList = args
|
|
||||||
if len(args) > 1 {
|
|
||||||
log.Warningf("Multiple endpoints have been deprecated, only the first specified endpoint '%s' is used", args[0])
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
case "tls": // cert key cacertfile
|
|
||||||
args := c.RemainingArgs()
|
|
||||||
if len(args) == 3 {
|
|
||||||
ldap.APIClientCert, ldap.APIClientKey, ldap.APICertAuth = args[0], args[1], args[2]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
case "labels":
|
|
||||||
args := c.RemainingArgs()
|
|
||||||
if len(args) > 0 {
|
|
||||||
labelSelectorString := strings.Join(args, " ")
|
|
||||||
ls, err := meta.ParseToLabelSelector(labelSelectorString)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to parse label selector value: '%v': %v", labelSelectorString, err)
|
|
||||||
}
|
|
||||||
ldap.opts.labelSelector = ls
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
case "namespace_labels":
|
|
||||||
args := c.RemainingArgs()
|
|
||||||
if len(args) > 0 {
|
|
||||||
namespaceLabelSelectorString := strings.Join(args, " ")
|
|
||||||
nls, err := meta.ParseToLabelSelector(namespaceLabelSelectorString)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to parse namespace_label selector value: '%v': %v", namespaceLabelSelectorString, err)
|
|
||||||
}
|
|
||||||
ldap.opts.namespaceLabelSelector = nls
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
case "fallthrough":
|
case "fallthrough":
|
||||||
ldap.Fall.SetZonesFromArgs(c.RemainingArgs())
|
ldap.Fall.SetZonesFromArgs(c.RemainingArgs())
|
||||||
case "ttl":
|
|
||||||
args := c.RemainingArgs()
|
|
||||||
if len(args) == 0 {
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
}
|
|
||||||
t, err := strconv.Atoi(args[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if t < 0 || t > 3600 {
|
|
||||||
return nil, c.Errf("ttl must be in range [0, 3600]: %d", t)
|
|
||||||
}
|
|
||||||
ldap.ttl = uint32(t)
|
|
||||||
case "transfer":
|
|
||||||
tos, froms, err := parse.Transfer(c, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(froms) != 0 {
|
|
||||||
return nil, c.Errf("transfer from is not supported with this plugin")
|
|
||||||
}
|
|
||||||
ldap.TransferTo = tos
|
|
||||||
case "noendpoints":
|
|
||||||
if len(c.RemainingArgs()) != 0 {
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
}
|
|
||||||
ldap.opts.initEndpointsCache = false
|
|
||||||
case "ignore":
|
|
||||||
args := c.RemainingArgs()
|
|
||||||
if len(args) > 0 {
|
|
||||||
ignore := args[0]
|
|
||||||
if ignore == "empty_service" {
|
|
||||||
ldap.opts.ignoreEmptyService = true
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("unable to parse ignore value: '%v'", ignore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "kubeconfig":
|
|
||||||
args := c.RemainingArgs()
|
|
||||||
if len(args) == 2 {
|
|
||||||
config := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
|
||||||
&clientcmd.ClientConfigLoadingRules{ExplicitPath: args[0]},
|
|
||||||
&clientcmd.ConfigOverrides{CurrentContext: args[1]},
|
|
||||||
)
|
|
||||||
ldap.ClientConfig = config
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return nil, c.ArgErr()
|
|
||||||
default:
|
default:
|
||||||
return nil, c.Errf("unknown property '%s'", c.Val())
|
return nil, c.Errf("unknown property '%s'", c.Val())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// validate non-default ldap values ...
|
||||||
if len(ldap.Namespaces) != 0 && ldap.opts.namespaceLabelSelector != nil {
|
if ldap.ldapURL == "" || &ldap.ldapURL == nil {
|
||||||
return nil, c.Errf("namespaces and namespace_labels cannot both be set")
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
if ldap.searchRequest.BaseDN == "" {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
if ldap.searchRequest.Filter == "" {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
if len(ldap.searchRequest.Attributes) != 2 {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
// if only one of password and username set
|
||||||
|
if (&ldap.username == nil) != (&ldap.password == nil) {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
// if both username/password and sasl are set
|
||||||
|
if &ldap.username != nil && &ldap.sasl != nil {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
// if neither username/password nor sasl are set
|
||||||
|
if &ldap.username == nil && &ldap.sasl == nil {
|
||||||
|
return nil, c.ArgErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
return ldap, nil
|
return ldap, nil
|
||||||
|
150
sync.go
Normal file
150
sync.go
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/coredns/coredns/plugin"
|
||||||
|
"github.com/coredns/coredns/plugin/file"
|
||||||
|
"github.com/coredns/coredns/request"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run updates the zone from ldap.
|
||||||
|
func (l *Ldap) Run(ctx context.Context) error {
|
||||||
|
if err := l.updateZones(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
log.Infof("Breaking out of Ldap update loop: %v", ctx.Err())
|
||||||
|
return
|
||||||
|
case <-time.After(l.syncInterval * time.Second):
|
||||||
|
if err := l.updateZones(ctx); err != nil && ctx.Err() == nil {
|
||||||
|
log.Errorf("Failed to update zones: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Ldap) updateZones(ctx context.Context) error {
|
||||||
|
var err error
|
||||||
|
var zoneFile file.Zone
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error updating zones: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Ldap) getValuePairs() (valuePairs *[][]string, err error) {
|
||||||
|
searchResult, err := l.Client.SearchWithPaging(l.searchRequest, l.pagingLimit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error fetching data from ldap server: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user