This commit is contained in:
Lukáš Doktor 2025-08-12 09:05:45 +02:00 committed by GitHub
commit 2e480bee36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 82 additions and 4 deletions

View File

@ -10,6 +10,7 @@ import (
"fmt"
"net/http"
"os"
"regexp"
"strings"
corev1 "k8s.io/api/core/v1"
@ -44,6 +45,11 @@ func annotatePodMutator(_ context.Context, ar *kwhmodel.AdmissionReview, obj met
fmt.Println("blacklisted namespace: ", ar.Namespace)
return &kwhmutating.MutatorResult{}, nil
}
// Check if we are only mutating pods in specific namespaces using the regular expression.
if whPolicy.nsOnlyRegexp != nil && !whPolicy.nsOnlyRegexp.MatchString(ar.Namespace) {
fmt.Println("namespace doesn't match re-only-namespaces: ", 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
@ -84,13 +90,15 @@ func annotatePodMutator(_ context.Context, ar *kwhmodel.AdmissionReview, obj met
}
type config struct {
certFile string
keyFile string
nsBlacklist string
certFile string
keyFile string
nsBlacklist string
nsOnlyRegexp string
}
type policy struct {
nsBlacklist map[string]bool
nsBlacklist map[string]bool
nsOnlyRegexp *regexp.Regexp
}
var whPolicy *policy
@ -102,6 +110,7 @@ func initFlags() *config {
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.StringVar(&cfg.nsOnlyRegexp, "only-namespaces-regexp", "", "Regexp namespace filter applied after --exclude-namespaces")
fl.Parse(os.Args[1:])
return cfg
@ -122,6 +131,15 @@ func main() {
}
}
if cfg.nsOnlyRegexp != "" {
var err error
whPolicy.nsOnlyRegexp, err = regexp.Compile(cfg.nsOnlyRegexp)
if err != nil {
fmt.Fprintf(os.Stderr, "error compiling regular expression: %s", err)
os.Exit(1)
}
}
// Create our mutator
mt := kwhmutating.MutatorFunc(annotatePodMutator)

View File

@ -0,0 +1,60 @@
// Copyright (c) 2025 Red Hat Inc.
//
// SPDX-License-Identifier: Apache-2.0
package main
import (
"context"
"regexp"
"testing"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kwhmodel "github.com/slok/kubewebhook/v2/pkg/model"
)
func TestAnnotatePodMutator(t *testing.T) {
tests := []struct {
name string
nsBlacklist map[string]bool
nsOnlyRegexp *regexp.Regexp
wantMutated bool
}{
{"no filters", nil, nil, true},
{"matching nsBlacklist", map[string]bool{"testing-namespace": true}, nil, false},
{"matching nsOnlyRegexp", nil, regexp.MustCompile("^testing-.*$"), true},
{"nonmatching nsOnlyRegexp", nil, regexp.MustCompile(".*nonexisting.*"), false},
}
expectedRuntimeClass := "kata"
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
whPolicy = &policy{nsBlacklist: tt.nsBlacklist, nsOnlyRegexp: tt.nsOnlyRegexp}
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: "testing-namespace",
},
}
ar := &kwhmodel.AdmissionReview{
Namespace: "testing-namespace",
}
result, err := annotatePodMutator(context.Background(), ar, pod)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
mutated := result.MutatedObject != nil && result.MutatedObject.(*corev1.Pod).Spec.RuntimeClassName != nil
if mutated != tt.wantMutated {
t.Errorf("expected mutation: %v, got: %v", tt.wantMutated, mutated)
}
if mutated && *result.MutatedObject.(*corev1.Pod).Spec.RuntimeClassName != expectedRuntimeClass {
t.Errorf("expected runtimeclass: %v, got %v", expectedRuntimeClass, result.MutatedObject.(*corev1.Pod).Spec.RuntimeClassName)
}
})
}
}