in cmd/webhook/server/server.go [153:226]
func (s *Server) HandleValidate(w http.ResponseWriter, r *http.Request) {
defer utilruntime.HandleCrash(func(_ interface{}) {
// Assume the crash happened before the response was written.
http.Error(w, "internal server error", http.StatusInternalServerError)
})
var (
body []byte
err error
ctx = r.Context()
)
if timeout, ok, err := parseTimeout(r); err != nil {
// Ignore an invalid timeout.
klog.V(2).InfoS("Invalid timeout", "error", err)
} else if ok {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
}
if r.Body == nil {
err = errors.New("request body is empty")
klog.ErrorS(err, "bad request")
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer r.Body.Close()
limitedReader := &io.LimitedReader{R: r.Body, N: maxRequestSize}
if body, err = ioutil.ReadAll(limitedReader); err != nil {
klog.ErrorS(err, "unable to read the body from the incoming request")
http.Error(w, "unable to read the body from the incoming request", http.StatusBadRequest)
return
}
if limitedReader.N <= 0 {
klog.ErrorS(err, "unable to read the body from the incoming request; limit reached")
http.Error(w, fmt.Sprintf("request entity is too large; limit is %d bytes", maxRequestSize), http.StatusRequestEntityTooLarge)
return
}
// verify the content type is accurate
if contentType := r.Header.Get("Content-Type"); contentType != "application/json" {
err = fmt.Errorf("contentType=%s, expected application/json", contentType)
klog.ErrorS(err, "unable to process a request with an unknown content type", "content type", contentType)
http.Error(w, "unable to process a request with a non-json content type", http.StatusBadRequest)
return
}
v1AdmissionReviewKind := admissionv1.SchemeGroupVersion.WithKind("AdmissionReview")
reviewObject, gvk, err := codecs.UniversalDeserializer().Decode(body, &v1AdmissionReviewKind, nil)
if err != nil {
klog.ErrorS(err, "unable to decode the request")
http.Error(w, "unable to decode the request", http.StatusBadRequest)
return
}
if *gvk != v1AdmissionReviewKind {
klog.InfoS("Unexpected AdmissionReview kind", "kind", gvk.String())
http.Error(w, fmt.Sprintf("unexpected AdmissionReview kind: %s", gvk.String()), http.StatusBadRequest)
return
}
review, ok := reviewObject.(*admissionv1.AdmissionReview)
if !ok {
klog.InfoS("Failed admissionv1.AdmissionReview type assertion")
http.Error(w, "unexpected AdmissionReview type", http.StatusBadRequest)
}
klog.V(1).InfoS("received request", "UID", review.Request.UID, "kind", review.Request.Kind, "resource", review.Request.Resource)
attributes := api.RequestAttributes(review.Request, codecs.UniversalDeserializer())
response := s.delegate.Validate(ctx, attributes)
response.UID = review.Request.UID // Response UID must match request UID
review.Response = response
writeResponse(w, review)
}