aboutsummaryrefslogtreecommitdiff
path: root/middleware/kubernetes/setup.go
blob: 557eca93da6129b299cd908c6821c718c0c9aaae (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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package kubernetes

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

	"github.com/coredns/coredns/core/dnsserver"
	"github.com/coredns/coredns/middleware"
	"github.com/coredns/coredns/middleware/pkg/dnsutil"
	"github.com/coredns/coredns/middleware/proxy"
	"github.com/miekg/dns"

	"github.com/mholt/caddy"
	unversionedapi "k8s.io/client-go/1.5/pkg/api/unversioned"
)

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

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

	err = kubernetes.initKubeCache(initOpts)
	if err != nil {
		return middleware.Error("kubernetes", err)
	}

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

	c.OnShutdown(func() error {
		if kubernetes.APIProxy != nil {
			kubernetes.APIProxy.Stop()
		}
		return kubernetes.APIConn.Stop()
	})

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

	return nil
}

func kubernetesParse(c *caddy.Controller) (*Kubernetes, dnsControlOpts, error) {
	k8s := New([]string{""})
	k8s.interfaceAddrsFunc = localPodIP
	k8s.autoPathSearch = searchFromResolvConf()

	opts := dnsControlOpts{
		resyncPeriod: defaultResyncPeriod,
	}

	for c.Next() {
		zones := c.RemainingArgs()

		if len(zones) != 0 {
			k8s.Zones = zones
			for i := 0; i < len(k8s.Zones); i++ {
				k8s.Zones[i] = middleware.Host(k8s.Zones[i]).Normalize()
			}
		} else {
			k8s.Zones = make([]string, len(c.ServerBlockKeys))
			for i := 0; i < len(c.ServerBlockKeys); i++ {
				k8s.Zones[i] = middleware.Host(c.ServerBlockKeys[i]).Normalize()
			}
		}

		k8s.primaryZoneIndex = -1
		for i, z := range k8s.Zones {
			if strings.HasSuffix(z, "in-addr.arpa.") || strings.HasSuffix(z, "ip6.arpa.") {
				continue
			}
			k8s.primaryZoneIndex = i
			break
		}

		if k8s.primaryZoneIndex == -1 {
			return nil, opts, errors.New("non-reverse zone name must be used")
		}

		for c.NextBlock() {
			switch c.Val() {
			case "pods":
				args := c.RemainingArgs()
				if len(args) == 1 {
					switch args[0] {
					case podModeDisabled, podModeInsecure, podModeVerified:
						k8s.podMode = args[0]
					default:
						return nil, opts, fmt.Errorf("wrong value for pods: %s,  must be one of: disabled, verified, insecure", args[0])
					}
					continue
				}
				return nil, opts, c.ArgErr()
			case "namespaces":
				args := c.RemainingArgs()
				if len(args) > 0 {
					for _, a := range args {
						k8s.Namespaces[a] = true
					}
					continue
				}
				return nil, opts, c.ArgErr()
			case "endpoint":
				args := c.RemainingArgs()
				if len(args) > 0 {
					for _, endpoint := range strings.Split(args[0], ",") {
						k8s.APIServerList = append(k8s.APIServerList, strings.TrimSpace(endpoint))
					}
					continue
				}
				return nil, opts, c.ArgErr()
			case "tls": // cert key cacertfile
				args := c.RemainingArgs()
				if len(args) == 3 {
					k8s.APIClientCert, k8s.APIClientKey, k8s.APICertAuth = args[0], args[1], args[2]
					continue
				}
				return nil, opts, c.ArgErr()
			case "resyncperiod":
				args := c.RemainingArgs()
				if len(args) > 0 {
					rp, err := time.ParseDuration(args[0])
					if err != nil {
						return nil, opts, fmt.Errorf("unable to parse resync duration value: '%v': %v", args[0], err)
					}
					opts.resyncPeriod = rp
					continue
				}
				return nil, opts, c.ArgErr()
			case "labels":
				args := c.RemainingArgs()
				if len(args) > 0 {
					labelSelectorString := strings.Join(args, " ")
					ls, err := unversionedapi.ParseToLabelSelector(labelSelectorString)
					if err != nil {
						return nil, opts, fmt.Errorf("unable to parse label selector value: '%v': %v", labelSelectorString, err)
					}
					opts.labelSelector = ls
					continue
				}
				return nil, opts, c.ArgErr()
			case "fallthrough":
				args := c.RemainingArgs()
				if len(args) == 0 {
					k8s.Fallthrough = true
					continue
				}
				return nil, opts, c.ArgErr()
			case "upstream":
				args := c.RemainingArgs()
				if len(args) == 0 {
					return nil, opts, c.ArgErr()
				}
				ups, err := dnsutil.ParseHostPortOrFile(args...)
				if err != nil {
					return nil, opts, err
				}
				k8s.Proxy = proxy.NewLookup(ups)
			default:
				return nil, opts, c.Errf("unknown property '%s'", c.Val())
			}
		}
	}
	return k8s, opts, nil
}

func searchFromResolvConf() []string {
	rc, err := dns.ClientConfigFromFile("/etc/resolv.conf")
	if err != nil {
		return nil
	}
	middleware.Zones(rc.Search).Normalize()
	return rc.Search
}

const defaultResyncPeriod = 5 * time.Minute
ss='deletions'>-6/+35 * fix astro scoping of "@import" inside of style tags * Create lovely-lies-dress.md * Update compile.ts * fix smoke test * Update package.json 2022-02-25[ci] update lockfile (#2659)Gravatar Fred K. Schott 1-20/+20 Co-authored-by: FredKSchott <FredKSchott@users.noreply.github.com> 2022-02-25feat: improve third-party Astro package compatability (#2665)Gravatar Nate Moore 3-6/+100 2022-02-25get new example working during buildGravatar Fred K. Schott 4-16/+21 2022-02-25[ci] yarn formatGravatar FredKSchott 1-7/+6 2022-02-25Add Non-HTML Pages example (#2637)Gravatar Joel Kuzmarski 11-0/+136 * Add Non-HTML Pages example * Rename dir non-html-example to non-html-pages * Update name to non-html-pages in package.json 2022-02-25[ci] collect statsGravatar FredKSchott 1-0/+1 2022-02-24[ci] yarn formatGravatar natemoo-re 2-24/+24 2022-02-24[ci] release (#2641)astro@0.23.1@astrojs/markdown-remark@0.6.2Gravatar github-actions[bot] 38-90/+81 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2022-02-24ensure utf8 encoding when serving html (#2654)Gravatar Fred K. Schott 3-4/+9 * ensure utf8 encoding on servers * Create spicy-tomatoes-act.md * Update spicy-tomatoes-act.md Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> 2022-02-24fix(core): Issue #2625. error with process.env.LANG larger than 5 (#2645)Gravatar Javier Cortés 2-1/+6 * Update logger.ts Solving #2625 * chore: add changeset Co-authored-by: Nate Moore <nate@skypack.dev> 2022-02-24[ci] update lockfile (#2646)Gravatar Fred K. Schott 1-130/+124 Co-authored-by: FredKSchott <FredKSchott@users.noreply.github.com> 2022-02-24chore: upgrade compiler (#2653)Gravatar Nate Moore 3-11/+11 2022-02-24[ci] yarn formatGravatar natemoo-re 2-5/+5 2022-02-24Add fine-grained HMR support (#2649)Gravatar Nate Moore 7-36/+37 * feat: add fine-grained HMR support * chore: lint * chore: lint * fix: handle hmr with custom event handler * refactor: cleanup hmr script 2022-02-24[ci] collect statsGravatar FredKSchott 1-0/+1 2022-02-23Fixed incorrect types and imports (#2630)Gravatar Juan Martín Seery 27-35/+37 * Fixed incorrect types and imports * Changeset 2022-02-23Add sass dev dep to blog-multiple-authors example (#2643)Gravatar Joel Kuzmarski 1-1/+2 Otherwise, new stackblitz projects throw an error. 2022-02-23Fix(component): align starting position in Markdown slot (#2631)Gravatar Shinobu Hayashi 4-6/+61 * Fix: align markdown starting position in each line * Chore: add testcase for aligning starting position in each line * Chore: update the test case on astro-markdown custom language * Update: remove trimmed only startWith trimmed space 2022-02-23[ci] yarn formatGravatar matthewp 1-1/+1 2022-02-23Run all smoke tests with the static build (#2609)Gravatar Matthew Phillips 2-26/+32 * Run all smoke tests with the static build * Use a direct relative path * Always use the static build * Use a path that works in both static and regualr build * Always download the zip * astro.build only needs to run once 2022-02-23[ci] collect statsGravatar FredKSchott 1-0/+1 2022-02-22[ci] update lockfile (#2624)Gravatar Fred K. Schott 1-171/+201 Co-authored-by: FredKSchott <FredKSchott@users.noreply.github.com> 2022-02-22Fixed shiki import to work with "type": "module" (#2628)Gravatar Juan Martín Seery 3-5/+13 * Fixed shiki import to work with "type": "module" * Changeset * Separated types import * Add "* as" to type import