sigs.k8s.io/controller-runtime@v0.18.2/pkg/webhook/example_test.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package webhook_test 18 19 import ( 20 "context" 21 "net/http" 22 23 ctrl "sigs.k8s.io/controller-runtime" 24 logf "sigs.k8s.io/controller-runtime/pkg/internal/log" 25 "sigs.k8s.io/controller-runtime/pkg/manager/signals" 26 . "sigs.k8s.io/controller-runtime/pkg/webhook" 27 "sigs.k8s.io/controller-runtime/pkg/webhook/admission" 28 ) 29 30 var ( 31 // Build webhooks used for the various server 32 // configuration options 33 // 34 // These handlers could be also be implementations 35 // of the AdmissionHandler interface for more complex 36 // implementations. 37 mutatingHook = &Admission{ 38 Handler: admission.HandlerFunc(func(ctx context.Context, req AdmissionRequest) AdmissionResponse { 39 return Patched("some changes", 40 JSONPatchOp{Operation: "add", Path: "/metadata/annotations/access", Value: "granted"}, 41 JSONPatchOp{Operation: "add", Path: "/metadata/annotations/reason", Value: "not so secret"}, 42 ) 43 }), 44 } 45 46 validatingHook = &Admission{ 47 Handler: admission.HandlerFunc(func(ctx context.Context, req AdmissionRequest) AdmissionResponse { 48 return Denied("none shall pass!") 49 }), 50 } 51 ) 52 53 // This example registers a webhooks to a webhook server 54 // that gets ran by a controller manager. 55 func Example() { 56 // Create a manager 57 // Note: GetConfigOrDie will os.Exit(1) w/o any message if no kube-config can be found 58 mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{}) 59 if err != nil { 60 panic(err) 61 } 62 63 // Create a webhook server. 64 hookServer := NewServer(Options{ 65 Port: 8443, 66 }) 67 if err := mgr.Add(hookServer); err != nil { 68 panic(err) 69 } 70 71 // Register the webhooks in the server. 72 hookServer.Register("/mutating", mutatingHook) 73 hookServer.Register("/validating", validatingHook) 74 75 // Start the server by starting a previously-set-up manager 76 err = mgr.Start(ctrl.SetupSignalHandler()) 77 if err != nil { 78 // handle error 79 panic(err) 80 } 81 } 82 83 // This example creates a webhook server that can be 84 // ran without a controller manager. 85 // 86 // Note that this assumes and requires a valid TLS 87 // cert and key at the default locations 88 // tls.crt and tls.key. 89 func ExampleServer_Start() { 90 // Create a webhook server 91 hookServer := NewServer(Options{ 92 Port: 8443, 93 }) 94 95 // Register the webhooks in the server. 96 hookServer.Register("/mutating", mutatingHook) 97 hookServer.Register("/validating", validatingHook) 98 99 // Start the server without a manger 100 err := hookServer.Start(signals.SetupSignalHandler()) 101 if err != nil { 102 // handle error 103 panic(err) 104 } 105 } 106 107 // This example creates a standalone webhook handler 108 // and runs it on a vanilla go HTTP server to demonstrate 109 // how you could run a webhook on an existing server 110 // without a controller manager. 111 func ExampleStandaloneWebhook() { 112 // Assume you have an existing HTTP server at your disposal 113 // configured as desired (e.g. with TLS). 114 // For this example just create a basic http.ServeMux 115 mux := http.NewServeMux() 116 port := ":8000" 117 118 // Create the standalone HTTP handlers from our webhooks 119 mutatingHookHandler, err := admission.StandaloneWebhook(mutatingHook, admission.StandaloneOptions{ 120 // Logger let's you optionally pass 121 // a custom logger (defaults to log.Log global Logger) 122 Logger: logf.RuntimeLog.WithName("mutating-webhook"), 123 // MetricsPath let's you optionally 124 // provide the path it will be served on 125 // to be used for labelling prometheus metrics 126 // If none is set, prometheus metrics will not be generated. 127 MetricsPath: "/mutating", 128 }) 129 if err != nil { 130 // handle error 131 panic(err) 132 } 133 134 validatingHookHandler, err := admission.StandaloneWebhook(validatingHook, admission.StandaloneOptions{ 135 Logger: logf.RuntimeLog.WithName("validating-webhook"), 136 MetricsPath: "/validating", 137 }) 138 if err != nil { 139 // handle error 140 panic(err) 141 } 142 143 // Register the webhook handlers to your server 144 mux.Handle("/mutating", mutatingHookHandler) 145 mux.Handle("/validating", validatingHookHandler) 146 147 // Run your handler 148 if err := http.ListenAndServe(port, mux); err != nil { //nolint:gosec // it's fine to not set timeouts here 149 panic(err) 150 } 151 }