diff --git a/pkg/apis/rbac/v1/zz_generated.validations.go b/pkg/apis/rbac/v1/zz_generated.validations.go index 44b6e35c742..25237fc34f1 100644 --- a/pkg/apis/rbac/v1/zz_generated.validations.go +++ b/pkg/apis/rbac/v1/zz_generated.validations.go @@ -47,6 +47,22 @@ func RegisterValidations(scheme *runtime.Scheme) error { } return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} }) + // 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 ClusterRoleList scheme.AddValidationFunc((*rbacv1.ClusterRoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { switch op.Request.SubresourcePath() { @@ -63,6 +79,22 @@ func RegisterValidations(scheme *runtime.Scheme) error { } 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()))} + }) // type RoleList scheme.AddValidationFunc((*rbacv1.RoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { switch op.Request.SubresourcePath() { @@ -96,6 +128,60 @@ func Validate_ClusterRole(ctx context.Context, op operation.Operation, fldPath * return errs } +// 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_ClusterRoleList validates an instance of ClusterRoleList according // to declarative validation rules in the API schema. func Validate_ClusterRoleList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.ClusterRoleList) (errs field.ErrorList) { @@ -167,6 +253,60 @@ func Validate_Role(ctx context.Context, op operation.Operation, fldPath *field.P 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_RoleList validates an instance of RoleList according // to declarative validation rules in the API schema. func Validate_RoleList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.RoleList) (errs field.ErrorList) { @@ -187,3 +327,59 @@ func Validate_RoleList(ctx context.Context, op operation.Operation, fldPath *fie 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 + 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("kind"), &obj.Kind, safe.Field(oldObj, func(oldObj *rbacv1.RoleRef) *string { return &oldObj.Kind }))...) + + // field rbacv1.RoleRef.Name has no validation + 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 + 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("kind"), &obj.Kind, safe.Field(oldObj, func(oldObj *rbacv1.Subject) *string { return &oldObj.Kind }))...) + + // field rbacv1.Subject.APIGroup has no validation + // field rbacv1.Subject.Name has no validation + // field rbacv1.Subject.Namespace has no validation + return errs +} diff --git a/pkg/apis/rbac/v1alpha1/zz_generated.validations.go b/pkg/apis/rbac/v1alpha1/zz_generated.validations.go index 90c331d3ba3..f8176f2e71b 100644 --- a/pkg/apis/rbac/v1alpha1/zz_generated.validations.go +++ b/pkg/apis/rbac/v1alpha1/zz_generated.validations.go @@ -47,6 +47,22 @@ func RegisterValidations(scheme *runtime.Scheme) error { } return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} }) + // 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 ClusterRoleList scheme.AddValidationFunc((*rbacv1alpha1.ClusterRoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { switch op.Request.SubresourcePath() { @@ -63,6 +79,22 @@ func RegisterValidations(scheme *runtime.Scheme) error { } 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()))} + }) // type RoleList scheme.AddValidationFunc((*rbacv1alpha1.RoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { switch op.Request.SubresourcePath() { @@ -96,6 +128,62 @@ func Validate_ClusterRole(ctx context.Context, op operation.Operation, fldPath * return errs } +// 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_ClusterRoleList validates an instance of ClusterRoleList according // to declarative validation rules in the API schema. func Validate_ClusterRoleList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.ClusterRoleList) (errs field.ErrorList) { @@ -167,6 +255,60 @@ func Validate_Role(ctx context.Context, op operation.Operation, fldPath *field.P 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_RoleList validates an instance of RoleList according // to declarative validation rules in the API schema. func Validate_RoleList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.RoleList) (errs field.ErrorList) { @@ -187,3 +329,59 @@ func Validate_RoleList(ctx context.Context, op operation.Operation, fldPath *fie 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 + 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("kind"), &obj.Kind, safe.Field(oldObj, func(oldObj *rbacv1alpha1.RoleRef) *string { return &oldObj.Kind }))...) + + // field rbacv1alpha1.RoleRef.Name has no validation + 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 + 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("kind"), &obj.Kind, safe.Field(oldObj, func(oldObj *rbacv1alpha1.Subject) *string { return &oldObj.Kind }))...) + + // field rbacv1alpha1.Subject.APIVersion has no validation + // field rbacv1alpha1.Subject.Name has no validation + // field rbacv1alpha1.Subject.Namespace has no validation + return errs +} diff --git a/pkg/apis/rbac/v1beta1/zz_generated.validations.go b/pkg/apis/rbac/v1beta1/zz_generated.validations.go index a405bb6de7d..9350b4e4d0f 100644 --- a/pkg/apis/rbac/v1beta1/zz_generated.validations.go +++ b/pkg/apis/rbac/v1beta1/zz_generated.validations.go @@ -47,6 +47,22 @@ func RegisterValidations(scheme *runtime.Scheme) error { } return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} }) + // 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 ClusterRoleList scheme.AddValidationFunc((*rbacv1beta1.ClusterRoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { switch op.Request.SubresourcePath() { @@ -63,6 +79,22 @@ func RegisterValidations(scheme *runtime.Scheme) error { } 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()))} + }) // type RoleList scheme.AddValidationFunc((*rbacv1beta1.RoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { switch op.Request.SubresourcePath() { @@ -96,6 +128,60 @@ func Validate_ClusterRole(ctx context.Context, op operation.Operation, fldPath * return errs } +// 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_ClusterRoleList validates an instance of ClusterRoleList according // to declarative validation rules in the API schema. func Validate_ClusterRoleList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.ClusterRoleList) (errs field.ErrorList) { @@ -167,6 +253,60 @@ func Validate_Role(ctx context.Context, op operation.Operation, fldPath *field.P 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_RoleList validates an instance of RoleList according // to declarative validation rules in the API schema. func Validate_RoleList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.RoleList) (errs field.ErrorList) { @@ -187,3 +327,59 @@ func Validate_RoleList(ctx context.Context, op operation.Operation, fldPath *fie 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 + 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("kind"), &obj.Kind, safe.Field(oldObj, func(oldObj *rbacv1beta1.RoleRef) *string { return &oldObj.Kind }))...) + + // field rbacv1beta1.RoleRef.Name has no validation + 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 + 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("kind"), &obj.Kind, safe.Field(oldObj, func(oldObj *rbacv1beta1.Subject) *string { return &oldObj.Kind }))...) + + // field rbacv1beta1.Subject.APIGroup has no validation + // field rbacv1beta1.Subject.Name has no validation + // field rbacv1beta1.Subject.Namespace has no validation + return errs +} diff --git a/pkg/registry/rbac/rolebinding/declarative_validation_test.go b/pkg/registry/rbac/rolebinding/declarative_validation_test.go new file mode 100644 index 00000000000..8b2c8353c22 --- /dev/null +++ b/pkg/registry/rbac/rolebinding/declarative_validation_test.go @@ -0,0 +1,134 @@ +/* +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 { + 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-namespace"}, + RoleRef: rbac.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + }, + Subjects: []rbac.Subject{ + {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "user"}, + }, + }, + expectedErrs: field.ErrorList{ + field.Required(field.NewPath("roleRef", "name"), "name is required"), + }, + }, + "valid binding": { + input: rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: "valid-binding", Namespace: "test-namespace"}, + RoleRef: rbac.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "admin", + }, + Subjects: []rbac.Subject{ + {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "user"}, + }, + }, + expectedErrs: field.ErrorList{}, + }, + } + 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.RoleBinding + update rbac.RoleBinding + expectedErrs field.ErrorList + }{ + "update immutable roleRef Kind": { + old: rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: "binding", Namespace: "test-namespace"}, + RoleRef: rbac.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "Role", Name: "reader"}, + }, + update: rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: "binding", ResourceVersion: "1", Namespace: "test-namespace"}, + RoleRef: rbac.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", Name: "reader"}, + }, + expectedErrs: field.ErrorList{ + field.Invalid(field.NewPath("roleRef"), rbac.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", Name: "reader"}, "cannot change roleRef"), + }, + }, + "valid update": { + old: rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: "binding", Namespace: "test-namespace"}, + RoleRef: rbac.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "Role", Name: "reader"}, + Subjects: []rbac.Subject{{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "user1"}}, + }, + update: rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: "binding", ResourceVersion: "1", Namespace: "test-namespace"}, + RoleRef: rbac.RoleRef{APIGroup: "rbac.authorization.k8s.io", Kind: "Role", Name: "reader"}, + Subjects: []rbac.Subject{ + {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "user1"}, + {Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "user2"}, + }, + }, + expectedErrs: field.ErrorList{}, + }, + } + for k, tc := range testCases { + t.Run(k, func(t *testing.T) { + apitesting.VerifyUpdateValidationEquivalence(t, ctx, &tc.update, &tc.old, Strategy.ValidateUpdate, tc.expectedErrs) + }) + } +} diff --git a/pkg/registry/rbac/rolebinding/strategy.go b/pkg/registry/rbac/rolebinding/strategy.go index 55618c7132b..a2fba905169 100644 --- a/pkg/registry/rbac/rolebinding/strategy.go +++ b/pkg/registry/rbac/rolebinding/strategy.go @@ -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. diff --git a/staging/src/k8s.io/api/rbac/v1/types.go b/staging/src/k8s.io/api/rbac/v1/types.go index 97ccc2a581d..68690a3a74c 100644 --- a/staging/src/k8s.io/api/rbac/v1/types.go +++ b/staging/src/k8s.io/api/rbac/v1/types.go @@ -80,6 +80,8 @@ type PolicyRule struct { type Subject struct { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required + // +k8s:required Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // APIGroup holds the API group of the referenced subject. // Defaults to "" for ServiceAccount subjects. @@ -100,6 +102,8 @@ type RoleRef struct { // APIGroup is the group for the resource being referenced APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"` // Kind is the type of resource being referenced + // +required + // +k8s:required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // Name is the name of resource being referenced Name string `json:"name" protobuf:"bytes,3,opt,name=name"` diff --git a/staging/src/k8s.io/api/rbac/v1alpha1/types.go b/staging/src/k8s.io/api/rbac/v1alpha1/types.go index 081a8055bd9..2a622e729c9 100644 --- a/staging/src/k8s.io/api/rbac/v1alpha1/types.go +++ b/staging/src/k8s.io/api/rbac/v1alpha1/types.go @@ -79,6 +79,8 @@ type PolicyRule struct { type Subject struct { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required + // +k8s:required Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // APIVersion holds the API group and version of the referenced subject. // Defaults to "v1" for ServiceAccount subjects. @@ -99,6 +101,8 @@ type RoleRef struct { // APIGroup is the group for the resource being referenced APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"` // Kind is the type of resource being referenced + // +required + // +k8s:required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // Name is the name of resource being referenced Name string `json:"name" protobuf:"bytes,3,opt,name=name"` diff --git a/staging/src/k8s.io/api/rbac/v1beta1/types.go b/staging/src/k8s.io/api/rbac/v1beta1/types.go index 35f319f4164..d2e6b8aa09a 100644 --- a/staging/src/k8s.io/api/rbac/v1beta1/types.go +++ b/staging/src/k8s.io/api/rbac/v1beta1/types.go @@ -80,6 +80,8 @@ type PolicyRule struct { type Subject struct { // Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". // If the Authorizer does not recognized the kind value, the Authorizer should report an error. + // +required + // +k8s:required Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // APIGroup holds the API group of the referenced subject. // Defaults to "" for ServiceAccount subjects. @@ -99,6 +101,8 @@ type RoleRef struct { // APIGroup is the group for the resource being referenced APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"` // Kind is the type of resource being referenced + // +required + // +k8s:required Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` // Name is the name of resource being referenced Name string `json:"name" protobuf:"bytes,3,opt,name=name"`