|
| 1 | +# Admission Webhook for Core Types |
| 2 | + |
| 3 | +It is very easy to build admission webhooks for CRDs, which has been covered in |
| 4 | +the CronJob tutorial. Given that kubebuilder doesn't support webhook scaffolding |
| 5 | +for core types, you have to use the library from controler-runtime to handle it. |
| 6 | +There is an [example](https://github.com/kubernetes-sigs/controller-runtime/tree/master/examples/builtins) |
| 7 | +in controller-runtime. |
| 8 | + |
| 9 | +It is suggested to use kubebuilder to initialize a project, and then you can |
| 10 | +follow the steps below to add admission webhooks for core types. |
| 11 | + |
| 12 | +## Implement Your Handler |
| 13 | + |
| 14 | +You need to have your handler implements the |
| 15 | +[admission.Handler](https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/webhook/admission#Handler) |
| 16 | +interface. |
| 17 | + |
| 18 | +```go |
| 19 | +type podAnnotator struct { |
| 20 | + Client client.Client |
| 21 | + decoder *admission.Decoder |
| 22 | +} |
| 23 | + |
| 24 | +func (a *podAnnotator) Handle(ctx context.Context, req admission.Request) admission.Response { |
| 25 | + pod := &corev1.Pod{} |
| 26 | + err := a.decoder.Decode(req, pod) |
| 27 | + if err != nil { |
| 28 | + return admission.Errored(http.StatusBadRequest, err) |
| 29 | + } |
| 30 | + |
| 31 | + // mutate the fields in pod |
| 32 | + |
| 33 | + marshaledPod, err := json.Marshal(pod) |
| 34 | + if err != nil { |
| 35 | + return admission.Errored(http.StatusInternalServerError, err) |
| 36 | + } |
| 37 | + return admission.PatchResponseFromRaw(req.Object.Raw, marshaledPod) |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | +If you need a client, just pass in the client at struct construction time. |
| 42 | + |
| 43 | +If you add the `InjectDecoder` method for your handler, a decoder will be |
| 44 | +injected for you. |
| 45 | + |
| 46 | +```go |
| 47 | +func (a *podAnnotator) InjectDecoder(d *admission.Decoder) error { |
| 48 | + a.decoder = d |
| 49 | + return nil |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +**Note**: in order to have controller-gen generate the webhook configuration for |
| 54 | +you, you need to add markers. For example, |
| 55 | +`// +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=fail,groups="",resources=pods,verbs=create;update,versions=v1,name=mpod.kb.io` |
| 56 | + |
| 57 | +## Update main.go |
| 58 | + |
| 59 | +Now you need to register your handler in the webhook server. |
| 60 | + |
| 61 | +```go |
| 62 | +mgr.GetWebhookServer().Register("/mutate-v1-pod", &webhook.Admission{Handler: &podAnnotator{Client: mgr.GetClient()}}) |
| 63 | +``` |
| 64 | + |
| 65 | +You need to ensure the path here match the path in the marker. |
| 66 | + |
| 67 | +## Deploy |
| 68 | + |
| 69 | +Deploying it is just like deploying a webhook server for CRD. You need to |
| 70 | +1) provision the serving certificate 2) deploy the server |
| 71 | + |
| 72 | +You can follow the [tutorial](/cronjob-tutorial/running.md). |
0 commit comments