@@ -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.
110116func (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 {
0 commit comments