93
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go
generated
vendored
93
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go
generated
vendored
@@ -22,13 +22,16 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"gomodules.xyz/jsonpatch/v2"
|
||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
||||
jsonpatch "gomodules.xyz/jsonpatch/v2"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -41,7 +44,7 @@ var (
|
||||
// name, namespace), as well as the operation in question
|
||||
// (e.g. Get, Create, etc), and the object itself.
|
||||
type Request struct {
|
||||
admissionv1beta1.AdmissionRequest
|
||||
admissionv1.AdmissionRequest
|
||||
}
|
||||
|
||||
// Response is the output of an admission handler.
|
||||
@@ -57,7 +60,7 @@ type Response struct {
|
||||
Patches []jsonpatch.JsonPatchOperation
|
||||
// AdmissionResponse is the raw admission response.
|
||||
// The Patch field in it will be overwritten by the listed patches.
|
||||
admissionv1beta1.AdmissionResponse
|
||||
admissionv1.AdmissionResponse
|
||||
}
|
||||
|
||||
// Complete populates any fields that are yet to be set in
|
||||
@@ -84,7 +87,7 @@ func (r *Response) Complete(req Request) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
patchType := admissionv1beta1.PatchTypeJSONPatch
|
||||
patchType := admissionv1.PatchTypeJSONPatch
|
||||
r.PatchType = &patchType
|
||||
|
||||
return nil
|
||||
@@ -110,11 +113,19 @@ func (f HandlerFunc) Handle(ctx context.Context, req Request) Response {
|
||||
}
|
||||
|
||||
// Webhook represents each individual webhook.
|
||||
//
|
||||
// It must be registered with a webhook.Server or
|
||||
// populated by StandaloneWebhook to be ran on an arbitrary HTTP server.
|
||||
type Webhook struct {
|
||||
// Handler actually processes an admission request returning whether it was allowed or denied,
|
||||
// and potentially patches to apply to the handler.
|
||||
Handler Handler
|
||||
|
||||
// WithContextFunc will allow you to take the http.Request.Context() and
|
||||
// add any additional information such as passing the request path or
|
||||
// headers thus allowing you to read them from within the handler
|
||||
WithContextFunc func(context.Context, *http.Request) context.Context
|
||||
|
||||
// decoder is constructed on receiving a scheme and passed down to then handler
|
||||
decoder *Decoder
|
||||
|
||||
@@ -122,8 +133,8 @@ type Webhook struct {
|
||||
}
|
||||
|
||||
// InjectLogger gets a handle to a logging instance, hopefully with more info about this particular webhook.
|
||||
func (w *Webhook) InjectLogger(l logr.Logger) error {
|
||||
w.log = l
|
||||
func (wh *Webhook) InjectLogger(l logr.Logger) error {
|
||||
wh.log = l
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -131,10 +142,10 @@ func (w *Webhook) InjectLogger(l logr.Logger) error {
|
||||
// If the webhook is mutating type, it delegates the AdmissionRequest to each handler and merge the patches.
|
||||
// If the webhook is validating type, it delegates the AdmissionRequest to each handler and
|
||||
// deny the request if anyone denies.
|
||||
func (w *Webhook) Handle(ctx context.Context, req Request) Response {
|
||||
resp := w.Handler.Handle(ctx, req)
|
||||
func (wh *Webhook) Handle(ctx context.Context, req Request) Response {
|
||||
resp := wh.Handler.Handle(ctx, req)
|
||||
if err := resp.Complete(req); err != nil {
|
||||
w.log.Error(err, "unable to encode response")
|
||||
wh.log.Error(err, "unable to encode response")
|
||||
return Errored(http.StatusInternalServerError, errUnableToEncodeResponse)
|
||||
}
|
||||
|
||||
@@ -142,19 +153,19 @@ func (w *Webhook) Handle(ctx context.Context, req Request) Response {
|
||||
}
|
||||
|
||||
// InjectScheme injects a scheme into the webhook, in order to construct a Decoder.
|
||||
func (w *Webhook) InjectScheme(s *runtime.Scheme) error {
|
||||
func (wh *Webhook) InjectScheme(s *runtime.Scheme) error {
|
||||
// TODO(directxman12): we should have a better way to pass this down
|
||||
|
||||
var err error
|
||||
w.decoder, err = NewDecoder(s)
|
||||
wh.decoder, err = NewDecoder(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// inject the decoder here too, just in case the order of calling this is not
|
||||
// scheme first, then inject func
|
||||
if w.Handler != nil {
|
||||
if _, err := InjectDecoderInto(w.GetDecoder(), w.Handler); err != nil {
|
||||
if wh.Handler != nil {
|
||||
if _, err := InjectDecoderInto(wh.GetDecoder(), wh.Handler); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -164,12 +175,12 @@ func (w *Webhook) InjectScheme(s *runtime.Scheme) error {
|
||||
|
||||
// GetDecoder returns a decoder to decode the objects embedded in admission requests.
|
||||
// It may be nil if we haven't received a scheme to use to determine object types yet.
|
||||
func (w *Webhook) GetDecoder() *Decoder {
|
||||
return w.decoder
|
||||
func (wh *Webhook) GetDecoder() *Decoder {
|
||||
return wh.decoder
|
||||
}
|
||||
|
||||
// InjectFunc injects the field setter into the webhook.
|
||||
func (w *Webhook) InjectFunc(f inject.Func) error {
|
||||
func (wh *Webhook) InjectFunc(f inject.Func) error {
|
||||
// inject directly into the handlers. It would be more correct
|
||||
// to do this in a sync.Once in Handle (since we don't have some
|
||||
// other start/finalize-type method), but it's more efficient to
|
||||
@@ -189,12 +200,56 @@ func (w *Webhook) InjectFunc(f inject.Func) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := InjectDecoderInto(w.GetDecoder(), target); err != nil {
|
||||
if _, err := InjectDecoderInto(wh.GetDecoder(), target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return setFields(w.Handler)
|
||||
return setFields(wh.Handler)
|
||||
}
|
||||
|
||||
// StandaloneOptions let you configure a StandaloneWebhook.
|
||||
type StandaloneOptions struct {
|
||||
// Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources
|
||||
// Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better
|
||||
// idea to pass your own scheme in. See the documentation in pkg/scheme for more information.
|
||||
Scheme *runtime.Scheme
|
||||
// Logger to be used by the webhook.
|
||||
// If none is set, it defaults to log.Log global logger.
|
||||
Logger logr.Logger
|
||||
// MetricsPath is used for labelling prometheus metrics
|
||||
// by the path is served on.
|
||||
// If none is set, prometheus metrics will not be generated.
|
||||
MetricsPath string
|
||||
}
|
||||
|
||||
// StandaloneWebhook prepares a webhook for use without a webhook.Server,
|
||||
// passing in the information normally populated by webhook.Server
|
||||
// and instrumenting the webhook with metrics.
|
||||
//
|
||||
// Use this to attach your webhook to an arbitrary HTTP server or mux.
|
||||
//
|
||||
// Note that you are responsible for terminating TLS if you use StandaloneWebhook
|
||||
// in your own server/mux. In order to be accessed by a kubernetes cluster,
|
||||
// all webhook servers require TLS.
|
||||
func StandaloneWebhook(hook *Webhook, opts StandaloneOptions) (http.Handler, error) {
|
||||
if opts.Scheme == nil {
|
||||
opts.Scheme = scheme.Scheme
|
||||
}
|
||||
|
||||
if err := hook.InjectScheme(opts.Scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.Logger == nil {
|
||||
opts.Logger = logf.RuntimeLog.WithName("webhook")
|
||||
}
|
||||
hook.log = opts.Logger
|
||||
|
||||
if opts.MetricsPath == "" {
|
||||
return hook, nil
|
||||
}
|
||||
return metrics.InstrumentedHook(opts.MetricsPath, hook), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user