code: func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool {
  	if !attrs.IsResourceRequest() {
  		return false
  	}
  
  	if len(r.Namespaces) > 0 {
  		if !hasString(r.Namespaces, attrs.GetNamespace()) { // Non-namespaced resources use the empty string.
  			return false
  		}
  	}
  	if len(r.Resources) == 0 {
  		return true
  	}
  
  	apiGroup := attrs.GetAPIGroup()
  	resource := attrs.GetResource()
  	subresource := attrs.GetSubresource()
  	combinedResource := resource
  	// If subresource, the resource in the policy must match "(resource)/(subresource)"
  	if subresource != "" {
  		combinedResource = resource + "/" + subresource
  	}
  
  	name := attrs.GetName()
  
  	for _, gr := range r.Resources {
  		if gr.Group == apiGroup {
  			if len(gr.Resources) == 0 {
  				return true
  			}
  			for _, res := range gr.Resources {
  				if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) {
  					// match "*"
  					if res == combinedResource || res == "*" {
  						return true
  					}
  					// match "*/subresource"
  					if len(subresource) > 0 && strings.HasPrefix(res, "*/") && subresource == strings.TrimLeft(res, "*/") {
  						return true
  					}
  					// match "resource/*"
  					if strings.HasSuffix(res, "/*") && resource == strings.TrimRight(res, "/*") {
  						return true
  					}
  				}
  			}
  		}
  	}
  	return false
  }
docs: // Check whether the rule's resource fields match the request attrs.