Commit b3017365 authored by Clayton Coleman's avatar Clayton Coleman

Slightly relax annotation validation

The more aggressive validation on annotations broke openshift (and backwards compat for our data). This change relaxes to allow mixed case so we can continue working in the short term, try to see if we can agree on relaxation, and if we can't, apply the stronger validation here.
parent e335e2d3
...@@ -29,6 +29,28 @@ import ( ...@@ -29,6 +29,28 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
// ValidateLabels validates that a set of labels are correctly defined.
func ValidateLabels(labels map[string]string, field string) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
for k := range labels {
if !util.IsQualifiedName(k) {
allErrs = append(allErrs, errs.NewFieldInvalid(field, k, ""))
}
}
return allErrs
}
// ValidateAnnotations validates that a set of annotations are correctly defined.
func ValidateAnnotations(annotations map[string]string, field string) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
for k := range annotations {
if !util.IsQualifiedName(strings.ToLower(k)) {
allErrs = append(allErrs, errs.NewFieldInvalid(field, k, ""))
}
}
return allErrs
}
// ValidateNameFunc validates that the provided name is valid for a given resource type. // ValidateNameFunc validates that the provided name is valid for a given resource type.
// Not all resources have the same validation rules for names. // Not all resources have the same validation rules for names.
type ValidateNameFunc func(name string) (bool, string) type ValidateNameFunc func(name string) (bool, string)
...@@ -71,7 +93,7 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val ...@@ -71,7 +93,7 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val
} }
} }
allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...) allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...)
allErrs = append(allErrs, ValidateLabels(meta.Annotations, "annotations")...) allErrs = append(allErrs, ValidateAnnotations(meta.Annotations, "annotations")...)
// Clear self link internally // Clear self link internally
// TODO: move to its own area // TODO: move to its own area
...@@ -106,7 +128,7 @@ func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorLis ...@@ -106,7 +128,7 @@ func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorLis
} }
allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...) allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...)
allErrs = append(allErrs, ValidateLabels(meta.Annotations, "annotations")...) allErrs = append(allErrs, ValidateAnnotations(meta.Annotations, "annotations")...)
// Clear self link internally // Clear self link internally
// TODO: move to its own area // TODO: move to its own area
...@@ -490,17 +512,6 @@ func ValidatePodSpec(spec *api.PodSpec) errs.ValidationErrorList { ...@@ -490,17 +512,6 @@ func ValidatePodSpec(spec *api.PodSpec) errs.ValidationErrorList {
return allErrs return allErrs
} }
// ValidateLabels validates that a set of labels are correctly defined.
func ValidateLabels(labels map[string]string, field string) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
for k := range labels {
if !util.IsQualifiedName(k) {
allErrs = append(allErrs, errs.NewFieldInvalid(field, k, ""))
}
}
return allErrs
}
// ValidatePodUpdate tests to see if the update is legal // ValidatePodUpdate tests to see if the update is legal
func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{} allErrs := errs.ValidationErrorList{}
...@@ -607,7 +618,6 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs ...@@ -607,7 +618,6 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs
if !selector.Matches(labels) { if !selector.Matches(labels) {
allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template"))
} }
allErrs = append(allErrs, ValidateLabels(spec.Template.Annotations, "annotations")...)
allErrs = append(allErrs, ValidatePodTemplateSpec(spec.Template).Prefix("template")...) allErrs = append(allErrs, ValidatePodTemplateSpec(spec.Template).Prefix("template")...)
// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
if spec.Template.Spec.RestartPolicy.Always == nil { if spec.Template.Spec.RestartPolicy.Always == nil {
...@@ -623,7 +633,7 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs ...@@ -623,7 +633,7 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs
func ValidatePodTemplateSpec(spec *api.PodTemplateSpec) errs.ValidationErrorList { func ValidatePodTemplateSpec(spec *api.PodTemplateSpec) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{} allErrs := errs.ValidationErrorList{}
allErrs = append(allErrs, ValidateLabels(spec.Labels, "labels")...) allErrs = append(allErrs, ValidateLabels(spec.Labels, "labels")...)
allErrs = append(allErrs, ValidateLabels(spec.Annotations, "annotations")...) allErrs = append(allErrs, ValidateAnnotations(spec.Annotations, "annotations")...)
allErrs = append(allErrs, ValidatePodSpec(&spec.Spec).Prefix("spec")...) allErrs = append(allErrs, ValidatePodSpec(&spec.Spec).Prefix("spec")...)
allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(spec.Spec.Volumes).Prefix("spec.volumes")...) allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(spec.Spec.Volumes).Prefix("spec.volumes")...)
return allErrs return allErrs
......
...@@ -74,6 +74,43 @@ func TestValidateLabels(t *testing.T) { ...@@ -74,6 +74,43 @@ func TestValidateLabels(t *testing.T) {
} }
} }
func TestValidateAnnotations(t *testing.T) {
successCases := []map[string]string{
{"simple": "bar"},
{"now-with-dashes": "bar"},
{"1-starts-with-num": "bar"},
{"1234": "bar"},
{"simple/simple": "bar"},
{"now-with-dashes/simple": "bar"},
{"now-with-dashes/now-with-dashes": "bar"},
{"now.with.dots/simple": "bar"},
{"now-with.dashes-and.dots/simple": "bar"},
{"1-num.2-num/3-num": "bar"},
{"1234/5678": "bar"},
{"1.2.3.4/5678": "bar"},
{"UpperCase123": "bar"},
}
for i := range successCases {
errs := ValidateAnnotations(successCases[i], "field")
if len(errs) != 0 {
t.Errorf("case[%d] expected success, got %#v", i, errs)
}
}
errorCases := []map[string]string{
{"nospecialchars^=@": "bar"},
{"cantendwithadash-": "bar"},
{"only/one/slash": "bar"},
{strings.Repeat("a", 254): "bar"},
}
for i := range errorCases {
errs := ValidateAnnotations(errorCases[i], "field")
if len(errs) != 1 {
t.Errorf("case[%d] expected failure", i)
}
}
}
func TestValidateVolumes(t *testing.T) { func TestValidateVolumes(t *testing.T) {
successCase := []api.Volume{ successCase := []api.Volume{
{Name: "abc"}, {Name: "abc"},
......
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