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 <mkhan@redhat.com>
This commit is contained in:
Monis Khan 2018-04-19 11:01:07 -04:00
parent 8306b692b6
commit fc6ee7e782
No known key found for this signature in database
GPG Key ID: 52C90ADA01B269B8

View File

@ -25,19 +25,20 @@ import (
"k8s.io/kubernetes/pkg/apis/rbac" "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: // 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/kubernetes/kubernetes/blob/60db50/pkg/api/validation/name.go
// * https://github.com/openshift/origin/blob/388478/pkg/api/helpers.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) return path.IsValidPathSegmentName(name)
} }
func ValidateRole(role *rbac.Role) field.ErrorList { func ValidateRole(role *rbac.Role) field.ErrorList {
allErrs := 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 { 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...) 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 { func ValidateClusterRole(role *rbac.ClusterRole) field.ErrorList {
allErrs := 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 { 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...) allErrs = append(allErrs, err...)
} }
} }
@ -92,7 +93,8 @@ func ValidateClusterRoleUpdate(role *rbac.ClusterRole, oldRole *rbac.ClusterRole
return allErrs 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{} allErrs := field.ErrorList{}
if len(rule.Verbs) == 0 { if len(rule.Verbs) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("verbs"), "verbs must contain at least one value")) 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 { func ValidateRoleBinding(roleBinding *rbac.RoleBinding) field.ErrorList {
allErrs := 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 // 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 // advantage of the binding infrastructure
@ -137,14 +139,14 @@ func ValidateRoleBinding(roleBinding *rbac.RoleBinding) field.ErrorList {
if len(roleBinding.RoleRef.Name) == 0 { if len(roleBinding.RoleRef.Name) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), "")) allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), ""))
} else { } 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)) allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg))
} }
} }
subjectsPath := field.NewPath("subjects") subjectsPath := field.NewPath("subjects")
for i, subject := range roleBinding.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 return allErrs
@ -163,7 +165,7 @@ func ValidateRoleBindingUpdate(roleBinding *rbac.RoleBinding, oldRoleBinding *rb
func ValidateClusterRoleBinding(roleBinding *rbac.ClusterRoleBinding) field.ErrorList { func ValidateClusterRoleBinding(roleBinding *rbac.ClusterRoleBinding) field.ErrorList {
allErrs := 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 // 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 // advantage of the binding infrastructure
@ -181,14 +183,14 @@ func ValidateClusterRoleBinding(roleBinding *rbac.ClusterRoleBinding) field.Erro
if len(roleBinding.RoleRef.Name) == 0 { if len(roleBinding.RoleRef.Name) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), "")) allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), ""))
} else { } 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)) allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg))
} }
} }
subjectsPath := field.NewPath("subjects") subjectsPath := field.NewPath("subjects")
for i, subject := range roleBinding.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 return allErrs
@ -205,7 +207,8 @@ func ValidateClusterRoleBindingUpdate(roleBinding *rbac.ClusterRoleBinding, oldR
return allErrs 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{} allErrs := field.ErrorList{}
if len(subject.Name) == 0 { if len(subject.Name) == 0 {