Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch RBAC subject apiVersion to apiGroup in v1beta1 #41184

Merged
merged 2 commits into from
Feb 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions api/openapi-spec/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -42724,7 +42724,7 @@
],
"properties": {
"apiVersion": {
"description": "APIVersion holds the API group and version of the referenced object.",
"description": "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects.",
"type": "string"
},
"kind": {
Expand Down Expand Up @@ -43095,8 +43095,8 @@
"name"
],
"properties": {
"apiVersion": {
"description": "APIVersion holds the API group and version of the referenced object.",
"apiGroup": {
"description": "APIGroup holds the API group of the referenced subject. Defaults to \"\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io\" for User and Group subjects.",
"type": "string"
},
"kind": {
Expand Down
2 changes: 1 addition & 1 deletion api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2924,7 +2924,7 @@
},
"apiVersion": {
"type": "string",
"description": "APIVersion holds the API group and version of the referenced object."
"description": "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects."
},
"name": {
"type": "string",
Expand Down
4 changes: 2 additions & 2 deletions api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2922,9 +2922,9 @@
"type": "string",
"description": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error."
},
"apiVersion": {
"apiGroup": {
"type": "string",
"description": "APIVersion holds the API group and version of the referenced object."
"description": "APIGroup holds the API group of the referenced subject. Defaults to \"\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io\" for User and Group subjects."
},
"name": {
"type": "string",
Expand Down
2 changes: 1 addition & 1 deletion cluster/addons/rbac/apiserver-node-proxy-binding.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ roleRef:
kind: ClusterRole
name: node-proxy
subjects:
- apiVersion: rbac/v1beta1
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kube-apiserver
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ <h3 id="_v1alpha1_subject">v1alpha1.Subject</h3>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">apiVersion</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion holds the API group and version of the referenced object.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion holds the API group and version of the referenced subject. Defaults to "v1" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io/v1alpha1" for User and Group subjects.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
Expand Down Expand Up @@ -1737,7 +1737,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-01-25 20:39:16 UTC
Last updated 2017-02-13 18:31:15 UTC
</div>
</div>
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1302,8 +1302,8 @@ <h3 id="_v1beta1_subject">v1beta1.Subject</h3>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">apiVersion</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion holds the API group and version of the referenced object.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apiGroup</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
Expand Down Expand Up @@ -1737,7 +1737,7 @@ <h3 id="_any">any</h3>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-01-25 20:39:12 UTC
Last updated 2017-02-13 18:31:09 UTC
</div>
</div>
</body>
Expand Down
8 changes: 4 additions & 4 deletions federation/pkg/kubefed/init/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -718,10 +718,10 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
},
Subjects: []rbacv1beta1.Subject{
{
Kind: "ServiceAccount",
APIVersion: "",
Name: "federation-controller-manager",
Namespace: "federation-system",
Kind: "ServiceAccount",
APIGroup: "",
Name: "federation-controller-manager",
Namespace: "federation-system",
},
},
RoleRef: rbacv1beta1.RoleRef{
Expand Down
17 changes: 17 additions & 0 deletions pkg/api/testing/fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,23 @@ func rbacFuncs(t apitesting.TestingCommon) []interface{} {
r.APIGroup = rbac.GroupName
}
},
func(r *rbac.Subject, c fuzz.Continue) {
switch c.Int31n(3) {
case 0:
r.Kind = rbac.ServiceAccountKind
r.APIGroup = ""
c.FuzzNoCustom(&r.Name)
c.FuzzNoCustom(&r.Namespace)
case 1:
r.Kind = rbac.UserKind
r.APIGroup = rbac.GroupName
c.FuzzNoCustom(&r.Name)
case 2:
r.Kind = rbac.GroupKind
r.APIGroup = rbac.GroupName
c.FuzzNoCustom(&r.Name)
}
},
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/rbac/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,14 @@ func NewClusterBinding(clusterRoleName string) *ClusterRoleBindingBuilder {

func (r *ClusterRoleBindingBuilder) Groups(groups ...string) *ClusterRoleBindingBuilder {
for _, group := range groups {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: GroupKind, Name: group})
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: GroupKind, APIGroup: GroupName, Name: group})
}
return r
}

func (r *ClusterRoleBindingBuilder) Users(users ...string) *ClusterRoleBindingBuilder {
for _, user := range users {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: UserKind, Name: user})
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: UserKind, APIGroup: GroupName, Name: user})
}
return r
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/apis/rbac/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string
// APIVersion holds the API group and version of the referenced object. For non-object references such as "Group" and "User" this is
// expected to be API version of this API group. For example, "rbac/v1alpha1".
APIVersion string
// APIGroup holds the API group of the referenced subject.
// Defaults to "" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
APIGroup string
// Name of the object being referenced.
Name string
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty
Expand Down
41 changes: 40 additions & 1 deletion pkg/apis/rbac/v1alpha1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1alpha1

import (
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime/schema"
api "k8s.io/kubernetes/pkg/apis/rbac"
)

Expand All @@ -30,13 +31,51 @@ func Convert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *api.Subject, s c
return err
}

// specifically set the APIGroup for the three subjects recognized in v1alpha1
switch {
case in.Kind == ServiceAccountKind:
out.APIGroup = ""
case in.Kind == UserKind:
out.APIGroup = GroupName
case in.Kind == GroupKind:
out.APIGroup = GroupName
default:
// For unrecognized kinds, use the group portion of the APIVersion if we can get it
if gv, err := schema.ParseGroupVersion(in.APIVersion); err == nil {
out.APIGroup = gv.Group
}
}

// 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 == "*" {
if out.Kind == UserKind && out.APIGroup == GroupName && out.Name == "*" {
out.Kind = GroupKind
out.Name = allAuthenticated
}

return nil
}

func Convert_rbac_Subject_To_v1alpha1_Subject(in *api.Subject, out *Subject, s conversion.Scope) error {
if err := autoConvert_rbac_Subject_To_v1alpha1_Subject(in, out, s); err != nil {
return err
}

switch {
case in.Kind == ServiceAccountKind && in.APIGroup == "":
// Make service accounts v1
out.APIVersion = "v1"
case in.Kind == UserKind && in.APIGroup == GroupName:
// users in the rbac API group get v1alpha
out.APIVersion = SchemeGroupVersion.String()
case in.Kind == GroupKind && in.APIGroup == GroupName:
// groups in the rbac API group get v1alpha
out.APIVersion = SchemeGroupVersion.String()
default:
// otherwise, they get an unspecified version of a group
out.APIVersion = schema.GroupVersion{Group: in.APIGroup}.String()
}

return nil
}
50 changes: 46 additions & 4 deletions pkg/apis/rbac/v1alpha1/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,63 @@ func TestConversion(t *testing.T) {
"specific user": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{{Kind: "User", Name: "bob"}},
Subjects: []v1alpha1.Subject{{Kind: "User", APIVersion: v1alpha1.SchemeGroupVersion.String(), Name: "bob"}},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{{Kind: "User", Name: "bob"}},
Subjects: []rbacapi.Subject{{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "bob"}},
},
},
"wildcard user matches authenticated": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{{Kind: "User", Name: "*"}},
Subjects: []v1alpha1.Subject{{Kind: "User", APIVersion: v1alpha1.SchemeGroupVersion.String(), Name: "*"}},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{{Kind: "Group", Name: "system:authenticated"}},
Subjects: []rbacapi.Subject{{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "system:authenticated"}},
},
},
"missing api group gets defaulted": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{
{Kind: "User", Name: "myuser"},
{Kind: "Group", Name: "mygroup"},
{Kind: "ServiceAccount", Name: "mysa", Namespace: "myns"},
},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{
{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "myuser"},
{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "mygroup"},
{Kind: "ServiceAccount", APIGroup: "", Name: "mysa", Namespace: "myns"},
},
},
},
"bad api group gets defaulted": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{
{Kind: "User", APIVersion: "rbac", Name: "myuser"},
{Kind: "Group", APIVersion: "rbac", Name: "mygroup"},
{Kind: "ServiceAccount", APIVersion: "rbac", Name: "mysa", Namespace: "myns"},
{Kind: "User", APIVersion: "rbac/v8", Name: "myuser"},
{Kind: "Group", APIVersion: "rbac/v8", Name: "mygroup"},
{Kind: "ServiceAccount", APIVersion: "rbac/v8", Name: "mysa", Namespace: "myns"},
},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{
{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "myuser"},
{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "mygroup"},
{Kind: "ServiceAccount", APIGroup: "", Name: "mysa", Namespace: "myns"},
{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "myuser"},
{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "mygroup"},
{Kind: "ServiceAccount", APIGroup: "", Name: "mysa", Namespace: "myns"},
},
},
},
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/apis/rbac/v1alpha1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
return scheme.AddDefaultingFuncs(
SetDefaults_ClusterRoleBinding,
SetDefaults_RoleBinding,
SetDefaults_Subject,
)
}

Expand All @@ -38,3 +39,15 @@ func SetDefaults_RoleBinding(obj *RoleBinding) {
obj.RoleRef.APIGroup = GroupName
}
}
func SetDefaults_Subject(obj *Subject) {
if len(obj.APIVersion) == 0 {
switch obj.Kind {
case ServiceAccountKind:
obj.APIVersion = "v1"
case UserKind:
obj.APIVersion = SchemeGroupVersion.String()
case GroupKind:
obj.APIVersion = SchemeGroupVersion.String()
}
}
}
5 changes: 4 additions & 1 deletion pkg/apis/rbac/v1alpha1/generated.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion pkg/apis/rbac/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// APIVersion holds the API group and version of the referenced object.
// APIVersion holds the API group and version of the referenced subject.
// Defaults to "v1" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io/v1alpha1" for User and Group subjects.
// +k8s:conversion-gen=false
// +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt.name=apiVersion"`
// Name of the object being referenced.
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/rbac/v1alpha1/types_swagger_doc_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (RoleRef) SwaggerDoc() map[string]string {
var map_Subject = map[string]string{
"": "Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names.",
"kind": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error.",
"apiVersion": "APIVersion holds the API group and version of the referenced object.",
"apiVersion": "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects.",
"name": "Name of the object being referenced.",
"namespace": "Namespace of the referenced object. If the object kind is non-namespace, such as \"User\" or \"Group\", and this value is not empty the Authorizer should report an error.",
}
Expand Down
8 changes: 2 additions & 6 deletions pkg/apis/rbac/v1alpha1/zz_generated.conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,20 +410,16 @@ func Convert_rbac_RoleRef_To_v1alpha1_RoleRef(in *rbac.RoleRef, out *RoleRef, s

func autoConvert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
// INFO: in.APIVersion opted out of conversion generation
out.Name = in.Name
out.Namespace = in.Namespace
return nil
}

func autoConvert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
// WARNING: in.APIGroup requires manual conversion: does not exist in peer-type
out.Name = in.Name
out.Namespace = in.Namespace
return nil
}

func Convert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
return autoConvert_rbac_Subject_To_v1alpha1_Subject(in, out, s)
}
8 changes: 8 additions & 0 deletions pkg/apis/rbac/v1alpha1/zz_generated.defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func RegisterDefaults(scheme *runtime.Scheme) error {

func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) {
SetDefaults_ClusterRoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
}

func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
Expand All @@ -48,6 +52,10 @@ func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {

func SetObjectDefaults_RoleBinding(in *RoleBinding) {
SetDefaults_RoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
}

func SetObjectDefaults_RoleBindingList(in *RoleBindingList) {
Expand Down