From fe53db0dbdc25c9b2f87adbd53f1ebe4b6c1169d Mon Sep 17 00:00:00 2001 From: Rita Zhang Date: Wed, 8 Nov 2023 15:38:11 -0800 Subject: [PATCH] authz: add benchmark for webhook authorizer Signed-off-by: Rita Zhang --- .../pkg/authorizer/webhook/webhook_v1_test.go | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go index 4cdfd1643dc..2baf2457ff0 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go @@ -782,6 +782,111 @@ func TestStructuredAuthzConfigFeatureEnablement(t *testing.T) { } } +func BenchmarkNoCELExpressionFeatureOff(b *testing.B) { + benchmarkWebhookAuthorizer(b, []apiserver.WebhookMatchCondition{}, false) +} + +func BenchmarkNoCELExpressionFeatureOn(b *testing.B) { + benchmarkWebhookAuthorizer(b, []apiserver.WebhookMatchCondition{}, true) +} +func BenchmarkWithOneCELExpressions(b *testing.B) { + expressions := []apiserver.WebhookMatchCondition{ + { + Expression: "request.user == 'alice'", + }, + } + benchmarkWebhookAuthorizer(b, expressions, true) +} +func BenchmarkWithTwoCELExpressions(b *testing.B) { + expressions := []apiserver.WebhookMatchCondition{ + { + Expression: "request.user == 'alice'", + }, + { + Expression: "request.uid == '1'", + }, + } + benchmarkWebhookAuthorizer(b, expressions, true) +} +func BenchmarkWithTwoComplexCELExpressions(b *testing.B) { + expressions := []apiserver.WebhookMatchCondition{ + { + Expression: "request.user == 'alice'", + }, + { + Expression: "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kittensandponies'", + }, + } + benchmarkWebhookAuthorizer(b, expressions, true) +} +func BenchmarkWithManyCELExpressions(b *testing.B) { + expressions := []apiserver.WebhookMatchCondition{ + { + Expression: "request.user == 'alice'", + }, + { + Expression: "request.uid == '1'", + }, + { + Expression: "('group1' in request.groups)", + }, + { + Expression: "('key1' in request.extra)", + }, + { + Expression: "!('key2' in request.extra)", + }, + { + Expression: "('a' in request.extra['key1'])", + }, + { + Expression: "!('z' in request.extra['key1'])", + }, + { + Expression: "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kittensandponies'", + }, + } + benchmarkWebhookAuthorizer(b, expressions, true) +} + +func benchmarkWebhookAuthorizer(b *testing.B, expressions []apiserver.WebhookMatchCondition, featureEnabled bool) { + attr := authorizer.AttributesRecord{ + User: &user.DefaultInfo{ + Name: "alice", + UID: "1", + Groups: []string{"group1", "group2"}, + Extra: map[string][]string{"key1": {"a", "b", "c"}}, + }, + ResourceRequest: true, + Namespace: "kittensandponies", + Verb: "get", + } + service := new(mockV1Service) + service.statusCode = 200 + service.Allow() + s, err := NewV1TestServer(service, serverCert, serverKey, caCert) + if err != nil { + b.Fatal(err) + } + defer s.Close() + defer featuregatetesting.SetFeatureGateDuringTest(b, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, featureEnabled)() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + // Create an authorizer with or without expressions to compile + wh, err := newV1Authorizer(s.URL, clientCert, clientKey, caCert, 0, noopAuthorizerMetrics(), expressions) + if err != nil { + b.Fatal(err) + } + // Call authorize may or may not require cel evaluations + _, _, err = wh.Authorize(context.Background(), attr) + if err != nil { + b.Fatal(err) + } + } + b.StopTimer() +} + // TestV1WebhookMatchConditions verifies cel expressions are compiled and evaluated correctly func TestV1WebhookMatchConditions(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthorizationConfiguration, true)()