Separate messages for malformed image and fully qualified image.
parent
d1469a006c
commit
e8223d9204
|
@ -34,27 +34,36 @@ func (fq *fullyQualifiedImageCheck) Description() string {
|
||||||
// Run runs this check on a set of Kubernetes objects. It can return warnings
|
// Run runs this check on a set of Kubernetes objects. It can return warnings
|
||||||
// (low-priority problems) and errors (high-priority problems) as well as an
|
// (low-priority problems) and errors (high-priority problems) as well as an
|
||||||
// error value indicating that the check failed to run.
|
// error value indicating that the check failed to run.
|
||||||
func (fq *fullyQualifiedImageCheck) Run(objects *kube.Objects) (warnings []error, errors []error, err error) {
|
func (fq *fullyQualifiedImageCheck) Run(objects *kube.Objects) ([]error, []error, error) {
|
||||||
var w []error
|
var warnings, errors []error
|
||||||
|
|
||||||
for _, pod := range objects.Pods.Items {
|
for _, pod := range objects.Pods.Items {
|
||||||
podName := pod.GetName()
|
podName := pod.GetName()
|
||||||
namespace := pod.GetNamespace()
|
namespace := pod.GetNamespace()
|
||||||
w = append(w, checkImage(pod.Spec.Containers, podName, namespace)...)
|
w, e := checkImage(pod.Spec.Containers, podName, namespace)
|
||||||
w = append(w, checkImage(pod.Spec.InitContainers, podName, namespace)...)
|
warnings = append(warnings, w...)
|
||||||
|
errors = append(errors, e...)
|
||||||
|
w, e = checkImage(pod.Spec.InitContainers, podName, namespace)
|
||||||
|
warnings = append(warnings, w...)
|
||||||
|
errors = append(errors, e...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return w, nil, nil
|
return warnings, errors, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkImage checks if the image name is fully qualified
|
// checkImage checks if the image name is fully qualified
|
||||||
// Adds a warning if the container does not use a fully qualified image name
|
// Adds a warning if the container does not use a fully qualified image name
|
||||||
func checkImage(containers []corev1.Container, podName string, namespace string) []error {
|
func checkImage(containers []corev1.Container, podName string, namespace string) ([]error, []error) {
|
||||||
var w []error
|
var w, e []error
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
if value, err := reference.ParseAnyReference(container.Image); err != nil || value.String() != container.Image {
|
value, err := reference.ParseAnyReference(container.Image)
|
||||||
|
if err != nil {
|
||||||
|
e = append(e, fmt.Errorf("[Error] Malformed image name for container '%s' in pod '%s' in namespace '%s'", container.Name, podName, namespace))
|
||||||
|
} else {
|
||||||
|
if value.String() != container.Image {
|
||||||
w = append(w, fmt.Errorf("[Best Practice] Use fully qualified image for container '%s' in pod '%s' in namespace '%s'", container.Name, podName, namespace))
|
w = append(w, fmt.Errorf("[Best Practice] Use fully qualified image for container '%s' in pod '%s' in namespace '%s'", container.Name, podName, namespace))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return w
|
}
|
||||||
|
return w, e
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - busybox:latest",
|
name: "pod with container image - busybox:latest",
|
||||||
arg: container("busybox:latest"),
|
arg: container("busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - k8s.gcr.io/busybox",
|
name: "pod with container image - k8s.gcr.io/busybox",
|
||||||
|
@ -53,7 +53,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - busybox",
|
name: "pod with container image - busybox",
|
||||||
arg: container("busybox"),
|
arg: container("busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - test:5000/repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - test:5000/repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
@ -63,7 +63,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
arg: container("repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
arg: container("repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - test:5000/repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - test:5000/repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
@ -73,7 +73,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
arg: container("repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
arg: container("repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - k8s.gcr.io/busybox:latest",
|
name: "pod with container image - k8s.gcr.io/busybox:latest",
|
||||||
|
@ -83,7 +83,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - busybox:latest",
|
name: "pod with container image - busybox:latest",
|
||||||
arg: initContainer("busybox:latest"),
|
arg: initContainer("busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - k8s.gcr.io/busybox",
|
name: "pod with container image - k8s.gcr.io/busybox",
|
||||||
|
@ -93,7 +93,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - busybox",
|
name: "pod with container image - busybox",
|
||||||
arg: initContainer("busybox"),
|
arg: initContainer("busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - test:5000/repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - test:5000/repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
@ -103,7 +103,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
arg: initContainer("repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
arg: initContainer("repo/image@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - test:5000/repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - test:5000/repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
@ -113,7 +113,7 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
name: "pod with container image - repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
arg: initContainer("repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
arg: initContainer("repo/image:ignore-tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,9 +122,42 @@ func TestFullyQualifiedImageWarning(t *testing.T) {
|
||||||
for _, scenario := range scenarios {
|
for _, scenario := range scenarios {
|
||||||
t.Run(scenario.name, func(t *testing.T) {
|
t.Run(scenario.name, func(t *testing.T) {
|
||||||
w, e, err := fullyQualifiedImageCheck.Run(scenario.arg)
|
w, e, err := fullyQualifiedImageCheck.Run(scenario.arg)
|
||||||
|
assert.NoError(t, err)
|
||||||
assert.ElementsMatch(t, scenario.expected, w)
|
assert.ElementsMatch(t, scenario.expected, w)
|
||||||
assert.Empty(t, e)
|
assert.Empty(t, e)
|
||||||
assert.Nil(t, err)
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMalformedImageError(t *testing.T) {
|
||||||
|
const e string = "[Error] Malformed image name for container 'bar' in pod 'pod_foo' in namespace 'k8s'"
|
||||||
|
|
||||||
|
scenarios := []struct {
|
||||||
|
name string
|
||||||
|
arg *kube.Objects
|
||||||
|
expected []error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "container with image : test:5000/repo/image@sha256:digest",
|
||||||
|
arg: container("test:5000/repo/image@sha256:digest"),
|
||||||
|
expected: issues(e),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "init container with image : test:5000/repo/image@sha256:digest",
|
||||||
|
arg: initContainer("test:5000/repo/image@sha256:digest"),
|
||||||
|
expected: issues(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fullyQualifiedImageCheck := fullyQualifiedImageCheck{}
|
||||||
|
|
||||||
|
for _, scenario := range scenarios {
|
||||||
|
t.Run(scenario.name, func(t *testing.T) {
|
||||||
|
w, e, err := fullyQualifiedImageCheck.Run(scenario.arg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.ElementsMatch(t, scenario.expected, e)
|
||||||
|
assert.Empty(t, w)
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,9 @@ func initContainer(image string) *kube.Objects {
|
||||||
return objs
|
return objs
|
||||||
}
|
}
|
||||||
|
|
||||||
func warnings(s string) []error {
|
func issues(s string) []error {
|
||||||
w := []error{
|
issue := []error{
|
||||||
fmt.Errorf(s),
|
fmt.Errorf(s),
|
||||||
}
|
}
|
||||||
return w
|
return issue
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,32 +37,32 @@ func TestLatestTagWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with container image - k8s.gcr.io/busybox:latest",
|
name: "pod with container image - k8s.gcr.io/busybox:latest",
|
||||||
arg: container("k8s.gcr.io/busybox:latest"),
|
arg: container("k8s.gcr.io/busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - busybox:latest",
|
name: "pod with container image - busybox:latest",
|
||||||
arg: container("busybox:latest"),
|
arg: container("busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - k8s.gcr.io/busybox",
|
name: "pod with container image - k8s.gcr.io/busybox",
|
||||||
arg: container("k8s.gcr.io/busybox"),
|
arg: container("k8s.gcr.io/busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - busybox",
|
name: "pod with container image - busybox",
|
||||||
arg: container("busybox"),
|
arg: container("busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - private:5000/repo/busybox",
|
name: "pod with container image - private:5000/repo/busybox",
|
||||||
arg: container("http://private:5000/repo/busybox"),
|
arg: container("http://private:5000/repo/busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - private:5000/repo/busybox:latest",
|
name: "pod with container image - private:5000/repo/busybox:latest",
|
||||||
arg: container("http://private:5000/repo/busybox:latest"),
|
arg: container("http://private:5000/repo/busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - test:5000/repo@sha256:digest",
|
name: "pod with container image - test:5000/repo@sha256:digest",
|
||||||
|
@ -88,32 +88,32 @@ func TestLatestTagWarning(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "pod with init container image - k8s.gcr.io/busybox:latest",
|
name: "pod with init container image - k8s.gcr.io/busybox:latest",
|
||||||
arg: initContainer("k8s.gcr.io/busybox:latest"),
|
arg: initContainer("k8s.gcr.io/busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with init container image - busybox:latest",
|
name: "pod with init container image - busybox:latest",
|
||||||
arg: initContainer("busybox:latest"),
|
arg: initContainer("busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with init container image - k8s.gcr.io/busybox",
|
name: "pod with init container image - k8s.gcr.io/busybox",
|
||||||
arg: initContainer("k8s.gcr.io/busybox"),
|
arg: initContainer("k8s.gcr.io/busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with init container image - busybox",
|
name: "pod with init container image - busybox",
|
||||||
arg: initContainer("busybox"),
|
arg: initContainer("busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - http://private:5000/repo/busybox",
|
name: "pod with container image - http://private:5000/repo/busybox",
|
||||||
arg: container("http://private:5000/repo/busybox"),
|
arg: container("http://private:5000/repo/busybox"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - http://private:5000/repo/busybox:latest",
|
name: "pod with container image - http://private:5000/repo/busybox:latest",
|
||||||
arg: container("http://private:5000/repo/busybox:latest"),
|
arg: container("http://private:5000/repo/busybox:latest"),
|
||||||
expected: warnings(warning),
|
expected: issues(warning),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod with container image - test:5000/repo@sha256:digest",
|
name: "pod with container image - test:5000/repo@sha256:digest",
|
||||||
|
|
Loading…
Reference in New Issue