@@ -56,31 +56,43 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
5656 resources * resource.Resources ,
5757 xdsIR resource.XdsIRMap ,
5858) []* egv1a1.SecurityPolicy {
59- var res []* egv1a1.SecurityPolicy
6059 // SecurityPolicies are already sorted by the provider layer
6160
6261 // First build a map out of the routes and gateways for faster lookup since users might have thousands of routes or more.
6362 // For gateways this probably isn't quite as necessary.
64- routeMap := map [policyTargetRouteKey ]* policyRouteTargetContext {}
63+ routeMapSize := len (routes )
64+ gatewayMapSize := len (gateways )
65+ policyMapSize := len (securityPolicies )
66+
67+ // Pre-allocate result slice and maps with estimated capacity to reduce memory allocations
68+ res := make ([]* egv1a1.SecurityPolicy , 0 , len (securityPolicies ))
69+ routeMap := make (map [policyTargetRouteKey ]* policyRouteTargetContext , routeMapSize )
6570 for _ , route := range routes {
6671 key := policyTargetRouteKey {
6772 Kind : string (route .GetRouteType ()),
6873 Name : route .GetName (),
6974 Namespace : route .GetNamespace (),
7075 }
71- routeMap [key ] = & policyRouteTargetContext {RouteContext : route , attachedToRouteRules : make (sets.Set [string ])}
76+ routeMap [key ] = & policyRouteTargetContext {
77+ RouteContext : route ,
78+ attachedToRouteRules : make (sets.Set [string ]),
79+ }
7280 }
73- gatewayMap := map [types.NamespacedName ]* policyGatewayTargetContext {}
81+
82+ gatewayMap := make (map [types.NamespacedName ]* policyGatewayTargetContext , gatewayMapSize )
7483 for _ , gw := range gateways {
7584 key := utils .NamespacedName (gw )
76- gatewayMap [key ] = & policyGatewayTargetContext {GatewayContext : gw , attachedToListeners : make (sets.Set [string ])}
85+ gatewayMap [key ] = & policyGatewayTargetContext {
86+ GatewayContext : gw ,
87+ attachedToListeners : make (sets.Set [string ]),
88+ }
7789 }
7890
7991 // Map of Gateway to the routes attached to it.
8092 // The routes are grouped by sectionNames of their targetRefs
81- gatewayRouteMap := make (map [string ]map [string ]sets.Set [string ])
93+ gatewayRouteMap := make (map [string ]map [string ]sets.Set [string ], gatewayMapSize )
8294
83- handledPolicies := make (map [types.NamespacedName ]* egv1a1.SecurityPolicy )
95+ handledPolicies := make (map [types.NamespacedName ]* egv1a1.SecurityPolicy , policyMapSize )
8496
8597 // Translate
8698 // 1. First translate Policies targeting RouteRules
@@ -622,6 +634,28 @@ func (t *Translator) translateSecurityPolicyForRoute(
622634 }
623635 }
624636
637+ // Pre-create security features to avoid repeated allocations
638+ securityFeatures := & ir.SecurityFeatures {
639+ CORS : cors ,
640+ JWT : jwt ,
641+ OIDC : oidc ,
642+ APIKeyAuth : apiKeyAuth ,
643+ BasicAuth : basicAuth ,
644+ ExtAuth : extAuth ,
645+ Authorization : authorization ,
646+ }
647+
648+ // Pre-create error response to avoid repeated allocations
649+ var errorResponse * ir.CustomResponse
650+ if errs != nil {
651+ shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
652+ if ! shouldFailOpen {
653+ errorResponse = & ir.CustomResponse {
654+ StatusCode : ptr .To (uint32 (500 )),
655+ }
656+ }
657+ }
658+
625659 irKey := t .getIRKey (gtwCtx .Gateway )
626660 for _ , listener := range parentRefCtx .listeners {
627661 irListener := xdsIR [irKey ].GetHTTPListener (irListenerName (listener ))
@@ -640,26 +674,10 @@ func (t *Translator) translateSecurityPolicyForRoute(
640674 continue
641675 }
642676
643- r .Security = & ir.SecurityFeatures {
644- CORS : cors ,
645- JWT : jwt ,
646- OIDC : oidc ,
647- APIKeyAuth : apiKeyAuth ,
648- BasicAuth : basicAuth ,
649- ExtAuth : extAuth ,
650- Authorization : authorization ,
651- }
652- if errs != nil {
653- // If there is only error for ext auth and ext auth is set to fail open, then skip the ext auth
654- // and allow the request to go through.
655- // Otherwise, return a 500 direct response to avoid unauthorized access.
656- shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
657- if ! shouldFailOpen {
658- // Return a 500 direct response to avoid unauthorized access
659- r .DirectResponse = & ir.CustomResponse {
660- StatusCode : ptr .To (uint32 (500 )),
661- }
662- }
677+ r .Security = securityFeatures
678+ if errorResponse != nil {
679+ // Return a 500 direct response to avoid unauthorized access
680+ r .DirectResponse = errorResponse
663681 }
664682 }
665683 }
@@ -760,6 +778,30 @@ func (t *Translator) translateSecurityPolicyForGateway(
760778 // Should exist since we've validated this
761779 x := xdsIR [irKey ]
762780
781+ // Pre-create security features and error response to avoid repeated allocations
782+ securityFeatures := & ir.SecurityFeatures {
783+ CORS : cors ,
784+ JWT : jwt ,
785+ OIDC : oidc ,
786+ APIKeyAuth : apiKeyAuth ,
787+ BasicAuth : basicAuth ,
788+ ExtAuth : extAuth ,
789+ Authorization : authorization ,
790+ }
791+
792+ var errorResponse * ir.CustomResponse
793+ if errs != nil {
794+ // If there is only error for ext auth and ext auth is set to fail open, then skip the ext auth
795+ // and allow the request to go through.
796+ // Otherwise, return a 500 direct response to avoid unauthorized access.
797+ shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
798+ if ! shouldFailOpen {
799+ errorResponse = & ir.CustomResponse {
800+ StatusCode : ptr .To (uint32 (500 )),
801+ }
802+ }
803+ }
804+
763805 policyTarget := irStringKey (policy .Namespace , string (target .Name ))
764806 for _ , h := range x .HTTP {
765807 // A HTTPListener name has the format namespace/gatewayName/listenerName
@@ -772,32 +814,17 @@ func (t *Translator) translateSecurityPolicyForGateway(
772814 if target .SectionName != nil && string (* target .SectionName ) != h .Metadata .SectionName {
773815 continue
774816 }
817+
775818 // A Policy targeting the specific scope(xRoute rule, xRoute, Gateway listener) wins over a policy
776819 // targeting a lesser specific scope(Gateway).
777820 for _ , r := range h .Routes {
778821 // if already set - there's a specific level policy, so skip.
779822 if r .Security != nil {
780823 continue
781824 }
782- r .Security = & ir.SecurityFeatures {
783- CORS : cors ,
784- JWT : jwt ,
785- OIDC : oidc ,
786- APIKeyAuth : apiKeyAuth ,
787- BasicAuth : basicAuth ,
788- ExtAuth : extAuth ,
789- Authorization : authorization ,
790- }
791- if errs != nil {
792- // If there is only error for ext auth and ext auth is set to fail open, then skip the ext auth
793- // and allow the request to go through.
794- // Otherwise, return a 500 direct response to avoid unauthorized access.
795- shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
796- if ! shouldFailOpen {
797- r .DirectResponse = & ir.CustomResponse {
798- StatusCode : ptr .To (uint32 (500 )),
799- }
800- }
825+ r .Security = securityFeatures
826+ if errorResponse != nil {
827+ r .DirectResponse = errorResponse
801828 }
802829 }
803830 }
0 commit comments