github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/install/attributes_util.go (about)

     1  package install
     2  
     3  import (
     4  	"fmt"
     5  
     6  	log "github.com/sirupsen/logrus"
     7  	corev1 "k8s.io/api/core/v1"
     8  	rbacv1 "k8s.io/api/rbac/v1"
     9  	"k8s.io/apiserver/pkg/authentication/serviceaccount"
    10  	"k8s.io/apiserver/pkg/authentication/user"
    11  	"k8s.io/apiserver/pkg/authorization/authorizer"
    12  )
    13  
    14  // toAttributesSet converts the given user, namespace, and PolicyRule into a set of Attributes expected. This is useful for checking
    15  // if a composed set of Roles/RoleBindings satisfies a PolicyRule.
    16  func toAttributesSet(user user.Info, namespace string, rule rbacv1.PolicyRule) []authorizer.Attributes {
    17  	set := map[string]authorizer.Attributes{}
    18  
    19  	// add empty string for empty groups, resources, resource names, and non resource urls
    20  	groups := rule.APIGroups
    21  	if len(groups) == 0 {
    22  		groups = make([]string, 1)
    23  	}
    24  	resources := rule.Resources
    25  	if len(resources) == 0 {
    26  		resources = make([]string, 1)
    27  	}
    28  	names := rule.ResourceNames
    29  	if len(names) == 0 {
    30  		names = make([]string, 1)
    31  	}
    32  	nonResourceURLs := rule.NonResourceURLs
    33  	if len(nonResourceURLs) == 0 {
    34  		nonResourceURLs = make([]string, 1)
    35  	}
    36  
    37  	for _, verb := range rule.Verbs {
    38  		for _, group := range groups {
    39  			for _, resource := range resources {
    40  				for _, name := range names {
    41  					for _, nonResourceURL := range nonResourceURLs {
    42  						attr := attributesRecord(user, namespace, verb, group, resource, name, nonResourceURL)
    43  						key := attributesKey(user, namespace, verb, group, resource, name, nonResourceURL)
    44  						set[key] = attr
    45  					}
    46  				}
    47  			}
    48  		}
    49  	}
    50  
    51  	attributes := make([]authorizer.Attributes, 0, len(set))
    52  	for _, attribute := range set {
    53  		attributes = append(attributes, attribute)
    54  	}
    55  	log.Debugf("attributes set %+v", attributes)
    56  
    57  	return attributes
    58  }
    59  
    60  // attribute creates a new AttributesRecord with the given info. Currently RBAC authz only looks at user, verb, apiGroup, resource, and name.
    61  func attributesRecord(user user.Info, namespace, verb, apiGroup, resource, name, path string) authorizer.AttributesRecord {
    62  	resourceRequest := path == ""
    63  	return authorizer.AttributesRecord{
    64  		User:            user,
    65  		Verb:            verb,
    66  		Namespace:       namespace,
    67  		APIGroup:        apiGroup,
    68  		Resource:        resource,
    69  		Name:            name,
    70  		ResourceRequest: resourceRequest,
    71  		Path:            path,
    72  	}
    73  }
    74  
    75  func toDefaultInfo(sa *corev1.ServiceAccount) *user.DefaultInfo {
    76  	// TODO(Nick): add Group if necessary
    77  	return &user.DefaultInfo{
    78  		Name: serviceaccount.MakeUsername(sa.GetNamespace(), sa.GetName()),
    79  		UID:  string(sa.GetUID()),
    80  	}
    81  }
    82  
    83  func attributesKey(user user.Info, namespace, verb, apiGroup, resource, name, path string) string {
    84  	return fmt.Sprintf("%s|%s|%s|%s|%s|%s|%s|%s",
    85  		user.GetName(),
    86  		verb,
    87  		namespace,
    88  		apiGroup,
    89  		resource,
    90  		name,
    91  		resource,
    92  		path,
    93  	)
    94  }