Skip to content

Commit d36a00e

Browse files
author
Mengqi Yu
committed
⚠️ split the webhook builder out as a separate builder.
Controller builder now only build controller; while webhook builder only build webhook.
1 parent 71cdf35 commit d36a00e

File tree

7 files changed

+541
-367
lines changed

7 files changed

+541
-367
lines changed

alias.go

+3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ var (
9494
// NewControllerManagedBy returns a new controller builder that will be started by the provided Manager
9595
NewControllerManagedBy = builder.ControllerManagedBy
9696

97+
// NewWebhookManagedBy returns a new webhook builder that will be started by the provided Manager
98+
NewWebhookManagedBy = builder.WebhookManagedBy
99+
97100
// NewManager returns a new Manager for creating Controllers.
98101
NewManager = manager.New
99102

examples/crd/main.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,19 @@ func main() {
125125
Client: mgr.GetClient(),
126126
scheme: mgr.GetScheme(),
127127
})
128-
129128
if err != nil {
130129
setupLog.Error(err, "unable to create controller")
131130
os.Exit(1)
132131
}
133132

133+
err = ctrl.NewWebhookManagedBy(mgr).
134+
For(&api.ChaosPod{}).
135+
Complete()
136+
if err != nil {
137+
setupLog.Error(err, "unable to create webhook")
138+
os.Exit(1)
139+
}
140+
134141
setupLog.Info("starting manager")
135142
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
136143
setupLog.Error(err, "problem running manager")

pkg/builder/build.go pkg/builder/controller.go

+2-92
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@ package builder
1818

1919
import (
2020
"fmt"
21-
"net/http"
22-
"net/url"
2321
"strings"
2422

2523
"k8s.io/apimachinery/pkg/runtime"
26-
"k8s.io/apimachinery/pkg/runtime/schema"
2724
"k8s.io/client-go/rest"
2825
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
2926
"sigs.k8s.io/controller-runtime/pkg/client/config"
@@ -33,8 +30,6 @@ import (
3330
"sigs.k8s.io/controller-runtime/pkg/predicate"
3431
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3532
"sigs.k8s.io/controller-runtime/pkg/source"
36-
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
37-
"sigs.k8s.io/controller-runtime/pkg/webhook/conversion"
3833
)
3934

4035
// Supporting mocking out functions for testing
@@ -71,8 +66,6 @@ func ControllerManagedBy(m manager.Manager) *Builder {
7166
// update events by *reconciling the object*.
7267
// This is the equivalent of calling
7368
// Watches(&source.Kind{Type: apiType}, &handler.EnqueueRequestForObject{})
74-
// If the passed in object has implemented the admission.Defaulter interface, a MutatingWebhook will be wired for this type.
75-
// If the passed in object has implemented the admission.Validator interface, a ValidatingWebhook will be wired for this type.
7669
//
7770
// Deprecated: Use For
7871
func (blder *Builder) ForType(apiType runtime.Object) *Builder {
@@ -83,8 +76,6 @@ func (blder *Builder) ForType(apiType runtime.Object) *Builder {
8376
// update events by *reconciling the object*.
8477
// This is the equivalent of calling
8578
// Watches(&source.Kind{Type: apiType}, &handler.EnqueueRequestForObject{})
86-
// If the passed in object has implemented the admission.Defaulter interface, a MutatingWebhook will be wired for this type.
87-
// If the passed in object has implemented the admission.Validator interface, a ValidatingWebhook will be wired for this type.
8879
func (blder *Builder) For(apiType runtime.Object) *Builder {
8980
blder.apiType = apiType
9081
return blder
@@ -159,7 +150,7 @@ func (blder *Builder) Build(r reconcile.Reconciler) (manager.Manager, error) {
159150
}
160151

161152
// Set the Config
162-
if err := blder.doConfig(); err != nil {
153+
if err := blder.loadRestConfig(); err != nil {
163154
return nil, err
164155
}
165156

@@ -173,11 +164,6 @@ func (blder *Builder) Build(r reconcile.Reconciler) (manager.Manager, error) {
173164
return nil, err
174165
}
175166

176-
// Set the Webook if needed
177-
if err := blder.doWebhook(); err != nil {
178-
return nil, err
179-
}
180-
181167
// Set the Watch
182168
if err := blder.doWatch(); err != nil {
183169
return nil, err
@@ -217,7 +203,7 @@ func (blder *Builder) doWatch() error {
217203
return nil
218204
}
219205

220-
func (blder *Builder) doConfig() error {
206+
func (blder *Builder) loadRestConfig() error {
221207
if blder.config != nil {
222208
return nil
223209
}
@@ -258,79 +244,3 @@ func (blder *Builder) doController(r reconcile.Reconciler) error {
258244
blder.ctrl, err = newController(name, blder.mgr, controller.Options{Reconciler: r})
259245
return err
260246
}
261-
262-
func (blder *Builder) doWebhook() error {
263-
// Create a webhook for each type
264-
gvk, err := apiutil.GVKForObject(blder.apiType, blder.mgr.GetScheme())
265-
if err != nil {
266-
return err
267-
}
268-
269-
// TODO: When the conversion webhook lands, we need to handle all registered versions of a given group-kind.
270-
// A potential workflow for defaulting webhook
271-
// 1) a bespoke (non-hub) version comes in
272-
// 2) convert it to the hub version
273-
// 3) do defaulting
274-
// 4) convert it back to the same bespoke version
275-
// 5) calculate the JSON patch
276-
//
277-
// A potential workflow for validating webhook
278-
// 1) a bespoke (non-hub) version comes in
279-
// 2) convert it to the hub version
280-
// 3) do validation
281-
if defaulter, isDefaulter := blder.apiType.(admission.Defaulter); isDefaulter {
282-
mwh := admission.DefaultingWebhookFor(defaulter)
283-
if mwh != nil {
284-
path := generateMutatePath(gvk)
285-
286-
// Checking if the path is already registered.
287-
// If so, just skip it.
288-
if !blder.isAlreadyHandled(path) {
289-
log.Info("Registering a mutating webhook",
290-
"GVK", gvk,
291-
"path", path)
292-
blder.mgr.GetWebhookServer().Register(path, mwh)
293-
}
294-
}
295-
}
296-
297-
if validator, isValidator := blder.apiType.(admission.Validator); isValidator {
298-
vwh := admission.ValidatingWebhookFor(validator)
299-
if vwh != nil {
300-
path := generateValidatePath(gvk)
301-
302-
// Checking if the path is already registered.
303-
// If so, just skip it.
304-
if !blder.isAlreadyHandled(path) {
305-
log.Info("Registering a validating webhook",
306-
"GVK", gvk,
307-
"path", path)
308-
blder.mgr.GetWebhookServer().Register(path, vwh)
309-
}
310-
}
311-
}
312-
313-
err = conversion.CheckConvertibility(blder.mgr.GetScheme(), blder.apiType)
314-
if err != nil {
315-
log.Error(err, "conversion check failed", "GVK", gvk)
316-
}
317-
return nil
318-
}
319-
320-
func (blder *Builder) isAlreadyHandled(path string) bool {
321-
h, p := blder.mgr.GetWebhookServer().WebhookMux.Handler(&http.Request{URL: &url.URL{Path: path}})
322-
if p == path && h != nil {
323-
return true
324-
}
325-
return false
326-
}
327-
328-
func generateMutatePath(gvk schema.GroupVersionKind) string {
329-
return "/mutate-" + strings.Replace(gvk.Group, ".", "-", -1) + "-" +
330-
gvk.Version + "-" + strings.ToLower(gvk.Kind)
331-
}
332-
333-
func generateValidatePath(gvk schema.GroupVersionKind) string {
334-
return "/validate-" + strings.Replace(gvk.Group, ".", "-", -1) + "-" +
335-
gvk.Version + "-" + strings.ToLower(gvk.Kind)
336-
}

0 commit comments

Comments
 (0)