Files
Oliver BählerandGitHub 2252c530f4 feat(performance): removed duplicate client calls from all admission paths (#2054)
* chore

* perfromance improvements

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* perfromance improvements

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat(performance): removed duplicate client calls from all admission paths

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat(performance): removed duplicate client calls from all admission paths

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat(performance): removed duplicate client calls from all admission paths

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat(performance): removed duplicate client calls from all admission paths

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat(performance): removed duplicate client calls from all admission paths

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat(performance): removed duplicate client calls from all admission paths

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat(performance): removed duplicate client calls from all admission paths

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

---------

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
2026-07-28 14:32:42 +02:00

367 lines
13 KiB
Go

// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0
package configuration_test
import (
"context"
"errors"
"reflect"
"testing"
"time"
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
capsuleapi "github.com/projectcapsule/capsule/pkg/api"
capsulemeta "github.com/projectcapsule/capsule/pkg/api/meta"
"github.com/projectcapsule/capsule/pkg/api/rbac"
"github.com/projectcapsule/capsule/pkg/runtime/configuration"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)
type failingConfigurationReader struct {
client.Reader
gets int
}
type timeoutConfigurationClient struct {
client.Client
}
func (c *timeoutConfigurationClient) Get(
context.Context,
client.ObjectKey,
client.Object,
...client.GetOption,
) error {
return context.DeadlineExceeded
}
func (r *failingConfigurationReader) Get(
context.Context,
client.ObjectKey,
client.Object,
...client.GetOption,
) error {
r.gets++
return errors.New("direct reader should not be used")
}
func TestDefaultCapsuleConfiguration(t *testing.T) {
t.Parallel()
got := configuration.DefaultCapsuleConfiguration()
if !reflect.DeepEqual(got.Users, rbac.UserListSpec{{Kind: rbac.GroupOwner, Name: "projectcapsule.dev"}}) {
t.Fatalf("DefaultCapsuleConfiguration().Users = %#v", got.Users)
}
if got.CacheInvalidation.Duration != time.Hour {
t.Fatalf("CacheInvalidation = %s, want 1h", got.CacheInvalidation.Duration)
}
if got.RBAC == nil || got.RBAC.DeleterClusterRole != "capsule-namespace-deleter" {
t.Fatalf("RBAC defaults = %#v, want namespace deleter defaults", got.RBAC)
}
}
func TestEnvironmentHelpers(t *testing.T) {
t.Setenv(configuration.EnvironmentServiceaccountName, "capsule-controller")
t.Setenv(configuration.EnvironmentControllerNamespace, "capsule-system")
if got := configuration.ControllerNamespace(); got != "capsule-system" {
t.Fatalf("ControllerNamespace() = %q, want capsule-system", got)
}
name, namespace := configuration.ControllerServiceAccount()
if name != "capsule-controller" || namespace != "capsule-system" {
t.Fatalf("ControllerServiceAccount() = %q/%q, want capsule-controller/capsule-system", namespace, name)
}
if !configuration.IsControllerServiceAccount("capsule-controller", "capsule-system") {
t.Fatalf("IsControllerServiceAccount() = false, want true")
}
if configuration.IsControllerServiceAccount("other", "capsule-system") {
t.Fatalf("IsControllerServiceAccount() = true, want false")
}
}
func TestNewCapsuleConfigurationCreatesDefaultWhenMissing(t *testing.T) {
t.Parallel()
ctx := context.Background()
cl := configurationFakeClient(t)
cfg := configuration.NewCapsuleConfiguration(ctx, cl, cl, &rest.Config{Host: "https://kubernetes.default"}, "capsule")
got := cfg.GetConfigObject()
if got.Name != "capsule" {
t.Fatalf("GetConfigObject().Name = %q, want capsule", got.Name)
}
if !reflect.DeepEqual(got.Spec.Users, configuration.DefaultCapsuleConfiguration().Users) {
t.Fatalf("default config users = %#v, want %#v", got.Spec.Users, configuration.DefaultCapsuleConfiguration().Users)
}
var stored capsulev1beta2.CapsuleConfiguration
if err := cl.Get(ctx, client.ObjectKey{Name: "capsule"}, &stored); err != nil {
t.Fatalf("created configuration was not stored: %v", err)
}
}
func TestNewCapsuleConfigurationCreatesDefaultAfterInformerTimeout(t *testing.T) {
t.Parallel()
ctx := context.Background()
storage := configurationFakeClient(t)
cachedClient := &timeoutConfigurationClient{Client: storage}
directReader := configurationFakeClient(t)
cfg := configuration.NewCapsuleConfiguration(
ctx,
cachedClient,
directReader,
&rest.Config{Host: "https://kubernetes.default"},
"capsule",
)
got := cfg.GetConfigObject()
if got.Name != "capsule" {
t.Fatalf("GetConfigObject().Name = %q, want capsule", got.Name)
}
if !reflect.DeepEqual(got.Spec, configuration.DefaultCapsuleConfiguration()) {
t.Fatalf("default configuration = %#v, want %#v", got.Spec, configuration.DefaultCapsuleConfiguration())
}
stored := &capsulev1beta2.CapsuleConfiguration{}
if err := storage.Get(ctx, client.ObjectKey{Name: "capsule"}, stored); err != nil {
t.Fatalf("created configuration was not stored: %v", err)
}
}
func TestCapsuleConfigurationUsesInformerClientBeforeDirectReader(t *testing.T) {
t.Parallel()
ctx := context.Background()
stored := &capsulev1beta2.CapsuleConfiguration{
ObjectMeta: metav1.ObjectMeta{Name: "capsule"},
Spec: capsulev1beta2.CapsuleConfigurationSpec{
ForceTenantPrefix: true,
},
}
cl := configurationFakeClient(t, stored)
reader := &failingConfigurationReader{Reader: cl}
cfg := configuration.NewCapsuleConfiguration(ctx, cl, reader, &rest.Config{}, "capsule")
if !cfg.ForceTenantPrefix() {
t.Fatal("ForceTenantPrefix() = false, want cached configuration value")
}
if reader.gets != 0 {
t.Fatalf("direct reader Get calls = %d, want 0", reader.gets)
}
}
func TestCapsuleConfigurationGetters(t *testing.T) {
t.Parallel()
ctx := context.Background()
stored := &capsulev1beta2.CapsuleConfiguration{
ObjectMeta: metav1.ObjectMeta{Name: "capsule"},
Spec: capsulev1beta2.CapsuleConfigurationSpec{
ProtectedNamespaceRegexpString: "^(kube|openshift)-",
ForceTenantPrefix: true,
EnableTLSReconciler: true,
AllowServiceAccountPromotion: true,
CapsuleResources: capsulev1beta2.CapsuleResources{
TLSSecretName: "capsule-tls",
},
Users: rbac.UserListSpec{
{Kind: rbac.UserOwner, Name: "alice"},
{Kind: rbac.GroupOwner, Name: "developers"},
{Kind: rbac.ServiceAccountOwner, Name: "system:serviceaccount:tenant-a:builder"},
},
UserNames: []string{"legacy-user"},
UserGroups: []string{"legacy-group"},
IgnoreUserWithGroups: []string{"ignored"},
Administrators: rbac.UserListSpec{{Kind: rbac.UserOwner, Name: "admin"}},
NodeMetadata: &capsulev1beta2.NodeMetadata{
ForbiddenLabels: capsuleapi.ForbiddenListSpec{Exact: []string{"node-role.kubernetes.io/control-plane"}},
ForbiddenAnnotations: capsuleapi.ForbiddenListSpec{Regex: "internal/.*"},
},
RBAC: &capsulev1beta2.RBACConfiguration{DeleterClusterRole: "delete-role"},
CacheInvalidation: metav1.Duration{
Duration: 2 * time.Hour,
},
Impersonation: capsulev1beta2.ServiceAccountClient{
Endpoint: "https://impersonation.example",
SkipTLSVerify: true,
},
Events: capsulev1beta2.EventsConfiguration{ClusterEventNamespace: "audit"},
},
Status: capsulev1beta2.CapsuleConfigurationStatus{
Users: rbac.UserListSpec{{Kind: rbac.GroupOwner, Name: "status-group"}},
},
}
cl := configurationFakeClient(t, stored)
cfg := configuration.NewCapsuleConfiguration(ctx, cl, cl, &rest.Config{
Host: "https://kubernetes.default",
TLSClientConfig: rest.TLSClientConfig{
CAData: []byte("ca"),
CAFile: "ca-file",
},
}, "capsule")
regex, err := cfg.ProtectedNamespaceRegexp()
if err != nil {
t.Fatalf("ProtectedNamespaceRegexp() unexpected error: %v", err)
}
if !regex.MatchString("kube-system") {
t.Fatalf("ProtectedNamespaceRegexp() did not match kube-system")
}
if !cfg.ForceTenantPrefix() || !cfg.EnableTLSConfiguration() || !cfg.AllowServiceAccountPromotion() {
t.Fatalf("boolean getters did not return configured true values")
}
if cfg.TLSSecretName() != "capsule-tls" {
t.Fatalf("TLSSecretName() = %q, want capsule-tls", cfg.TLSSecretName())
}
if cfg.TenantCRDName() != configuration.TenantCRDName {
t.Fatalf("TenantCRDName() = %q, want %q", cfg.TenantCRDName(), configuration.TenantCRDName)
}
if !reflect.DeepEqual(cfg.IgnoreUserWithGroups(), []string{"ignored"}) {
t.Fatalf("IgnoreUserWithGroups() = %#v", cfg.IgnoreUserWithGroups())
}
if !reflect.DeepEqual(cfg.GetUsersByStatus(), rbac.UserListSpec{{Kind: rbac.GroupOwner, Name: "status-group"}}) {
t.Fatalf("GetUsersByStatus() = %#v", cfg.GetUsersByStatus())
}
if cfg.ForbiddenUserNodeLabels() == nil || cfg.ForbiddenUserNodeLabels().Exact[0] != "node-role.kubernetes.io/control-plane" {
t.Fatalf("ForbiddenUserNodeLabels() = %#v", cfg.ForbiddenUserNodeLabels())
}
if cfg.ForbiddenUserNodeAnnotations() == nil || cfg.ForbiddenUserNodeAnnotations().Regex != "internal/.*" {
t.Fatalf("ForbiddenUserNodeAnnotations() = %#v", cfg.ForbiddenUserNodeAnnotations())
}
if cfg.Administrators()[0].Name != "admin" {
t.Fatalf("Administrators() = %#v", cfg.Administrators())
}
if cfg.Events().ClusterEventNamespace != "audit" {
t.Fatalf("Events() = %#v", cfg.Events())
}
if cfg.RBAC().DeleterClusterRole != "delete-role" {
t.Fatalf("RBAC() = %#v", cfg.RBAC())
}
if cfg.CacheInvalidation().Duration != 2*time.Hour {
t.Fatalf("CacheInvalidation() = %s", cfg.CacheInvalidation().Duration)
}
wantUsers := rbac.UserListSpec{
{Kind: rbac.GroupOwner, Name: "developers"},
{Kind: rbac.GroupOwner, Name: "legacy-group"},
{Kind: rbac.ServiceAccountOwner, Name: "system:serviceaccount:tenant-a:builder"},
{Kind: rbac.UserOwner, Name: "alice"},
{Kind: rbac.UserOwner, Name: "legacy-user"},
}
if got := cfg.Users(); !reflect.DeepEqual(got, wantUsers) {
t.Fatalf("Users() = %#v, want %#v", got, wantUsers)
}
saClient, err := cfg.ServiceAccountClient(ctx)
if err != nil {
t.Fatalf("ServiceAccountClient() unexpected error: %v", err)
}
if saClient.Host != "https://impersonation.example" ||
!saClient.Insecure ||
len(saClient.TLSClientConfig.CAData) != 0 ||
saClient.TLSClientConfig.CAFile != "" {
t.Fatalf("ServiceAccountClient() = %#v, want endpoint with insecure TLS", saClient)
}
}
func TestProtectedNamespaceRegexpErrors(t *testing.T) {
t.Parallel()
ctx := context.Background()
cl := configurationFakeClient(t, &capsulev1beta2.CapsuleConfiguration{
ObjectMeta: metav1.ObjectMeta{Name: "capsule"},
Spec: capsulev1beta2.CapsuleConfigurationSpec{
ProtectedNamespaceRegexpString: "[",
},
})
cfg := configuration.NewCapsuleConfiguration(ctx, cl, cl, &rest.Config{}, "capsule")
if _, err := cfg.ProtectedNamespaceRegexp(); err == nil {
t.Fatalf("ProtectedNamespaceRegexp() expected error")
}
}
func TestServiceAccountClientLoadsCASecret(t *testing.T) {
t.Parallel()
ctx := context.Background()
cl := configurationFakeClient(t,
&capsulev1beta2.CapsuleConfiguration{
ObjectMeta: metav1.ObjectMeta{Name: "capsule"},
Spec: capsulev1beta2.CapsuleConfigurationSpec{
Impersonation: capsulev1beta2.ServiceAccountClient{
Endpoint: "https://impersonation.example",
CASecretNamespace: capsulemeta.RFC1123SubdomainName("capsule-system"),
CASecretName: capsulemeta.RFC1123Name("ca"),
CASecretKey: "ca.crt",
},
},
},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: "capsule-system", Name: "ca"}, Data: map[string][]byte{"ca.crt": []byte("secret-ca")}},
)
cfg := configuration.NewCapsuleConfiguration(ctx, cl, cl, &rest.Config{
Host: "https://kubernetes.default",
TLSClientConfig: rest.TLSClientConfig{CAFile: "old"},
}, "capsule")
got, err := cfg.ServiceAccountClient(ctx)
if err != nil {
t.Fatalf("ServiceAccountClient() unexpected error: %v", err)
}
if got.Host != "https://impersonation.example" || string(got.TLSClientConfig.CAData) != "secret-ca" || got.TLSClientConfig.CAFile != "" {
t.Fatalf("ServiceAccountClient() = %#v, want CA data from secret", got)
}
}
func TestServiceAccountClientMissingCASecretKey(t *testing.T) {
t.Parallel()
ctx := context.Background()
cl := configurationFakeClient(t,
&capsulev1beta2.CapsuleConfiguration{
ObjectMeta: metav1.ObjectMeta{Name: "capsule"},
Spec: capsulev1beta2.CapsuleConfigurationSpec{
Impersonation: capsulev1beta2.ServiceAccountClient{
CASecretNamespace: capsulemeta.RFC1123SubdomainName("capsule-system"),
CASecretName: capsulemeta.RFC1123Name("ca"),
CASecretKey: "missing",
},
},
},
&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: "capsule-system", Name: "ca"}, Data: map[string][]byte{"ca.crt": []byte("secret-ca")}},
)
cfg := configuration.NewCapsuleConfiguration(ctx, cl, cl, &rest.Config{}, "capsule")
if _, err := cfg.ServiceAccountClient(ctx); err == nil {
t.Fatalf("ServiceAccountClient() expected error for missing CA key")
}
}
func configurationFakeClient(t *testing.T, objects ...client.Object) client.Client {
t.Helper()
scheme := runtime.NewScheme()
if err := corev1.AddToScheme(scheme); err != nil {
t.Fatalf("adding core scheme: %v", err)
}
if err := capsulev1beta2.AddToScheme(scheme); err != nil {
t.Fatalf("adding capsule scheme: %v", err)
}
return fake.NewClientBuilder().WithScheme(scheme).WithObjects(objects...).Build()
}