@@ -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:
183+ Namespace:"" APIGroups:[] Resources:[services] Verbs:[list,watch]
184+ Namespace:"test-namespace" APIGroups:[*] Resources:[certificates] Verbs:[create]`
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