{"id":22423858,"url":"https://github.com/statcan/mutating-webhook","last_synced_at":"2025-08-01T07:32:34.231Z","repository":{"id":49896758,"uuid":"367390335","full_name":"StatCan/mutating-webhook","owner":"StatCan","description":"A small library that allows for the quick creation of Admission Controllers. // Une petite librairie facilitant facilement la création de Admission Controllers.","archived":false,"fork":false,"pushed_at":"2021-08-12T17:54:22.000Z","size":101,"stargazers_count":1,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-20T20:11:27.048Z","etag":null,"topics":["admission-controller","cloud-native","cns","golang","kubernetes","mutating-webhook"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StatCan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null}},"created_at":"2021-05-14T14:36:58.000Z","updated_at":"2022-11-02T22:33:56.000Z","dependencies_parsed_at":"2022-08-29T17:52:00.960Z","dependency_job_id":null,"html_url":"https://github.com/StatCan/mutating-webhook","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatCan%2Fmutating-webhook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatCan%2Fmutating-webhook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatCan%2Fmutating-webhook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatCan%2Fmutating-webhook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StatCan","download_url":"https://codeload.github.com/StatCan/mutating-webhook/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228348339,"owners_count":17905899,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admission-controller","cloud-native","cns","golang","kubernetes","mutating-webhook"],"created_at":"2024-12-05T18:13:17.189Z","updated_at":"2024-12-05T18:13:18.074Z","avatar_url":"https://github.com/StatCan.png","language":"Go","readme":"## Mutating Webhook\n\nThis 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.\n\n## How To Use\n\n### Implement `Mutator`\n\nThe `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.\n\n### Get A `MutatingWebhook` \n\nThe `MutatingWebhook` interface returned by `NewMutatingWebhook(mutator Mutator, configs MutatingWebhookConfigs)` function is what is used to create the server. \n\nIt requires two arguments:\n- `mutator Mutator`: a reference to the `struct` that implements your `Mutate` function.\n- `configs MutatingWebhookConfigs`: a reference to the configs you wish to pass to the webserver. Any `nil` values will use defaults.\n  | Field          | Default           |\n  | -------------- | ----------------- |\n  | Addr           | \":8443\"           |\n  | ReadTimeout    | 10 * time.Second  |\n  | WriteTimeout   | 10 * time.Second  |\n  | MaxHeaderBytes | 0                 |\n  | CertFilePath   | \"./certs/tls.crt\" |\n  | KeyFilePath    | \"./certs/tls.key\" |\n\nOnce you instantiate the struct that implements the interface via the constructor, you can start the server!\n\n### ListenAndServe()\n\n`ListenAndServe()` is how you'll start the server! It is a blocking function, so it's best to run it in a go routine.\n\n### Shutdown()\nOnce 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.\nThis will cause the blocking `ListenAndServe` to return a non-nil error. If the shutdown was gracefully completed `ErrServerClosed` will be returned as the error.\n\n### Endpoints\n\nThere are four endpoints that are available from the webserver:\n- `/` - A welcome message is served at the root.\n- `/mutate` - The `Mutate` function you implemented is served from this endpoint.\n- `/_healthz` - A health endpoint for the Kubernetes Liveness Probe.\n- `/_ready` - A readiness endpoint for the Kubernetes Readiness Probe.\n\n## Example Code\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\n\tmutatingwebhook \"github.com/statcan/mutating-webhook\"\n\tv1 \"k8s.io/api/admission/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/klog\"\n)\n\n// Define the variables that you will need.\nvar (\n// define the variables\n)\n\n// Initialize the variables.\nfunc init() {\n\t// initialize the variables via arguments\n\t// flag.StringVar(\u0026variable, \"argument\", \"default-value\", \"Argument description.\")\n}\n\n// Define the variables you need in the struct\ntype customMutator struct {\n\t// add variables you may need in your mutating code\n}\n\n// This is the function that will be called to mutate\nfunc (cm *customMutator) Mutate(request v1.AdmissionRequest) (v1.AdmissionResponse, error) {\n\tresponse := v1.AdmissionResponse{}\n\n\t// Default response\n\tresponse.Allowed = true\n\tresponse.UID = request.UID\n\n\t// Decode the object you are trying to mutate.\n\t// Here's an example with a Pod:\n\n\t// Decode the object\n\t// (an example for Pod)\n\tvar err error\n\t//pod := v1.Pod{}\n\t// if err := json.Unmarshal(request.Object.Raw, \u0026pod); err != nil {\n\t// \treturn response, fmt.Errorf(\"unable to decode Pod %w\", err)\n\t// }\n\n\t// Add the logic you wish to implement and create patches:\n\tpatches := []map[string]interface{}{\n\t\t{\n\t\t\t\"op\":    \"add\",\n\t\t\t\"path\":  \"/spec/\",\n\t\t\t\"value\": \"\",\n\t\t},\n\t}\n\n\t// If there are any patches, they will be appended to the\n\tif len(patches) \u003e 0 {\n\n\t\tpatchType := v1.PatchTypeJSONPatch\n\t\tresponse.PatchType = \u0026patchType\n\n\t\tresponse.AuditAnnotations = map[string]string{\n\t\t\t// Add annotations to clearly denote that actions have\n\t\t\t// been performed on objects\n\t\t}\n\n\t\tresponse.Patch, err = json.Marshal(patches)\n\t\tif err != nil {\n\t\t\treturn response, err\n\t\t}\n\n\t\tresponse.Result = \u0026metav1.Status{\n\t\t\tStatus: metav1.StatusSuccess,\n\t\t}\n\t}\n\n\treturn response, nil\n}\n\n// Starts the webserver and serves the mutate function.\nfunc main() {\n\n\tmutator := customMutator{\n\t\t// Your variables\n\t}\n\n\tmw, err := mutatingwebhook.NewMutatingWebhook(\u0026mutator, mutatingwebhook.MutatingWebhookConfigs{\n\t\t// If you want to change defaults, update them here.\n\t})\n\tif err != nil {\n\t\tklog.Fatal(err)\n\t}\n\tdefer klog.Info(mw.Shutdown(context.TODO()))\n\n\t// Make a channel for the error and launch the blocking function in its own thread\n\terrChan := make(chan error)\n\tgo func() {\n\t\terrChan \u003c- mw.ListenAndServe()\n\t}()\n\n\t// Create channel for interrupts\n\tc := make(chan os.Signal, 1)\n\tsignal.Notify(c, os.Interrupt, syscall.SIGTERM)\n\n\t// Wait for interrupt or for server error to exit\n\tselect {\n\tcase interrupt := \u003c-c:\n\t\tklog.Info(\"received interrupt %d -- exiting\", interrupt)\n\t\treturn\n\tcase err := \u003c-errChan:\n\t\tklog.Error(err)\n\t}\n}\n```\n\n## Dockerfile\n\nA [Dockerfile](./Dockerfile) is supplied that can be used to build the Webhook quickly.\n\n## Helm Chart\n\nA Helm Chart is available in the [statcan/charts](https://github.com/statcan/charts/mutating-webhook). \nThis is the preferred method of deployment which uses cert-manager's capabilities of generating certificates for TLS, a requirement for Admission Webhooks. \n\n## Testing\n\nTo test your webhook, you may use the tests available in `mutatingwebhook/mutatingwebhook_test.go` for inspiration in devising your own tests.\n______________________\n\n## Webhook Mutant\n\nCe répertoire fourni une base duquel un Mutating Webhook peut être facilement développer.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatcan%2Fmutating-webhook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstatcan%2Fmutating-webhook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatcan%2Fmutating-webhook/lists"}