-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ Helper for unmanaged webhook server #1429
Changes from all commits
83846f5
2c24442
12c19f7
9a73ff4
4dc10f9
5a5106d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,18 +18,24 @@ package webhook_test | |
|
||
import ( | ||
"context" | ||
"net/http" | ||
|
||
"k8s.io/client-go/kubernetes/scheme" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
logf "sigs.k8s.io/controller-runtime/pkg/internal/log" | ||
"sigs.k8s.io/controller-runtime/pkg/manager/signals" | ||
. "sigs.k8s.io/controller-runtime/pkg/webhook" | ||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission" | ||
) | ||
|
||
func Example() { | ||
// Build webhooks | ||
var ( | ||
// Build webhooks used for the various server | ||
// configuration options | ||
// | ||
// These handlers could be also be implementations | ||
// of the AdmissionHandler interface for more complex | ||
// implementations. | ||
mutatingHook := &Admission{ | ||
mutatingHook = &Admission{ | ||
Handler: admission.HandlerFunc(func(ctx context.Context, req AdmissionRequest) AdmissionResponse { | ||
return Patched("some changes", | ||
JSONPatchOp{Operation: "add", Path: "/metadata/annotations/access", Value: "granted"}, | ||
|
@@ -38,12 +44,16 @@ func Example() { | |
}), | ||
} | ||
|
||
validatingHook := &Admission{ | ||
validatingHook = &Admission{ | ||
Handler: admission.HandlerFunc(func(ctx context.Context, req AdmissionRequest) AdmissionResponse { | ||
return Denied("none shall pass!") | ||
}), | ||
} | ||
) | ||
|
||
// This example registers a webhooks to a webhook server | ||
// that gets ran by a controller manager. | ||
func Example() { | ||
// Create a manager | ||
// Note: GetConfigOrDie will os.Exit(1) w/o any message if no kube-config can be found | ||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{}) | ||
|
@@ -70,3 +80,72 @@ func Example() { | |
panic(err) | ||
} | ||
} | ||
|
||
// This example creates a webhook server that can be | ||
// ran without a controller manager. | ||
func ExampleServer_StartStandalone() { | ||
// Create a webhook server | ||
hookServer := &Server{ | ||
Port: 8443, | ||
} | ||
|
||
// Register the webhooks in the server. | ||
hookServer.Register("/mutating", mutatingHook) | ||
hookServer.Register("/validating", validatingHook) | ||
|
||
// Start the server without a manger | ||
err := hookServer.StartStandalone(signals.SetupSignalHandler(), scheme.Scheme) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kevindelgado one more thing - maybe we could write an e2e for examples to help catch these, but it looks like the cert and key are not optional on this server? When using code similar to this, I get:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's intentional -- same with the non-standalone server. More broadly, the main point of the webhook server is to help with managing TLS setup properly. If you don't want TLS, use StandaloneWebhook. We could certainly document that better, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
if err != nil { | ||
// handle error | ||
panic(err) | ||
} | ||
} | ||
|
||
// This example creates a standalone webhook handler | ||
// and runs it on a vanilla go HTTP server to demonstrate | ||
// how you could run a webhook on an existing server | ||
// without a controller manager. | ||
func ExampleStandaloneWebhook() { | ||
// Assume you have an existing HTTP server at your disposal | ||
// configured as desired (e.g. with TLS). | ||
// For this example just create a basic http.ServeMux | ||
mux := http.NewServeMux() | ||
port := ":8000" | ||
|
||
// Create the standalone HTTP handlers from our webhooks | ||
mutatingHookHandler, err := admission.StandaloneWebhook(mutatingHook, admission.StandaloneOptions{ | ||
Scheme: scheme.Scheme, | ||
// Logger let's you optionally pass | ||
// a custom logger (defaults to log.Log global Logger) | ||
Logger: logf.RuntimeLog.WithName("mutating-webhook"), | ||
// MetricsPath let's you optionally | ||
// provide the path it will be served on | ||
// to be used for labelling prometheus metrics | ||
// If none is set, prometheus metrics will not be generated. | ||
MetricsPath: "/mutating", | ||
}) | ||
if err != nil { | ||
// handle error | ||
panic(err) | ||
} | ||
|
||
validatingHookHandler, err := admission.StandaloneWebhook(validatingHook, admission.StandaloneOptions{ | ||
Scheme: scheme.Scheme, | ||
Logger: logf.RuntimeLog.WithName("validating-webhook"), | ||
MetricsPath: "/validating", | ||
}) | ||
if err != nil { | ||
// handle error | ||
panic(err) | ||
} | ||
|
||
// Register the webhook handlers to your server | ||
mux.Handle("/mutating", mutatingHookHandler) | ||
mux.Handle("/validating", validatingHookHandler) | ||
|
||
// Run your handler | ||
if err := http.ListenAndServe(port, mux); err != nil { | ||
panic(err) | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kevindelgado what actually injects this into the
hook.Handler
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦 It doesn't... because I'm dumb
See #1490
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi, fixed now @stevekuznetsov