...

Source file src/k8s.io/kubernetes/pkg/registry/rbac/validation/policy_compact_test.go

Documentation: k8s.io/kubernetes/pkg/registry/rbac/validation

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package validation
    18  
    19  import (
    20  	"reflect"
    21  	"sort"
    22  	"testing"
    23  
    24  	rbacv1 "k8s.io/api/rbac/v1"
    25  	"k8s.io/component-helpers/auth/rbac/validation"
    26  	rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
    27  )
    28  
    29  func TestCompactRules(t *testing.T) {
    30  	testcases := map[string]struct {
    31  		Rules    []rbacv1.PolicyRule
    32  		Expected []rbacv1.PolicyRule
    33  	}{
    34  		"empty": {
    35  			Rules:    []rbacv1.PolicyRule{},
    36  			Expected: []rbacv1.PolicyRule{},
    37  		},
    38  		"simple": {
    39  			Rules: []rbacv1.PolicyRule{
    40  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}},
    41  				{Verbs: []string{"list"}, APIGroups: []string{""}, Resources: []string{"builds"}},
    42  				{Verbs: []string{"update", "patch"}, APIGroups: []string{""}, Resources: []string{"builds"}},
    43  
    44  				{Verbs: []string{"create"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}},
    45  				{Verbs: []string{"delete"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}},
    46  				{Verbs: []string{"patch"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}, ResourceNames: []string{""}},
    47  				{Verbs: []string{"get"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}, ResourceNames: []string{"foo"}},
    48  				{Verbs: []string{"list"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}, ResourceNames: []string{"foo"}},
    49  
    50  				{Verbs: []string{"educate"}, APIGroups: []string{""}, Resources: []string{"dolphins"}},
    51  
    52  				// nil verbs are preserved in non-merge cases.
    53  				// these are the pirates who don't do anything.
    54  				{Verbs: nil, APIGroups: []string{""}, Resources: []string{"pirates"}},
    55  
    56  				// Test merging into a nil Verbs string set
    57  				{Verbs: nil, APIGroups: []string{""}, Resources: []string{"pods"}},
    58  				{Verbs: []string{"create"}, APIGroups: []string{""}, Resources: []string{"pods"}},
    59  			},
    60  			Expected: []rbacv1.PolicyRule{
    61  				{Verbs: []string{"create", "delete"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}},
    62  				{Verbs: []string{"patch"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}, ResourceNames: []string{""}},
    63  				{Verbs: []string{"get", "list"}, APIGroups: []string{"extensions"}, Resources: []string{"daemonsets"}, ResourceNames: []string{"foo"}},
    64  				{Verbs: []string{"get", "list", "update", "patch"}, APIGroups: []string{""}, Resources: []string{"builds"}},
    65  				{Verbs: []string{"educate"}, APIGroups: []string{""}, Resources: []string{"dolphins"}},
    66  				{Verbs: nil, APIGroups: []string{""}, Resources: []string{"pirates"}},
    67  				{Verbs: []string{"create"}, APIGroups: []string{""}, Resources: []string{"pods"}},
    68  			},
    69  		},
    70  		"complex multi-group": {
    71  			Rules: []rbacv1.PolicyRule{
    72  				{Verbs: []string{"get"}, APIGroups: []string{"", "builds.openshift.io"}, Resources: []string{"builds"}},
    73  				{Verbs: []string{"list"}, APIGroups: []string{"", "builds.openshift.io"}, Resources: []string{"builds"}},
    74  			},
    75  			Expected: []rbacv1.PolicyRule{
    76  				{Verbs: []string{"get"}, APIGroups: []string{"", "builds.openshift.io"}, Resources: []string{"builds"}},
    77  				{Verbs: []string{"list"}, APIGroups: []string{"", "builds.openshift.io"}, Resources: []string{"builds"}},
    78  			},
    79  		},
    80  
    81  		"complex multi-resource": {
    82  			Rules: []rbacv1.PolicyRule{
    83  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds", "images"}},
    84  				{Verbs: []string{"list"}, APIGroups: []string{""}, Resources: []string{"builds", "images"}},
    85  			},
    86  			Expected: []rbacv1.PolicyRule{
    87  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds", "images"}},
    88  				{Verbs: []string{"list"}, APIGroups: []string{""}, Resources: []string{"builds", "images"}},
    89  			},
    90  		},
    91  
    92  		"complex named-resource": {
    93  			Rules: []rbacv1.PolicyRule{
    94  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, ResourceNames: []string{"mybuild"}},
    95  				{Verbs: []string{"list"}, APIGroups: []string{""}, Resources: []string{"builds"}, ResourceNames: []string{"mybuild2"}},
    96  			},
    97  			Expected: []rbacv1.PolicyRule{
    98  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, ResourceNames: []string{"mybuild"}},
    99  				{Verbs: []string{"list"}, APIGroups: []string{""}, Resources: []string{"builds"}, ResourceNames: []string{"mybuild2"}},
   100  			},
   101  		},
   102  
   103  		"complex non-resource": {
   104  			Rules: []rbacv1.PolicyRule{
   105  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, NonResourceURLs: []string{"/"}},
   106  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, NonResourceURLs: []string{"/foo"}},
   107  			},
   108  			Expected: []rbacv1.PolicyRule{
   109  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, NonResourceURLs: []string{"/"}},
   110  				{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, NonResourceURLs: []string{"/foo"}},
   111  			},
   112  		},
   113  	}
   114  
   115  	for k, tc := range testcases {
   116  		rules := tc.Rules
   117  		originalRules := make([]rbacv1.PolicyRule, len(tc.Rules))
   118  		for i := range tc.Rules {
   119  			originalRules[i] = *tc.Rules[i].DeepCopy()
   120  		}
   121  		compacted, err := CompactRules(tc.Rules)
   122  		if err != nil {
   123  			t.Errorf("%s: unexpected error: %v", k, err)
   124  			continue
   125  		}
   126  		if !reflect.DeepEqual(rules, originalRules) {
   127  			t.Errorf("%s: CompactRules mutated rules. Expected\n%#v\ngot\n%#v", k, originalRules, rules)
   128  			continue
   129  		}
   130  		if covers, missing := validation.Covers(compacted, rules); !covers {
   131  			t.Errorf("%s: compacted rules did not cover original rules. missing: %#v", k, missing)
   132  			continue
   133  		}
   134  		if covers, missing := validation.Covers(rules, compacted); !covers {
   135  			t.Errorf("%s: original rules did not cover compacted rules. missing: %#v", k, missing)
   136  			continue
   137  		}
   138  
   139  		sort.Stable(rbacv1helpers.SortableRuleSlice(compacted))
   140  		sort.Stable(rbacv1helpers.SortableRuleSlice(tc.Expected))
   141  		if !reflect.DeepEqual(compacted, tc.Expected) {
   142  			t.Errorf("%s: Expected\n%#v\ngot\n%#v", k, tc.Expected, compacted)
   143  			continue
   144  		}
   145  	}
   146  }
   147  
   148  func TestIsSimpleResourceRule(t *testing.T) {
   149  	testcases := map[string]struct {
   150  		Rule     rbacv1.PolicyRule
   151  		Simple   bool
   152  		Resource simpleResource
   153  	}{
   154  		"simple, no verbs": {
   155  			Rule:     rbacv1.PolicyRule{Verbs: []string{}, APIGroups: []string{""}, Resources: []string{"builds"}},
   156  			Simple:   true,
   157  			Resource: simpleResource{Group: "", Resource: "builds"},
   158  		},
   159  		"simple, one verb": {
   160  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}},
   161  			Simple:   true,
   162  			Resource: simpleResource{Group: "", Resource: "builds"},
   163  		},
   164  		"simple, one empty resource name": {
   165  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, ResourceNames: []string{""}},
   166  			Simple:   true,
   167  			Resource: simpleResource{Group: "", Resource: "builds", ResourceNameExist: true, ResourceName: ""},
   168  		},
   169  		"simple, one resource name": {
   170  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, ResourceNames: []string{"foo"}},
   171  			Simple:   true,
   172  			Resource: simpleResource{Group: "", Resource: "builds", ResourceNameExist: true, ResourceName: "foo"},
   173  		},
   174  		"simple, multi verb": {
   175  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get", "list"}, APIGroups: []string{""}, Resources: []string{"builds"}},
   176  			Simple:   true,
   177  			Resource: simpleResource{Group: "", Resource: "builds"},
   178  		},
   179  
   180  		"complex, empty": {
   181  			Rule:     rbacv1.PolicyRule{},
   182  			Simple:   false,
   183  			Resource: simpleResource{},
   184  		},
   185  		"complex, no group": {
   186  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{}, Resources: []string{"builds"}},
   187  			Simple:   false,
   188  			Resource: simpleResource{},
   189  		},
   190  		"complex, multi group": {
   191  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{"a", "b"}, Resources: []string{"builds"}},
   192  			Simple:   false,
   193  			Resource: simpleResource{},
   194  		},
   195  		"complex, no resource": {
   196  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{}},
   197  			Simple:   false,
   198  			Resource: simpleResource{},
   199  		},
   200  		"complex, multi resource": {
   201  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds", "images"}},
   202  			Simple:   false,
   203  			Resource: simpleResource{},
   204  		},
   205  		"complex, resource names": {
   206  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, ResourceNames: []string{"foo", "bar"}},
   207  			Simple:   false,
   208  			Resource: simpleResource{},
   209  		},
   210  		"complex, non-resource urls": {
   211  			Rule:     rbacv1.PolicyRule{Verbs: []string{"get"}, APIGroups: []string{""}, Resources: []string{"builds"}, NonResourceURLs: []string{"/"}},
   212  			Simple:   false,
   213  			Resource: simpleResource{},
   214  		},
   215  	}
   216  
   217  	for k, tc := range testcases {
   218  		resource, simple := isSimpleResourceRule(&tc.Rule)
   219  		if simple != tc.Simple {
   220  			t.Errorf("%s: expected simple=%v, got simple=%v", k, tc.Simple, simple)
   221  			continue
   222  		}
   223  		if resource != tc.Resource {
   224  			t.Errorf("%s: expected resource=%v, got resource=%v", k, tc.Resource, resource)
   225  			continue
   226  		}
   227  	}
   228  }
   229  

View as plain text