diff --git a/pkg/api/BUILD b/pkg/api/BUILD index 75d3a45dd9..3eb82eac90 100644 --- a/pkg/api/BUILD +++ b/pkg/api/BUILD @@ -29,11 +29,9 @@ go_library( deps = [ "//pkg/api/resource:go_default_library", "//pkg/fields:go_default_library", - "//pkg/genericapiserver/api/request:go_default_library", "//pkg/util/intstr:go_default_library", "//pkg/util/labels:go_default_library", "//pkg/util/rand:go_default_library", - "//pkg/util/uuid:go_default_library", "//vendor:github.com/davecgh/go-spew/spew", "//vendor:k8s.io/apimachinery/pkg/api/meta", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", @@ -88,8 +86,6 @@ go_test( "//pkg/apis/batch/v2alpha1:go_default_library", "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", - "//pkg/genericapiserver/api/request:go_default_library", - "//pkg/util/uuid:go_default_library", "//vendor:github.com/davecgh/go-spew/spew", "//vendor:github.com/gogo/protobuf/proto", "//vendor:github.com/golang/protobuf/proto", diff --git a/pkg/api/meta.go b/pkg/api/meta.go index 8beb0672d5..7ad2e1d3da 100644 --- a/pkg/api/meta.go +++ b/pkg/api/meta.go @@ -22,23 +22,8 @@ import ( "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" - "k8s.io/kubernetes/pkg/util/uuid" ) -// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta. -func FillObjectMetaSystemFields(ctx genericapirequest.Context, meta *ObjectMeta) { - meta.CreationTimestamp = metav1.Now() - // allows admission controllers to assign a UID earlier in the request processing - // to support tracking resources pending creation. - uid, found := genericapirequest.UIDFrom(ctx) - if !found { - uid = uuid.NewUUID() - } - meta.UID = uid - meta.SelfLink = "" -} - // HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values. func HasObjectMetaSystemFieldValues(meta *ObjectMeta) bool { return !meta.CreationTimestamp.Time.IsZero() || diff --git a/pkg/api/meta_test.go b/pkg/api/meta_test.go index 4c44e6082a..e9d534781f 100644 --- a/pkg/api/meta_test.go +++ b/pkg/api/meta_test.go @@ -28,45 +28,10 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kubernetes/pkg/api" - genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" - "k8s.io/kubernetes/pkg/util/uuid" ) var _ meta.Object = &api.ObjectMeta{} -// TestFillObjectMetaSystemFields validates that system populated fields are set on an object -func TestFillObjectMetaSystemFields(t *testing.T) { - ctx := genericapirequest.NewDefaultContext() - resource := api.ObjectMeta{} - api.FillObjectMetaSystemFields(ctx, &resource) - if resource.CreationTimestamp.Time.IsZero() { - t.Errorf("resource.CreationTimestamp is zero") - } else if len(resource.UID) == 0 { - t.Errorf("resource.UID missing") - } - // verify we can inject a UID - uid := uuid.NewUUID() - ctx = genericapirequest.WithUID(ctx, uid) - resource = api.ObjectMeta{} - api.FillObjectMetaSystemFields(ctx, &resource) - if resource.UID != uid { - t.Errorf("resource.UID expected: %v, actual: %v", uid, resource.UID) - } -} - -// TestHasObjectMetaSystemFieldValues validates that true is returned if and only if all fields are populated -func TestHasObjectMetaSystemFieldValues(t *testing.T) { - ctx := genericapirequest.NewDefaultContext() - resource := api.ObjectMeta{} - if api.HasObjectMetaSystemFieldValues(&resource) { - t.Errorf("the resource does not have all fields yet populated, but incorrectly reports it does") - } - api.FillObjectMetaSystemFields(ctx, &resource) - if !api.HasObjectMetaSystemFieldValues(&resource) { - t.Errorf("the resource does have all fields populated, but incorrectly reports it does not") - } -} - func getObjectMetaAndOwnerReferences() (objectMeta api.ObjectMeta, metaOwnerReferences []metav1.OwnerReference) { fuzz.New().NilChance(.5).NumElements(1, 5).Fuzz(&objectMeta) references := objectMeta.OwnerReferences diff --git a/pkg/api/resource_helpers.go b/pkg/api/resource_helpers.go index e3eb31888e..9ca3297e66 100644 --- a/pkg/api/resource_helpers.go +++ b/pkg/api/resource_helpers.go @@ -21,7 +21,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/api/resource" - genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" ) // Returns string version of ResourceName. @@ -228,13 +227,3 @@ func PodRequestsAndLimits(pod *Pod) (reqs map[ResourceName]resource.Quantity, li } return } - -// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context. -// TODO(sttts): move into pkg/genericapiserver/api -func ValidNamespace(ctx genericapirequest.Context, resource *ObjectMeta) bool { - ns, ok := genericapirequest.NamespaceFrom(ctx) - if len(resource.Namespace) == 0 { - resource.Namespace = ns - } - return ns == resource.Namespace && ok -} diff --git a/pkg/api/rest/BUILD b/pkg/api/rest/BUILD index 4fe769802a..ea67055744 100644 --- a/pkg/api/rest/BUILD +++ b/pkg/api/rest/BUILD @@ -5,6 +5,7 @@ licenses(["notice"]) load( "@io_bazel_rules_go//go:def.bzl", "go_library", + "go_test", ) go_library( @@ -14,6 +15,7 @@ go_library( "delete.go", "doc.go", "export.go", + "meta.go", "rest.go", "types.go", "update.go", @@ -25,6 +27,7 @@ go_library( "//pkg/api/validation/genericvalidation:go_default_library", "//pkg/api/validation/path:go_default_library", "//pkg/genericapiserver/api/request:go_default_library", + "//pkg/util/uuid:go_default_library", "//vendor:k8s.io/apimachinery/pkg/api/meta", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", "//vendor:k8s.io/apimachinery/pkg/runtime", @@ -49,3 +52,15 @@ filegroup( ], tags = ["automanaged"], ) + +go_test( + name = "go_default_test", + srcs = ["meta_test.go"], + library = ":go_default_library", + tags = ["automanaged"], + deps = [ + "//pkg/api:go_default_library", + "//pkg/genericapiserver/api/request:go_default_library", + "//pkg/util/uuid:go_default_library", + ], +) diff --git a/pkg/api/rest/create.go b/pkg/api/rest/create.go index 9b52324144..b510015fde 100644 --- a/pkg/api/rest/create.go +++ b/pkg/api/rest/create.go @@ -23,7 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/validation/genericvalidation" - path "k8s.io/kubernetes/pkg/api/validation/path" + "k8s.io/kubernetes/pkg/api/validation/path" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" ) @@ -61,7 +61,7 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx genericapirequest.Context, ob } if strategy.NamespaceScoped() { - if !api.ValidNamespace(ctx, objectMeta) { + if !ValidNamespace(ctx, objectMeta) { return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request") } } else { @@ -70,7 +70,7 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx genericapirequest.Context, ob objectMeta.DeletionTimestamp = nil objectMeta.DeletionGracePeriodSeconds = nil strategy.PrepareForCreate(ctx, obj) - api.FillObjectMetaSystemFields(ctx, objectMeta) + FillObjectMetaSystemFields(ctx, objectMeta) api.GenerateName(strategy, objectMeta) // ClusterName is ignored and should not be saved diff --git a/pkg/api/rest/meta.go b/pkg/api/rest/meta.go new file mode 100644 index 0000000000..155f888210 --- /dev/null +++ b/pkg/api/rest/meta.go @@ -0,0 +1,47 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rest + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/api" + genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" + "k8s.io/kubernetes/pkg/util/uuid" +) + +// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta. +func FillObjectMetaSystemFields(ctx genericapirequest.Context, meta *api.ObjectMeta) { + meta.CreationTimestamp = metav1.Now() + // allows admission controllers to assign a UID earlier in the request processing + // to support tracking resources pending creation. + uid, found := genericapirequest.UIDFrom(ctx) + if !found { + uid = uuid.NewUUID() + } + meta.UID = uid + meta.SelfLink = "" +} + +// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context. +// TODO(sttts): move into pkg/genericapiserver/api +func ValidNamespace(ctx genericapirequest.Context, resource *api.ObjectMeta) bool { + ns, ok := genericapirequest.NamespaceFrom(ctx) + if len(resource.Namespace) == 0 { + resource.Namespace = ns + } + return ns == resource.Namespace && ok +} diff --git a/pkg/api/rest/meta_test.go b/pkg/api/rest/meta_test.go new file mode 100644 index 0000000000..9b79147e05 --- /dev/null +++ b/pkg/api/rest/meta_test.go @@ -0,0 +1,85 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package rest + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" + "k8s.io/kubernetes/pkg/util/uuid" +) + +// TestFillObjectMetaSystemFields validates that system populated fields are set on an object +func TestFillObjectMetaSystemFields(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resource := api.ObjectMeta{} + FillObjectMetaSystemFields(ctx, &resource) + if resource.CreationTimestamp.Time.IsZero() { + t.Errorf("resource.CreationTimestamp is zero") + } else if len(resource.UID) == 0 { + t.Errorf("resource.UID missing") + } + // verify we can inject a UID + uid := uuid.NewUUID() + ctx = genericapirequest.WithUID(ctx, uid) + resource = api.ObjectMeta{} + FillObjectMetaSystemFields(ctx, &resource) + if resource.UID != uid { + t.Errorf("resource.UID expected: %v, actual: %v", uid, resource.UID) + } +} + +// TestHasObjectMetaSystemFieldValues validates that true is returned if and only if all fields are populated +func TestHasObjectMetaSystemFieldValues(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + resource := api.ObjectMeta{} + if api.HasObjectMetaSystemFieldValues(&resource) { + t.Errorf("the resource does not have all fields yet populated, but incorrectly reports it does") + } + FillObjectMetaSystemFields(ctx, &resource) + if !api.HasObjectMetaSystemFieldValues(&resource) { + t.Errorf("the resource does have all fields populated, but incorrectly reports it does not") + } +} + +// TestValidNamespace validates that namespace rules are enforced on a resource prior to create or update +func TestValidNamespace(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + namespace, _ := genericapirequest.NamespaceFrom(ctx) + resource := api.ReplicationController{} + if !ValidNamespace(ctx, &resource.ObjectMeta) { + t.Fatalf("expected success") + } + if namespace != resource.Namespace { + t.Fatalf("expected resource to have the default namespace assigned during validation") + } + resource = api.ReplicationController{ObjectMeta: api.ObjectMeta{Namespace: "other"}} + if ValidNamespace(ctx, &resource.ObjectMeta) { + t.Fatalf("Expected error that resource and context errors do not match because resource has different namespace") + } + ctx = genericapirequest.NewContext() + if ValidNamespace(ctx, &resource.ObjectMeta) { + t.Fatalf("Expected error that resource and context errors do not match since context has no namespace") + } + + ctx = genericapirequest.NewContext() + ns := genericapirequest.NamespaceValue(ctx) + if ns != "" { + t.Fatalf("Expected the empty string") + } +} diff --git a/pkg/api/rest/update.go b/pkg/api/rest/update.go index 4534888675..ed0dc0fe2a 100644 --- a/pkg/api/rest/update.go +++ b/pkg/api/rest/update.go @@ -81,7 +81,7 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx genericapirequest.Context, ob return kerr } if strategy.NamespaceScoped() { - if !api.ValidNamespace(ctx, objectMeta) { + if !ValidNamespace(ctx, objectMeta) { return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request") } } else { diff --git a/pkg/apis/abac/v0/BUILD b/pkg/apis/abac/v0/BUILD index ee92953ed3..0e3a00fd48 100644 --- a/pkg/apis/abac/v0/BUILD +++ b/pkg/apis/abac/v0/BUILD @@ -22,7 +22,6 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/conversion", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apimachinery/pkg/runtime/schema", - "//vendor:k8s.io/apiserver/pkg/authentication/user", ], ) diff --git a/pkg/apis/abac/v0/conversion.go b/pkg/apis/abac/v0/conversion.go index 07dffb16f7..e0f78c77f1 100644 --- a/pkg/apis/abac/v0/conversion.go +++ b/pkg/apis/abac/v0/conversion.go @@ -19,10 +19,13 @@ package v0 import ( "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apiserver/pkg/authentication/user" 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 { return scheme.AddConversionFuncs( 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 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 if in.User == "*" || in.Group == "*" { - out.Spec.Group = user.AllAuthenticated + out.Spec.Group = allAuthenticated out.Spec.User = "" } diff --git a/pkg/apis/abac/v1beta1/BUILD b/pkg/apis/abac/v1beta1/BUILD index a88f0a9934..a91ee77980 100644 --- a/pkg/apis/abac/v1beta1/BUILD +++ b/pkg/apis/abac/v1beta1/BUILD @@ -26,7 +26,6 @@ go_library( "//vendor:k8s.io/apimachinery/pkg/conversion", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apimachinery/pkg/runtime/schema", - "//vendor:k8s.io/apiserver/pkg/authentication/user", ], ) diff --git a/pkg/apis/abac/v1beta1/conversion.go b/pkg/apis/abac/v1beta1/conversion.go index 41c10dab28..b830f532d9 100644 --- a/pkg/apis/abac/v1beta1/conversion.go +++ b/pkg/apis/abac/v1beta1/conversion.go @@ -19,10 +19,13 @@ package v1beta1 import ( "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apiserver/pkg/authentication/user" 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 { return scheme.AddConversionFuncs( 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 if in.Spec.User == "*" || in.Spec.Group == "*" { - out.Spec.Group = user.AllAuthenticated + out.Spec.Group = allAuthenticated out.Spec.User = "" } diff --git a/pkg/apis/rbac/validation/BUILD b/pkg/apis/rbac/validation/BUILD index f9fd6947b5..4434172811 100644 --- a/pkg/apis/rbac/validation/BUILD +++ b/pkg/apis/rbac/validation/BUILD @@ -10,41 +10,25 @@ load( go_library( name = "go_default_library", - srcs = [ - "policy_comparator.go", - "rulevalidation.go", - "validation.go", - ], + srcs = ["validation.go"], tags = ["automanaged"], deps = [ - "//pkg/api/errors:go_default_library", "//pkg/api/validation:go_default_library", "//pkg/api/validation/path:go_default_library", "//pkg/apis/rbac:go_default_library", - "//pkg/genericapiserver/api/request:go_default_library", - "//pkg/serviceaccount:go_default_library", - "//vendor:github.com/golang/glog", - "//vendor:k8s.io/apimachinery/pkg/util/errors", "//vendor:k8s.io/apimachinery/pkg/util/validation/field", - "//vendor:k8s.io/apiserver/pkg/authentication/user", ], ) go_test( name = "go_default_test", - srcs = [ - "policy_comparator_test.go", - "rulevalidation_test.go", - "validation_test.go", - ], + srcs = ["validation_test.go"], library = ":go_default_library", tags = ["automanaged"], deps = [ "//pkg/api:go_default_library", "//pkg/apis/rbac:go_default_library", - "//vendor:k8s.io/apimachinery/pkg/util/diff", "//vendor:k8s.io/apimachinery/pkg/util/validation/field", - "//vendor:k8s.io/apiserver/pkg/authentication/user", ], ) diff --git a/pkg/apis/rbac/validation/validation_test.go b/pkg/apis/rbac/validation/validation_test.go index 765f492f5e..4868a92eb7 100644 --- a/pkg/apis/rbac/validation/validation_test.go +++ b/pkg/apis/rbac/validation/validation_test.go @@ -20,7 +20,7 @@ import ( "testing" "k8s.io/apimachinery/pkg/util/validation/field" - api "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api" "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 { role rbac.Role wantErr bool diff --git a/pkg/genericapiserver/api/request/context_test.go b/pkg/genericapiserver/api/request/context_test.go index 4c5f766b6b..5d2608f5c4 100644 --- a/pkg/genericapiserver/api/request/context_test.go +++ b/pkg/genericapiserver/api/request/context_test.go @@ -43,33 +43,6 @@ func TestNamespaceContext(t *testing.T) { } } -// TestValidNamespace validates that namespace rules are enforced on a resource prior to create or update -func TestValidNamespace(t *testing.T) { - ctx := genericapirequest.NewDefaultContext() - namespace, _ := genericapirequest.NamespaceFrom(ctx) - resource := api.ReplicationController{} - if !api.ValidNamespace(ctx, &resource.ObjectMeta) { - t.Fatalf("expected success") - } - if namespace != resource.Namespace { - t.Fatalf("expected resource to have the default namespace assigned during validation") - } - resource = api.ReplicationController{ObjectMeta: api.ObjectMeta{Namespace: "other"}} - if api.ValidNamespace(ctx, &resource.ObjectMeta) { - t.Fatalf("Expected error that resource and context errors do not match because resource has different namespace") - } - ctx = genericapirequest.NewContext() - if api.ValidNamespace(ctx, &resource.ObjectMeta) { - t.Fatalf("Expected error that resource and context errors do not match since context has no namespace") - } - - ctx = genericapirequest.NewContext() - ns := genericapirequest.NamespaceValue(ctx) - if ns != "" { - t.Fatalf("Expected the empty string") - } -} - //TestUserContext validates that a userinfo can be get/set on a context object func TestUserContext(t *testing.T) { ctx := genericapirequest.NewContext() diff --git a/pkg/registry/core/service/rest.go b/pkg/registry/core/service/rest.go index 798145636a..f0d49478b3 100644 --- a/pkg/registry/core/service/rest.go +++ b/pkg/registry/core/service/rest.go @@ -381,7 +381,7 @@ func (rs *REST) Update(ctx genericapirequest.Context, name string, objInfo rest. } service := obj.(*api.Service) - if !api.ValidNamespace(ctx, &service.ObjectMeta) { + if !rest.ValidNamespace(ctx, &service.ObjectMeta) { return nil, false, errors.NewConflict(api.Resource("services"), service.Namespace, fmt.Errorf("Service.Namespace does not match the provided context")) } diff --git a/pkg/registry/rbac/BUILD b/pkg/registry/rbac/BUILD index f72aae5d8f..13367f69bd 100644 --- a/pkg/registry/rbac/BUILD +++ b/pkg/registry/rbac/BUILD @@ -36,6 +36,7 @@ filegroup( "//pkg/registry/rbac/rest:all-srcs", "//pkg/registry/rbac/role:all-srcs", "//pkg/registry/rbac/rolebinding:all-srcs", + "//pkg/registry/rbac/validation:all-srcs", ], tags = ["automanaged"], ) diff --git a/pkg/registry/rbac/clusterrole/policybased/BUILD b/pkg/registry/rbac/clusterrole/policybased/BUILD index 34c298f449..eacf4d81d8 100644 --- a/pkg/registry/rbac/clusterrole/policybased/BUILD +++ b/pkg/registry/rbac/clusterrole/policybased/BUILD @@ -15,9 +15,9 @@ go_library( "//pkg/api/errors:go_default_library", "//pkg/api/rest:go_default_library", "//pkg/apis/rbac:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", "//pkg/genericapiserver/api/request:go_default_library", "//pkg/registry/rbac:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//vendor:k8s.io/apimachinery/pkg/runtime", ], ) diff --git a/pkg/registry/rbac/clusterrole/policybased/storage.go b/pkg/registry/rbac/clusterrole/policybased/storage.go index c0d9e58be5..26f1e219d9 100644 --- a/pkg/registry/rbac/clusterrole/policybased/storage.go +++ b/pkg/registry/rbac/clusterrole/policybased/storage.go @@ -22,9 +22,9 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apis/rbac/validation" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" + rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation" ) var groupResource = rbac.Resource("clusterroles") @@ -32,10 +32,10 @@ var groupResource = rbac.Resource("clusterroles") type Storage struct { 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} } @@ -46,7 +46,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run clusterRole := obj.(*rbac.ClusterRole) 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 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) 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 obj, nil diff --git a/pkg/registry/rbac/clusterrolebinding/policybased/BUILD b/pkg/registry/rbac/clusterrolebinding/policybased/BUILD index 3e30504e42..3dc66e08af 100644 --- a/pkg/registry/rbac/clusterrolebinding/policybased/BUILD +++ b/pkg/registry/rbac/clusterrolebinding/policybased/BUILD @@ -15,9 +15,9 @@ go_library( "//pkg/api/errors:go_default_library", "//pkg/api/rest:go_default_library", "//pkg/apis/rbac:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", "//pkg/genericapiserver/api/request:go_default_library", "//pkg/registry/rbac:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer", ], diff --git a/pkg/registry/rbac/clusterrolebinding/policybased/storage.go b/pkg/registry/rbac/clusterrolebinding/policybased/storage.go index 38299a109a..d5d45521a5 100644 --- a/pkg/registry/rbac/clusterrolebinding/policybased/storage.go +++ b/pkg/registry/rbac/clusterrolebinding/policybased/storage.go @@ -23,9 +23,9 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apis/rbac/validation" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" + rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation" ) var groupResource = rbac.Resource("clusterrolebindings") @@ -35,10 +35,10 @@ type Storage struct { 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} } @@ -56,7 +56,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run if err != nil { 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 s.StandardStorage.Create(ctx, obj) @@ -80,7 +80,7 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up if err != nil { 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 obj, nil diff --git a/pkg/registry/rbac/rest/BUILD b/pkg/registry/rbac/rest/BUILD index b32d88e758..d73327798e 100644 --- a/pkg/registry/rbac/rest/BUILD +++ b/pkg/registry/rbac/rest/BUILD @@ -16,7 +16,6 @@ go_library( "//pkg/api/rest:go_default_library", "//pkg/apis/rbac:go_default_library", "//pkg/apis/rbac/v1alpha1:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion:go_default_library", "//pkg/genericapiserver:go_default_library", "//pkg/registry/generic:go_default_library", @@ -32,6 +31,7 @@ go_library( "//pkg/registry/rbac/rolebinding:go_default_library", "//pkg/registry/rbac/rolebinding/etcd:go_default_library", "//pkg/registry/rbac/rolebinding/policybased:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library", "//vendor:github.com/golang/glog", "//vendor:k8s.io/apimachinery/pkg/util/runtime", diff --git a/pkg/registry/rbac/rest/storage_rbac.go b/pkg/registry/rbac/rest/storage_rbac.go index 114839d4bc..10bcd0732e 100644 --- a/pkg/registry/rbac/rest/storage_rbac.go +++ b/pkg/registry/rbac/rest/storage_rbac.go @@ -30,7 +30,6 @@ import ( "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/apis/rbac" 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" "k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/registry/generic" @@ -46,6 +45,7 @@ import ( "k8s.io/kubernetes/pkg/registry/rbac/rolebinding" rolebindingetcd "k8s.io/kubernetes/pkg/registry/rbac/rolebinding/etcd" 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" ) @@ -71,7 +71,7 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapis once := new(sync.Once) var ( - authorizationRuleResolver rbacvalidation.AuthorizationRuleResolver + authorizationRuleResolver rbacregistryvalidation.AuthorizationRuleResolver rolesStorage rest.StandardStorage roleBindingsStorage rest.StandardStorage clusterRolesStorage rest.StandardStorage @@ -85,7 +85,7 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapis clusterRolesStorage = clusterroleetcd.NewREST(restOptionsGetter) clusterRoleBindingsStorage = clusterrolebindingetcd.NewREST(restOptionsGetter) - authorizationRuleResolver = rbacvalidation.NewDefaultRuleResolver( + authorizationRuleResolver = rbacregistryvalidation.NewDefaultRuleResolver( role.AuthorizerAdapter{Registry: role.NewRegistry(rolesStorage)}, rolebinding.AuthorizerAdapter{Registry: rolebinding.NewRegistry(roleBindingsStorage)}, clusterrole.AuthorizerAdapter{Registry: clusterrole.NewRegistry(clusterRolesStorage)}, diff --git a/pkg/registry/rbac/role/policybased/BUILD b/pkg/registry/rbac/role/policybased/BUILD index 34c298f449..eacf4d81d8 100644 --- a/pkg/registry/rbac/role/policybased/BUILD +++ b/pkg/registry/rbac/role/policybased/BUILD @@ -15,9 +15,9 @@ go_library( "//pkg/api/errors:go_default_library", "//pkg/api/rest:go_default_library", "//pkg/apis/rbac:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", "//pkg/genericapiserver/api/request:go_default_library", "//pkg/registry/rbac:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//vendor:k8s.io/apimachinery/pkg/runtime", ], ) diff --git a/pkg/registry/rbac/role/policybased/storage.go b/pkg/registry/rbac/role/policybased/storage.go index 9e1a618e0b..4cedc0329a 100644 --- a/pkg/registry/rbac/role/policybased/storage.go +++ b/pkg/registry/rbac/role/policybased/storage.go @@ -22,9 +22,9 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apis/rbac/validation" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" + rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation" ) var groupResource = rbac.Resource("roles") @@ -32,10 +32,10 @@ var groupResource = rbac.Resource("roles") type Storage struct { 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} } @@ -46,7 +46,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run role := obj.(*rbac.Role) 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 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) 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 obj, nil diff --git a/pkg/registry/rbac/rolebinding/policybased/BUILD b/pkg/registry/rbac/rolebinding/policybased/BUILD index 3e30504e42..3dc66e08af 100644 --- a/pkg/registry/rbac/rolebinding/policybased/BUILD +++ b/pkg/registry/rbac/rolebinding/policybased/BUILD @@ -15,9 +15,9 @@ go_library( "//pkg/api/errors:go_default_library", "//pkg/api/rest:go_default_library", "//pkg/apis/rbac:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", "//pkg/genericapiserver/api/request:go_default_library", "//pkg/registry/rbac:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer", ], diff --git a/pkg/registry/rbac/rolebinding/policybased/storage.go b/pkg/registry/rbac/rolebinding/policybased/storage.go index e30c8ce866..fdf115f65f 100644 --- a/pkg/registry/rbac/rolebinding/policybased/storage.go +++ b/pkg/registry/rbac/rolebinding/policybased/storage.go @@ -23,9 +23,9 @@ import ( "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apis/rbac/validation" genericapirequest "k8s.io/kubernetes/pkg/genericapiserver/api/request" rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" + rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation" ) var groupResource = rbac.Resource("rolebindings") @@ -35,10 +35,10 @@ type Storage struct { 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} } @@ -56,7 +56,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run if err != nil { 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 s.StandardStorage.Create(ctx, obj) @@ -80,7 +80,7 @@ func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.Up if err != nil { 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 obj, nil diff --git a/pkg/registry/rbac/validation/BUILD b/pkg/registry/rbac/validation/BUILD new file mode 100644 index 0000000000..faa0a203b3 --- /dev/null +++ b/pkg/registry/rbac/validation/BUILD @@ -0,0 +1,56 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", + "go_test", +) + +go_test( + name = "go_default_test", + srcs = [ + "policy_comparator_test.go", + "rule_test.go", + ], + library = ":go_default_library", + tags = ["automanaged"], + deps = [ + "//pkg/api:go_default_library", + "//pkg/apis/rbac:go_default_library", + "//vendor:k8s.io/apimachinery/pkg/util/diff", + "//vendor:k8s.io/apiserver/pkg/authentication/user", + ], +) + +go_library( + name = "go_default_library", + srcs = [ + "policy_comparator.go", + "rule.go", + ], + tags = ["automanaged"], + deps = [ + "//pkg/api/errors:go_default_library", + "//pkg/apis/rbac:go_default_library", + "//pkg/genericapiserver/api/request:go_default_library", + "//pkg/serviceaccount:go_default_library", + "//vendor:github.com/golang/glog", + "//vendor:k8s.io/apimachinery/pkg/util/errors", + "//vendor:k8s.io/apiserver/pkg/authentication/user", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/pkg/apis/rbac/validation/policy_comparator.go b/pkg/registry/rbac/validation/policy_comparator.go similarity index 100% rename from pkg/apis/rbac/validation/policy_comparator.go rename to pkg/registry/rbac/validation/policy_comparator.go diff --git a/pkg/apis/rbac/validation/policy_comparator_test.go b/pkg/registry/rbac/validation/policy_comparator_test.go similarity index 95% rename from pkg/apis/rbac/validation/policy_comparator_test.go rename to pkg/registry/rbac/validation/policy_comparator_test.go index 2b5c3b2072..d4d9247ab2 100644 --- a/pkg/apis/rbac/validation/policy_comparator_test.go +++ b/pkg/registry/rbac/validation/policy_comparator_test.go @@ -400,3 +400,28 @@ func rulesMatch(expectedRules, actualRules []rbac.PolicyRule) bool { 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) + } + } +} diff --git a/pkg/apis/rbac/validation/rulevalidation.go b/pkg/registry/rbac/validation/rule.go similarity index 100% rename from pkg/apis/rbac/validation/rulevalidation.go rename to pkg/registry/rbac/validation/rule.go diff --git a/pkg/apis/rbac/validation/rulevalidation_test.go b/pkg/registry/rbac/validation/rule_test.go similarity index 100% rename from pkg/apis/rbac/validation/rulevalidation_test.go rename to pkg/registry/rbac/validation/rule_test.go diff --git a/plugin/pkg/auth/authorizer/rbac/BUILD b/plugin/pkg/auth/authorizer/rbac/BUILD index 6f9caf25c8..45ac8441c2 100644 --- a/plugin/pkg/auth/authorizer/rbac/BUILD +++ b/plugin/pkg/auth/authorizer/rbac/BUILD @@ -17,7 +17,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/apis/rbac:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//vendor:github.com/golang/glog", "//vendor:k8s.io/apimachinery/pkg/util/errors", "//vendor:k8s.io/apiserver/pkg/authentication/user", @@ -36,7 +36,7 @@ go_test( deps = [ "//pkg/api:go_default_library", "//pkg/apis/rbac:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//vendor:k8s.io/apiserver/pkg/authentication/user", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer", ], diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD index 5f28e70024..3de0026db3 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD @@ -37,7 +37,7 @@ go_test( "//pkg/apis/rbac:go_default_library", "//pkg/apis/rbac/install:go_default_library", "//pkg/apis/rbac/v1alpha1:go_default_library", - "//pkg/apis/rbac/validation:go_default_library", + "//pkg/registry/rbac/validation:go_default_library", "//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library", "//vendor:github.com/ghodss/yaml", "//vendor:k8s.io/apimachinery/pkg/api/meta", diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go index b050fc2567..216069aa42 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go @@ -32,10 +32,10 @@ import ( "k8s.io/kubernetes/pkg/api" _ "k8s.io/kubernetes/pkg/api/install" "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" 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" ) @@ -67,13 +67,13 @@ func getSemanticRoles(roles []rbac.ClusterRole) semanticRoles { func TestCovers(t *testing.T) { 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) } - 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) } - 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) } } @@ -91,17 +91,17 @@ func TestAdminEditRelationship(t *testing.T) { // confirm that the edit role doesn't already have extra powers 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) } } semanticRoles.edit.Rules = append(semanticRoles.edit.Rules, additionalAdminPowers...) // 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) } - 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) } } @@ -136,17 +136,17 @@ func TestEditViewRelationship(t *testing.T) { // confirm that the view role doesn't already have extra powers 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) } } semanticRoles.view.Rules = append(semanticRoles.view.Rules, viewEscalatingNamespaceResources...) // 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) } - 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) } } diff --git a/plugin/pkg/auth/authorizer/rbac/rbac.go b/plugin/pkg/auth/authorizer/rbac/rbac.go index 3b07cda1fa..47a789da3a 100644 --- a/plugin/pkg/auth/authorizer/rbac/rbac.go +++ b/plugin/pkg/auth/authorizer/rbac/rbac.go @@ -24,7 +24,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apis/rbac/validation" + rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation" ) type RequestToRuleMapper interface { @@ -55,9 +55,9 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (boo 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{ - authorizationRuleResolver: validation.NewDefaultRuleResolver( + authorizationRuleResolver: rbacregistryvalidation.NewDefaultRuleResolver( roles, roleBindings, clusterRoles, clusterRoleBindings, ), } diff --git a/plugin/pkg/auth/authorizer/rbac/rbac_test.go b/plugin/pkg/auth/authorizer/rbac/rbac_test.go index 13b4d48b22..3cb1162246 100644 --- a/plugin/pkg/auth/authorizer/rbac/rbac_test.go +++ b/plugin/pkg/auth/authorizer/rbac/rbac_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/kubernetes/pkg/api" "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 { @@ -219,7 +219,7 @@ func TestAuthorizer(t *testing.T) { }, } 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} for _, attr := range tt.shouldPass { if authorized, _, _ := a.Authorize(attr); !authorized { diff --git a/plugin/pkg/auth/authorizer/rbac/subject_locator.go b/plugin/pkg/auth/authorizer/rbac/subject_locator.go index 77bc3460e5..eb0be95cc7 100644 --- a/plugin/pkg/auth/authorizer/rbac/subject_locator.go +++ b/plugin/pkg/auth/authorizer/rbac/subject_locator.go @@ -22,7 +22,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/apis/rbac/validation" + rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation" ) type RoleToRuleMapper interface { @@ -34,17 +34,17 @@ type RoleToRuleMapper interface { type SubjectAccessEvaluator struct { superUser string - roleBindingLister validation.RoleBindingLister - clusterRoleBindingLister validation.ClusterRoleBindingLister + roleBindingLister rbacregistryvalidation.RoleBindingLister + clusterRoleBindingLister rbacregistryvalidation.ClusterRoleBindingLister 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{ superUser: superUser, roleBindingLister: roleBindings, clusterRoleBindingLister: clusterRoleBindings, - roleToRuleMapper: validation.NewDefaultRuleResolver( + roleToRuleMapper: rbacregistryvalidation.NewDefaultRuleResolver( roles, roleBindings, clusterRoles, clusterRoleBindings, ), } diff --git a/plugin/pkg/auth/authorizer/rbac/subject_locator_test.go b/plugin/pkg/auth/authorizer/rbac/subject_locator_test.go index c8e810f99d..f0d85aa641 100644 --- a/plugin/pkg/auth/authorizer/rbac/subject_locator_test.go +++ b/plugin/pkg/auth/authorizer/rbac/subject_locator_test.go @@ -23,7 +23,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "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) { @@ -136,7 +136,7 @@ func TestSubjectLocator(t *testing.T) { }, } 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} for i, action := range tt.actionsToSubjects { actualSubjects, err := a.AllowedSubjects(action.action)