From 89b211d1f951664cefd148daf2341f5634019fde Mon Sep 17 00:00:00 2001 From: belyshevdenis <belyshev.denis@apriorit.com> Date: Tue, 19 Mar 2019 21:32:31 +0200 Subject: [PATCH] NK-31: Implemented webhook registration logic. --- definitions/examples/selector-policy.yaml | 21 +++++ init.go | 7 +- main.go | 8 +- webhooks/registration.go | 98 +++++++++++++++++++++++ 4 files changed, 127 insertions(+), 7 deletions(-) create mode 100644 definitions/examples/selector-policy.yaml create mode 100644 webhooks/registration.go diff --git a/definitions/examples/selector-policy.yaml b/definitions/examples/selector-policy.yaml new file mode 100644 index 0000000000..d15312b76d --- /dev/null +++ b/definitions/examples/selector-policy.yaml @@ -0,0 +1,21 @@ +apiVersion: policy.nirmata.io/v1alpha1 +kind : Policy +metadata: + name: selector-policy +spec: + failurePolicy: continueOnError + rules: + - resource: + kind: ConfigMap + selector: + matchLabels: + label1: test1 + matchExpressions: + - key: label2 + operator: In + values: + - test2 + patch: + - path: / + op : add + value : "20" diff --git a/init.go b/init.go index cd729e91dc..8940b39c8c 100644 --- a/init.go +++ b/init.go @@ -72,9 +72,4 @@ func initTlsPemsPair(config *rest.Config, client *kubeclient.KubeClient) (*utils } return tlsPair, nil -} - -func registerWebhook(client *kubeclient.KubeClient) error { - // TODO - return nil -} +} \ No newline at end of file diff --git a/main.go b/main.go index 1cf206a68d..d3dea750e1 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ 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" signals "k8s.io/sample-controller/pkg/signals" @@ -23,9 +24,14 @@ 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! Error: %s\n", err) + log.Fatalf("Error creating PolicyController: %s\n", err) } kubeclient, err := kubeclient.NewKubeClient(clientConfig, nil) diff --git a/webhooks/registration.go b/webhooks/registration.go new file mode 100644 index 0000000000..db8912bf45 --- /dev/null +++ b/webhooks/registration.go @@ -0,0 +1,98 @@ +package webhooks +import ( + "io/ioutil" + "encoding/base64" + + rest "k8s.io/client-go/rest" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + adm "k8s.io/api/admissionregistration/v1beta1" + types "k8s.io/api/admissionregistration/v1beta1" + admreg "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1" +) + +const ( + webhookName = "nirmata-kube-policy-webhook-cfg" + mutationWebhookName = "webhook.nirmata.kube-policy" + webhookServiceNamespace = "default" + webhookServiceName = "kube-policy-svc" +) + +var ( + webhookPath = "mutate" + webhookLabels = map[string]string { + "app": "kube-policy", + } +) + +func RegisterMutationWebhook(config *rest.Config) (*types.MutatingWebhookConfiguration, error) { +var result *types.MutatingWebhookConfiguration = nil + + registrationClient, err := admreg.NewForConfig(config) + if err != nil { + return nil, err + } + + result, err = registrationClient.MutatingWebhookConfigurations().Create(constructWebhookConfig(config)) + if err != nil { + return nil, err + } + + return result, nil +} + +func constructWebhookConfig(config *rest.Config) *adm.MutatingWebhookConfiguration { + return &adm.MutatingWebhookConfiguration { + ObjectMeta: meta.ObjectMeta { + Name: webhookName, + Labels: webhookLabels, + }, + Webhooks: []adm.Webhook { + adm.Webhook { + Name: mutationWebhookName, + ClientConfig: adm.WebhookClientConfig { + Service: &adm.ServiceReference { + Namespace: webhookServiceNamespace, + Name: webhookServiceName, + Path: &webhookPath, + }, + CABundle: extractCA(config), + }, + Rules: []adm.RuleWithOperations { + adm.RuleWithOperations { + Operations: []adm.OperationType { + adm.Create, + }, + Rule: adm.Rule { + APIGroups: []string { + "*", + }, + APIVersions: []string { + "*", + }, + Resources: []string { + "*/*", + }, + }, + }, + }, + }, + }, + } +} + +func extractCA(config *rest.Config) (result []byte) { + + if config.TLSClientConfig.CAData != nil { + return config.TLSClientConfig.CAData + } else { + fileName := config.TLSClientConfig.CAFile + bytes, err := ioutil.ReadFile(fileName) + + if err != nil { + return nil + } + + base64.StdEncoding.Encode(result, bytes) + return + } +} \ No newline at end of file