unify the validation rules on initializer name
This commit is contained in:
parent
a64eeb47f6
commit
c33de9f204
@ -22,7 +22,7 @@ import (
|
|||||||
|
|
||||||
genericvalidation "k8s.io/apimachinery/pkg/api/validation"
|
genericvalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
validationutil "k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||||
)
|
)
|
||||||
@ -38,15 +38,7 @@ func ValidateInitializerConfiguration(ic *admissionregistration.InitializerConfi
|
|||||||
func validateInitializer(initializer *admissionregistration.Initializer, fldPath *field.Path) field.ErrorList {
|
func validateInitializer(initializer *admissionregistration.Initializer, fldPath *field.Path) field.ErrorList {
|
||||||
var allErrors field.ErrorList
|
var allErrors field.ErrorList
|
||||||
// initlializer.Name must be fully qualified
|
// initlializer.Name must be fully qualified
|
||||||
if len(initializer.Name) == 0 {
|
allErrors = append(allErrors, validation.IsFullyQualifiedName(fldPath.Child("name"), initializer.Name)...)
|
||||||
allErrors = append(allErrors, field.Required(fldPath.Child("name"), ""))
|
|
||||||
}
|
|
||||||
if errs := validationutil.IsDNS1123Subdomain(initializer.Name); len(errs) > 0 {
|
|
||||||
allErrors = append(allErrors, field.Invalid(fldPath.Child("name"), initializer.Name, strings.Join(errs, ",")))
|
|
||||||
}
|
|
||||||
if len(strings.Split(initializer.Name, ".")) < 3 {
|
|
||||||
allErrors = append(allErrors, field.Invalid(fldPath.Child("name"), initializer.Name, "should be a domain with at least two dots"))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, rule := range initializer.Rules {
|
for i, rule := range initializer.Rules {
|
||||||
notAllowSubresources := false
|
notAllowSubresources := false
|
||||||
@ -186,15 +178,7 @@ func ValidateExternalAdmissionHookConfiguration(e *admissionregistration.Externa
|
|||||||
func validateExternalAdmissionHook(hook *admissionregistration.ExternalAdmissionHook, fldPath *field.Path) field.ErrorList {
|
func validateExternalAdmissionHook(hook *admissionregistration.ExternalAdmissionHook, fldPath *field.Path) field.ErrorList {
|
||||||
var allErrors field.ErrorList
|
var allErrors field.ErrorList
|
||||||
// hook.Name must be fully qualified
|
// hook.Name must be fully qualified
|
||||||
if len(hook.Name) == 0 {
|
allErrors = append(allErrors, validation.IsFullyQualifiedName(fldPath.Child("name"), hook.Name)...)
|
||||||
allErrors = append(allErrors, field.Required(fldPath.Child("name"), ""))
|
|
||||||
}
|
|
||||||
if errs := validationutil.IsDNS1123Subdomain(hook.Name); len(errs) > 0 {
|
|
||||||
allErrors = append(allErrors, field.Invalid(fldPath.Child("name"), hook.Name, strings.Join(errs, ",")))
|
|
||||||
}
|
|
||||||
if len(strings.Split(hook.Name, ".")) < 3 {
|
|
||||||
allErrors = append(allErrors, field.Invalid(fldPath.Child("name"), hook.Name, "should be a domain with at least two dots"))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, rule := range hook.Rules {
|
for i, rule := range hook.Rules {
|
||||||
allErrors = append(allErrors, validateRuleWithOperations(&rule, fldPath.Child("rules").Index(i))...)
|
allErrors = append(allErrors, validateRuleWithOperations(&rule, fldPath.Child("rules").Index(i))...)
|
||||||
|
@ -62,7 +62,7 @@ func TestValidateInitializerConfiguration(t *testing.T) {
|
|||||||
Name: "",
|
Name: "",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
expectedError: `initializers[1].name: Invalid value: "k8s.io": should be a domain with at least two dots, initializers[2].name: Required value`,
|
expectedError: `initializers[1].name: Invalid value: "k8s.io": should be a domain with at least three segments separated by dots, initializers[2].name: Required value`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "APIGroups must not be empty or nil",
|
name: "APIGroups must not be empty or nil",
|
||||||
@ -274,7 +274,7 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
|
|||||||
Name: "",
|
Name: "",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
expectedError: `externalAdmissionHooks[1].name: Invalid value: "k8s.io": should be a domain with at least two dots, externalAdmissionHooks[2].name: Required value`,
|
expectedError: `externalAdmissionHooks[1].name: Invalid value: "k8s.io": should be a domain with at least three segments separated by dots, externalAdmissionHooks[2].name: Required value`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Operations must not be empty or nil",
|
name: "Operations must not be empty or nil",
|
||||||
|
@ -195,9 +195,7 @@ func ValidateInitializers(initializers *metav1.Initializers, fldPath *field.Path
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
for i, initializer := range initializers.Pending {
|
for i, initializer := range initializers.Pending {
|
||||||
for _, msg := range validation.IsQualifiedName(initializer.Name) {
|
allErrs = append(allErrs, validation.IsFullyQualifiedName(fldPath.Child("pending").Index(i).Child("name"), initializer.Name)...)
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("pending").Index(i), initializer.Name, msg))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
allErrs = append(allErrs, validateInitializersResult(initializers.Result, fldPath.Child("result"))...)
|
allErrs = append(allErrs, validateInitializersResult(initializers.Result, fldPath.Child("result"))...)
|
||||||
return allErrs
|
return allErrs
|
||||||
|
@ -10,11 +10,13 @@ go_test(
|
|||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = ["validation_test.go"],
|
srcs = ["validation_test.go"],
|
||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
|
deps = ["//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library"],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["validation.go"],
|
srcs = ["validation.go"],
|
||||||
|
deps = ["//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library"],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -22,6 +22,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
const qnameCharFmt string = "[A-Za-z0-9]"
|
const qnameCharFmt string = "[A-Za-z0-9]"
|
||||||
@ -67,6 +69,21 @@ func IsQualifiedName(value string) []string {
|
|||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsFullyQualifiedName checks if the name is fully qualified.
|
||||||
|
func IsFullyQualifiedName(fldPath *field.Path, name string) field.ErrorList {
|
||||||
|
var allErrors field.ErrorList
|
||||||
|
if len(name) == 0 {
|
||||||
|
return append(allErrors, field.Required(fldPath, ""))
|
||||||
|
}
|
||||||
|
if errs := IsDNS1123Subdomain(name); len(errs) > 0 {
|
||||||
|
return append(allErrors, field.Invalid(fldPath, name, strings.Join(errs, ",")))
|
||||||
|
}
|
||||||
|
if len(strings.Split(name, ".")) < 3 {
|
||||||
|
return append(allErrors, field.Invalid(fldPath, name, "should be a domain with at least three segments separated by dots"))
|
||||||
|
}
|
||||||
|
return allErrors
|
||||||
|
}
|
||||||
|
|
||||||
const labelValueFmt string = "(" + qualifiedNameFmt + ")?"
|
const labelValueFmt string = "(" + qualifiedNameFmt + ")?"
|
||||||
const labelValueErrMsg string = "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character"
|
const labelValueErrMsg string = "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character"
|
||||||
const LabelValueMaxLength int = 63
|
const LabelValueMaxLength int = 63
|
||||||
|
@ -19,6 +19,8 @@ package validation
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIsDNS1123Label(t *testing.T) {
|
func TestIsDNS1123Label(t *testing.T) {
|
||||||
@ -450,3 +452,38 @@ func TestIsWildcardDNS1123Subdomain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsFullyQualifiedName(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
targetName string
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "name needs to be fully qualified, i.e., contains at least 2 dots",
|
||||||
|
targetName: "k8s.io",
|
||||||
|
err: "should be a domain with at least three segments separated by dots",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "name cannot be empty",
|
||||||
|
targetName: "",
|
||||||
|
err: "Required value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "name must conform to RFC 1123",
|
||||||
|
targetName: "A.B.C",
|
||||||
|
err: "a DNS-1123 subdomain must consist of lower case alphanumeric characters",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
err := IsFullyQualifiedName(field.NewPath(""), tc.targetName).ToAggregate()
|
||||||
|
switch {
|
||||||
|
case tc.err == "" && err != nil:
|
||||||
|
t.Errorf("%q: unexpected error: %v", tc.name, err)
|
||||||
|
case tc.err != "" && err == nil:
|
||||||
|
t.Errorf("%q: unexpected no error, expected %s", tc.name, tc.err)
|
||||||
|
case tc.err != "" && err != nil && !strings.Contains(err.Error(), tc.err):
|
||||||
|
t.Errorf("%q: expected %s, got %v", tc.name, tc.err, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user