Skip to content

Commit f223549

Browse files
committed
Update docs and Makefile, add more logging
1 parent 3801a2a commit f223549

File tree

7 files changed

+89
-101
lines changed

7 files changed

+89
-101
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ run:
2424
send:
2525
@echo "Sending a request that includes a Pod container with allowed image name:"
2626
@echo
27-
curl -k -X POST -H "Content-Type: application/json" --data @files/admission_req_1.json https://localhost:4443/
27+
curl -k -X POST -H "Content-Type: application/json" --data @files/image_review_1.json https://localhost:4443/
2828
@echo
2929
@echo
3030

3131
@echo "Sending a request that includes a Pod container with denied image name:"
3232
@echo
33-
curl -k -X POST -H "Content-Type: application/json" --data @files/admission_req_2.json https://localhost:4443/
33+
curl -k -X POST -H "Content-Type: application/json" --data @files/image_review_2.json https://localhost:4443/
3434
@echo
3535

3636
docker-build:

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,46 @@ curl --cacert ./certs/ca.crt https://localhost:4443
4242

4343
### Deploy in Kubernetes
4444

45+
1. Deploy `imagine` using Helm, this deploys the latest released version of `imagine`:
46+
47+
```bash
48+
make deploy
49+
```
50+
51+
2. Generate the needed certificate to be used with `imagine`, this will be used by `imagine` as the server-side certificate of the webhook:
52+
53+
```bash
54+
make k8s-gen-cert
55+
```
56+
57+
3. Copy the following files to a specific directory on all control-plane nodes:
58+
59+
```bash
60+
files/admissionconfig.yaml
61+
files/config.yaml
62+
```
63+
64+
shall be copied to `/etc/kubernetes/imagine`, make sure you've created it first.
65+
66+
4. Now change the `kube-apiserver` static Pod manifest (in `/etc/kubernetes/manifests`), you'll need to add the following configuration:
67+
68+
* `ImagePolicyWebhook` to the `--enable-admission-plugins`flag
69+
* `--admission-control-config-file=/etc/kubernetes/imagine/admissionconfig.yaml`
70+
71+
and:
72+
73+
```bash
74+
...
75+
spec:
76+
containers:
77+
- volumeMounts:
78+
- mountPath: /etc/kubernetes/imagine
79+
name: imagine
80+
readOnly: true
81+
...
82+
volumes:
83+
- hostPath:
84+
path: /etc/kubernetes/imagine
85+
type: DirectoryOrCreate
86+
name: imagine
87+
```

files/admission_req_1.json

Lines changed: 0 additions & 48 deletions
This file was deleted.

files/admission_req_2.json

Lines changed: 0 additions & 48 deletions
This file was deleted.

files/image_review_1.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"kind": "ImageReview",
3+
"apiVersion": "imagepolicy.k8s.io/v1alpha1",
4+
"metadata": {
5+
"creationTimestamp": null
6+
},
7+
"spec": {
8+
"containers": [
9+
{
10+
"image": "nginx"
11+
}
12+
],
13+
"namespace": "default"
14+
},
15+
"status": {
16+
"allowed": false
17+
}
18+
}

files/image_review_2.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"kind": "ImageReview",
3+
"apiVersion": "imagepolicy.k8s.io/v1alpha1",
4+
"metadata": {
5+
"creationTimestamp": null
6+
},
7+
"spec": {
8+
"containers": [
9+
{
10+
"image": "nope"
11+
}
12+
],
13+
"namespace": "default"
14+
},
15+
"status": {
16+
"allowed": false
17+
}
18+
}

main.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ type imagineOpts struct {
2323
func main() {
2424
opts := imagineOpts{}
2525

26-
// Parse command line arguments
2726
flag.StringVar(&opts.key, "key", "", "Path to the key file")
2827
flag.StringVar(&opts.cert, "cert", "", "Path to the cert file")
29-
flag.StringVar(&opts.imageName, "image-name", "", "Part of the image name used when validating")
28+
flag.StringVar(&opts.imageName, "image-name", "", "Part of the image name that is not allowed")
3029
flag.IntVar(&opts.port, "port", 4443, "Port to listen on")
3130
flag.Parse()
3231

@@ -89,14 +88,18 @@ func imagineHandler(imageName string) http.HandlerFunc {
8988
}
9089

9190
var allowed bool
91+
reason := fmt.Sprintf("image name contains disallowed string: %s", imageName)
92+
9293
for _, container := range imageReview.Spec.Containers {
93-
if strings.Contains(container.Image, imageName) {
94+
if !strings.Contains(container.Image, imageName) {
9495
allowed = true
96+
reason = ""
9597
break
9698
}
9799
}
98100

99101
imageReview.Status.Allowed = allowed
102+
imageReview.Status.Reason = reason
100103

101104
responseBytes, err := json.Marshal(imageReview)
102105
if err != nil {
@@ -110,5 +113,7 @@ func imagineHandler(imageName string) http.HandlerFunc {
110113
if _, err := w.Write(responseBytes); err != nil {
111114
log.Printf("Failed to write response: %v", err)
112115
}
116+
117+
log.Printf("Image: %s, Allowed: %t, Reason: %s", imageReview.Spec.Containers[0].Image, imageReview.Status.Allowed, imageReview.Status.Reason)
113118
}
114119
}

0 commit comments

Comments
 (0)