Skip to content

Commit 7fb889e

Browse files
committed
test(e2e): add sanity check for project admin permissions
1 parent be048a8 commit 7fb889e

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

scripts/build_local.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
set -e
77

8-
if [ -z "$NO_MINIKUBE" ] || [ -x "$(command -v minikube)" ]; then
8+
if [ -z "$NO_MINIKUBE" ]; then
99
ps x | grep -q [m]inikube || minikube start --kubernetes-version="v1.12.0" --extra-config=apiserver.v=4 || { echo 'Cannot start minikube.'; exit 1; }
1010
eval $(minikube docker-env) || { echo 'Cannot switch to minikube docker'; exit 1; }
1111
kubectl config use-context minikube

test/e2e/operator_groups_e2e_test.go

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,14 +447,48 @@ func TestOperatorGroup(t *testing.T) {
447447
require.NoError(t, err)
448448
}
449449

450+
func createProjectAdmin(t *testing.T, c operatorclient.ClientInterface, namespace string) (string, cleanupFunc) {
451+
sa, err := c.CreateServiceAccount(&corev1.ServiceAccount{
452+
ObjectMeta: metav1.ObjectMeta{
453+
Namespace: namespace,
454+
Name: genName("padmin-"),
455+
},
456+
})
457+
require.NoError(t, err)
458+
459+
rb, err := c.CreateRoleBinding(&rbacv1.RoleBinding{
460+
ObjectMeta: metav1.ObjectMeta{
461+
Name: genName("padmin-"),
462+
Namespace: namespace,
463+
},
464+
Subjects: []rbacv1.Subject{
465+
{
466+
Kind: "ServiceAccount",
467+
Name: sa.GetName(),
468+
Namespace: sa.GetNamespace(),
469+
},
470+
},
471+
RoleRef: rbacv1.RoleRef{
472+
APIGroup: "rbac.authorization.k8s.io",
473+
Kind: "ClusterRole",
474+
Name: "admin",
475+
},
476+
})
477+
require.NoError(t, err)
478+
return "system:serviceaccount:" + sa.GetNamespace() + ":" + sa.GetName(), func() {
479+
_ = c.DeleteServiceAccount(sa.GetNamespace(), sa.GetName(), metav1.NewDeleteOptions(0))
480+
_ = c.DeleteRoleBinding(rb.GetNamespace(), rb.GetName(), metav1.NewDeleteOptions(0))
481+
}
482+
}
483+
450484
func TestOperatorGroupInstallModeSupport(t *testing.T) {
451485
// Generate namespaceA
452486
// Generate namespaceB
453487
// Create operatorGroupA in namespaceA that selects namespaceA
454488
// Generate csvA with an unfulfilled required CRD and no supported InstallModes in namespaceA
455489
// Ensure csvA transitions to Failed with reason "UnsupportedOperatorGroup"
456490
// Update csvA to have OwnNamespace supported=true
457-
// Ensure csvA transitions to Pending
491+
// Ensure csvA transitions to Succeeded
458492
// Update operatorGroupA's target namespaces to select namespaceB
459493
// Ensure csvA transitions to Failed with reason "UnsupportedOperatorGroup"
460494
// Update csvA to have SingleNamespace supported=true
@@ -555,8 +589,13 @@ func TestOperatorGroupInstallModeSupport(t *testing.T) {
555589
_, err = crc.OperatorsV1alpha1().ClusterServiceVersions(nsA).Update(csvA)
556590
require.NoError(t, err)
557591

558-
// Ensure csvA transitions to Pending
559-
csvA, err = fetchCSV(t, crc, csvA.GetName(), nsA, csvPendingChecker)
592+
// Create crd so csv succeeds
593+
cleanupCRD, err := createCRD(c, crd)
594+
require.NoError(t, err)
595+
defer cleanupCRD()
596+
597+
// Ensure csvA transitions to Succeeded
598+
csvA, err = fetchCSV(t, crc, csvA.GetName(), nsA, csvSucceededChecker)
560599
require.NoError(t, err)
561600

562601
// Update operatorGroupA's target namespaces to select namespaceB
@@ -689,6 +728,7 @@ func TestOperatorGroupIntersection(t *testing.T) {
689728
// Ensure csvD in namespaceD is still successful
690729
// Generate csvA in namespaceA that owns crdA
691730
// Wait for csvA to be successful
731+
// Ensure clusterroles created and aggregated for accessing provided APIs
692732
// Wait for operatorGroupA to have providedAPI annotation with crdA's Kind.version.group in its providedAPIs annotation
693733
// Wait for csvA to have a CSV with copied status in namespace C
694734
// Generate operatorGroupB in namespaceB that selects namespace C
@@ -851,6 +891,25 @@ func TestOperatorGroupIntersection(t *testing.T) {
851891
_, err = awaitCSV(t, crc, nsA, csvA.GetName(), csvSucceededChecker)
852892
require.NoError(t, err)
853893

894+
// Ensure clusterroles created and aggregated for access provided APIs
895+
padmin, cleanupPadmin := createProjectAdmin(t, c, nsA)
896+
defer cleanupPadmin()
897+
898+
res, err := c.KubernetesInterface().AuthorizationV1().SubjectAccessReviews().Create(&v1.SubjectAccessReview{
899+
Spec: v1.SubjectAccessReviewSpec{
900+
User: padmin,
901+
ResourceAttributes: &v1.ResourceAttributes{
902+
Namespace: nsA,
903+
Group: crdA.Spec.Group,
904+
Version: crdA.Spec.Version,
905+
Resource: crdA.Spec.Names.Plural,
906+
Verb: "create",
907+
},
908+
},
909+
})
910+
require.NoError(t, err)
911+
require.True(t, res.Status.Allowed, "got %#v", res.Status)
912+
854913
// Await annotation on groupA
855914
q = func() (metav1.ObjectMeta, error) {
856915
g, err := crc.OperatorsV1().OperatorGroups(nsA).Get(groupA.GetName(), metav1.GetOptions{})

0 commit comments

Comments
 (0)