diff --git a/pkg/builder/build.go b/pkg/builder/build.go index 487786586b..96a64974a2 100644 --- a/pkg/builder/build.go +++ b/pkg/builder/build.go @@ -18,6 +18,8 @@ package builder import ( "fmt" + "net/http" + "net/url" "strings" "k8s.io/apimachinery/pkg/runtime" @@ -280,11 +282,16 @@ func (blder *Builder) doWebhook() error { mwh := admission.DefaultingWebhookFor(defaulter) if mwh != nil { path := generateMutatePath(gvk) - log.Info("Registering a mutating webhook", - "GVK", gvk, - "path", path) - blder.mgr.GetWebhookServer().Register(path, mwh) + // Checking if the path is already registered. + // If so, just skip it. + h, p := blder.mgr.GetWebhookServer().WebhookMux.Handler(&http.Request{URL: &url.URL{Path: path}}) + if p != path || h == nil { + log.Info("Registering a mutating webhook", + "GVK", gvk, + "path", path) + blder.mgr.GetWebhookServer().Register(path, mwh) + } } } @@ -292,10 +299,16 @@ func (blder *Builder) doWebhook() error { vwh := admission.ValidatingWebhookFor(validator) if vwh != nil { path := generateValidatePath(gvk) - log.Info("Registering a validating webhook", - "GVK", gvk, - "path", path) - blder.mgr.GetWebhookServer().Register(path, vwh) + + // Checking if the path is already registered. + // If so, just skip it. + h, p := blder.mgr.GetWebhookServer().WebhookMux.Handler(&http.Request{URL: &url.URL{Path: path}}) + if p != path || h == nil { + log.Info("Registering a validating webhook", + "GVK", gvk, + "path", path) + blder.mgr.GetWebhookServer().Register(path, vwh) + } } } diff --git a/pkg/builder/build_test.go b/pkg/builder/build_test.go index 241f51c3f1..545f222a9e 100644 --- a/pkg/builder/build_test.go +++ b/pkg/builder/build_test.go @@ -350,6 +350,34 @@ var _ = Describe("application", func() { Expect(w.Body).To(ContainSubstring(`"allowed":true`)) Expect(w.Body).To(ContainSubstring(`"code":200`)) }) + + It("should allow multiple controllers for the same kind", func() { + By("creating a controller manager") + m, err := manager.New(cfg, manager.Options{}) + Expect(err).NotTo(HaveOccurred()) + + By("registering the type in the Scheme") + builder := scheme.Builder{GroupVersion: testDefaultValidatorGVK.GroupVersion()} + builder.Register(&TestDefaultValidator{}, &TestDefaultValidatorList{}) + err = builder.AddToScheme(m.GetScheme()) + Expect(err).NotTo(HaveOccurred()) + + By("creating the 1st controller") + ctrl1, err := ControllerManagedBy(m). + For(&TestDefaultValidator{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(ctrl1).NotTo(BeNil()) + + By("creating the 2nd controller") + ctrl2, err := ControllerManagedBy(m). + For(&TestDefaultValidator{}). + Owns(&appsv1.ReplicaSet{}). + Build(noop) + Expect(err).NotTo(HaveOccurred()) + Expect(ctrl2).NotTo(BeNil()) + }) }) Describe("Start with SimpleController", func() {