Skip to content

Commit b00261b

Browse files
authored
Merge pull request #1044 from chrischdi/pr-rbac-fix-urls
🐛 rbac: fix adding nonResourceURLs including normalisation
2 parents 8208058 + 97708aa commit b00261b

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

pkg/rbac/parser.go

+39
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ func (r *Rule) keyWithResourcesResourceNamesURLsVerbs() string {
105105
return fmt.Sprintf("%s + %s + %s + %s", key.Resources, key.ResourceNames, key.URLs, verbs)
106106
}
107107

108+
func (r *Rule) keyWitGroupResourcesResourceNamesVerbs() string {
109+
key := r.key()
110+
verbs := strings.Join(r.Verbs, "&")
111+
return fmt.Sprintf("%s + %s + %s + %s", key.Groups, key.Resources, key.ResourceNames, verbs)
112+
}
113+
108114
// addVerbs adds new verbs into a Rule.
109115
// The duplicates in `r.Verbs` will be removed, and then `r.Verbs` will be sorted.
110116
func (r *Rule) addVerbs(verbs []string) {
@@ -190,6 +196,20 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
190196
// group RBAC markers by namespace and separate by resource
191197
for _, markerValue := range markerSet[RuleDefinition.Name] {
192198
rule := markerValue.(Rule)
199+
if len(rule.Resources) == 0 {
200+
// Add a rule without any resource if Resources is empty.
201+
r := Rule{
202+
Groups: rule.Groups,
203+
Resources: []string{},
204+
ResourceNames: rule.ResourceNames,
205+
URLs: rule.URLs,
206+
Namespace: rule.Namespace,
207+
Verbs: rule.Verbs,
208+
}
209+
namespace := r.Namespace
210+
rulesByNSResource[namespace] = append(rulesByNSResource[namespace], &r)
211+
continue
212+
}
193213
for _, resource := range rule.Resources {
194214
r := Rule{
195215
Groups: rule.Groups,
@@ -257,6 +277,25 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
257277
ruleMap[key] = rule
258278
}
259279

280+
// deduplicate URLs
281+
// 1. create map based on key without URLs
282+
ruleMapWithoutURLs := make(map[string][]*Rule)
283+
for _, rule := range ruleMap {
284+
// get key without Group
285+
key := rule.keyWitGroupResourcesResourceNamesVerbs()
286+
ruleMapWithoutURLs[key] = append(ruleMapWithoutURLs[key], rule)
287+
}
288+
// 2. merge to ruleMap
289+
ruleMap = make(map[ruleKey]*Rule)
290+
for _, rules := range ruleMapWithoutURLs {
291+
rule := rules[0]
292+
for _, mergeRule := range rules[1:] {
293+
rule.URLs = append(rule.URLs, mergeRule.URLs...)
294+
}
295+
key := rule.key()
296+
ruleMap[key] = rule
297+
}
298+
260299
// sort the Rules in rules according to their ruleKeys
261300
keys := make([]ruleKey, 0, len(ruleMap))
262301
for key := range ruleMap {

pkg/rbac/testdata/controller.go

+2
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ package controller
2828
// +kubebuilder:rbac:groups=not-deduplicate-resources,resources=another,verbs=list
2929
// +kubebuilder:rbac:groups=not-deduplicate-groups1,resources=some,verbs=get
3030
// +kubebuilder:rbac:groups=not-deduplicate-groups2,resources=some,verbs=list
31+
// +kubebuilder:rbac:urls=/url-to-duplicate,verbs=get
32+
// +kubebuilder:rbac:urls=/another/url-to-duplicate,verbs=get

pkg/rbac/testdata/role.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ kind: ClusterRole
44
metadata:
55
name: manager-role
66
rules:
7+
- nonResourceURLs:
8+
- /another/url-to-duplicate
9+
- /url-to-duplicate
10+
verbs:
11+
- get
712
- apiGroups:
813
- art
914
resources:

0 commit comments

Comments
 (0)