Skip to content

Commit 11aa07e

Browse files
authored
Merge pull request kubernetes#87385 from krzysied/agnhost_webhook_sidecar
Agnhost webhook sidecar
2 parents 0b18af6 + 3593fc6 commit 11aa07e

File tree

6 files changed

+92
-13
lines changed

6 files changed

+92
-13
lines changed

test/images/agnhost/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ For example, let's consider the following `pod.yaml` file:
4040
containers:
4141
- args:
4242
- dns-suffix
43-
image: gcr.io/kubernetes-e2e-test-images/agnhost:2.9
43+
image: gcr.io/kubernetes-e2e-test-images/agnhost:2.10
4444
name: agnhost
4545
dnsConfig:
4646
nameservers:
@@ -290,14 +290,14 @@ Examples:
290290

291291
```console
292292
docker run -i \
293-
gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \
293+
gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \
294294
logs-generator --log-lines-total 10 --run-duration 1s
295295
```
296296

297297
```console
298298
kubectl run logs-generator \
299299
--generator=run-pod/v1 \
300-
--image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \
300+
--image=gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \
301301
--restart=Never \
302302
-- logs-generator -t 10 -d 1s
303303
```
@@ -455,7 +455,7 @@ Usage:
455455
```console
456456
kubectl run test-agnhost \
457457
--generator=run-pod/v1 \
458-
--image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \
458+
--image=gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \
459459
--restart=Never \
460460
--env "POD_IP=<POD_IP>" \
461461
--env "NODE_IP=<NODE_IP>" \
@@ -510,7 +510,7 @@ Usage:
510510
```console
511511
kubectl run test-agnhost \
512512
--generator=run-pod/v1 \
513-
--image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \
513+
--image=gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \
514514
--restart=Never \
515515
--env "BIND_ADDRESS=localhost" \
516516
--env "BIND_PORT=8080" \
@@ -631,6 +631,6 @@ The image contains `iperf`, `curl`, `dns-tools` (including `dig`), CoreDNS.
631631

632632
## Image
633633

634-
The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.9` for Linux
634+
The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.10` for Linux
635635
containers, and `e2eteam/agnhost:2.8` for Windows containers. In the future, the same
636636
repository can be used for both OSes.

test/images/agnhost/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.9
1+
2.10

test/images/agnhost/agnhost.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import (
4848
)
4949

5050
func main() {
51-
rootCmd := &cobra.Command{Use: "app", Version: "2.9"}
51+
rootCmd := &cobra.Command{Use: "app", Version: "2.10"}
5252

5353
rootCmd.AddCommand(auditproxy.CmdAuditProxy)
5454
rootCmd.AddCommand(connect.CmdConnect)

test/images/agnhost/webhook/main.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ import (
3333
)
3434

3535
var (
36-
certFile string
37-
keyFile string
38-
port int
36+
certFile string
37+
keyFile string
38+
port int
39+
sidecarImage string
3940
)
4041

4142
// CmdWebhook is used by agnhost Cobra.
@@ -56,6 +57,8 @@ func init() {
5657
"File containing the default x509 private key matching --tls-cert-file.")
5758
CmdWebhook.Flags().IntVar(&port, "port", 443,
5859
"Secure port that the webhook listens on")
60+
CmdWebhook.Flags().StringVar(&sidecarImage, "sidecar-image", "",
61+
"Image to be used as the injected sidecar")
5962
}
6063

6164
// admitv1beta1Func handles a v1beta1 admission
@@ -181,6 +184,10 @@ func serveMutatePods(w http.ResponseWriter, r *http.Request) {
181184
serve(w, r, newDelegateToV1AdmitHandler(mutatePods))
182185
}
183186

187+
func serveMutatePodsSidecar(w http.ResponseWriter, r *http.Request) {
188+
serve(w, r, newDelegateToV1AdmitHandler(mutatePodsSidecar))
189+
}
190+
184191
func serveConfigmaps(w http.ResponseWriter, r *http.Request) {
185192
serve(w, r, newDelegateToV1AdmitHandler(admitConfigMaps))
186193
}
@@ -213,6 +220,7 @@ func main(cmd *cobra.Command, args []string) {
213220
http.HandleFunc("/pods", servePods)
214221
http.HandleFunc("/pods/attach", serveAttachingPods)
215222
http.HandleFunc("/mutating-pods", serveMutatePods)
223+
http.HandleFunc("/mutating-pods-sidecar", serveMutatePodsSidecar)
216224
http.HandleFunc("/configmaps", serveConfigmaps)
217225
http.HandleFunc("/mutating-configmaps", serveMutateConfigmaps)
218226
http.HandleFunc("/custom-resource", serveCustomResource)

test/images/agnhost/webhook/patch_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package webhook
1818

1919
import (
2020
"encoding/json"
21+
"fmt"
2122
"reflect"
2223
"testing"
2324

@@ -27,6 +28,7 @@ import (
2728
)
2829

2930
func TestPatches(t *testing.T) {
31+
sidecarImage = "test-image"
3032
testCases := []struct {
3133
patch string
3234
initial interface{}
@@ -81,6 +83,36 @@ func TestPatches(t *testing.T) {
8183
},
8284
},
8385
},
86+
{
87+
patch: fmt.Sprintf(podsSidecarPatch, sidecarImage),
88+
initial: corev1.Pod{
89+
Spec: corev1.PodSpec{
90+
Containers: []corev1.Container{
91+
{
92+
Image: "image1",
93+
Name: "container1",
94+
Resources: corev1.ResourceRequirements{},
95+
},
96+
},
97+
},
98+
},
99+
expected: &corev1.Pod{
100+
Spec: corev1.PodSpec{
101+
Containers: []corev1.Container{
102+
{
103+
Image: "image1",
104+
Name: "container1",
105+
Resources: corev1.ResourceRequirements{},
106+
},
107+
{
108+
Image: sidecarImage,
109+
Name: "webhook-added-sidecar",
110+
Resources: corev1.ResourceRequirements{},
111+
},
112+
},
113+
},
114+
},
115+
},
84116
}
85117
for _, testcase := range testCases {
86118
objJS, err := json.Marshal(testcase.initial)

test/images/agnhost/webhook/pods.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const (
3030
podsInitContainerPatch string = `[
3131
{"op":"add","path":"/spec/initContainers","value":[{"image":"webhook-added-image","name":"webhook-added-init-container","resources":{}}]}
3232
]`
33+
podsSidecarPatch string = `[
34+
{"op":"add", "path":"/spec/containers/-","value":{"image":"%v","name":"webhook-added-sidecar","resources":{}}}
35+
]`
3336
)
3437

3538
// only allow pods to pull images from specific registry.
@@ -77,6 +80,42 @@ func admitPods(ar v1.AdmissionReview) *v1.AdmissionResponse {
7780
}
7881

7982
func mutatePods(ar v1.AdmissionReview) *v1.AdmissionResponse {
83+
shouldPatchPod := func(pod *corev1.Pod) bool {
84+
if pod.Name != "webhook-to-be-mutated" {
85+
return false
86+
}
87+
return !hasContainer(pod.Spec.InitContainers, "webhook-added-init-container")
88+
}
89+
return applyPodPatch(ar, shouldPatchPod, podsInitContainerPatch)
90+
}
91+
92+
func mutatePodsSidecar(ar v1.AdmissionReview) *v1.AdmissionResponse {
93+
if sidecarImage == "" {
94+
return &v1.AdmissionResponse{
95+
Allowed: false,
96+
Result: &metav1.Status{
97+
Status: "Failure",
98+
Message: "No image specified by the sidecar-image parameter",
99+
Code: 500,
100+
},
101+
}
102+
}
103+
shouldPatchPod := func(pod *corev1.Pod) bool {
104+
return !hasContainer(pod.Spec.Containers, "webhook-added-sidecar")
105+
}
106+
return applyPodPatch(ar, shouldPatchPod, fmt.Sprintf(podsSidecarPatch, sidecarImage))
107+
}
108+
109+
func hasContainer(containers []corev1.Container, containerName string) bool {
110+
for _, container := range containers {
111+
if container.Name == containerName {
112+
return true
113+
}
114+
}
115+
return false
116+
}
117+
118+
func applyPodPatch(ar v1.AdmissionReview, shouldPatchPod func(*corev1.Pod) bool, patch string) *v1.AdmissionResponse {
80119
klog.V(2).Info("mutating pods")
81120
podResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
82121
if ar.Request.Resource != podResource {
@@ -93,8 +132,8 @@ func mutatePods(ar v1.AdmissionReview) *v1.AdmissionResponse {
93132
}
94133
reviewResponse := v1.AdmissionResponse{}
95134
reviewResponse.Allowed = true
96-
if pod.Name == "webhook-to-be-mutated" {
97-
reviewResponse.Patch = []byte(podsInitContainerPatch)
135+
if shouldPatchPod(&pod) {
136+
reviewResponse.Patch = []byte(patch)
98137
pt := v1.PatchTypeJSONPatch
99138
reviewResponse.PatchType = &pt
100139
}

0 commit comments

Comments
 (0)