How to Build a Kubernetes Admission Webhook in Go

Create a Go HTTP server handling AdmissionReview requests and deploy it via a ValidatingWebhookConfiguration resource.

Build a Kubernetes admission webhook in Go by creating a server that implements the admissionv1 interface, handling AdmissionReview requests, and returning AdmissionResponse objects.

package main

import (
	"context"
	"encoding/json"
	"net/http"
	"k8s.io/api/admission/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/serializer"
)

var decoder = admission.NewDecoder(runtime.NewScheme())

func HandleAdmission(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	review := v1.AdmissionReview{}
	if err := decoder.Decode(r, nil, &review); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	response := v1.AdmissionResponse{Allowed: true}
	if review.Request != nil {
		// Add your validation logic here
		// response.Allowed = false
		// response.Result = &metav1.Status{Message: "Invalid"}
	}
	review.Response = &response
	codec := serializer.NewCodecFactory(runtime.NewScheme()).LegacyCodec(v1.SchemeGroupVersion)
	if err := json.NewEncoder(w).Encode(review); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func main() {
	http.HandleFunc("/mutate", HandleAdmission)
	http.ListenAndServeTLS(":8443", "tls.crt", "tls.key", nil)
}

Deploy the webhook with a ValidatingWebhookConfiguration or MutatingWebhookConfiguration resource pointing to your service URL.