Add support for admission review v1beta1
This commit is contained in:
parent
2feb43b522
commit
9c94d772fb
5 changed files with 203 additions and 169 deletions
|
|
@ -17,26 +17,29 @@ limitations under the License.
|
|||
package controller
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
codecs = serializer.NewCodecFactory(scheme)
|
||||
)
|
||||
|
||||
func init() {
|
||||
admissionv1beta1.AddToScheme(scheme)
|
||||
admissionv1.AddToScheme(scheme)
|
||||
}
|
||||
|
||||
// AdmissionController checks if an object
|
||||
// is allowed in the cluster
|
||||
type AdmissionController interface {
|
||||
HandleAdmission(*admissionv1.AdmissionReview)
|
||||
HandleAdmission(runtime.Object) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// AdmissionControllerServer implements an HTTP server
|
||||
|
|
@ -44,7 +47,6 @@ type AdmissionController interface {
|
|||
// https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook
|
||||
type AdmissionControllerServer struct {
|
||||
AdmissionController AdmissionController
|
||||
Decoder runtime.Decoder
|
||||
}
|
||||
|
||||
// NewAdmissionControllerServer instanciates an admission controller server with
|
||||
|
|
@ -52,36 +54,41 @@ type AdmissionControllerServer struct {
|
|||
func NewAdmissionControllerServer(ac AdmissionController) *AdmissionControllerServer {
|
||||
return &AdmissionControllerServer{
|
||||
AdmissionController: ac,
|
||||
Decoder: codecs.UniversalDeserializer(),
|
||||
}
|
||||
}
|
||||
|
||||
// ServeHTTP implements http.Server method
|
||||
func (acs *AdmissionControllerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
review, err := parseAdmissionReview(acs.Decoder, r.Body)
|
||||
func (acs *AdmissionControllerServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
defer req.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Unexpected error decoding request")
|
||||
klog.ErrorS(err, "Failed to read request body")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
acs.AdmissionController.HandleAdmission(review)
|
||||
if err := writeAdmissionReview(w, review); err != nil {
|
||||
klog.ErrorS(err, "Unexpected returning admission review")
|
||||
}
|
||||
}
|
||||
codec := json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, json.SerializerOptions{
|
||||
Pretty: true,
|
||||
})
|
||||
|
||||
func parseAdmissionReview(decoder runtime.Decoder, r io.Reader) (*admissionv1.AdmissionReview, error) {
|
||||
review := &admissionv1.AdmissionReview{}
|
||||
data, err := ioutil.ReadAll(r)
|
||||
obj, _, err := codec.Decode(data, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
klog.ErrorS(err, "Failed to decode request body")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
_, _, err = decoder.Decode(data, nil, review)
|
||||
return review, err
|
||||
}
|
||||
|
||||
func writeAdmissionReview(w io.Writer, ar *admissionv1.AdmissionReview) error {
|
||||
e := json.NewEncoder(w)
|
||||
return e.Encode(ar)
|
||||
result, err := acs.AdmissionController.HandleAdmission(obj)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "failed to process webhook request")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err := codec.Encode(result, w); err != nil {
|
||||
klog.ErrorS(err, "failed to encode response body")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue