github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/install/attributes_util_test.go (about)

     1  package install
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  	rbacv1 "k8s.io/api/rbac/v1"
     9  	"k8s.io/apiserver/pkg/authentication/user"
    10  	"k8s.io/apiserver/pkg/authorization/authorizer"
    11  )
    12  
    13  func TestToAttributeSet(t *testing.T) {
    14  	user := &user.DefaultInfo{
    15  		Name: "Jim",
    16  	}
    17  	namespace := "olm"
    18  
    19  	tests := []struct {
    20  		description        string
    21  		rule               rbacv1.PolicyRule
    22  		expectedAttributes map[string]authorizer.AttributesRecord
    23  	}{
    24  		{
    25  			description: "SimpleRule",
    26  			rule: rbacv1.PolicyRule{
    27  				Verbs:     []string{"*"},
    28  				APIGroups: []string{"*"},
    29  				Resources: []string{"*"},
    30  			},
    31  			expectedAttributes: map[string]authorizer.AttributesRecord{
    32  				attributesKey(user, namespace, "*", "*", "*", "", ""): attributesRecord(user, namespace, "*", "*", "*", "", ""),
    33  			},
    34  		},
    35  		{
    36  			description: "SimpleNonResourceRule",
    37  			rule: rbacv1.PolicyRule{
    38  				Verbs:           []string{"*"},
    39  				NonResourceURLs: []string{"/api"},
    40  			},
    41  			expectedAttributes: map[string]authorizer.AttributesRecord{
    42  				attributesKey(user, namespace, "*", "", "", "", "/api"): attributesRecord(user, namespace, "*", "", "", "", "/api"),
    43  			},
    44  		},
    45  		{
    46  			description: "SeparateVerbs",
    47  			rule: rbacv1.PolicyRule{
    48  				Verbs:     []string{"create", "delete"},
    49  				APIGroups: []string{"*"},
    50  				Resources: []string{"*"},
    51  			},
    52  			expectedAttributes: map[string]authorizer.AttributesRecord{
    53  				attributesKey(user, namespace, "create", "*", "*", "", ""): attributesRecord(user, namespace, "create", "*", "*", "", ""),
    54  				attributesKey(user, namespace, "delete", "*", "*", "", ""): attributesRecord(user, namespace, "delete", "*", "*", "", ""),
    55  			},
    56  		},
    57  		{
    58  			description: "MultipleResources",
    59  			rule: rbacv1.PolicyRule{
    60  				Verbs:     []string{"get", "update"},
    61  				Resources: []string{"donuts", "coffee"},
    62  			},
    63  			expectedAttributes: map[string]authorizer.AttributesRecord{
    64  				attributesKey(user, namespace, "get", "", "donuts", "", ""):    attributesRecord(user, namespace, "get", "", "donuts", "", ""),
    65  				attributesKey(user, namespace, "update", "", "donuts", "", ""): attributesRecord(user, namespace, "update", "", "donuts", "", ""),
    66  				attributesKey(user, namespace, "get", "", "coffee", "", ""):    attributesRecord(user, namespace, "get", "", "coffee", "", ""),
    67  				attributesKey(user, namespace, "update", "", "coffee", "", ""): attributesRecord(user, namespace, "update", "", "coffee", "", ""),
    68  			},
    69  		},
    70  		{
    71  			description: "MultipleNonResourceURLs",
    72  			rule: rbacv1.PolicyRule{
    73  				Verbs:           []string{"*"},
    74  				NonResourceURLs: []string{"/capybaras", "/caviidaes"},
    75  			},
    76  			expectedAttributes: map[string]authorizer.AttributesRecord{
    77  				attributesKey(user, namespace, "*", "", "", "", "/capybaras"): attributesRecord(user, namespace, "*", "", "", "", "/capybaras"),
    78  				attributesKey(user, namespace, "*", "", "", "", "/caviidaes"): attributesRecord(user, namespace, "*", "", "", "", "/caviidaes"),
    79  			},
    80  		},
    81  		{
    82  			description: "MultipleResourcesWithResourceName",
    83  			rule: rbacv1.PolicyRule{
    84  				Verbs:         []string{"get", "update"},
    85  				Resources:     []string{"donuts", "coffee"},
    86  				ResourceNames: []string{"nyc"},
    87  			},
    88  			expectedAttributes: map[string]authorizer.AttributesRecord{
    89  				attributesKey(user, namespace, "get", "", "donuts", "nyc", ""):    attributesRecord(user, namespace, "get", "", "donuts", "nyc", ""),
    90  				attributesKey(user, namespace, "update", "", "donuts", "nyc", ""): attributesRecord(user, namespace, "update", "", "donuts", "nyc", ""),
    91  				attributesKey(user, namespace, "get", "", "coffee", "nyc", ""):    attributesRecord(user, namespace, "get", "", "coffee", "nyc", ""),
    92  				attributesKey(user, namespace, "update", "", "coffee", "nyc", ""): attributesRecord(user, namespace, "update", "", "coffee", "nyc", ""),
    93  			},
    94  		},
    95  		{
    96  			description: "MultipleResourcesWithMultipleAPIGroups",
    97  			rule: rbacv1.PolicyRule{
    98  				Verbs:         []string{"get", "update"},
    99  				Resources:     []string{"donuts", "coffee"},
   100  				APIGroups:     []string{"apps.coreos.com", "apps.redhat.com"},
   101  				ResourceNames: []string{"nyc"},
   102  			},
   103  			expectedAttributes: map[string]authorizer.AttributesRecord{
   104  				attributesKey(user, namespace, "get", "apps.coreos.com", "donuts", "nyc", ""):    attributesRecord(user, namespace, "get", "apps.coreos.com", "donuts", "nyc", ""),
   105  				attributesKey(user, namespace, "update", "apps.coreos.com", "donuts", "nyc", ""): attributesRecord(user, namespace, "update", "apps.coreos.com", "donuts", "nyc", ""),
   106  				attributesKey(user, namespace, "get", "apps.coreos.com", "coffee", "nyc", ""):    attributesRecord(user, namespace, "get", "apps.coreos.com", "coffee", "nyc", ""),
   107  				attributesKey(user, namespace, "update", "apps.coreos.com", "coffee", "nyc", ""): attributesRecord(user, namespace, "update", "apps.coreos.com", "coffee", "nyc", ""),
   108  				attributesKey(user, namespace, "get", "apps.redhat.com", "donuts", "nyc", ""):    attributesRecord(user, namespace, "get", "apps.redhat.com", "donuts", "nyc", ""),
   109  				attributesKey(user, namespace, "update", "apps.redhat.com", "donuts", "nyc", ""): attributesRecord(user, namespace, "update", "apps.redhat.com", "donuts", "nyc", ""),
   110  				attributesKey(user, namespace, "get", "apps.redhat.com", "coffee", "nyc", ""):    attributesRecord(user, namespace, "get", "apps.redhat.com", "coffee", "nyc", ""),
   111  				attributesKey(user, namespace, "update", "apps.redhat.com", "coffee", "nyc", ""): attributesRecord(user, namespace, "update", "apps.redhat.com", "coffee", "nyc", ""),
   112  			},
   113  		},
   114  		{
   115  			description:        "NoVerbs",
   116  			rule:               rbacv1.PolicyRule{},
   117  			expectedAttributes: map[string]authorizer.AttributesRecord{},
   118  		},
   119  	}
   120  
   121  	for _, tt := range tests {
   122  		t.Run(tt.description, func(t *testing.T) {
   123  			attributesSet := toAttributesSet(user, namespace, tt.rule)
   124  
   125  			require.Equal(t, len(tt.expectedAttributes), len(attributesSet))
   126  
   127  			for _, attributes := range attributesSet {
   128  				// type assert as AttributesRecord
   129  				a, ok := attributes.(authorizer.AttributesRecord)
   130  				require.True(t, ok, "type assertion for attributes failed")
   131  
   132  				// make sure we're expecting the attribute
   133  				key := attributesKey(a.GetUser(), a.GetNamespace(), a.GetVerb(), a.GetAPIGroup(), a.GetResource(), a.GetName(), a.GetPath())
   134  				_, exists := tt.expectedAttributes[key]
   135  				require.True(t, exists, fmt.Sprintf("found unexpected attributes %v", attributes))
   136  
   137  				// ensure each expected attribute only appears once
   138  				delete(tt.expectedAttributes, key)
   139  			}
   140  
   141  			// check that all expected have been found
   142  			require.Zero(t, len(tt.expectedAttributes), fmt.Sprintf("%d expected attributes not found", len(tt.expectedAttributes)))
   143  		})
   144  	}
   145  }