@@ -105,6 +105,12 @@ func (r *Rule) keyWithResourcesResourceNamesURLsVerbs() string {
105
105
return fmt .Sprintf ("%s + %s + %s + %s" , key .Resources , key .ResourceNames , key .URLs , verbs )
106
106
}
107
107
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
+
108
114
// addVerbs adds new verbs into a Rule.
109
115
// The duplicates in `r.Verbs` will be removed, and then `r.Verbs` will be sorted.
110
116
func (r * Rule ) addVerbs (verbs []string ) {
@@ -190,6 +196,20 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
190
196
// group RBAC markers by namespace and separate by resource
191
197
for _ , markerValue := range markerSet [RuleDefinition .Name ] {
192
198
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
+ }
193
213
for _ , resource := range rule .Resources {
194
214
r := Rule {
195
215
Groups : rule .Groups ,
@@ -257,6 +277,25 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
257
277
ruleMap [key ] = rule
258
278
}
259
279
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
+
260
299
// sort the Rules in rules according to their ruleKeys
261
300
keys := make ([]ruleKey , 0 , len (ruleMap ))
262
301
for key := range ruleMap {
0 commit comments