diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index 936d1db706a..8fe84d312bd 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -5695,7 +5695,7 @@ func TestValidateSecret(t *testing.T) { overMaxSize.Data = map[string][]byte{ "over": make([]byte, api.MaxSecretSize+1), } - invalidKey.Data["a..b"] = []byte("whoops") + invalidKey.Data["a*b"] = []byte("whoops") leadingDotKey.Data[".key"] = []byte("bar") dotKey.Data["."] = []byte("bar") doubleDotKey.Data[".."] = []byte("bar") @@ -6300,7 +6300,7 @@ func TestValidateConfigMap(t *testing.T) { invalidName = newConfigMap("NoUppercaseOrSpecialCharsLike=Equals", "validns", nil) emptyNs = newConfigMap("validname", "", nil) invalidNs = newConfigMap("validname", "NoUppercaseOrSpecialCharsLike=Equals", nil) - invalidKey = newConfigMap("validname", "validns", map[string]string{"a..b": "value"}) + invalidKey = newConfigMap("validname", "validns", map[string]string{"a*b": "value"}) leadingDotKey = newConfigMap("validname", "validns", map[string]string{".ab": "value"}) dotKey = newConfigMap("validname", "validns", map[string]string{".": "value"}) doubleDotKey = newConfigMap("validname", "validns", map[string]string{"..": "value"}) diff --git a/pkg/registry/configmap/etcd/etcd_test.go b/pkg/registry/configmap/etcd/etcd_test.go index be4bc57e348..d638edc45f4 100644 --- a/pkg/registry/configmap/etcd/etcd_test.go +++ b/pkg/registry/configmap/etcd/etcd_test.go @@ -93,7 +93,7 @@ func TestUpdate(t *testing.T) { // invalid updateFunc func(obj runtime.Object) runtime.Object { cfg := obj.(*api.ConfigMap) - cfg.Data["badKey"] = "value" + cfg.Data["bad*Key"] = "value" return cfg }, ) diff --git a/pkg/util/validation/validation.go b/pkg/util/validation/validation.go index 6e6a0270ca4..e698b581ef2 100644 --- a/pkg/util/validation/validation.go +++ b/pkg/util/validation/validation.go @@ -247,19 +247,26 @@ func IsHTTPHeaderName(value string) []string { return nil } -const configMapKeyFmt = "\\.?" + dns1123SubdomainFmt +const configMapKeyFmt = `[-._a-zA-Z0-9]+` var configMapKeyRegexp = regexp.MustCompile("^" + configMapKeyFmt + "$") -// IsConfigMapKey tests for a string that conforms to the definition of a -// subdomain in DNS (RFC 1123), except that a leading dot is allowed +// IsConfigMapKey tests for a string that is a valid key for a ConfigMap or Secret func IsConfigMapKey(value string) []string { var errs []string if len(value) > DNS1123SubdomainMaxLength { errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength)) } if !configMapKeyRegexp.MatchString(value) { - errs = append(errs, RegexError(configMapKeyFmt, "key.name")) + errs = append(errs, RegexError(configMapKeyFmt, "key.name", "KEY_NAME", "key-name")) + } + if value == "." { + errs = append(errs, `must not be '.'`) + } + if value == ".." { + errs = append(errs, `must not be '..'`) + } else if strings.HasPrefix(value, "..") { + errs = append(errs, `must not start with '..'`) } return errs } diff --git a/pkg/util/validation/validation_test.go b/pkg/util/validation/validation_test.go index b799469450f..d9a256392c8 100644 --- a/pkg/util/validation/validation_test.go +++ b/pkg/util/validation/validation_test.go @@ -377,11 +377,14 @@ func TestIsValidPercent(t *testing.T) { func TestIsConfigMapKey(t *testing.T) { successCases := []string{ + "a", "good", "good-good", "still.good", "this.is.also.good", ".so.is.this", + "THIS_IS_GOOD", + "so_is_this_17", } for i := range successCases { @@ -391,14 +394,16 @@ func TestIsConfigMapKey(t *testing.T) { } failureCases := []string{ - "bad_bad", + ".", + "..", "..bad", - "bad.", + "b*d", + "bad!&bad", } for i := range failureCases { if errs := IsConfigMapKey(failureCases[i]); len(errs) == 0 { - t.Errorf("[%d] expected success", i) + t.Errorf("[%d] expected failure", i) } } }