mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Make IsValidLabelValue return error strings
This commit is contained in:
parent
a0cc59f28a
commit
66d0d87829
@ -181,12 +181,12 @@ func SlaveAttributesToLabels(attrs []*mesos.Attribute) map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if errs := validation.IsQualifiedName(k); len(errs) != 0 {
|
if errs := validation.IsQualifiedName(k); len(errs) != 0 {
|
||||||
log.V(3).Infof("ignoring invalid node label name %q", k, errs)
|
log.V(3).Infof("ignoring invalid node label %q: %v", k, errs)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !validation.IsValidLabelValue(v) {
|
if errs := validation.IsValidLabelValue(v); len(errs) != 0 {
|
||||||
log.V(3).Infof("ignoring invalid node label %s value: %q", k, v)
|
log.V(3).Infof("ignoring invalid node %s=%q: %v", k, v, errs)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,17 +17,11 @@ limitations under the License.
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/util/validation"
|
"k8s.io/kubernetes/pkg/util/validation"
|
||||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt)
|
|
||||||
)
|
|
||||||
|
|
||||||
func ValidateLabelSelector(ps *unversioned.LabelSelector, fldPath *field.Path) field.ErrorList {
|
func ValidateLabelSelector(ps *unversioned.LabelSelector, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
if ps == nil {
|
if ps == nil {
|
||||||
@ -72,8 +66,8 @@ func ValidateLabels(labels map[string]string, fldPath *field.Path) field.ErrorLi
|
|||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
for k, v := range labels {
|
for k, v := range labels {
|
||||||
allErrs = append(allErrs, ValidateLabelName(k, fldPath)...)
|
allErrs = append(allErrs, ValidateLabelName(k, fldPath)...)
|
||||||
if !validation.IsValidLabelValue(v) {
|
for _, err := range validation.IsValidLabelValue(v) {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath, v, labelValueErrorMsg))
|
allErrs = append(allErrs, field.Invalid(fldPath, v, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allErrs
|
return allErrs
|
||||||
|
@ -67,20 +67,22 @@ func TestValidateLabels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
labelValueErrorCases := []map[string]string{
|
labelValueErrorCases := []struct {
|
||||||
{"toolongvalue": strings.Repeat("a", 64)},
|
labels map[string]string
|
||||||
{"backslashesinvalue": "some\\bad\\value"},
|
expect string
|
||||||
{"nocommasallowed": "bad,value"},
|
}{
|
||||||
{"strangecharsinvalue": "?#$notsogood"},
|
{map[string]string{"toolongvalue": strings.Repeat("a", 64)}, "must be no more than"},
|
||||||
|
{map[string]string{"backslashesinvalue": "some\\bad\\value"}, "must match the regex"},
|
||||||
|
{map[string]string{"nocommasallowed": "bad,value"}, "must match the regex"},
|
||||||
|
{map[string]string{"strangecharsinvalue": "?#$notsogood"}, "must match the regex"},
|
||||||
}
|
}
|
||||||
for i := range labelValueErrorCases {
|
for i := range labelValueErrorCases {
|
||||||
errs := ValidateLabels(labelValueErrorCases[i], field.NewPath("field"))
|
errs := ValidateLabels(labelValueErrorCases[i].labels, field.NewPath("field"))
|
||||||
if len(errs) != 1 {
|
if len(errs) != 1 {
|
||||||
t.Errorf("case[%d] expected failure", i)
|
t.Errorf("case[%d]: expected failure", i)
|
||||||
} else {
|
} else {
|
||||||
detail := errs[0].Detail
|
if !strings.Contains(errs[0].Detail, labelValueErrorCases[i].expect) {
|
||||||
if detail != labelValueErrorMsg {
|
t.Errorf("case[%d]: error details do not include %q: %q", i, labelValueErrorCases[i].expect, errs[0].Detail)
|
||||||
t.Errorf("error detail %s should be equal %s", detail, labelValueErrorMsg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@ func InclusiveRangeErrorMsg(lo, hi int) string {
|
|||||||
return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi)
|
return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi)
|
||||||
}
|
}
|
||||||
|
|
||||||
var labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt)
|
|
||||||
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 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 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)
|
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)
|
||||||
|
@ -124,9 +124,12 @@ func parseLabels(spec []string) (map[string]string, []string, error) {
|
|||||||
for _, labelSpec := range spec {
|
for _, labelSpec := range spec {
|
||||||
if strings.Index(labelSpec, "=") != -1 {
|
if strings.Index(labelSpec, "=") != -1 {
|
||||||
parts := strings.Split(labelSpec, "=")
|
parts := strings.Split(labelSpec, "=")
|
||||||
if len(parts) != 2 || len(parts[1]) == 0 || !validation.IsValidLabelValue(parts[1]) {
|
if len(parts) != 2 || len(parts[1]) == 0 {
|
||||||
return nil, nil, fmt.Errorf("invalid label spec: %v", labelSpec)
|
return nil, nil, fmt.Errorf("invalid label spec: %v", labelSpec)
|
||||||
}
|
}
|
||||||
|
if errs := validation.IsValidLabelValue(parts[1]); len(errs) != 0 {
|
||||||
|
return nil, nil, fmt.Errorf("invalid label value: %q: %s", labelSpec, strings.Join(errs, ";"))
|
||||||
|
}
|
||||||
labels[parts[0]] = parts[1]
|
labels[parts[0]] = parts[1]
|
||||||
} else if strings.HasSuffix(labelSpec, "-") {
|
} else if strings.HasSuffix(labelSpec, "-") {
|
||||||
remove = append(remove, labelSpec[:len(labelSpec)-1])
|
remove = append(remove, labelSpec[:len(labelSpec)-1])
|
||||||
|
@ -120,8 +120,8 @@ func InitNetworkPlugin(plugins []NetworkPlugin, networkPluginName string, host H
|
|||||||
allErrs := []error{}
|
allErrs := []error{}
|
||||||
for _, plugin := range plugins {
|
for _, plugin := range plugins {
|
||||||
name := plugin.Name()
|
name := plugin.Name()
|
||||||
if len(validation.IsQualifiedName(name)) != 0 {
|
if errs := validation.IsQualifiedName(name); len(errs) != 0 {
|
||||||
allErrs = append(allErrs, fmt.Errorf("network plugin has invalid name: %#v", plugin))
|
allErrs = append(allErrs, fmt.Errorf("network plugin has invalid name: %q: %s", name, strings.Join(errs, ";")))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,8 +764,6 @@ func parse(selector string) (internalSelector, error) {
|
|||||||
return internalSelector(items), err
|
return internalSelector(items), err
|
||||||
}
|
}
|
||||||
|
|
||||||
var labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt)
|
|
||||||
|
|
||||||
func validateLabelKey(k string) error {
|
func validateLabelKey(k string) error {
|
||||||
if errs := validation.IsQualifiedName(k); len(errs) != 0 {
|
if errs := validation.IsQualifiedName(k); len(errs) != 0 {
|
||||||
return fmt.Errorf("invalid label key %q: %s", k, strings.Join(errs, "; "))
|
return fmt.Errorf("invalid label key %q: %s", k, strings.Join(errs, "; "))
|
||||||
@ -774,8 +772,8 @@ func validateLabelKey(k string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validateLabelValue(v string) error {
|
func validateLabelValue(v string) error {
|
||||||
if !validation.IsValidLabelValue(v) {
|
if errs := validation.IsValidLabelValue(v); len(errs) != 0 {
|
||||||
return fmt.Errorf("invalid label value: %s", labelValueErrorMsg)
|
return fmt.Errorf("invalid label value: %q: %s", v, strings.Join(errs, "; "))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,24 @@ func IsQualifiedName(value string) []string {
|
|||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
const LabelValueFmt string = "(" + qualifiedNameFmt + ")?"
|
const labelValueFmt string = "(" + qualifiedNameFmt + ")?"
|
||||||
const LabelValueMaxLength int = 63
|
const LabelValueMaxLength int = 63
|
||||||
|
|
||||||
var labelValueRegexp = regexp.MustCompile("^" + LabelValueFmt + "$")
|
var labelValueMaxLengthString = strconv.Itoa(LabelValueMaxLength)
|
||||||
|
var labelValueRegexp = regexp.MustCompile("^" + labelValueFmt + "$")
|
||||||
|
|
||||||
func IsValidLabelValue(value string) bool {
|
// IsValidLabelValue tests whether the value passed is a valid label value. If
|
||||||
return (len(value) <= LabelValueMaxLength && labelValueRegexp.MatchString(value))
|
// the value is not valid, a list of error strings is returned. Otherwise an
|
||||||
|
// empty list (or nil) is returned.
|
||||||
|
func IsValidLabelValue(value string) []string {
|
||||||
|
var errs []string
|
||||||
|
if len(value) > LabelValueMaxLength {
|
||||||
|
errs = append(errs, "must be no more than "+labelValueMaxLengthString+" characters")
|
||||||
|
}
|
||||||
|
if !labelValueRegexp.MatchString(value) {
|
||||||
|
errs = append(errs, "must match the regex "+labelValueFmt+" (e.g. 'MyValue' or 'my_value' or '12345')")
|
||||||
|
}
|
||||||
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
const DNS1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
|
const DNS1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
|
||||||
|
@ -257,8 +257,8 @@ func TestIsValidLabelValue(t *testing.T) {
|
|||||||
"", // empty value
|
"", // empty value
|
||||||
}
|
}
|
||||||
for i := range successCases {
|
for i := range successCases {
|
||||||
if !IsValidLabelValue(successCases[i]) {
|
if errs := IsValidLabelValue(successCases[i]); len(errs) != 0 {
|
||||||
t.Errorf("case %s expected success", successCases[i])
|
t.Errorf("case %s expected success: %v", successCases[i], errs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ func TestIsValidLabelValue(t *testing.T) {
|
|||||||
strings.Repeat("a", 64), // over the limit
|
strings.Repeat("a", 64), // over the limit
|
||||||
}
|
}
|
||||||
for i := range errorCases {
|
for i := range errorCases {
|
||||||
if IsValidLabelValue(errorCases[i]) {
|
if errs := IsValidLabelValue(errorCases[i]); len(errs) == 0 {
|
||||||
t.Errorf("case[%d] expected failure", i)
|
t.Errorf("case[%d] expected failure", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,8 +272,8 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, host VolumeHost)
|
|||||||
allErrs := []error{}
|
allErrs := []error{}
|
||||||
for _, plugin := range plugins {
|
for _, plugin := range plugins {
|
||||||
name := plugin.Name()
|
name := plugin.Name()
|
||||||
if len(validation.IsQualifiedName(name)) != 0 {
|
if errs := validation.IsQualifiedName(name); len(errs) != 0 {
|
||||||
allErrs = append(allErrs, fmt.Errorf("volume plugin has invalid name: %#v", plugin))
|
allErrs = append(allErrs, fmt.Errorf("volume plugin has invalid name: %q: %s", name, strings.Join(errs, ";")))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,8 +307,8 @@ func (f *ConfigFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String,
|
|||||||
|
|
||||||
failureDomainArgs := strings.Split(f.FailureDomains, ",")
|
failureDomainArgs := strings.Split(f.FailureDomains, ",")
|
||||||
for _, failureDomain := range failureDomainArgs {
|
for _, failureDomain := range failureDomainArgs {
|
||||||
if len(utilvalidation.IsQualifiedName(failureDomain)) != 0 {
|
if errs := utilvalidation.IsQualifiedName(failureDomain); len(errs) != 0 {
|
||||||
return nil, fmt.Errorf("invalid failure domain: %s", failureDomain)
|
return nil, fmt.Errorf("invalid failure domain: %q: %s", failureDomain, strings.Join(errs, ";"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user