diff --git a/charts/consul/templates/connect-inject-clusterrole.yaml b/charts/consul/templates/connect-inject-clusterrole.yaml index ef1e93adac..94542838c1 100644 --- a/charts/consul/templates/connect-inject-clusterrole.yaml +++ b/charts/consul/templates/connect-inject-clusterrole.yaml @@ -37,6 +37,7 @@ rules: - peeringdialers {{- end }} - jwtproviders + - routeauthfilters verbs: - create - delete @@ -65,6 +66,7 @@ rules: - peeringdialers/status {{- end }} - jwtproviders/status + - routeauthfilters/status verbs: - get - patch diff --git a/control-plane/api-gateway/common/diff.go b/control-plane/api-gateway/common/diff.go index fcb05eb6cc..b37b961247 100644 --- a/control-plane/api-gateway/common/diff.go +++ b/control-plane/api-gateway/common/diff.go @@ -219,7 +219,8 @@ func (e entryComparator) httpRouteRulesEqual(a, b api.HTTPRouteRule) bool { slices.EqualFunc(a.Matches, b.Matches, e.httpMatchesEqual) && slices.EqualFunc(a.Services, b.Services, e.httpServicesEqual) && bothNilOrEqualFunc(a.Filters.RetryFilter, b.Filters.RetryFilter, e.retryFiltersEqual) && - bothNilOrEqualFunc(a.Filters.TimeoutFilter, b.Filters.TimeoutFilter, e.timeoutFiltersEqual) + bothNilOrEqualFunc(a.Filters.TimeoutFilter, b.Filters.TimeoutFilter, e.timeoutFiltersEqual) && + bothNilOrEqualFunc(a.Filters.JWT, b.Filters.JWT, e.jwtFiltersEqual) } func (e entryComparator) httpServicesEqual(a, b api.HTTPService) bool { @@ -269,6 +270,16 @@ func (e entryComparator) timeoutFiltersEqual(a, b api.TimeoutFilter) bool { return a.RequestTimeout == b.RequestTimeout && a.IdleTimeout == b.IdleTimeout } +// jwtFiltersEqual compares the contents of the list of providers on the JWT filters for a route, returning true if the +// filters have equal contents. +func (e entryComparator) jwtFiltersEqual(a, b api.JWTFilter) bool { + if len(a.Providers) != len(b.Providers) { + return false + } + + return slices.EqualFunc(a.Providers, b.Providers, providersEqual) +} + func tcpRoutesEqual(a, b *api.TCPRouteConfigEntry) bool { if a == nil || b == nil { return false diff --git a/control-plane/api-gateway/common/helpers.go b/control-plane/api-gateway/common/helpers.go index f2ac883571..7bc7eb61b6 100644 --- a/control-plane/api-gateway/common/helpers.go +++ b/control-plane/api-gateway/common/helpers.go @@ -38,7 +38,7 @@ func FilterIsExternalFilter(filter gwv1beta1.HTTPRouteFilter) bool { } switch filter.ExtensionRef.Kind { - case v1alpha1.RouteRetryFilterKind, v1alpha1.RouteTimeoutFilterKind: + case v1alpha1.RouteRetryFilterKind, v1alpha1.RouteTimeoutFilterKind, v1alpha1.RouteAuthFilterKind: return true } diff --git a/control-plane/api-gateway/controllers/gateway_controller.go b/control-plane/api-gateway/controllers/gateway_controller.go index 7f72a7778a..e01b4b931f 100644 --- a/control-plane/api-gateway/controllers/gateway_controller.go +++ b/control-plane/api-gateway/controllers/gateway_controller.go @@ -477,7 +477,13 @@ func SetupGatewayControllerWithManager(ctx context.Context, mgr ctrl.Manager, co Watches( source.NewKindWithCache((&v1alpha1.RouteTimeoutFilter{}), mgr.GetCache()), handler.EnqueueRequestsFromMapFunc(r.transformRouteTimeoutFilter(ctx)), - ).Complete(r) + ). + Watches( + // Subscribe to changes in RouteAuthFilter custom resources referenced by HTTPRoutes. + source.NewKindWithCache((&v1alpha1.RouteAuthFilter{}), mgr.GetCache()), + handler.EnqueueRequestsFromMapFunc(r.transformRouteAuthFilter(ctx)), + ). + Complete(r) } // transformGatewayClass will check the list of GatewayClass objects for a matching @@ -628,6 +634,12 @@ func (r *GatewayController) transformRouteTimeoutFilter(ctx context.Context) fun } } +func (r *GatewayController) transformRouteAuthFilter(ctx context.Context) func(object client.Object) []reconcile.Request { + return func(o client.Object) []reconcile.Request { + return r.gatewaysForRoutesReferencing(ctx, "", HTTPRoute_RouteAuthFilterIndex, client.ObjectKeyFromObject(o).String()) + } +} + func (r *GatewayController) transformConsulTCPRoute(ctx context.Context) func(entry api.ConfigEntry) []types.NamespacedName { return func(entry api.ConfigEntry) []types.NamespacedName { parents := mapset.NewSet() @@ -883,6 +895,8 @@ func (c *GatewayController) filterFiltersForExternalRefs(ctx context.Context, ro externalFilter = &v1alpha1.RouteRetryFilter{} case v1alpha1.RouteTimeoutFilterKind: externalFilter = &v1alpha1.RouteTimeoutFilter{} + case v1alpha1.RouteAuthFilterKind: + externalFilter = &v1alpha1.RouteAuthFilter{} default: continue } diff --git a/control-plane/api-gateway/controllers/index.go b/control-plane/api-gateway/controllers/index.go index d18e2dec85..4bb5c5f666 100644 --- a/control-plane/api-gateway/controllers/index.go +++ b/control-plane/api-gateway/controllers/index.go @@ -5,6 +5,7 @@ package controllers import ( "context" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" @@ -20,18 +21,23 @@ const ( // Naming convention: TARGET_REFERENCE. GatewayClass_GatewayClassConfigIndex = "__gatewayclass_referencing_gatewayclassconfig" GatewayClass_ControllerNameIndex = "__gatewayclass_controller_name" - Gateway_GatewayClassIndex = "__gateway_referencing_gatewayclass" - HTTPRoute_GatewayIndex = "__httproute_referencing_gateway" - HTTPRoute_ServiceIndex = "__httproute_referencing_service" - HTTPRoute_MeshServiceIndex = "__httproute_referencing_mesh_service" - TCPRoute_GatewayIndex = "__tcproute_referencing_gateway" - TCPRoute_ServiceIndex = "__tcproute_referencing_service" - TCPRoute_MeshServiceIndex = "__tcproute_referencing_mesh_service" - MeshService_PeerIndex = "__meshservice_referencing_peer" - Secret_GatewayIndex = "__secret_referencing_gateway" - HTTPRoute_RouteRetryFilterIndex = "__httproute_referencing_retryfilter" - HTTPRoute_RouteTimeoutFilterIndex = "__httproute_referencing_timeoutfilter" - Gatewaypolicy_GatewayIndex = "__gatewaypolicy_referencing_gateway" + + Gateway_GatewayClassIndex = "__gateway_referencing_gatewayclass" + + HTTPRoute_GatewayIndex = "__httproute_referencing_gateway" + HTTPRoute_ServiceIndex = "__httproute_referencing_service" + HTTPRoute_MeshServiceIndex = "__httproute_referencing_mesh_service" + HTTPRoute_RouteRetryFilterIndex = "__httproute_referencing_retryfilter" + HTTPRoute_RouteTimeoutFilterIndex = "__httproute_referencing_timeoutfilter" + HTTPRoute_RouteAuthFilterIndex = "__httproute_referencing_routeauthfilter" + + TCPRoute_GatewayIndex = "__tcproute_referencing_gateway" + TCPRoute_ServiceIndex = "__tcproute_referencing_service" + TCPRoute_MeshServiceIndex = "__tcproute_referencing_mesh_service" + + MeshService_PeerIndex = "__meshservice_referencing_peer" + Secret_GatewayIndex = "__secret_referencing_gateway" + Gatewaypolicy_GatewayIndex = "__gatewaypolicy_referencing_gateway" ) // RegisterFieldIndexes registers all of the field indexes for the API gateway controllers. @@ -118,6 +124,11 @@ var indexes = []index{ target: &gwv1beta1.HTTPRoute{}, indexerFunc: filtersForHTTPRoute, }, + { + name: HTTPRoute_RouteAuthFilterIndex, + target: &gwv1beta1.HTTPRoute{}, + indexerFunc: filtersForHTTPRoute, + }, { name: Gatewaypolicy_GatewayIndex, target: &v1alpha1.GatewayPolicy{},