Make IsQualifiedName return error strings

This commit is contained in:
Tim Hockin
2015-12-15 21:28:42 -08:00
parent f6eefd4762
commit 72955770f3
11 changed files with 102 additions and 72 deletions

View File

@@ -59,7 +59,6 @@ func InclusiveRangeErrorMsg(lo, hi int) string {
}
var labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt)
var qualifiedNameErrorMsg string = fmt.Sprintf(`must be a qualified name (at most %d characters, matching regex %s), with an optional DNS subdomain prefix (at most %d characters, matching regex %s) and slash (/): e.g. "MyName" or "example.com/MyName"`, validation.QualifiedNameMaxLength, validation.QualifiedNameFmt, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt)
var DNSSubdomainErrorMsg string = fmt.Sprintf(`must be a DNS subdomain (at most %d characters, matching regex %s): e.g. "example.com"`, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt)
var DNS1123LabelErrorMsg string = fmt.Sprintf(`must be a DNS label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS1123LabelMaxLength, validation.DNS1123LabelFmt)
var DNS952LabelErrorMsg string = fmt.Sprintf(`must be a DNS 952 label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS952LabelMaxLength, validation.DNS952LabelFmt)
@@ -94,8 +93,8 @@ func ValidateAnnotations(annotations map[string]string, fldPath *field.Path) fie
allErrs := field.ErrorList{}
var totalSize int64
for k, v := range annotations {
if !validation.IsQualifiedName(strings.ToLower(k)) {
allErrs = append(allErrs, field.Invalid(fldPath, k, qualifiedNameErrorMsg))
for _, err := range validation.IsQualifiedName(strings.ToLower(k)) {
allErrs = append(allErrs, field.Invalid(fldPath, k, err))
}
totalSize += (int64)(len(k)) + (int64)(len(v))
}
@@ -2148,8 +2147,11 @@ func ValidateNodeUpdate(node, oldNode *api.Node) field.ErrorList {
// Refer to docs/design/resources.md for more details.
func validateResourceName(value string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if !validation.IsQualifiedName(value) {
return append(allErrs, field.Invalid(fldPath, value, qualifiedNameErrorMsg))
for _, err := range validation.IsQualifiedName(value) {
allErrs = append(allErrs, field.Invalid(fldPath, value, err))
}
if len(allErrs) != 0 {
return allErrs
}
if len(strings.Split(value, "/")) == 1 {
@@ -2188,8 +2190,11 @@ func validateResourceQuotaResourceName(value string, fldPath *field.Path) field.
// Validate limit range types
func validateLimitRangeTypeName(value string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if !validation.IsQualifiedName(value) {
return append(allErrs, field.Invalid(fldPath, value, qualifiedNameErrorMsg))
for _, err := range validation.IsQualifiedName(value) {
allErrs = append(allErrs, field.Invalid(fldPath, value, err))
}
if len(allErrs) != 0 {
return allErrs
}
if len(strings.Split(value, "/")) == 1 {
@@ -2656,8 +2661,11 @@ func ValidateNamespace(namespace *api.Namespace) field.ErrorList {
// Validate finalizer names
func validateFinalizerName(stringValue string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if !validation.IsQualifiedName(stringValue) {
return append(allErrs, field.Invalid(fldPath, stringValue, qualifiedNameErrorMsg))
for _, err := range validation.IsQualifiedName(stringValue) {
allErrs = append(allErrs, field.Invalid(fldPath, stringValue, err))
}
if len(allErrs) != 0 {
return allErrs
}
if len(strings.Split(stringValue, "/")) == 1 {

View File

@@ -310,20 +310,23 @@ func TestValidateAnnotations(t *testing.T) {
}
}
nameErrorCases := []map[string]string{
{"nospecialchars^=@": "bar"},
{"cantendwithadash-": "bar"},
{"only/one/slash": "bar"},
{strings.Repeat("a", 254): "bar"},
nameErrorCases := []struct {
annotations map[string]string
expect string
}{
{map[string]string{"nospecialchars^=@": "bar"}, "must match the regex"},
{map[string]string{"cantendwithadash-": "bar"}, "must match the regex"},
{map[string]string{"only/one/slash": "bar"}, "must match the regex"},
{map[string]string{strings.Repeat("a", 254): "bar"}, "must be no more than"},
}
for i := range nameErrorCases {
errs := ValidateAnnotations(nameErrorCases[i], field.NewPath("field"))
errs := ValidateAnnotations(nameErrorCases[i].annotations, field.NewPath("field"))
if len(errs) != 1 {
t.Errorf("case[%d] expected failure", i)
}
detail := errs[0].Detail
if detail != qualifiedNameErrorMsg {
t.Errorf("error detail %s should be equal %s", detail, qualifiedNameErrorMsg)
t.Errorf("case[%d]: expected failure", i)
} else {
if !strings.Contains(errs[0].Detail, nameErrorCases[i].expect) {
t.Errorf("case[%d]: error details do not include %q: %q", i, nameErrorCases[i].expect, errs[0].Detail)
}
}
}
totalSizeErrorCases := []map[string]string{
@@ -4242,23 +4245,24 @@ func TestValidateResourceNames(t *testing.T) {
table := []struct {
input string
success bool
expect string
}{
{"memory", true},
{"cpu", true},
{"network", false},
{"disk", false},
{"", false},
{".", false},
{"..", false},
{"my.favorite.app.co/12345", true},
{"my.favorite.app.co/_12345", false},
{"my.favorite.app.co/12345_", false},
{"kubernetes.io/..", false},
{"kubernetes.io/" + strings.Repeat("a", 63), true},
{"kubernetes.io/" + strings.Repeat("a", 64), false},
{"kubernetes.io//", false},
{"kubernetes.io", false},
{"kubernetes.io/will/not/work/", false},
{"memory", true, ""},
{"cpu", true, ""},
{"network", false, ""},
{"disk", false, ""},
{"", false, ""},
{".", false, ""},
{"..", false, ""},
{"my.favorite.app.co/12345", true, ""},
{"my.favorite.app.co/_12345", false, ""},
{"my.favorite.app.co/12345_", false, ""},
{"kubernetes.io/..", false, ""},
{"kubernetes.io/" + strings.Repeat("a", 63), true, ""},
{"kubernetes.io/" + strings.Repeat("a", 64), false, ""},
{"kubernetes.io//", false, ""},
{"kubernetes.io", false, ""},
{"kubernetes.io/will/not/work/", false, ""},
}
for k, item := range table {
err := validateResourceName(item.input, field.NewPath("field"))
@@ -4268,8 +4272,8 @@ func TestValidateResourceNames(t *testing.T) {
t.Errorf("expected failure for input %q", item.input)
for i := range err {
detail := err[i].Detail
if detail != "" && detail != qualifiedNameErrorMsg {
t.Errorf("%d: expected error detail either empty or %s, got %s", k, qualifiedNameErrorMsg, detail)
if detail != "" && !strings.Contains(detail, item.expect) {
t.Errorf("%d: expected error detail either empty or %s, got %s", k, item.expect, detail)
}
}
}