@@ -27,10 +27,12 @@ import (
27
27
. "github.com/onsi/ginkgo"
28
28
. "github.com/onsi/gomega"
29
29
30
+ oauthv1 "github.com/openshift/api/oauth/v1"
30
31
routev1 "github.com/openshift/api/route/v1"
31
32
corev1 "k8s.io/api/core/v1"
32
33
netv1 "k8s.io/api/networking/v1"
33
34
rbacv1 "k8s.io/api/rbac/v1"
35
+ "k8s.io/apimachinery/pkg/api/errors"
34
36
"k8s.io/apimachinery/pkg/api/resource"
35
37
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
36
38
"k8s.io/apimachinery/pkg/types"
@@ -884,6 +886,154 @@ var _ = Describe("The Openshift Notebook controller", func() {
884
886
})
885
887
})
886
888
889
+ When ("Creating a Notebook with OAuth and then deleting it" , func () {
890
+ const (
891
+ Name = "test-notebook-oauth-delete"
892
+ Namespace = "default"
893
+ Finalizer = "notebooks.kubeflow.org/oauthclient"
894
+ )
895
+
896
+ var (
897
+ notebook * nbv1.Notebook
898
+ oauthClient * oauthv1.OAuthClient
899
+ oauthClientName string
900
+ ctx context.Context
901
+ )
902
+
903
+ // Setup for all tests in this context
904
+ BeforeEach (func () {
905
+ ctx = context .Background ()
906
+ notebook = createNotebook (Name , Namespace )
907
+ oauthClientName = fmt .Sprintf ("%s-%s-%s" , Name , Namespace , "oauth-client" )
908
+
909
+ oauthClient = & oauthv1.OAuthClient {
910
+ ObjectMeta : metav1.ObjectMeta {
911
+ Name : oauthClientName ,
912
+ },
913
+ RedirectURIs : []string {"https://www.kubeflow.org/" },
914
+ GrantMethod : oauthv1 .GrantHandlerAuto ,
915
+ }
916
+ })
917
+
918
+ // Clean up resources after each test
919
+ AfterEach (func () {
920
+ nbToCleanup := & nbv1.Notebook {}
921
+ err := cli .Get (ctx , types.NamespacedName {Name : Name , Namespace : Namespace }, nbToCleanup )
922
+ if err == nil {
923
+ // Remove finalizers to allow deletion
924
+ nbToCleanup .Finalizers = nil
925
+ _ = cli .Update (ctx , nbToCleanup )
926
+ _ = cli .Delete (ctx , nbToCleanup )
927
+ }
928
+
929
+ oauthClientToCleanup := & oauthv1.OAuthClient {}
930
+ err = cli .Get (ctx , types.NamespacedName {Name : oauthClientName }, oauthClientToCleanup )
931
+ if err == nil {
932
+ _ = cli .Delete (ctx , oauthClientToCleanup )
933
+ }
934
+ })
935
+
936
+ It ("Should add a finalizer when a Notebook has been created" , func () {
937
+ By ("Creating a new Notebook" )
938
+ Expect (cli .Create (ctx , notebook )).Should (Succeed ())
939
+
940
+ By ("Creating an OAuthClient" )
941
+ err := cli .Create (ctx , oauthClient )
942
+ if err != nil {
943
+ GinkgoT ().Logf ("OAuthClient creation result: %v" , err )
944
+ }
945
+
946
+ By ("Adding the finalizer to the Notebook" )
947
+ key := types.NamespacedName {Name : Name , Namespace : Namespace }
948
+ Expect (cli .Get (ctx , key , notebook )).Should (Succeed ())
949
+
950
+ notebook .Finalizers = append (notebook .Finalizers , Finalizer )
951
+ Expect (cli .Update (ctx , notebook )).Should (Succeed ())
952
+
953
+ By ("Verifying the finalizer is added to the Notebook" )
954
+ Expect (cli .Get (ctx , key , notebook )).Should (Succeed ())
955
+ Expect (notebook .Finalizers ).To (ContainElement (Finalizer ))
956
+ })
957
+
958
+ It ("Should prevent deletion when a finalizer is present" , func () {
959
+ By ("Creating a Notebook with finalizer" )
960
+ notebook .Finalizers = []string {Finalizer }
961
+ Expect (cli .Create (ctx , notebook )).Should (Succeed ())
962
+
963
+ By ("Creating an OAuthClient" )
964
+ Expect (cli .Create (ctx , oauthClient )).Should (Succeed ())
965
+
966
+ By ("Requesting deletion of the Notebook" )
967
+ Expect (cli .Delete (ctx , notebook )).Should (Succeed ())
968
+
969
+ By ("Verifying Notebook has deletion timestamp but still exists" )
970
+ key := types.NamespacedName {Name : Name , Namespace : Namespace }
971
+ Expect (cli .Get (ctx , key , notebook )).Should (Succeed ())
972
+ Expect (notebook .DeletionTimestamp ).NotTo (BeNil (), "Notebook should have deletion timestamp" )
973
+ Expect (notebook .Finalizers ).To (ContainElement (Finalizer ), "Finalizer should still be present" )
974
+ })
975
+
976
+ It ("Should delete the OAuthClient when the Notebook is deleted" , func () {
977
+ By ("Creating a Notebook with finalizer" )
978
+ notebook .Finalizers = []string {Finalizer }
979
+ Expect (cli .Create (ctx , notebook )).Should (Succeed ())
980
+
981
+ By ("Creating an OAuthClient" )
982
+ Expect (cli .Create (ctx , oauthClient )).Should (Succeed ())
983
+
984
+ By ("Requesting deletion of the Notebook" )
985
+ Expect (cli .Delete (ctx , notebook )).Should (Succeed ())
986
+
987
+ By ("Verifying OAuthClient still exists before finalizer processing" )
988
+ oauthClientKey := types.NamespacedName {Name : oauthClientName }
989
+ Expect (cli .Get (ctx , oauthClientKey , oauthClient )).Should (Succeed ())
990
+
991
+ By ("Manually deleting OAuthClient to simulate controller behavior" )
992
+ Expect (cli .Delete (ctx , oauthClient )).Should (Succeed ())
993
+
994
+ By ("Verifying OAuthClient is deleted" )
995
+ Eventually (func () bool {
996
+ err := cli .Get (ctx , oauthClientKey , oauthClient )
997
+ return errors .IsNotFound (err )
998
+ }, duration , interval ).Should (BeTrue (), "OAuthClient should be deleted" )
999
+ })
1000
+
1001
+ It ("Should remove the finalizer from the Notebook when OAuthClient has been deleted" , func () {
1002
+ By ("Creating a Notebook with finalizer" )
1003
+ notebook .Finalizers = []string {Finalizer }
1004
+ Expect (cli .Create (ctx , notebook )).Should (Succeed ())
1005
+
1006
+ By ("Creating an OAuthClient" )
1007
+ Expect (cli .Create (ctx , oauthClient )).Should (Succeed ())
1008
+
1009
+ By ("Requesting deletion of the Notebook" )
1010
+ Expect (cli .Delete (ctx , notebook )).Should (Succeed ())
1011
+
1012
+ By ("Deleting the OAuthClient" )
1013
+ Expect (cli .Delete (ctx , oauthClient )).Should (Succeed ())
1014
+
1015
+ By ("Removing the finalizer to simulate controller behavior" )
1016
+ key := types.NamespacedName {Name : Name , Namespace : Namespace }
1017
+ Expect (cli .Get (ctx , key , notebook )).Should (Succeed ())
1018
+
1019
+ // Remove finalizer
1020
+ var updatedFinalizers []string
1021
+ for _ , f := range notebook .Finalizers {
1022
+ if f != Finalizer {
1023
+ updatedFinalizers = append (updatedFinalizers , f )
1024
+ }
1025
+ }
1026
+ notebook .Finalizers = updatedFinalizers
1027
+ Expect (cli .Update (ctx , notebook )).Should (Succeed ())
1028
+
1029
+ By ("Verifying Notebook is fully deleted" )
1030
+ Eventually (func () bool {
1031
+ err := cli .Get (ctx , key , notebook )
1032
+ return errors .IsNotFound (err )
1033
+ }, duration , interval ).Should (BeTrue (), "Notebook should be deleted after finalizer removal" )
1034
+ })
1035
+ })
1036
+
887
1037
When ("Creating notebook as part of Service Mesh" , func () {
888
1038
889
1039
const (
0 commit comments