plugin/loadbalance: add parse and tests (#1947)

Automatically submitted.
This commit is contained in:
Miek Gieben
2018-07-06 22:49:21 +01:00
committed by corbot[bot]
parent bcc749db04
commit 7c41f2ce9f
4 changed files with 71 additions and 16 deletions

View File

@@ -2,12 +2,12 @@
## Name ## Name
*loadbalance* - randomize the order of A and AAAA records. *loadbalance* - randomize the order of A, AAAA and MX records.
## Description ## Description
The *loadbalance* will act as a round-robin DNS loadbalancer by randomizing the order of A and AAAA The *loadbalance* will act as a round-robin DNS loadbalancer by randomizing the order of A, AAAA,
records in the answer. and MX records in the answer.
See [Wikipedia](https://en.wikipedia.org/wiki/Round-robin_DNS) about the pros and cons on this See [Wikipedia](https://en.wikipedia.org/wiki/Round-robin_DNS) about the pros and cons on this
setup. It will take care to sort any CNAMEs before any address records, because some stub resolver setup. It will take care to sort any CNAMEs before any address records, because some stub resolver

View File

@@ -1,14 +1,12 @@
// Package loadbalance shuffles A and AAAA records. // Package loadbalance shuffles A, AAAA and MX records.
package loadbalance package loadbalance
import ( import (
"github.com/miekg/dns" "github.com/miekg/dns"
) )
// RoundRobinResponseWriter is a response writer that shuffles A and AAAA records. // RoundRobinResponseWriter is a response writer that shuffles A, AAAA and MX records.
type RoundRobinResponseWriter struct { type RoundRobinResponseWriter struct{ dns.ResponseWriter }
dns.ResponseWriter
}
// WriteMsg implements the dns.ResponseWriter interface. // WriteMsg implements the dns.ResponseWriter interface.
func (r *RoundRobinResponseWriter) WriteMsg(res *dns.Msg) error { func (r *RoundRobinResponseWriter) WriteMsg(res *dns.Msg) error {
@@ -77,9 +75,3 @@ func (r *RoundRobinResponseWriter) Write(buf []byte) (int, error) {
n, err := r.ResponseWriter.Write(buf) n, err := r.ResponseWriter.Write(buf)
return n, err return n, err
} }
// Hijack implements the dns.ResponseWriter interface.
func (r *RoundRobinResponseWriter) Hijack() {
r.ResponseWriter.Hijack()
return
}

View File

@@ -1,6 +1,8 @@
package loadbalance package loadbalance
import ( import (
"fmt"
"github.com/coredns/coredns/core/dnsserver" "github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin" "github.com/coredns/coredns/plugin"
clog "github.com/coredns/coredns/plugin/pkg/log" clog "github.com/coredns/coredns/plugin/pkg/log"
@@ -18,8 +20,9 @@ func init() {
} }
func setup(c *caddy.Controller) error { func setup(c *caddy.Controller) error {
for c.Next() { err := parse(c)
// TODO(miek): block and option parsing if err != nil {
return plugin.Error("loadbalance", err)
} }
dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
@@ -28,3 +31,20 @@ func setup(c *caddy.Controller) error {
return nil return nil
} }
func parse(c *caddy.Controller) error {
for c.Next() {
args := c.RemainingArgs()
switch len(args) {
case 0:
return nil
case 1:
if args[0] != "round_robin" {
return fmt.Errorf("unknown policy: %s", args[0])
}
return nil
}
}
return c.ArgErr()
}

View File

@@ -0,0 +1,43 @@
package loadbalance
import (
"strings"
"testing"
"github.com/mholt/caddy"
)
func TestSetup(t *testing.T) {
tests := []struct {
input string
shouldErr bool
expectedPolicy string
expectedErrContent string // substring from the expected error. Empty for positive cases.
}{
// positive
{`loadbalance`, false, "round_robin", ""},
{`loadbalance round_robin`, false, "round_robin", ""},
// negative
{`loadbalance fleeb`, true, "", "unknown policy"},
{`loadbalance a b`, true, "", "argument count or unexpected line"},
}
for i, test := range tests {
c := caddy.NewTestController("dns", test.input)
err := parse(c)
if test.shouldErr && err == nil {
t.Errorf("Test %d: Expected error but found %s for input %s", i, err, test.input)
}
if err != nil {
if !test.shouldErr {
t.Errorf("Test %d: Expected no error but found one for input %s. Error was: %v", i, test.input, err)
}
if !strings.Contains(err.Error(), test.expectedErrContent) {
t.Errorf("Test %d: Expected error to contain: %v, found error: %v, input: %s", i, test.expectedErrContent, err, test.input)
}
}
}
}