From 594f3f45fb95b238b6696a5eb01aabb45f510c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Wed, 8 May 2024 13:32:19 +0200 Subject: [PATCH] feat(dataplane): add implementation of setting ExternalTrafficPolicy --- .../gateway/controller_reconciler_utils.go | 5 +- pkg/utils/kubernetes/resources/services.go | 17 +- .../kubernetes/resources/services_test.go | 160 ++++++++++++++++++ 3 files changed, 177 insertions(+), 5 deletions(-) diff --git a/controller/gateway/controller_reconciler_utils.go b/controller/gateway/controller_reconciler_utils.go index 6995691f..ffd0ea1a 100644 --- a/controller/gateway/controller_reconciler_utils.go +++ b/controller/gateway/controller_reconciler_utils.go @@ -134,8 +134,9 @@ func gatewayConfigDataPlaneOptionsToDataPlaneOptions(opts operatorv1beta1.Gatewa Services: &operatorv1beta1.DataPlaneServices{ Ingress: &operatorv1beta1.DataPlaneServiceOptions{ ServiceOptions: operatorv1beta1.ServiceOptions{ - Type: opts.Network.Services.Ingress.Type, - Annotations: opts.Network.Services.Ingress.Annotations, + Type: opts.Network.Services.Ingress.Type, + Annotations: opts.Network.Services.Ingress.Annotations, + ExternalTrafficPolicy: opts.Network.Services.Ingress.ExternalTrafficPolicy, }, }, }, diff --git a/pkg/utils/kubernetes/resources/services.go b/pkg/utils/kubernetes/resources/services.go index b8ffecc3..71064b5f 100644 --- a/pkg/utils/kubernetes/resources/services.go +++ b/pkg/utils/kubernetes/resources/services.go @@ -57,9 +57,12 @@ func GenerateNewIngressServiceForDataPlane(dataplane *operatorv1beta1.DataPlane, }, }, Spec: corev1.ServiceSpec{ - Type: getDataPlaneIngressServiceType(dataplane), - Selector: map[string]string{"app": dataplane.Name}, - Ports: DefaultDataPlaneIngressServicePorts, + Type: getDataPlaneIngressServiceType(dataplane), + Selector: map[string]string{ + "app": dataplane.Name, + }, + Ports: DefaultDataPlaneIngressServicePorts, + ExternalTrafficPolicy: getDataPlaneIngressServiceExternalTrafficPolicy(dataplane), }, } LabelObjectAsDataPlaneManaged(svc) @@ -109,6 +112,14 @@ func getDataPlaneIngressServiceType(dataplane *operatorv1beta1.DataPlane) corev1 return dataplane.Spec.Network.Services.Ingress.Type } +func getDataPlaneIngressServiceExternalTrafficPolicy(dataplane *operatorv1beta1.DataPlane) corev1.ServiceExternalTrafficPolicy { + if dataplane == nil || dataplane.Spec.Network.Services == nil { + return corev1.ServiceExternalTrafficPolicyCluster + } + + return dataplane.Spec.Network.Services.Ingress.ExternalTrafficPolicy +} + // ServiceOpt is an option function for a Service. type ServiceOpt func(*corev1.Service) diff --git a/pkg/utils/kubernetes/resources/services_test.go b/pkg/utils/kubernetes/resources/services_test.go index 2f7726ce..7e45312f 100644 --- a/pkg/utils/kubernetes/resources/services_test.go +++ b/pkg/utils/kubernetes/resources/services_test.go @@ -3,7 +3,14 @@ package resources import ( "testing" + "github.com/samber/lo" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" + + operatorv1beta1 "github.com/kong/gateway-operator/api/v1beta1" ) func TestGetSelectorOverrides(t *testing.T) { @@ -69,3 +76,156 @@ func TestGetSelectorOverrides(t *testing.T) { }) } } + +func TestGenerateNewIngressServiceForDataPlane(t *testing.T) { + testCases := []struct { + name string + dataplane *operatorv1beta1.DataPlane + expectedSvc *corev1.Service + expectedErr error + }{ + { + name: "base", + dataplane: &operatorv1beta1.DataPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dp-1", + Namespace: "default", + UID: types.UID("1234"), + }, + TypeMeta: metav1.TypeMeta{ + APIVersion: "gateway.konghq.com/v1beta1", + Kind: "DataPlane", + }, + }, + expectedSvc: &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "dataplane-ingress-dp-1-", + Namespace: "default", + Labels: map[string]string{ + "app": "dp-1", + "gateway-operator.konghq.com/dataplane-service-type": "ingress", + "gateway-operator.konghq.com/managed-by": "dataplane", + "konghq.com/gateway-operator": "dataplane", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "gateway.konghq.com/v1beta1", + Kind: "DataPlane", + Name: "dp-1", + UID: "1234", + Controller: lo.ToPtr(true), + }, + }, + Finalizers: []string{ + "gateway-operator.konghq.com/wait-for-owner", + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{ + { + Name: "http", + Protocol: corev1.ProtocolTCP, + Port: 80, + TargetPort: intstr.FromInt(8000), + }, + { + Name: "https", + Protocol: corev1.ProtocolTCP, + Port: 443, + TargetPort: intstr.FromInt(8443), + }, + }, + Selector: map[string]string{ + "app": "dp-1", + }, + ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeCluster, + }, + }, + expectedErr: nil, + }, + { + name: "setting ExternalTrafficPolicy to Local", + dataplane: &operatorv1beta1.DataPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dp-1", + Namespace: "default", + UID: types.UID("1234"), + }, + TypeMeta: metav1.TypeMeta{ + APIVersion: "gateway.konghq.com/v1beta1", + Kind: "DataPlane", + }, + Spec: operatorv1beta1.DataPlaneSpec{ + DataPlaneOptions: operatorv1beta1.DataPlaneOptions{ + Network: operatorv1beta1.DataPlaneNetworkOptions{ + Services: &operatorv1beta1.DataPlaneServices{ + Ingress: &operatorv1beta1.DataPlaneServiceOptions{ + ServiceOptions: operatorv1beta1.ServiceOptions{ + ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal, + Type: corev1.ServiceTypeLoadBalancer, + }, + }, + }, + }, + }, + }, + }, + expectedSvc: &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "dataplane-ingress-dp-1-", + Namespace: "default", + Labels: map[string]string{ + "app": "dp-1", + "gateway-operator.konghq.com/dataplane-service-type": "ingress", + "gateway-operator.konghq.com/managed-by": "dataplane", + "konghq.com/gateway-operator": "dataplane", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "gateway.konghq.com/v1beta1", + Kind: "DataPlane", + Name: "dp-1", + UID: "1234", + Controller: lo.ToPtr(true), + }, + }, + Finalizers: []string{ + "gateway-operator.konghq.com/wait-for-owner", + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{ + { + Name: "http", + Protocol: corev1.ProtocolTCP, + Port: 80, + TargetPort: intstr.FromInt(8000), + }, + { + Name: "https", + Protocol: corev1.ProtocolTCP, + Port: 443, + TargetPort: intstr.FromInt(8443), + }, + }, + Selector: map[string]string{ + "app": "dp-1", + }, + ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyTypeLocal, + }, + }, + expectedErr: nil, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + svc, err := GenerateNewIngressServiceForDataPlane(tc.dataplane) + require.Equal(t, tc.expectedErr, err) + require.Equal(t, tc.expectedSvc, svc) + }) + } +}