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.