Merge pull request #134537 from itzPranshul/master-vg-enable-clusterRole

[RBAC] Enable Declarative Validation(DV) support for ClusterRole and RoleBinding
This commit is contained in:
Kubernetes Prow Robot
2025-10-22 16:48:38 -07:00
committed by GitHub
17 changed files with 954 additions and 7 deletions

View File

@@ -19,6 +19,8 @@ limitations under the License.
// +k8s:defaulter-gen=TypeMeta
// +k8s:defaulter-gen-input=k8s.io/api/rbac/v1
// +k8s:deepcopy-gen=package
// +k8s:validation-gen=TypeMeta
// +k8s:validation-gen-input=k8s.io/api/rbac/v1
// +groupName=rbac.authorization.k8s.io

View File

@@ -0,0 +1,240 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by validation-gen. DO NOT EDIT.
package v1
import (
context "context"
fmt "fmt"
rbacv1 "k8s.io/api/rbac/v1"
equality "k8s.io/apimachinery/pkg/api/equality"
operation "k8s.io/apimachinery/pkg/api/operation"
safe "k8s.io/apimachinery/pkg/api/safe"
validate "k8s.io/apimachinery/pkg/api/validate"
runtime "k8s.io/apimachinery/pkg/runtime"
field "k8s.io/apimachinery/pkg/util/validation/field"
)
func init() { localSchemeBuilder.Register(RegisterValidations) }
// RegisterValidations adds validation functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterValidations(scheme *runtime.Scheme) error {
// type ClusterRoleBinding
scheme.AddValidationFunc((*rbacv1.ClusterRoleBinding)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_ClusterRoleBinding(ctx, op, nil /* fldPath */, obj.(*rbacv1.ClusterRoleBinding), safe.Cast[*rbacv1.ClusterRoleBinding](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type ClusterRoleBindingList
scheme.AddValidationFunc((*rbacv1.ClusterRoleBindingList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_ClusterRoleBindingList(ctx, op, nil /* fldPath */, obj.(*rbacv1.ClusterRoleBindingList), safe.Cast[*rbacv1.ClusterRoleBindingList](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type RoleBinding
scheme.AddValidationFunc((*rbacv1.RoleBinding)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_RoleBinding(ctx, op, nil /* fldPath */, obj.(*rbacv1.RoleBinding), safe.Cast[*rbacv1.RoleBinding](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type RoleBindingList
scheme.AddValidationFunc((*rbacv1.RoleBindingList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_RoleBindingList(ctx, op, nil /* fldPath */, obj.(*rbacv1.RoleBindingList), safe.Cast[*rbacv1.RoleBindingList](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
return nil
}
// Validate_ClusterRoleBinding validates an instance of ClusterRoleBinding according
// to declarative validation rules in the API schema.
func Validate_ClusterRoleBinding(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.ClusterRoleBinding) (errs field.ErrorList) {
// field rbacv1.ClusterRoleBinding.TypeMeta has no validation
// field rbacv1.ClusterRoleBinding.ObjectMeta has no validation
// field rbacv1.ClusterRoleBinding.Subjects
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1.Subject) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Subject)...)
return
}(fldPath.Child("subjects"), obj.Subjects, safe.Field(oldObj, func(oldObj *rbacv1.ClusterRoleBinding) []rbacv1.Subject { return oldObj.Subjects }))...)
// field rbacv1.ClusterRoleBinding.RoleRef
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *rbacv1.RoleRef) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call the type's validation function
errs = append(errs, Validate_RoleRef(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("roleRef"), &obj.RoleRef, safe.Field(oldObj, func(oldObj *rbacv1.ClusterRoleBinding) *rbacv1.RoleRef { return &oldObj.RoleRef }))...)
return errs
}
// Validate_ClusterRoleBindingList validates an instance of ClusterRoleBindingList according
// to declarative validation rules in the API schema.
func Validate_ClusterRoleBindingList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.ClusterRoleBindingList) (errs field.ErrorList) {
// field rbacv1.ClusterRoleBindingList.TypeMeta has no validation
// field rbacv1.ClusterRoleBindingList.ListMeta has no validation
// field rbacv1.ClusterRoleBindingList.Items
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1.ClusterRoleBinding) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_ClusterRoleBinding)...)
return
}(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1.ClusterRoleBindingList) []rbacv1.ClusterRoleBinding { return oldObj.Items }))...)
return errs
}
// Validate_RoleBinding validates an instance of RoleBinding according
// to declarative validation rules in the API schema.
func Validate_RoleBinding(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.RoleBinding) (errs field.ErrorList) {
// field rbacv1.RoleBinding.TypeMeta has no validation
// field rbacv1.RoleBinding.ObjectMeta has no validation
// field rbacv1.RoleBinding.Subjects
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1.Subject) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Subject)...)
return
}(fldPath.Child("subjects"), obj.Subjects, safe.Field(oldObj, func(oldObj *rbacv1.RoleBinding) []rbacv1.Subject { return oldObj.Subjects }))...)
// field rbacv1.RoleBinding.RoleRef
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *rbacv1.RoleRef) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call the type's validation function
errs = append(errs, Validate_RoleRef(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("roleRef"), &obj.RoleRef, safe.Field(oldObj, func(oldObj *rbacv1.RoleBinding) *rbacv1.RoleRef { return &oldObj.RoleRef }))...)
return errs
}
// Validate_RoleBindingList validates an instance of RoleBindingList according
// to declarative validation rules in the API schema.
func Validate_RoleBindingList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.RoleBindingList) (errs field.ErrorList) {
// field rbacv1.RoleBindingList.TypeMeta has no validation
// field rbacv1.RoleBindingList.ListMeta has no validation
// field rbacv1.RoleBindingList.Items
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1.RoleBinding) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_RoleBinding)...)
return
}(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1.RoleBindingList) []rbacv1.RoleBinding { return oldObj.Items }))...)
return errs
}
// Validate_RoleRef validates an instance of RoleRef according
// to declarative validation rules in the API schema.
func Validate_RoleRef(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.RoleRef) (errs field.ErrorList) {
// field rbacv1.RoleRef.APIGroup has no validation
// field rbacv1.RoleRef.Kind has no validation
// field rbacv1.RoleRef.Name
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("name"), &obj.Name, safe.Field(oldObj, func(oldObj *rbacv1.RoleRef) *string { return &oldObj.Name }))...)
return errs
}
// Validate_Subject validates an instance of Subject according
// to declarative validation rules in the API schema.
func Validate_Subject(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.Subject) (errs field.ErrorList) {
// field rbacv1.Subject.Kind has no validation
// field rbacv1.Subject.APIGroup has no validation
// field rbacv1.Subject.Name
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("name"), &obj.Name, safe.Field(oldObj, func(oldObj *rbacv1.Subject) *string { return &oldObj.Name }))...)
// field rbacv1.Subject.Namespace has no validation
return errs
}

View File

@@ -18,6 +18,8 @@ limitations under the License.
// +k8s:conversion-gen-external-types=k8s.io/api/rbac/v1alpha1
// +k8s:defaulter-gen=TypeMeta
// +k8s:defaulter-gen-input=k8s.io/api/rbac/v1alpha1
// +k8s:validation-gen=TypeMeta
// +k8s:validation-gen-input=k8s.io/api/rbac/v1alpha1
// +groupName=rbac.authorization.k8s.io

View File

@@ -0,0 +1,242 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by validation-gen. DO NOT EDIT.
package v1alpha1
import (
context "context"
fmt "fmt"
rbacv1alpha1 "k8s.io/api/rbac/v1alpha1"
equality "k8s.io/apimachinery/pkg/api/equality"
operation "k8s.io/apimachinery/pkg/api/operation"
safe "k8s.io/apimachinery/pkg/api/safe"
validate "k8s.io/apimachinery/pkg/api/validate"
runtime "k8s.io/apimachinery/pkg/runtime"
field "k8s.io/apimachinery/pkg/util/validation/field"
)
func init() { localSchemeBuilder.Register(RegisterValidations) }
// RegisterValidations adds validation functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterValidations(scheme *runtime.Scheme) error {
// type ClusterRoleBinding
scheme.AddValidationFunc((*rbacv1alpha1.ClusterRoleBinding)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_ClusterRoleBinding(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.ClusterRoleBinding), safe.Cast[*rbacv1alpha1.ClusterRoleBinding](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type ClusterRoleBindingList
scheme.AddValidationFunc((*rbacv1alpha1.ClusterRoleBindingList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_ClusterRoleBindingList(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.ClusterRoleBindingList), safe.Cast[*rbacv1alpha1.ClusterRoleBindingList](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type RoleBinding
scheme.AddValidationFunc((*rbacv1alpha1.RoleBinding)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_RoleBinding(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.RoleBinding), safe.Cast[*rbacv1alpha1.RoleBinding](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type RoleBindingList
scheme.AddValidationFunc((*rbacv1alpha1.RoleBindingList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_RoleBindingList(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.RoleBindingList), safe.Cast[*rbacv1alpha1.RoleBindingList](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
return nil
}
// Validate_ClusterRoleBinding validates an instance of ClusterRoleBinding according
// to declarative validation rules in the API schema.
func Validate_ClusterRoleBinding(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.ClusterRoleBinding) (errs field.ErrorList) {
// field rbacv1alpha1.ClusterRoleBinding.TypeMeta has no validation
// field rbacv1alpha1.ClusterRoleBinding.ObjectMeta has no validation
// field rbacv1alpha1.ClusterRoleBinding.Subjects
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.Subject) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Subject)...)
return
}(fldPath.Child("subjects"), obj.Subjects, safe.Field(oldObj, func(oldObj *rbacv1alpha1.ClusterRoleBinding) []rbacv1alpha1.Subject { return oldObj.Subjects }))...)
// field rbacv1alpha1.ClusterRoleBinding.RoleRef
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *rbacv1alpha1.RoleRef) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call the type's validation function
errs = append(errs, Validate_RoleRef(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("roleRef"), &obj.RoleRef, safe.Field(oldObj, func(oldObj *rbacv1alpha1.ClusterRoleBinding) *rbacv1alpha1.RoleRef { return &oldObj.RoleRef }))...)
return errs
}
// Validate_ClusterRoleBindingList validates an instance of ClusterRoleBindingList according
// to declarative validation rules in the API schema.
func Validate_ClusterRoleBindingList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.ClusterRoleBindingList) (errs field.ErrorList) {
// field rbacv1alpha1.ClusterRoleBindingList.TypeMeta has no validation
// field rbacv1alpha1.ClusterRoleBindingList.ListMeta has no validation
// field rbacv1alpha1.ClusterRoleBindingList.Items
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.ClusterRoleBinding) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_ClusterRoleBinding)...)
return
}(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1alpha1.ClusterRoleBindingList) []rbacv1alpha1.ClusterRoleBinding {
return oldObj.Items
}))...)
return errs
}
// Validate_RoleBinding validates an instance of RoleBinding according
// to declarative validation rules in the API schema.
func Validate_RoleBinding(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.RoleBinding) (errs field.ErrorList) {
// field rbacv1alpha1.RoleBinding.TypeMeta has no validation
// field rbacv1alpha1.RoleBinding.ObjectMeta has no validation
// field rbacv1alpha1.RoleBinding.Subjects
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.Subject) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Subject)...)
return
}(fldPath.Child("subjects"), obj.Subjects, safe.Field(oldObj, func(oldObj *rbacv1alpha1.RoleBinding) []rbacv1alpha1.Subject { return oldObj.Subjects }))...)
// field rbacv1alpha1.RoleBinding.RoleRef
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *rbacv1alpha1.RoleRef) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call the type's validation function
errs = append(errs, Validate_RoleRef(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("roleRef"), &obj.RoleRef, safe.Field(oldObj, func(oldObj *rbacv1alpha1.RoleBinding) *rbacv1alpha1.RoleRef { return &oldObj.RoleRef }))...)
return errs
}
// Validate_RoleBindingList validates an instance of RoleBindingList according
// to declarative validation rules in the API schema.
func Validate_RoleBindingList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.RoleBindingList) (errs field.ErrorList) {
// field rbacv1alpha1.RoleBindingList.TypeMeta has no validation
// field rbacv1alpha1.RoleBindingList.ListMeta has no validation
// field rbacv1alpha1.RoleBindingList.Items
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.RoleBinding) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_RoleBinding)...)
return
}(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1alpha1.RoleBindingList) []rbacv1alpha1.RoleBinding { return oldObj.Items }))...)
return errs
}
// Validate_RoleRef validates an instance of RoleRef according
// to declarative validation rules in the API schema.
func Validate_RoleRef(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.RoleRef) (errs field.ErrorList) {
// field rbacv1alpha1.RoleRef.APIGroup has no validation
// field rbacv1alpha1.RoleRef.Kind has no validation
// field rbacv1alpha1.RoleRef.Name
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("name"), &obj.Name, safe.Field(oldObj, func(oldObj *rbacv1alpha1.RoleRef) *string { return &oldObj.Name }))...)
return errs
}
// Validate_Subject validates an instance of Subject according
// to declarative validation rules in the API schema.
func Validate_Subject(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.Subject) (errs field.ErrorList) {
// field rbacv1alpha1.Subject.Kind has no validation
// field rbacv1alpha1.Subject.APIVersion has no validation
// field rbacv1alpha1.Subject.Name
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("name"), &obj.Name, safe.Field(oldObj, func(oldObj *rbacv1alpha1.Subject) *string { return &oldObj.Name }))...)
// field rbacv1alpha1.Subject.Namespace has no validation
return errs
}

View File

@@ -18,6 +18,8 @@ limitations under the License.
// +k8s:conversion-gen-external-types=k8s.io/api/rbac/v1beta1
// +k8s:defaulter-gen=TypeMeta
// +k8s:defaulter-gen-input=k8s.io/api/rbac/v1beta1
// +k8s:validation-gen=TypeMeta
// +k8s:validation-gen-input=k8s.io/api/rbac/v1beta1
// +groupName=rbac.authorization.k8s.io

View File

@@ -0,0 +1,240 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by validation-gen. DO NOT EDIT.
package v1beta1
import (
context "context"
fmt "fmt"
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
equality "k8s.io/apimachinery/pkg/api/equality"
operation "k8s.io/apimachinery/pkg/api/operation"
safe "k8s.io/apimachinery/pkg/api/safe"
validate "k8s.io/apimachinery/pkg/api/validate"
runtime "k8s.io/apimachinery/pkg/runtime"
field "k8s.io/apimachinery/pkg/util/validation/field"
)
func init() { localSchemeBuilder.Register(RegisterValidations) }
// RegisterValidations adds validation functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterValidations(scheme *runtime.Scheme) error {
// type ClusterRoleBinding
scheme.AddValidationFunc((*rbacv1beta1.ClusterRoleBinding)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_ClusterRoleBinding(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.ClusterRoleBinding), safe.Cast[*rbacv1beta1.ClusterRoleBinding](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type ClusterRoleBindingList
scheme.AddValidationFunc((*rbacv1beta1.ClusterRoleBindingList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_ClusterRoleBindingList(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.ClusterRoleBindingList), safe.Cast[*rbacv1beta1.ClusterRoleBindingList](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type RoleBinding
scheme.AddValidationFunc((*rbacv1beta1.RoleBinding)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_RoleBinding(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.RoleBinding), safe.Cast[*rbacv1beta1.RoleBinding](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
// type RoleBindingList
scheme.AddValidationFunc((*rbacv1beta1.RoleBindingList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_RoleBindingList(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.RoleBindingList), safe.Cast[*rbacv1beta1.RoleBindingList](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
return nil
}
// Validate_ClusterRoleBinding validates an instance of ClusterRoleBinding according
// to declarative validation rules in the API schema.
func Validate_ClusterRoleBinding(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.ClusterRoleBinding) (errs field.ErrorList) {
// field rbacv1beta1.ClusterRoleBinding.TypeMeta has no validation
// field rbacv1beta1.ClusterRoleBinding.ObjectMeta has no validation
// field rbacv1beta1.ClusterRoleBinding.Subjects
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1beta1.Subject) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Subject)...)
return
}(fldPath.Child("subjects"), obj.Subjects, safe.Field(oldObj, func(oldObj *rbacv1beta1.ClusterRoleBinding) []rbacv1beta1.Subject { return oldObj.Subjects }))...)
// field rbacv1beta1.ClusterRoleBinding.RoleRef
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *rbacv1beta1.RoleRef) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call the type's validation function
errs = append(errs, Validate_RoleRef(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("roleRef"), &obj.RoleRef, safe.Field(oldObj, func(oldObj *rbacv1beta1.ClusterRoleBinding) *rbacv1beta1.RoleRef { return &oldObj.RoleRef }))...)
return errs
}
// Validate_ClusterRoleBindingList validates an instance of ClusterRoleBindingList according
// to declarative validation rules in the API schema.
func Validate_ClusterRoleBindingList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.ClusterRoleBindingList) (errs field.ErrorList) {
// field rbacv1beta1.ClusterRoleBindingList.TypeMeta has no validation
// field rbacv1beta1.ClusterRoleBindingList.ListMeta has no validation
// field rbacv1beta1.ClusterRoleBindingList.Items
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1beta1.ClusterRoleBinding) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_ClusterRoleBinding)...)
return
}(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1beta1.ClusterRoleBindingList) []rbacv1beta1.ClusterRoleBinding { return oldObj.Items }))...)
return errs
}
// Validate_RoleBinding validates an instance of RoleBinding according
// to declarative validation rules in the API schema.
func Validate_RoleBinding(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.RoleBinding) (errs field.ErrorList) {
// field rbacv1beta1.RoleBinding.TypeMeta has no validation
// field rbacv1beta1.RoleBinding.ObjectMeta has no validation
// field rbacv1beta1.RoleBinding.Subjects
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1beta1.Subject) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Subject)...)
return
}(fldPath.Child("subjects"), obj.Subjects, safe.Field(oldObj, func(oldObj *rbacv1beta1.RoleBinding) []rbacv1beta1.Subject { return oldObj.Subjects }))...)
// field rbacv1beta1.RoleBinding.RoleRef
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *rbacv1beta1.RoleRef) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call the type's validation function
errs = append(errs, Validate_RoleRef(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("roleRef"), &obj.RoleRef, safe.Field(oldObj, func(oldObj *rbacv1beta1.RoleBinding) *rbacv1beta1.RoleRef { return &oldObj.RoleRef }))...)
return errs
}
// Validate_RoleBindingList validates an instance of RoleBindingList according
// to declarative validation rules in the API schema.
func Validate_RoleBindingList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.RoleBindingList) (errs field.ErrorList) {
// field rbacv1beta1.RoleBindingList.TypeMeta has no validation
// field rbacv1beta1.RoleBindingList.ListMeta has no validation
// field rbacv1beta1.RoleBindingList.Items
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []rbacv1beta1.RoleBinding) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// iterate the list and call the type's validation function
errs = append(errs, validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_RoleBinding)...)
return
}(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1beta1.RoleBindingList) []rbacv1beta1.RoleBinding { return oldObj.Items }))...)
return errs
}
// Validate_RoleRef validates an instance of RoleRef according
// to declarative validation rules in the API schema.
func Validate_RoleRef(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.RoleRef) (errs field.ErrorList) {
// field rbacv1beta1.RoleRef.APIGroup has no validation
// field rbacv1beta1.RoleRef.Kind has no validation
// field rbacv1beta1.RoleRef.Name
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("name"), &obj.Name, safe.Field(oldObj, func(oldObj *rbacv1beta1.RoleRef) *string { return &oldObj.Name }))...)
return errs
}
// Validate_Subject validates an instance of Subject according
// to declarative validation rules in the API schema.
func Validate_Subject(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.Subject) (errs field.ErrorList) {
// field rbacv1beta1.Subject.Kind has no validation
// field rbacv1beta1.Subject.APIGroup has no validation
// field rbacv1beta1.Subject.Name
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) {
// don't revalidate unchanged data
if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("name"), &obj.Name, safe.Field(oldObj, func(oldObj *rbacv1beta1.Subject) *string { return &oldObj.Name }))...)
// field rbacv1beta1.Subject.Namespace has no validation
return errs
}

View File

@@ -143,7 +143,7 @@ func ValidateRoleBinding(roleBinding *rbac.RoleBinding) field.ErrorList {
}
if len(roleBinding.RoleRef.Name) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), ""))
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), "").MarkCoveredByDeclarative())
} else {
for _, msg := range ValidateRBACName(roleBinding.RoleRef.Name, false) {
allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg))
@@ -187,7 +187,7 @@ func ValidateClusterRoleBinding(roleBinding *rbac.ClusterRoleBinding) field.Erro
}
if len(roleBinding.RoleRef.Name) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), ""))
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), "").MarkCoveredByDeclarative())
} else {
for _, msg := range ValidateRBACName(roleBinding.RoleRef.Name, false) {
allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg))
@@ -218,7 +218,7 @@ func ValidateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath
allErrs := field.ErrorList{}
if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "").MarkCoveredByDeclarative())
}
switch subject.Kind {

View File

@@ -0,0 +1,77 @@
/*
Copyright 2025 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 clusterrole
import (
"testing"
"k8s.io/apimachinery/pkg/util/validation/field"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
apitesting "k8s.io/kubernetes/pkg/api/testing"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
)
var apiVersions = []string{"v1", "v1alpha1", "v1beta1"}
func TestDeclarativeValidateForDeclarative(t *testing.T) {
for _, apiVersion := range apiVersions {
testDeclarativeValidateForDeclarative(t, apiVersion)
}
}
func testDeclarativeValidateForDeclarative(t *testing.T, apiVersion string) {
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
APIGroup: "rbac.authorization.k8s.io",
APIVersion: apiVersion,
})
testCases := map[string]struct {
input rbac.ClusterRole
expectedErrs field.ErrorList
}{
// TODO: Add more test cases
}
for k, tc := range testCases {
t.Run(k, func(t *testing.T) {
apitesting.VerifyValidationEquivalence(t, ctx, &tc.input, Strategy.Validate, tc.expectedErrs)
})
}
}
func TestValidateUpdateForDeclarative(t *testing.T) {
for _, apiVersion := range apiVersions {
testValidateUpdateForDeclarative(t, apiVersion)
}
}
func testValidateUpdateForDeclarative(t *testing.T, apiVersion string) {
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
APIGroup: "rbac.authorization.k8s.io",
APIVersion: apiVersion,
})
testCases := map[string]struct {
old rbac.ClusterRole
update rbac.ClusterRole
expectedErrs field.ErrorList
}{
// TODO: Add more test cases
}
for k, tc := range testCases {
t.Run(k, func(t *testing.T) {
apitesting.VerifyUpdateValidationEquivalence(t, ctx, &tc.update, &tc.old, Strategy.ValidateUpdate, tc.expectedErrs)
})
}
}

View File

@@ -19,6 +19,7 @@ package clusterrole
import (
"context"
"k8s.io/apimachinery/pkg/api/operation"
metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -75,7 +76,9 @@ func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorLis
opts := validation.ClusterRoleValidationOptions{
AllowInvalidLabelValueInSelector: false,
}
return validation.ValidateClusterRole(clusterRole, opts)
allErrs := validation.ValidateClusterRole(clusterRole, opts)
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, clusterRole, nil, allErrs, operation.Create)
}
// WarningsOnCreate returns warnings for the creation of the given object.
@@ -93,7 +96,9 @@ func (strategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) fie
opts := validation.ClusterRoleValidationOptions{
AllowInvalidLabelValueInSelector: hasInvalidLabelValueInLabelSelector(oldObj),
}
return validation.ValidateClusterRoleUpdate(newObj, old.(*rbac.ClusterRole), opts)
errs := validation.ValidateClusterRoleUpdate(newObj, oldObj, opts)
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, newObj, oldObj, errs, operation.Update)
}
// WarningsOnUpdate returns warnings for the given update.

View File

@@ -0,0 +1,105 @@
/*
Copyright 2025 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 rolebinding
import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
apitesting "k8s.io/kubernetes/pkg/api/testing"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
)
var apiVersions = []string{"v1", "v1alpha1", "v1beta1"}
func TestDeclarativeValidateForDeclarative(t *testing.T) {
for _, apiVersion := range apiVersions {
t.Run(apiVersion, func(t *testing.T) {
testDeclarativeValidateForDeclarative(t, apiVersion)
})
}
}
func testDeclarativeValidateForDeclarative(t *testing.T, apiVersion string) {
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
APIGroup: "rbac.authorization.k8s.io",
APIVersion: apiVersion,
})
testCases := map[string]struct {
input rbac.RoleBinding
expectedErrs field.ErrorList
}{
"missing roleRef.name": {
input: rbac.RoleBinding{
ObjectMeta: metav1.ObjectMeta{Name: "test-binding", Namespace: "test-ns"},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
// Name is intentionally missing here
},
Subjects: []rbac.Subject{
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "user1"},
},
},
expectedErrs: field.ErrorList{
field.Required(field.NewPath("roleRef", "name"), "name is required"),
},
},
"missing subject.name": {
input: rbac.RoleBinding{
ObjectMeta: metav1.ObjectMeta{Name: "test-binding", Namespace: "test-ns"},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "Role",
Name: "reader",
},
Subjects: []rbac.Subject{
{Kind: rbac.UserKind, APIGroup: rbac.GroupName},
},
},
expectedErrs: field.ErrorList{
field.Required(field.NewPath("subjects").Index(0).Child("name"), "name is required"),
},
},
"valid binding": {
input: rbac.RoleBinding{
ObjectMeta: metav1.ObjectMeta{Name: "valid-binding", Namespace: "test-ns"},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "Role",
Name: "admin",
},
Subjects: []rbac.Subject{
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "user1"},
},
},
expectedErrs: field.ErrorList{},
},
// TODO: Add more test cases
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
apitesting.VerifyValidationEquivalence(t, ctx, &tc.input, Strategy.Validate, tc.expectedErrs)
})
}
}

View File

@@ -19,6 +19,7 @@ package rolebinding
import (
"context"
"k8s.io/apimachinery/pkg/api/operation"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/registry/rest"
@@ -71,7 +72,8 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
// Validate validates a new RoleBinding. Validation must check for a correct signature.
func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
roleBinding := obj.(*rbac.RoleBinding)
return validation.ValidateRoleBinding(roleBinding)
allErrs := validation.ValidateRoleBinding(roleBinding)
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, roleBinding, nil, allErrs, operation.Create)
}
// WarningsOnCreate returns warnings for the creation of the given object.
@@ -84,7 +86,13 @@ func (strategy) Canonicalize(obj runtime.Object) {
// ValidateUpdate is the default update validation for an end user.
func (strategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
return validation.ValidateRoleBindingUpdate(obj.(*rbac.RoleBinding), old.(*rbac.RoleBinding))
newRoleBinding := obj.(*rbac.RoleBinding)
oldRoleBinding := old.(*rbac.RoleBinding)
allErrs := validation.ValidateRoleBindingUpdate(newRoleBinding, oldRoleBinding)
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, newRoleBinding, oldRoleBinding, allErrs, operation.Update)
}
// WarningsOnUpdate returns warnings for the given update.

View File

@@ -185,6 +185,8 @@ message RoleRef {
optional string kind = 2;
// Name is the name of resource being referenced
// +required
// +k8s:required
optional string name = 3;
}
@@ -203,6 +205,8 @@ message Subject {
optional string apiGroup = 2;
// Name of the object being referenced.
// +required
// +k8s:required
optional string name = 3;
// 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

@@ -86,6 +86,8 @@ type Subject struct {
// +optional
APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,2,opt,name=apiGroup"`
// Name of the object being referenced.
// +required
// +k8s:required
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
// the Authorizer should report an error.
@@ -101,6 +103,8 @@ type RoleRef struct {
// Kind is the type of resource being referenced
Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"`
// Name is the name of resource being referenced
// +required
// +k8s:required
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
}

View File

@@ -190,6 +190,8 @@ message RoleRef {
optional string kind = 2;
// Name is the name of resource being referenced
// +required
// +k8s:required
optional string name = 3;
}
@@ -208,6 +210,8 @@ message Subject {
optional string apiVersion = 2;
// Name of the object being referenced.
// +required
// +k8s:required
optional string name = 3;
// 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

@@ -86,6 +86,8 @@ type Subject struct {
// +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
// Name of the object being referenced.
// +required
// +k8s:required
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
// the Authorizer should report an error.
@@ -100,6 +102,8 @@ type RoleRef struct {
// Kind is the type of resource being referenced
Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"`
// Name is the name of resource being referenced
// +required
// +k8s:required
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
}

View File

@@ -191,6 +191,8 @@ message RoleRef {
optional string kind = 2;
// Name is the name of resource being referenced
// +required
// +k8s:required
optional string name = 3;
}
@@ -208,6 +210,8 @@ message Subject {
optional string apiGroup = 2;
// Name of the object being referenced.
// +required
// +k8s:required
optional string name = 3;
// 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

@@ -86,6 +86,8 @@ type Subject struct {
// +optional
APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,2,opt,name=apiGroup"`
// Name of the object being referenced.
// +required
// +k8s:required
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
// the Authorizer should report an error.
@@ -100,6 +102,8 @@ type RoleRef struct {
// Kind is the type of resource being referenced
Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"`
// Name is the name of resource being referenced
// +required
// +k8s:required
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
}