Commit 4f09f514 authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #24800 from thockin/validation_pt8-3

Automatic merge from submit-queue Make name validators return string slices Part of the larger validation PR, broken out for easier review and merge. Builds on previous PRs in the series.
parents f538d601 152c86ab
...@@ -22,9 +22,7 @@ import ( ...@@ -22,9 +22,7 @@ import (
"k8s.io/kubernetes/pkg/util/validation/field" "k8s.io/kubernetes/pkg/util/validation/field"
) )
func ValidateClusterName(name string, prefix bool) (bool, string) { var ValidateClusterName = validation.NameIsDNSSubdomain
return validation.NameIsDNSSubdomain(name, prefix)
}
func ValidateClusterSpec(spec *federation.ClusterSpec, fieldPath *field.Path) field.ErrorList { func ValidateClusterSpec(spec *federation.ClusterSpec, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
......
...@@ -367,7 +367,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) { ...@@ -367,7 +367,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) {
ctx := t.TestContext() ctx := t.TestContext()
_, err := t.storage.(rest.Creater).Create(ctx, objCopy) _, err := t.storage.(rest.Creater).Create(ctx, objCopy)
if !errors.IsInvalid(err) { if !errors.IsInvalid(err) {
t.Errorf("%s: Expected to get an invalid resource error, got %v", invalidName, err) t.Errorf("%s: Expected to get an invalid resource error, got '%v'", invalidName, err)
} }
} }
...@@ -379,7 +379,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) { ...@@ -379,7 +379,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) {
ctx := t.TestContext() ctx := t.TestContext()
_, err := t.storage.(rest.Creater).Create(ctx, objCopy) _, err := t.storage.(rest.Creater).Create(ctx, objCopy)
if !errors.IsInvalid(err) { if !errors.IsInvalid(err) {
t.Errorf("%s: Expected to get an invalid resource error, got %v", invalidSuffix, err) t.Errorf("%s: Expected to get an invalid resource error, got '%v'", invalidSuffix, err)
} }
} }
} }
......
...@@ -55,8 +55,8 @@ func ValidateLabelSelectorRequirement(sr unversioned.LabelSelectorRequirement, f ...@@ -55,8 +55,8 @@ func ValidateLabelSelectorRequirement(sr unversioned.LabelSelectorRequirement, f
// ValidateLabelName validates that the label name is correctly defined. // ValidateLabelName validates that the label name is correctly defined.
func ValidateLabelName(labelName string, fldPath *field.Path) field.ErrorList { func ValidateLabelName(labelName string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
for _, err := range validation.IsQualifiedName(labelName) { for _, msg := range validation.IsQualifiedName(labelName) {
allErrs = append(allErrs, field.Invalid(fldPath, labelName, err)) allErrs = append(allErrs, field.Invalid(fldPath, labelName, msg))
} }
return allErrs return allErrs
} }
...@@ -66,8 +66,8 @@ func ValidateLabels(labels map[string]string, fldPath *field.Path) field.ErrorLi ...@@ -66,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)...)
for _, err := range validation.IsValidLabelValue(v) { for _, msg := range validation.IsValidLabelValue(v) {
allErrs = append(allErrs, field.Invalid(fldPath, v, err)) allErrs = append(allErrs, field.Invalid(fldPath, v, msg))
} }
} }
return allErrs return allErrs
......
...@@ -28,36 +28,36 @@ var NameMayNotBe = []string{".", ".."} ...@@ -28,36 +28,36 @@ var NameMayNotBe = []string{".", ".."}
var NameMayNotContain = []string{"/", "%"} var NameMayNotContain = []string{"/", "%"}
// IsValidPathSegmentName validates the name can be safely encoded as a path segment // IsValidPathSegmentName validates the name can be safely encoded as a path segment
func IsValidPathSegmentName(name string) (bool, string) { func IsValidPathSegmentName(name string) []string {
for _, illegalName := range NameMayNotBe { for _, illegalName := range NameMayNotBe {
if name == illegalName { if name == illegalName {
return false, fmt.Sprintf(`name may not be %q`, illegalName) return []string{fmt.Sprintf(`may not be '%s'`, illegalName)}
} }
} }
for _, illegalContent := range NameMayNotContain { for _, illegalContent := range NameMayNotContain {
if strings.Contains(name, illegalContent) { if strings.Contains(name, illegalContent) {
return false, fmt.Sprintf(`name may not contain %q`, illegalContent) return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)}
} }
} }
return true, "" return nil
} }
// IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment // IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment
// It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid // It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid
func IsValidPathSegmentPrefix(name string) (bool, string) { func IsValidPathSegmentPrefix(name string) []string {
for _, illegalContent := range NameMayNotContain { for _, illegalContent := range NameMayNotContain {
if strings.Contains(name, illegalContent) { if strings.Contains(name, illegalContent) {
return false, fmt.Sprintf(`name may not contain %q`, illegalContent) return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)}
} }
} }
return true, "" return nil
} }
// ValidatePathSegmentName validates the name can be safely encoded as a path segment // ValidatePathSegmentName validates the name can be safely encoded as a path segment
func ValidatePathSegmentName(name string, prefix bool) (bool, string) { func ValidatePathSegmentName(name string, prefix bool) []string {
if prefix { if prefix {
return IsValidPathSegmentPrefix(name) return IsValidPathSegmentPrefix(name)
} else { } else {
......
...@@ -25,32 +25,27 @@ func TestValidatePathSegmentName(t *testing.T) { ...@@ -25,32 +25,27 @@ func TestValidatePathSegmentName(t *testing.T) {
testcases := map[string]struct { testcases := map[string]struct {
Name string Name string
Prefix bool Prefix bool
ExpectedOK bool
ExpectedMsg string ExpectedMsg string
}{ }{
"empty": { "empty": {
Name: "", Name: "",
Prefix: false, Prefix: false,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
"empty,prefix": { "empty,prefix": {
Name: "", Name: "",
Prefix: true, Prefix: true,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
"valid": { "valid": {
Name: "foo.bar.baz", Name: "foo.bar.baz",
Prefix: false, Prefix: false,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
"valid,prefix": { "valid,prefix": {
Name: "foo.bar.baz", Name: "foo.bar.baz",
Prefix: true, Prefix: true,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
...@@ -58,92 +53,80 @@ func TestValidatePathSegmentName(t *testing.T) { ...@@ -58,92 +53,80 @@ func TestValidatePathSegmentName(t *testing.T) {
"valid complex": { "valid complex": {
Name: "sha256:ABCDEF012345@ABCDEF012345", Name: "sha256:ABCDEF012345@ABCDEF012345",
Prefix: false, Prefix: false,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
// Make sure non-ascii characters are tolerated // Make sure non-ascii characters are tolerated
"valid extended charset": { "valid extended charset": {
Name: "Iñtërnâtiônàlizætiøn", Name: "Iñtërnâtiônàlizætiøn",
Prefix: false, Prefix: false,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
"dot": { "dot": {
Name: ".", Name: ".",
Prefix: false, Prefix: false,
ExpectedOK: false,
ExpectedMsg: ".", ExpectedMsg: ".",
}, },
"dot leading": { "dot leading": {
Name: ".test", Name: ".test",
Prefix: false, Prefix: false,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
"dot,prefix": { "dot,prefix": {
Name: ".", Name: ".",
Prefix: true, Prefix: true,
ExpectedOK: true, // allowed because a suffix could make it valid
ExpectedMsg: "", ExpectedMsg: "",
}, },
"dot dot": { "dot dot": {
Name: "..", Name: "..",
Prefix: false, Prefix: false,
ExpectedOK: false,
ExpectedMsg: "..", ExpectedMsg: "..",
}, },
"dot dot leading": { "dot dot leading": {
Name: "..test", Name: "..test",
Prefix: false, Prefix: false,
ExpectedOK: true,
ExpectedMsg: "", ExpectedMsg: "",
}, },
"dot dot,prefix": { "dot dot,prefix": {
Name: "..", Name: "..",
Prefix: true, Prefix: true,
ExpectedOK: true, // allowed because a suffix could make it valid
ExpectedMsg: "", ExpectedMsg: "",
}, },
"slash": { "slash": {
Name: "foo/bar", Name: "foo/bar",
Prefix: false, Prefix: false,
ExpectedOK: false,
ExpectedMsg: "/", ExpectedMsg: "/",
}, },
"slash,prefix": { "slash,prefix": {
Name: "foo/bar", Name: "foo/bar",
Prefix: true, Prefix: true,
ExpectedOK: false,
ExpectedMsg: "/", ExpectedMsg: "/",
}, },
"percent": { "percent": {
Name: "foo%bar", Name: "foo%bar",
Prefix: false, Prefix: false,
ExpectedOK: false,
ExpectedMsg: "%", ExpectedMsg: "%",
}, },
"percent,prefix": { "percent,prefix": {
Name: "foo%bar", Name: "foo%bar",
Prefix: true, Prefix: true,
ExpectedOK: false,
ExpectedMsg: "%", ExpectedMsg: "%",
}, },
} }
for k, tc := range testcases { for k, tc := range testcases {
ok, msg := ValidatePathSegmentName(tc.Name, tc.Prefix) msgs := ValidatePathSegmentName(tc.Name, tc.Prefix)
if ok != tc.ExpectedOK { if len(tc.ExpectedMsg) == 0 && len(msgs) > 0 {
t.Errorf("%s: expected ok=%v, got %v", k, tc.ExpectedOK, ok) t.Errorf("%s: expected no message, got %v", k, msgs)
} }
if len(tc.ExpectedMsg) == 0 && len(msg) > 0 { if len(tc.ExpectedMsg) > 0 && len(msgs) == 0 {
t.Errorf("%s: expected no message, got %v", k, msg) t.Errorf("%s: expected error message, got none", k)
} }
if len(tc.ExpectedMsg) > 0 && !strings.Contains(msg, tc.ExpectedMsg) { if len(tc.ExpectedMsg) > 0 && !strings.Contains(msgs[0], tc.ExpectedMsg) {
t.Errorf("%s: expected message containing %q, got %v", k, tc.ExpectedMsg, msg) t.Errorf("%s: expected message containing %q, got %v", k, tc.ExpectedMsg, msgs[0])
} }
} }
} }
...@@ -47,11 +47,11 @@ func TestValidateObjectMetaCustomName(t *testing.T) { ...@@ -47,11 +47,11 @@ func TestValidateObjectMetaCustomName(t *testing.T) {
errs := ValidateObjectMeta( errs := ValidateObjectMeta(
&api.ObjectMeta{Name: "test", GenerateName: "foo"}, &api.ObjectMeta{Name: "test", GenerateName: "foo"},
false, false,
func(s string, prefix bool) (bool, string) { func(s string, prefix bool) []string {
if s == "test" { if s == "test" {
return true, "" return nil
} }
return false, "name-gen" return []string{"name-gen"}
}, },
field.NewPath("field")) field.NewPath("field"))
if len(errs) != 1 { if len(errs) != 1 {
...@@ -67,8 +67,8 @@ func TestValidateObjectMetaNamespaces(t *testing.T) { ...@@ -67,8 +67,8 @@ func TestValidateObjectMetaNamespaces(t *testing.T) {
errs := ValidateObjectMeta( errs := ValidateObjectMeta(
&api.ObjectMeta{Name: "test", Namespace: "foo.bar"}, &api.ObjectMeta{Name: "test", Namespace: "foo.bar"},
true, true,
func(s string, prefix bool) (bool, string) { func(s string, prefix bool) []string {
return true, "" return nil
}, },
field.NewPath("field")) field.NewPath("field"))
if len(errs) != 1 { if len(errs) != 1 {
...@@ -86,8 +86,8 @@ func TestValidateObjectMetaNamespaces(t *testing.T) { ...@@ -86,8 +86,8 @@ func TestValidateObjectMetaNamespaces(t *testing.T) {
errs = ValidateObjectMeta( errs = ValidateObjectMeta(
&api.ObjectMeta{Name: "test", Namespace: string(b)}, &api.ObjectMeta{Name: "test", Namespace: string(b)},
true, true,
func(s string, prefix bool) (bool, string) { func(s string, prefix bool) []string {
return true, "" return nil
}, },
field.NewPath("field")) field.NewPath("field"))
if len(errs) != 1 { if len(errs) != 1 {
...@@ -132,8 +132,8 @@ func TestValidateObjectMetaOwnerReferences(t *testing.T) { ...@@ -132,8 +132,8 @@ func TestValidateObjectMetaOwnerReferences(t *testing.T) {
errs := ValidateObjectMeta( errs := ValidateObjectMeta(
&api.ObjectMeta{Name: "test", Namespace: "test", OwnerReferences: tc.ownerReferences}, &api.ObjectMeta{Name: "test", Namespace: "test", OwnerReferences: tc.ownerReferences},
true, true,
func(s string, prefix bool) (bool, string) { func(s string, prefix bool) []string {
return true, "" return nil
}, },
field.NewPath("field")) field.NewPath("field"))
if len(errs) != 0 && !tc.expectError { if len(errs) != 0 && !tc.expectError {
......
...@@ -28,11 +28,10 @@ import ( ...@@ -28,11 +28,10 @@ import (
"k8s.io/kubernetes/pkg/util/validation/field" "k8s.io/kubernetes/pkg/util/validation/field"
) )
// ValidatePetSetName can be used to check whether the given PetSet // ValidatePetSetName can be used to check whether the given PetSet name is valid.
// name is valid.
// Prefix indicates this name will be used as part of generation, in which case // Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed. // trailing dashes are allowed.
func ValidatePetSetName(name string, prefix bool) (bool, string) { func ValidatePetSetName(name string, prefix bool) []string {
// TODO: Validate that there's name for the suffix inserted by the pets. // TODO: Validate that there's name for the suffix inserted by the pets.
// Currently this is just "-index". In the future we may allow a user // Currently this is just "-index". In the future we may allow a user
// specified list of suffixes and we need to validate the longest one. // specified list of suffixes and we need to validate the longest one.
......
...@@ -39,10 +39,7 @@ func ValidateScale(scale *autoscaling.Scale) field.ErrorList { ...@@ -39,10 +39,7 @@ func ValidateScale(scale *autoscaling.Scale) field.ErrorList {
// ValidateHorizontalPodAutoscaler can be used to check whether the given autoscaler name is valid. // ValidateHorizontalPodAutoscaler can be used to check whether the given autoscaler name is valid.
// Prefix indicates this name will be used as part of generation, in which case trailing dashes are allowed. // Prefix indicates this name will be used as part of generation, in which case trailing dashes are allowed.
func ValidateHorizontalPodAutoscalerName(name string, prefix bool) (bool, string) { var ValidateHorizontalPodAutoscalerName = apivalidation.ValidateReplicationControllerName
// TODO: finally move it to pkg/api/validation and use nameIsDNSSubdomain function
return apivalidation.ValidateReplicationControllerName(name, prefix)
}
func validateHorizontalPodAutoscalerSpec(autoscaler autoscaling.HorizontalPodAutoscalerSpec, fldPath *field.Path) field.ErrorList { func validateHorizontalPodAutoscalerSpec(autoscaler autoscaling.HorizontalPodAutoscalerSpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
...@@ -68,15 +65,19 @@ func ValidateCrossVersionObjectReference(ref autoscaling.CrossVersionObjectRefer ...@@ -68,15 +65,19 @@ func ValidateCrossVersionObjectReference(ref autoscaling.CrossVersionObjectRefer
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if len(ref.Kind) == 0 { if len(ref.Kind) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("kind"), "")) allErrs = append(allErrs, field.Required(fldPath.Child("kind"), ""))
} else if ok, msg := apivalidation.IsValidPathSegmentName(ref.Kind); !ok { } else {
for _, msg := range apivalidation.IsValidPathSegmentName(ref.Kind) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("kind"), ref.Kind, msg)) allErrs = append(allErrs, field.Invalid(fldPath.Child("kind"), ref.Kind, msg))
} }
}
if len(ref.Name) == 0 { if len(ref.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
} else if ok, msg := apivalidation.IsValidPathSegmentName(ref.Name); !ok { } else {
for _, msg := range apivalidation.IsValidPathSegmentName(ref.Name) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), ref.Name, msg)) allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), ref.Name, msg))
} }
}
return allErrs return allErrs
} }
......
...@@ -43,21 +43,21 @@ func ValidateThirdPartyResourceUpdate(update, old *extensions.ThirdPartyResource ...@@ -43,21 +43,21 @@ func ValidateThirdPartyResourceUpdate(update, old *extensions.ThirdPartyResource
return allErrs return allErrs
} }
func ValidateThirdPartyResourceName(name string, prefix bool) (bool, string) { func ValidateThirdPartyResourceName(name string, prefix bool) []string {
// Make sure it's a valid DNS subdomain // Make sure it's a valid DNS subdomain
if ok, msg := apivalidation.NameIsDNSSubdomain(name, prefix); !ok { if msgs := apivalidation.NameIsDNSSubdomain(name, prefix); len(msgs) != 0 {
return ok, msg return msgs
} }
// Make sure it's at least three segments (kind + two-segment group name) // Make sure it's at least three segments (kind + two-segment group name)
if !prefix { if !prefix {
parts := strings.Split(name, ".") parts := strings.Split(name, ".")
if len(parts) < 3 { if len(parts) < 3 {
return false, "must be at least three segments long: <kind>.<domain>.<tld>" return []string{"must be at least three segments long: <kind>.<domain>.<tld>"}
} }
} }
return true, "" return nil
} }
func ValidateThirdPartyResource(obj *extensions.ThirdPartyResource) field.ErrorList { func ValidateThirdPartyResource(obj *extensions.ThirdPartyResource) field.ErrorList {
...@@ -137,14 +137,10 @@ func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec, fldPath *field.Path) ...@@ -137,14 +137,10 @@ func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec, fldPath *field.Path)
// ValidateDaemonSetName can be used to check whether the given daemon set name is valid. // ValidateDaemonSetName can be used to check whether the given daemon set name is valid.
// Prefix indicates this name will be used as part of generation, in which case // Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed. // trailing dashes are allowed.
func ValidateDaemonSetName(name string, prefix bool) (bool, string) { var ValidateDaemonSetName = apivalidation.NameIsDNSSubdomain
return apivalidation.NameIsDNSSubdomain(name, prefix)
}
// Validates that the given name can be used as a deployment name. // Validates that the given name can be used as a deployment name.
func ValidateDeploymentName(name string, prefix bool) (bool, string) { var ValidateDeploymentName = apivalidation.NameIsDNSSubdomain
return apivalidation.NameIsDNSSubdomain(name, prefix)
}
func ValidatePositiveIntOrPercent(intOrPercent intstr.IntOrString, fldPath *field.Path) field.ErrorList { func ValidatePositiveIntOrPercent(intOrPercent intstr.IntOrString, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
...@@ -305,9 +301,7 @@ func ValidateIngress(ingress *extensions.Ingress) field.ErrorList { ...@@ -305,9 +301,7 @@ func ValidateIngress(ingress *extensions.Ingress) field.ErrorList {
} }
// ValidateIngressName validates that the given name can be used as an Ingress name. // ValidateIngressName validates that the given name can be used as an Ingress name.
func ValidateIngressName(name string, prefix bool) (bool, string) { var ValidateIngressName = apivalidation.NameIsDNSSubdomain
return apivalidation.NameIsDNSSubdomain(name, prefix)
}
func validateIngressTLS(spec *extensions.IngressSpec, fldPath *field.Path) field.ErrorList { func validateIngressTLS(spec *extensions.IngressSpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
...@@ -357,8 +351,8 @@ func validateIngressRules(IngressRules []extensions.IngressRule, fldPath *field. ...@@ -357,8 +351,8 @@ func validateIngressRules(IngressRules []extensions.IngressRule, fldPath *field.
if len(ih.Host) > 0 { if len(ih.Host) > 0 {
// TODO: Ports and ips are allowed in the host part of a url // TODO: Ports and ips are allowed in the host part of a url
// according to RFC 3986, consider allowing them. // according to RFC 3986, consider allowing them.
if valid, errMsg := apivalidation.NameIsDNSSubdomain(ih.Host, false); !valid { for _, msg := range apivalidation.NameIsDNSSubdomain(ih.Host, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, errMsg)) allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg))
} }
if isIP := (net.ParseIP(ih.Host) != nil); isIP { if isIP := (net.ParseIP(ih.Host) != nil); isIP {
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, "must be a DNS name, not an IP address")) allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, "must be a DNS name, not an IP address"))
...@@ -413,8 +407,10 @@ func validateIngressBackend(backend *extensions.IngressBackend, fldPath *field.P ...@@ -413,8 +407,10 @@ func validateIngressBackend(backend *extensions.IngressBackend, fldPath *field.P
// All backends must reference a single local service by name, and a single service port by name or number. // All backends must reference a single local service by name, and a single service port by name or number.
if len(backend.ServiceName) == 0 { if len(backend.ServiceName) == 0 {
return append(allErrs, field.Required(fldPath.Child("serviceName"), "")) return append(allErrs, field.Required(fldPath.Child("serviceName"), ""))
} else if ok, errMsg := apivalidation.ValidateServiceName(backend.ServiceName, false); !ok { } else {
allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceName"), backend.ServiceName, errMsg)) for _, msg := range apivalidation.ValidateServiceName(backend.ServiceName, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceName"), backend.ServiceName, msg))
}
} }
if backend.ServicePort.Type == intstr.String { if backend.ServicePort.Type == intstr.String {
if !validation.IsDNS1123Label(backend.ServicePort.StrVal) { if !validation.IsDNS1123Label(backend.ServicePort.StrVal) {
...@@ -444,9 +440,7 @@ func ValidateScale(scale *extensions.Scale) field.ErrorList { ...@@ -444,9 +440,7 @@ func ValidateScale(scale *extensions.Scale) field.ErrorList {
// name is valid. // name is valid.
// Prefix indicates this name will be used as part of generation, in which case // Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed. // trailing dashes are allowed.
func ValidateReplicaSetName(name string, prefix bool) (bool, string) { var ValidateReplicaSetName = apivalidation.NameIsDNSSubdomain
return apivalidation.NameIsDNSSubdomain(name, prefix)
}
// ValidateReplicaSet tests if required fields in the ReplicaSet are set. // ValidateReplicaSet tests if required fields in the ReplicaSet are set.
func ValidateReplicaSet(rs *extensions.ReplicaSet) field.ErrorList { func ValidateReplicaSet(rs *extensions.ReplicaSet) field.ErrorList {
...@@ -526,9 +520,7 @@ func ValidatePodTemplateSpecForReplicaSet(template *api.PodTemplateSpec, selecto ...@@ -526,9 +520,7 @@ func ValidatePodTemplateSpecForReplicaSet(template *api.PodTemplateSpec, selecto
// pod security policy name is valid. // pod security policy name is valid.
// Prefix indicates this name will be used as part of generation, in which case // Prefix indicates this name will be used as part of generation, in which case
// trailing dashes are allowed. // trailing dashes are allowed.
func ValidatePodSecurityPolicyName(name string, prefix bool) (bool, string) { var ValidatePodSecurityPolicyName = apivalidation.NameIsDNSSubdomain
return apivalidation.NameIsDNSSubdomain(name, prefix)
}
func ValidatePodSecurityPolicy(psp *extensions.PodSecurityPolicy) field.ErrorList { func ValidatePodSecurityPolicy(psp *extensions.PodSecurityPolicy) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
......
...@@ -25,7 +25,7 @@ import ( ...@@ -25,7 +25,7 @@ import (
// Minimal validation of names for roles and bindings. Identical to the validation for Openshift. See: // Minimal validation of names for roles and bindings. Identical to the validation for Openshift. See:
// * https://github.com/kubernetes/kubernetes/blob/60db50/pkg/api/validation/name.go // * https://github.com/kubernetes/kubernetes/blob/60db50/pkg/api/validation/name.go
// * https://github.com/openshift/origin/blob/388478/pkg/api/helpers.go // * https://github.com/openshift/origin/blob/388478/pkg/api/helpers.go
func minimalNameRequirements(name string, prefix bool) (bool, string) { func minimalNameRequirements(name string, prefix bool) []string {
return validation.IsValidPathSegmentName(name) return validation.IsValidPathSegmentName(name)
} }
...@@ -86,16 +86,16 @@ func validateRoleBinding(roleBinding *rbac.RoleBinding, isNamespaced bool, fldPa ...@@ -86,16 +86,16 @@ func validateRoleBinding(roleBinding *rbac.RoleBinding, isNamespaced bool, fldPa
// roleRef namespace is empty when referring to global policy. // roleRef namespace is empty when referring to global policy.
if len(roleBinding.RoleRef.Namespace) > 0 { if len(roleBinding.RoleRef.Namespace) > 0 {
if ok, reason := validation.ValidateNamespaceName(roleBinding.RoleRef.Namespace, false); !ok { for _, msg := range validation.ValidateNamespaceName(roleBinding.RoleRef.Namespace, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("roleRef", "namespace"), roleBinding.RoleRef.Namespace, reason)) allErrs = append(allErrs, field.Invalid(fldPath.Child("roleRef", "namespace"), roleBinding.RoleRef.Namespace, msg))
} }
} }
if len(roleBinding.RoleRef.Name) == 0 { if len(roleBinding.RoleRef.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("roleRef", "name"), "")) allErrs = append(allErrs, field.Required(fldPath.Child("roleRef", "name"), ""))
} else { } else {
if valid, err := minimalNameRequirements(roleBinding.RoleRef.Name, false); !valid { for _, msg := range minimalNameRequirements(roleBinding.RoleRef.Name, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("roleRef", "name"), roleBinding.RoleRef.Name, err)) allErrs = append(allErrs, field.Invalid(fldPath.Child("roleRef", "name"), roleBinding.RoleRef.Name, msg))
} }
} }
...@@ -119,8 +119,10 @@ func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath ...@@ -119,8 +119,10 @@ func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath
switch subject.Kind { switch subject.Kind {
case rbac.ServiceAccountKind: case rbac.ServiceAccountKind:
if valid, reason := validation.ValidateServiceAccountName(subject.Name, false); len(subject.Name) > 0 && !valid { if len(subject.Name) > 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, reason)) for _, msg := range validation.ValidateServiceAccountName(subject.Name, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, msg))
}
} }
if !isNamespaced && len(subject.Namespace) == 0 { if !isNamespaced && len(subject.Namespace) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), "")) allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
......
...@@ -179,8 +179,8 @@ func (r *Request) Resource(resource string) *Request { ...@@ -179,8 +179,8 @@ func (r *Request) Resource(resource string) *Request {
r.err = fmt.Errorf("resource already set to %q, cannot change to %q", r.resource, resource) r.err = fmt.Errorf("resource already set to %q, cannot change to %q", r.resource, resource)
return r return r
} }
if ok, msg := validation.IsValidPathSegmentName(resource); !ok { if msgs := validation.IsValidPathSegmentName(resource); len(msgs) != 0 {
r.err = fmt.Errorf("invalid resource %q: %s", resource, msg) r.err = fmt.Errorf("invalid resource %q: %v", resource, msgs)
return r return r
} }
r.resource = resource r.resource = resource
...@@ -199,8 +199,8 @@ func (r *Request) SubResource(subresources ...string) *Request { ...@@ -199,8 +199,8 @@ func (r *Request) SubResource(subresources ...string) *Request {
return r return r
} }
for _, s := range subresources { for _, s := range subresources {
if ok, msg := validation.IsValidPathSegmentName(s); !ok { if msgs := validation.IsValidPathSegmentName(s); len(msgs) != 0 {
r.err = fmt.Errorf("invalid subresource %q: %s", s, msg) r.err = fmt.Errorf("invalid subresource %q: %v", s, msgs)
return r return r
} }
} }
...@@ -221,8 +221,8 @@ func (r *Request) Name(resourceName string) *Request { ...@@ -221,8 +221,8 @@ func (r *Request) Name(resourceName string) *Request {
r.err = fmt.Errorf("resource name already set to %q, cannot change to %q", r.resourceName, resourceName) r.err = fmt.Errorf("resource name already set to %q, cannot change to %q", r.resourceName, resourceName)
return r return r
} }
if ok, msg := validation.IsValidPathSegmentName(resourceName); !ok { if msgs := validation.IsValidPathSegmentName(resourceName); len(msgs) != 0 {
r.err = fmt.Errorf("invalid resource name %q: %s", resourceName, msg) r.err = fmt.Errorf("invalid resource name %q: %v", resourceName, msgs)
return r return r
} }
r.resourceName = resourceName r.resourceName = resourceName
...@@ -238,8 +238,8 @@ func (r *Request) Namespace(namespace string) *Request { ...@@ -238,8 +238,8 @@ func (r *Request) Namespace(namespace string) *Request {
r.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace) r.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace)
return r return r
} }
if ok, msg := validation.IsValidPathSegmentName(namespace); !ok { if msgs := validation.IsValidPathSegmentName(namespace); len(msgs) != 0 {
r.err = fmt.Errorf("invalid namespace %q: %s", namespace, msg) r.err = fmt.Errorf("invalid namespace %q: %v", namespace, msgs)
return r return r
} }
r.namespaceSet = true r.namespaceSet = true
......
...@@ -399,7 +399,7 @@ func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) ...@@ -399,7 +399,7 @@ func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object)
func getPodsPrefix(controllerName string) string { func getPodsPrefix(controllerName string) string {
// use the dash (if the name isn't too long) to make the pod name a bit prettier // use the dash (if the name isn't too long) to make the pod name a bit prettier
prefix := fmt.Sprintf("%s-", controllerName) prefix := fmt.Sprintf("%s-", controllerName)
if ok, _ := validation.ValidatePodName(prefix, true); !ok { if len(validation.ValidatePodName(prefix, true)) != 0 {
prefix = controllerName prefix = controllerName
} }
return prefix return prefix
......
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"strings"
"time" "time"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
...@@ -98,8 +99,8 @@ func NewStaticKubeletClient(config *KubeletClientConfig) (KubeletClient, error) ...@@ -98,8 +99,8 @@ func NewStaticKubeletClient(config *KubeletClientConfig) (KubeletClient, error)
// In default HTTPKubeletClient ctx is unused. // In default HTTPKubeletClient ctx is unused.
func (c *HTTPKubeletClient) GetConnectionInfo(ctx api.Context, nodeName string) (string, uint, http.RoundTripper, error) { func (c *HTTPKubeletClient) GetConnectionInfo(ctx api.Context, nodeName string) (string, uint, http.RoundTripper, error) {
if ok, msg := validation.ValidateNodeName(nodeName, false); !ok { if errs := validation.ValidateNodeName(nodeName, false); len(errs) != 0 {
return "", 0, nil, fmt.Errorf("invalid node name: %s", msg) return "", 0, nil, fmt.Errorf("invalid node name: %s", strings.Join(errs, ";"))
} }
scheme := "http" scheme := "http"
if c.Config.EnableHttps { if c.Config.EnableHttps {
......
...@@ -19,6 +19,7 @@ package registry ...@@ -19,6 +19,7 @@ package registry
import ( import (
"fmt" "fmt"
"reflect" "reflect"
"strings"
"sync" "sync"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
...@@ -137,8 +138,8 @@ func NamespaceKeyFunc(ctx api.Context, prefix string, name string) (string, erro ...@@ -137,8 +138,8 @@ func NamespaceKeyFunc(ctx api.Context, prefix string, name string) (string, erro
if len(name) == 0 { if len(name) == 0 {
return "", kubeerr.NewBadRequest("Name parameter required.") return "", kubeerr.NewBadRequest("Name parameter required.")
} }
if ok, msg := validation.IsValidPathSegmentName(name); !ok { if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 {
return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %v.", msg)) return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %q: %s", name, strings.Join(msgs, ";")))
} }
key = key + "/" + name key = key + "/" + name
return key, nil return key, nil
...@@ -149,8 +150,8 @@ func NoNamespaceKeyFunc(ctx api.Context, prefix string, name string) (string, er ...@@ -149,8 +150,8 @@ func NoNamespaceKeyFunc(ctx api.Context, prefix string, name string) (string, er
if len(name) == 0 { if len(name) == 0 {
return "", kubeerr.NewBadRequest("Name parameter required.") return "", kubeerr.NewBadRequest("Name parameter required.")
} }
if ok, msg := validation.IsValidPathSegmentName(name); !ok { if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 {
return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %v.", msg)) return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %q: %s", name, strings.Join(msgs, ";")))
} }
key := prefix + "/" + name key := prefix + "/" + name
return key, nil return key, nil
......
...@@ -52,10 +52,10 @@ func SplitUsername(username string) (string, string, error) { ...@@ -52,10 +52,10 @@ func SplitUsername(username string) (string, string, error) {
return "", "", invalidUsernameErr return "", "", invalidUsernameErr
} }
namespace, name := parts[0], parts[1] namespace, name := parts[0], parts[1]
if ok, _ := validation.ValidateNamespaceName(namespace, false); !ok { if len(validation.ValidateNamespaceName(namespace, false)) != 0 {
return "", "", invalidUsernameErr return "", "", invalidUsernameErr
} }
if ok, _ := validation.ValidateServiceAccountName(name, false); !ok { if len(validation.ValidateServiceAccountName(name, false)) != 0 {
return "", "", invalidUsernameErr return "", "", invalidUsernameErr
} }
return namespace, name, nil return namespace, name, nil
......
...@@ -71,8 +71,8 @@ func NamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { ...@@ -71,8 +71,8 @@ func NamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) {
return "", err return "", err
} }
name := meta.GetName() name := meta.GetName()
if ok, msg := validation.IsValidPathSegmentName(name); !ok { if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 {
return "", fmt.Errorf("invalid name: %v", msg) return "", fmt.Errorf("invalid name: %v", msgs)
} }
return prefix + "/" + meta.GetNamespace() + "/" + name, nil return prefix + "/" + meta.GetNamespace() + "/" + name, nil
} }
...@@ -83,8 +83,8 @@ func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { ...@@ -83,8 +83,8 @@ func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) {
return "", err return "", err
} }
name := meta.GetName() name := meta.GetName()
if ok, msg := validation.IsValidPathSegmentName(name); !ok { if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 {
return "", fmt.Errorf("invalid name: %v", msg) return "", fmt.Errorf("invalid name: %v", msgs)
} }
return prefix + "/" + name, nil return prefix + "/" + name, nil
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment