From 6ae916a577cfc922d190285c3cef29fb54331091 Mon Sep 17 00:00:00 2001 From: pranshul gupta Date: Fri, 17 Oct 2025 21:33:42 +0530 Subject: [PATCH] rbac: Remove PolicyRule.Verbs from declarative validation migration --- pkg/apis/rbac/v1/zz_generated.validations.go | 146 ------------------ .../rbac/v1alpha1/zz_generated.validations.go | 146 ------------------ .../rbac/v1beta1/zz_generated.validations.go | 146 ------------------ pkg/apis/rbac/validation/validation.go | 2 +- .../declarative_validation_test.go | 77 +-------- pkg/registry/rbac/clusterrole/strategy.go | 18 +-- staging/src/k8s.io/api/rbac/v1/types.go | 1 - staging/src/k8s.io/api/rbac/v1alpha1/types.go | 1 - staging/src/k8s.io/api/rbac/v1beta1/types.go | 1 - 9 files changed, 5 insertions(+), 533 deletions(-) diff --git a/pkg/apis/rbac/v1/zz_generated.validations.go b/pkg/apis/rbac/v1/zz_generated.validations.go index 25237fc34f1..136262bcad2 100644 --- a/pkg/apis/rbac/v1/zz_generated.validations.go +++ b/pkg/apis/rbac/v1/zz_generated.validations.go @@ -39,14 +39,6 @@ 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 ClusterRole - scheme.AddValidationFunc((*rbacv1.ClusterRole)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_ClusterRole(ctx, op, nil /* fldPath */, obj.(*rbacv1.ClusterRole), safe.Cast[*rbacv1.ClusterRole](oldObj)) - } - 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() { @@ -63,22 +55,6 @@ 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 ClusterRoleList - scheme.AddValidationFunc((*rbacv1.ClusterRoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_ClusterRoleList(ctx, op, nil /* fldPath */, obj.(*rbacv1.ClusterRoleList), safe.Cast[*rbacv1.ClusterRoleList](oldObj)) - } - return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} - }) - // type Role - scheme.AddValidationFunc((*rbacv1.Role)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_Role(ctx, op, nil /* fldPath */, obj.(*rbacv1.Role), safe.Cast[*rbacv1.Role](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() { @@ -95,39 +71,9 @@ 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 RoleList - scheme.AddValidationFunc((*rbacv1.RoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_RoleList(ctx, op, nil /* fldPath */, obj.(*rbacv1.RoleList), safe.Cast[*rbacv1.RoleList](oldObj)) - } - return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} - }) return nil } -// Validate_ClusterRole validates an instance of ClusterRole according -// to declarative validation rules in the API schema. -func Validate_ClusterRole(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.ClusterRole) (errs field.ErrorList) { - // field rbacv1.ClusterRole.TypeMeta has no validation - // field rbacv1.ClusterRole.ObjectMeta has no validation - - // field rbacv1.ClusterRole.Rules - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1.PolicyRule) (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_PolicyRule)...) - return - }(fldPath.Child("rules"), obj.Rules, safe.Field(oldObj, func(oldObj *rbacv1.ClusterRole) []rbacv1.PolicyRule { return oldObj.Rules }))...) - - // field rbacv1.ClusterRole.AggregationRule has no validation - 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) { @@ -182,77 +128,6 @@ func Validate_ClusterRoleBindingList(ctx context.Context, op operation.Operation 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) { - // field rbacv1.ClusterRoleList.TypeMeta has no validation - // field rbacv1.ClusterRoleList.ListMeta has no validation - - // field rbacv1.ClusterRoleList.Items - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1.ClusterRole) (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_ClusterRole)...) - return - }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1.ClusterRoleList) []rbacv1.ClusterRole { return oldObj.Items }))...) - - return errs -} - -// Validate_PolicyRule validates an instance of PolicyRule according -// to declarative validation rules in the API schema. -func Validate_PolicyRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.PolicyRule) (errs field.ErrorList) { - // field rbacv1.PolicyRule.Verbs - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []string) (errs field.ErrorList) { - // don't revalidate unchanged data - if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { - return nil - } - // call field-attached validations - earlyReturn := false - if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if earlyReturn { - return // do not proceed - } - return - }(fldPath.Child("verbs"), obj.Verbs, safe.Field(oldObj, func(oldObj *rbacv1.PolicyRule) []string { return oldObj.Verbs }))...) - - // field rbacv1.PolicyRule.APIGroups has no validation - // field rbacv1.PolicyRule.Resources has no validation - // field rbacv1.PolicyRule.ResourceNames has no validation - // field rbacv1.PolicyRule.NonResourceURLs has no validation - return errs -} - -// Validate_Role validates an instance of Role according -// to declarative validation rules in the API schema. -func Validate_Role(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1.Role) (errs field.ErrorList) { - // field rbacv1.Role.TypeMeta has no validation - // field rbacv1.Role.ObjectMeta has no validation - - // field rbacv1.Role.Rules - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1.PolicyRule) (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_PolicyRule)...) - return - }(fldPath.Child("rules"), obj.Rules, safe.Field(oldObj, func(oldObj *rbacv1.Role) []rbacv1.PolicyRule { return oldObj.Rules }))...) - - 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) { @@ -307,27 +182,6 @@ func Validate_RoleBindingList(ctx context.Context, op operation.Operation, fldPa 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) { - // field rbacv1.RoleList.TypeMeta has no validation - // field rbacv1.RoleList.ListMeta has no validation - - // field rbacv1.RoleList.Items - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1.Role) (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_Role)...) - return - }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1.RoleList) []rbacv1.Role { 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) { diff --git a/pkg/apis/rbac/v1alpha1/zz_generated.validations.go b/pkg/apis/rbac/v1alpha1/zz_generated.validations.go index f8176f2e71b..2ac5d5b7624 100644 --- a/pkg/apis/rbac/v1alpha1/zz_generated.validations.go +++ b/pkg/apis/rbac/v1alpha1/zz_generated.validations.go @@ -39,14 +39,6 @@ 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 ClusterRole - scheme.AddValidationFunc((*rbacv1alpha1.ClusterRole)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_ClusterRole(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.ClusterRole), safe.Cast[*rbacv1alpha1.ClusterRole](oldObj)) - } - 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() { @@ -63,22 +55,6 @@ 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 ClusterRoleList - scheme.AddValidationFunc((*rbacv1alpha1.ClusterRoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_ClusterRoleList(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.ClusterRoleList), safe.Cast[*rbacv1alpha1.ClusterRoleList](oldObj)) - } - return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} - }) - // type Role - scheme.AddValidationFunc((*rbacv1alpha1.Role)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_Role(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.Role), safe.Cast[*rbacv1alpha1.Role](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() { @@ -95,39 +71,9 @@ 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 RoleList - scheme.AddValidationFunc((*rbacv1alpha1.RoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_RoleList(ctx, op, nil /* fldPath */, obj.(*rbacv1alpha1.RoleList), safe.Cast[*rbacv1alpha1.RoleList](oldObj)) - } - return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} - }) return nil } -// Validate_ClusterRole validates an instance of ClusterRole according -// to declarative validation rules in the API schema. -func Validate_ClusterRole(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.ClusterRole) (errs field.ErrorList) { - // field rbacv1alpha1.ClusterRole.TypeMeta has no validation - // field rbacv1alpha1.ClusterRole.ObjectMeta has no validation - - // field rbacv1alpha1.ClusterRole.Rules - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.PolicyRule) (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_PolicyRule)...) - return - }(fldPath.Child("rules"), obj.Rules, safe.Field(oldObj, func(oldObj *rbacv1alpha1.ClusterRole) []rbacv1alpha1.PolicyRule { return oldObj.Rules }))...) - - // field rbacv1alpha1.ClusterRole.AggregationRule has no validation - 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) { @@ -184,77 +130,6 @@ func Validate_ClusterRoleBindingList(ctx context.Context, op operation.Operation 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) { - // field rbacv1alpha1.ClusterRoleList.TypeMeta has no validation - // field rbacv1alpha1.ClusterRoleList.ListMeta has no validation - - // field rbacv1alpha1.ClusterRoleList.Items - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.ClusterRole) (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_ClusterRole)...) - return - }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1alpha1.ClusterRoleList) []rbacv1alpha1.ClusterRole { return oldObj.Items }))...) - - return errs -} - -// Validate_PolicyRule validates an instance of PolicyRule according -// to declarative validation rules in the API schema. -func Validate_PolicyRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.PolicyRule) (errs field.ErrorList) { - // field rbacv1alpha1.PolicyRule.Verbs - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []string) (errs field.ErrorList) { - // don't revalidate unchanged data - if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { - return nil - } - // call field-attached validations - earlyReturn := false - if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if earlyReturn { - return // do not proceed - } - return - }(fldPath.Child("verbs"), obj.Verbs, safe.Field(oldObj, func(oldObj *rbacv1alpha1.PolicyRule) []string { return oldObj.Verbs }))...) - - // field rbacv1alpha1.PolicyRule.APIGroups has no validation - // field rbacv1alpha1.PolicyRule.Resources has no validation - // field rbacv1alpha1.PolicyRule.ResourceNames has no validation - // field rbacv1alpha1.PolicyRule.NonResourceURLs has no validation - return errs -} - -// Validate_Role validates an instance of Role according -// to declarative validation rules in the API schema. -func Validate_Role(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1alpha1.Role) (errs field.ErrorList) { - // field rbacv1alpha1.Role.TypeMeta has no validation - // field rbacv1alpha1.Role.ObjectMeta has no validation - - // field rbacv1alpha1.Role.Rules - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.PolicyRule) (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_PolicyRule)...) - return - }(fldPath.Child("rules"), obj.Rules, safe.Field(oldObj, func(oldObj *rbacv1alpha1.Role) []rbacv1alpha1.PolicyRule { return oldObj.Rules }))...) - - 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) { @@ -309,27 +184,6 @@ func Validate_RoleBindingList(ctx context.Context, op operation.Operation, fldPa 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) { - // field rbacv1alpha1.RoleList.TypeMeta has no validation - // field rbacv1alpha1.RoleList.ListMeta has no validation - - // field rbacv1alpha1.RoleList.Items - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1alpha1.Role) (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_Role)...) - return - }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1alpha1.RoleList) []rbacv1alpha1.Role { 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) { diff --git a/pkg/apis/rbac/v1beta1/zz_generated.validations.go b/pkg/apis/rbac/v1beta1/zz_generated.validations.go index 9350b4e4d0f..1b48ba3ca76 100644 --- a/pkg/apis/rbac/v1beta1/zz_generated.validations.go +++ b/pkg/apis/rbac/v1beta1/zz_generated.validations.go @@ -39,14 +39,6 @@ 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 ClusterRole - scheme.AddValidationFunc((*rbacv1beta1.ClusterRole)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_ClusterRole(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.ClusterRole), safe.Cast[*rbacv1beta1.ClusterRole](oldObj)) - } - 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() { @@ -63,22 +55,6 @@ 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 ClusterRoleList - scheme.AddValidationFunc((*rbacv1beta1.ClusterRoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_ClusterRoleList(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.ClusterRoleList), safe.Cast[*rbacv1beta1.ClusterRoleList](oldObj)) - } - return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} - }) - // type Role - scheme.AddValidationFunc((*rbacv1beta1.Role)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_Role(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.Role), safe.Cast[*rbacv1beta1.Role](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() { @@ -95,39 +71,9 @@ 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 RoleList - scheme.AddValidationFunc((*rbacv1beta1.RoleList)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { - switch op.Request.SubresourcePath() { - case "/": - return Validate_RoleList(ctx, op, nil /* fldPath */, obj.(*rbacv1beta1.RoleList), safe.Cast[*rbacv1beta1.RoleList](oldObj)) - } - return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))} - }) return nil } -// Validate_ClusterRole validates an instance of ClusterRole according -// to declarative validation rules in the API schema. -func Validate_ClusterRole(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.ClusterRole) (errs field.ErrorList) { - // field rbacv1beta1.ClusterRole.TypeMeta has no validation - // field rbacv1beta1.ClusterRole.ObjectMeta has no validation - - // field rbacv1beta1.ClusterRole.Rules - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1beta1.PolicyRule) (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_PolicyRule)...) - return - }(fldPath.Child("rules"), obj.Rules, safe.Field(oldObj, func(oldObj *rbacv1beta1.ClusterRole) []rbacv1beta1.PolicyRule { return oldObj.Rules }))...) - - // field rbacv1beta1.ClusterRole.AggregationRule has no validation - 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) { @@ -182,77 +128,6 @@ func Validate_ClusterRoleBindingList(ctx context.Context, op operation.Operation 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) { - // field rbacv1beta1.ClusterRoleList.TypeMeta has no validation - // field rbacv1beta1.ClusterRoleList.ListMeta has no validation - - // field rbacv1beta1.ClusterRoleList.Items - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1beta1.ClusterRole) (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_ClusterRole)...) - return - }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1beta1.ClusterRoleList) []rbacv1beta1.ClusterRole { return oldObj.Items }))...) - - return errs -} - -// Validate_PolicyRule validates an instance of PolicyRule according -// to declarative validation rules in the API schema. -func Validate_PolicyRule(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.PolicyRule) (errs field.ErrorList) { - // field rbacv1beta1.PolicyRule.Verbs - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []string) (errs field.ErrorList) { - // don't revalidate unchanged data - if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { - return nil - } - // call field-attached validations - earlyReturn := false - if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if earlyReturn { - return // do not proceed - } - return - }(fldPath.Child("verbs"), obj.Verbs, safe.Field(oldObj, func(oldObj *rbacv1beta1.PolicyRule) []string { return oldObj.Verbs }))...) - - // field rbacv1beta1.PolicyRule.APIGroups has no validation - // field rbacv1beta1.PolicyRule.Resources has no validation - // field rbacv1beta1.PolicyRule.ResourceNames has no validation - // field rbacv1beta1.PolicyRule.NonResourceURLs has no validation - return errs -} - -// Validate_Role validates an instance of Role according -// to declarative validation rules in the API schema. -func Validate_Role(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *rbacv1beta1.Role) (errs field.ErrorList) { - // field rbacv1beta1.Role.TypeMeta has no validation - // field rbacv1beta1.Role.ObjectMeta has no validation - - // field rbacv1beta1.Role.Rules - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1beta1.PolicyRule) (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_PolicyRule)...) - return - }(fldPath.Child("rules"), obj.Rules, safe.Field(oldObj, func(oldObj *rbacv1beta1.Role) []rbacv1beta1.PolicyRule { return oldObj.Rules }))...) - - 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) { @@ -307,27 +182,6 @@ func Validate_RoleBindingList(ctx context.Context, op operation.Operation, fldPa 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) { - // field rbacv1beta1.RoleList.TypeMeta has no validation - // field rbacv1beta1.RoleList.ListMeta has no validation - - // field rbacv1beta1.RoleList.Items - errs = append(errs, - func(fldPath *field.Path, obj, oldObj []rbacv1beta1.Role) (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_Role)...) - return - }(fldPath.Child("items"), obj.Items, safe.Field(oldObj, func(oldObj *rbacv1beta1.RoleList) []rbacv1beta1.Role { 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) { diff --git a/pkg/apis/rbac/validation/validation.go b/pkg/apis/rbac/validation/validation.go index 511159404db..b65ac19f72e 100644 --- a/pkg/apis/rbac/validation/validation.go +++ b/pkg/apis/rbac/validation/validation.go @@ -103,7 +103,7 @@ func ValidateClusterRoleUpdate(role *rbac.ClusterRole, oldRole *rbac.ClusterRole func ValidatePolicyRule(rule rbac.PolicyRule, isNamespaced bool, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if len(rule.Verbs) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("verbs"), "verbs must contain at least one value").MarkCoveredByDeclarative()) + allErrs = append(allErrs, field.Required(fldPath.Child("verbs"), "verbs must contain at least one value")) } if len(rule.NonResourceURLs) > 0 { diff --git a/pkg/registry/rbac/clusterrole/declarative_validation_test.go b/pkg/registry/rbac/clusterrole/declarative_validation_test.go index 6daa5041b01..89689554eee 100644 --- a/pkg/registry/rbac/clusterrole/declarative_validation_test.go +++ b/pkg/registry/rbac/clusterrole/declarative_validation_test.go @@ -19,7 +19,6 @@ package clusterrole 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" @@ -43,33 +42,7 @@ func testDeclarativeValidateForDeclarative(t *testing.T, apiVersion string) { input rbac.ClusterRole expectedErrs field.ErrorList }{ - "missing verbs": { - input: rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{Name: "test-role"}, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"pods"}, - }, - }, - }, - expectedErrs: field.ErrorList{ - field.Required(field.NewPath("rules").Index(0).Child("verbs"), "must have at least one verb"), - }, - }, - "valid rule": { - input: rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{Name: "valid-role"}, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"pods"}, - Verbs: []string{"get", "list"}, - }, - }, - }, - expectedErrs: field.ErrorList{}, - }, + // TODO: Add more test cases } for k, tc := range testCases { t.Run(k, func(t *testing.T) { @@ -94,53 +67,7 @@ func testValidateUpdateForDeclarative(t *testing.T, apiVersion string) { update rbac.ClusterRole expectedErrs field.ErrorList }{ - "update missing verbs": { - old: rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{Name: "role"}, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"pods"}, - Verbs: []string{"get"}, - }, - }, - }, - update: rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{Name: "role", ResourceVersion: "1"}, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"pods"}, - }, - }, - }, - expectedErrs: field.ErrorList{ - field.Required(field.NewPath("rules").Index(0).Child("verbs"), "must have at least one verb"), - }, - }, - "valid update": { - old: rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{Name: "role"}, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"pods"}, - Verbs: []string{"get"}, - }, - }, - }, - update: rbac.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{Name: "role", ResourceVersion: "1"}, - Rules: []rbac.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"pods"}, - Verbs: []string{"get", "list"}, - }, - }, - }, - expectedErrs: field.ErrorList{}, - }, + // TODO: Add more test cases } for k, tc := range testCases { t.Run(k, func(t *testing.T) { diff --git a/pkg/registry/rbac/clusterrole/strategy.go b/pkg/registry/rbac/clusterrole/strategy.go index e5d63cbc8bb..4ed857f47f8 100644 --- a/pkg/registry/rbac/clusterrole/strategy.go +++ b/pkg/registry/rbac/clusterrole/strategy.go @@ -78,14 +78,7 @@ func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorLis } allErrs := validation.ValidateClusterRole(clusterRole, opts) - return rest.ValidateDeclarativelyWithMigrationChecks( - ctx, - legacyscheme.Scheme, - clusterRole, - nil, - allErrs, - operation.Create, - ) + return rest.ValidateDeclarativelyWithMigrationChecks(ctx,legacyscheme.Scheme,clusterRole,nil,allErrs,operation.Create) } // WarningsOnCreate returns warnings for the creation of the given object. @@ -105,14 +98,7 @@ func (strategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) fie } errs := validation.ValidateClusterRoleUpdate(newObj, oldObj, opts) - return rest.ValidateDeclarativelyWithMigrationChecks( - ctx, - legacyscheme.Scheme, - newObj, - oldObj, - errs, - operation.Update, - ) + return rest.ValidateDeclarativelyWithMigrationChecks(ctx,legacyscheme.Scheme,newObj,oldObj,errs,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 68690a3a74c..772561c0df0 100644 --- a/staging/src/k8s.io/api/rbac/v1/types.go +++ b/staging/src/k8s.io/api/rbac/v1/types.go @@ -49,7 +49,6 @@ const ( type PolicyRule struct { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic - // +k8s:required Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of diff --git a/staging/src/k8s.io/api/rbac/v1alpha1/types.go b/staging/src/k8s.io/api/rbac/v1alpha1/types.go index 2a622e729c9..38887b9b8a1 100644 --- a/staging/src/k8s.io/api/rbac/v1alpha1/types.go +++ b/staging/src/k8s.io/api/rbac/v1alpha1/types.go @@ -49,7 +49,6 @@ const ( type PolicyRule struct { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic - // +k8s:required Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of diff --git a/staging/src/k8s.io/api/rbac/v1beta1/types.go b/staging/src/k8s.io/api/rbac/v1beta1/types.go index d2e6b8aa09a..40ad5db7283 100644 --- a/staging/src/k8s.io/api/rbac/v1beta1/types.go +++ b/staging/src/k8s.io/api/rbac/v1beta1/types.go @@ -49,7 +49,6 @@ const ( type PolicyRule struct { // Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs. // +listType=atomic - // +k8s:required Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"` // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of