Skip to content

Commit

Permalink
Simplify validators (#3818)
Browse files Browse the repository at this point in the history
* Simplify validators
  • Loading branch information
jjngx authored May 8, 2023
1 parent 1e92ba4 commit 19b8ad1
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 467 deletions.
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

0 comments on commit 19b8ad1

Please sign in to comment.