diff --git a/test/images/agnhost/README.md b/test/images/agnhost/README.md index aa89ec59c30..bd2b4986d8e 100644 --- a/test/images/agnhost/README.md +++ b/test/images/agnhost/README.md @@ -40,7 +40,7 @@ For example, let's consider the following `pod.yaml` file: containers: - args: - dns-suffix - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.9 + image: gcr.io/kubernetes-e2e-test-images/agnhost:2.10 name: agnhost dnsConfig: nameservers: @@ -290,14 +290,14 @@ Examples: ```console docker run -i \ - gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ + gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \ logs-generator --log-lines-total 10 --run-duration 1s ``` ```console kubectl run logs-generator \ --generator=run-pod/v1 \ - --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ + --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \ --restart=Never \ -- logs-generator -t 10 -d 1s ``` @@ -455,7 +455,7 @@ Usage: ```console kubectl run test-agnhost \ --generator=run-pod/v1 \ - --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ + --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \ --restart=Never \ --env "POD_IP=" \ --env "NODE_IP=" \ @@ -510,7 +510,7 @@ Usage: ```console kubectl run test-agnhost \ --generator=run-pod/v1 \ - --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ + --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.10 \ --restart=Never \ --env "BIND_ADDRESS=localhost" \ --env "BIND_PORT=8080" \ @@ -631,6 +631,6 @@ The image contains `iperf`, `curl`, `dns-tools` (including `dig`), CoreDNS. ## Image -The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.9` for Linux +The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.10` for Linux containers, and `e2eteam/agnhost:2.8` for Windows containers. In the future, the same repository can be used for both OSes. diff --git a/test/images/agnhost/VERSION b/test/images/agnhost/VERSION index 8c2691509e7..37989bd16b4 100644 --- a/test/images/agnhost/VERSION +++ b/test/images/agnhost/VERSION @@ -1 +1 @@ -2.9 +2.10 diff --git a/test/images/agnhost/agnhost.go b/test/images/agnhost/agnhost.go index 2c862a83322..6d6510d8c71 100644 --- a/test/images/agnhost/agnhost.go +++ b/test/images/agnhost/agnhost.go @@ -48,7 +48,7 @@ import ( ) func main() { - rootCmd := &cobra.Command{Use: "app", Version: "2.9"} + rootCmd := &cobra.Command{Use: "app", Version: "2.10"} rootCmd.AddCommand(auditproxy.CmdAuditProxy) rootCmd.AddCommand(connect.CmdConnect) diff --git a/test/images/agnhost/webhook/main.go b/test/images/agnhost/webhook/main.go index 2118e6aad6c..64ebe55e185 100644 --- a/test/images/agnhost/webhook/main.go +++ b/test/images/agnhost/webhook/main.go @@ -33,9 +33,10 @@ import ( ) var ( - certFile string - keyFile string - port int + certFile string + keyFile string + port int + sidecarImage string ) // CmdWebhook is used by agnhost Cobra. @@ -56,6 +57,8 @@ func init() { "File containing the default x509 private key matching --tls-cert-file.") CmdWebhook.Flags().IntVar(&port, "port", 443, "Secure port that the webhook listens on") + CmdWebhook.Flags().StringVar(&sidecarImage, "sidecar-image", "", + "Image to be used as the injected sidecar") } // admitv1beta1Func handles a v1beta1 admission @@ -181,6 +184,10 @@ func serveMutatePods(w http.ResponseWriter, r *http.Request) { serve(w, r, newDelegateToV1AdmitHandler(mutatePods)) } +func serveMutatePodsSidecar(w http.ResponseWriter, r *http.Request) { + serve(w, r, newDelegateToV1AdmitHandler(mutatePodsSidecar)) +} + func serveConfigmaps(w http.ResponseWriter, r *http.Request) { serve(w, r, newDelegateToV1AdmitHandler(admitConfigMaps)) } @@ -213,6 +220,7 @@ func main(cmd *cobra.Command, args []string) { http.HandleFunc("/pods", servePods) http.HandleFunc("/pods/attach", serveAttachingPods) http.HandleFunc("/mutating-pods", serveMutatePods) + http.HandleFunc("/mutating-pods-sidecar", serveMutatePodsSidecar) http.HandleFunc("/configmaps", serveConfigmaps) http.HandleFunc("/mutating-configmaps", serveMutateConfigmaps) http.HandleFunc("/custom-resource", serveCustomResource) diff --git a/test/images/agnhost/webhook/patch_test.go b/test/images/agnhost/webhook/patch_test.go index 252074373ba..e919a553ef6 100644 --- a/test/images/agnhost/webhook/patch_test.go +++ b/test/images/agnhost/webhook/patch_test.go @@ -18,6 +18,7 @@ package webhook import ( "encoding/json" + "fmt" "reflect" "testing" @@ -27,6 +28,7 @@ import ( ) func TestPatches(t *testing.T) { + sidecarImage = "test-image" testCases := []struct { patch string initial interface{} @@ -81,6 +83,36 @@ func TestPatches(t *testing.T) { }, }, }, + { + patch: fmt.Sprintf(podsSidecarPatch, sidecarImage), + initial: corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Image: "image1", + Name: "container1", + Resources: corev1.ResourceRequirements{}, + }, + }, + }, + }, + expected: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Image: "image1", + Name: "container1", + Resources: corev1.ResourceRequirements{}, + }, + { + Image: sidecarImage, + Name: "webhook-added-sidecar", + Resources: corev1.ResourceRequirements{}, + }, + }, + }, + }, + }, } for _, testcase := range testCases { objJS, err := json.Marshal(testcase.initial) diff --git a/test/images/agnhost/webhook/pods.go b/test/images/agnhost/webhook/pods.go index 9d6976d691b..cf559f276f8 100644 --- a/test/images/agnhost/webhook/pods.go +++ b/test/images/agnhost/webhook/pods.go @@ -30,6 +30,9 @@ const ( podsInitContainerPatch string = `[ {"op":"add","path":"/spec/initContainers","value":[{"image":"webhook-added-image","name":"webhook-added-init-container","resources":{}}]} ]` + podsSidecarPatch string = `[ + {"op":"add", "path":"/spec/containers/-","value":{"image":"%v","name":"webhook-added-sidecar","resources":{}}} + ]` ) // only allow pods to pull images from specific registry. @@ -77,6 +80,42 @@ func admitPods(ar v1.AdmissionReview) *v1.AdmissionResponse { } func mutatePods(ar v1.AdmissionReview) *v1.AdmissionResponse { + shouldPatchPod := func(pod *corev1.Pod) bool { + if pod.Name != "webhook-to-be-mutated" { + return false + } + return !hasContainer(pod.Spec.InitContainers, "webhook-added-init-container") + } + return applyPodPatch(ar, shouldPatchPod, podsInitContainerPatch) +} + +func mutatePodsSidecar(ar v1.AdmissionReview) *v1.AdmissionResponse { + if sidecarImage == "" { + return &v1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Status: "Failure", + Message: "No image specified by the sidecar-image parameter", + Code: 500, + }, + } + } + shouldPatchPod := func(pod *corev1.Pod) bool { + return !hasContainer(pod.Spec.Containers, "webhook-added-sidecar") + } + return applyPodPatch(ar, shouldPatchPod, fmt.Sprintf(podsSidecarPatch, sidecarImage)) +} + +func hasContainer(containers []corev1.Container, containerName string) bool { + for _, container := range containers { + if container.Name == containerName { + return true + } + } + return false +} + +func applyPodPatch(ar v1.AdmissionReview, shouldPatchPod func(*corev1.Pod) bool, patch string) *v1.AdmissionResponse { klog.V(2).Info("mutating pods") podResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"} if ar.Request.Resource != podResource { @@ -93,8 +132,8 @@ func mutatePods(ar v1.AdmissionReview) *v1.AdmissionResponse { } reviewResponse := v1.AdmissionResponse{} reviewResponse.Allowed = true - if pod.Name == "webhook-to-be-mutated" { - reviewResponse.Patch = []byte(podsInitContainerPatch) + if shouldPatchPod(&pod) { + reviewResponse.Patch = []byte(patch) pt := v1.PatchTypeJSONPatch reviewResponse.PatchType = &pt }