func (m *VirtualStorage) createRole(ctx kapi.Context, obj runtime.Object, allowEscalation bool) (*authorizationapi.Role, error) { if err := rest.BeforeCreate(m.CreateStrategy, ctx, obj); err != nil { return nil, err } role := obj.(*authorizationapi.Role) if !allowEscalation { if err := rulevalidation.ConfirmNoEscalation(ctx, authorizationapi.Resource("role"), role.Name, m.RuleResolver, authorizationinterfaces.NewLocalRoleAdapter(role)); err != nil { return nil, err } } policy, err := m.EnsurePolicy(ctx) if err != nil { return nil, err } if _, exists := policy.Roles[role.Name]; exists { return nil, kapierrors.NewAlreadyExists(authorizationapi.Resource("role"), role.Name) } role.ResourceVersion = policy.ResourceVersion policy.Roles[role.Name] = role policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, err } return role, nil }
func (o *ReconcileClusterRolesOptions) Complete(cmd *cobra.Command, f *clientcmd.Factory, args []string) error { oclient, _, err := f.Clients() if err != nil { return err } o.RoleClient = oclient.ClusterRoles() o.Output = kcmdutil.GetFlagString(cmd, "output") mapper, _ := f.Object() for _, resourceString := range args { resource, name, err := osutil.ResolveResource(authorizationapi.Resource("clusterroles"), resourceString, mapper) if err != nil { return err } if resource != authorizationapi.Resource("clusterroles") { return fmt.Errorf("%v is not a valid resource type for this command", resource) } if len(name) == 0 { return fmt.Errorf("%s did not contain a name", resourceString) } o.RolesToReconcile = append(o.RolesToReconcile, name) } return nil }
func (m *VirtualStorage) updateRole(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.Role, bool, error) { old, err := m.Get(ctx, name) if err != nil { return nil, false, err } obj, err := objInfo.UpdatedObject(ctx, old) if err != nil { return nil, false, err } role, ok := obj.(*authorizationapi.Role) if !ok { return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj)) } if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil { return nil, false, err } if !allowEscalation { if err := rulevalidation.ConfirmNoEscalation(ctx, authorizationapi.Resource("role"), role.Name, m.RuleResolver, authorizationinterfaces.NewLocalRoleAdapter(role)); err != nil { return nil, false, err } } policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName) if err != nil && kapierrors.IsNotFound(err) { return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("role"), role.Name) } if err != nil { return nil, false, err } oldRole, exists := policy.Roles[role.Name] if !exists { return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("role"), role.Name) } // non-mutating change if kapi.Semantic.DeepEqual(oldRole, role) { return role, false, nil } role.ResourceVersion = policy.ResourceVersion policy.Roles[role.Name] = role policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, false, err } return role, false, nil }
func (m *VirtualStorage) Get(ctx kapi.Context, name string) (runtime.Object, error) { policyBinding, err := m.getPolicyBindingOwningRoleBinding(ctx, name) if kapierrors.IsNotFound(err) { return nil, kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), name) } if err != nil { return nil, err } binding, exists := policyBinding.RoleBindings[name] if !exists { return nil, kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), name) } return binding, nil }
// NewStorage returns a RESTStorage object that will work against nodes. func NewStorage(s storage.Interface) *REST { store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &authorizationapi.ClusterPolicy{} }, NewListFunc: func() runtime.Object { return &authorizationapi.ClusterPolicyList{} }, QualifiedResource: authorizationapi.Resource("clusterpolicy"), KeyRootFunc: func(ctx kapi.Context) string { return ClusterPolicyPath }, KeyFunc: func(ctx kapi.Context, id string) (string, error) { return util.NoNamespaceKeyFunc(ctx, ClusterPolicyPath, id) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*authorizationapi.ClusterPolicy).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return clusterpolicy.Matcher(label, field) }, CreateStrategy: clusterpolicy.Strategy, UpdateStrategy: clusterpolicy.Strategy, Storage: s, } return &REST{store} }
func (m *VirtualStorage) Get(ctx kapi.Context, name string) (runtime.Object, error) { policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName) if err != nil && kapierrors.IsNotFound(err) { return nil, kapierrors.NewNotFound(authorizationapi.Resource("role"), name) } if err != nil { return nil, err } role, exists := policy.Roles[name] if !exists { return nil, kapierrors.NewNotFound(authorizationapi.Resource("role"), name) } return role, nil }
// NewStorage returns a RESTStorage object that will work against nodes. func NewStorage(optsGetter restoptions.Getter) (*REST, error) { store := ®istry.Store{ NewFunc: func() runtime.Object { return &authorizationapi.ClusterPolicy{} }, NewListFunc: func() runtime.Object { return &authorizationapi.ClusterPolicyList{} }, QualifiedResource: authorizationapi.Resource("clusterpolicies"), KeyRootFunc: func(ctx kapi.Context) string { return ClusterPolicyPath }, KeyFunc: func(ctx kapi.Context, id string) (string, error) { return util.NoNamespaceKeyFunc(ctx, ClusterPolicyPath, id) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*authorizationapi.ClusterPolicy).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return clusterpolicy.Matcher(label, field) }, CreateStrategy: clusterpolicy.Strategy, UpdateStrategy: clusterpolicy.Strategy, } if err := restoptions.ApplyOptions(optsGetter, store, ClusterPolicyPath); err != nil { return nil, err } return &REST{store}, nil }
// resolveRules doesn't enforce namespace checks func (e clusterRoleEvaluator) resolveRules(scope string, clusterPolicyGetter client.ClusterPolicyLister) ([]authorizationapi.PolicyRule, error) { roleName, _, escalating, err := e.parseScope(scope) if err != nil { return nil, err } policy, err := clusterPolicyGetter.Get("default") if err != nil { return nil, err } role, exists := policy.Roles[roleName] if !exists { return nil, kapierrors.NewNotFound(authorizationapi.Resource("clusterrole"), roleName) } rules := []authorizationapi.PolicyRule{} for _, rule := range role.Rules { if escalating { rules = append(rules, rule) continue } // rules with unbounded access shouldn't be allowed in scopes. if rule.Verbs.Has(authorizationapi.VerbAll) || rule.Resources.Has(authorizationapi.ResourceAll) || getAPIGroupSet(rule).Has(authorizationapi.APIGroupAll) { continue } // rules that allow escalating resource access should be cleaned. safeRule := removeEscalatingResources(rule) rules = append(rules, safeRule) } return rules, nil }
func (m *VirtualStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { if err := rest.BeforeCreate(m.CreateStrategy, ctx, obj); err != nil { return nil, err } role := obj.(*authorizationapi.Role) policy, err := m.EnsurePolicy(ctx) if err != nil { return nil, err } if _, exists := policy.Roles[role.Name]; exists { return nil, kapierrors.NewAlreadyExists(authorizationapi.Resource("role"), role.Name) } role.ResourceVersion = policy.ResourceVersion policy.Roles[role.Name] = role policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, err } return role, nil }
func (m *VirtualStorage) confirmNoEscalation(ctx kapi.Context, roleBinding *authorizationapi.RoleBinding) error { modifyingRole, err := m.RuleResolver.GetRole(authorizationinterfaces.NewLocalRoleBindingAdapter(roleBinding)) if err != nil { return err } return rulevalidation.ConfirmNoEscalation(ctx, authorizationapi.Resource("rolebinding"), roleBinding.Name, m.RuleResolver, modifyingRole) }
// isAllowed checks to see if the current user has rights to issue a LocalSubjectAccessReview on the namespace they're attempting to access func (r *REST) isAllowed(ctx kapi.Context, rar *authorizationapi.ResourceAccessReview) error { localRARAttributes := authorizer.DefaultAuthorizationAttributes{ Verb: "create", Resource: "localresourceaccessreviews", } allowed, reason, err := r.authorizer.Authorize(kapi.WithNamespace(ctx, rar.Action.Namespace), localRARAttributes) if err != nil { return kapierrors.NewForbidden(authorizationapi.Resource(localRARAttributes.GetResource()), localRARAttributes.GetResourceName(), err) } if !allowed { forbiddenError := kapierrors.NewForbidden(authorizationapi.Resource(localRARAttributes.GetResource()), localRARAttributes.GetResourceName(), errors.New("") /*discarded*/) forbiddenError.ErrStatus.Message = reason return forbiddenError } return nil }
// Get retrieves the Policy from the indexer for a given namespace and name. func (s policyNamespaceLister) Get(name string) (*v1.Policy, error) { obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) if err != nil { return nil, err } if !exists { return nil, errors.NewNotFound(api.Resource("policy"), name) } return obj.(*v1.Policy), nil }
func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.RoleBinding, bool, error) { old, err := m.Get(ctx, name) if err != nil { return nil, false, err } obj, err := objInfo.UpdatedObject(ctx, old) if err != nil { return nil, false, err } roleBinding, ok := obj.(*authorizationapi.RoleBinding) if !ok { return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj)) } if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil { return nil, false, err } if err := m.validateReferentialIntegrity(ctx, roleBinding); err != nil { return nil, false, err } if !allowEscalation { if err := m.confirmNoEscalation(ctx, roleBinding); err != nil { return nil, false, err } } policyBinding, err := m.getPolicyBindingForPolicy(ctx, roleBinding.RoleRef.Namespace, allowEscalation) if err != nil { return nil, false, err } previousRoleBinding, exists := policyBinding.RoleBindings[roleBinding.Name] if !exists { return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), roleBinding.Name) } if previousRoleBinding.RoleRef != roleBinding.RoleRef { return nil, false, errors.New("roleBinding.RoleRef may not be modified") } if kapi.Semantic.DeepEqual(previousRoleBinding, roleBinding) { return roleBinding, false, nil } roleBinding.ResourceVersion = policyBinding.ResourceVersion policyBinding.RoleBindings[roleBinding.Name] = roleBinding policyBinding.LastModified = unversioned.Now() if err := m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil { return nil, false, err } return roleBinding, false, nil }
func (a *DefaultRuleResolver) GetRole(roleBinding authorizationinterfaces.RoleBinding) (authorizationinterfaces.Role, error) { namespace := roleBinding.RoleRef().Namespace name := roleBinding.RoleRef().Name if len(namespace) == 0 { policy, err := a.clusterPolicyGetter.Get(authorizationapi.PolicyName) if kapierror.IsNotFound(err) { return nil, kapierror.NewNotFound(authorizationapi.Resource("role"), name) } if err != nil { return nil, err } role, exists := policy.Roles[name] if !exists { return nil, kapierror.NewNotFound(authorizationapi.Resource("role"), name) } return authorizationinterfaces.NewClusterRoleAdapter(role), nil } if a.policyGetter == nil { return nil, kapierror.NewNotFound(authorizationapi.Resource("role"), name) } policy, err := a.policyGetter.Policies(namespace).Get(authorizationapi.PolicyName) if kapierror.IsNotFound(err) { return nil, kapierror.NewNotFound(authorizationapi.Resource("role"), name) } if err != nil { return nil, err } role, exists := policy.Roles[name] if !exists { return nil, kapierror.NewNotFound(authorizationapi.Resource("role"), name) } return authorizationinterfaces.NewLocalRoleAdapter(role), nil }
// Delete(ctx api.Context, name string) (runtime.Object, error) func (m *VirtualStorage) Delete(ctx kapi.Context, name string, options *kapi.DeleteOptions) (runtime.Object, error) { policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName) if err != nil && kapierrors.IsNotFound(err) { return nil, kapierrors.NewNotFound(authorizationapi.Resource("role"), name) } if err != nil { return nil, err } if _, exists := policy.Roles[name]; !exists { return nil, kapierrors.NewNotFound(authorizationapi.Resource("role"), name) } delete(policy.Roles, name) policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, err } return &unversioned.Status{Status: unversioned.StatusSuccess}, nil }
func (m *VirtualStorage) createRole(ctx kapi.Context, obj runtime.Object, allowEscalation bool) (*authorizationapi.Role, error) { // Copy object before passing to BeforeCreate, since it mutates objCopy, err := kapi.Scheme.DeepCopy(obj) if err != nil { return nil, err } obj = objCopy.(runtime.Object) if err := rest.BeforeCreate(m.CreateStrategy, ctx, obj); err != nil { return nil, err } role := obj.(*authorizationapi.Role) if !allowEscalation { if err := rulevalidation.ConfirmNoEscalation(ctx, authorizationapi.Resource("role"), role.Name, m.RuleResolver, authorizationinterfaces.NewLocalRoleAdapter(role)); err != nil { return nil, err } } if err := kclient.RetryOnConflict(kclient.DefaultRetry, func() error { policy, err := m.EnsurePolicy(ctx) if err != nil { return err } if _, exists := policy.Roles[role.Name]; exists { return kapierrors.NewAlreadyExists(authorizationapi.Resource("role"), role.Name) } role.ResourceVersion = policy.ResourceVersion policy.Roles[role.Name] = role policy.LastModified = unversioned.Now() return m.PolicyStorage.UpdatePolicy(ctx, policy) }); err != nil { return nil, err } return role, nil }
func (m *VirtualStorage) Delete(ctx kapi.Context, name string, options *kapi.DeleteOptions) (runtime.Object, error) { owningPolicyBinding, err := m.getPolicyBindingOwningRoleBinding(ctx, name) if err != nil && kapierrors.IsNotFound(err) { return nil, kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), name) } if err != nil { return nil, err } if _, exists := owningPolicyBinding.RoleBindings[name]; !exists { return nil, kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), name) } delete(owningPolicyBinding.RoleBindings, name) owningPolicyBinding.LastModified = unversioned.Now() if err := m.BindingRegistry.UpdatePolicyBinding(ctx, owningPolicyBinding); err != nil { return nil, err } return &unversioned.Status{Status: unversioned.StatusSuccess}, nil }
func (i *InformerToClusterPolicyLister) Get(name string) (*authorizationapi.ClusterPolicy, error) { keyObj := &authorizationapi.ClusterPolicy{ObjectMeta: kapi.ObjectMeta{Name: name}} key, _ := framework.DeletionHandlingMetaNamespaceKeyFunc(keyObj) item, exists, getErr := i.GetIndexer().GetByKey(key) if getErr != nil { return nil, getErr } if !exists { existsErr := kapierrors.NewNotFound(authorizationapi.Resource("clusterpolicy"), name) return nil, existsErr } return item.(*authorizationapi.ClusterPolicy), nil }
func (i *indexerToPolicyBindingLister) Get(name string) (*authorizationapi.PolicyBinding, error) { keyObj := &authorizationapi.PolicyBinding{ObjectMeta: kapi.ObjectMeta{Namespace: i.namespace, Name: name}} key, _ := framework.DeletionHandlingMetaNamespaceKeyFunc(keyObj) item, exists, getErr := i.Indexer.GetByKey(key) if getErr != nil { return nil, getErr } if !exists { existsErr := kapierrors.NewNotFound(authorizationapi.Resource("policyBinding"), name) return nil, existsErr } return item.(*authorizationapi.PolicyBinding), nil }
func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { role, ok := obj.(*authorizationapi.Role) if !ok { return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj)) } old, err := m.Get(ctx, role.Name) if err != nil { return nil, false, err } if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil { return nil, false, err } policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName) if err != nil && kapierrors.IsNotFound(err) { return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("role"), role.Name) } if err != nil { return nil, false, err } if _, exists := policy.Roles[role.Name]; !exists { return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("role"), role.Name) } role.ResourceVersion = policy.ResourceVersion policy.Roles[role.Name] = role policy.LastModified = unversioned.Now() if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil { return nil, false, err } return role, false, nil }
func addAuthorizationListerWatchers(customListerWatchers shared.DefaultListerWatcherOverrides, optsGetter restoptions.Getter) error { lw, err := newClusterPolicyLW(optsGetter) if err != nil { return err } customListerWatchers[authorizationapi.Resource("clusterpolicies")] = lw lw, err = newClusterPolicyBindingLW(optsGetter) if err != nil { return err } customListerWatchers[authorizationapi.Resource("clusterpolicybindings")] = lw lw, err = newPolicyLW(optsGetter) if err != nil { return err } customListerWatchers[authorizationapi.Resource("policies")] = lw lw, err = newPolicyBindingLW(optsGetter) if err != nil { return err } customListerWatchers[authorizationapi.Resource("policybindings")] = lw return nil }
func (m *VirtualStorage) getPolicyBindingOwningRoleBinding(ctx kapi.Context, bindingName string) (*authorizationapi.PolicyBinding, error) { policyBindingList, err := m.BindingRegistry.ListPolicyBindings(ctx, &kapi.ListOptions{}) if err != nil { return nil, err } for _, policyBinding := range policyBindingList.Items { _, exists := policyBinding.RoleBindings[bindingName] if exists { return &policyBinding, nil } } return nil, kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), bindingName) }
// UpdateClusterPolicy updates a policy. func (r *ClusterPolicyRegistry) UpdateClusterPolicy(ctx kapi.Context, policy *authorizationapi.ClusterPolicy) error { if r.Err != nil { return r.Err } namespace := kapi.NamespaceValue(ctx) if len(namespace) != 0 { return errors.New("invalid request. Namespace parameter disallowed.") } if existing, _ := r.GetClusterPolicy(ctx, policy.Name); existing == nil { return kapierrors.NewNotFound(authorizationapi.Resource("clusterpolicy"), policy.Name) } addClusterPolicy(r.clusterPolicies, *policy) return nil }
// UpdatePolicyBinding updates a policyBinding. func (r *PolicyBindingRegistry) UpdatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error { if r.Err != nil { return r.Err } namespace := kapi.NamespaceValue(ctx) if len(namespace) == 0 { return errors.New("invalid request. Namespace parameter required.") } if existing, _ := r.GetPolicyBinding(ctx, policyBinding.Name); existing == nil { return kapierrors.NewNotFound(authorizationapi.Resource("policybinding"), policyBinding.Name) } addPolicyBinding(r.PolicyBindings, *policyBinding) return nil }
// CreateClusterPolicyBinding creates a new policyBinding. func (r *ClusterPolicyBindingRegistry) CreateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error { if r.Err != nil { return r.Err } namespace := kapi.NamespaceValue(ctx) if len(namespace) != 0 { return errors.New("invalid request. Namespace parameter disallowed.") } if existing, _ := r.GetClusterPolicyBinding(ctx, policyBinding.Name); existing != nil { return kapierrors.NewAlreadyExists(authorizationapi.Resource("clusterpolicybinding"), policyBinding.Name) } addClusterPolicyBinding(r.clusterPolicyBindings, *policyBinding) return nil }
// GetClusterPolicyBinding retrieves a specific policyBinding. func (r *ClusterPolicyBindingRegistry) GetClusterPolicyBinding(ctx kapi.Context, id string) (*authorizationapi.ClusterPolicyBinding, error) { if r.Err != nil { return nil, r.Err } namespace := kapi.NamespaceValue(ctx) if len(namespace) != 0 { return nil, errors.New("invalid request. Namespace parameter disallowed.") } if namespacedBindings, ok := r.clusterPolicyBindings[namespace]; ok { if binding, ok := namespacedBindings[id]; ok { return &binding, nil } } return nil, kapierrors.NewNotFound(authorizationapi.Resource("clusterpolicybinding"), id) }
func (c *readOnlyPolicyBindingCache) Get(name, namespace string) (*authorizationapi.PolicyBinding, error) { keyObj := &authorizationapi.PolicyBinding{ObjectMeta: kapi.ObjectMeta{Namespace: namespace, Name: name}} key, _ := c.keyFunc(keyObj) item, exists, getErr := c.indexer.GetByKey(key) if getErr != nil { return &authorizationapi.PolicyBinding{}, getErr } if !exists { existsErr := errors.NewNotFound(authorizationapi.Resource("policybinding"), name) return &authorizationapi.PolicyBinding{}, existsErr } policyBinding, castOK := item.(*authorizationapi.PolicyBinding) if !castOK { castErr := errors.NewInvalid(authorizationapi.Kind("PolicyBinding"), name, kfield.ErrorList{}) return &authorizationapi.PolicyBinding{}, castErr } return policyBinding, nil }
func (c *readOnlyClusterPolicyCache) Get(name string) (*authorizationapi.ClusterPolicy, error) { keyObj := &authorizationapi.ClusterPolicy{ObjectMeta: kapi.ObjectMeta{Name: name}} key, _ := c.keyFunc(keyObj) item, exists, getErr := c.indexer.GetByKey(key) if getErr != nil { return &authorizationapi.ClusterPolicy{}, getErr } if !exists { existsErr := errors.NewNotFound(authorizationapi.Resource("clusterpolicy"), name) return &authorizationapi.ClusterPolicy{}, existsErr } clusterPolicy, castOK := item.(*authorizationapi.ClusterPolicy) if !castOK { castErr := errors.NewInvalid(authorizationapi.Kind("ClusterPolicy"), name, kfield.ErrorList{}) return &authorizationapi.ClusterPolicy{}, castErr } return clusterPolicy, nil }
func (m *VirtualStorage) createRoleBinding(ctx kapi.Context, obj runtime.Object, allowEscalation bool) (*authorizationapi.RoleBinding, error) { // Copy object before passing to BeforeCreate, since it mutates objCopy, err := kapi.Scheme.DeepCopy(obj) if err != nil { return nil, err } obj = objCopy.(runtime.Object) if err := rest.BeforeCreate(m.CreateStrategy, ctx, obj); err != nil { return nil, err } roleBinding := obj.(*authorizationapi.RoleBinding) if !allowEscalation { if err := m.confirmNoEscalation(ctx, roleBinding); err != nil { return nil, err } } // Retry if we hit a conflict on the underlying PolicyBinding object if err := kclient.RetryOnConflict(kclient.DefaultRetry, func() error { policyBinding, err := m.getPolicyBindingForPolicy(ctx, roleBinding.RoleRef.Namespace, allowEscalation) if err != nil { return err } _, exists := policyBinding.RoleBindings[roleBinding.Name] if exists { return kapierrors.NewAlreadyExists(authorizationapi.Resource("rolebinding"), roleBinding.Name) } roleBinding.ResourceVersion = policyBinding.ResourceVersion policyBinding.RoleBindings[roleBinding.Name] = roleBinding policyBinding.LastModified = unversioned.Now() return m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding) }); err != nil { return nil, err } return roleBinding, nil }
func (e clusterRoleEvaluator) ResolveRules(scope, namespace string, clusterPolicyGetter rulevalidation.ClusterPolicyGetter) ([]authorizationapi.PolicyRule, error) { roleName, scopeNamespace, escalating, err := e.parseScope(scope) if err != nil { return nil, err } // if the scope limit on the clusterrole doesn't match, then don't add any rules, but its not an error if !(scopeNamespace == authorizationapi.ScopesAllNamespaces || scopeNamespace == namespace) { return []authorizationapi.PolicyRule{}, nil } ctx := kapi.WithNamespace(kapi.NewContext(), namespace) policy, err := clusterPolicyGetter.GetClusterPolicy(ctx, "default") if err != nil { return nil, err } role, exists := policy.Roles[roleName] if !exists { return nil, kapierrors.NewNotFound(authorizationapi.Resource("clusterrole"), roleName) } rules := []authorizationapi.PolicyRule{} for _, rule := range role.Rules { if escalating { rules = append(rules, rule) continue } // rules with unbounded access shouldn't be allowed in scopes. if rule.Verbs.Has(authorizationapi.VerbAll) || rule.Resources.Has(authorizationapi.ResourceAll) || getAPIGroupSet(rule).Has(authorizationapi.APIGroupAll) { continue } // rules that allow escalating resource access should be cleaned. safeRule := removeEscalatingResources(rule) rules = append(rules, safeRule) } return rules, nil }