1
16
17 package service
18
19 import (
20 "context"
21 "encoding/json"
22 "reflect"
23 "testing"
24 "time"
25
26 corev1 "k8s.io/api/core/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "k8s.io/apimachinery/pkg/types"
29 "k8s.io/apimachinery/pkg/util/strategicpatch"
30 utilfeature "k8s.io/apiserver/pkg/util/feature"
31 "k8s.io/client-go/informers"
32 clientset "k8s.io/client-go/kubernetes"
33 servicecontroller "k8s.io/cloud-provider/controllers/service"
34 fakecloud "k8s.io/cloud-provider/fake"
35 featuregatetesting "k8s.io/component-base/featuregate/testing"
36 controllersmetrics "k8s.io/component-base/metrics/prometheus/controllers"
37 kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
38 "k8s.io/kubernetes/pkg/features"
39 "k8s.io/kubernetes/test/integration/framework"
40 "k8s.io/utils/net"
41 utilpointer "k8s.io/utils/pointer"
42 )
43
44
45
46 func Test_ServiceLoadBalancerDisableAllocateNodePorts(t *testing.T) {
47 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
48 defer server.TearDownFn()
49
50 client, err := clientset.NewForConfig(server.ClientConfig)
51 if err != nil {
52 t.Fatalf("Error creating clientset: %v", err)
53 }
54
55 ns := framework.CreateNamespaceOrDie(client, "test-service-allocate-node-ports", t)
56 defer framework.DeleteNamespaceOrDie(client, ns, t)
57
58 service := &corev1.Service{
59 ObjectMeta: metav1.ObjectMeta{
60 Name: "test-123",
61 },
62 Spec: corev1.ServiceSpec{
63 Type: corev1.ServiceTypeLoadBalancer,
64 AllocateLoadBalancerNodePorts: utilpointer.Bool(false),
65 Ports: []corev1.ServicePort{{
66 Port: int32(80),
67 }},
68 Selector: map[string]string{
69 "foo": "bar",
70 },
71 },
72 }
73
74 service, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
75 if err != nil {
76 t.Fatalf("Error creating test service: %v", err)
77 }
78
79 if serviceHasNodePorts(service) {
80 t.Error("found node ports when none was expected")
81 }
82 }
83
84
85
86 func Test_ServiceUpdateLoadBalancerDisableAllocateNodePorts(t *testing.T) {
87 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
88 defer server.TearDownFn()
89
90 client, err := clientset.NewForConfig(server.ClientConfig)
91 if err != nil {
92 t.Fatalf("Error creating clientset: %v", err)
93 }
94
95 ns := framework.CreateNamespaceOrDie(client, "test-service-allocate-node-ports", t)
96 defer framework.DeleteNamespaceOrDie(client, ns, t)
97
98 service := &corev1.Service{
99 ObjectMeta: metav1.ObjectMeta{
100 Name: "test-123",
101 },
102 Spec: corev1.ServiceSpec{
103 Type: corev1.ServiceTypeClusterIP,
104 Ports: []corev1.ServicePort{{
105 Port: int32(80),
106 }},
107 Selector: map[string]string{
108 "foo": "bar",
109 },
110 },
111 }
112
113 service, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
114 if err != nil {
115 t.Fatalf("Error creating test service: %v", err)
116 }
117
118 if serviceHasNodePorts(service) {
119 t.Error("found node ports when none was expected")
120 }
121
122 service.Spec.Type = corev1.ServiceTypeLoadBalancer
123 service.Spec.AllocateLoadBalancerNodePorts = utilpointer.Bool(false)
124 service, err = client.CoreV1().Services(ns.Name).Update(context.TODO(), service, metav1.UpdateOptions{})
125 if err != nil {
126 t.Fatalf("Error updating test service: %v", err)
127 }
128
129 if serviceHasNodePorts(service) {
130 t.Error("found node ports when none was expected")
131 }
132 }
133
134
135
136 func Test_ServiceLoadBalancerEnableThenDisableAllocatedNodePorts(t *testing.T) {
137 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
138 defer server.TearDownFn()
139
140 client, err := clientset.NewForConfig(server.ClientConfig)
141 if err != nil {
142 t.Fatalf("Error creating clientset: %v", err)
143 }
144
145 ns := framework.CreateNamespaceOrDie(client, "test-service-deallocate-node-ports", t)
146 defer framework.DeleteNamespaceOrDie(client, ns, t)
147
148 service := &corev1.Service{
149 ObjectMeta: metav1.ObjectMeta{
150 Name: "test-123",
151 },
152 Spec: corev1.ServiceSpec{
153 Type: corev1.ServiceTypeLoadBalancer,
154 AllocateLoadBalancerNodePorts: utilpointer.Bool(true),
155 Ports: []corev1.ServicePort{{
156 Port: int32(80),
157 }},
158 Selector: map[string]string{
159 "foo": "bar",
160 },
161 },
162 }
163
164 service, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
165 if err != nil {
166 t.Fatalf("Error creating test service: %v", err)
167 }
168
169 if !serviceHasNodePorts(service) {
170 t.Error("expected node ports but found none")
171 }
172
173 service.Spec.AllocateLoadBalancerNodePorts = utilpointer.Bool(false)
174 service, err = client.CoreV1().Services(ns.Name).Update(context.TODO(), service, metav1.UpdateOptions{})
175 if err != nil {
176 t.Fatalf("Error updating test service: %v", err)
177 }
178
179 if !serviceHasNodePorts(service) {
180 t.Error("node ports were unexpectedly deallocated")
181 }
182 }
183
184
185
186 func Test_ServiceLoadBalancerDisableAllocatedNodePort(t *testing.T) {
187 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
188 defer server.TearDownFn()
189
190 client, err := clientset.NewForConfig(server.ClientConfig)
191 if err != nil {
192 t.Fatalf("Error creating clientset: %v", err)
193 }
194
195 ns := framework.CreateNamespaceOrDie(client, "test-service-deallocate-node-ports", t)
196 defer framework.DeleteNamespaceOrDie(client, ns, t)
197
198 service := &corev1.Service{
199 ObjectMeta: metav1.ObjectMeta{
200 Name: "test-123",
201 },
202 Spec: corev1.ServiceSpec{
203 Type: corev1.ServiceTypeLoadBalancer,
204 AllocateLoadBalancerNodePorts: utilpointer.Bool(true),
205 Ports: []corev1.ServicePort{{
206 Port: int32(80),
207 }},
208 Selector: map[string]string{
209 "foo": "bar",
210 },
211 },
212 }
213
214 service, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
215 if err != nil {
216 t.Fatalf("Error creating test service: %v", err)
217 }
218
219 if !serviceHasNodePorts(service) {
220 t.Error("expected node ports but found none")
221 }
222
223 service.Spec.AllocateLoadBalancerNodePorts = utilpointer.Bool(false)
224 service.Spec.Ports[0].NodePort = 0
225 service, err = client.CoreV1().Services(ns.Name).Update(context.TODO(), service, metav1.UpdateOptions{})
226 if err != nil {
227 t.Fatalf("Error updating test service: %v", err)
228 }
229
230 if serviceHasNodePorts(service) {
231 t.Error("node ports were expected to be deallocated")
232 }
233 }
234
235
236
237 func Test_ServiceLoadBalancerDisableAllocatedNodePorts(t *testing.T) {
238 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
239 defer server.TearDownFn()
240
241 client, err := clientset.NewForConfig(server.ClientConfig)
242 if err != nil {
243 t.Fatalf("Error creating clientset: %v", err)
244 }
245
246 ns := framework.CreateNamespaceOrDie(client, "test-service-deallocate-node-ports", t)
247 defer framework.DeleteNamespaceOrDie(client, ns, t)
248
249 service := &corev1.Service{
250 ObjectMeta: metav1.ObjectMeta{
251 Name: "test-123",
252 },
253 Spec: corev1.ServiceSpec{
254 Type: corev1.ServiceTypeLoadBalancer,
255 AllocateLoadBalancerNodePorts: utilpointer.Bool(true),
256 Ports: []corev1.ServicePort{{
257 Name: "np-1",
258 Port: int32(80),
259 }, {
260 Name: "np-2",
261 Port: int32(81),
262 }},
263 Selector: map[string]string{
264 "foo": "bar",
265 },
266 },
267 }
268
269 service, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
270 if err != nil {
271 t.Fatalf("Error creating test service: %v", err)
272 }
273
274 if !serviceHasNodePorts(service) {
275 t.Error("expected node ports but found none")
276 }
277
278 service.Spec.AllocateLoadBalancerNodePorts = utilpointer.Bool(false)
279 service.Spec.Ports[0].NodePort = 0
280 service, err = client.CoreV1().Services(ns.Name).Update(context.TODO(), service, metav1.UpdateOptions{})
281 if err != nil {
282 t.Fatalf("Error updating test service: %v", err)
283 }
284
285 if service.Spec.Ports[0].NodePort != 0 {
286 t.Error("node ports[0] was expected to be deallocated")
287 }
288 if service.Spec.Ports[1].NodePort == 0 {
289 t.Error("node ports was not expected to be deallocated")
290 }
291 }
292
293
294
295 func Test_ServiceLoadBalancerDisableAllocatedNodePortsByPatch(t *testing.T) {
296 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
297 defer server.TearDownFn()
298
299 client, err := clientset.NewForConfig(server.ClientConfig)
300 if err != nil {
301 t.Fatalf("Error creating clientset: %v", err)
302 }
303
304 ns := framework.CreateNamespaceOrDie(client, "test-service-deallocate-node-ports", t)
305 defer framework.DeleteNamespaceOrDie(client, ns, t)
306
307 service := &corev1.Service{
308 ObjectMeta: metav1.ObjectMeta{
309 Name: "test-123",
310 },
311 Spec: corev1.ServiceSpec{
312 Type: corev1.ServiceTypeLoadBalancer,
313 AllocateLoadBalancerNodePorts: utilpointer.Bool(true),
314 Ports: []corev1.ServicePort{{
315 Name: "np-1",
316 Port: int32(80),
317 }, {
318 Name: "np-2",
319 Port: int32(81),
320 }},
321 Selector: map[string]string{
322 "foo": "bar",
323 },
324 },
325 }
326
327 service, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
328 if err != nil {
329 t.Fatalf("Error creating test service: %v", err)
330 }
331
332 if !serviceHasNodePorts(service) {
333 t.Error("expected node ports but found none")
334 }
335
336 clone := service.DeepCopy()
337 clone.Spec.AllocateLoadBalancerNodePorts = utilpointer.Bool(false)
338 clone.Spec.Ports[0].NodePort = 0
339
340 oldData, err := json.Marshal(service)
341 if err != nil {
342 t.Fatalf("Error marshalling test service: %v", err)
343 }
344 newData, err := json.Marshal(clone)
345 if err != nil {
346 t.Fatalf("Error marshalling test service: %v", err)
347 }
348 patch, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, corev1.Service{})
349 if err != nil {
350 t.Fatalf("Error creating patch: %v", err)
351 }
352
353 service, err = client.CoreV1().Services(ns.Name).Patch(context.TODO(), service.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{})
354 if err != nil {
355 t.Fatalf("Error updating test service: %v", err)
356 }
357
358 if service.Spec.Ports[0].NodePort != 0 {
359 t.Error("node ports[0] was expected to be deallocated")
360 }
361 if service.Spec.Ports[1].NodePort == 0 {
362 t.Error("node ports was not expected to be deallocated")
363 }
364 }
365
366
367
368 func Test_ServiceLoadBalancerDisableThenEnableAllocatedNodePorts(t *testing.T) {
369 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
370 defer server.TearDownFn()
371
372 client, err := clientset.NewForConfig(server.ClientConfig)
373 if err != nil {
374 t.Fatalf("Error creating clientset: %v", err)
375 }
376
377 ns := framework.CreateNamespaceOrDie(client, "test-service-reallocate-node-ports", t)
378 defer framework.DeleteNamespaceOrDie(client, ns, t)
379
380 service := &corev1.Service{
381 ObjectMeta: metav1.ObjectMeta{
382 Name: "test-123",
383 },
384 Spec: corev1.ServiceSpec{
385 Type: corev1.ServiceTypeLoadBalancer,
386 AllocateLoadBalancerNodePorts: utilpointer.Bool(false),
387 Ports: []corev1.ServicePort{{
388 Port: int32(80),
389 }},
390 Selector: map[string]string{
391 "foo": "bar",
392 },
393 },
394 }
395
396 service, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
397 if err != nil {
398 t.Fatalf("Error creating test service: %v", err)
399 }
400
401 if serviceHasNodePorts(service) {
402 t.Error("not expected node ports but found one")
403 }
404
405 service.Spec.AllocateLoadBalancerNodePorts = utilpointer.Bool(true)
406 service, err = client.CoreV1().Services(ns.Name).Update(context.TODO(), service, metav1.UpdateOptions{})
407 if err != nil {
408 t.Fatalf("Error updating test service: %v", err)
409 }
410
411 if !serviceHasNodePorts(service) {
412 t.Error("expected node ports but found none")
413 }
414 }
415
416 func serviceHasNodePorts(svc *corev1.Service) bool {
417 for _, port := range svc.Spec.Ports {
418 if port.NodePort > 0 {
419 return true
420 }
421 }
422
423 return false
424 }
425
426
427
428 func Test_ServiceLoadBalancerEnableLoadBalancerClass(t *testing.T) {
429 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
430 defer server.TearDownFn()
431
432 client, err := clientset.NewForConfig(server.ClientConfig)
433 if err != nil {
434 t.Fatalf("Error creating clientset: %v", err)
435 }
436
437 ns := framework.CreateNamespaceOrDie(client, "test-service-load-balancer-class", t)
438 defer framework.DeleteNamespaceOrDie(client, ns, t)
439
440 controller, cloud, informer := newServiceController(t, client)
441
442 ctx, cancel := context.WithCancel(context.Background())
443 defer cancel()
444 informer.Start(ctx.Done())
445 go controller.Run(ctx, 1, controllersmetrics.NewControllerManagerMetrics("loadbalancer-test"))
446
447 service := &corev1.Service{
448 ObjectMeta: metav1.ObjectMeta{
449 Name: "test-load-balancer-class",
450 },
451 Spec: corev1.ServiceSpec{
452 Type: corev1.ServiceTypeLoadBalancer,
453 Ports: []corev1.ServicePort{{
454 Port: int32(80),
455 }},
456 LoadBalancerClass: utilpointer.String("test.com/test"),
457 },
458 }
459
460 _, err = client.CoreV1().Services(ns.Name).Create(ctx, service, metav1.CreateOptions{})
461 if err != nil {
462 t.Fatalf("Error creating test service: %v", err)
463 }
464
465 time.Sleep(5 * time.Second)
466 if len(cloud.Calls) > 0 {
467 t.Errorf("Unexpected cloud provider calls: %v", cloud.Calls)
468 }
469 }
470
471
472
473
474 func Test_SetLoadBalancerClassThenUpdateLoadBalancerClass(t *testing.T) {
475 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
476 defer server.TearDownFn()
477
478 client, err := clientset.NewForConfig(server.ClientConfig)
479 if err != nil {
480 t.Fatalf("Error creating clientset: %v", err)
481 }
482
483 ns := framework.CreateNamespaceOrDie(client, "test-service-immutable-load-balancer-class", t)
484 defer framework.DeleteNamespaceOrDie(client, ns, t)
485
486 controller, cloud, informer := newServiceController(t, client)
487
488 ctx, cancel := context.WithCancel(context.Background())
489 defer cancel()
490 informer.Start(ctx.Done())
491 go controller.Run(ctx, 1, controllersmetrics.NewControllerManagerMetrics("loadbalancer-test"))
492
493 service := &corev1.Service{
494 ObjectMeta: metav1.ObjectMeta{
495 Name: "test-load-balancer-class",
496 },
497 Spec: corev1.ServiceSpec{
498 Type: corev1.ServiceTypeLoadBalancer,
499 Ports: []corev1.ServicePort{{
500 Port: int32(80),
501 }},
502 LoadBalancerClass: utilpointer.String("test.com/test"),
503 },
504 }
505
506 service, err = client.CoreV1().Services(ns.Name).Create(ctx, service, metav1.CreateOptions{})
507 if err != nil {
508 t.Fatalf("Error creating test service: %v", err)
509 }
510
511 service.Spec.LoadBalancerClass = utilpointer.String("test.com/update")
512 _, err = client.CoreV1().Services(ns.Name).Update(ctx, service, metav1.UpdateOptions{})
513 if err == nil {
514 t.Fatal("Error: updating test service load balancer class should throw error, field is immutable")
515 }
516
517 time.Sleep(5 * time.Second)
518 if len(cloud.Calls) > 0 {
519 t.Errorf("Unexpected cloud provider calls: %v", cloud.Calls)
520 }
521 }
522
523
524
525 func Test_UpdateLoadBalancerWithLoadBalancerClass(t *testing.T) {
526 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
527 defer server.TearDownFn()
528
529 client, err := clientset.NewForConfig(server.ClientConfig)
530 if err != nil {
531 t.Fatalf("Error creating clientset: %v", err)
532 }
533
534 ns := framework.CreateNamespaceOrDie(client, "test-service-update-load-balancer-class", t)
535 defer framework.DeleteNamespaceOrDie(client, ns, t)
536
537 controller, cloud, informer := newServiceController(t, client)
538
539 ctx, cancel := context.WithCancel(context.Background())
540 defer cancel()
541 informer.Start(ctx.Done())
542 go controller.Run(ctx, 1, controllersmetrics.NewControllerManagerMetrics("loadbalancer-test"))
543
544 service := &corev1.Service{
545 ObjectMeta: metav1.ObjectMeta{
546 Name: "test-update-load-balancer-class",
547 },
548 Spec: corev1.ServiceSpec{
549 Type: corev1.ServiceTypeLoadBalancer,
550 Ports: []corev1.ServicePort{{
551 Port: int32(80),
552 }},
553 },
554 }
555
556 service, err = client.CoreV1().Services(ns.Name).Create(ctx, service, metav1.CreateOptions{})
557 if err != nil {
558 t.Fatalf("Error creating test service: %v", err)
559 }
560
561 service.Spec.LoadBalancerClass = utilpointer.String("test.com/test")
562 _, err = client.CoreV1().Services(ns.Name).Update(ctx, service, metav1.UpdateOptions{})
563 if err == nil {
564 t.Fatal("Error: updating test service load balancer class should throw error, field is immutable")
565 }
566
567 time.Sleep(5 * time.Second)
568 if len(cloud.Calls) == 0 {
569 t.Errorf("expected cloud provider calls to create load balancer")
570 }
571 }
572
573
574
575 func Test_ServiceLoadBalancerMixedProtocolSetup(t *testing.T) {
576 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
577 defer server.TearDownFn()
578
579 client, err := clientset.NewForConfig(server.ClientConfig)
580 if err != nil {
581 t.Fatalf("Error creating clientset: %v", err)
582 }
583
584 ns := framework.CreateNamespaceOrDie(client, "test-service-mixed-protocols", t)
585 defer framework.DeleteNamespaceOrDie(client, ns, t)
586
587 controller, cloud, informer := newServiceController(t, client)
588
589 ctx, cancel := context.WithCancel(context.Background())
590 defer cancel()
591 informer.Start(ctx.Done())
592 go controller.Run(ctx, 1, controllersmetrics.NewControllerManagerMetrics("loadbalancer-test"))
593
594 service := &corev1.Service{
595 ObjectMeta: metav1.ObjectMeta{
596 Name: "test-123",
597 },
598 Spec: corev1.ServiceSpec{
599 Type: corev1.ServiceTypeLoadBalancer,
600 Ports: []corev1.ServicePort{
601 {
602 Name: "tcpport",
603 Port: int32(53),
604 Protocol: corev1.ProtocolTCP,
605 },
606 {
607 Name: "udpport",
608 Port: int32(53),
609 Protocol: corev1.ProtocolUDP,
610 },
611 },
612 },
613 }
614
615 _, err = client.CoreV1().Services(ns.Name).Create(context.TODO(), service, metav1.CreateOptions{})
616 if err != nil {
617 t.Fatalf("Error creating test service: %v", err)
618 }
619
620 time.Sleep(5 * time.Second)
621 if len(cloud.Calls) == 0 {
622 t.Errorf("expected cloud provider calls to create load balancer")
623 }
624 }
625
626 func newServiceController(t *testing.T, client *clientset.Clientset) (*servicecontroller.Controller, *fakecloud.Cloud, informers.SharedInformerFactory) {
627 cloud := &fakecloud.Cloud{}
628 informerFactory := informers.NewSharedInformerFactory(client, 0)
629 serviceInformer := informerFactory.Core().V1().Services()
630 nodeInformer := informerFactory.Core().V1().Nodes()
631
632 controller, err := servicecontroller.New(cloud,
633 client,
634 serviceInformer,
635 nodeInformer,
636 "test-cluster",
637 utilfeature.DefaultFeatureGate)
638 if err != nil {
639 t.Fatalf("Error creating service controller: %v", err)
640 }
641 cloud.ClearCalls()
642 return controller, cloud, informerFactory
643 }
644
645
646 func Test_ServiceLoadBalancerIPMode(t *testing.T) {
647 ipModeVIP := corev1.LoadBalancerIPModeVIP
648 testCases := []struct {
649 ipModeEnabled bool
650 externalIP string
651 expectedIPMode *corev1.LoadBalancerIPMode
652 }{
653 {
654 ipModeEnabled: false,
655 externalIP: "1.2.3.4",
656 expectedIPMode: nil,
657 },
658 {
659 ipModeEnabled: true,
660 externalIP: "1.2.3.5",
661 expectedIPMode: &ipModeVIP,
662 },
663 }
664
665 for _, tc := range testCases {
666 t.Run("", func(t *testing.T) {
667 defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.LoadBalancerIPMode, tc.ipModeEnabled)()
668 server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
669 defer server.TearDownFn()
670
671 client, err := clientset.NewForConfig(server.ClientConfig)
672 if err != nil {
673 t.Fatalf("Error creating clientset: %v", err)
674 }
675
676 ns := framework.CreateNamespaceOrDie(client, "test-service-update-load-balancer-ip-mode", t)
677 defer framework.DeleteNamespaceOrDie(client, ns, t)
678
679 controller, cloud, informer := newServiceController(t, client)
680 cloud.ExternalIP = net.ParseIPSloppy(tc.externalIP)
681
682 ctx, cancel := context.WithCancel(context.Background())
683 defer cancel()
684 informer.Start(ctx.Done())
685 go controller.Run(ctx, 1, controllersmetrics.NewControllerManagerMetrics("loadbalancer-test"))
686
687 service := &corev1.Service{
688 ObjectMeta: metav1.ObjectMeta{
689 Name: "test-update-load-balancer-ip-mode",
690 },
691 Spec: corev1.ServiceSpec{
692 Type: corev1.ServiceTypeLoadBalancer,
693 Ports: []corev1.ServicePort{{
694 Port: int32(80),
695 }},
696 },
697 }
698
699 service, err = client.CoreV1().Services(ns.Name).Create(ctx, service, metav1.CreateOptions{})
700 if err != nil {
701 t.Fatalf("Error creating test service: %v", err)
702 }
703
704 time.Sleep(5 * time.Second)
705 service, err = client.CoreV1().Services(ns.Name).Get(ctx, service.Name, metav1.GetOptions{})
706 if err != nil {
707 t.Fatalf("Error getting test service: %v", err)
708 }
709
710 if len(service.Status.LoadBalancer.Ingress) == 0 {
711 t.Fatalf("unexpected load balancer status")
712 }
713
714 gotIngress := service.Status.LoadBalancer.Ingress[0]
715 if gotIngress.IP != tc.externalIP || !reflect.DeepEqual(gotIngress.IPMode, tc.expectedIPMode) {
716 t.Errorf("unexpected load balancer ingress, got ingress %v, expected IP %v, expected ipMode %v",
717 gotIngress, tc.externalIP, tc.expectedIPMode)
718 }
719 })
720 }
721 }
722
View as plain text