From 4912f2088572cfcf265cca1040cc8e6684dde56e Mon Sep 17 00:00:00 2001 From: belyshevdenis Date: Fri, 22 Mar 2019 22:11:55 +0200 Subject: [PATCH] NK-47: Implemented webhook deregistration. TLS pair initialization functionality moved to init.go. Separated server and mutation webhook objects, implemented registration of webhook with the creation of corresponding object. Added comments for webhook configuration definitions, changed name of configuration for debug. --- definitions/MutatingWebhookConfiguration.yaml | 1 + .../MutatingWebhookConfiguration_debug.yaml | 3 +- init.go | 29 ++++++++++++--- main.go | 35 ++++++++----------- server/server.go | 32 +++++------------ 5 files changed, 51 insertions(+), 49 deletions(-) diff --git a/definitions/MutatingWebhookConfiguration.yaml b/definitions/MutatingWebhookConfiguration.yaml index e421733fdd..420ee023d5 100644 --- a/definitions/MutatingWebhookConfiguration.yaml +++ b/definitions/MutatingWebhookConfiguration.yaml @@ -1,4 +1,5 @@ # MutatingWebhookConfiguration document which should be used when placing controller inside the cluster +# This configuration is just an example. Webhook for in-cluster configuration is registered by controller (see webhooks/registration.go). apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: diff --git a/definitions/MutatingWebhookConfiguration_debug.yaml b/definitions/MutatingWebhookConfiguration_debug.yaml index cc235922c1..713fb9cb40 100644 --- a/definitions/MutatingWebhookConfiguration_debug.yaml +++ b/definitions/MutatingWebhookConfiguration_debug.yaml @@ -1,8 +1,9 @@ # Example of MutatingWebhookConfiguration which can be used for debug, when controller is placed on master node +# To register webhook for debug, replace ${CA_BUNDLE} with corresponding data from ~/.kube/config and create this resource apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: - name: nirmata-kube-policy-webhook-cfg + name: nirmata-kube-policy-webhook-cfg-debug labels: app: kube-policy webhooks: diff --git a/init.go b/init.go index ca32bbd693..609b64af7b 100644 --- a/init.go +++ b/init.go @@ -23,7 +23,27 @@ func createClientConfig(kubeconfig string) (*rest.Config, error) { } } -func readTlsPairFromFiles(certFile, keyFile string) *utils.TlsPemPair { +func initTlsPemPair(certFile, keyFile string, clientConfig *rest.Config, kubeclient *kubeclient.KubeClient) (*utils.TlsPemPair, error) { + var tlsPair *utils.TlsPemPair + if certFile != "" || keyFile != "" { + tlsPair = tlsPairFromFiles(certFile, keyFile) + } + + var err error + if tlsPair != nil { + log.Print("Using given TLS key/certificate pair") + return tlsPair, nil + } else { + tlsPair, err = tlsPairFromCluster(clientConfig, kubeclient) + if err == nil { + log.Printf("Using TLS key/certificate from cluster") + } + return tlsPair, err + } +} + +// Loads PEM private key and TLS certificate from given files +func tlsPairFromFiles(certFile, keyFile string) *utils.TlsPemPair { if certFile == "" || keyFile == "" { return nil } @@ -46,9 +66,10 @@ func readTlsPairFromFiles(certFile, keyFile string) *utils.TlsPemPair { } } -// Loads or creates PEM private key and TLS certificate for webhook server -// Returns struct with key/certificate pair -func initTlsPemsPair(configuration *rest.Config, client *kubeclient.KubeClient) (*utils.TlsPemPair, error) { +// Loads or creates PEM private key and TLS certificate for webhook server. +// Created pair is stored in cluster's secret. +// Returns struct with key/certificate pair. +func tlsPairFromCluster(configuration *rest.Config, client *kubeclient.KubeClient) (*utils.TlsPemPair, error) { apiServerUrl, err := url.Parse(configuration.Host) if err != nil { return nil, err diff --git a/main.go b/main.go index 0e93ed2192..3b518e41cc 100644 --- a/main.go +++ b/main.go @@ -6,8 +6,8 @@ import ( "github.com/nirmata/kube-policy/controller" "github.com/nirmata/kube-policy/kubeclient" - "github.com/nirmata/kube-policy/webhooks" "github.com/nirmata/kube-policy/server" + "github.com/nirmata/kube-policy/webhooks" signals "k8s.io/sample-controller/pkg/signals" ) @@ -24,11 +24,6 @@ func main() { log.Fatalf("Error building kubeconfig: %v\n", err) } - err = webhooks.RegisterMutationWebhook(clientConfig) - if err != nil { - log.Fatalf("Error registering mutation webhook server: %v\n", err) - } - controller, err := controller.NewPolicyController(clientConfig, nil) if err != nil { log.Fatalf("Error creating PolicyController: %s\n", err) @@ -39,22 +34,17 @@ func main() { log.Fatalf("Error creating kubeclient: %v\n", err) } - tlsPair := readTlsPairFromFiles(cert, key) - if tlsPair != nil { - log.Print("Using given TLS key/certificate pair") - } else { - tlsPair, err = initTlsPemsPair(clientConfig, kubeclient) - if err != nil { - log.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err) - } + mutationWebhook, err := webhooks.CreateMutationWebhook(clientConfig, kubeclient, controller, nil) + if err != nil { + log.Fatalf("Error creating mutation webhook: %v\n", err) } - serverConfig := server.WebhookServerConfig{ - TlsPemPair: tlsPair, - Controller: controller, - Kubeclient: kubeclient, + tlsPair, err := initTlsPemPair(cert, key, clientConfig, kubeclient) + if err != nil { + log.Fatalf("Failed to initialize TLS key/certificate pair: %v\n", err) } - server, err := server.NewWebhookServer(serverConfig, nil) + + server, err := server.NewWebhookServer(tlsPair, mutationWebhook, nil) if err != nil { log.Fatalf("Unable to create webhook server: %v\n", err) } @@ -66,10 +56,15 @@ func main() { if err != nil { log.Fatalf("Error running PolicyController: %s\n", err) } - log.Println("Policy Controller has started") + <-stopCh server.Stop() + err = mutationWebhook.Deregister() + if err != nil { + log.Printf("Unable to deregister mutation webhook: %v", err) + } + log.Println("Policy Controller has stopped") } diff --git a/server/server.go b/server/server.go index ae02586664..f714f535ac 100644 --- a/server/server.go +++ b/server/server.go @@ -13,8 +13,6 @@ import ( "time" "github.com/nirmata/kube-policy/config" - "github.com/nirmata/kube-policy/controller" - "github.com/nirmata/kube-policy/kubeclient" "github.com/nirmata/kube-policy/utils" "github.com/nirmata/kube-policy/webhooks" @@ -24,46 +22,32 @@ import ( // WebhookServer contains configured TLS server with MutationWebhook. // MutationWebhook gets policies from policyController and takes control of the cluster with kubeclient. type WebhookServer struct { - server http.Server - policyController *controller.PolicyController - mutationWebhook *webhooks.MutationWebhook - logger *log.Logger -} - -// Configuration struct for WebhookServer used in NewWebhookServer -// Controller and Kubeclient should be initialized and valid -type WebhookServerConfig struct { - TlsPemPair *utils.TlsPemPair - Controller *controller.PolicyController - Kubeclient *kubeclient.KubeClient + server http.Server + mutationWebhook *webhooks.MutationWebhook + logger *log.Logger } // NewWebhookServer creates new instance of WebhookServer accordingly to given configuration // Policy Controller and Kubernetes Client should be initialized in configuration -func NewWebhookServer(configuration WebhookServerConfig, logger *log.Logger) (*WebhookServer, error) { +func NewWebhookServer(tlsPair *utils.TlsPemPair, mutationWebhook *webhooks.MutationWebhook, logger *log.Logger) (*WebhookServer, error) { if logger == nil { logger = log.New(os.Stdout, "HTTPS Server: ", log.LstdFlags|log.Lshortfile) } - if configuration.TlsPemPair == nil || configuration.Controller == nil || configuration.Kubeclient == nil { - return nil, errors.New("WebhookServerConfig is not initialized properly") + if tlsPair == nil || mutationWebhook == nil { + return nil, errors.New("NewWebhookServer is not initialized properly") } var tlsConfig tls.Config - pair, err := tls.X509KeyPair(configuration.TlsPemPair.Certificate, configuration.TlsPemPair.PrivateKey) + pair, err := tls.X509KeyPair(tlsPair.Certificate, tlsPair.PrivateKey) if err != nil { return nil, err } tlsConfig.Certificates = []tls.Certificate{pair} - mw, err := webhooks.NewMutationWebhook(configuration.Kubeclient, configuration.Controller, logger) - if err != nil { - return nil, err - } - ws := &WebhookServer{ logger: logger, - mutationWebhook: mw, + mutationWebhook: mutationWebhook, } mux := http.NewServeMux()