mirror of
https://github.com/coredns/coredns.git
synced 2025-11-02 02:03:13 -05:00
Remove the word middleware (#1067)
* Rename middleware to plugin first pass; mostly used 'sed', few spots where I manually changed text. This still builds a coredns binary. * fmt error * Rename AddMiddleware to AddPlugin * Readd AddMiddleware to remain backwards compat
This commit is contained in:
15
plugin/pkg/dnsutil/cname.go
Normal file
15
plugin/pkg/dnsutil/cname.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package dnsutil
|
||||
|
||||
import "github.com/miekg/dns"
|
||||
|
||||
// DuplicateCNAME returns true if r already exists in records.
|
||||
func DuplicateCNAME(r *dns.CNAME, records []dns.RR) bool {
|
||||
for _, rec := range records {
|
||||
if v, ok := rec.(*dns.CNAME); ok {
|
||||
if v.Target == r.Target {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
55
plugin/pkg/dnsutil/cname_test.go
Normal file
55
plugin/pkg/dnsutil/cname_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
func TestDuplicateCNAME(t *testing.T) {
|
||||
tests := []struct {
|
||||
cname string
|
||||
records []string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
|
||||
[]string{
|
||||
"US. 86400 IN NSEC 0-.us. NS SOA RRSIG NSEC DNSKEY TYPE65534",
|
||||
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
|
||||
[]string{
|
||||
"US. 86400 IN NSEC 0-.us. NS SOA RRSIG NSEC DNSKEY TYPE65534",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
|
||||
[]string{},
|
||||
false,
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
cnameRR, err := dns.NewRR(test.cname)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d, cname ('%s') error (%s)!", i, test.cname, err)
|
||||
}
|
||||
cname := cnameRR.(*dns.CNAME)
|
||||
records := []dns.RR{}
|
||||
for j, r := range test.records {
|
||||
rr, err := dns.NewRR(r)
|
||||
if err != nil {
|
||||
t.Fatalf("Test %d, record %d ('%s') error (%s)!", i, j, r, err)
|
||||
}
|
||||
records = append(records, rr)
|
||||
}
|
||||
got := DuplicateCNAME(cname, records)
|
||||
if got != test.expected {
|
||||
t.Errorf("Test %d, expected '%v', got '%v' for CNAME ('%s') and RECORDS (%v)", i, test.expected, got, test.cname, test.records)
|
||||
}
|
||||
}
|
||||
}
|
||||
12
plugin/pkg/dnsutil/dedup.go
Normal file
12
plugin/pkg/dnsutil/dedup.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package dnsutil
|
||||
|
||||
import "github.com/miekg/dns"
|
||||
|
||||
// Dedup de-duplicates a message.
|
||||
func Dedup(m *dns.Msg) *dns.Msg {
|
||||
// TODO(miek): expensive!
|
||||
m.Answer = dns.Dedup(m.Answer, nil)
|
||||
m.Ns = dns.Dedup(m.Ns, nil)
|
||||
m.Extra = dns.Dedup(m.Extra, nil)
|
||||
return m
|
||||
}
|
||||
2
plugin/pkg/dnsutil/doc.go
Normal file
2
plugin/pkg/dnsutil/doc.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package dnsutil contains DNS related helper functions.
|
||||
package dnsutil
|
||||
82
plugin/pkg/dnsutil/host.go
Normal file
82
plugin/pkg/dnsutil/host.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// ParseHostPortOrFile parses the strings in s, each string can either be a address,
|
||||
// address:port or a filename. The address part is checked and the filename case a
|
||||
// resolv.conf like file is parsed and the nameserver found are returned.
|
||||
func ParseHostPortOrFile(s ...string) ([]string, error) {
|
||||
var servers []string
|
||||
for _, host := range s {
|
||||
addr, _, err := net.SplitHostPort(host)
|
||||
if err != nil {
|
||||
// Parse didn't work, it is not a addr:port combo
|
||||
if net.ParseIP(host) == nil {
|
||||
// Not an IP address.
|
||||
ss, err := tryFile(host)
|
||||
if err == nil {
|
||||
servers = append(servers, ss...)
|
||||
continue
|
||||
}
|
||||
return servers, fmt.Errorf("not an IP address or file: %q", host)
|
||||
}
|
||||
ss := net.JoinHostPort(host, "53")
|
||||
servers = append(servers, ss)
|
||||
continue
|
||||
}
|
||||
|
||||
if net.ParseIP(addr) == nil {
|
||||
// No an IP address.
|
||||
ss, err := tryFile(host)
|
||||
if err == nil {
|
||||
servers = append(servers, ss...)
|
||||
continue
|
||||
}
|
||||
return servers, fmt.Errorf("not an IP address or file: %q", host)
|
||||
}
|
||||
servers = append(servers, host)
|
||||
}
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
// Try to open this is a file first.
|
||||
func tryFile(s string) ([]string, error) {
|
||||
c, err := dns.ClientConfigFromFile(s)
|
||||
if err == os.ErrNotExist {
|
||||
return nil, fmt.Errorf("failed to open file %q: %q", s, err)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
servers := []string{}
|
||||
for _, s := range c.Servers {
|
||||
servers = append(servers, net.JoinHostPort(s, c.Port))
|
||||
}
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
// ParseHostPort will check if the host part is a valid IP address, if the
|
||||
// IP address is valid, but no port is found, defaultPort is added.
|
||||
func ParseHostPort(s, defaultPort string) (string, error) {
|
||||
addr, port, err := net.SplitHostPort(s)
|
||||
if port == "" {
|
||||
port = defaultPort
|
||||
}
|
||||
if err != nil {
|
||||
if net.ParseIP(s) == nil {
|
||||
return "", fmt.Errorf("must specify an IP address: `%s'", s)
|
||||
}
|
||||
return net.JoinHostPort(s, port), nil
|
||||
}
|
||||
|
||||
if net.ParseIP(addr) == nil {
|
||||
return "", fmt.Errorf("must specify an IP address: `%s'", addr)
|
||||
}
|
||||
return net.JoinHostPort(addr, port), nil
|
||||
}
|
||||
85
plugin/pkg/dnsutil/host_test.go
Normal file
85
plugin/pkg/dnsutil/host_test.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseHostPortOrFile(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
expected string
|
||||
shouldErr bool
|
||||
}{
|
||||
{
|
||||
"8.8.8.8",
|
||||
"8.8.8.8:53",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"8.8.8.8:153",
|
||||
"8.8.8.8:153",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"/etc/resolv.conf:53",
|
||||
"",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"resolv.conf",
|
||||
"127.0.0.1:53",
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
err := ioutil.WriteFile("resolv.conf", []byte("nameserver 127.0.0.1\n"), 0600)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write test resolv.conf")
|
||||
}
|
||||
defer os.Remove("resolv.conf")
|
||||
|
||||
for i, tc := range tests {
|
||||
got, err := ParseHostPortOrFile(tc.in)
|
||||
if err == nil && tc.shouldErr {
|
||||
t.Errorf("Test %d, expected error, got nil", i)
|
||||
continue
|
||||
}
|
||||
if err != nil && tc.shouldErr {
|
||||
continue
|
||||
}
|
||||
if got[0] != tc.expected {
|
||||
t.Errorf("Test %d, expected %q, got %q", i, tc.expected, got[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseHostPort(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
expected string
|
||||
shouldErr bool
|
||||
}{
|
||||
{"8.8.8.8:53", "8.8.8.8:53", false},
|
||||
{"a.a.a.a:153", "", true},
|
||||
{"8.8.8.8", "8.8.8.8:53", false},
|
||||
{"8.8.8.8:", "8.8.8.8:53", false},
|
||||
{"8.8.8.8::53", "", true},
|
||||
{"resolv.conf", "", true},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
got, err := ParseHostPort(tc.in, "53")
|
||||
if err == nil && tc.shouldErr {
|
||||
t.Errorf("Test %d, expected error, got nil", i)
|
||||
continue
|
||||
}
|
||||
if err != nil && !tc.shouldErr {
|
||||
t.Errorf("Test %d, expected no error, got %q", i, err)
|
||||
}
|
||||
if got != tc.expected {
|
||||
t.Errorf("Test %d, expected %q, got %q", i, tc.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
plugin/pkg/dnsutil/join.go
Normal file
19
plugin/pkg/dnsutil/join.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Join joins labels to form a fully qualified domain name. If the last label is
|
||||
// the root label it is ignored. Not other syntax checks are performed.
|
||||
func Join(labels []string) string {
|
||||
ll := len(labels)
|
||||
if labels[ll-1] == "." {
|
||||
s := strings.Join(labels[:ll-1], ".")
|
||||
return dns.Fqdn(s)
|
||||
}
|
||||
s := strings.Join(labels, ".")
|
||||
return dns.Fqdn(s)
|
||||
}
|
||||
20
plugin/pkg/dnsutil/join_test.go
Normal file
20
plugin/pkg/dnsutil/join_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package dnsutil
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestJoin(t *testing.T) {
|
||||
tests := []struct {
|
||||
in []string
|
||||
out string
|
||||
}{
|
||||
{[]string{"bla", "bliep", "example", "org"}, "bla.bliep.example.org."},
|
||||
{[]string{"example", "."}, "example."},
|
||||
{[]string{"."}, "."},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
if x := Join(tc.in); x != tc.out {
|
||||
t.Errorf("Test %d, expected %s, got %s", i, tc.out, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
68
plugin/pkg/dnsutil/reverse.go
Normal file
68
plugin/pkg/dnsutil/reverse.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ExtractAddressFromReverse turns a standard PTR reverse record name
|
||||
// into an IP address. This works for ipv4 or ipv6.
|
||||
//
|
||||
// 54.119.58.176.in-addr.arpa. becomes 176.58.119.54. If the conversion
|
||||
// failes the empty string is returned.
|
||||
func ExtractAddressFromReverse(reverseName string) string {
|
||||
search := ""
|
||||
|
||||
f := reverse
|
||||
|
||||
switch {
|
||||
case strings.HasSuffix(reverseName, v4arpaSuffix):
|
||||
search = strings.TrimSuffix(reverseName, v4arpaSuffix)
|
||||
case strings.HasSuffix(reverseName, v6arpaSuffix):
|
||||
search = strings.TrimSuffix(reverseName, v6arpaSuffix)
|
||||
f = reverse6
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
// Reverse the segments and then combine them.
|
||||
return f(strings.Split(search, "."))
|
||||
}
|
||||
|
||||
func reverse(slice []string) string {
|
||||
for i := 0; i < len(slice)/2; i++ {
|
||||
j := len(slice) - i - 1
|
||||
slice[i], slice[j] = slice[j], slice[i]
|
||||
}
|
||||
ip := net.ParseIP(strings.Join(slice, ".")).To4()
|
||||
if ip == nil {
|
||||
return ""
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
|
||||
// reverse6 reverse the segments and combine them according to RFC3596:
|
||||
// b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2
|
||||
// is reversed to 2001:db8::567:89ab
|
||||
func reverse6(slice []string) string {
|
||||
for i := 0; i < len(slice)/2; i++ {
|
||||
j := len(slice) - i - 1
|
||||
slice[i], slice[j] = slice[j], slice[i]
|
||||
}
|
||||
slice6 := []string{}
|
||||
for i := 0; i < len(slice)/4; i++ {
|
||||
slice6 = append(slice6, strings.Join(slice[i*4:i*4+4], ""))
|
||||
}
|
||||
ip := net.ParseIP(strings.Join(slice6, ":")).To16()
|
||||
if ip == nil {
|
||||
return ""
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
|
||||
const (
|
||||
// v4arpaSuffix is the reverse tree suffix for v4 IP addresses.
|
||||
v4arpaSuffix = ".in-addr.arpa."
|
||||
// v6arpaSuffix is the reverse tree suffix for v6 IP addresses.
|
||||
v6arpaSuffix = ".ip6.arpa."
|
||||
)
|
||||
51
plugin/pkg/dnsutil/reverse_test.go
Normal file
51
plugin/pkg/dnsutil/reverse_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExtractAddressFromReverse(t *testing.T) {
|
||||
tests := []struct {
|
||||
reverseName string
|
||||
expectedAddress string
|
||||
}{
|
||||
{
|
||||
"54.119.58.176.in-addr.arpa.",
|
||||
"176.58.119.54",
|
||||
},
|
||||
{
|
||||
".58.176.in-addr.arpa.",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.in-addr.arpa.",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
|
||||
"2001:db8::567:89ab",
|
||||
},
|
||||
{
|
||||
"d.0.1.0.0.2.ip6.arpa.",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"54.119.58.176.ip6.arpa.",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"NONAME",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"",
|
||||
"",
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
got := ExtractAddressFromReverse(test.reverseName)
|
||||
if got != test.expectedAddress {
|
||||
t.Errorf("Test %d, expected '%s', got '%s'", i, test.expectedAddress, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
20
plugin/pkg/dnsutil/zone.go
Normal file
20
plugin/pkg/dnsutil/zone.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// TrimZone removes the zone component from q. It returns the trimmed
|
||||
// name or an error is zone is longer then qname. The trimmed name will be returned
|
||||
// without a trailing dot.
|
||||
func TrimZone(q string, z string) (string, error) {
|
||||
zl := dns.CountLabel(z)
|
||||
i, ok := dns.PrevLabel(q, zl)
|
||||
if ok || i-1 < 0 {
|
||||
return "", errors.New("trimzone: overshot qname: " + q + "for zone " + z)
|
||||
}
|
||||
// This includes the '.', remove on return
|
||||
return q[:i-1], nil
|
||||
}
|
||||
39
plugin/pkg/dnsutil/zone_test.go
Normal file
39
plugin/pkg/dnsutil/zone_test.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package dnsutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
func TestTrimZone(t *testing.T) {
|
||||
tests := []struct {
|
||||
qname string
|
||||
zone string
|
||||
expected string
|
||||
err error
|
||||
}{
|
||||
{"a.example.org", "example.org", "a", nil},
|
||||
{"a.b.example.org", "example.org", "a.b", nil},
|
||||
{"b.", ".", "b", nil},
|
||||
{"example.org", "example.org", "", errors.New("should err")},
|
||||
{"org", "example.org", "", errors.New("should err")},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
got, err := TrimZone(dns.Fqdn(tc.qname), dns.Fqdn(tc.zone))
|
||||
if tc.err != nil && err == nil {
|
||||
t.Errorf("Test %d, expected error got nil", i)
|
||||
continue
|
||||
}
|
||||
if tc.err == nil && err != nil {
|
||||
t.Errorf("Test %d, expected no error got %v", i, err)
|
||||
continue
|
||||
}
|
||||
if got != tc.expected {
|
||||
t.Errorf("Test %d, expected %s, got %s", i, tc.expected, got)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user