Skip to content

Commit

Permalink
feat: allow filters for container context
Browse files Browse the repository at this point in the history
Previously it wasn't possible to filter based on container specific
details since only the entire pod is available within the context.

A new filter context attribute "Container" holds the currently
processes container and allows more fine-grained control.

fixes #32
  • Loading branch information
estahn committed Dec 22, 2020
1 parent 1e1c186 commit c7e4c51
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
18 changes: 17 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ If a condition matches, the pod will **NOT** be processed.
```yaml
obj:
<Object Spec>
container:
<Container Spec>
```

=== "Example"
Expand All @@ -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:
Expand All @@ -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
Expand Down
10 changes: 7 additions & 3 deletions pkg/webhook/image_swapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions pkg/webhook/image_swapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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'"}}))
}

0 comments on commit c7e4c51

Please sign in to comment.