@@ -16,6 +16,7 @@ import (
1616	"helm.sh/helm/v3/pkg/release" 
1717	"helm.sh/helm/v3/pkg/storage/driver" 
1818	corev1 "k8s.io/api/core/v1" 
19+ 	rbacv1 "k8s.io/api/rbac/v1" 
1920	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 
2021	featuregatetesting "k8s.io/component-base/featuregate/testing" 
2122	"sigs.k8s.io/controller-runtime/pkg/client" 
@@ -34,26 +35,17 @@ type mockPreflight struct {
3435	upgradeErr  error 
3536}
3637
37- type  noOpPreAuthorizer  struct {}
38- 
39- func  (p  * noOpPreAuthorizer ) PreAuthorize (
40- 	ctx  context.Context ,
41- 	ext  * ocv1.ClusterExtension ,
42- 	manifestReader  io.Reader ,
43- ) ([]authorization.ScopedPolicyRules , error ) {
44- 	// No-op: always return an empty map and no error 
45- 	return  nil , nil 
38+ type  mockPreAuthorizer  struct  {
39+ 	missingRules  []authorization.ScopedPolicyRules 
40+ 	returnError   error 
4641}
4742
48- type  errorPreAuthorizer  struct {}
49- 
50- func  (p  * errorPreAuthorizer ) PreAuthorize (
43+ func  (p  * mockPreAuthorizer ) PreAuthorize (
5144	ctx  context.Context ,
5245	ext  * ocv1.ClusterExtension ,
5346	manifestReader  io.Reader ,
5447) ([]authorization.ScopedPolicyRules , error ) {
55- 	// Always returns no missing rules and an error 
56- 	return  nil , errors .New ("problem running preauthorization" )
48+ 	return  p .missingRules , p .returnError 
5749}
5850
5951func  (mp  * mockPreflight ) Install (context.Context , * release.Release ) error  {
@@ -163,6 +155,33 @@ spec:
163155	testCE             =  & ocv1.ClusterExtension {}
164156	testObjectLabels   =  map [string ]string {"object" : "label" }
165157	testStorageLabels  =  map [string ]string {"storage" : "label" }
158+ 	errPreAuth         =  errors .New ("problem running preauthorization" )
159+ 	missingRBAC        =  []authorization.ScopedPolicyRules {
160+ 		{
161+ 			Namespace : "" ,
162+ 			MissingRules : []rbacv1.PolicyRule {
163+ 				{
164+ 					Verbs :           []string {"list" , "watch" },
165+ 					APIGroups :       []string {"" },
166+ 					Resources :       []string {"services" },
167+ 					ResourceNames :   []string (nil ),
168+ 					NonResourceURLs : []string (nil )},
169+ 			},
170+ 		},
171+ 		{
172+ 			Namespace : "test-namespace" ,
173+ 			MissingRules : []rbacv1.PolicyRule {
174+ 				{
175+ 					Verbs :     []string {"create" },
176+ 					APIGroups : []string {"*" },
177+ 					Resources : []string {"certificates" }},
178+ 			},
179+ 		},
180+ 	}
181+ 
182+ 	errMissingRBAC  =  "pre-authorization failed: service account requires the following permissions to manage cluster extension:\n "  + 
183+ 		"  Namespace:\" \"  APIGroups:[] Resources:[services] Verbs:[list,watch]\n "  + 
184+ 		"  Namespace:\" test-namespace\"  APIGroups:[*] Resources:[certificates] Verbs:[create]\n " 
166185)
167186
168187func  TestApply_Base (t  * testing.T ) {
@@ -311,7 +330,7 @@ func TestApply_InstallationWithPreflightPermissionsEnabled(t *testing.T) {
311330		helmApplier  :=  applier.Helm {
312331			ActionClientGetter :  mockAcg ,
313332			Preflights :          []applier.Preflight {mockPf },
314- 			PreAuthorizer :       & noOpPreAuthorizer { },
333+ 			PreAuthorizer :       & mockPreAuthorizer { nil ,  nil },
315334			BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
316335		}
317336
@@ -332,7 +351,7 @@ func TestApply_InstallationWithPreflightPermissionsEnabled(t *testing.T) {
332351		}
333352		helmApplier  :=  applier.Helm {
334353			ActionClientGetter :  mockAcg ,
335- 			PreAuthorizer :       & errorPreAuthorizer { },
354+ 			PreAuthorizer :       & mockPreAuthorizer { nil ,  errPreAuth },
336355			BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
337356		}
338357		// Use a ClusterExtension with valid Spec fields. 
@@ -351,6 +370,35 @@ func TestApply_InstallationWithPreflightPermissionsEnabled(t *testing.T) {
351370		require .Nil (t , objs )
352371	})
353372
373+ 	t .Run ("fails during installation due to missing RBAC rules" , func (t  * testing.T ) {
374+ 		mockAcg  :=  & mockActionGetter {
375+ 			getClientErr : driver .ErrReleaseNotFound ,
376+ 			desiredRel : & release.Release {
377+ 				Info :     & release.Info {Status : release .StatusDeployed },
378+ 				Manifest : validManifest ,
379+ 			},
380+ 		}
381+ 		helmApplier  :=  applier.Helm {
382+ 			ActionClientGetter :  mockAcg ,
383+ 			PreAuthorizer :       & mockPreAuthorizer {missingRBAC , nil },
384+ 			BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
385+ 		}
386+ 		// Use a ClusterExtension with valid Spec fields. 
387+ 		validCE  :=  & ocv1.ClusterExtension {
388+ 			Spec : ocv1.ClusterExtensionSpec {
389+ 				Namespace : "default" ,
390+ 				ServiceAccount : ocv1.ServiceAccountReference {
391+ 					Name : "default" ,
392+ 				},
393+ 			},
394+ 		}
395+ 		objs , state , err  :=  helmApplier .Apply (context .TODO (), validFS , validCE , testObjectLabels , testStorageLabels )
396+ 		require .Error (t , err )
397+ 		require .ErrorContains (t , err , errMissingRBAC )
398+ 		require .Equal (t , "" , state )
399+ 		require .Nil (t , objs )
400+ 	})
401+ 
354402	t .Run ("successful installation" , func (t  * testing.T ) {
355403		mockAcg  :=  & mockActionGetter {
356404			getClientErr : driver .ErrReleaseNotFound ,
@@ -361,7 +409,7 @@ func TestApply_InstallationWithPreflightPermissionsEnabled(t *testing.T) {
361409		}
362410		helmApplier  :=  applier.Helm {
363411			ActionClientGetter :  mockAcg ,
364- 			PreAuthorizer :       & noOpPreAuthorizer { },
412+ 			PreAuthorizer :       & mockPreAuthorizer { nil ,  nil },
365413			BundleToHelmChartFn : convert .RegistryV1ToHelmChart ,
366414		}
367415
0 commit comments