Deprecate RBAC UserAll, convert v1alpha1 User * rolebindings to Group system:authenticated

This commit is contained in:
Jordan Liggitt 2017-01-04 17:11:16 -05:00
parent 6b70211568
commit b8c2ad6d42
No known key found for this signature in database
GPG Key ID: 24E7ADF9A3B42012
10 changed files with 230 additions and 18 deletions

View File

@ -94,6 +94,7 @@ pkg/apis/imagepolicy/install
pkg/apis/meta/v1/unstructured
pkg/apis/policy/install
pkg/apis/rbac/install
pkg/apis/rbac/v1alpha1
pkg/apis/storage/install
pkg/apis/storage/validation
pkg/auth/authenticator

View File

@ -36,8 +36,6 @@ const (
GroupKind = "Group"
ServiceAccountKind = "ServiceAccount"
UserKind = "User"
UserAll = "*"
)
// PolicyRule holds information that describes a policy rule, but does not contain information

View File

@ -5,11 +5,13 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"conversion.go",
"defaults.go",
"doc.go",
"generated.pb.go",
@ -34,5 +36,18 @@ go_library(
"//pkg/watch/versioned:go_default_library",
"//vendor:github.com/gogo/protobuf/proto",
"//vendor:github.com/ugorji/go/codec",
"//vendor:k8s.io/apiserver/pkg/authentication/user",
],
)
go_test(
name = "go_default_xtest",
srcs = ["conversion_test.go"],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/rbac/install:go_default_library",
"//pkg/apis/rbac/v1alpha1:go_default_library",
],
)

View File

@ -0,0 +1,39 @@
/*
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 v1alpha1
import (
"k8s.io/apiserver/pkg/authentication/user"
api "k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/conversion"
)
func Convert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *api.Subject, s conversion.Scope) error {
if err := autoConvert_v1alpha1_Subject_To_rbac_Subject(in, out, s); err != nil {
return err
}
// User * in v1alpha1 will only match all authenticated users
// This is only for compatibility with old RBAC bindings
// Special treatment for * should not be included in v1beta1
if out.Kind == UserKind && out.Name == "*" {
out.Kind = GroupKind
out.Name = user.AllAuthenticated
}
return nil
}

View File

@ -0,0 +1,64 @@
/*
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 v1alpha1_test
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
rbacapi "k8s.io/kubernetes/pkg/apis/rbac"
_ "k8s.io/kubernetes/pkg/apis/rbac/install"
"k8s.io/kubernetes/pkg/apis/rbac/v1alpha1"
)
func TestConversion(t *testing.T) {
testcases := map[string]struct {
old *v1alpha1.RoleBinding
expected *rbacapi.RoleBinding
}{
"specific user": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{{Kind: "User", Name: "bob"}},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{{Kind: "User", Name: "bob"}},
},
},
"wildcard user matches authenticated": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{{Kind: "User", Name: "*"}},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{{Kind: "Group", Name: "system:authenticated"}},
},
},
}
for k, tc := range testcases {
internal := &rbacapi.RoleBinding{}
if err := api.Scheme.Convert(tc.old, internal, nil); err != nil {
t.Errorf("%s: unexpected error: %v", k, err)
}
if !reflect.DeepEqual(internal, tc.expected) {
t.Errorf("%s: expected\n\t%#v, got \n\t%#v", k, tc.expected, internal)
}
}
}

View File

@ -36,8 +36,6 @@ const (
GroupKind = "Group"
ServiceAccountKind = "ServiceAccount"
UserKind = "User"
UserAll = "*"
)
// Authorization is calculated against

View File

@ -115,7 +115,17 @@ func autoConvert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding(in *Clus
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]rbac.Subject)(unsafe.Pointer(&in.Subjects))
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]rbac.Subject, len(*in))
for i := range *in {
if err := Convert_v1alpha1_Subject_To_rbac_Subject(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Subjects = nil
}
if err := Convert_v1alpha1_RoleRef_To_rbac_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
@ -131,7 +141,17 @@ func autoConvert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(in *rbac
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]Subject)(unsafe.Pointer(&in.Subjects))
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]Subject, len(*in))
for i := range *in {
if err := Convert_rbac_Subject_To_v1alpha1_Subject(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Subjects = nil
}
if err := Convert_rbac_RoleRef_To_v1alpha1_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
@ -166,7 +186,17 @@ func Convert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilde
func autoConvert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList(in *ClusterRoleBindingList, out *rbac.ClusterRoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]rbac.ClusterRoleBinding)(unsafe.Pointer(&in.Items))
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]rbac.ClusterRoleBinding, len(*in))
for i := range *in {
if err := Convert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
@ -176,7 +206,17 @@ func Convert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList(in *
func autoConvert_rbac_ClusterRoleBindingList_To_v1alpha1_ClusterRoleBindingList(in *rbac.ClusterRoleBindingList, out *ClusterRoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]ClusterRoleBinding)(unsafe.Pointer(&in.Items))
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterRoleBinding, len(*in))
for i := range *in {
if err := Convert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
@ -329,7 +369,17 @@ func autoConvert_v1alpha1_RoleBinding_To_rbac_RoleBinding(in *RoleBinding, out *
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]rbac.Subject)(unsafe.Pointer(&in.Subjects))
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]rbac.Subject, len(*in))
for i := range *in {
if err := Convert_v1alpha1_Subject_To_rbac_Subject(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Subjects = nil
}
if err := Convert_v1alpha1_RoleRef_To_rbac_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
@ -345,7 +395,17 @@ func autoConvert_rbac_RoleBinding_To_v1alpha1_RoleBinding(in *rbac.RoleBinding,
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]Subject)(unsafe.Pointer(&in.Subjects))
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]Subject, len(*in))
for i := range *in {
if err := Convert_rbac_Subject_To_v1alpha1_Subject(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Subjects = nil
}
if err := Convert_rbac_RoleRef_To_v1alpha1_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
@ -358,7 +418,17 @@ func Convert_rbac_RoleBinding_To_v1alpha1_RoleBinding(in *rbac.RoleBinding, out
func autoConvert_v1alpha1_RoleBindingList_To_rbac_RoleBindingList(in *RoleBindingList, out *rbac.RoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]rbac.RoleBinding)(unsafe.Pointer(&in.Items))
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]rbac.RoleBinding, len(*in))
for i := range *in {
if err := Convert_v1alpha1_RoleBinding_To_rbac_RoleBinding(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
@ -368,7 +438,17 @@ func Convert_v1alpha1_RoleBindingList_To_rbac_RoleBindingList(in *RoleBindingLis
func autoConvert_rbac_RoleBindingList_To_v1alpha1_RoleBindingList(in *rbac.RoleBindingList, out *RoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]RoleBinding)(unsafe.Pointer(&in.Items))
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]RoleBinding, len(*in))
for i := range *in {
if err := Convert_rbac_RoleBinding_To_v1alpha1_RoleBinding(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
@ -446,10 +526,6 @@ func autoConvert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject
return nil
}
func Convert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
return autoConvert_v1alpha1_Subject_To_rbac_Subject(in, out, s)
}
func autoConvert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion

View File

@ -168,7 +168,7 @@ func appliesTo(user user.Info, bindingSubjects []rbac.Subject, namespace string)
func appliesToUser(user user.Info, subject rbac.Subject, namespace string) bool {
switch subject.Kind {
case rbac.UserKind:
return subject.Name == rbac.UserAll || user.GetName() == subject.Name
return user.GetName() == subject.Name
case rbac.GroupKind:
return has(user.GetGroups(), subject.Name)

View File

@ -232,8 +232,28 @@ func TestAppliesTo(t *testing.T) {
},
user: &user.DefaultInfo{Name: "foobar"},
namespace: "default",
appliesTo: false,
testCase: "* user subject name doesn't match all users",
},
{
subjects: []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.AllAuthenticated},
{Kind: rbac.GroupKind, Name: user.AllUnauthenticated},
},
user: &user.DefaultInfo{Name: "foobar", Groups: []string{user.AllAuthenticated}},
namespace: "default",
appliesTo: true,
testCase: "multiple subjects with a service account that matches",
testCase: "binding to all authenticated and unauthenticated subjects matches authenticated user",
},
{
subjects: []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.AllAuthenticated},
{Kind: rbac.GroupKind, Name: user.AllUnauthenticated},
},
user: &user.DefaultInfo{Name: "system:anonymous", Groups: []string{user.AllUnauthenticated}},
namespace: "default",
appliesTo: true,
testCase: "binding to all authenticated and unauthenticated subjects matches anonymous user",
},
}

View File

@ -585,6 +585,7 @@ k8s.io/kubernetes/pkg/apis/meta/v1,sttts,0
k8s.io/kubernetes/pkg/apis/meta/v1/unstructured,smarterclayton,0
k8s.io/kubernetes/pkg/apis/meta/v1/validation,smarterclayton,0
k8s.io/kubernetes/pkg/apis/policy/validation,deads2k,1
k8s.io/kubernetes/pkg/apis/rbac/v1alpha1,liggitt,0
k8s.io/kubernetes/pkg/apis/rbac/validation,erictune,0
k8s.io/kubernetes/pkg/apis/storage/validation,caesarxuchao,1
k8s.io/kubernetes/pkg/genericapiserver/api,nikhiljindal,0

1 name owner auto-assigned
585 k8s.io/kubernetes/pkg/apis/meta/v1/unstructured smarterclayton 0
586 k8s.io/kubernetes/pkg/apis/meta/v1/validation smarterclayton 0
587 k8s.io/kubernetes/pkg/apis/policy/validation deads2k 1
588 k8s.io/kubernetes/pkg/apis/rbac/v1alpha1 liggitt 0
589 k8s.io/kubernetes/pkg/apis/rbac/validation erictune 0
590 k8s.io/kubernetes/pkg/apis/storage/validation caesarxuchao 1
591 k8s.io/kubernetes/pkg/genericapiserver/api nikhiljindal 0