kata-containers/tools/testing/kata-webhook/main.go
Lukáš Doktor 4c58478536
ci/openshift-ci: Move openshift-ci from the tests repo
Move the f15be37d9bef58a0128bcba006f8abb3ea13e8da version of scripts
required for openshift-ci from "kata-containers/tests/.ci/openshift-ci"
into "kata-containers/kata-containers/ci/openshift-ci" and required
webhook+libs into "kata-containers/kata-containers/tools/testing" as is
to simplify verification, the different location handling will be added
in following commit.

Signed-off-by: Lukáš Doktor <ldoktor@redhat.com>
2024-01-30 19:05:55 +01:00

155 lines
4.3 KiB
Go

// Copyright (c) 2019 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
package main
import (
"context"
"flag"
"fmt"
"net/http"
"os"
"strings"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/sirupsen/logrus"
kwhhttp "github.com/slok/kubewebhook/v2/pkg/http"
kwhlogrus "github.com/slok/kubewebhook/v2/pkg/log/logrus"
kwhmodel "github.com/slok/kubewebhook/v2/pkg/model"
kwhmutating "github.com/slok/kubewebhook/v2/pkg/webhook/mutating"
)
func getRuntimeClass(runtimeClassKey, defaultRuntimeClass string) string {
if runtimeClass, ok := os.LookupEnv(runtimeClassKey); ok {
return runtimeClass
}
return defaultRuntimeClass
}
func annotatePodMutator(_ context.Context, ar *kwhmodel.AdmissionReview, obj metav1.Object) (*kwhmutating.MutatorResult, error) {
pod, ok := obj.(*corev1.Pod)
if !ok {
// If not a pod just continue the mutation chain (if there is one) and don't do anything
return &kwhmutating.MutatorResult{}, nil
}
// The Namespace is not always available in the pod Spec
// specially when operators create the pods. Hence access
// the Namespace in the actual request (vs the object)
// https://godoc.org/k8s.io/api/admission/v1beta1#AdmissionRequest
if whPolicy.nsBlacklist[ar.Namespace] {
fmt.Println("blacklisted namespace: ", ar.Namespace)
return &kwhmutating.MutatorResult{}, nil
}
// We cannot support --net=host in Kata
// https://github.com/kata-containers/documentation/blob/master/Limitations.md#docker---nethost
if pod.Spec.HostNetwork {
fmt.Println("host network: ", pod.GetNamespace(), pod.GetName())
return &kwhmutating.MutatorResult{}, nil
}
if pod.GetNamespace() == "sonobuoy" {
fmt.Println("sonobuoy pods will not be changed to kata", pod.GetNamespace(), pod.GetName())
return &kwhmutating.MutatorResult{}, nil
}
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].SecurityContext != nil && pod.Spec.Containers[i].SecurityContext.Privileged != nil {
if *pod.Spec.Containers[i].SecurityContext.Privileged {
fmt.Println("privileged container: ", pod.GetNamespace(), pod.GetName())
return &kwhmutating.MutatorResult{}, nil
}
}
}
if pod.Spec.RuntimeClassName != nil {
fmt.Println("explicit runtime: ", pod.GetNamespace(), pod.GetName(), pod.Spec.RuntimeClassName)
return &kwhmutating.MutatorResult{}, nil
}
// Mutate the pod
fmt.Println("setting runtime to kata: ", pod.GetNamespace(), pod.GetName())
runtimeClassEnvKey := "RUNTIME_CLASS"
kataRuntimeClassName := getRuntimeClass(runtimeClassEnvKey, "kata")
pod.Spec.RuntimeClassName = &kataRuntimeClassName
return &kwhmutating.MutatorResult{
MutatedObject: pod,
}, nil
}
type config struct {
certFile string
keyFile string
nsBlacklist string
}
type policy struct {
nsBlacklist map[string]bool
}
var whPolicy *policy
func initFlags() *config {
cfg := &config{}
fl := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
fl.StringVar(&cfg.certFile, "tls-cert-file", "", "TLS certificate file")
fl.StringVar(&cfg.keyFile, "tls-key-file", "", "TLS key file")
fl.StringVar(&cfg.nsBlacklist, "exclude-namespaces", "", "Comma separated namespace blacklist")
fl.Parse(os.Args[1:])
return cfg
}
func main() {
logrusLogEntry := logrus.NewEntry(logrus.New())
logrusLogEntry.Logger.SetLevel(logrus.DebugLevel)
logger := kwhlogrus.NewLogrus(logrusLogEntry)
cfg := initFlags()
whPolicy = &policy{}
whPolicy.nsBlacklist = make(map[string]bool)
if cfg.nsBlacklist != "" {
for _, s := range strings.Split(cfg.nsBlacklist, ",") {
whPolicy.nsBlacklist[s] = true
}
}
// Create our mutator
mt := kwhmutating.MutatorFunc(annotatePodMutator)
mcfg := kwhmutating.WebhookConfig{
ID: "podAnnotate",
Obj: &corev1.Pod{},
Mutator: mt,
Logger: logger,
}
wh, err := kwhmutating.NewWebhook(mcfg)
if err != nil {
fmt.Fprintf(os.Stderr, "error creating webhook: %s", err)
os.Exit(1)
}
// Get the handler for our webhook.
whHandler, err := kwhhttp.HandlerFor(kwhhttp.HandlerConfig{Webhook: wh, Logger: logger})
if err != nil {
fmt.Fprintf(os.Stderr, "error creating webhook handler: %s", err)
os.Exit(1)
}
port := ":8080"
logger.Infof("Listening on %s", port)
err = http.ListenAndServeTLS(port, cfg.certFile, cfg.keyFile, whHandler)
if err != nil {
fmt.Fprintf(os.Stderr, "error serving webhook: %s", err)
os.Exit(1)
}
}