diff --git a/example/main.go b/example/main.go index 81bcdc1cce..55188fc739 100644 --- a/example/main.go +++ b/example/main.go @@ -92,7 +92,7 @@ func main() { Build() entryLog.Info("setting up webhook server") - as, err := webhook.NewServer("foo-admission-server", mgr, webhook.ServerOptions{ + as, err := webhook.NewServer(mgr, webhook.ServerOptions{ Port: 9876, CertDir: "/tmp/cert", }) @@ -104,7 +104,7 @@ func main() { entryLog.Info("registering webhooks to the webhook server") err = as.Register(mutatingWebhook, validatingWebhook) if err != nil { - entryLog.Error(err, "unable to register webhooks in the admission server") + entryLog.Error(err, "unable to setup the admission server") os.Exit(1) } diff --git a/pkg/webhook/admission/webhook.go b/pkg/webhook/admission/webhook.go index 75983b6751..632160c0cb 100644 --- a/pkg/webhook/admission/webhook.go +++ b/pkg/webhook/admission/webhook.go @@ -30,7 +30,6 @@ import ( admissionv1beta1 "k8s.io/api/admission/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/runtime/inject" atypes "sigs.k8s.io/controller-runtime/pkg/webhook/admission/types" "sigs.k8s.io/controller-runtime/pkg/webhook/types" @@ -210,24 +209,12 @@ func (w *Webhook) Validate() error { return nil } -var _ inject.Client = &Webhook{} +var _ inject.Injector = &Webhook{} -// InjectClient injects the client into the handlers -func (w *Webhook) InjectClient(c client.Client) error { +// InjectFunc injects dependencies into the handlers. +func (w *Webhook) InjectFunc(f inject.Func) error { for _, handler := range w.Handlers { - if _, err := inject.ClientInto(c, handler); err != nil { - return err - } - } - return nil -} - -var _ inject.Decoder = &Webhook{} - -// InjectDecoder injects the decoder into the handlers -func (w *Webhook) InjectDecoder(d atypes.Decoder) error { - for _, handler := range w.Handlers { - if _, err := inject.DecoderInto(d, handler); err != nil { + if err := f(handler); err != nil { return err } } diff --git a/pkg/webhook/server.go b/pkg/webhook/server.go index b6f1cea94f..3b9f3b14e3 100644 --- a/pkg/webhook/server.go +++ b/pkg/webhook/server.go @@ -19,18 +19,14 @@ package webhook import ( "context" "crypto/tls" - "fmt" "net" "net/http" "path" "strconv" "sync" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/runtime/inject" - atypes "sigs.k8s.io/controller-runtime/pkg/webhook/admission/types" ) const ( @@ -50,28 +46,20 @@ type ServerOptions struct { // If using SecretCertWriter in Provisioner, the server will provision the certificate in a secret, // the user is responsible to mount the secret to the this location for the server to consume. CertDir string - - // Client is a client defined in controller-runtime instead of a client-go client. - // It knows how to talk to a kubernetes cluster. - // Client will be injected by the manager if not set. - Client client.Client - - // err will be non-nil if there is an error occur during initialization. - err error // nolint: structcheck } // Server is an admission webhook server that can serve traffic and // generates related k8s resources for deploying. type Server struct { - // Name is the name of server - Name string - // ServerOptions contains options for configuring the admission server. ServerOptions sMux *http.ServeMux // registry maps a path to a http.Handler. - registry map[string]Webhook + registry map[string]http.Handler + + // setFields is used to inject dependencies into webhooks + setFields func(i interface{}) error // manager is the manager that this webhook server will be registered. manager manager.Manager @@ -81,6 +69,8 @@ type Server struct { // Webhook defines the basics that a webhook should support. type Webhook interface { + http.Handler + // GetPath returns the path that the webhook registered. GetPath() string // Handler returns a http.Handler for the webhook. @@ -91,11 +81,10 @@ type Webhook interface { } // NewServer creates a new admission webhook server. -func NewServer(name string, mgr manager.Manager, options ServerOptions) (*Server, error) { +func NewServer(mgr manager.Manager, options ServerOptions) (*Server, error) { as := &Server{ - Name: name, sMux: http.NewServeMux(), - registry: map[string]Webhook{}, + registry: map[string]http.Handler{}, ServerOptions: options, manager: mgr, } @@ -105,14 +94,11 @@ func NewServer(name string, mgr manager.Manager, options ServerOptions) (*Server // setDefault does defaulting for the Server. func (s *Server) setDefault() { - if len(s.Name) == 0 { - s.Name = "default-k8s-webhook-server" - } if s.registry == nil { - s.registry = map[string]Webhook{} + s.registry = map[string]http.Handler{} } if s.sMux == nil { - s.sMux = http.DefaultServeMux + s.sMux = http.NewServeMux() } if s.Port <= 0 { s.Port = 443 @@ -120,19 +106,6 @@ func (s *Server) setDefault() { if len(s.CertDir) == 0 { s.CertDir = path.Join("k8s-webhook-server", "cert") } - - if s.Client == nil { - cfg, err := config.GetConfig() - if err != nil { - s.err = err - return - } - s.Client, err = client.New(cfg, client.Options{}) - if err != nil { - s.err = err - return - } - } } // Register validates and registers webhook(s) in the server @@ -143,12 +116,14 @@ func (s *Server) Register(webhooks ...Webhook) error { if err != nil { return err } - _, found := s.registry[webhook.GetPath()] - if found { - return fmt.Errorf("can't register duplicate path: %v", webhook.GetPath()) - } - s.registry[webhook.GetPath()] = webhooks[i] + // Handle actually ensures that no duplicate paths are registered. s.sMux.Handle(webhook.GetPath(), webhook.Handler()) + s.registry[webhook.GetPath()] = webhooks[i] + + // Inject dependencies to each webhook. + if err := s.setFields(webhooks[i]); err != nil { + return err + } } // Lazily add Server to manager. @@ -167,9 +142,6 @@ var _ manager.Runnable = &Server{} // It will install the webhook related resources depend on the server configuration. func (s *Server) Start(stop <-chan struct{}) error { s.once.Do(s.setDefault) - if s.err != nil { - return s.err - } // TODO: watch the cert dir. Reload the cert if it changes cert, err := tls.LoadX509KeyPair(path.Join(s.CertDir, certName), path.Join(s.CertDir, keyName)) @@ -211,27 +183,10 @@ func (s *Server) Start(stop <-chan struct{}) error { return nil } -var _ inject.Client = &Server{} - -// InjectClient injects the client into the server -func (s *Server) InjectClient(c client.Client) error { - s.Client = c - for _, wh := range s.registry { - if _, err := inject.ClientInto(c, wh.Handler()); err != nil { - return err - } - } - return nil -} - -var _ inject.Decoder = &Server{} +var _ inject.Injector = &Server{} -// InjectDecoder injects the decoder into the server -func (s *Server) InjectDecoder(d atypes.Decoder) error { - for _, wh := range s.registry { - if _, err := inject.DecoderInto(d, wh.Handler()); err != nil { - return err - } - } +// InjectFunc injects dependencies into the handlers. +func (s *Server) InjectFunc(f inject.Func) error { + s.setFields = f return nil }