webhook

package
Version: v0.0.0-...-5dfa7fa Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2019 License: Apache-2.0 Imports: 24 Imported by: 0

README

Knative Webhooks

Knative provides infrastructure for authoring webhooks under knative.dev/pkg/webhook and has a few built-in helpers for certain common admission control scenarios. The built-in admission controllers are:

  1. Resource validation and defaulting (builds around apis.Validatable and apis.Defaultable under knative.dev/pkg/apis).
  2. ConfigMap validation, which builds around similar patterns from knative.dev/pkg/configmap (in particular the store concept)

To illustrate standing up the webhook, let's start with one of these built-in admission controllers and then talk about how you can write your own admission controller.

Standing up a Webhook from an Admission Controller

We provide facilities in knative.dev/pkg/injection/sharedmain to try and eliminate much of the boilerplate involved in standing up a webhook. For this example we will show how to stand up the webhook using the built-in admission controller for validating and defaulting resources.

The code to stand up such a webhook looks roughly like this:

// Create a function matching this signature to pass into sharedmain.
func NewResourceAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
	return resourcesemantics.NewAdmissionController(ctx,
		// Name of the resource webhook (created via yaml)
		fmt.Sprintf("resources.webhook.%s.knative.dev", system.Namespace()),

		// The path on which to serve the webhook.
		"/resource-validation",

		// The resources to validate and default.
		map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
			// List the types to validate, this from knative.dev/sample-controller
			v1alpha1.SchemeGroupVersion.WithKind("AddressableService"): &v1alpha1.AddressableService{},
		},

		// A function that infuses the context passed to Validate/SetDefaults with custom metadata.
		func(ctx context.Context) context.Context {
			// Here is where you would infuse the context with state
			// (e.g. attach a store with configmap data, like knative.dev/serving attaches config-defaults)
			return ctx
		},

		// Whether to disallow unknown fields when parsing the resources' JSON.
		true,
	)
}

func main() {
	// Set up a signal context with our webhook options.
	ctx := webhook.WithOptions(signals.NewContext(), webhook.Options{
		// The name of the Kubernetes service selecting over this deployment's pods.
		ServiceName: "webhook",

		// The port on which to serve.
		Port:        8443,

		// The name of the secret containing certificate data.
		SecretName:  "webhook-certs",
	})

	sharedmain.MainWithContext(ctx, "webhook",
		// The certificate controller will ensure that the named secret (above) has
		// the appropriate shape for our webhook's admission controllers.
		certificates.NewController,

		// This invokes the method defined above to instantiate the resource admission
		// controller.
		NewResourceAdmissionController,
	)
}

There is also a config map validation admission controller built in under knative.dev/pkg/webhook/configmaps.

Writing new Admission Controllers

To implement your own admission controller akin to the resource defaulting and validation controller above, you implement a knative.dev/pkg/controller.Reconciler as with any you would with any other type of controller, but the Reconciler that gets embedded in the *controller.Impl should also implement:

// AdmissionController provides the interface for different admission controllers
type AdmissionController interface {
	// Path returns the path that this particular admission controller serves on.
	Path() string

	// Admit is the callback which is invoked when an HTTPS request comes in on Path().
	Admit(context.Context, *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
}

The Reconciler part is responsible for the mutating or validating webhook configuration. The AdmissionController part is responsible for guiding request dispatch (Path()) and handling admission requests (Admit()).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MakeErrorStatus

func MakeErrorStatus(reason string, args ...interface{}) *admissionv1beta1.AdmissionResponse

func RegisterMetrics

func RegisterMetrics()

func WithOptions

func WithOptions(ctx context.Context, opt Options) context.Context

WithOptions associates a set of webhook.Options with the returned context.

Types

type AdmissionController

type AdmissionController interface {
	// Path returns the path that this particular admission controller serves on.
	Path() string

	// Admit is the callback which is invoked when an HTTPS request comes in on Path().
	// TODO(mattmoor): This will need to be different for Conversion webhooks, which is something
	// to start thinking about.
	Admit(context.Context, *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse
}

AdmissionController provides the interface for different admission controllers

type Options

type Options struct {
	// ServiceName is the service name of the webhook.
	ServiceName string

	// SecretName is the name of k8s secret that contains the webhook
	// server key/cert and corresponding CA cert that signed them. The
	// server key/cert are used to serve the webhook and the CA cert
	// is provided to k8s apiserver during admission controller
	// registration.
	SecretName string

	// Port where the webhook is served. Per k8s admission
	// registration requirements this should be 443 unless there is
	// only a single port for the service.
	Port int

	// StatsReporter reports metrics about the webhook.
	// This will be automatically initialized by the constructor if left uninitialized.
	StatsReporter StatsReporter
}

Options contains the configuration for the webhook

func GetOptions

func GetOptions(ctx context.Context) *Options

GetOptions retrieves webhook.Options associated with the given context via WithOptions (above).

type StatsReporter

type StatsReporter interface {
	ReportRequest(request *admissionv1beta1.AdmissionRequest, response *admissionv1beta1.AdmissionResponse, d time.Duration) error
}

StatsReporter reports webhook metrics

func NewStatsReporter

func NewStatsReporter() (StatsReporter, error)

NewStatsReporter creaters a reporter for webhook metrics

type Webhook

type Webhook struct {
	Client  kubernetes.Interface
	Options Options
	Logger  *zap.SugaredLogger
	// contains filtered or unexported fields
}

Webhook implements the external webhook for validation of resources and configuration.

func New

func New(
	ctx context.Context,
	admissionControllers []AdmissionController,
) (*Webhook, error)

New constructs a Webhook

func (*Webhook) Run

func (ac *Webhook) Run(stop <-chan struct{}) error

Run implements the admission controller run loop.

func (*Webhook) ServeHTTP

func (ac *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the external admission webhook for mutating serving resources.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL