Merge pull request #4898 from gmarek/client2
Loosen label and annotation validation and related tests
This commit is contained in:
@@ -18,19 +18,33 @@ package util
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IsDNSLabel tests for a string that conforms to the definition of a label in
|
||||
// DNS (RFC 1123).
|
||||
func IsDNSLabel(value string) bool {
|
||||
return IsDNS1123Label(value)
|
||||
const kubeChar string = "[A-Za-z0-9]"
|
||||
const extendedKubeChar string = "[-A-Za-z0-9_.]"
|
||||
const qualifiedToken string = "(" + kubeChar + extendedKubeChar + "*)?" + kubeChar
|
||||
|
||||
const LabelValueFmt string = "((" + kubeChar + extendedKubeChar + "*)?" + kubeChar + ")?"
|
||||
|
||||
var labelValueRegexp = regexp.MustCompile("^" + LabelValueFmt + "$")
|
||||
|
||||
const LabelValueMaxLength int = 63
|
||||
|
||||
func IsValidLabelValue(value string) bool {
|
||||
return (len(value) <= LabelValueMaxLength && labelValueRegexp.MatchString(value))
|
||||
}
|
||||
|
||||
// IsDNSSubdomain tests for a string that conforms to the definition of a
|
||||
// subdomain in DNS (RFC 1123).
|
||||
func IsDNSSubdomain(value string) bool {
|
||||
return IsDNS1123Subdomain(value)
|
||||
// Annotation values are opaque.
|
||||
func IsValidAnnotationValue(value string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
const QualifiedNameFmt string = "(" + qualifiedToken + "/)?" + qualifiedToken
|
||||
|
||||
var qualifiedNameRegexp = regexp.MustCompile("^" + QualifiedNameFmt + "$")
|
||||
|
||||
func IsQualifiedName(value string) bool {
|
||||
return (len(value) <= DNS1123SubdomainMaxLength && qualifiedNameRegexp.MatchString(value))
|
||||
}
|
||||
|
||||
const DNS1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
|
||||
@@ -57,6 +71,18 @@ func IsDNS1123Subdomain(value string) bool {
|
||||
return len(value) <= DNS1123SubdomainMaxLength && dns1123SubdomainRegexp.MatchString(value)
|
||||
}
|
||||
|
||||
// IsDNSLabel tests for a string that conforms to the definition of a label in
|
||||
// DNS (RFC 1123).
|
||||
func IsDNSLabel(value string) bool {
|
||||
return IsDNS1123Label(value)
|
||||
}
|
||||
|
||||
// IsDNSSubdomain tests for a string that conforms to the definition of a
|
||||
// subdomain in DNS (RFC 1123).
|
||||
func IsDNSSubdomain(value string) bool {
|
||||
return IsDNS1123Subdomain(value)
|
||||
}
|
||||
|
||||
const DNS952LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
|
||||
|
||||
var dns952LabelRegexp = regexp.MustCompile("^" + DNS952LabelFmt + "$")
|
||||
@@ -83,33 +109,3 @@ func IsCIdentifier(value string) bool {
|
||||
func IsValidPortNum(port int) bool {
|
||||
return 0 < port && port < 65536
|
||||
}
|
||||
|
||||
// IsQualifiedName tests whether a string fits the "optionally-namespaced
|
||||
// name" pattern: [ DNS_SUBDOMAIN "/" ] DNS_LABEL
|
||||
func IsQualifiedName(value string) bool {
|
||||
var n, ns string
|
||||
parts := strings.Split(value, "/")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
n = parts[0]
|
||||
case 2:
|
||||
ns = parts[0]
|
||||
n = parts[1]
|
||||
default:
|
||||
return false
|
||||
}
|
||||
if (ns != "" && !IsDNSSubdomain(ns)) || !IsDNSLabel(n) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const LabelValueFmt string = "([A-Za-z0-9_\\-\\\\.]*)"
|
||||
|
||||
var labelValueRegexp = regexp.MustCompile("^" + LabelValueFmt + "$")
|
||||
|
||||
const labelValueMaxLength int = 63
|
||||
|
||||
func IsValidLabelValue(value string) bool {
|
||||
return (len(value) <= labelValueMaxLength && labelValueRegexp.MatchString(value))
|
||||
}
|
||||
|
@@ -168,6 +168,7 @@ func TestIsQualifiedName(t *testing.T) {
|
||||
"1-num.2-num/3-num",
|
||||
"1234/5678",
|
||||
"1.2.3.4/5678",
|
||||
"UppercaseIsOK123",
|
||||
}
|
||||
for i := range successCases {
|
||||
if !IsQualifiedName(successCases[i]) {
|
||||
@@ -176,12 +177,11 @@ func TestIsQualifiedName(t *testing.T) {
|
||||
}
|
||||
|
||||
errorCases := []string{
|
||||
"NoUppercase123",
|
||||
"nospecialchars%^=@",
|
||||
"cantendwithadash-",
|
||||
"-cantstartwithadash",
|
||||
"only/one/slash",
|
||||
strings.Repeat("a", 254),
|
||||
"-cantstartwithadash",
|
||||
}
|
||||
for i := range errorCases {
|
||||
if IsQualifiedName(errorCases[i]) {
|
||||
@@ -196,24 +196,25 @@ func TestIsValidLabelValue(t *testing.T) {
|
||||
"now-with-dashes",
|
||||
"1-starts-with-num",
|
||||
"end-with-num-1",
|
||||
"-starts-with-dash",
|
||||
"ends-with-dash-",
|
||||
".starts.with.dot",
|
||||
"ends.with.dot.",
|
||||
"\\preserve\\backslash",
|
||||
"1234", // only num
|
||||
strings.Repeat("a", 63), // to the limit
|
||||
"", // empty value
|
||||
}
|
||||
for i := range successCases {
|
||||
if !IsValidLabelValue(successCases[i]) {
|
||||
t.Errorf("case[%d] expected success", i)
|
||||
t.Errorf("case %s expected success", successCases[i])
|
||||
}
|
||||
}
|
||||
|
||||
errorCases := []string{
|
||||
"nospecialchars%^=@",
|
||||
"Tama-nui-te-rā.is.Māori.sun",
|
||||
strings.Repeat("a", 65),
|
||||
"\\backslashes\\are\\bad",
|
||||
"-starts-with-dash",
|
||||
"ends-with-dash-",
|
||||
".starts.with.dot",
|
||||
"ends.with.dot.",
|
||||
strings.Repeat("a", 64), // over the limit
|
||||
}
|
||||
for i := range errorCases {
|
||||
if IsValidLabelValue(errorCases[i]) {
|
||||
|
Reference in New Issue
Block a user