https://github.com/statcan/mutating-webhook
A small library that allows for the quick creation of Admission Controllers. // Une petite librairie facilitant facilement la création de Admission Controllers.
https://github.com/statcan/mutating-webhook
admission-controller cloud-native cns golang kubernetes mutating-webhook
Last synced: 8 months ago
JSON representation
A small library that allows for the quick creation of Admission Controllers. // Une petite librairie facilitant facilement la création de Admission Controllers.
- Host: GitHub
- URL: https://github.com/statcan/mutating-webhook
- Owner: StatCan
- License: mit
- Created: 2021-05-14T14:36:58.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2021-08-12T17:54:22.000Z (over 4 years ago)
- Last Synced: 2024-06-20T20:11:27.048Z (almost 2 years ago)
- Topics: admission-controller, cloud-native, cns, golang, kubernetes, mutating-webhook
- Language: Go
- Homepage:
- Size: 98.6 KB
- Stars: 1
- Watchers: 3
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
- Security: SECURITY.md
Awesome Lists containing this project
README
## Mutating Webhook
This repository provides a simple library for easily deploying a [Kubernetes Admission Controller](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/) that allows for easy mutation of objects.
## How To Use
### Implement `Mutator`
The `Mutator` interface is what needs to be implemented. It requires a single function: `Mutate(request v1.AdmissionRequest) (v1.AdmissionResponse, error)`. In this function, implement the logic of your mutating webhook.
### Get A `MutatingWebhook`
The `MutatingWebhook` interface returned by `NewMutatingWebhook(mutator Mutator, configs MutatingWebhookConfigs)` function is what is used to create the server.
It requires two arguments:
- `mutator Mutator`: a reference to the `struct` that implements your `Mutate` function.
- `configs MutatingWebhookConfigs`: a reference to the configs you wish to pass to the webserver. Any `nil` values will use defaults.
| Field | Default |
| -------------- | ----------------- |
| Addr | ":8443" |
| ReadTimeout | 10 * time.Second |
| WriteTimeout | 10 * time.Second |
| MaxHeaderBytes | 0 |
| CertFilePath | "./certs/tls.crt" |
| KeyFilePath | "./certs/tls.key" |
Once you instantiate the struct that implements the interface via the constructor, you can start the server!
### ListenAndServe()
`ListenAndServe()` is how you'll start the server! It is a blocking function, so it's best to run it in a go routine.
### Shutdown()
Once you're ready to stop the application, the `Shutdown()` function can be called. This will attempt to gracefully close all resources and will shutdown the server.
This will cause the blocking `ListenAndServe` to return a non-nil error. If the shutdown was gracefully completed `ErrServerClosed` will be returned as the error.
### Endpoints
There are four endpoints that are available from the webserver:
- `/` - A welcome message is served at the root.
- `/mutate` - The `Mutate` function you implemented is served from this endpoint.
- `/_healthz` - A health endpoint for the Kubernetes Liveness Probe.
- `/_ready` - A readiness endpoint for the Kubernetes Readiness Probe.
## Example Code
```go
package main
import (
"context"
"encoding/json"
"os"
"os/signal"
"syscall"
mutatingwebhook "github.com/statcan/mutating-webhook"
v1 "k8s.io/api/admission/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog"
)
// Define the variables that you will need.
var (
// define the variables
)
// Initialize the variables.
func init() {
// initialize the variables via arguments
// flag.StringVar(&variable, "argument", "default-value", "Argument description.")
}
// Define the variables you need in the struct
type customMutator struct {
// add variables you may need in your mutating code
}
// This is the function that will be called to mutate
func (cm *customMutator) Mutate(request v1.AdmissionRequest) (v1.AdmissionResponse, error) {
response := v1.AdmissionResponse{}
// Default response
response.Allowed = true
response.UID = request.UID
// Decode the object you are trying to mutate.
// Here's an example with a Pod:
// Decode the object
// (an example for Pod)
var err error
//pod := v1.Pod{}
// if err := json.Unmarshal(request.Object.Raw, &pod); err != nil {
// return response, fmt.Errorf("unable to decode Pod %w", err)
// }
// Add the logic you wish to implement and create patches:
patches := []map[string]interface{}{
{
"op": "add",
"path": "/spec/",
"value": "",
},
}
// If there are any patches, they will be appended to the
if len(patches) > 0 {
patchType := v1.PatchTypeJSONPatch
response.PatchType = &patchType
response.AuditAnnotations = map[string]string{
// Add annotations to clearly denote that actions have
// been performed on objects
}
response.Patch, err = json.Marshal(patches)
if err != nil {
return response, err
}
response.Result = &metav1.Status{
Status: metav1.StatusSuccess,
}
}
return response, nil
}
// Starts the webserver and serves the mutate function.
func main() {
mutator := customMutator{
// Your variables
}
mw, err := mutatingwebhook.NewMutatingWebhook(&mutator, mutatingwebhook.MutatingWebhookConfigs{
// If you want to change defaults, update them here.
})
if err != nil {
klog.Fatal(err)
}
defer klog.Info(mw.Shutdown(context.TODO()))
// Make a channel for the error and launch the blocking function in its own thread
errChan := make(chan error)
go func() {
errChan <- mw.ListenAndServe()
}()
// Create channel for interrupts
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
// Wait for interrupt or for server error to exit
select {
case interrupt := <-c:
klog.Info("received interrupt %d -- exiting", interrupt)
return
case err := <-errChan:
klog.Error(err)
}
}
```
## Dockerfile
A [Dockerfile](./Dockerfile) is supplied that can be used to build the Webhook quickly.
## Helm Chart
A Helm Chart is available in the [statcan/charts](https://github.com/statcan/charts/mutating-webhook).
This is the preferred method of deployment which uses cert-manager's capabilities of generating certificates for TLS, a requirement for Admission Webhooks.
## Testing
To test your webhook, you may use the tests available in `mutatingwebhook/mutatingwebhook_test.go` for inspiration in devising your own tests.
______________________
## Webhook Mutant
Ce répertoire fourni une base duquel un Mutating Webhook peut être facilement développer.