From fc6ee7e7824afeb00cf8ade82d836613a7e54daa Mon Sep 17 00:00:00 2001 From: Monis Khan Date: Thu, 19 Apr 2018 11:01:07 -0400 Subject: [PATCH] Export RBAC validation functions This change exports the RBAC validation functions to allow types outside of the RBAC API group to embed a RBAC type and reuse this validation logic. Note that only ValidateRBACName, ValidatePolicyRule and ValidateRoleBindingSubject were exported. The rest of the functions were already exported. Signed-off-by: Monis Khan --- pkg/apis/rbac/validation/validation.go | 29 ++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/pkg/apis/rbac/validation/validation.go b/pkg/apis/rbac/validation/validation.go index 92fc5bdb15b..1cb0850cc3a 100644 --- a/pkg/apis/rbac/validation/validation.go +++ b/pkg/apis/rbac/validation/validation.go @@ -25,19 +25,20 @@ import ( "k8s.io/kubernetes/pkg/apis/rbac" ) +// ValidateRBACName is exported to allow types outside of the RBAC API group to reuse this validation logic // Minimal validation of names for roles and bindings. Identical to the validation for Openshift. See: // * https://github.com/kubernetes/kubernetes/blob/60db50/pkg/api/validation/name.go // * https://github.com/openshift/origin/blob/388478/pkg/api/helpers.go -func minimalNameRequirements(name string, prefix bool) []string { +func ValidateRBACName(name string, prefix bool) []string { return path.IsValidPathSegmentName(name) } func ValidateRole(role *rbac.Role) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, true, minimalNameRequirements, field.NewPath("metadata"))...) + allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, true, ValidateRBACName, field.NewPath("metadata"))...) for i, rule := range role.Rules { - if err := validatePolicyRule(rule, true, field.NewPath("rules").Index(i)); err != nil { + if err := ValidatePolicyRule(rule, true, field.NewPath("rules").Index(i)); err != nil { allErrs = append(allErrs, err...) } } @@ -56,10 +57,10 @@ func ValidateRoleUpdate(role *rbac.Role, oldRole *rbac.Role) field.ErrorList { func ValidateClusterRole(role *rbac.ClusterRole) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, false, minimalNameRequirements, field.NewPath("metadata"))...) + allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, false, ValidateRBACName, field.NewPath("metadata"))...) for i, rule := range role.Rules { - if err := validatePolicyRule(rule, false, field.NewPath("rules").Index(i)); err != nil { + if err := ValidatePolicyRule(rule, false, field.NewPath("rules").Index(i)); err != nil { allErrs = append(allErrs, err...) } } @@ -92,7 +93,8 @@ func ValidateClusterRoleUpdate(role *rbac.ClusterRole, oldRole *rbac.ClusterRole return allErrs } -func validatePolicyRule(rule rbac.PolicyRule, isNamespaced bool, fldPath *field.Path) field.ErrorList { +// ValidatePolicyRule is exported to allow types outside of the RBAC API group to embed a rbac.PolicyRule and reuse this validation logic +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")) @@ -119,7 +121,7 @@ func validatePolicyRule(rule rbac.PolicyRule, isNamespaced bool, fldPath *field. func ValidateRoleBinding(roleBinding *rbac.RoleBinding) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, true, minimalNameRequirements, field.NewPath("metadata"))...) + allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, true, ValidateRBACName, field.NewPath("metadata"))...) // TODO allow multiple API groups. For now, restrict to one, but I can envision other experimental roles in other groups taking // advantage of the binding infrastructure @@ -137,14 +139,14 @@ func ValidateRoleBinding(roleBinding *rbac.RoleBinding) field.ErrorList { if len(roleBinding.RoleRef.Name) == 0 { allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), "")) } else { - for _, msg := range minimalNameRequirements(roleBinding.RoleRef.Name, false) { + for _, msg := range ValidateRBACName(roleBinding.RoleRef.Name, false) { allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg)) } } subjectsPath := field.NewPath("subjects") for i, subject := range roleBinding.Subjects { - allErrs = append(allErrs, validateRoleBindingSubject(subject, true, subjectsPath.Index(i))...) + allErrs = append(allErrs, ValidateRoleBindingSubject(subject, true, subjectsPath.Index(i))...) } return allErrs @@ -163,7 +165,7 @@ func ValidateRoleBindingUpdate(roleBinding *rbac.RoleBinding, oldRoleBinding *rb func ValidateClusterRoleBinding(roleBinding *rbac.ClusterRoleBinding) field.ErrorList { allErrs := field.ErrorList{} - allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, false, minimalNameRequirements, field.NewPath("metadata"))...) + allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, false, ValidateRBACName, field.NewPath("metadata"))...) // TODO allow multiple API groups. For now, restrict to one, but I can envision other experimental roles in other groups taking // advantage of the binding infrastructure @@ -181,14 +183,14 @@ func ValidateClusterRoleBinding(roleBinding *rbac.ClusterRoleBinding) field.Erro if len(roleBinding.RoleRef.Name) == 0 { allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), "")) } else { - for _, msg := range minimalNameRequirements(roleBinding.RoleRef.Name, false) { + for _, msg := range ValidateRBACName(roleBinding.RoleRef.Name, false) { allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg)) } } subjectsPath := field.NewPath("subjects") for i, subject := range roleBinding.Subjects { - allErrs = append(allErrs, validateRoleBindingSubject(subject, false, subjectsPath.Index(i))...) + allErrs = append(allErrs, ValidateRoleBindingSubject(subject, false, subjectsPath.Index(i))...) } return allErrs @@ -205,7 +207,8 @@ func ValidateClusterRoleBindingUpdate(roleBinding *rbac.ClusterRoleBinding, oldR return allErrs } -func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath *field.Path) field.ErrorList { +// ValidateRoleBindingSubject is exported to allow types outside of the RBAC API group to embed a rbac.Subject and reuse this validation logic +func ValidateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if len(subject.Name) == 0 {