...
1
16
17 package validation
18
19 import (
20 "reflect"
21
22 rbacv1 "k8s.io/api/rbac/v1"
23 )
24
25 type simpleResource struct {
26 Group string
27 Resource string
28 ResourceNameExist bool
29 ResourceName string
30 }
31
32
33
34 func CompactRules(rules []rbacv1.PolicyRule) ([]rbacv1.PolicyRule, error) {
35 compacted := make([]rbacv1.PolicyRule, 0, len(rules))
36
37 simpleRules := map[simpleResource]*rbacv1.PolicyRule{}
38 for _, rule := range rules {
39 if resource, isSimple := isSimpleResourceRule(&rule); isSimple {
40 if existingRule, ok := simpleRules[resource]; ok {
41
42 if existingRule.Verbs == nil {
43 existingRule.Verbs = []string{}
44 }
45 existingRule.Verbs = append(existingRule.Verbs, rule.Verbs...)
46 } else {
47
48 simpleRules[resource] = rule.DeepCopy()
49 }
50 } else {
51 compacted = append(compacted, rule)
52 }
53 }
54
55
56 for _, simpleRule := range simpleRules {
57 compacted = append(compacted, *simpleRule)
58 }
59
60 return compacted, nil
61 }
62
63
64 func isSimpleResourceRule(rule *rbacv1.PolicyRule) (simpleResource, bool) {
65 resource := simpleResource{}
66
67
68 if len(rule.ResourceNames) > 1 || len(rule.NonResourceURLs) > 0 {
69 return resource, false
70 }
71
72 if len(rule.APIGroups) != 1 || len(rule.Resources) != 1 {
73 return resource, false
74 }
75
76
77 simpleRule := &rbacv1.PolicyRule{APIGroups: rule.APIGroups, Resources: rule.Resources, Verbs: rule.Verbs, ResourceNames: rule.ResourceNames}
78 if !reflect.DeepEqual(simpleRule, rule) {
79 return resource, false
80 }
81
82 if len(rule.ResourceNames) == 0 {
83 resource = simpleResource{Group: rule.APIGroups[0], Resource: rule.Resources[0], ResourceNameExist: false}
84 } else {
85 resource = simpleResource{Group: rule.APIGroups[0], Resource: rule.Resources[0], ResourceNameExist: true, ResourceName: rule.ResourceNames[0]}
86 }
87
88 return resource, true
89 }
90
View as plain text