Skip to content

Commit 921fb0b

Browse files
authored
Merge pull request kubernetes#125237 from aojea/ipmode_integration
improve loadbalancer IPMode testing
2 parents d236a91 + e7425cf commit 921fb0b

File tree

2 files changed

+111
-34
lines changed

2 files changed

+111
-34
lines changed

staging/src/k8s.io/cloud-provider/fake/fake.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type Cloud struct {
8484
ClusterList []string
8585
MasterName string
8686
ExternalIP net.IP
87+
BalancerIPMode *v1.LoadBalancerIPMode
8788
Balancers map[string]Balancer
8889
updateCallLock sync.Mutex
8990
UpdateCalls []UpdateBalancerCall
@@ -224,7 +225,15 @@ func (f *Cloud) EnsureLoadBalancer(ctx context.Context, clusterName string, serv
224225
f.Balancers[name] = Balancer{name, region, spec.LoadBalancerIP, spec.Ports, nodes}
225226

226227
status := &v1.LoadBalancerStatus{}
227-
status.Ingress = []v1.LoadBalancerIngress{{IP: f.ExternalIP.String()}}
228+
// process Ports
229+
portStatus := []v1.PortStatus{}
230+
for _, port := range spec.Ports {
231+
portStatus = append(portStatus, v1.PortStatus{
232+
Port: port.Port,
233+
Protocol: port.Protocol,
234+
})
235+
}
236+
status.Ingress = []v1.LoadBalancerIngress{{IP: f.ExternalIP.String(), IPMode: f.BalancerIPMode, Ports: portStatus}}
228237

229238
return status, f.Err
230239
}

test/integration/service/loadbalancer_test.go

Lines changed: 101 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ package service
1919
import (
2020
"context"
2121
"encoding/json"
22-
"reflect"
2322
"testing"
2423
"time"
2524

2625
corev1 "k8s.io/api/core/v1"
26+
apiequality "k8s.io/apimachinery/pkg/api/equality"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
"k8s.io/apimachinery/pkg/types"
2929
"k8s.io/apimachinery/pkg/util/strategicpatch"
30+
"k8s.io/apimachinery/pkg/util/wait"
3031
utilfeature "k8s.io/apiserver/pkg/util/feature"
3132
"k8s.io/client-go/informers"
3233
clientset "k8s.io/client-go/kubernetes"
@@ -39,6 +40,7 @@ import (
3940
"k8s.io/kubernetes/test/integration/framework"
4041
"k8s.io/utils/net"
4142
utilpointer "k8s.io/utils/pointer"
43+
"k8s.io/utils/ptr"
4244
)
4345

4446
// Test_ServiceLoadBalancerAllocateNodePorts tests that a Service with spec.allocateLoadBalancerNodePorts=false
@@ -644,21 +646,62 @@ func newServiceController(t *testing.T, client *clientset.Clientset) (*serviceco
644646

645647
// Test_ServiceLoadBalancerIPMode tests whether the cloud provider has correctly updated the ipMode field.
646648
func Test_ServiceLoadBalancerIPMode(t *testing.T) {
647-
ipModeVIP := corev1.LoadBalancerIPModeVIP
649+
baseService := &corev1.Service{
650+
ObjectMeta: metav1.ObjectMeta{
651+
Name: "test-update-load-balancer-ip-mode",
652+
},
653+
Spec: corev1.ServiceSpec{
654+
Type: corev1.ServiceTypeLoadBalancer,
655+
Ports: []corev1.ServicePort{{
656+
Port: int32(80),
657+
}},
658+
},
659+
}
660+
648661
testCases := []struct {
649-
ipModeEnabled bool
650-
externalIP string
651-
expectedIPMode *corev1.LoadBalancerIPMode
662+
ipModeEnabled bool
663+
setIPMode *corev1.LoadBalancerIPMode
664+
externalIP string
665+
expectedIngress corev1.LoadBalancerIngress
652666
}{
653667
{
654-
ipModeEnabled: false,
655-
externalIP: "1.2.3.4",
656-
expectedIPMode: nil,
668+
ipModeEnabled: false,
669+
externalIP: "1.2.3.4",
670+
expectedIngress: corev1.LoadBalancerIngress{
671+
IP: "1.2.3.4",
672+
IPMode: nil,
673+
Ports: []corev1.PortStatus{{Port: 80, Protocol: corev1.ProtocolTCP}},
674+
},
657675
},
658676
{
659-
ipModeEnabled: true,
660-
externalIP: "1.2.3.5",
661-
expectedIPMode: &ipModeVIP,
677+
ipModeEnabled: true,
678+
setIPMode: nil,
679+
externalIP: "1.2.3.4",
680+
expectedIngress: corev1.LoadBalancerIngress{
681+
IP: "1.2.3.4",
682+
IPMode: ptr.To(corev1.LoadBalancerIPModeVIP),
683+
Ports: []corev1.PortStatus{{Port: 80, Protocol: corev1.ProtocolTCP}},
684+
},
685+
},
686+
{
687+
ipModeEnabled: true,
688+
setIPMode: ptr.To(corev1.LoadBalancerIPModeVIP),
689+
externalIP: "1.2.3.4",
690+
expectedIngress: corev1.LoadBalancerIngress{
691+
IP: "1.2.3.4",
692+
IPMode: ptr.To(corev1.LoadBalancerIPModeVIP),
693+
Ports: []corev1.PortStatus{{Port: 80, Protocol: corev1.ProtocolTCP}},
694+
},
695+
},
696+
{
697+
ipModeEnabled: true,
698+
setIPMode: ptr.To(corev1.LoadBalancerIPModeProxy),
699+
externalIP: "1.2.3.4",
700+
expectedIngress: corev1.LoadBalancerIngress{
701+
IP: "1.2.3.4",
702+
IPMode: ptr.To(corev1.LoadBalancerIPModeProxy),
703+
Ports: []corev1.PortStatus{{Port: 80, Protocol: corev1.ProtocolTCP}},
704+
},
662705
},
663706
}
664707

@@ -678,43 +721,68 @@ func Test_ServiceLoadBalancerIPMode(t *testing.T) {
678721

679722
controller, cloud, informer := newServiceController(t, client)
680723
cloud.ExternalIP = net.ParseIPSloppy(tc.externalIP)
724+
cloud.BalancerIPMode = tc.expectedIngress.IPMode
681725

682726
ctx, cancel := context.WithCancel(context.Background())
683727
defer cancel()
684728
informer.Start(ctx.Done())
685729
go controller.Run(ctx, 1, controllersmetrics.NewControllerManagerMetrics("loadbalancer-test"))
686730

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{})
731+
service, err := client.CoreV1().Services(ns.Name).Create(ctx, baseService, metav1.CreateOptions{})
700732
if err != nil {
701733
t.Fatalf("Error creating test service: %v", err)
702734
}
703735

704-
time.Sleep(5 * time.Second) // sleep 5 second to wait for the service controller reconcile
705-
service, err = client.CoreV1().Services(ns.Name).Get(ctx, service.Name, metav1.GetOptions{})
736+
err = wait.PollUntilContextTimeout(ctx, 500*time.Millisecond, 10*time.Second, true, func(_ context.Context) (done bool, err error) {
737+
service, err = client.CoreV1().Services(ns.Name).Get(ctx, service.Name, metav1.GetOptions{})
738+
if err != nil {
739+
t.Fatalf("Error getting test service: %v", err)
740+
}
741+
if len(service.Status.LoadBalancer.Ingress) != 1 {
742+
return false, nil
743+
}
744+
return true, nil
745+
})
706746
if err != nil {
707-
t.Fatalf("Error getting test service: %v", err)
747+
t.Fatalf("unexpected load balancer status")
708748
}
709749

710-
if len(service.Status.LoadBalancer.Ingress) == 0 {
711-
t.Fatalf("unexpected load balancer status")
750+
ingress := service.Status.LoadBalancer.Ingress[0]
751+
if !apiequality.Semantic.DeepEqual(&ingress, &tc.expectedIngress) {
752+
t.Errorf("expected Ingress %v, got IP %v",
753+
ingress, tc.expectedIngress)
754+
if ingress.IPMode != nil && tc.expectedIngress.IPMode != nil {
755+
t.Logf("IPMode %v expected %v", *ingress.IPMode, *tc.expectedIngress.IPMode)
756+
}
712757
}
713758

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)
759+
// mutate the service and check the status is preserved
760+
newService := service.DeepCopy()
761+
newService.Spec.Ports[0].Port = 443
762+
service, err = client.CoreV1().Services(ns.Name).Update(ctx, newService, metav1.UpdateOptions{})
763+
if err != nil {
764+
t.Fatalf("Error updating test service: %v", err)
765+
}
766+
767+
expectedIngress := tc.expectedIngress
768+
expectedIngress.Ports[0].Port = 443
769+
err = wait.PollUntilContextTimeout(ctx, 500*time.Millisecond, 10*time.Second, true, func(_ context.Context) (done bool, err error) {
770+
service, err = client.CoreV1().Services(ns.Name).Get(ctx, service.Name, metav1.GetOptions{})
771+
if err != nil {
772+
t.Fatalf("Error getting test service: %v", err)
773+
}
774+
if len(service.Status.LoadBalancer.Ingress) != 1 {
775+
return false, nil
776+
}
777+
ingress = service.Status.LoadBalancer.Ingress[0]
778+
if !apiequality.Semantic.DeepEqual(&ingress, &expectedIngress) {
779+
t.Logf("Ingress %v Expected %v", ingress, expectedIngress)
780+
return false, nil
781+
}
782+
return true, nil
783+
})
784+
if err != nil {
785+
t.Fatalf("unexpected load balancer status")
718786
}
719787
})
720788
}

0 commit comments

Comments
 (0)