1
16
17 package util
18
19 import (
20 "testing"
21
22 kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
23 )
24
25 func TestGetControlPlaneEndpoint(t *testing.T) {
26 var tests = []struct {
27 name string
28 cfg *kubeadmapi.InitConfiguration
29 expectedEndpoint string
30 expectedError bool
31 }{
32 {
33 name: "use ControlPlaneEndpoint (dns) if fully defined",
34 cfg: &kubeadmapi.InitConfiguration{
35 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
36 BindPort: 4567,
37 AdvertiseAddress: "4.5.6.7",
38 },
39 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
40 ControlPlaneEndpoint: "cp.k8s.io:1234",
41 },
42 },
43 expectedEndpoint: "https://cp.k8s.io:1234",
44 },
45 {
46 name: "use ControlPlaneEndpoint (ipv4) if fully defined",
47 cfg: &kubeadmapi.InitConfiguration{
48 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
49 BindPort: 4567,
50 AdvertiseAddress: "4.5.6.7",
51 },
52 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
53 ControlPlaneEndpoint: "1.2.3.4:1234",
54 },
55 },
56 expectedEndpoint: "https://1.2.3.4:1234",
57 },
58 {
59 name: "use ControlPlaneEndpoint (ipv6) if fully defined",
60 cfg: &kubeadmapi.InitConfiguration{
61 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
62 BindPort: 4567,
63 AdvertiseAddress: "4.5.6.7",
64 },
65 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
66 ControlPlaneEndpoint: "[2001:db8::1]:1234",
67 },
68 },
69 expectedEndpoint: "https://[2001:db8::1]:1234",
70 },
71 {
72 name: "use ControlPlaneEndpoint (dns) + BindPort if ControlPlaneEndpoint defined without port",
73 cfg: &kubeadmapi.InitConfiguration{
74 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
75 BindPort: 4567,
76 AdvertiseAddress: "4.5.6.7",
77 },
78 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
79
80 ControlPlaneEndpoint: "cp.k8s.io",
81 },
82 },
83 expectedEndpoint: "https://cp.k8s.io:4567",
84 },
85 {
86 name: "use ControlPlaneEndpoint (ipv4) + BindPort if ControlPlaneEndpoint defined without port",
87 cfg: &kubeadmapi.InitConfiguration{
88 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
89 BindPort: 4567,
90 AdvertiseAddress: "4.5.6.7",
91 },
92 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
93 ControlPlaneEndpoint: "1.2.3.4",
94 },
95 },
96 expectedEndpoint: "https://1.2.3.4:4567",
97 },
98 {
99 name: "use ControlPlaneEndpoint (ipv6) + BindPort if ControlPlaneEndpoint defined without port",
100 cfg: &kubeadmapi.InitConfiguration{
101 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
102 BindPort: 4567,
103 AdvertiseAddress: "4.5.6.7",
104 },
105 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
106
107 ControlPlaneEndpoint: "2001:db8::1",
108 },
109 },
110 expectedEndpoint: "https://[2001:db8::1]:4567",
111 },
112 {
113 name: "use AdvertiseAddress (ipv4) + BindPort if ControlPlaneEndpoint is not defined",
114 cfg: &kubeadmapi.InitConfiguration{
115 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
116 BindPort: 4567,
117 AdvertiseAddress: "4.5.6.7",
118 },
119 },
120 expectedEndpoint: "https://4.5.6.7:4567",
121 },
122 {
123 name: "use AdvertiseAddress (ipv6) + BindPort if ControlPlaneEndpoint is not defined",
124 cfg: &kubeadmapi.InitConfiguration{
125 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
126 BindPort: 4567,
127 AdvertiseAddress: "2001:db8::1",
128 },
129 },
130 expectedEndpoint: "https://[2001:db8::1]:4567",
131 },
132 {
133 name: "fail if invalid BindPort",
134 cfg: &kubeadmapi.InitConfiguration{
135 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
136 BindPort: 0,
137 },
138 },
139 expectedError: true,
140 },
141 {
142 name: "fail if invalid ControlPlaneEndpoint (dns)",
143 cfg: &kubeadmapi.InitConfiguration{
144 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
145 ControlPlaneEndpoint: "bad!!.cp.k8s.io",
146 },
147 },
148 expectedError: true,
149 },
150 {
151 name: "fail if invalid ControlPlaneEndpoint (ip4)",
152 cfg: &kubeadmapi.InitConfiguration{
153 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
154 ControlPlaneEndpoint: "1..0",
155 },
156 },
157 expectedError: true,
158 },
159 {
160 name: "fail if invalid ControlPlaneEndpoint (ip6)",
161 cfg: &kubeadmapi.InitConfiguration{
162 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
163 ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313",
164 },
165 },
166 expectedError: true,
167 },
168 {
169 name: "fail if invalid ControlPlaneEndpoint (port)",
170 cfg: &kubeadmapi.InitConfiguration{
171 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
172 ControlPlaneEndpoint: "cp.k8s.io:0",
173 },
174 },
175 expectedError: true,
176 },
177 {
178 name: "fail if invalid AdvertiseAddress (ip4)",
179 cfg: &kubeadmapi.InitConfiguration{
180 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
181 AdvertiseAddress: "1..0",
182 BindPort: 4567,
183 },
184 },
185 expectedError: true,
186 },
187 {
188 name: "fail if invalid AdvertiseAddress (ip6)",
189 cfg: &kubeadmapi.InitConfiguration{
190 LocalAPIEndpoint: kubeadmapi.APIEndpoint{
191 AdvertiseAddress: "1200::AB00:1234::2552:7777:1313",
192 BindPort: 4567,
193 },
194 },
195 expectedError: true,
196 },
197 }
198
199 for _, rt := range tests {
200 t.Run(rt.name, func(t *testing.T) {
201 actualEndpoint, actualError := GetControlPlaneEndpoint(rt.cfg.ControlPlaneEndpoint, &rt.cfg.LocalAPIEndpoint)
202
203 if (actualError != nil) && !rt.expectedError {
204 t.Errorf("%s unexpected failure: %v", rt.name, actualError)
205 return
206 } else if (actualError == nil) && rt.expectedError {
207 t.Errorf("%s passed when expected to fail", rt.name)
208 return
209 }
210
211 if actualEndpoint != rt.expectedEndpoint {
212 t.Errorf("%s returned invalid endpoint %s, expected %s", rt.name, actualEndpoint, rt.expectedEndpoint)
213 }
214 })
215 }
216 }
217
218 func TestParseHostPort(t *testing.T) {
219
220 var tests = []struct {
221 name string
222 hostport string
223 expectedHost string
224 expectedPort string
225 expectedError bool
226 }{
227 {
228 name: "valid dns",
229 hostport: "cp.k8s.io",
230 expectedHost: "cp.k8s.io",
231 expectedPort: "",
232 },
233 {
234 name: "valid dns:port",
235 hostport: "cp.k8s.io:1234",
236 expectedHost: "cp.k8s.io",
237 expectedPort: "1234",
238 },
239 {
240 name: "valid ip4",
241 hostport: "1.2.3.4",
242 expectedHost: "1.2.3.4",
243 expectedPort: "",
244 },
245 {
246 name: "valid ipv4:port",
247 hostport: "1.2.3.4:1234",
248 expectedHost: "1.2.3.4",
249 expectedPort: "1234",
250 },
251 {
252 name: "valid ipv6",
253 hostport: "2001:db8::1",
254 expectedHost: "2001:db8::1",
255 expectedPort: "",
256 },
257 {
258 name: "valid ipv6:port",
259 hostport: "[2001:db8::1]:1234",
260 expectedHost: "2001:db8::1",
261 expectedPort: "1234",
262 },
263 {
264 name: "invalid port(not a number)",
265 hostport: "cp.k8s.io:aaa",
266 expectedError: true,
267 },
268 {
269 name: "invalid port(out of range, positive port number)",
270 hostport: "cp.k8s.io:987654321",
271 expectedError: true,
272 },
273 {
274 name: "invalid port(out of range, negative port number)",
275 hostport: "cp.k8s.io:-987654321",
276 expectedError: true,
277 },
278 {
279 name: "invalid port(out of range, negative port number)",
280 hostport: "cp.k8s.io:123:123",
281 expectedError: true,
282 },
283 {
284 name: "invalid dns",
285 hostport: "bad!!cp.k8s.io",
286 expectedError: true,
287 },
288 {
289 name: "invalid valid dns:port",
290 hostport: "bad!!cp.k8s.io:1234",
291 expectedError: true,
292 },
293 {
294 name: "invalid ip4, but valid DNS",
295 hostport: "259.2.3.4",
296 expectedHost: "259.2.3.4",
297 },
298 {
299 name: "invalid ip4",
300 hostport: "1..3.4",
301 expectedError: true,
302 },
303 {
304 name: "invalid ip4(2):port",
305 hostport: "1..3.4:1234",
306 expectedError: true,
307 },
308 {
309 name: "invalid ipv6",
310 hostport: "1200::AB00:1234::2552:7777:1313",
311 expectedError: true,
312 },
313 {
314 name: "invalid ipv6:port",
315 hostport: "[1200::AB00:1234::2552:7777:1313]:1234",
316 expectedError: true,
317 },
318 }
319
320 for _, rt := range tests {
321 t.Run(rt.name, func(t *testing.T) {
322 actualHost, actualPort, actualError := ParseHostPort(rt.hostport)
323
324 if (actualError != nil) && !rt.expectedError {
325 t.Errorf("%s unexpected failure: %v", rt.name, actualError)
326 return
327 } else if (actualError == nil) && rt.expectedError {
328 t.Errorf("%s passed when expected to fail", rt.name)
329 return
330 }
331
332 if actualHost != rt.expectedHost {
333 t.Errorf("%s returned invalid host %s, expected %s", rt.name, actualHost, rt.expectedHost)
334 return
335 }
336
337 if actualPort != rt.expectedPort {
338 t.Errorf("%s returned invalid port %s, expected %s", rt.name, actualPort, rt.expectedPort)
339 }
340 })
341 }
342 }
343
344 func TestParsePort(t *testing.T) {
345
346 var tests = []struct {
347 name string
348 port string
349 expectedPort int
350 expectedError bool
351 }{
352 {
353 name: "valid port",
354 port: "1234",
355 expectedPort: 1234,
356 },
357 {
358 name: "invalid port (not a number)",
359 port: "a",
360 expectedError: true,
361 },
362 {
363 name: "invalid port (<1)",
364 port: "-10",
365 expectedError: true,
366 },
367 {
368 name: "invalid port (>65535)",
369 port: "66535",
370 expectedError: true,
371 },
372 }
373
374 for _, rt := range tests {
375 t.Run(rt.name, func(t *testing.T) {
376 actualPort, actualError := ParsePort(rt.port)
377
378 if (actualError != nil) && !rt.expectedError {
379 t.Errorf("%s unexpected failure: %v", rt.name, actualError)
380 return
381 } else if (actualError == nil) && rt.expectedError {
382 t.Errorf("%s passed when expected to fail", rt.name)
383 return
384 }
385
386 if actualPort != rt.expectedPort {
387 t.Errorf("%s returned invalid port %d, expected %d", rt.name, actualPort, rt.expectedPort)
388 }
389 })
390 }
391 }
392
View as plain text