Merge pull request #41184 from liggitt/subject-apigroup

Automatic merge from submit-queue (batch tested with PRs 41357, 41178, 41280, 41184, 41278)

Switch RBAC subject apiVersion to apiGroup in v1beta1

Referencing a subject from an RBAC role binding, the API group and kind of the subject is needed to fully-qualify the reference.

The version is not, and adds complexity around re-writing the reference when returning the binding from different versions of the API, and when reconciling subjects.

This PR:
* v1beta1: change the subject `apiVersion` field to `apiGroup` (to match roleRef)
* v1alpha1: convert apiVersion to apiGroup for backwards compatibility
* all versions: add defaulting for the three allowed subject kinds
* all versions: add validation to the field so we can count on the data in etcd being good until we decide to relax the apiGroup restriction

```release-note
RBAC `v1beta1` RoleBinding/ClusterRoleBinding subjects changed `apiVersion` to `apiGroup` to fully-qualify a subject. ServiceAccount subjects default to an apiGroup of `""`, User and Group subjects default to an apiGroup of `"rbac.authorization.k8s.io"`.
```

@deads2k @kubernetes/sig-auth-api-reviews @kubernetes/sig-auth-pr-reviews
This commit is contained in:
Kubernetes Submit Queue 2017-02-13 21:07:10 -08:00 committed by GitHub
commit 1f4e2efc5b
36 changed files with 356 additions and 173 deletions

View File

@ -42731,7 +42731,7 @@
], ],
"properties": { "properties": {
"apiVersion": { "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" "type": "string"
}, },
"kind": { "kind": {
@ -43102,8 +43102,8 @@
"name" "name"
], ],
"properties": { "properties": {
"apiVersion": { "apiGroup": {
"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.",
"type": "string" "type": "string"
}, },
"kind": { "kind": {

View File

@ -2924,7 +2924,7 @@
}, },
"apiVersion": { "apiVersion": {
"type": "string", "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": { "name": {
"type": "string", "type": "string",

View File

@ -2922,9 +2922,9 @@
"type": "string", "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." "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", "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": { "name": {
"type": "string", "type": "string",

View File

@ -9,6 +9,6 @@ roleRef:
kind: ClusterRole kind: ClusterRole
name: node-proxy name: node-proxy
subjects: subjects:
- apiVersion: rbac/v1beta1 - apiGroup: rbac.authorization.k8s.io
kind: User kind: User
name: kube-apiserver name: kube-apiserver

View File

@ -802,7 +802,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</tr> </tr>
<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</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">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
@ -1737,7 +1737,7 @@ Examples:<br>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-01-25 20:39:16 UTC Last updated 2017-02-13 18:31:15 UTC
</div> </div>
</div> </div>
</body> </body>

View File

@ -1302,8 +1302,8 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<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">apiGroup</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 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">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
@ -1737,7 +1737,7 @@ Examples:<br>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-01-25 20:39:12 UTC Last updated 2017-02-13 18:31:09 UTC
</div> </div>
</div> </div>
</body> </body>

View File

@ -718,10 +718,10 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
}, },
Subjects: []rbacv1beta1.Subject{ Subjects: []rbacv1beta1.Subject{
{ {
Kind: "ServiceAccount", Kind: "ServiceAccount",
APIVersion: "", APIGroup: "",
Name: "federation-controller-manager", Name: "federation-controller-manager",
Namespace: "federation-system", Namespace: "federation-system",
}, },
}, },
RoleRef: rbacv1beta1.RoleRef{ RoleRef: rbacv1beta1.RoleRef{

View File

@ -590,6 +590,23 @@ func rbacFuncs(t apitesting.TestingCommon) []interface{} {
r.APIGroup = rbac.GroupName 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)
}
},
} }
} }

View File

@ -220,14 +220,14 @@ func NewClusterBinding(clusterRoleName string) *ClusterRoleBindingBuilder {
func (r *ClusterRoleBindingBuilder) Groups(groups ...string) *ClusterRoleBindingBuilder { func (r *ClusterRoleBindingBuilder) Groups(groups ...string) *ClusterRoleBindingBuilder {
for _, group := range groups { 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 return r
} }
func (r *ClusterRoleBindingBuilder) Users(users ...string) *ClusterRoleBindingBuilder { func (r *ClusterRoleBindingBuilder) Users(users ...string) *ClusterRoleBindingBuilder {
for _, user := range users { 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 return r
} }

View File

@ -63,9 +63,10 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // 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. // If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string Kind string
// APIVersion holds the API group and version of the referenced object. For non-object references such as "Group" and "User" this is // APIGroup holds the API group of the referenced subject.
// expected to be API version of this API group. For example, "rbac/v1alpha1". // Defaults to "" for ServiceAccount subjects.
APIVersion string // Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
APIGroup string
// Name of the object being referenced. // Name of the object being referenced.
Name string 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 // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty

View File

@ -18,6 +18,7 @@ package v1alpha1
import ( import (
"k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime/schema"
api "k8s.io/kubernetes/pkg/apis/rbac" api "k8s.io/kubernetes/pkg/apis/rbac"
) )
@ -30,13 +31,51 @@ func Convert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *api.Subject, s c
return err 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 // User * in v1alpha1 will only match all authenticated users
// This is only for compatibility with old RBAC bindings // This is only for compatibility with old RBAC bindings
// Special treatment for * should not be included in v1beta1 // 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.Kind = GroupKind
out.Name = allAuthenticated out.Name = allAuthenticated
} }
return nil 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
}

View File

@ -34,21 +34,63 @@ func TestConversion(t *testing.T) {
"specific user": { "specific user": {
old: &v1alpha1.RoleBinding{ old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName}, 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{ expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName}, 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": { "wildcard user matches authenticated": {
old: &v1alpha1.RoleBinding{ old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName}, 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{ expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName}, 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"},
},
}, },
}, },
} }

View File

@ -25,6 +25,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
return scheme.AddDefaultingFuncs( return scheme.AddDefaultingFuncs(
SetDefaults_ClusterRoleBinding, SetDefaults_ClusterRoleBinding,
SetDefaults_RoleBinding, SetDefaults_RoleBinding,
SetDefaults_Subject,
) )
} }
@ -38,3 +39,15 @@ func SetDefaults_RoleBinding(obj *RoleBinding) {
obj.RoleRef.APIGroup = GroupName 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()
}
}
}

View File

@ -184,7 +184,10 @@ message Subject {
// If the Authorizer does not recognized the kind value, the Authorizer should report an error. // If the Authorizer does not recognized the kind value, the Authorizer should report an error.
optional string kind = 1; optional string kind = 1;
// 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 // +optional
optional string apiVersion = 2; optional string apiVersion = 2;

View File

@ -72,7 +72,10 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // 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. // 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"` 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 // +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt.name=apiVersion"` APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt.name=apiVersion"`
// Name of the object being referenced. // Name of the object being referenced.

View File

@ -136,7 +136,7 @@ func (RoleRef) SwaggerDoc() map[string]string {
var map_Subject = 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.", "": "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.", "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.", "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.", "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.",
} }

View File

@ -410,7 +410,7 @@ 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 { func autoConvert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
out.Kind = in.Kind out.Kind = in.Kind
out.APIVersion = in.APIVersion // INFO: in.APIVersion opted out of conversion generation
out.Name = in.Name out.Name = in.Name
out.Namespace = in.Namespace out.Namespace = in.Namespace
return nil return nil
@ -418,12 +418,8 @@ func autoConvert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject
func autoConvert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error { func autoConvert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
out.Kind = in.Kind 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.Name = in.Name
out.Namespace = in.Namespace out.Namespace = in.Namespace
return nil 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)
}

View File

@ -37,6 +37,10 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) { func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) {
SetDefaults_ClusterRoleBinding(in) SetDefaults_ClusterRoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
} }
func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) { func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
@ -48,6 +52,10 @@ func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
func SetObjectDefaults_RoleBinding(in *RoleBinding) { func SetObjectDefaults_RoleBinding(in *RoleBinding) {
SetDefaults_RoleBinding(in) SetDefaults_RoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
} }
func SetObjectDefaults_RoleBindingList(in *RoleBindingList) { func SetObjectDefaults_RoleBindingList(in *RoleBindingList) {

View File

@ -25,6 +25,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
return scheme.AddDefaultingFuncs( return scheme.AddDefaultingFuncs(
SetDefaults_ClusterRoleBinding, SetDefaults_ClusterRoleBinding,
SetDefaults_RoleBinding, SetDefaults_RoleBinding,
SetDefaults_Subject,
) )
} }
@ -38,3 +39,15 @@ func SetDefaults_RoleBinding(obj *RoleBinding) {
obj.RoleRef.APIGroup = GroupName obj.RoleRef.APIGroup = GroupName
} }
} }
func SetDefaults_Subject(obj *Subject) {
if len(obj.APIGroup) == 0 {
switch obj.Kind {
case ServiceAccountKind:
obj.APIGroup = ""
case UserKind:
obj.APIGroup = GroupName
case GroupKind:
obj.APIGroup = GroupName
}
}
}

View File

@ -644,8 +644,8 @@ func (m *Subject) MarshalTo(data []byte) (int, error) {
i += copy(data[i:], m.Kind) i += copy(data[i:], m.Kind)
data[i] = 0x12 data[i] = 0x12
i++ i++
i = encodeVarintGenerated(data, i, uint64(len(m.APIVersion))) i = encodeVarintGenerated(data, i, uint64(len(m.APIGroup)))
i += copy(data[i:], m.APIVersion) i += copy(data[i:], m.APIGroup)
data[i] = 0x1a data[i] = 0x1a
i++ i++
i = encodeVarintGenerated(data, i, uint64(len(m.Name))) i = encodeVarintGenerated(data, i, uint64(len(m.Name)))
@ -869,7 +869,7 @@ func (m *Subject) Size() (n int) {
_ = l _ = l
l = len(m.Kind) l = len(m.Kind)
n += 1 + l + sovGenerated(uint64(l)) n += 1 + l + sovGenerated(uint64(l))
l = len(m.APIVersion) l = len(m.APIGroup)
n += 1 + l + sovGenerated(uint64(l)) n += 1 + l + sovGenerated(uint64(l))
l = len(m.Name) l = len(m.Name)
n += 1 + l + sovGenerated(uint64(l)) n += 1 + l + sovGenerated(uint64(l))
@ -1033,7 +1033,7 @@ func (this *Subject) String() string {
} }
s := strings.Join([]string{`&Subject{`, s := strings.Join([]string{`&Subject{`,
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
`APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, `APIGroup:` + fmt.Sprintf("%v", this.APIGroup) + `,`,
`Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
`Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`,
`}`, `}`,
@ -2548,7 +2548,7 @@ func (m *Subject) Unmarshal(data []byte) error {
iNdEx = postIndex iNdEx = postIndex
case 2: case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field APIVersion", wireType) return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType)
} }
var stringLen uint64 var stringLen uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -2573,7 +2573,7 @@ func (m *Subject) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.APIVersion = string(data[iNdEx:postIndex]) m.APIGroup = string(data[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 3: case 3:
if wireType != 2 { if wireType != 2 {
@ -2760,58 +2760,57 @@ var (
) )
var fileDescriptorGenerated = []byte{ var fileDescriptorGenerated = []byte{
// 845 bytes of a gzipped FileDescriptorProto // 830 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x54, 0x4d, 0x6f, 0x23, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x54, 0xbf, 0x8f, 0xe3, 0x44,
0x10, 0x75, 0x27, 0xb6, 0x62, 0x57, 0x88, 0x42, 0x1a, 0x09, 0x0d, 0x39, 0xd8, 0x91, 0x2f, 0x04, 0x14, 0xce, 0x64, 0x13, 0x6d, 0x3c, 0xcb, 0x2a, 0xec, 0x20, 0x21, 0x93, 0xc2, 0x89, 0xdc, 0xb0,
0xb1, 0x3b, 0xb3, 0xc9, 0xae, 0x58, 0x24, 0xc4, 0x61, 0x87, 0x03, 0x8a, 0x58, 0x42, 0xd4, 0x88, 0x88, 0x3b, 0xfb, 0xf6, 0xee, 0xc4, 0x21, 0x21, 0x0a, 0x4c, 0x81, 0x4e, 0x1c, 0xcb, 0x69, 0x10,
0x15, 0x5f, 0x42, 0xdb, 0x1e, 0xd7, 0x3a, 0x8d, 0xe7, 0x4b, 0xdd, 0x3d, 0x16, 0x2b, 0x38, 0x70, 0x88, 0x5f, 0x42, 0x37, 0x71, 0xe6, 0xbc, 0x43, 0xfc, 0x4b, 0x33, 0xe3, 0x88, 0x13, 0x14, 0x74,
0xe3, 0xca, 0x9f, 0xe0, 0xc6, 0x09, 0xae, 0x9c, 0x38, 0x05, 0x4e, 0x7b, 0xcc, 0xc9, 0x22, 0xe6, 0xb4, 0xfc, 0x13, 0x74, 0xd7, 0xd1, 0x52, 0x51, 0x2d, 0x54, 0x57, 0x6e, 0x15, 0xb1, 0xe6, 0x0f,
0x87, 0x80, 0x66, 0xa6, 0xe7, 0xc3, 0xd8, 0x51, 0x4c, 0x90, 0x22, 0x21, 0xed, 0xc9, 0xee, 0xaa, 0x01, 0xd9, 0x1e, 0xff, 0x08, 0x4e, 0xd8, 0xb0, 0x48, 0x91, 0x90, 0xa8, 0x92, 0x79, 0xef, 0xfb,
0xf7, 0xaa, 0xeb, 0x55, 0xf5, 0x3c, 0xb8, 0x3f, 0x7e, 0x53, 0xd9, 0x22, 0x72, 0xc6, 0xc9, 0x00, 0xde, 0xbc, 0xef, 0xbd, 0xf1, 0x07, 0xef, 0xcd, 0x5f, 0x17, 0x16, 0x8b, 0xec, 0x79, 0x32, 0xa5,
0x65, 0x88, 0x1a, 0x95, 0x13, 0x8f, 0x47, 0x0e, 0x8f, 0x85, 0x72, 0xe4, 0x80, 0x7b, 0xce, 0xe4, 0x3c, 0xa4, 0x92, 0x0a, 0x3b, 0x9e, 0x7b, 0x36, 0x89, 0x99, 0xb0, 0xf9, 0x94, 0xb8, 0xf6, 0xe2,
0x60, 0x80, 0x9a, 0x1f, 0x38, 0x23, 0x0c, 0x51, 0x72, 0x8d, 0x43, 0x3b, 0x96, 0x91, 0x8e, 0xe8, 0x64, 0x4a, 0x25, 0x39, 0xb1, 0x3d, 0x1a, 0x52, 0x4e, 0x24, 0x9d, 0x59, 0x31, 0x8f, 0x64, 0x84,
0xab, 0x39, 0xd1, 0xae, 0x88, 0x76, 0x3c, 0x1e, 0xd9, 0x29, 0xd1, 0x4e, 0x89, 0xb6, 0x21, 0xee, 0x5e, 0x2e, 0x88, 0x56, 0x4d, 0xb4, 0xe2, 0xb9, 0x67, 0x65, 0x44, 0x2b, 0x23, 0x5a, 0x8a, 0x38,
0xde, 0x1e, 0x09, 0x7d, 0x9a, 0x0c, 0x6c, 0x2f, 0x0a, 0x9c, 0x51, 0x34, 0x8a, 0x9c, 0x8c, 0x3f, 0xba, 0xe9, 0x31, 0x79, 0x96, 0x4c, 0x2d, 0x37, 0x0a, 0x6c, 0x2f, 0xf2, 0x22, 0x3b, 0xe7, 0x4f,
0x48, 0x9e, 0x64, 0xa7, 0xec, 0x90, 0xfd, 0xcb, 0xeb, 0xee, 0xde, 0x33, 0x0d, 0xf1, 0x58, 0x04, 0x93, 0xc7, 0xf9, 0x29, 0x3f, 0xe4, 0xff, 0x8a, 0xba, 0xa3, 0xbb, 0xaa, 0x21, 0x12, 0xb3, 0x80,
0xdc, 0x3b, 0x15, 0x21, 0xca, 0xa7, 0x55, 0x4b, 0x01, 0x6a, 0xee, 0x4c, 0x16, 0xba, 0xd9, 0x75, 0xb8, 0x67, 0x2c, 0xa4, 0xfc, 0x49, 0xdd, 0x52, 0x40, 0x25, 0xb1, 0x17, 0xad, 0x6e, 0x46, 0xf6,
0x2e, 0x63, 0xc9, 0x24, 0xd4, 0x22, 0xc0, 0x05, 0xc2, 0x1b, 0x57, 0x11, 0x94, 0x77, 0x8a, 0x01, 0x26, 0x16, 0x4f, 0x42, 0xc9, 0x02, 0xda, 0x22, 0xbc, 0x76, 0x15, 0x41, 0xb8, 0x67, 0x34, 0x20,
0x5f, 0xe0, 0xdd, 0xbd, 0x8c, 0x97, 0x68, 0xe1, 0x3b, 0x22, 0xd4, 0x4a, 0xcb, 0x05, 0x52, 0x4d, 0x2d, 0xde, 0x9d, 0x4d, 0xbc, 0x44, 0x32, 0xdf, 0x66, 0xa1, 0x14, 0x92, 0xb7, 0x48, 0x0d, 0x4d,
0x93, 0x42, 0x39, 0x41, 0x59, 0x09, 0xc2, 0xaf, 0x78, 0x10, 0xfb, 0xb8, 0x4c, 0xd3, 0xad, 0x4b, 0x82, 0xf2, 0x05, 0xe5, 0xb5, 0x20, 0xfa, 0x15, 0x09, 0x62, 0x9f, 0xae, 0xd3, 0x74, 0x63, 0xe3,
0x57, 0xb3, 0x04, 0xdd, 0xff, 0x8d, 0xc0, 0xe6, 0x3b, 0x7e, 0xa2, 0x34, 0x4a, 0x16, 0xf9, 0x48, 0x6a, 0xd6, 0xa0, 0xcd, 0x5f, 0x00, 0x3c, 0x78, 0xdb, 0x4f, 0x84, 0xa4, 0x1c, 0x47, 0x3e, 0x45,
0x1f, 0x43, 0x3b, 0x1d, 0xd6, 0x90, 0x6b, 0x6e, 0x91, 0x3d, 0xb2, 0xbf, 0x79, 0x78, 0xc7, 0x36, 0x8f, 0xe0, 0x20, 0x1b, 0xd6, 0x8c, 0x48, 0xa2, 0x83, 0x09, 0x38, 0x3e, 0xb8, 0x7d, 0xcb, 0x52,
0x2b, 0xab, 0xf7, 0x5e, 0x2d, 0x2d, 0x45, 0xdb, 0x93, 0x03, 0xfb, 0x83, 0xc1, 0x97, 0xe8, 0xe9, 0x2b, 0x6b, 0xf6, 0x5e, 0x2f, 0x2d, 0x43, 0x5b, 0x8b, 0x13, 0xeb, 0xfd, 0xe9, 0x97, 0xd4, 0x95,
0xf7, 0x51, 0x73, 0x97, 0x9e, 0x4d, 0x7b, 0x8d, 0xd9, 0xb4, 0x07, 0x55, 0x8c, 0x95, 0x55, 0xe9, 0xef, 0x51, 0x49, 0x1c, 0x74, 0xbe, 0x1c, 0x77, 0xd2, 0xe5, 0x18, 0xd6, 0x31, 0x5c, 0x55, 0x45,
0xc7, 0xd0, 0x92, 0x89, 0x8f, 0xca, 0x5a, 0xdb, 0x5b, 0xdf, 0xdf, 0x3c, 0xbc, 0x6b, 0xaf, 0xf8, 0x1f, 0xc3, 0x3e, 0x4f, 0x7c, 0x2a, 0xf4, 0xee, 0x64, 0xef, 0xf8, 0xe0, 0xf6, 0x1d, 0x6b, 0xcb,
0x22, 0xec, 0x93, 0xc8, 0x17, 0xde, 0x53, 0x96, 0xf8, 0xe8, 0x6e, 0x99, 0x1b, 0x5a, 0xe9, 0x49, 0x17, 0x61, 0x3d, 0x8c, 0x7c, 0xe6, 0x3e, 0xc1, 0x89, 0x4f, 0x9d, 0x43, 0x75, 0x43, 0x3f, 0x3b,
0xb1, 0xbc, 0x60, 0xff, 0xe7, 0x35, 0xa0, 0x35, 0x2d, 0xae, 0x08, 0x87, 0x22, 0x1c, 0xdd, 0x80, 0x09, 0x5c, 0x14, 0x34, 0x7f, 0xec, 0x42, 0xd4, 0xd0, 0xe2, 0xb0, 0x70, 0xc6, 0x42, 0x6f, 0x07,
0xa4, 0x2f, 0xa0, 0xad, 0x92, 0x2c, 0x51, 0xa8, 0xba, 0xb3, 0xb2, 0xaa, 0x0f, 0x73, 0xa2, 0xfb, 0x92, 0xbe, 0x80, 0x03, 0x91, 0xe4, 0x89, 0x52, 0xd5, 0xad, 0xad, 0x55, 0x7d, 0x50, 0x10, 0x9d,
0xa2, 0xb9, 0xa1, 0x6d, 0x02, 0x8a, 0x95, 0x35, 0xe9, 0x67, 0xb0, 0x21, 0x23, 0x1f, 0x19, 0x3e, 0xe7, 0xd5, 0x0d, 0x03, 0x15, 0x10, 0xb8, 0xaa, 0x89, 0x3e, 0x83, 0xfb, 0x3c, 0xf2, 0x29, 0xa6,
0xb1, 0xd6, 0xe7, 0x05, 0x5c, 0x59, 0x9e, 0xe5, 0x3c, 0x77, 0xdb, 0x94, 0xdf, 0x30, 0x01, 0x56, 0x8f, 0xf5, 0xbd, 0x55, 0x01, 0x57, 0x96, 0xc7, 0x05, 0xcf, 0x19, 0xaa, 0xf2, 0xfb, 0x2a, 0x80,
0x54, 0xec, 0xff, 0x40, 0xe0, 0x95, 0xc5, 0xa9, 0xb9, 0x89, 0xf0, 0x87, 0x28, 0xe9, 0x77, 0x04, 0xcb, 0x8a, 0xe6, 0x0f, 0x00, 0xbe, 0xd4, 0x9e, 0x9a, 0x93, 0x30, 0x7f, 0x46, 0x39, 0xfa, 0x0e,
0xa8, 0xb7, 0x90, 0x35, 0x73, 0x7c, 0x6b, 0xe5, 0x36, 0x96, 0x5c, 0xb0, 0x6b, 0x3a, 0x5a, 0xb2, 0x40, 0xe4, 0xb6, 0xb2, 0x6a, 0x8e, 0x6f, 0x6c, 0xdd, 0xc6, 0x9a, 0x0b, 0x46, 0xaa, 0xa3, 0x35,
0x32, 0xb6, 0xe4, 0xca, 0xfe, 0x39, 0x81, 0x97, 0x17, 0xa1, 0x0f, 0x85, 0xd2, 0xf4, 0xf3, 0x85, 0x2b, 0xc3, 0x6b, 0xae, 0x34, 0x2f, 0x00, 0x7c, 0xb1, 0x0d, 0x7d, 0xc0, 0x84, 0x44, 0x9f, 0xb7,
0x0d, 0xdb, 0xab, 0x6d, 0x38, 0x65, 0x67, 0xfb, 0x2d, 0xa7, 0x5f, 0x44, 0x6a, 0xdb, 0x7d, 0x0c, 0x36, 0x6c, 0x6d, 0xb7, 0xe1, 0x8c, 0x9d, 0xef, 0xb7, 0x9a, 0x7e, 0x19, 0x69, 0x6c, 0xf7, 0x11,
0x2d, 0xa1, 0x31, 0x28, 0x56, 0xfb, 0x9f, 0x44, 0x97, 0x0f, 0xf7, 0x28, 0xad, 0xc8, 0xf2, 0xc2, 0xec, 0x33, 0x49, 0x83, 0x72, 0xb5, 0xff, 0x4a, 0x74, 0xf5, 0x70, 0xef, 0x67, 0x15, 0x71, 0x51,
0xfd, 0xdf, 0x09, 0x6c, 0xd7, 0xc0, 0x37, 0xa0, 0xe9, 0x93, 0x79, 0x4d, 0xf7, 0xae, 0xa5, 0x69, 0xd8, 0xfc, 0x15, 0xc0, 0x61, 0x03, 0xbc, 0x03, 0x4d, 0x9f, 0xac, 0x6a, 0xba, 0x7b, 0x2d, 0x4d,
0xb9, 0x98, 0xbf, 0x08, 0x40, 0xf5, 0xa9, 0xd2, 0x1e, 0xb4, 0x26, 0x28, 0x07, 0xca, 0x22, 0x7b, 0xeb, 0xc5, 0xfc, 0x01, 0x20, 0xac, 0x3f, 0x55, 0x34, 0x86, 0xfd, 0x05, 0xe5, 0x53, 0xa1, 0x83,
0xeb, 0xfb, 0x1d, 0xb7, 0x93, 0xe2, 0x1f, 0xa5, 0x01, 0x96, 0xc7, 0xe9, 0xeb, 0xd0, 0xe1, 0xb1, 0xc9, 0xde, 0xb1, 0xe6, 0x68, 0x19, 0xfe, 0xa3, 0x2c, 0x80, 0x8b, 0x38, 0x7a, 0x15, 0x6a, 0x24,
0x78, 0x57, 0x46, 0x49, 0x9c, 0xb7, 0xd3, 0x71, 0xb7, 0x66, 0xd3, 0x5e, 0xe7, 0xc1, 0xc9, 0x51, 0x66, 0xef, 0xf0, 0x28, 0x89, 0x8b, 0x76, 0x34, 0xe7, 0x30, 0x5d, 0x8e, 0xb5, 0xb7, 0x1e, 0xde,
0x1e, 0x64, 0x55, 0x3e, 0x05, 0x4b, 0x54, 0x51, 0x22, 0x3d, 0x54, 0xd6, 0x7a, 0x05, 0x66, 0x45, 0x2f, 0x82, 0xb8, 0xce, 0x67, 0x60, 0x4e, 0x45, 0x94, 0x70, 0x97, 0x0a, 0x7d, 0xaf, 0x06, 0xe3,
0x90, 0x55, 0x79, 0x7a, 0x1f, 0xb6, 0x8a, 0xc3, 0x31, 0x0f, 0x50, 0x59, 0xcd, 0x8c, 0xb0, 0x33, 0x32, 0x88, 0xeb, 0x3c, 0xba, 0x07, 0x0f, 0xcb, 0xc3, 0x29, 0x09, 0xa8, 0xd0, 0x7b, 0x39, 0xe1,
0x9b, 0xf6, 0xb6, 0x58, 0x3d, 0xc1, 0xe6, 0x71, 0xf4, 0x6d, 0xd8, 0x0e, 0xa3, 0xb0, 0x80, 0x7c, 0x28, 0x5d, 0x8e, 0x0f, 0x71, 0x33, 0x81, 0x57, 0x71, 0xe8, 0x4d, 0x38, 0x0c, 0xa3, 0xb0, 0x84,
0xc4, 0x1e, 0x2a, 0xab, 0x95, 0x51, 0x5f, 0x9a, 0x4d, 0x7b, 0xdb, 0xc7, 0xf3, 0x29, 0xf6, 0x4f, 0x7c, 0x88, 0x1f, 0x08, 0xbd, 0x9f, 0x53, 0x5f, 0x48, 0x97, 0xe3, 0xe1, 0xe9, 0x6a, 0x0a, 0xff,
0x6c, 0xff, 0x1b, 0xd8, 0xa9, 0x79, 0x95, 0xf9, 0x90, 0x46, 0x00, 0x71, 0x19, 0x34, 0x1b, 0xbd, 0x15, 0x6b, 0x7e, 0x03, 0x8f, 0x1a, 0x5e, 0xa5, 0x3e, 0x24, 0x0f, 0xc2, 0xb8, 0x0a, 0xaa, 0x8d,
0x96, 0xf7, 0x95, 0x56, 0x54, 0xc5, 0x58, 0xad, 0x74, 0xff, 0x57, 0x02, 0xcd, 0xff, 0xbd, 0x95, 0x5e, 0xcb, 0xfb, 0x2a, 0x2b, 0xaa, 0x63, 0xb8, 0x51, 0xda, 0xfc, 0x19, 0xc0, 0xde, 0x7f, 0xde,
0xff, 0xb8, 0x06, 0x9b, 0xcf, 0x3d, 0x7c, 0x65, 0x0f, 0x4f, 0x0d, 0xe4, 0x66, 0x4d, 0xf1, 0xda, 0xca, 0x9f, 0x76, 0xe1, 0xc1, 0xff, 0x1e, 0xbe, 0xb5, 0x87, 0x67, 0x06, 0xb2, 0x5b, 0x53, 0xbc,
0x06, 0x72, 0xb5, 0x1b, 0xfe, 0x42, 0xa0, 0x7d, 0x43, 0x36, 0xc8, 0xe6, 0x55, 0xdc, 0xfe, 0x77, 0xb6, 0x81, 0x5c, 0xed, 0x86, 0x3f, 0x01, 0x38, 0xd8, 0x91, 0x0d, 0xe2, 0x55, 0x15, 0x37, 0xff,
0x2a, 0x96, 0xb7, 0xff, 0x35, 0x14, 0xfb, 0xa1, 0xb7, 0xa0, 0x5d, 0x58, 0x57, 0xd6, 0x7c, 0xa7, 0x99, 0x8a, 0xf5, 0xed, 0x7f, 0x0d, 0xcb, 0xfd, 0xa0, 0x1b, 0x70, 0x50, 0x5a, 0x57, 0xde, 0xbc,
0x6a, 0xa6, 0x70, 0x37, 0x56, 0x22, 0xe8, 0x1e, 0x34, 0xc7, 0x22, 0x1c, 0x5a, 0x6b, 0x19, 0xf2, 0x56, 0x37, 0x53, 0xba, 0x1b, 0xae, 0x10, 0x68, 0x02, 0x7b, 0x73, 0x16, 0xce, 0xf4, 0x6e, 0x8e,
0x05, 0x83, 0x6c, 0xbe, 0x27, 0xc2, 0x21, 0xcb, 0x32, 0x29, 0x22, 0xe4, 0x01, 0x66, 0x0f, 0xa8, 0x7c, 0x4e, 0x21, 0x7b, 0xef, 0xb2, 0x70, 0x86, 0xf3, 0x4c, 0x86, 0x08, 0x49, 0x40, 0xf3, 0x07,
0x86, 0x48, 0x4d, 0x8b, 0x65, 0x99, 0xfe, 0x4f, 0x04, 0x36, 0xcc, 0xe3, 0x2b, 0xeb, 0x91, 0x4b, 0xd4, 0x40, 0x64, 0xa6, 0x85, 0xf3, 0x8c, 0xf9, 0x14, 0xc0, 0x7d, 0xf5, 0xf8, 0xaa, 0x7a, 0x60,
0xeb, 0x1d, 0x02, 0xf0, 0x58, 0x3c, 0x42, 0xa9, 0x44, 0x14, 0x9a, 0x7b, 0xcb, 0xaf, 0xe4, 0xc1, 0x63, 0xbd, 0x66, 0x7f, 0xdd, 0x6d, 0xfa, 0xfb, 0xfb, 0xdb, 0x91, 0x0d, 0xb5, 0xec, 0x57, 0xc4,
0xc9, 0x91, 0xc9, 0xb0, 0x1a, 0xea, 0xea, 0x1e, 0xa8, 0x03, 0x9d, 0xf4, 0x57, 0xc5, 0xdc, 0x43, 0xc4, 0xa5, 0x7a, 0x2f, 0x87, 0x1d, 0x29, 0x98, 0x76, 0x5a, 0x26, 0x70, 0x8d, 0x71, 0x5e, 0x39,
0xab, 0x99, 0xc1, 0x76, 0x0c, 0xac, 0x73, 0x5c, 0x24, 0x58, 0x85, 0x71, 0x5f, 0x3b, 0xbb, 0xe8, 0xbf, 0x34, 0x3a, 0xcf, 0x2e, 0x8d, 0xce, 0xc5, 0xa5, 0xd1, 0xf9, 0x36, 0x35, 0xc0, 0x79, 0x6a,
0x36, 0x9e, 0x5d, 0x74, 0x1b, 0xe7, 0x17, 0xdd, 0xc6, 0xb7, 0xb3, 0x2e, 0x39, 0x9b, 0x75, 0xc9, 0x80, 0x67, 0xa9, 0x01, 0x7e, 0x4b, 0x0d, 0xf0, 0xfd, 0xef, 0x46, 0xe7, 0xd3, 0x7d, 0x35, 0xf1,
0xb3, 0x59, 0x97, 0xfc, 0x31, 0xeb, 0x92, 0xef, 0xff, 0xec, 0x36, 0x3e, 0xdd, 0x30, 0x73, 0xff, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x96, 0xa1, 0xd4, 0x72, 0x0c, 0x00, 0x00,
0x3b, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x49, 0x60, 0xfe, 0x78, 0x0c, 0x00, 0x00,
} }

View File

@ -183,9 +183,11 @@ message Subject {
// If the Authorizer does not recognized the kind value, the Authorizer should report an error. // If the Authorizer does not recognized the kind value, the Authorizer should report an error.
optional string kind = 1; optional string kind = 1;
// APIVersion holds the API group and version of the referenced object. // 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.
// +optional // +optional
optional string apiVersion = 2; optional string apiGroup = 2;
// Name of the object being referenced. // Name of the object being referenced.
optional string name = 3; optional string name = 3;

View File

@ -540,7 +540,7 @@ func (x *Subject) CodecEncodeSelf(e *codec1978.Encoder) {
var yyq2 [4]bool var yyq2 [4]bool
_, _, _ = yysep2, yyq2, yy2arr2 _, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false const yyr2 bool = false
yyq2[1] = x.APIVersion != "" yyq2[1] = x.APIGroup != ""
yyq2[3] = x.Namespace != "" yyq2[3] = x.Namespace != ""
var yynn2 int var yynn2 int
if yyr2 || yy2arr2 { if yyr2 || yy2arr2 {
@ -581,7 +581,7 @@ func (x *Subject) CodecEncodeSelf(e *codec1978.Encoder) {
_ = yym7 _ = yym7
if false { if false {
} else { } else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) r.EncodeString(codecSelferC_UTF81234, string(x.APIGroup))
} }
} else { } else {
r.EncodeString(codecSelferC_UTF81234, "") r.EncodeString(codecSelferC_UTF81234, "")
@ -589,13 +589,13 @@ func (x *Subject) CodecEncodeSelf(e *codec1978.Encoder) {
} else { } else {
if yyq2[1] { if yyq2[1] {
z.EncSendContainerState(codecSelfer_containerMapKey1234) z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) r.EncodeString(codecSelferC_UTF81234, string("apiGroup"))
z.EncSendContainerState(codecSelfer_containerMapValue1234) z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary() yym8 := z.EncBinary()
_ = yym8 _ = yym8
if false { if false {
} else { } else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) r.EncodeString(codecSelferC_UTF81234, string(x.APIGroup))
} }
} }
} }
@ -716,11 +716,11 @@ func (x *Subject) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
*((*string)(yyv4)) = r.DecodeString() *((*string)(yyv4)) = r.DecodeString()
} }
} }
case "apiVersion": case "apiGroup":
if r.TryDecodeAsNil() { if r.TryDecodeAsNil() {
x.APIVersion = "" x.APIGroup = ""
} else { } else {
yyv6 := &x.APIVersion yyv6 := &x.APIGroup
yym7 := z.DecBinary() yym7 := z.DecBinary()
_ = yym7 _ = yym7
if false { if false {
@ -800,9 +800,9 @@ func (x *Subject) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
} }
z.DecSendContainerState(codecSelfer_containerArrayElem1234) z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() { if r.TryDecodeAsNil() {
x.APIVersion = "" x.APIGroup = ""
} else { } else {
yyv15 := &x.APIVersion yyv15 := &x.APIGroup
yym16 := z.DecBinary() yym16 := z.DecBinary()
_ = yym16 _ = yym16
if false { if false {

View File

@ -71,9 +71,11 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // 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. // 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"` Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// APIVersion holds the API group and version of the referenced object. // 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.
// +optional // +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt.name=apiVersion"` APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,2,opt.name=apiGroup"`
// Name of the object being referenced. // Name of the object being referenced.
Name string `json:"name" protobuf:"bytes,3,opt,name=name"` Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty // Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty

View File

@ -134,11 +134,11 @@ func (RoleRef) SwaggerDoc() map[string]string {
} }
var map_Subject = 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.", "": "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.", "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.", "apiGroup": "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": "Name of the object being referenced.", "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.", "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.",
} }
func (Subject) SwaggerDoc() map[string]string { func (Subject) SwaggerDoc() map[string]string {

View File

@ -330,7 +330,7 @@ func Convert_rbac_RoleRef_To_v1beta1_RoleRef(in *rbac.RoleRef, out *RoleRef, s c
func autoConvert_v1beta1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error { func autoConvert_v1beta1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
out.Kind = in.Kind out.Kind = in.Kind
out.APIVersion = in.APIVersion out.APIGroup = in.APIGroup
out.Name = in.Name out.Name = in.Name
out.Namespace = in.Namespace out.Namespace = in.Namespace
return nil return nil
@ -342,7 +342,7 @@ func Convert_v1beta1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s c
func autoConvert_rbac_Subject_To_v1beta1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error { func autoConvert_rbac_Subject_To_v1beta1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
out.Kind = in.Kind out.Kind = in.Kind
out.APIVersion = in.APIVersion out.APIGroup = in.APIGroup
out.Name = in.Name out.Name = in.Name
out.Namespace = in.Namespace out.Namespace = in.Namespace
return nil return nil

View File

@ -37,6 +37,10 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) { func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) {
SetDefaults_ClusterRoleBinding(in) SetDefaults_ClusterRoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
} }
func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) { func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
@ -48,6 +52,10 @@ func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
func SetObjectDefaults_RoleBinding(in *RoleBinding) { func SetObjectDefaults_RoleBinding(in *RoleBinding) {
SetDefaults_RoleBinding(in) SetDefaults_RoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
} }
func SetObjectDefaults_RoleBindingList(in *RoleBindingList) { func SetObjectDefaults_RoleBindingList(in *RoleBindingList) {

View File

@ -201,6 +201,9 @@ func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, msg)) allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, msg))
} }
} }
if len(subject.APIGroup) > 0 {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("apiGroup"), subject.APIGroup, []string{""}))
}
if !isNamespaced && len(subject.Namespace) == 0 { if !isNamespaced && len(subject.Namespace) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), "")) allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
} }
@ -210,12 +213,18 @@ func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath
if len(subject.Name) == 0 { if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "user name cannot be empty")) allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "user name cannot be empty"))
} }
if subject.APIGroup != rbac.GroupName {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("apiGroup"), subject.APIGroup, []string{rbac.GroupName}))
}
case rbac.GroupKind: case rbac.GroupKind:
// TODO(ericchiang): What other restrictions on group name are there? // TODO(ericchiang): What other restrictions on group name are there?
if len(subject.Name) == 0 { if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "group name cannot be empty")) allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "group name cannot be empty"))
} }
if subject.APIGroup != rbac.GroupName {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("apiGroup"), subject.APIGroup, []string{rbac.GroupName}))
}
default: default:
allErrs = append(allErrs, field.NotSupported(fldPath.Child("kind"), subject.Kind, []string{rbac.ServiceAccountKind, rbac.UserKind, rbac.GroupKind})) allErrs = append(allErrs, field.NotSupported(fldPath.Child("kind"), subject.Kind, []string{rbac.ServiceAccountKind, rbac.UserKind, rbac.GroupKind}))

View File

@ -30,9 +30,9 @@ func TestValidateClusterRoleBinding(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Name: "master"}, ObjectMeta: metav1.ObjectMeta{Name: "master"},
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: "valid"}, RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: "valid"},
Subjects: []rbac.Subject{ Subjects: []rbac.Subject{
{Name: "validsaname", Namespace: "foo", Kind: rbac.ServiceAccountKind}, {Name: "validsaname", APIGroup: "", Namespace: "foo", Kind: rbac.ServiceAccountKind},
{Name: "valid@username", Kind: rbac.UserKind}, {Name: "valid@username", APIGroup: rbac.GroupName, Kind: rbac.UserKind},
{Name: "valid@groupname", Kind: rbac.GroupKind}, {Name: "valid@groupname", APIGroup: rbac.GroupName, Kind: rbac.GroupKind},
}, },
}, },
) )
@ -145,9 +145,9 @@ func TestValidateRoleBinding(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "master"}, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "master"},
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "Role", Name: "valid"}, RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "Role", Name: "valid"},
Subjects: []rbac.Subject{ Subjects: []rbac.Subject{
{Name: "validsaname", Kind: rbac.ServiceAccountKind}, {Name: "validsaname", APIGroup: "", Kind: rbac.ServiceAccountKind},
{Name: "valid@username", Kind: rbac.UserKind}, {Name: "valid@username", APIGroup: rbac.GroupName, Kind: rbac.UserKind},
{Name: "valid@groupname", Kind: rbac.GroupKind}, {Name: "valid@groupname", APIGroup: rbac.GroupName, Kind: rbac.GroupKind},
}, },
}, },
) )

View File

@ -11697,7 +11697,7 @@ func GetOpenAPIDefinitions(ref openapi.ReferenceCallback) map[string]openapi.Ope
}, },
"apiVersion": { "apiVersion": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
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{"string"}, Type: []string{"string"},
Format: "", Format: "",
}, },
@ -15314,9 +15314,9 @@ func GetOpenAPIDefinitions(ref openapi.ReferenceCallback) map[string]openapi.Ope
Format: "", Format: "",
}, },
}, },
"apiVersion": { "apiGroup": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
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.",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
}, },

View File

@ -117,16 +117,16 @@ func (s ClusterRoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, err
} }
for _, user := range s.Users { for _, user := range s.Users {
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{ clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{
Kind: rbac.UserKind, Kind: rbac.UserKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1", APIGroup: rbac.GroupName,
Name: user, Name: user,
}) })
} }
for _, group := range s.Groups { for _, group := range s.Groups {
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{ clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{
Kind: rbac.GroupKind, Kind: rbac.GroupKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1", APIGroup: rbac.GroupName,
Name: group, Name: group,
}) })
} }
for _, sa := range s.ServiceAccounts { for _, sa := range s.ServiceAccounts {
@ -136,6 +136,7 @@ func (s ClusterRoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, err
} }
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{ clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{
Kind: rbac.ServiceAccountKind, Kind: rbac.ServiceAccountKind,
APIGroup: "",
Namespace: tokens[0], Namespace: tokens[0],
Name: tokens[1], Name: tokens[1],
}) })

View File

@ -132,16 +132,16 @@ func (s RoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, error) {
for _, user := range s.Users { for _, user := range s.Users {
roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{ roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{
Kind: rbac.UserKind, Kind: rbac.UserKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1", APIGroup: rbac.GroupName,
Name: user, Name: user,
}) })
} }
for _, group := range s.Groups { for _, group := range s.Groups {
roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{ roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{
Kind: rbac.GroupKind, Kind: rbac.GroupKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1", APIGroup: rbac.GroupName,
Name: group, Name: group,
}) })
} }
for _, sa := range s.ServiceAccounts { for _, sa := range s.ServiceAccounts {
@ -151,6 +151,7 @@ func (s RoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, error) {
} }
roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{ roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{
Kind: rbac.ServiceAccountKind, Kind: rbac.ServiceAccountKind,
APIGroup: "",
Namespace: tokens[0], Namespace: tokens[0],
Name: tokens[1], Name: tokens[1],
}) })

View File

@ -12,7 +12,8 @@ items:
kind: ClusterRole kind: ClusterRole
name: cluster-admin name: cluster-admin
subjects: subjects:
- kind: Group - apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters name: system:masters
- apiVersion: rbac.authorization.k8s.io/v1beta1 - apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@ -26,9 +27,11 @@ items:
kind: ClusterRole kind: ClusterRole
name: system:basic-user name: system:basic-user
subjects: subjects:
- kind: Group - apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated name: system:authenticated
- kind: Group - apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:unauthenticated name: system:unauthenticated
- apiVersion: rbac.authorization.k8s.io/v1beta1 - apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@ -42,9 +45,11 @@ items:
kind: ClusterRole kind: ClusterRole
name: system:discovery name: system:discovery
subjects: subjects:
- kind: Group - apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated name: system:authenticated
- kind: Group - apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:unauthenticated name: system:unauthenticated
- apiVersion: rbac.authorization.k8s.io/v1beta1 - apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@ -58,7 +63,8 @@ items:
kind: ClusterRole kind: ClusterRole
name: system:kube-controller-manager name: system:kube-controller-manager
subjects: subjects:
- kind: User - apiGroup: rbac.authorization.k8s.io
kind: User
name: system:kube-controller-manager name: system:kube-controller-manager
- apiVersion: rbac.authorization.k8s.io/v1beta1 - apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@ -72,7 +78,8 @@ items:
kind: ClusterRole kind: ClusterRole
name: system:node name: system:node
subjects: subjects:
- kind: Group - apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes name: system:nodes
- apiVersion: rbac.authorization.k8s.io/v1beta1 - apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding kind: ClusterRoleBinding
@ -86,7 +93,8 @@ items:
kind: ClusterRole kind: ClusterRole
name: system:node-proxier name: system:node-proxier
subjects: subjects:
- kind: User - apiGroup: rbac.authorization.k8s.io
kind: User
name: system:kube-proxy name: system:kube-proxy
kind: List kind: List
metadata: {} metadata: {}

View File

@ -64,6 +64,15 @@ func newClusterRoleBinding(roleName string, subjects ...string) *rbac.ClusterRol
for i, subject := range subjects { for i, subject := range subjects {
split := strings.SplitN(subject, ":", 2) split := strings.SplitN(subject, ":", 2)
r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1] r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1]
switch r.Subjects[i].Kind {
case rbac.ServiceAccountKind:
r.Subjects[i].APIGroup = ""
case rbac.UserKind, rbac.GroupKind:
r.Subjects[i].APIGroup = rbac.GroupName
default:
panic(fmt.Errorf("invalid kind %s", r.Subjects[i].Kind))
}
} }
return r return r
} }
@ -82,6 +91,15 @@ func newRoleBinding(namespace, roleName string, bindType uint16, subjects ...str
for i, subject := range subjects { for i, subject := range subjects {
split := strings.SplitN(subject, ":", 2) split := strings.SplitN(subject, ":", 2)
r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1] r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1]
switch r.Subjects[i].Kind {
case rbac.ServiceAccountKind:
r.Subjects[i].APIGroup = ""
case rbac.UserKind, rbac.GroupKind:
r.Subjects[i].APIGroup = rbac.GroupName
default:
panic(fmt.Errorf("invalid kind %s", r.Subjects[i].Kind))
}
} }
return r return r
} }

View File

@ -54,9 +54,9 @@ func NewSubjectAccessEvaluator(roles rbacregistryvalidation.RoleGetter, roleBind
// AllowedSubjects returns the subjects that can perform an action and any errors encountered while computing the list. // AllowedSubjects returns the subjects that can perform an action and any errors encountered while computing the list.
// It is possible to have both subjects and errors returned if some rolebindings couldn't be resolved, but others could be. // It is possible to have both subjects and errors returned if some rolebindings couldn't be resolved, but others could be.
func (r *SubjectAccessEvaluator) AllowedSubjects(requestAttributes authorizer.Attributes) ([]rbac.Subject, error) { func (r *SubjectAccessEvaluator) AllowedSubjects(requestAttributes authorizer.Attributes) ([]rbac.Subject, error) {
subjects := []rbac.Subject{{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}} subjects := []rbac.Subject{{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup}}
if len(r.superUser) > 0 { if len(r.superUser) > 0 {
subjects = append(subjects, rbac.Subject{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: r.superUser}) subjects = append(subjects, rbac.Subject{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: r.superUser})
} }
errorlist := []error{} errorlist := []error{}

View File

@ -58,29 +58,29 @@ func TestSubjectLocator(t *testing.T) {
{ {
&defaultAttributes{"", "", "get", "Pods", "", "ns1", ""}, &defaultAttributes{"", "", "get", "Pods", "", "ns1", ""},
[]rbac.Subject{ []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, Name: "super-admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
{Kind: rbac.UserKind, Name: "admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "admin"},
{Kind: rbac.GroupKind, Name: "admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "admins"},
}, },
}, },
{ {
// cluster role matches star in namespace // cluster role matches star in namespace
&defaultAttributes{"", "", "*", "Pods", "", "*", ""}, &defaultAttributes{"", "", "*", "Pods", "", "*", ""},
[]rbac.Subject{ []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, Name: "super-admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
}, },
}, },
{ {
// empty ns // empty ns
&defaultAttributes{"", "", "*", "Pods", "", "", ""}, &defaultAttributes{"", "", "*", "Pods", "", "", ""},
[]rbac.Subject{ []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, Name: "super-admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
}, },
}, },
}, },
@ -104,32 +104,32 @@ func TestSubjectLocator(t *testing.T) {
{ {
&defaultAttributes{"", "", "get", "Pods", "", "ns1", ""}, &defaultAttributes{"", "", "get", "Pods", "", "ns1", ""},
[]rbac.Subject{ []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: "foo"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, Name: "super-admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
{Kind: rbac.UserKind, Name: "admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "admin"},
{Kind: rbac.GroupKind, Name: "admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "admins"},
}, },
}, },
{ {
// verb matchies correctly // verb matchies correctly
&defaultAttributes{"", "", "create", "Pods", "", "ns1", ""}, &defaultAttributes{"", "", "create", "Pods", "", "ns1", ""},
[]rbac.Subject{ []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: "foo"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, Name: "super-admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
}, },
}, },
{ {
// binding only works in correct ns // binding only works in correct ns
&defaultAttributes{"", "", "get", "Pods", "", "ns2", ""}, &defaultAttributes{"", "", "get", "Pods", "", "ns2", ""},
[]rbac.Subject{ []rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: "foo"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, Name: "super-admin"}, {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"}, {Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
}, },
}, },
}, },
@ -144,7 +144,7 @@ func TestSubjectLocator(t *testing.T) {
t.Errorf("case %q %d: error %v", tt.name, i, err) t.Errorf("case %q %d: error %v", tt.name, i, err)
} }
if !reflect.DeepEqual(actualSubjects, action.subjects) { if !reflect.DeepEqual(actualSubjects, action.subjects) {
t.Errorf("case %q %d: expected %v actual %v", tt.name, i, action.subjects, actualSubjects) t.Errorf("case %q %d: expected\n%v\nactual\n%v", tt.name, i, action.subjects, actualSubjects)
} }
} }
} }

View File

@ -181,7 +181,7 @@ var (
"name": "write-jobs" "name": "write-jobs"
}, },
"subjects": [{ "subjects": [{
"apiVersion": "rbac/v1alpha1", "apiGroup": "rbac.authorization.k8s.io",
"kind": "User", "kind": "User",
"name": "admin" "name": "admin"
}] }]