Skip to content

Commit f6ac55a

Browse files
authored
test(envtest): Add test cases for adopting KongService and KonnectCloudGatewayNetwork (#2574)
1 parent db68b95 commit f6ac55a

File tree

2 files changed

+295
-0
lines changed

2 files changed

+295
-0
lines changed

test/envtest/konnect_entities_kongservice_test.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import (
1515
apiwatch "k8s.io/apimachinery/pkg/watch"
1616
"sigs.k8s.io/controller-runtime/pkg/client"
1717

18+
commonv1alpha1 "github.com/kong/kong-operator/api/common/v1alpha1"
1819
configurationv1alpha1 "github.com/kong/kong-operator/api/configuration/v1alpha1"
20+
konnectv1alpha1 "github.com/kong/kong-operator/api/konnect/v1alpha1"
1921
konnectv1alpha2 "github.com/kong/kong-operator/api/konnect/v1alpha2"
2022
"github.com/kong/kong-operator/controller/konnect"
2123
"github.com/kong/kong-operator/modules/manager/logging"
@@ -419,4 +421,165 @@ func TestKongService(t *testing.T) {
419421
"Object didn't get Programmed set to True",
420422
)
421423
})
424+
425+
t.Run("adopting a service in override mode then deleting it", func(t *testing.T) {
426+
427+
serviceKonnectID := uuid.NewString()
428+
w := setupWatch[configurationv1alpha1.KongServiceList](t, ctx, cl, client.InNamespace(ns.Name))
429+
430+
t.Log("Setting up SDK expectations for getting and updating service")
431+
sdk.ServicesSDK.EXPECT().GetService(
432+
mock.Anything, serviceKonnectID, cp.GetKonnectID(),
433+
).Return(
434+
&sdkkonnectops.GetServiceResponse{
435+
Service: &sdkkonnectcomp.ServiceOutput{
436+
ID: lo.ToPtr(serviceKonnectID),
437+
Host: "example.com",
438+
},
439+
}, nil,
440+
)
441+
sdk.ServicesSDK.EXPECT().UpsertService(
442+
mock.Anything,
443+
mock.MatchedBy(func(req sdkkonnectops.UpsertServiceRequest) bool {
444+
return req.ServiceID == serviceKonnectID
445+
}),
446+
).Return(&sdkkonnectops.UpsertServiceResponse{}, nil)
447+
448+
t.Log("Creating a KongService to adopt the existing service")
449+
createdService := deploy.KongService(t, t.Context(), clientNamespaced, deploy.WithKonnectNamespacedRefControlPlaneRef(cp),
450+
func(obj client.Object) {
451+
ks, ok := obj.(*configurationv1alpha1.KongService)
452+
require.True(t, ok)
453+
ks.Spec.URL = lo.ToPtr("https://example.com/example")
454+
ks.Spec.Adopt = &commonv1alpha1.AdoptOptions{
455+
From: commonv1alpha1.AdoptSourceKonnect,
456+
Mode: commonv1alpha1.AdoptModeOverride,
457+
Konnect: &commonv1alpha1.AdoptKonnectOptions{
458+
ID: serviceKonnectID,
459+
},
460+
}
461+
})
462+
463+
t.Log("Waiting for the service to be programmed and get Konnect ID")
464+
watchFor(t, t.Context(), w, apiwatch.Modified, func(ks *configurationv1alpha1.KongService) bool {
465+
return ks.Name == createdService.Name &&
466+
ks.GetKonnectID() == serviceKonnectID && k8sutils.IsProgrammed(ks)
467+
},
468+
"Did not see KongService marked as Programmed and set Konnect ID",
469+
)
470+
471+
t.Log("Setting up SDK expectations for deleting the service")
472+
sdk.ServicesSDK.EXPECT().DeleteService(
473+
mock.Anything,
474+
cp.GetKonnectID(),
475+
serviceKonnectID,
476+
).Return(&sdkkonnectops.DeleteServiceResponse{}, nil)
477+
478+
t.Log("Deleting the KongService")
479+
require.NoError(t, clientNamespaced.Delete(t.Context(), createdService))
480+
481+
t.Log("Waiting for the SDK's DeleteService to be called")
482+
eventuallyAssertSDKExpectations(t, factory.SDK.ServicesSDK, waitTime, tickTime)
483+
484+
t.Log("Waiting for the KongService to disappear")
485+
eventually.WaitForObjectToNotExist(t, ctx, cl, createdService, waitTime, tickTime)
486+
})
487+
488+
t.Run("adopting a service with NotFound error returned from upstream", func(t *testing.T) {
489+
490+
serviceKonnectID := uuid.NewString()
491+
w := setupWatch[configurationv1alpha1.KongServiceList](t, ctx, cl, client.InNamespace(ns.Name))
492+
493+
t.Log("Setting up SDK expectations for getting service")
494+
sdk.ServicesSDK.EXPECT().GetService(
495+
mock.Anything, serviceKonnectID, cp.GetKonnectID(),
496+
).Return(
497+
nil, &sdkkonnecterrs.NotFoundError{
498+
Title: "NotFound",
499+
Detail: fmt.Sprintf("Service %s not found", serviceKonnectID),
500+
},
501+
)
502+
503+
t.Log("Creating a KongService to adopt the existing service")
504+
createdService := deploy.KongService(t, t.Context(), clientNamespaced, deploy.WithKonnectNamespacedRefControlPlaneRef(cp),
505+
func(obj client.Object) {
506+
ks, ok := obj.(*configurationv1alpha1.KongService)
507+
require.True(t, ok)
508+
ks.Spec.URL = lo.ToPtr("https://example.com/example")
509+
ks.Spec.Adopt = &commonv1alpha1.AdoptOptions{
510+
From: commonv1alpha1.AdoptSourceKonnect,
511+
Mode: commonv1alpha1.AdoptModeOverride,
512+
Konnect: &commonv1alpha1.AdoptKonnectOptions{
513+
ID: serviceKonnectID,
514+
},
515+
}
516+
})
517+
518+
t.Log("Waiting for the KongService to be marked as not programmed")
519+
watchFor(t, t.Context(), w, apiwatch.Modified, func(ks *configurationv1alpha1.KongService) bool {
520+
return ks.Name == createdService.Name &&
521+
conditionsContainProgrammedFalse(ks.GetConditions()) &&
522+
lo.ContainsBy(ks.GetConditions(), func(c metav1.Condition) bool {
523+
return c.Type == konnectv1alpha1.KonnectEntityAdoptedConditionType &&
524+
c.Status == metav1.ConditionFalse
525+
})
526+
},
527+
"Did not see KongService marked as not Programmed and not Adopted",
528+
)
529+
})
530+
531+
t.Run("adopting a service with the k8s-uid tag already exists in the upstream service", func(t *testing.T) {
532+
serviceKonnectID := uuid.NewString()
533+
w := setupWatch[configurationv1alpha1.KongServiceList](t, ctx, cl, client.InNamespace(ns.Name))
534+
535+
t.Log("Setting up SDK expectations for getting service")
536+
sdk.ServicesSDK.EXPECT().GetService(
537+
mock.Anything, serviceKonnectID, cp.GetKonnectID(),
538+
).Return(
539+
&sdkkonnectops.GetServiceResponse{
540+
Service: &sdkkonnectcomp.ServiceOutput{
541+
ID: lo.ToPtr(serviceKonnectID),
542+
Host: "example.com",
543+
Tags: []string{
544+
"k8s-group:configuration.konghq.com",
545+
"k8s-version:v1alpha1",
546+
"k8s-kind:KongService",
547+
"k8s-uid:12345678-9999-0000-1111-abcdeffedcba",
548+
"k8s-namespace:" + ns.Name,
549+
"k8s-name:another-service",
550+
"k8s-generation:1",
551+
},
552+
},
553+
}, nil,
554+
)
555+
556+
t.Log("Creating a KongService to adopt the existing service")
557+
createdService := deploy.KongService(t, t.Context(), clientNamespaced, deploy.WithKonnectNamespacedRefControlPlaneRef(cp),
558+
func(obj client.Object) {
559+
ks, ok := obj.(*configurationv1alpha1.KongService)
560+
require.True(t, ok)
561+
ks.Spec.URL = lo.ToPtr("https://example.com/example")
562+
ks.Spec.Adopt = &commonv1alpha1.AdoptOptions{
563+
From: commonv1alpha1.AdoptSourceKonnect,
564+
Mode: commonv1alpha1.AdoptModeOverride,
565+
Konnect: &commonv1alpha1.AdoptKonnectOptions{
566+
ID: serviceKonnectID,
567+
},
568+
}
569+
})
570+
571+
t.Log("Waiting for the KongService to be marked as not programmed")
572+
watchFor(t, t.Context(), w, apiwatch.Modified, func(ks *configurationv1alpha1.KongService) bool {
573+
return ks.Name == createdService.Name &&
574+
conditionsContainProgrammedFalse(ks.GetConditions()) &&
575+
lo.ContainsBy(ks.GetConditions(), func(c metav1.Condition) bool {
576+
return c.Type == konnectv1alpha1.KonnectEntityAdoptedConditionType &&
577+
c.Status == metav1.ConditionFalse
578+
})
579+
},
580+
"Did not see KongService marked as not Programmed and not Adopted, conditions:",
581+
)
582+
583+
t.Log(createdService.GetConditions())
584+
})
422585
}

test/envtest/konnect_entities_konnectcloudgatewaynetwork_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import (
77
sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations"
88
sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors"
99
"github.com/google/uuid"
10+
"github.com/samber/lo"
1011
"github.com/stretchr/testify/mock"
1112
"github.com/stretchr/testify/require"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1314
apiwatch "k8s.io/apimachinery/pkg/watch"
1415
"sigs.k8s.io/controller-runtime/pkg/client"
1516

17+
commonv1alpha1 "github.com/kong/kong-operator/api/common/v1alpha1"
1618
konnectv1alpha1 "github.com/kong/kong-operator/api/konnect/v1alpha1"
1719
"github.com/kong/kong-operator/controller/konnect"
1820
"github.com/kong/kong-operator/modules/manager/logging"
@@ -140,4 +142,134 @@ func TestKonnectCloudGatewayNetwork(t *testing.T) {
140142
t.Log("Waiting for the expected calls called in SDK")
141143
eventuallyAssertSDKExpectations(t, factory.SDK.CloudGatewaysSDK, waitTime, tickTime)
142144
})
145+
146+
t.Run("Adopting a network with match mode", func(t *testing.T) {
147+
t.Log("Setting up a watch for KonnectCloudGatewayNetwork events")
148+
w := setupWatch[konnectv1alpha1.KonnectCloudGatewayNetworkList](t, ctx, cl, client.InNamespace(ns.Name))
149+
150+
networkName := "cloud-gateway-network-test-adopt-" + uuid.NewString()[:8]
151+
networkID := uuid.NewString()
152+
153+
t.Log("Setting up SDK expectation on getting")
154+
sdk.CloudGatewaysSDK.EXPECT().GetNetwork(mock.Anything, networkID).Return(
155+
&sdkkonnectops.GetNetworkResponse{
156+
Network: &sdkkonnectcomp.Network{
157+
ID: networkID,
158+
Name: networkName,
159+
CloudGatewayProviderAccountID: "aws:1234",
160+
Region: "us-east-1",
161+
AvailabilityZones: []string{
162+
"us-east-1",
163+
},
164+
CidrBlock: "10.0.0.0/24",
165+
State: sdkkonnectcomp.NetworkStateInitializing,
166+
ProviderMetadata: sdkkonnectcomp.NetworkProviderMetadata{
167+
VpcID: lo.ToPtr("vpc-1234"),
168+
},
169+
},
170+
}, nil,
171+
)
172+
173+
t.Log("Creating KonnectAPIAuthConfiguration")
174+
apiAuth := deploy.KonnectAPIAuthConfigurationWithProgrammed(t, ctx, clientNamespaced)
175+
176+
t.Log("Creating a KonnectCloudGatewayNetwork to adopt the existing network")
177+
createdNetwork := deploy.KonnectCloudGatewayNetwork(t, ctx, clientNamespaced, apiAuth, func(o client.Object) {
178+
n, ok := o.(*konnectv1alpha1.KonnectCloudGatewayNetwork)
179+
if !ok {
180+
return
181+
}
182+
183+
n.Spec.Adopt = &commonv1alpha1.AdoptOptions{
184+
From: commonv1alpha1.AdoptSourceKonnect,
185+
Mode: commonv1alpha1.AdoptModeMatch,
186+
Konnect: &commonv1alpha1.AdoptKonnectOptions{
187+
ID: networkID,
188+
},
189+
}
190+
n.Spec.Name = networkName
191+
n.Spec.CloudGatewayProviderAccountID = "aws:1234"
192+
n.Spec.Region = "us-east-1"
193+
n.Spec.AvailabilityZones = []string{"us-east-1"}
194+
n.Spec.CidrBlock = "10.0.0.0/24"
195+
})
196+
197+
t.Log("Waiting for KonnectCloudGatewayNetwork to be marked as programmed and get Konnect ID")
198+
watchFor(t, t.Context(), w, apiwatch.Modified, func(n *konnectv1alpha1.KonnectCloudGatewayNetwork) bool {
199+
return n.Name == createdNetwork.Name &&
200+
conditionsContainProgrammedTrue(n.GetConditions()) &&
201+
n.GetKonnectID() == networkID
202+
},
203+
"Did not see KonnectCloudGatewayNetwork turn Programmed and set Konnect ID",
204+
)
205+
206+
})
207+
208+
t.Run("Adopting a network with match mode but not matching the network in Konnect", func(t *testing.T) {
209+
t.Log("Setting up a watch for KonnectCloudGatewayNetwork events")
210+
w := setupWatch[konnectv1alpha1.KonnectCloudGatewayNetworkList](t, ctx, cl, client.InNamespace(ns.Name))
211+
212+
networkName := "cloud-gateway-network-test-adopt-" + uuid.NewString()[:8]
213+
networkID := uuid.NewString()
214+
215+
t.Log("Setting up SDK expectation on getting")
216+
sdk.CloudGatewaysSDK.EXPECT().GetNetwork(mock.Anything, networkID).Return(
217+
&sdkkonnectops.GetNetworkResponse{
218+
Network: &sdkkonnectcomp.Network{
219+
ID: networkID,
220+
Name: networkName,
221+
CloudGatewayProviderAccountID: "aws:1234",
222+
Region: "us-east-1",
223+
AvailabilityZones: []string{
224+
"us-east-1",
225+
},
226+
CidrBlock: "10.0.0.0/24",
227+
State: sdkkonnectcomp.NetworkStateInitializing,
228+
ProviderMetadata: sdkkonnectcomp.NetworkProviderMetadata{
229+
VpcID: lo.ToPtr("vpc-1234"),
230+
},
231+
},
232+
}, nil,
233+
)
234+
235+
t.Log("Creating KonnectAPIAuthConfiguration")
236+
apiAuth := deploy.KonnectAPIAuthConfigurationWithProgrammed(t, ctx, clientNamespaced)
237+
238+
t.Log("Creating a KonnectCloudGatewayNetwork to adopt the existing network but not matching the configuration")
239+
createdNetwork := deploy.KonnectCloudGatewayNetwork(t, ctx, clientNamespaced, apiAuth, func(o client.Object) {
240+
n, ok := o.(*konnectv1alpha1.KonnectCloudGatewayNetwork)
241+
if !ok {
242+
return
243+
}
244+
245+
n.Spec.Adopt = &commonv1alpha1.AdoptOptions{
246+
From: commonv1alpha1.AdoptSourceKonnect,
247+
Mode: commonv1alpha1.AdoptModeMatch,
248+
Konnect: &commonv1alpha1.AdoptKonnectOptions{
249+
ID: networkID,
250+
},
251+
}
252+
n.Spec.Name = networkName
253+
n.Spec.CloudGatewayProviderAccountID = "aws:1234"
254+
n.Spec.Region = "us-east-1"
255+
n.Spec.AvailabilityZones = []string{"us-east-1"}
256+
n.Spec.CidrBlock = "10.1.0.0/24" // different CIDRs with the existing network
257+
})
258+
259+
t.Log("Waiting for KonnectCloudGatewayNetwork to be marked as not programmed")
260+
watchFor(t, t.Context(), w, apiwatch.Modified, func(n *konnectv1alpha1.KonnectCloudGatewayNetwork) bool {
261+
return n.Name == createdNetwork.Name &&
262+
conditionsContainProgrammedFalse(n.GetConditions()) && lo.ContainsBy(
263+
n.GetConditions(), func(c metav1.Condition) bool {
264+
return c.Type == konnectv1alpha1.KonnectEntityAdoptedConditionType &&
265+
c.Status == metav1.ConditionFalse &&
266+
c.Reason == konnectv1alpha1.KonnectEntityAdoptedReasonNotMatch
267+
268+
},
269+
)
270+
},
271+
"Did not see KonnectCloudGatewayNetwork marked as not Programmed and not Adopted",
272+
)
273+
274+
})
143275
}

0 commit comments

Comments
 (0)