diff --git a/docs/configuration.md b/docs/configuration.md index d2474631..82fb7b10 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -42,6 +42,8 @@ If a condition matches, the pod will **NOT** be processed. ```yaml obj: + container: + ``` === "Example" @@ -59,11 +61,18 @@ If a condition matches, the pod will **NOT** be processed. - name: web containerPort: 80 protocol: TCP + container: + name: web + image: nginx + ports: + - name: web + containerPort: 80 + protocol: TCP ``` Below you will find a list of common queries and/or ideas: -??? tip "List of common queries/ideas" +!!! tip "List of common queries/ideas" * Do not process if namespace equals `kube-system` (_Helm chart default_) ```yaml source: @@ -82,6 +91,13 @@ Below you will find a list of common queries and/or ideas: filters: - jmespath: "ends_with(obj.metadata.namespace,'-dev')" ``` + * Do not process AWS ECR images + ```yaml + source: + filters: + - jmespath: "contains(container.image, `.dkr.ecr.`) && contains(container.image, `.amazonaws.com`)" + ``` + `k8s-image-swapper` will log the filter data and result in `debug` mode. This can be used in conjunction with [JMESPath.org](https://jmespath.org/) which diff --git a/pkg/webhook/image_swapper.go b/pkg/webhook/image_swapper.go index 95902562..2e1da462 100644 --- a/pkg/webhook/image_swapper.go +++ b/pkg/webhook/image_swapper.go @@ -99,7 +99,7 @@ func (p *ImageSwapper) Mutate(ctx context.Context, obj metav1.Object) (bool, err continue } - filterCtx := NewFilterContext(*ar, pod) + filterCtx := NewFilterContext(*ar, pod, pod.Spec.Containers[i]) if filterMatch(filterCtx, p.filters) { log.Ctx(lctx).Info().Msg("skip due to filter condition") continue @@ -175,15 +175,19 @@ func (p *ImageSwapper) targetName(ref types.ImageReference) string { // FilterContext is being used by JMESPath to search and match type FilterContext struct { + // Obj contains the object submitted to the webhook (currently only pods) Obj metav1.Object `json:"obj,omitempty"` + + // Container contains the currently processed container + Container corev1.Container `json:"container,omitempty"` } -func NewFilterContext(request v1beta1.AdmissionRequest, obj metav1.Object) FilterContext { +func NewFilterContext(request v1beta1.AdmissionRequest, obj metav1.Object, container corev1.Container) FilterContext { if obj.GetNamespace() == "" { obj.SetNamespace(request.Namespace) } - return FilterContext{Obj: obj} + return FilterContext{Obj: obj, Container: container} } func copyImage(src string, srcCeds string, dest string, destCreds string) error { diff --git a/pkg/webhook/image_swapper_test.go b/pkg/webhook/image_swapper_test.go index b047f455..67a5c3bf 100644 --- a/pkg/webhook/image_swapper_test.go +++ b/pkg/webhook/image_swapper_test.go @@ -154,14 +154,20 @@ func TestFilterMatch(t *testing.T) { Spec: corev1.PodSpec{ Containers: []corev1.Container{ { + Name: "nginx", Image: "nginx:latest", }, }, }, }, + Container: corev1.Container{ + Name: "nginx", + Image: "nginx:latest", + }, } assert.True(t, filterMatch(filterContext, []pkg.JMESPathFilter{{JMESPath: "obj.metadata.namespace == 'kube-system'"}})) assert.False(t, filterMatch(filterContext, []pkg.JMESPathFilter{{JMESPath: "obj.metadata.namespace != 'kube-system'"}})) assert.False(t, filterMatch(filterContext, []pkg.JMESPathFilter{{JMESPath: "obj"}})) + assert.True(t, filterMatch(filterContext, []pkg.JMESPathFilter{{JMESPath: "container.name == 'nginx'"}})) }