@@ -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}
0 commit comments