@@ -782,6 +782,212 @@ func TestStructuredAuthzConfigFeatureEnablement(t *testing.T) {
782
782
}
783
783
}
784
784
785
+ func BenchmarkNoCELExpressionFeatureOff (b * testing.B ) {
786
+ expressions := []apiserver.WebhookMatchCondition {}
787
+ b .Run ("compile" , func (b * testing.B ) {
788
+ benchmarkNewWebhookAuthorizer (b , expressions , false )
789
+ })
790
+ b .Run ("authorize" , func (b * testing.B ) {
791
+ benchmarkWebhookAuthorize (b , expressions , false )
792
+ })
793
+ }
794
+
795
+ func BenchmarkNoCELExpressionFeatureOn (b * testing.B ) {
796
+ expressions := []apiserver.WebhookMatchCondition {}
797
+ b .Run ("compile" , func (b * testing.B ) {
798
+ benchmarkNewWebhookAuthorizer (b , expressions , true )
799
+ })
800
+ b .Run ("authorize" , func (b * testing.B ) {
801
+ benchmarkWebhookAuthorize (b , expressions , true )
802
+ })
803
+ }
804
+ func BenchmarkWithOneCELExpressions (b * testing.B ) {
805
+ expressions := []apiserver.WebhookMatchCondition {
806
+ {
807
+ Expression : "request.user == 'alice'" ,
808
+ },
809
+ }
810
+ b .Run ("compile" , func (b * testing.B ) {
811
+ benchmarkNewWebhookAuthorizer (b , expressions , true )
812
+ })
813
+ b .Run ("authorize" , func (b * testing.B ) {
814
+ benchmarkWebhookAuthorize (b , expressions , true )
815
+ })
816
+ }
817
+ func BenchmarkWithOneCELExpressionsFalse (b * testing.B ) {
818
+ expressions := []apiserver.WebhookMatchCondition {
819
+ {
820
+ Expression : "request.user == 'alice2'" ,
821
+ },
822
+ }
823
+ b .Run ("compile" , func (b * testing.B ) {
824
+ benchmarkNewWebhookAuthorizer (b , expressions , true )
825
+ })
826
+ b .Run ("authorize" , func (b * testing.B ) {
827
+ benchmarkWebhookAuthorize (b , expressions , true )
828
+ })
829
+ }
830
+ func BenchmarkWithTwoCELExpressions (b * testing.B ) {
831
+ expressions := []apiserver.WebhookMatchCondition {
832
+ {
833
+ Expression : "request.user == 'alice'" ,
834
+ },
835
+ {
836
+ Expression : "request.uid == '1'" ,
837
+ },
838
+ }
839
+ b .Run ("compile" , func (b * testing.B ) {
840
+ benchmarkNewWebhookAuthorizer (b , expressions , true )
841
+ })
842
+ b .Run ("authorize" , func (b * testing.B ) {
843
+ benchmarkWebhookAuthorize (b , expressions , true )
844
+ })
845
+ }
846
+ func BenchmarkWithTwoCELExpressionsFalse (b * testing.B ) {
847
+ expressions := []apiserver.WebhookMatchCondition {
848
+ {
849
+ Expression : "request.user == 'alice'" ,
850
+ },
851
+ {
852
+ Expression : "request.uid == '2'" ,
853
+ },
854
+ }
855
+ b .Run ("compile" , func (b * testing.B ) {
856
+ benchmarkNewWebhookAuthorizer (b , expressions , true )
857
+ })
858
+ b .Run ("authorize" , func (b * testing.B ) {
859
+ benchmarkWebhookAuthorize (b , expressions , true )
860
+ })
861
+ }
862
+ func BenchmarkWithManyCELExpressions (b * testing.B ) {
863
+ expressions := []apiserver.WebhookMatchCondition {
864
+ {
865
+ Expression : "request.user == 'alice'" ,
866
+ },
867
+ {
868
+ Expression : "request.uid == '1'" ,
869
+ },
870
+ {
871
+ Expression : "('group1' in request.groups)" ,
872
+ },
873
+ {
874
+ Expression : "('key1' in request.extra)" ,
875
+ },
876
+ {
877
+ Expression : "!('key2' in request.extra)" ,
878
+ },
879
+ {
880
+ Expression : "('a' in request.extra['key1'])" ,
881
+ },
882
+ {
883
+ Expression : "!('z' in request.extra['key1'])" ,
884
+ },
885
+ {
886
+ Expression : "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kittensandponies'" ,
887
+ },
888
+ }
889
+ b .Run ("compile" , func (b * testing.B ) {
890
+ benchmarkNewWebhookAuthorizer (b , expressions , true )
891
+ })
892
+ b .Run ("authorize" , func (b * testing.B ) {
893
+ benchmarkWebhookAuthorize (b , expressions , true )
894
+ })
895
+ }
896
+ func BenchmarkWithManyCELExpressionsFalse (b * testing.B ) {
897
+ expressions := []apiserver.WebhookMatchCondition {
898
+ {
899
+ Expression : "request.user == 'alice'" ,
900
+ },
901
+ {
902
+ Expression : "request.uid == '1'" ,
903
+ },
904
+ {
905
+ Expression : "('group1' in request.groups)" ,
906
+ },
907
+ {
908
+ Expression : "('key1' in request.extra)" ,
909
+ },
910
+ {
911
+ Expression : "!('key2' in request.extra)" ,
912
+ },
913
+ {
914
+ Expression : "('a' in request.extra['key1'])" ,
915
+ },
916
+ {
917
+ Expression : "!('z' in request.extra['key1'])" ,
918
+ },
919
+ {
920
+ Expression : "has(request.resourceAttributes) && request.resourceAttributes.namespace == 'kittensandponies1'" ,
921
+ },
922
+ }
923
+ b .Run ("compile" , func (b * testing.B ) {
924
+ benchmarkNewWebhookAuthorizer (b , expressions , true )
925
+ })
926
+ b .Run ("authorize" , func (b * testing.B ) {
927
+ benchmarkWebhookAuthorize (b , expressions , true )
928
+ })
929
+ }
930
+
931
+ func benchmarkNewWebhookAuthorizer (b * testing.B , expressions []apiserver.WebhookMatchCondition , featureEnabled bool ) {
932
+ service := new (mockV1Service )
933
+ service .statusCode = 200
934
+ service .Allow ()
935
+ s , err := NewV1TestServer (service , serverCert , serverKey , caCert )
936
+ if err != nil {
937
+ b .Fatal (err )
938
+ }
939
+ defer s .Close ()
940
+ defer featuregatetesting .SetFeatureGateDuringTest (b , utilfeature .DefaultFeatureGate , features .StructuredAuthorizationConfiguration , featureEnabled )()
941
+
942
+ b .ResetTimer ()
943
+ for i := 0 ; i < b .N ; i ++ {
944
+ // Create an authorizer with or without expressions to compile
945
+ _ , err := newV1Authorizer (s .URL , clientCert , clientKey , caCert , 0 , noopAuthorizerMetrics (), expressions )
946
+ if err != nil {
947
+ b .Fatal (err )
948
+ }
949
+ }
950
+ b .StopTimer ()
951
+ }
952
+
953
+ func benchmarkWebhookAuthorize (b * testing.B , expressions []apiserver.WebhookMatchCondition , featureEnabled bool ) {
954
+ attr := authorizer.AttributesRecord {
955
+ User : & user.DefaultInfo {
956
+ Name : "alice" ,
957
+ UID : "1" ,
958
+ Groups : []string {"group1" , "group2" },
959
+ Extra : map [string ][]string {"key1" : {"a" , "b" , "c" }},
960
+ },
961
+ ResourceRequest : true ,
962
+ Namespace : "kittensandponies" ,
963
+ Verb : "get" ,
964
+ }
965
+ service := new (mockV1Service )
966
+ service .statusCode = 200
967
+ service .Allow ()
968
+ s , err := NewV1TestServer (service , serverCert , serverKey , caCert )
969
+ if err != nil {
970
+ b .Fatal (err )
971
+ }
972
+ defer s .Close ()
973
+ defer featuregatetesting .SetFeatureGateDuringTest (b , utilfeature .DefaultFeatureGate , features .StructuredAuthorizationConfiguration , featureEnabled )()
974
+ // Create an authorizer with or without expressions to compile
975
+ wh , err := newV1Authorizer (s .URL , clientCert , clientKey , caCert , 0 , noopAuthorizerMetrics (), expressions )
976
+ if err != nil {
977
+ b .Fatal (err )
978
+ }
979
+
980
+ b .ResetTimer ()
981
+ for i := 0 ; i < b .N ; i ++ {
982
+ // Call authorize may or may not require cel evaluations
983
+ _ , _ , err = wh .Authorize (context .Background (), attr )
984
+ if err != nil {
985
+ b .Fatal (err )
986
+ }
987
+ }
988
+ b .StopTimer ()
989
+ }
990
+
785
991
// TestV1WebhookMatchConditions verifies cel expressions are compiled and evaluated correctly
786
992
func TestV1WebhookMatchConditions (t * testing.T ) {
787
993
defer featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .StructuredAuthorizationConfiguration , true )()
0 commit comments