1 package mapper
2
3 import (
4 "fmt"
5 "testing"
6
7 "github.com/stretchr/testify/assert"
8 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9
10 "edge-infra.dev/pkg/edge/api/graph/model"
11 "edge-infra.dev/pkg/edge/api/utils"
12
13 v1ien "edge-infra.dev/pkg/sds/ien/k8s/apis/v1"
14 )
15
16 var (
17 terminalID = "0e38e7d7-1a2c-4cce-8b81-79a10f1b9765"
18 clusterEdgeID = "b74a86c3-1294-44f6-8a1d-2934c06fac4d"
19 edgeVersion = "v0.18.0"
20 clusterName = "cluster-name-1"
21 hostname = "ien-a253ebb27439"
22 lane01 = "lane1"
23 swapEnabled = false
24
25
26 controlRole = model.TerminalClassType(model.TerminalRoleTypeControlplane.String())
27 serverClass = model.TerminalClassType(model.TerminalClassTypeServer.String())
28
29 terminalDiskID = "96f7fb7a-e697-4a68-b6f9-a778db6c3610"
30 terminalDiskTypeEmpty = model.TerminalDiscoverDisksTypeEmpty
31
32 interfaceID = "53154d95-a0c7-4be8-abb9-0c2aa2b0d98f"
33 interfaceID2 = "0e5944bc-1633-44b6-aff9-79e6c63bb44a"
34 macAddress = "a2:53:eb:b2:74:39"
35 macAddress2 = "90:74:c2:0f:d8:77"
36 dhcp4False = false
37 dhcp4True = true
38 dhcp6False = false
39 dhcp6True = true
40 gateway4 = "34.48.218.56"
41 gateway6 = "f45a:2064:3ad6:6e0d:9044:03ef:15b1:4ce1"
42
43 addressID = "d257bf51-dfb8-4a8b-bb4c-55eb54195f6c"
44 addressID2 = "3248ae96-4f40-4269-8675-ad39d79f6011"
45 ipv4 = "34.48.218.53"
46 ipv6 = "5f17:a4ef:602a:4fb1:eedd:94e1:441a:086d"
47 prefixLen16 = 16
48 prefixLen24 = 24
49 inetFamily = model.InetTypeInet
50 inet6Family = model.InetTypeInet6
51 kubeVipIP = "10.0.0.1"
52 customLabels = map[string]string{
53 "custom.node.ncr.com/test1": "test-1-description",
54 "custom.node.ncr.com/test2": "test-2-description",
55 }
56 emptyCustomLabels = make(map[string]string, 0)
57 )
58
59 func TestTerminalToIENodeWithoutDHCP(t *testing.T) {
60 terminal := createDefaultTerminal(gateway4, ipv4)
61 dnsService := &model.ClusterNetworkServiceInfo{
62 ServiceType: "dns",
63 Family: "inet",
64 IP: "8.8.8.8",
65 }
66
67 ntpService := &model.ClusterNetworkServiceInfo{
68 ServiceType: "ntp",
69 Family: "inet",
70 IP: "time.google.com",
71 }
72
73 kubeVip := &model.ClusterNetworkServiceInfo{
74 ServiceType: "kube-vip",
75 Family: "inet",
76 IP: kubeVipIP,
77 }
78
79 clusterNetworkServices := []*model.ClusterNetworkServiceInfo{dnsService, ntpService, kubeVip}
80
81 expectedIENode := v1ien.IENode{
82 TypeMeta: metav1.TypeMeta{
83 Kind: v1ien.IENodeGVK.Kind,
84 APIVersion: v1ien.IENodeGVK.GroupVersion().String(),
85 },
86 ObjectMeta: metav1.ObjectMeta{
87 Name: utils.CreateIENodeHostname(terminal.Interfaces[0].MacAddress),
88 Labels: map[string]string{
89 "node.ncr.com/terminal-id": terminal.TerminalID,
90 },
91 },
92 Spec: v1ien.IENodeSpec{
93 Role: v1ien.Role(terminal.Role),
94 Lane: *terminal.Lane,
95 Class: v1ien.Class(*terminal.Class),
96 SwapEnabled: &swapEnabled,
97 Network: []v1ien.Network{
98 {
99 DHCP4: terminal.Interfaces[0].Dhcp4,
100 DHCP6: terminal.Interfaces[0].Dhcp6,
101 MacAddress: terminal.Interfaces[0].MacAddress,
102 Gateway4: *terminal.Interfaces[0].Gateway4,
103 Gateway6: *terminal.Interfaces[0].Gateway6,
104 Addresses: []string{
105 fmt.Sprintf("%s/%d", *terminal.Interfaces[0].Addresses[0].IP, terminal.Interfaces[0].Addresses[0].PrefixLen),
106 fmt.Sprintf("%s/%d", *terminal.Interfaces[0].Addresses[1].IP, terminal.Interfaces[0].Addresses[1].PrefixLen),
107 },
108 },
109 },
110 PrimaryInterface: &v1ien.PrimaryInterface{
111 InterfaceID: terminal.Interfaces[0].TerminalInterfaceID,
112 MacAddresses: []string{terminal.Interfaces[0].MacAddress},
113 },
114 NetworkServices: v1ien.NetworkServices{
115 NTPServers: []string{"time.google.com"},
116 DNSServers: []string{"8.8.8.8"},
117 KubeVip: kubeVipIP,
118 },
119 CustomLabels: emptyCustomLabels,
120 },
121 }
122
123 actualIENode := TerminalToIENode(terminal, clusterNetworkServices, emptyCustomLabels, edgeVersion)
124 assert.Equal(t, expectedIENode, actualIENode)
125 }
126
127
128 func TestTerminalToIENodeWithDHCP(t *testing.T) {
129 terminal0 := createDefaultTerminal(gateway4, ipv4)
130 iface := terminal0.Interfaces[0]
131 iface.Dhcp4 = dhcp4True
132 iface.Gateway4 = nil
133 iface.Addresses[0].IP = nil
134
135 dnsService := &model.ClusterNetworkServiceInfo{
136 ServiceType: "dns",
137 Family: "inet",
138 IP: "8.8.8.8",
139 }
140
141 ntpService := &model.ClusterNetworkServiceInfo{
142 ServiceType: "ntp",
143 Family: "inet",
144 IP: "time.google.com",
145 }
146
147 clusterNetworkServices := []*model.ClusterNetworkServiceInfo{dnsService, ntpService}
148
149 expectedIENode := v1ien.IENode{
150 TypeMeta: metav1.TypeMeta{
151 Kind: v1ien.IENodeGVK.Kind,
152 APIVersion: v1ien.GroupVersion.String(),
153 },
154 ObjectMeta: metav1.ObjectMeta{
155 Name: utils.CreateIENodeHostname(terminal0.Interfaces[0].MacAddress),
156 Labels: map[string]string{
157 "node.ncr.com/terminal-id": terminal0.TerminalID,
158 },
159 },
160 Spec: v1ien.IENodeSpec{
161 Role: v1ien.Role(terminal0.Role),
162 Lane: *terminal0.Lane,
163 Class: v1ien.Class(*terminal0.Class),
164 SwapEnabled: &swapEnabled,
165 Network: []v1ien.Network{
166 {
167 DHCP4: terminal0.Interfaces[0].Dhcp4,
168 DHCP6: terminal0.Interfaces[0].Dhcp6,
169 MacAddress: terminal0.Interfaces[0].MacAddress,
170 Gateway6: *terminal0.Interfaces[0].Gateway6,
171 Addresses: []string{fmt.Sprintf("%s/%d", *terminal0.Interfaces[0].Addresses[1].IP,
172 terminal0.Interfaces[0].Addresses[1].PrefixLen)},
173 },
174 },
175 PrimaryInterface: &v1ien.PrimaryInterface{
176 InterfaceID: terminal0.Interfaces[0].TerminalInterfaceID,
177 MacAddresses: []string{terminal0.Interfaces[0].MacAddress},
178 },
179 NetworkServices: v1ien.NetworkServices{
180 NTPServers: []string{"time.google.com"},
181 DNSServers: []string{"8.8.8.8"},
182 },
183 CustomLabels: emptyCustomLabels,
184 },
185 }
186
187 actualIENode := TerminalToIENode(terminal0, clusterNetworkServices, emptyCustomLabels, edgeVersion)
188 assert.Equal(t, expectedIENode, actualIENode)
189
190 terminal1 := createDefaultTerminal(gateway4, ipv4)
191 iface = terminal1.Interfaces[0]
192 iface.Dhcp6 = dhcp6True
193 iface.Gateway6 = nil
194 iface.Addresses[1].IP = nil
195
196 dnsService = &model.ClusterNetworkServiceInfo{
197 ServiceType: "dns",
198 Family: "inet",
199 IP: "8.8.8.8",
200 }
201
202 ntpService = &model.ClusterNetworkServiceInfo{
203 ServiceType: "ntp",
204 Family: "inet",
205 IP: "time.google.com",
206 }
207
208 clusterNetworkServices = []*model.ClusterNetworkServiceInfo{dnsService, ntpService}
209
210 expectedIENode = v1ien.IENode{
211 TypeMeta: metav1.TypeMeta{
212 Kind: v1ien.IENodeGVK.Kind,
213 APIVersion: v1ien.IENodeGVK.GroupVersion().String(),
214 },
215 ObjectMeta: metav1.ObjectMeta{
216 Name: utils.CreateIENodeHostname(terminal1.Interfaces[0].MacAddress),
217 Labels: map[string]string{
218 "node.ncr.com/terminal-id": terminal1.TerminalID,
219 },
220 },
221 Spec: v1ien.IENodeSpec{
222 Role: v1ien.Role(terminal0.Role),
223 Lane: *terminal0.Lane,
224 Class: v1ien.Class(*terminal0.Class),
225 SwapEnabled: &swapEnabled,
226 Network: []v1ien.Network{
227 {
228 DHCP4: terminal1.Interfaces[0].Dhcp4,
229 DHCP6: terminal1.Interfaces[0].Dhcp6,
230 MacAddress: terminal1.Interfaces[0].MacAddress,
231 Gateway4: *terminal1.Interfaces[0].Gateway4,
232 Addresses: []string{fmt.Sprintf("%s/%d", *terminal1.Interfaces[0].Addresses[0].IP,
233 terminal1.Interfaces[0].Addresses[0].PrefixLen)},
234 },
235 },
236 PrimaryInterface: &v1ien.PrimaryInterface{
237 InterfaceID: terminal0.Interfaces[0].TerminalInterfaceID,
238 MacAddresses: []string{terminal0.Interfaces[0].MacAddress},
239 },
240 NetworkServices: v1ien.NetworkServices{
241 NTPServers: []string{"time.google.com"},
242 DNSServers: []string{"8.8.8.8"},
243 },
244 CustomLabels: emptyCustomLabels,
245 },
246 }
247
248 actualIENode = TerminalToIENode(terminal1, clusterNetworkServices, emptyCustomLabels, edgeVersion)
249 assert.Equal(t, expectedIENode, actualIENode)
250
251 terminal2 := createDefaultTerminal(gateway4, ipv4)
252 iface = terminal2.Interfaces[0]
253 iface.Dhcp4, iface.Dhcp6 = dhcp4True, dhcp6True
254 iface.Gateway4, iface.Gateway6 = nil, nil
255 iface.Addresses[0].IP, iface.Addresses[1].IP = nil, nil
256
257 dnsService = &model.ClusterNetworkServiceInfo{
258 ServiceType: "dns",
259 Family: "inet",
260 IP: "8.8.8.8",
261 }
262
263 ntpService = &model.ClusterNetworkServiceInfo{
264 ServiceType: "ntp",
265 Family: "inet",
266 IP: "time.google.com",
267 }
268
269 clusterNetworkServices = []*model.ClusterNetworkServiceInfo{dnsService, ntpService}
270
271 expectedIENode = v1ien.IENode{
272 TypeMeta: metav1.TypeMeta{
273 Kind: v1ien.IENodeGVK.Kind,
274 APIVersion: v1ien.IENodeGVK.GroupVersion().String(),
275 },
276 ObjectMeta: metav1.ObjectMeta{
277 Name: utils.CreateIENodeHostname(terminal2.Interfaces[0].MacAddress),
278 Labels: map[string]string{
279 "node.ncr.com/terminal-id": terminal2.TerminalID,
280 },
281 },
282 Spec: v1ien.IENodeSpec{
283 Role: v1ien.Role(terminal0.Role),
284 Lane: *terminal0.Lane,
285 Class: v1ien.Class(*terminal0.Class),
286 SwapEnabled: &swapEnabled,
287 Network: []v1ien.Network{
288 {
289 DHCP4: terminal2.Interfaces[0].Dhcp4,
290 DHCP6: terminal2.Interfaces[0].Dhcp6,
291 MacAddress: terminal2.Interfaces[0].MacAddress,
292 },
293 },
294 PrimaryInterface: &v1ien.PrimaryInterface{
295 InterfaceID: terminal0.Interfaces[0].TerminalInterfaceID,
296 MacAddresses: []string{terminal0.Interfaces[0].MacAddress},
297 },
298 NetworkServices: v1ien.NetworkServices{
299 NTPServers: []string{"time.google.com"},
300 DNSServers: []string{"8.8.8.8"},
301 },
302 CustomLabels: emptyCustomLabels,
303 },
304 }
305
306 actualIENode = TerminalToIENode(terminal2, clusterNetworkServices, emptyCustomLabels, edgeVersion)
307 assert.Equal(t, expectedIENode, actualIENode)
308 }
309
310 func TestTerminalToIENodeWithoutAddress(t *testing.T) {
311 terminal := createDefaultTerminal(gateway4, ipv4)
312 terminal.Interfaces[0].Dhcp4, terminal.Interfaces[0].Dhcp6 = true, true
313 terminal.Interfaces[0].Gateway4, terminal.Interfaces[0].Gateway6 = nil, nil
314 terminal.Interfaces[0].Addresses = nil
315
316 dnsService := &model.ClusterNetworkServiceInfo{
317 ServiceType: "dns",
318 Family: "inet",
319 IP: "8.8.8.8",
320 }
321 ntpService := &model.ClusterNetworkServiceInfo{
322 ServiceType: "ntp",
323 Family: "inet",
324 IP: "time.google.com",
325 }
326 clusterNetworkServices := []*model.ClusterNetworkServiceInfo{dnsService, ntpService}
327
328 expectedIENode := v1ien.IENode{
329 TypeMeta: metav1.TypeMeta{
330 Kind: v1ien.IENodeGVK.Kind,
331 APIVersion: v1ien.IENodeGVK.GroupVersion().String(),
332 },
333 ObjectMeta: metav1.ObjectMeta{
334 Name: utils.CreateIENodeHostname(terminal.Interfaces[0].MacAddress),
335 Labels: map[string]string{
336 "node.ncr.com/terminal-id": terminal.TerminalID,
337 },
338 },
339 Spec: v1ien.IENodeSpec{
340 Role: v1ien.Role(terminal.Role),
341 Lane: *terminal.Lane,
342 Class: v1ien.Class(*terminal.Class),
343 SwapEnabled: &swapEnabled,
344 Network: []v1ien.Network{
345 {
346 DHCP4: terminal.Interfaces[0].Dhcp4,
347 DHCP6: terminal.Interfaces[0].Dhcp6,
348 MacAddress: terminal.Interfaces[0].MacAddress,
349 },
350 },
351 NetworkServices: v1ien.NetworkServices{
352 NTPServers: []string{"time.google.com"},
353 DNSServers: []string{"8.8.8.8"},
354 },
355 PrimaryInterface: &v1ien.PrimaryInterface{
356 InterfaceID: terminal.Interfaces[0].TerminalInterfaceID,
357 MacAddresses: []string{terminal.Interfaces[0].MacAddress},
358 },
359 CustomLabels: emptyCustomLabels,
360 },
361 }
362
363 actualIENode := TerminalToIENode(terminal, clusterNetworkServices, emptyCustomLabels, edgeVersion)
364 assert.Equal(t, expectedIENode, actualIENode)
365 }
366
367
368 func TestTerminalToIENodeWithLabels(t *testing.T) {
369 terminal := createDefaultTerminal(gateway4, ipv4)
370 terminal.Interfaces[0].Dhcp4, terminal.Interfaces[0].Dhcp6 = true, true
371 terminal.Interfaces[0].Gateway4, terminal.Interfaces[0].Gateway6 = nil, nil
372 terminal.Interfaces[0].Addresses = nil
373
374 dnsService := &model.ClusterNetworkServiceInfo{
375 ServiceType: "dns",
376 Family: "inet",
377 IP: "8.8.8.8",
378 }
379 ntpService := &model.ClusterNetworkServiceInfo{
380 ServiceType: "ntp",
381 Family: "inet",
382 IP: "time.google.com",
383 }
384 clusterNetworkServices := []*model.ClusterNetworkServiceInfo{dnsService, ntpService}
385
386 expectedIENode := v1ien.IENode{
387 TypeMeta: metav1.TypeMeta{
388 Kind: v1ien.IENodeGVK.Kind,
389 APIVersion: v1ien.IENodeGVK.GroupVersion().String(),
390 },
391 ObjectMeta: metav1.ObjectMeta{
392 Name: utils.CreateIENodeHostname(terminal.Interfaces[0].MacAddress),
393 Labels: map[string]string{
394 "node.ncr.com/terminal-id": terminal.TerminalID,
395 },
396 },
397 Spec: v1ien.IENodeSpec{
398 Role: v1ien.Role(terminal.Role),
399 Lane: *terminal.Lane,
400 Class: v1ien.Class(*terminal.Class),
401 SwapEnabled: &swapEnabled,
402 Network: []v1ien.Network{
403 {
404 DHCP4: terminal.Interfaces[0].Dhcp4,
405 DHCP6: terminal.Interfaces[0].Dhcp6,
406 MacAddress: terminal.Interfaces[0].MacAddress,
407 },
408 },
409 PrimaryInterface: &v1ien.PrimaryInterface{
410 InterfaceID: terminal.Interfaces[0].TerminalInterfaceID,
411 MacAddresses: []string{terminal.Interfaces[0].MacAddress},
412 },
413 NetworkServices: v1ien.NetworkServices{
414 NTPServers: []string{"time.google.com"},
415 DNSServers: []string{"8.8.8.8"},
416 },
417 CustomLabels: customLabels,
418 },
419 }
420
421 actualIENode := TerminalToIENode(terminal, clusterNetworkServices, customLabels, edgeVersion)
422 assert.Equal(t, expectedIENode, actualIENode)
423 }
424
425 func TestTerminalToIENodeWithDefinedPrimaryInterface(t *testing.T) {
426 terminal := createDefaultTerminal(gateway4, ipv4)
427
428 terminal.Interfaces[0].Addresses = nil
429 terminal.Interfaces[0].Gateway4 = nil
430 terminal.Interfaces[0].Gateway6 = nil
431
432 terminal.Interfaces = append(terminal.Interfaces,
433 &model.TerminalInterface{
434 TerminalInterfaceID: interfaceID2,
435 TerminalID: terminalID,
436 MacAddress: macAddress2,
437 Dhcp4: dhcp4True,
438 Dhcp6: dhcp6False,
439 },
440 )
441
442 terminal.PrimaryInterface = &interfaceID2
443
444 dnsService := &model.ClusterNetworkServiceInfo{
445 ServiceType: "dns",
446 Family: "inet",
447 IP: "8.8.8.8",
448 }
449
450 ntpService := &model.ClusterNetworkServiceInfo{
451 ServiceType: "ntp",
452 Family: "inet",
453 IP: "time.google.com",
454 }
455
456 kubeVip := &model.ClusterNetworkServiceInfo{
457 ServiceType: "kube-vip",
458 Family: "inet",
459 IP: kubeVipIP,
460 }
461
462 clusterNetworkServices := []*model.ClusterNetworkServiceInfo{dnsService, ntpService, kubeVip}
463
464 expectedIENode := v1ien.IENode{
465 TypeMeta: metav1.TypeMeta{
466 Kind: v1ien.IENodeGVK.Kind,
467 APIVersion: v1ien.IENodeGVK.GroupVersion().String(),
468 },
469 ObjectMeta: metav1.ObjectMeta{
470 Name: utils.CreateIENodeHostname(terminal.Interfaces[0].MacAddress),
471 Labels: map[string]string{
472 "node.ncr.com/terminal-id": terminal.TerminalID,
473 },
474 },
475 Spec: v1ien.IENodeSpec{
476 Role: v1ien.Role(terminal.Role),
477 Lane: *terminal.Lane,
478 Class: v1ien.Class(*terminal.Class),
479 SwapEnabled: &swapEnabled,
480 Network: []v1ien.Network{
481 {
482 DHCP4: terminal.Interfaces[0].Dhcp4,
483 DHCP6: terminal.Interfaces[0].Dhcp6,
484 MacAddress: terminal.Interfaces[0].MacAddress,
485 },
486 {
487 DHCP4: terminal.Interfaces[1].Dhcp4,
488 DHCP6: terminal.Interfaces[1].Dhcp6,
489 MacAddress: terminal.Interfaces[1].MacAddress,
490 },
491 },
492 PrimaryInterface: &v1ien.PrimaryInterface{
493 InterfaceID: terminal.Interfaces[1].TerminalInterfaceID,
494 MacAddresses: []string{terminal.Interfaces[1].MacAddress},
495 },
496 NetworkServices: v1ien.NetworkServices{
497 NTPServers: []string{"time.google.com"},
498 DNSServers: []string{"8.8.8.8"},
499 KubeVip: kubeVipIP,
500 },
501 CustomLabels: emptyCustomLabels,
502 },
503 }
504
505 actualIENode := TerminalToIENode(terminal, clusterNetworkServices, emptyCustomLabels, edgeVersion)
506 assert.Equal(t, expectedIENode, actualIENode)
507 }
508
509
510
511 func createDefaultTerminal(gw4 string, addr4 string) *model.Terminal {
512 return &model.Terminal{
513 TerminalID: terminalID,
514 ClusterEdgeID: clusterEdgeID,
515 Role: model.TerminalRoleType(controlRole),
516 Lane: &lane01,
517 Hostname: hostname,
518 ClusterName: clusterName,
519 Class: &serverClass,
520 SwapEnabled: swapEnabled,
521 DiscoverDisks: &terminalDiskTypeEmpty,
522 Disks: []*model.TerminalDisk{
523 {
524 TerminalDiskID: terminalDiskID,
525 TerminalID: terminalID,
526 ExpectEmpty: false,
527 IncludeDisk: true,
528 UsePart: false,
529 },
530 },
531 PrimaryInterface: &interfaceID,
532 Interfaces: []*model.TerminalInterface{
533 {
534 TerminalInterfaceID: interfaceID,
535 TerminalID: terminalID,
536 MacAddress: macAddress,
537 Dhcp4: dhcp4False,
538 Dhcp6: dhcp6False,
539 Gateway4: &gw4,
540 Gateway6: &gateway6,
541 Addresses: []*model.TerminalAddress{
542 {
543 TerminalAddressID: addressID,
544 TerminalInterfaceID: interfaceID,
545 IP: &addr4,
546 PrefixLen: prefixLen16,
547 Family: inetFamily,
548 },
549 {
550 TerminalAddressID: addressID2,
551 TerminalInterfaceID: interfaceID,
552 IP: &ipv6,
553 PrefixLen: prefixLen24,
554 Family: inet6Family,
555 },
556 },
557 },
558 },
559 }
560 }
561
View as plain text