@@ -2,22 +2,30 @@ package integration
22
33import (
44 "fmt"
5+ "net/http"
56 "testing"
7+ "time"
68
79 "github.com/google/uuid"
10+ "github.com/kong/kubernetes-testing-framework/pkg/utils/kubernetes/generators"
811 "github.com/samber/lo"
912 "github.com/stretchr/testify/assert"
1013 "github.com/stretchr/testify/require"
1114 corev1 "k8s.io/api/core/v1"
12- "k8s.io/apimachinery/pkg/types"
15+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+ k8stypes "k8s.io/apimachinery/pkg/types"
1317 "sigs.k8s.io/controller-runtime/pkg/client"
1418
19+ "github.com/kong/gateway-operator/pkg/consts"
1520 testutils "github.com/kong/gateway-operator/pkg/utils/test"
1621 "github.com/kong/gateway-operator/test"
1722 "github.com/kong/gateway-operator/test/helpers"
1823 "github.com/kong/gateway-operator/test/helpers/deploy"
1924
2025 kcfgconsts "github.com/kong/kubernetes-configuration/api/common/consts"
26+ commonv1alpha1 "github.com/kong/kubernetes-configuration/api/common/v1alpha1"
27+ configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1"
28+ operatorv1beta1 "github.com/kong/kubernetes-configuration/api/gateway-operator/v1beta1"
2129 konnectv1alpha1 "github.com/kong/kubernetes-configuration/api/konnect/v1alpha1"
2230)
2331
@@ -50,7 +58,7 @@ func TestKonnectExtension(t *testing.T) {
5058
5159 t .Logf ("Waiting for Konnect ID to be assigned to ControlPlane %s/%s" , cp .Namespace , cp .Name )
5260 require .EventuallyWithT (t , func (t * assert.CollectT ) {
53- err := GetClients ().MgrClient .Get (GetCtx (), types .NamespacedName {Name : cp .Name , Namespace : cp .Namespace }, cp )
61+ err := GetClients ().MgrClient .Get (GetCtx (), k8stypes .NamespacedName {Name : cp .Name , Namespace : cp .Namespace }, cp )
5462 require .NoError (t , err )
5563 assertKonnectEntityProgrammed (t , cp )
5664 }, testutils .ObjectUpdateTimeout , testutils .ObjectUpdateTick )
@@ -92,6 +100,107 @@ func TestKonnectExtension(t *testing.T) {
92100 checkKonnectExtensionStatus (keWithKonnectIDCPRef , cp .GetKonnectID (), dpCert1 .Name ),
93101 testutils .ObjectUpdateTimeout , testutils .ObjectUpdateTick )
94102
103+ // Create a DataPlane using the KonnectExension.
104+ t .Logf ("Creating a DataPlane using the KonnectExtension %s/%s" , keWithKonnectIDCPRef .Namespace , keWithKonnectIDCPRef .Name )
105+ dp := & operatorv1beta1.DataPlane {
106+ ObjectMeta : metav1.ObjectMeta {
107+ Namespace : ns .String (),
108+ Name : "test-konnect-extension-dp-1" ,
109+ },
110+ Spec : operatorv1beta1.DataPlaneSpec {
111+ DataPlaneOptions : operatorv1beta1.DataPlaneOptions {
112+ Extensions : []commonv1alpha1.ExtensionRef {
113+ {
114+ Group : konnectv1alpha1 .GroupVersion .Group ,
115+ Kind : "KonnectExtension" ,
116+ NamespacedRef : commonv1alpha1.NamespacedRef {
117+ Name : keWithKonnectIDCPRef .Name ,
118+ },
119+ },
120+ },
121+ },
122+ },
123+ }
124+ require .NoError (t , clientNamespaced .Create (ctx , dp ))
125+
126+ dpName := k8stypes.NamespacedName {
127+ Namespace : dp .Namespace ,
128+ Name : dp .Name ,
129+ }
130+ t .Logf ("verifying dataplane %s gets marked provisioned" , dpName )
131+
132+ require .Eventually (t , testutils .DataPlaneIsReady (t , GetCtx (), dpName , GetClients ().OperatorClient ), waitTime , tickTime )
133+
134+ t .Logf ("verifying dataplane %s has ingress service" , dpName )
135+ var dpIngressService corev1.Service
136+ require .Eventually (t , testutils .DataPlaneHasActiveService (t , GetCtx (), dpName , & dpIngressService , clients , client.MatchingLabels {
137+ consts .GatewayOperatorManagedByLabel : consts .DataPlaneManagedLabelValue ,
138+ consts .DataPlaneServiceTypeLabel : string (consts .DataPlaneIngressServiceLabelValue ),
139+ }), waitTime , tickTime )
140+
141+ t .Log ("verifying dataplane services receive IP addresses" )
142+ require .Eventually (t , func () bool {
143+ err := clientNamespaced .Get (ctx , k8stypes.NamespacedName {
144+ Namespace : dpIngressService .Namespace ,
145+ Name : dpIngressService .Name ,
146+ }, & dpIngressService )
147+ require .NoError (t , err )
148+ return len (dpIngressService .Status .LoadBalancer .Ingress ) > 0
149+ }, waitTime , tickTime )
150+ dpIngressIP := dpIngressService .Status .LoadBalancer .Ingress [0 ].IP
151+ require .Eventuallyf (t , Expect404WithNoRouteFunc (t , GetCtx (), "http://" + dpIngressIP ), waitTime , tickTime ,
152+ "Should receive 'No Route' response from dataplane's ingress service IP %s" , dpIngressIP )
153+
154+ t .Log ("deploying backend deployment (httpbin) of HTTPRoute" )
155+ container := generators .NewContainer ("httpbin" , testutils .HTTPBinImage , 80 )
156+ deployment := generators .NewDeploymentForContainer (container )
157+ require .NoError (t , clientNamespaced .Create (ctx , deployment ))
158+
159+ t .Logf ("exposing deployment %s via service" , deployment .Name )
160+ service := generators .NewServiceForDeployment (deployment , corev1 .ServiceTypeClusterIP )
161+ require .NoError (t , clientNamespaced .Create (ctx , service ))
162+
163+ t .Log ("Creating a KongService and a KongRoute to the service" )
164+ ks := deploy .KongService (t , ctx , clientNamespaced ,
165+ deploy .WithKonnectNamespacedRefControlPlaneRef (cp ),
166+ func (obj client.Object ) {
167+ ks , ok := obj .(* configurationv1alpha1.KongService )
168+ require .True (t , ok )
169+ ks .Spec .KongServiceAPISpec = configurationv1alpha1.KongServiceAPISpec {
170+ Name : lo .ToPtr ("httpbin" ),
171+ URL : lo .ToPtr (fmt .Sprintf ("http://%s.%s.svc.cluster.local/" , service .Name , ns .Name )),
172+ Host : fmt .Sprintf ("%s.%s.svc.cluster.local" , service .Name , ns .Name ),
173+ }
174+ },
175+ )
176+ t .Logf ("Waiting for KongService to be updated with Konnect ID" )
177+ require .EventuallyWithT (t , func (t * assert.CollectT ) {
178+ err := GetClients ().MgrClient .Get (GetCtx (), k8stypes.NamespacedName {Name : ks .Name , Namespace : ks .Namespace }, ks )
179+ require .NoError (t , err )
180+ assertKonnectEntityProgrammed (t , ks )
181+ }, testutils .ObjectUpdateTimeout , testutils .ObjectUpdateTick )
182+
183+ kr := deploy .KongRouteAttachedToService (t , ctx , clientNamespaced , ks )
184+ t .Logf ("Waiting for KongRoute to be updated with Konnect ID" )
185+ require .EventuallyWithT (t , func (t * assert.CollectT ) {
186+ err := GetClients ().MgrClient .Get (GetCtx (), k8stypes.NamespacedName {Name : kr .Name , Namespace : kr .Namespace }, kr )
187+ require .NoError (t , err )
188+
189+ assertKonnectEntityProgrammed (t , kr )
190+ }, testutils .ObjectUpdateTimeout , testutils .ObjectUpdateTick )
191+
192+ t .Log ("route to / path of service httpbin should receive a 200 OK response" )
193+ httpClient , err := helpers .CreateHTTPClient (nil , "" )
194+ require .NoError (t , err )
195+ const routeAccessTimeout = 3 * time .Minute
196+ request := helpers .MustBuildRequest (t , GetCtx (), http .MethodGet , "http://" + dpIngressIP + "/test" , "" )
197+ require .Eventually (
198+ t ,
199+ testutils .GetResponseBodyContains (t , clients , httpClient , request , "<title>httpbin.org</title>" ),
200+ routeAccessTimeout ,
201+ time .Second ,
202+ )
203+
95204 // Tests on KonnectExtension with KonnectNamespacedRef control plane ref.
96205 dpCert2 := deploy .Secret (
97206 t , ctx , clientNamespaced ,
@@ -122,9 +231,12 @@ func TestKonnectExtension(t *testing.T) {
122231 testutils .ObjectUpdateTimeout , testutils .ObjectUpdateTick )
123232
124233 // Order of deleting objects with finalizers:
125- // KonnectExtension -> Secret -> KonnectGatewayControlPlane.
234+ // DataPlane -> KonnectExtension -> Secret -> KonnectGatewayControlPlane.
126235 // After they are all deleted, the namespace can be deleted in the final clean up.
236+
127237 t .Cleanup (deleteObjectAndWaitForDeletionFn (t , cp .DeepCopy ()))
238+ t .Cleanup (deleteObjectAndWaitForDeletionFn (t , ks ))
239+ t .Cleanup (deleteObjectAndWaitForDeletionFn (t , kr ))
128240 t .Cleanup (deleteObjectAndWaitForDeletionFn (t , dpCert1 .DeepCopy ()))
129241 t .Cleanup (deleteObjectAndWaitForDeletionFn (t , dpCert2 .DeepCopy ()))
130242 t .Cleanup (deleteObjectAndWaitForDeletionFn (t , keWithKonnectIDCPRef .DeepCopy ()))
@@ -148,7 +260,7 @@ func setKonnectExtensionDPCertSecretRef(t *testing.T, s *corev1.Secret) deploy.O
148260}
149261
150262func checkKonnectExtensionConditions (t * assert.CollectT , ke * konnectv1alpha1.KonnectExtension ) (bool , string ) {
151- err := GetClients ().MgrClient .Get (GetCtx (), types .NamespacedName {Name : ke .Name , Namespace : ke .Namespace }, ke )
263+ err := GetClients ().MgrClient .Get (GetCtx (), k8stypes .NamespacedName {Name : ke .Name , Namespace : ke .Namespace }, ke )
152264 require .NoError (t , err )
153265
154266 checkConditionTypes := []kcfgconsts.ConditionType {
@@ -165,7 +277,7 @@ func checkKonnectExtensionStatus(
165277 expectedDPCertificateSecretName string ,
166278) func (t * assert.CollectT ) {
167279 return func (t * assert.CollectT ) {
168- err := GetClients ().MgrClient .Get (GetCtx (), types .NamespacedName {Name : ke .Name , Namespace : ke .Namespace }, ke )
280+ err := GetClients ().MgrClient .Get (GetCtx (), k8stypes .NamespacedName {Name : ke .Name , Namespace : ke .Namespace }, ke )
169281 require .NoError (t , err )
170282 // Check Konnect control plane ID
171283 require .NotNil (t , ke .Status .Konnect , "status.konnect should be present" )
0 commit comments