...

Source file src/sigs.k8s.io/controller-runtime/pkg/webhook/example_test.go

Documentation: sigs.k8s.io/controller-runtime/pkg/webhook

     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  }
   152  

View as plain text