mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
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:
parent
8306b692b6
commit
fc6ee7e782
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user