aboutsummaryrefslogtreecommitdiff
path: root/middleware/etcd
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/etcd')
-rw-r--r--middleware/etcd/cname_test.go2
-rw-r--r--middleware/etcd/debug_test.go7
-rw-r--r--middleware/etcd/group_test.go2
-rw-r--r--middleware/etcd/multi_test.go3
-rw-r--r--middleware/etcd/other_test.go2
-rw-r--r--middleware/etcd/proxy_lookup_test.go11
-rw-r--r--middleware/etcd/setup.go207
-rw-r--r--middleware/etcd/setup_test.go17
-rw-r--r--middleware/etcd/stub_test.go3
9 files changed, 235 insertions, 19 deletions
diff --git a/middleware/etcd/cname_test.go b/middleware/etcd/cname_test.go
index 4a00c05c2..ee341b7b6 100644
--- a/middleware/etcd/cname_test.go
+++ b/middleware/etcd/cname_test.go
@@ -16,6 +16,8 @@ import (
// Check the ordering of returned cname.
func TestCnameLookup(t *testing.T) {
+ etc := newEtcdMiddleware()
+
for _, serv := range servicesCname {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
diff --git a/middleware/etcd/debug_test.go b/middleware/etcd/debug_test.go
index 91796816f..82de9fe1f 100644
--- a/middleware/etcd/debug_test.go
+++ b/middleware/etcd/debug_test.go
@@ -30,12 +30,13 @@ func TestIsDebug(t *testing.T) {
}
func TestDebugLookup(t *testing.T) {
+ etc := newEtcdMiddleware()
+ etc.Debug = true
+
for _, serv := range servicesDebug {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
- etc.Debug = true
- defer func() { etc.Debug = false }()
for _, tc := range dnsTestCasesDebug {
m := tc.Msg()
@@ -69,6 +70,8 @@ func TestDebugLookup(t *testing.T) {
}
func TestDebugLookupFalse(t *testing.T) {
+ etc := newEtcdMiddleware()
+
for _, serv := range servicesDebug {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
diff --git a/middleware/etcd/group_test.go b/middleware/etcd/group_test.go
index f5283e3ba..7a2808d45 100644
--- a/middleware/etcd/group_test.go
+++ b/middleware/etcd/group_test.go
@@ -14,6 +14,8 @@ import (
)
func TestGroupLookup(t *testing.T) {
+ etc := newEtcdMiddleware()
+
for _, serv := range servicesGroup {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
diff --git a/middleware/etcd/multi_test.go b/middleware/etcd/multi_test.go
index 19e6ca7a3..f4b59f50b 100644
--- a/middleware/etcd/multi_test.go
+++ b/middleware/etcd/multi_test.go
@@ -14,10 +14,9 @@ import (
)
func TestMultiLookup(t *testing.T) {
+ etc := newEtcdMiddleware()
etc.Zones = []string{"skydns.test.", "miek.nl."}
- defer func() { etc.Zones = []string{"skydns.test.", "skydns_extra.test.", "in-addr.arpa."} }()
etc.Next = test.ErrorHandler()
- defer func() { etc.Next = nil }()
for _, serv := range servicesMulti {
set(t, etc, serv.Key, 0, serv)
diff --git a/middleware/etcd/other_test.go b/middleware/etcd/other_test.go
index 34971c6f1..ff37d27d2 100644
--- a/middleware/etcd/other_test.go
+++ b/middleware/etcd/other_test.go
@@ -18,6 +18,8 @@ import (
)
func TestOtherLookup(t *testing.T) {
+ etc := newEtcdMiddleware()
+
for _, serv := range servicesOther {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
diff --git a/middleware/etcd/proxy_lookup_test.go b/middleware/etcd/proxy_lookup_test.go
index 9a31eee24..5e0999fb0 100644
--- a/middleware/etcd/proxy_lookup_test.go
+++ b/middleware/etcd/proxy_lookup_test.go
@@ -15,18 +15,15 @@ import (
)
func TestProxyLookupFailDebug(t *testing.T) {
+ etc := newEtcdMiddleware()
+ etc.Proxy = proxy.New([]string{"127.0.0.1:154"})
+ etc.Debug = true
+
for _, serv := range servicesProxy {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
- prxy := etc.Proxy
- etc.Proxy = proxy.New([]string{"127.0.0.1:154"})
- defer func() { etc.Proxy = prxy }()
-
- etc.Debug = true
- defer func() { etc.Debug = false }()
-
for _, tc := range dnsTestCasesProxy {
m := tc.Msg()
diff --git a/middleware/etcd/setup.go b/middleware/etcd/setup.go
new file mode 100644
index 000000000..dc1dddb0e
--- /dev/null
+++ b/middleware/etcd/setup.go
@@ -0,0 +1,207 @@
+package etcd
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "io/ioutil"
+ "net"
+ "net/http"
+ "time"
+
+ "github.com/miekg/coredns/core/dnsserver"
+ "github.com/miekg/coredns/middleware"
+ "github.com/miekg/coredns/middleware/proxy"
+ "github.com/miekg/coredns/singleflight"
+
+ etcdc "github.com/coreos/etcd/client"
+ "github.com/mholt/caddy"
+ "golang.org/x/net/context"
+)
+
+func init() {
+ caddy.RegisterPlugin("etcd", caddy.Plugin{
+ ServerType: "dns",
+ Action: setup,
+ })
+}
+
+func setup(c *caddy.Controller) error {
+ e, stubzones, err := etcdParse(c)
+ if err != nil {
+ return err
+ }
+ if stubzones {
+ c.OnStartup(func() error {
+ e.UpdateStubZones()
+ return nil
+ })
+ }
+
+ dnsserver.GetConfig(c).AddMiddleware(func(next dnsserver.Handler) dnsserver.Handler {
+ e.Next = next
+ return e
+ })
+
+ return nil
+}
+
+func etcdParse(c *caddy.Controller) (*Etcd, bool, error) {
+ stub := make(map[string]proxy.Proxy)
+ etc := Etcd{
+ Proxy: proxy.New([]string{"8.8.8.8:53", "8.8.4.4:53"}),
+ PathPrefix: "skydns",
+ Ctx: context.Background(),
+ Inflight: &singleflight.Group{},
+ Stubmap: &stub,
+ }
+ var (
+ client etcdc.KeysAPI
+ tlsCertFile = ""
+ tlsKeyFile = ""
+ tlsCAcertFile = ""
+ endpoints = []string{defaultEndpoint}
+ stubzones = false
+ )
+ for c.Next() {
+ if c.Val() == "etcd" {
+ etc.Client = client
+ etc.Zones = c.RemainingArgs()
+ if len(etc.Zones) == 0 {
+ etc.Zones = make([]string, len(c.ServerBlockKeys))
+ copy(etc.Zones, c.ServerBlockKeys)
+ }
+ middleware.Zones(etc.Zones).FullyQualify()
+ if c.NextBlock() {
+ // TODO(miek): 2 switches?
+ switch c.Val() {
+ case "stubzones":
+ stubzones = true
+ case "debug":
+ etc.Debug = true
+ case "path":
+ if !c.NextArg() {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ etc.PathPrefix = c.Val()
+ case "endpoint":
+ args := c.RemainingArgs()
+ if len(args) == 0 {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ endpoints = args
+ case "upstream":
+ args := c.RemainingArgs()
+ if len(args) == 0 {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ for i := 0; i < len(args); i++ {
+ h, p, e := net.SplitHostPort(args[i])
+ if e != nil && p == "" {
+ args[i] = h + ":53"
+ }
+ }
+ endpoints = args
+ etc.Proxy = proxy.New(args)
+ case "tls": // cert key cacertfile
+ args := c.RemainingArgs()
+ if len(args) != 3 {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ tlsCertFile, tlsKeyFile, tlsCAcertFile = args[0], args[1], args[2]
+ }
+ for c.Next() {
+ switch c.Val() {
+ case "stubzones":
+ stubzones = true
+ case "debug":
+ etc.Debug = true
+ case "path":
+ if !c.NextArg() {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ etc.PathPrefix = c.Val()
+ case "endpoint":
+ args := c.RemainingArgs()
+ if len(args) == 0 {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ endpoints = args
+ case "upstream":
+ args := c.RemainingArgs()
+ if len(args) == 0 {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ for i := 0; i < len(args); i++ {
+ h, p, e := net.SplitHostPort(args[i])
+ if e != nil && p == "" {
+ args[i] = h + ":53"
+ }
+ }
+ etc.Proxy = proxy.New(args)
+ case "tls": // cert key cacertfile
+ args := c.RemainingArgs()
+ if len(args) != 3 {
+ return &Etcd{}, false, c.ArgErr()
+ }
+ tlsCertFile, tlsKeyFile, tlsCAcertFile = args[0], args[1], args[2]
+ }
+ }
+ }
+ client, err := newEtcdClient(endpoints, tlsCertFile, tlsKeyFile, tlsCAcertFile)
+ if err != nil {
+ return &Etcd{}, false, err
+ }
+ etc.Client = client
+ return &etc, stubzones, nil
+ }
+ }
+ return &Etcd{}, false, nil
+}
+
+func newEtcdClient(endpoints []string, tlsCert, tlsKey, tlsCACert string) (etcdc.KeysAPI, error) {
+ etcdCfg := etcdc.Config{
+ Endpoints: endpoints,
+ Transport: newHTTPSTransport(tlsCert, tlsKey, tlsCACert),
+ }
+ cli, err := etcdc.New(etcdCfg)
+ if err != nil {
+ return nil, err
+ }
+ return etcdc.NewKeysAPI(cli), nil
+}
+
+func newHTTPSTransport(tlsCertFile, tlsKeyFile, tlsCACertFile string) etcdc.CancelableTransport {
+ var cc *tls.Config = nil
+
+ if tlsCertFile != "" && tlsKeyFile != "" {
+ var rpool *x509.CertPool
+ if tlsCACertFile != "" {
+ if pemBytes, err := ioutil.ReadFile(tlsCACertFile); err == nil {
+ rpool = x509.NewCertPool()
+ rpool.AppendCertsFromPEM(pemBytes)
+ }
+ }
+
+ if tlsCert, err := tls.LoadX509KeyPair(tlsCertFile, tlsKeyFile); err == nil {
+ cc = &tls.Config{
+ RootCAs: rpool,
+ Certificates: []tls.Certificate{tlsCert},
+ InsecureSkipVerify: true,
+ }
+ }
+ }
+
+ tr := &http.Transport{
+ Proxy: http.ProxyFromEnvironment,
+ Dial: (&net.Dialer{
+ Timeout: 30 * time.Second,
+ KeepAlive: 30 * time.Second,
+ }).Dial,
+ TLSHandshakeTimeout: 10 * time.Second,
+ TLSClientConfig: cc,
+ }
+
+ return tr
+}
+
+const defaultEndpoint = "http://localhost:2379"
diff --git a/middleware/etcd/setup_test.go b/middleware/etcd/setup_test.go
index 799b4a1bb..b522345d2 100644
--- a/middleware/etcd/setup_test.go
+++ b/middleware/etcd/setup_test.go
@@ -19,20 +19,19 @@ import (
"golang.org/x/net/context"
)
-var (
- etc *Etcd
- client etcdc.KeysAPI
- ctxt context.Context
-)
-
func init() {
ctxt, _ = context.WithTimeout(context.Background(), etcdTimeout)
+}
+
+// etc *Etcd
+func newEtcdMiddleware() *Etcd {
+ ctxt, _ = context.WithTimeout(context.Background(), etcdTimeout)
etcdCfg := etcdc.Config{
Endpoints: []string{"http://localhost:2379"},
}
cli, _ := etcdc.New(etcdCfg)
- etc = &Etcd{
+ return &Etcd{
Proxy: proxy.New([]string{"8.8.8.8:53"}),
PathPrefix: "skydns",
Ctx: context.Background(),
@@ -57,10 +56,12 @@ func delete(t *testing.T, e *Etcd, k string) {
}
func TestLookup(t *testing.T) {
+ etc := newEtcdMiddleware()
for _, serv := range services {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
+
for _, tc := range dnsTestCases {
m := tc.Msg()
@@ -91,3 +92,5 @@ func TestLookup(t *testing.T) {
}
}
}
+
+var ctxt context.Context
diff --git a/middleware/etcd/stub_test.go b/middleware/etcd/stub_test.go
index 1dc0901c0..b5a101dad 100644
--- a/middleware/etcd/stub_test.go
+++ b/middleware/etcd/stub_test.go
@@ -41,13 +41,14 @@ func TestStubLookup(t *testing.T) {
exampleNetStub := &msg.Service{Host: host, Port: port, Key: "a.example.net.stub.dns.skydns.test."}
servicesStub = append(servicesStub, exampleNetStub)
+ etc := newEtcdMiddleware()
+
for _, serv := range servicesStub {
set(t, etc, serv.Key, 0, serv)
defer delete(t, etc, serv.Key)
}
etc.updateStubZones()
- defer func() { etc.Stubmap = nil }()
for _, tc := range dnsTestCasesStub {
m := tc.Msg()