Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify validators #3818

Merged
merged 6 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 19 additions & 35 deletions pkg/apis/configuration/validation/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ func ValidateEscapedString(body string, examples ...string) error {
}

func validateVariable(nVar string, validVars map[string]bool, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if !validVars[nVar] {
msg := fmt.Sprintf("'%v' contains an invalid NGINX variable. Accepted variables are: %v", nVar, mapToPrettyString(validVars))
allErrs = append(allErrs, field.Invalid(fieldPath, nVar, msg))
return field.ErrorList{field.Invalid(fieldPath, nVar, msg)}
}
return allErrs
return nil
}

// isValidSpecialHeaderLikeVariable validates special variables $http_, $jwt_header_, $jwt_claim_
Expand Down Expand Up @@ -103,26 +101,25 @@ func validateSpecialVariable(nVar string, fieldPath *field.Path, isPlus bool) fi
}

func validateStringWithVariables(str string, fieldPath *field.Path, specialVars []string, validVars map[string]bool, isPlus bool) field.ErrorList {
allErrs := field.ErrorList{}

if strings.HasSuffix(str, "$") {
return append(allErrs, field.Invalid(fieldPath, str, "must not end with $"))
return field.ErrorList{field.Invalid(fieldPath, str, "must not end with $")}
}

for i, c := range str {
if c == '$' {
msg := "variables must be enclosed in curly braces, for example ${host}"

if str[i+1] != '{' {
return append(allErrs, field.Invalid(fieldPath, str, msg))
return field.ErrorList{field.Invalid(fieldPath, str, msg)}
}

if !strings.Contains(str[i+1:], "}") {
return append(allErrs, field.Invalid(fieldPath, str, msg))
return field.ErrorList{field.Invalid(fieldPath, str, msg)}
}
}
}

allErrs := field.ErrorList{}
nginxVars := captureVariables(str)
for _, nVar := range nginxVars {
special := false
Expand All @@ -144,67 +141,56 @@ func validateStringWithVariables(str string, fieldPath *field.Path, specialVars
}

func validateTime(time string, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if time == "" {
return allErrs
return nil
}

if _, err := configs.ParseTime(time); err != nil {
return append(allErrs, field.Invalid(fieldPath, time, err.Error()))
return field.ErrorList{field.Invalid(fieldPath, time, err.Error())}
}

return allErrs
return nil
}

// http://nginx.org/en/docs/syntax.html
const offsetErrMsg = "must consist of numeric characters followed by a valid size suffix. 'k|K|m|M|g|G"

func validateOffset(offset string, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if offset == "" {
return allErrs
return nil
}

if _, err := configs.ParseOffset(offset); err != nil {
msg := validation.RegexError(offsetErrMsg, configs.OffsetFmt, "16", "32k", "64M", "2G")
return append(allErrs, field.Invalid(fieldPath, offset, msg))
return field.ErrorList{field.Invalid(fieldPath, offset, msg)}
}

return allErrs
return nil
}

// http://nginx.org/en/docs/syntax.html
const sizeErrMsg = "must consist of numeric characters followed by a valid size suffix. 'k|K|m|M"

func validateSize(size string, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if size == "" {
return allErrs
return nil
}

if _, err := configs.ParseSize(size); err != nil {
msg := validation.RegexError(sizeErrMsg, configs.SizeFmt, "16", "32k", "64M")
return append(allErrs, field.Invalid(fieldPath, size, msg))
return field.ErrorList{field.Invalid(fieldPath, size, msg)}
}
return allErrs
return nil
}

// validateSecretName checks if a secret name is valid.
// It performs the same validation as ValidateSecretName from k8s.io/kubernetes/pkg/apis/core/validation/validation.go.
func validateSecretName(name string, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if name == "" {
return allErrs
return nil
}

allErrs := field.ErrorList{}
for _, msg := range validation.IsDNS1123Subdomain(name) {
allErrs = append(allErrs, field.Invalid(fieldPath, name, msg))
}

return allErrs
}

Expand All @@ -220,11 +206,9 @@ func mapToPrettyString(m map[string]bool) string {

// ValidateParameter validates a parameter against a map of valid parameters for the directive
func ValidateParameter(nPar string, validParams map[string]bool, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if !validParams[nPar] {
msg := fmt.Sprintf("'%v' contains an invalid NGINX parameter. Accepted parameters are: %v", nPar, mapToPrettyString(validParams))
allErrs = append(allErrs, field.Invalid(fieldPath, nPar, msg))
return field.ErrorList{field.Invalid(fieldPath, nPar, msg)}
}
return allErrs
return nil
}
15 changes: 4 additions & 11 deletions pkg/apis/configuration/validation/globalconfiguration.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,29 @@ func generatePortProtocolKey(port int, protocol string) string {
}

func (gcv *GlobalConfigurationValidator) validateListener(listener v1alpha1.Listener, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

allErrs = append(allErrs, validateGlobalConfigurationListenerName(listener.Name, fieldPath.Child("name"))...)
allErrs := validateGlobalConfigurationListenerName(listener.Name, fieldPath.Child("name"))
allErrs = append(allErrs, gcv.validateListenerPort(listener.Port, fieldPath.Child("port"))...)
allErrs = append(allErrs, validateListenerProtocol(listener.Protocol, fieldPath.Child("protocol"))...)

return allErrs
}

func validateGlobalConfigurationListenerName(name string, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if name == v1alpha1.TLSPassthroughListenerName {
return append(allErrs, field.Forbidden(fieldPath, "is the name of a built-in listener"))
return field.ErrorList{field.Forbidden(fieldPath, "is the name of a built-in listener")}
}

return validateListenerName(name, fieldPath)
}

func (gcv *GlobalConfigurationValidator) validateListenerPort(port int, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if gcv.forbiddenListenerPorts[port] {
msg := fmt.Sprintf("port %v is forbidden", port)
return append(allErrs, field.Forbidden(fieldPath, msg))
return field.ErrorList{field.Forbidden(fieldPath, msg)}
}

allErrs := field.ErrorList{}
for _, msg := range validation.IsValidPortNum(port) {
allErrs = append(allErrs, field.Invalid(fieldPath, port, msg))
}

return allErrs
}
Loading