Split out server side code from pkg/apis/rbac/validation

This commit is contained in:
Dr. Stefan Schimanski 2017-01-11 11:11:25 +01:00
parent 57e3a57c10
commit cf60bec396
18 changed files with 84 additions and 80 deletions

View File

@ -19,7 +19,6 @@ package rest
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
"k8s.io/kubernetes/pkg/util/uuid" "k8s.io/kubernetes/pkg/util/uuid"
@ -58,7 +57,6 @@ func TestHasObjectMetaSystemFieldValues(t *testing.T) {
} }
} }
// TestValidNamespace validates that namespace rules are enforced on a resource prior to create or update // TestValidNamespace validates that namespace rules are enforced on a resource prior to create or update
func TestValidNamespace(t *testing.T) { func TestValidNamespace(t *testing.T) {
ctx := genericapirequest.NewDefaultContext() ctx := genericapirequest.NewDefaultContext()

View File

@ -19,10 +19,13 @@ package v0
import ( import (
"k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/authentication/user"
api "k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
) )
// allAuthenticated matches k8s.io/apiserver/pkg/authentication/user.AllAuthenticated,
// but we don't want an client library (which must include types), depending on a server library
const allAuthenticated = "system:authenticated"
func addConversionFuncs(scheme *runtime.Scheme) error { func addConversionFuncs(scheme *runtime.Scheme) error {
return scheme.AddConversionFuncs( return scheme.AddConversionFuncs(
func(in *Policy, out *api.Policy, s conversion.Scope) error { func(in *Policy, out *api.Policy, s conversion.Scope) error {
@ -35,11 +38,11 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
// In v0, unspecified user and group matches all authenticated subjects // In v0, unspecified user and group matches all authenticated subjects
if len(in.User) == 0 && len(in.Group) == 0 { if len(in.User) == 0 && len(in.Group) == 0 {
out.Spec.Group = user.AllAuthenticated out.Spec.Group = allAuthenticated
} }
// In v0, user or group of * matches all authenticated subjects // In v0, user or group of * matches all authenticated subjects
if in.User == "*" || in.Group == "*" { if in.User == "*" || in.Group == "*" {
out.Spec.Group = user.AllAuthenticated out.Spec.Group = allAuthenticated
out.Spec.User = "" out.Spec.User = ""
} }

View File

@ -19,10 +19,13 @@ package v1beta1
import ( import (
"k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/authentication/user"
api "k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
) )
// allAuthenticated matches k8s.io/apiserver/pkg/authentication/user.AllAuthenticated,
// but we don't want an client library (which must include types), depending on a server library
const allAuthenticated = "system:authenticated"
func addConversionFuncs(scheme *runtime.Scheme) error { func addConversionFuncs(scheme *runtime.Scheme) error {
return scheme.AddConversionFuncs( return scheme.AddConversionFuncs(
func(in *Policy, out *api.Policy, s conversion.Scope) error { func(in *Policy, out *api.Policy, s conversion.Scope) error {
@ -33,7 +36,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
// In v1beta1, * user or group maps to all authenticated subjects // In v1beta1, * user or group maps to all authenticated subjects
if in.Spec.User == "*" || in.Spec.Group == "*" { if in.Spec.User == "*" || in.Spec.Group == "*" {
out.Spec.Group = user.AllAuthenticated out.Spec.Group = allAuthenticated
out.Spec.User = "" out.Spec.User = ""
} }

View File

@ -20,7 +20,7 @@ import (
"testing" "testing"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
api "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
) )
@ -293,31 +293,6 @@ func TestValidateRoleBindingUpdate(t *testing.T) {
} }
} }
func TestNonResourceURLCovers(t *testing.T) {
tests := []struct {
owner string
requested string
want bool
}{
{"*", "/api", true},
{"/api", "/api", true},
{"/apis", "/api", false},
{"/api/v1", "/api", false},
{"/api/v1", "/api/v1", true},
{"/api/*", "/api/v1", true},
{"/api/*", "/api", false},
{"/api/*/*", "/api/v1", false},
{"/*/v1/*", "/api/v1", false},
}
for _, tc := range tests {
got := nonResourceURLCovers(tc.owner, tc.requested)
if got != tc.want {
t.Errorf("nonResourceURLCovers(%q, %q): want=(%t), got=(%t)", tc.owner, tc.requested, tc.want, got)
}
}
}
type ValidateRoleTest struct { type ValidateRoleTest struct {
role rbac.Role role rbac.Role
wantErr bool wantErr bool

View File

@ -22,9 +22,9 @@ import (
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
var groupResource = rbac.Resource("clusterroles") var groupResource = rbac.Resource("clusterroles")
@ -32,10 +32,10 @@ var groupResource = rbac.Resource("clusterroles")
type Storage struct { type Storage struct {
rest.StandardStorage rest.StandardStorage
ruleResolver validation.AuthorizationRuleResolver ruleResolver rbacregistryvalidation.AuthorizationRuleResolver
} }
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver) *Storage { func NewStorage(s rest.StandardStorage, ruleResolver rbacregistryvalidation.AuthorizationRuleResolver) *Storage {
return &Storage{s, ruleResolver} return &Storage{s, ruleResolver}
} }
@ -46,7 +46,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
clusterRole := obj.(*rbac.ClusterRole) clusterRole := obj.(*rbac.ClusterRole)
rules := clusterRole.Rules rules := clusterRole.Rules
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, clusterRole.Name, err) return nil, errors.NewForbidden(groupResource, clusterRole.Name, err)
} }
return s.StandardStorage.Create(ctx, obj) return s.StandardStorage.Create(ctx, obj)
@ -61,7 +61,7 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up
clusterRole := obj.(*rbac.ClusterRole) clusterRole := obj.(*rbac.ClusterRole)
rules := clusterRole.Rules rules := clusterRole.Rules
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, clusterRole.Name, err) return nil, errors.NewForbidden(groupResource, clusterRole.Name, err)
} }
return obj, nil return obj, nil

View File

@ -23,9 +23,9 @@ import (
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
var groupResource = rbac.Resource("clusterrolebindings") var groupResource = rbac.Resource("clusterrolebindings")
@ -35,10 +35,10 @@ type Storage struct {
authorizer authorizer.Authorizer authorizer authorizer.Authorizer
ruleResolver validation.AuthorizationRuleResolver ruleResolver rbacregistryvalidation.AuthorizationRuleResolver
} }
func NewStorage(s rest.StandardStorage, authorizer authorizer.Authorizer, ruleResolver validation.AuthorizationRuleResolver) *Storage { func NewStorage(s rest.StandardStorage, authorizer authorizer.Authorizer, ruleResolver rbacregistryvalidation.AuthorizationRuleResolver) *Storage {
return &Storage{s, authorizer, ruleResolver} return &Storage{s, authorizer, ruleResolver}
} }
@ -56,7 +56,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err) return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err)
} }
return s.StandardStorage.Create(ctx, obj) return s.StandardStorage.Create(ctx, obj)
@ -80,7 +80,7 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err) return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err)
} }
return obj, nil return obj, nil

View File

@ -30,7 +30,6 @@ import (
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
rbacapiv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1" rbacapiv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1"
rbacvalidation "k8s.io/kubernetes/pkg/apis/rbac/validation"
rbacclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion" rbacclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic"
@ -46,6 +45,7 @@ import (
"k8s.io/kubernetes/pkg/registry/rbac/rolebinding" "k8s.io/kubernetes/pkg/registry/rbac/rolebinding"
rolebindingetcd "k8s.io/kubernetes/pkg/registry/rbac/rolebinding/etcd" rolebindingetcd "k8s.io/kubernetes/pkg/registry/rbac/rolebinding/etcd"
rolebindingpolicybased "k8s.io/kubernetes/pkg/registry/rbac/rolebinding/policybased" rolebindingpolicybased "k8s.io/kubernetes/pkg/registry/rbac/rolebinding/policybased"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy" "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
) )
@ -71,7 +71,7 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapis
once := new(sync.Once) once := new(sync.Once)
var ( var (
authorizationRuleResolver rbacvalidation.AuthorizationRuleResolver authorizationRuleResolver rbacregistryvalidation.AuthorizationRuleResolver
rolesStorage rest.StandardStorage rolesStorage rest.StandardStorage
roleBindingsStorage rest.StandardStorage roleBindingsStorage rest.StandardStorage
clusterRolesStorage rest.StandardStorage clusterRolesStorage rest.StandardStorage
@ -85,7 +85,7 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapis
clusterRolesStorage = clusterroleetcd.NewREST(restOptionsGetter) clusterRolesStorage = clusterroleetcd.NewREST(restOptionsGetter)
clusterRoleBindingsStorage = clusterrolebindingetcd.NewREST(restOptionsGetter) clusterRoleBindingsStorage = clusterrolebindingetcd.NewREST(restOptionsGetter)
authorizationRuleResolver = rbacvalidation.NewDefaultRuleResolver( authorizationRuleResolver = rbacregistryvalidation.NewDefaultRuleResolver(
role.AuthorizerAdapter{Registry: role.NewRegistry(rolesStorage)}, role.AuthorizerAdapter{Registry: role.NewRegistry(rolesStorage)},
rolebinding.AuthorizerAdapter{Registry: rolebinding.NewRegistry(roleBindingsStorage)}, rolebinding.AuthorizerAdapter{Registry: rolebinding.NewRegistry(roleBindingsStorage)},
clusterrole.AuthorizerAdapter{Registry: clusterrole.NewRegistry(clusterRolesStorage)}, clusterrole.AuthorizerAdapter{Registry: clusterrole.NewRegistry(clusterRolesStorage)},

View File

@ -22,9 +22,9 @@ import (
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
var groupResource = rbac.Resource("roles") var groupResource = rbac.Resource("roles")
@ -32,10 +32,10 @@ var groupResource = rbac.Resource("roles")
type Storage struct { type Storage struct {
rest.StandardStorage rest.StandardStorage
ruleResolver validation.AuthorizationRuleResolver ruleResolver rbacregistryvalidation.AuthorizationRuleResolver
} }
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver) *Storage { func NewStorage(s rest.StandardStorage, ruleResolver rbacregistryvalidation.AuthorizationRuleResolver) *Storage {
return &Storage{s, ruleResolver} return &Storage{s, ruleResolver}
} }
@ -46,7 +46,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
role := obj.(*rbac.Role) role := obj.(*rbac.Role)
rules := role.Rules rules := role.Rules
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, role.Name, err) return nil, errors.NewForbidden(groupResource, role.Name, err)
} }
return s.StandardStorage.Create(ctx, obj) return s.StandardStorage.Create(ctx, obj)
@ -61,7 +61,7 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up
role := obj.(*rbac.Role) role := obj.(*rbac.Role)
rules := role.Rules rules := role.Rules
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, role.Name, err) return nil, errors.NewForbidden(groupResource, role.Name, err)
} }
return obj, nil return obj, nil

View File

@ -23,9 +23,9 @@ import (
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request"
rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
var groupResource = rbac.Resource("rolebindings") var groupResource = rbac.Resource("rolebindings")
@ -35,10 +35,10 @@ type Storage struct {
authorizer authorizer.Authorizer authorizer authorizer.Authorizer
ruleResolver validation.AuthorizationRuleResolver ruleResolver rbacregistryvalidation.AuthorizationRuleResolver
} }
func NewStorage(s rest.StandardStorage, authorizer authorizer.Authorizer, ruleResolver validation.AuthorizationRuleResolver) *Storage { func NewStorage(s rest.StandardStorage, authorizer authorizer.Authorizer, ruleResolver rbacregistryvalidation.AuthorizationRuleResolver) *Storage {
return &Storage{s, authorizer, ruleResolver} return &Storage{s, authorizer, ruleResolver}
} }
@ -56,7 +56,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, roleBinding.Name, err) return nil, errors.NewForbidden(groupResource, roleBinding.Name, err)
} }
return s.StandardStorage.Create(ctx, obj) return s.StandardStorage.Create(ctx, obj)
@ -80,7 +80,7 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
return nil, errors.NewForbidden(groupResource, roleBinding.Name, err) return nil, errors.NewForbidden(groupResource, roleBinding.Name, err)
} }
return obj, nil return obj, nil

View File

@ -400,3 +400,28 @@ func rulesMatch(expectedRules, actualRules []rbac.PolicyRule) bool {
return true return true
} }
func TestNonResourceURLCovers(t *testing.T) {
tests := []struct {
owner string
requested string
want bool
}{
{"*", "/api", true},
{"/api", "/api", true},
{"/apis", "/api", false},
{"/api/v1", "/api", false},
{"/api/v1", "/api/v1", true},
{"/api/*", "/api/v1", true},
{"/api/*", "/api", false},
{"/api/*/*", "/api/v1", false},
{"/*/v1/*", "/api/v1", false},
}
for _, tc := range tests {
got := nonResourceURLCovers(tc.owner, tc.requested)
if got != tc.want {
t.Errorf("nonResourceURLCovers(%q, %q): want=(%t), got=(%t)", tc.owner, tc.requested, tc.want, got)
}
}
}

View File

@ -32,10 +32,10 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
_ "k8s.io/kubernetes/pkg/api/install" _ "k8s.io/kubernetes/pkg/api/install"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
rbac "k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
_ "k8s.io/kubernetes/pkg/apis/rbac/install" _ "k8s.io/kubernetes/pkg/apis/rbac/install"
rbacv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1" rbacv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1"
rbacvalidation "k8s.io/kubernetes/pkg/apis/rbac/validation" rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy" "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
) )
@ -67,13 +67,13 @@ func getSemanticRoles(roles []rbac.ClusterRole) semanticRoles {
func TestCovers(t *testing.T) { func TestCovers(t *testing.T) {
semanticRoles := getSemanticRoles(bootstrappolicy.ClusterRoles()) semanticRoles := getSemanticRoles(bootstrappolicy.ClusterRoles())
if covers, miss := rbacvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.edit.Rules); !covers { if covers, miss := rbacregistryvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.edit.Rules); !covers {
t.Errorf("failed to cover: %#v", miss) t.Errorf("failed to cover: %#v", miss)
} }
if covers, miss := rbacvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.view.Rules); !covers { if covers, miss := rbacregistryvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.view.Rules); !covers {
t.Errorf("failed to cover: %#v", miss) t.Errorf("failed to cover: %#v", miss)
} }
if covers, miss := rbacvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.view.Rules); !covers { if covers, miss := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.view.Rules); !covers {
t.Errorf("failed to cover: %#v", miss) t.Errorf("failed to cover: %#v", miss)
} }
} }
@ -91,17 +91,17 @@ func TestAdminEditRelationship(t *testing.T) {
// confirm that the edit role doesn't already have extra powers // confirm that the edit role doesn't already have extra powers
for _, rule := range additionalAdminPowers { for _, rule := range additionalAdminPowers {
if covers, _ := rbacvalidation.Covers(semanticRoles.edit.Rules, []rbac.PolicyRule{rule}); covers { if covers, _ := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, []rbac.PolicyRule{rule}); covers {
t.Errorf("edit has extra powers: %#v", rule) t.Errorf("edit has extra powers: %#v", rule)
} }
} }
semanticRoles.edit.Rules = append(semanticRoles.edit.Rules, additionalAdminPowers...) semanticRoles.edit.Rules = append(semanticRoles.edit.Rules, additionalAdminPowers...)
// at this point, we should have a two way covers relationship // at this point, we should have a two way covers relationship
if covers, miss := rbacvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.edit.Rules); !covers { if covers, miss := rbacregistryvalidation.Covers(semanticRoles.admin.Rules, semanticRoles.edit.Rules); !covers {
t.Errorf("admin has lost rules for: %#v", miss) t.Errorf("admin has lost rules for: %#v", miss)
} }
if covers, miss := rbacvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.admin.Rules); !covers { if covers, miss := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.admin.Rules); !covers {
t.Errorf("edit is missing rules for: %#v\nIf these should only be admin powers, add them to the list. Otherwise, add them to the edit role.", miss) t.Errorf("edit is missing rules for: %#v\nIf these should only be admin powers, add them to the list. Otherwise, add them to the edit role.", miss)
} }
} }
@ -136,17 +136,17 @@ func TestEditViewRelationship(t *testing.T) {
// confirm that the view role doesn't already have extra powers // confirm that the view role doesn't already have extra powers
for _, rule := range viewEscalatingNamespaceResources { for _, rule := range viewEscalatingNamespaceResources {
if covers, _ := rbacvalidation.Covers(semanticRoles.view.Rules, []rbac.PolicyRule{rule}); covers { if covers, _ := rbacregistryvalidation.Covers(semanticRoles.view.Rules, []rbac.PolicyRule{rule}); covers {
t.Errorf("view has extra powers: %#v", rule) t.Errorf("view has extra powers: %#v", rule)
} }
} }
semanticRoles.view.Rules = append(semanticRoles.view.Rules, viewEscalatingNamespaceResources...) semanticRoles.view.Rules = append(semanticRoles.view.Rules, viewEscalatingNamespaceResources...)
// at this point, we should have a two way covers relationship // at this point, we should have a two way covers relationship
if covers, miss := rbacvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.view.Rules); !covers { if covers, miss := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, semanticRoles.view.Rules); !covers {
t.Errorf("edit has lost rules for: %#v", miss) t.Errorf("edit has lost rules for: %#v", miss)
} }
if covers, miss := rbacvalidation.Covers(semanticRoles.view.Rules, semanticRoles.edit.Rules); !covers { if covers, miss := rbacregistryvalidation.Covers(semanticRoles.view.Rules, semanticRoles.edit.Rules); !covers {
t.Errorf("view is missing rules for: %#v\nIf these are escalating powers, add them to the list. Otherwise, add them to the view role.", miss) t.Errorf("view is missing rules for: %#v\nIf these are escalating powers, add them to the list. Otherwise, add them to the view role.", miss)
} }
} }

View File

@ -24,7 +24,7 @@ import (
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation" rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
type RequestToRuleMapper interface { type RequestToRuleMapper interface {
@ -55,9 +55,9 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (boo
return false, reason, nil return false, reason, nil
} }
func New(roles validation.RoleGetter, roleBindings validation.RoleBindingLister, clusterRoles validation.ClusterRoleGetter, clusterRoleBindings validation.ClusterRoleBindingLister) *RBACAuthorizer { func New(roles rbacregistryvalidation.RoleGetter, roleBindings rbacregistryvalidation.RoleBindingLister, clusterRoles rbacregistryvalidation.ClusterRoleGetter, clusterRoleBindings rbacregistryvalidation.ClusterRoleBindingLister) *RBACAuthorizer {
authorizer := &RBACAuthorizer{ authorizer := &RBACAuthorizer{
authorizationRuleResolver: validation.NewDefaultRuleResolver( authorizationRuleResolver: rbacregistryvalidation.NewDefaultRuleResolver(
roles, roleBindings, clusterRoles, clusterRoleBindings, roles, roleBindings, clusterRoles, clusterRoleBindings,
), ),
} }

View File

@ -25,7 +25,7 @@ import (
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation" rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
func newRule(verbs, apiGroups, resources, nonResourceURLs string) rbac.PolicyRule { func newRule(verbs, apiGroups, resources, nonResourceURLs string) rbac.PolicyRule {
@ -219,7 +219,7 @@ func TestAuthorizer(t *testing.T) {
}, },
} }
for i, tt := range tests { for i, tt := range tests {
ruleResolver, _ := validation.NewTestRuleResolver(tt.roles, tt.roleBindings, tt.clusterRoles, tt.clusterRoleBindings) ruleResolver, _ := rbacregistryvalidation.NewTestRuleResolver(tt.roles, tt.roleBindings, tt.clusterRoles, tt.clusterRoleBindings)
a := RBACAuthorizer{ruleResolver} a := RBACAuthorizer{ruleResolver}
for _, attr := range tt.shouldPass { for _, attr := range tt.shouldPass {
if authorized, _, _ := a.Authorize(attr); !authorized { if authorized, _, _ := a.Authorize(attr); !authorized {

View File

@ -22,7 +22,7 @@ import (
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation" rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
type RoleToRuleMapper interface { type RoleToRuleMapper interface {
@ -34,17 +34,17 @@ type RoleToRuleMapper interface {
type SubjectAccessEvaluator struct { type SubjectAccessEvaluator struct {
superUser string superUser string
roleBindingLister validation.RoleBindingLister roleBindingLister rbacregistryvalidation.RoleBindingLister
clusterRoleBindingLister validation.ClusterRoleBindingLister clusterRoleBindingLister rbacregistryvalidation.ClusterRoleBindingLister
roleToRuleMapper RoleToRuleMapper roleToRuleMapper RoleToRuleMapper
} }
func NewSubjectAccessEvaluator(roles validation.RoleGetter, roleBindings validation.RoleBindingLister, clusterRoles validation.ClusterRoleGetter, clusterRoleBindings validation.ClusterRoleBindingLister, superUser string) *SubjectAccessEvaluator { func NewSubjectAccessEvaluator(roles rbacregistryvalidation.RoleGetter, roleBindings rbacregistryvalidation.RoleBindingLister, clusterRoles rbacregistryvalidation.ClusterRoleGetter, clusterRoleBindings rbacregistryvalidation.ClusterRoleBindingLister, superUser string) *SubjectAccessEvaluator {
subjectLocator := &SubjectAccessEvaluator{ subjectLocator := &SubjectAccessEvaluator{
superUser: superUser, superUser: superUser,
roleBindingLister: roleBindings, roleBindingLister: roleBindings,
clusterRoleBindingLister: clusterRoleBindings, clusterRoleBindingLister: clusterRoleBindings,
roleToRuleMapper: validation.NewDefaultRuleResolver( roleToRuleMapper: rbacregistryvalidation.NewDefaultRuleResolver(
roles, roleBindings, clusterRoles, clusterRoleBindings, roles, roleBindings, clusterRoles, clusterRoleBindings,
), ),
} }

View File

@ -23,7 +23,7 @@ import (
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation" rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
) )
func TestSubjectLocator(t *testing.T) { func TestSubjectLocator(t *testing.T) {
@ -136,7 +136,7 @@ func TestSubjectLocator(t *testing.T) {
}, },
} }
for _, tt := range tests { for _, tt := range tests {
ruleResolver, lister := validation.NewTestRuleResolver(tt.roles, tt.roleBindings, tt.clusterRoles, tt.clusterRoleBindings) ruleResolver, lister := rbacregistryvalidation.NewTestRuleResolver(tt.roles, tt.roleBindings, tt.clusterRoles, tt.clusterRoleBindings)
a := SubjectAccessEvaluator{tt.superUser, lister, lister, ruleResolver} a := SubjectAccessEvaluator{tt.superUser, lister, lister, ruleResolver}
for i, action := range tt.actionsToSubjects { for i, action := range tt.actionsToSubjects {
actualSubjects, err := a.AllowedSubjects(action.action) actualSubjects, err := a.AllowedSubjects(action.action)