mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
adding sidecar injecting webhook
This commit is contained in:
parent
f680c261e6
commit
dc5791b47a
@ -33,9 +33,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
certFile string
|
certFile string
|
||||||
keyFile string
|
keyFile string
|
||||||
port int
|
port int
|
||||||
|
sidecarImage string
|
||||||
)
|
)
|
||||||
|
|
||||||
// CmdWebhook is used by agnhost Cobra.
|
// CmdWebhook is used by agnhost Cobra.
|
||||||
@ -56,6 +57,8 @@ func init() {
|
|||||||
"File containing the default x509 private key matching --tls-cert-file.")
|
"File containing the default x509 private key matching --tls-cert-file.")
|
||||||
CmdWebhook.Flags().IntVar(&port, "port", 443,
|
CmdWebhook.Flags().IntVar(&port, "port", 443,
|
||||||
"Secure port that the webhook listens on")
|
"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
|
// admitv1beta1Func handles a v1beta1 admission
|
||||||
@ -181,6 +184,10 @@ func serveMutatePods(w http.ResponseWriter, r *http.Request) {
|
|||||||
serve(w, r, newDelegateToV1AdmitHandler(mutatePods))
|
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) {
|
func serveConfigmaps(w http.ResponseWriter, r *http.Request) {
|
||||||
serve(w, r, newDelegateToV1AdmitHandler(admitConfigMaps))
|
serve(w, r, newDelegateToV1AdmitHandler(admitConfigMaps))
|
||||||
}
|
}
|
||||||
@ -213,6 +220,7 @@ func main(cmd *cobra.Command, args []string) {
|
|||||||
http.HandleFunc("/pods", servePods)
|
http.HandleFunc("/pods", servePods)
|
||||||
http.HandleFunc("/pods/attach", serveAttachingPods)
|
http.HandleFunc("/pods/attach", serveAttachingPods)
|
||||||
http.HandleFunc("/mutating-pods", serveMutatePods)
|
http.HandleFunc("/mutating-pods", serveMutatePods)
|
||||||
|
http.HandleFunc("/mutating-pods-sidecar", serveMutatePodsSidecar)
|
||||||
http.HandleFunc("/configmaps", serveConfigmaps)
|
http.HandleFunc("/configmaps", serveConfigmaps)
|
||||||
http.HandleFunc("/mutating-configmaps", serveMutateConfigmaps)
|
http.HandleFunc("/mutating-configmaps", serveMutateConfigmaps)
|
||||||
http.HandleFunc("/custom-resource", serveCustomResource)
|
http.HandleFunc("/custom-resource", serveCustomResource)
|
||||||
|
@ -18,6 +18,7 @@ package webhook
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestPatches(t *testing.T) {
|
func TestPatches(t *testing.T) {
|
||||||
|
sidecarImage = "test-image"
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
patch string
|
patch string
|
||||||
initial interface{}
|
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 {
|
for _, testcase := range testCases {
|
||||||
objJS, err := json.Marshal(testcase.initial)
|
objJS, err := json.Marshal(testcase.initial)
|
||||||
|
@ -30,6 +30,9 @@ const (
|
|||||||
podsInitContainerPatch string = `[
|
podsInitContainerPatch string = `[
|
||||||
{"op":"add","path":"/spec/initContainers","value":[{"image":"webhook-added-image","name":"webhook-added-init-container","resources":{}}]}
|
{"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.
|
// 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 {
|
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")
|
klog.V(2).Info("mutating pods")
|
||||||
podResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
|
podResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
|
||||||
if ar.Request.Resource != podResource {
|
if ar.Request.Resource != podResource {
|
||||||
@ -93,8 +132,8 @@ func mutatePods(ar v1.AdmissionReview) *v1.AdmissionResponse {
|
|||||||
}
|
}
|
||||||
reviewResponse := v1.AdmissionResponse{}
|
reviewResponse := v1.AdmissionResponse{}
|
||||||
reviewResponse.Allowed = true
|
reviewResponse.Allowed = true
|
||||||
if pod.Name == "webhook-to-be-mutated" {
|
if shouldPatchPod(&pod) {
|
||||||
reviewResponse.Patch = []byte(podsInitContainerPatch)
|
reviewResponse.Patch = []byte(patch)
|
||||||
pt := v1.PatchTypeJSONPatch
|
pt := v1.PatchTypeJSONPatch
|
||||||
reviewResponse.PatchType = &pt
|
reviewResponse.PatchType = &pt
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user