Skip to content

Commit

Permalink
image name may not have leading or trailing whitespace
Browse files Browse the repository at this point in the history
  • Loading branch information
derekwaynecarr committed Jun 14, 2017
1 parent 3cb7796 commit 59b1bac
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
28 changes: 28 additions & 0 deletions pkg/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,9 @@ func validateContainers(containers []api.Container, volumes sets.String, fldPath
} else {
allNames.Insert(ctr.Name)
}
// TODO: do not validate leading and trailing whitespace to preserve backward compatibility.
// for example: https://github.com/openshift/origin/issues/14659 image = " " is special token in pod template
// others may have done similar
if len(ctr.Image) == 0 {
allErrs = append(allErrs, field.Required(idxPath.Child("image"), ""))
}
Expand Down Expand Up @@ -2211,12 +2214,33 @@ func ValidateTolerations(tolerations []api.Toleration, fldPath *field.Path) fiel
return allErrors
}

// validateContainersOnlyForPod does additional validation for containers on a pod versus a pod template
// it only does additive validation of fields not covered in validateContainers
func validateContainersOnlyForPod(containers []api.Container, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for i, ctr := range containers {
idxPath := fldPath.Index(i)
if len(ctr.Image) != len(strings.TrimSpace(ctr.Image)) {
allErrs = append(allErrs, field.Invalid(idxPath.Child("image"), ctr.Image, "must not have leading or trailing whitespace"))
}
}
return allErrs
}

// ValidatePod tests if required fields in the pod are set.
func ValidatePod(pod *api.Pod) field.ErrorList {
fldPath := field.NewPath("metadata")
allErrs := ValidateObjectMeta(&pod.ObjectMeta, true, ValidatePodName, fldPath)
allErrs = append(allErrs, ValidatePodSpecificAnnotations(pod.ObjectMeta.Annotations, &pod.Spec, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidatePodSpec(&pod.Spec, field.NewPath("spec"))...)

// we do additional validation only pertinent for pods and not pod templates
// this was done to preserve backwards compatibility
specPath := field.NewPath("spec")

allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.Containers, specPath.Child("containers"))...)
allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...)

return allErrs
}

Expand Down Expand Up @@ -2605,6 +2629,10 @@ func ValidateContainerUpdates(newContainers, oldContainers []api.Container, fldP
if len(ctr.Image) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Index(i).Child("image"), ""))
}
// this is only called from ValidatePodUpdate so its safe to check leading/trailing whitespace.
if len(strings.TrimSpace(ctr.Image)) != len(ctr.Image) {
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("image"), ctr.Image, "must not have leading or trailing whitespace"))
}
}
return allErrs, false
}
Expand Down
26 changes: 26 additions & 0 deletions pkg/api/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3080,6 +3080,9 @@ func TestValidateContainers(t *testing.T) {

successCase := []api.Container{
{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"},
// backwards compatibility to ensure containers in pod template spec do not check for this
{Name: "def", Image: " ", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"},
{Name: "ghi", Image: " some ", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"},
{Name: "123", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"},
{Name: "abc-123", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"},
{
Expand Down Expand Up @@ -3234,6 +3237,7 @@ func TestValidateContainers(t *testing.T) {
})
errorCases := map[string][]api.Container{
"zero-length name": {{Name: "", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
"zero-length-image": {{Name: "abc", Image: "", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
"name > 63 characters": {{Name: strings.Repeat("a", 64), Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
"name not a DNS label": {{Name: "a.b.c", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
"name not unique": {
Expand Down Expand Up @@ -4214,6 +4218,28 @@ func TestValidatePod(t *testing.T) {
},
},
},
"image whitespace": {
expectedError: "spec.containers[0].image",
spec: api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: "ns"},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
Containers: []api.Container{{Name: "ctr", Image: " ", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
},
},
},
"image leading and trailing whitespace": {
expectedError: "spec.containers[0].image",
spec: api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: "ns"},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
Containers: []api.Container{{Name: "ctr", Image: " something ", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
},
},
},
"bad namespace": {
expectedError: "metadata.namespace",
spec: api.Pod{
Expand Down

0 comments on commit 59b1bac

Please sign in to comment.