aboutsummaryrefslogtreecommitdiff
path: root/middleware/kubernetes/setup.go
blob: fc3c036b89ecb1b104936310f3e1b5c7e7ae5531 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package kubernetes

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/miekg/coredns/core/dnsserver"
	"github.com/miekg/coredns/middleware"
	"github.com/miekg/coredns/middleware/kubernetes/nametemplate"

	"github.com/mholt/caddy"
	unversionedapi "k8s.io/kubernetes/pkg/api/unversioned"
)

func init() {
	caddy.RegisterPlugin("kubernetes", caddy.Plugin{
		ServerType: "dns",
		Action:     setup,
	})
}

func setup(c *caddy.Controller) error {
	kubernetes, err := kubernetesParse(c)
	if err != nil {
		return err
	}

	err = kubernetes.InitKubeCache()
	if err != nil {
		return err
	}

	// Register KubeCache start and stop functions with Caddy
	c.OnStartup(func() error {
		go kubernetes.APIConn.Run()
		return nil
	})

	c.OnShutdown(func() error {
		return kubernetes.APIConn.Stop()
	})

	dnsserver.GetConfig(c).AddMiddleware(func(next dnsserver.Handler) dnsserver.Handler {
		kubernetes.Next = next
		return kubernetes
	})

	return nil
}

func kubernetesParse(c *caddy.Controller) (Kubernetes, error) {
	var err error
	template := defaultNameTemplate

	k8s := Kubernetes{ResyncPeriod: defaultResyncPeriod}
	k8s.NameTemplate = new(nametemplate.NameTemplate)
	k8s.NameTemplate.SetTemplate(template)

	for c.Next() {
		if c.Val() == "kubernetes" {
			zones := c.RemainingArgs()

			if len(zones) == 0 {
				k8s.Zones = make([]string, len(c.ServerBlockKeys))
				copy(k8s.Zones, c.ServerBlockKeys)
			}

			k8s.Zones = NormalizeZoneList(zones)
			middleware.Zones(k8s.Zones).FullyQualify()

			if k8s.Zones == nil || len(k8s.Zones) < 1 {
				err = errors.New("Zone name must be provided for kubernetes middleware.")
				return Kubernetes{}, err
			}

			for c.NextBlock() {
				switch c.Val() {
				case "template":
					args := c.RemainingArgs()
					if len(args) != 0 {
						template := strings.Join(args, "")
						err = k8s.NameTemplate.SetTemplate(template)
						if err != nil {
							return Kubernetes{}, err
						}
					} else {
						return Kubernetes{}, c.ArgErr()
					}
				case "namespaces":
					args := c.RemainingArgs()
					if len(args) != 0 {
						k8s.Namespaces = append(k8s.Namespaces, args...)
					} else {
						return Kubernetes{}, c.ArgErr()
					}
				case "endpoint":
					args := c.RemainingArgs()
					if len(args) != 0 {
						k8s.APIEndpoint = args[0]
					} else {
						return Kubernetes{}, c.ArgErr()
					}
				case "resyncperiod":
					args := c.RemainingArgs()
					if len(args) != 0 {
						k8s.ResyncPeriod, err = time.ParseDuration(args[0])
						if err != nil {
							err = errors.New(fmt.Sprintf("Unable to parse resync duration value. Value provided was '%v'. Example valid values: '15s', '5m', '1h'. Error was: %v", args[0], err))
							return Kubernetes{}, err
						}
					} else {
						return Kubernetes{}, c.ArgErr()
					}
				case "labels":
					args := c.RemainingArgs()
					if len(args) != 0 {
						labelSelectorString := strings.Join(args, " ")
						k8s.LabelSelector, err = unversionedapi.ParseToLabelSelector(labelSelectorString)
						if err != nil {
							err = errors.New(fmt.Sprintf("Unable to parse label selector. Value provided was '%v'. Error was: %v", labelSelectorString, err))
							return Kubernetes{}, err
						}
					} else {
						return Kubernetes{}, c.ArgErr()
					}
				}
			}
			return k8s, nil
		}
	}
	err = errors.New("Kubernetes setup called without keyword 'kubernetes' in Corefile")
	return Kubernetes{}, err
}

const (
	defaultNameTemplate = "{service}.{namespace}.{zone}"
	defaultResyncPeriod = 5 * time.Minute
)