Skip to content

Commit 0f0c9c4

Browse files
committed
Add RBAC preflight test case, reorder wrapErrorWithResolutionInfo
Adds another test case to helm_test.go for when PreAuthorize() returns missing RBAC rules. Merges the noOpPreauthorizer and errPreAuthorizer into one mockPreAuthorizer in helm_test.go. Reverses the structure of the error string in wrapErrorWithResolutionInfo such that the context is first and the error follows. Signed-off-by: Tayler Geiger <[email protected]>
1 parent a7ab445 commit 0f0c9c4

File tree

2 files changed

+66
-18
lines changed

2 files changed

+66
-18
lines changed

internal/operator-controller/applier/helm_test.go

+65-17
Original file line numberDiff line numberDiff line change
@@ -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

5951
func (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

168187
func 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

internal/operator-controller/controllers/clusterextension_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
439439
}
440440

441441
func wrapErrorWithResolutionInfo(resolved ocv1.BundleMetadata, err error) error {
442-
return fmt.Errorf("%w for resolved bundle %q with version %q", err, resolved.Name, resolved.Version)
442+
return fmt.Errorf("error for resolved bundle %q with version %q: %w", resolved.Name, resolved.Version, err)
443443
}
444444

445445
// Generate reconcile requests for all cluster extensions affected by a catalog change

0 commit comments

Comments
 (0)