diff --git a/internal/controller/gateway_controller.go b/internal/controller/gateway_controller.go index addb206f3..e71e56e0c 100644 --- a/internal/controller/gateway_controller.go +++ b/internal/controller/gateway_controller.go @@ -36,30 +36,22 @@ type GatewayReconciler struct { //nolint:revive Provider provider.Provider } -func (r *GatewayReconciler) setupIndexer(mgr ctrl.Manager) error { - if err := mgr.GetFieldIndexer().IndexField( - context.Background(), - &gatewayv1.Gateway{}, - indexer.ParametersRef, - indexer.GatewayParametersRefIndexFunc, - ); err != nil { - return err - } - return nil -} - // SetupWithManager sets up the controller with the Manager. func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error { - if err := r.setupIndexer(mgr); err != nil { - return err - } return ctrl.NewControllerManagedBy(mgr). - For(&gatewayv1.Gateway{}). + For( + &gatewayv1.Gateway{}, + builder.WithPredicates( + predicate.NewPredicateFuncs(r.checkGatewayClass), + ), + ). WithEventFilter(predicate.GenerationChangedPredicate{}). Watches( &gatewayv1.GatewayClass{}, handler.EnqueueRequestsFromMapFunc(r.listGatewayForGatewayClass), - builder.WithPredicates(predicate.NewPredicateFuncs(r.matchesGatewayClass)), + builder.WithPredicates( + predicate.NewPredicateFuncs(r.matchesGatewayClass), + ), ). Watches( &gatewayv1.HTTPRoute{}, @@ -90,11 +82,6 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct } return ctrl.Result{}, err } - ns := gateway.GetNamespace() - if !r.checkGatewayClass(gateway) { - return ctrl.Result{}, nil - } - conditionProgrammedStatus, conditionProgrammedMsg := true, "Programmed" cfg := config.GetFirstGatewayConfig() @@ -126,8 +113,8 @@ func (r *GatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct tctx := &provider.TranslateContext{ Secrets: make(map[types.NamespacedName]*corev1.Secret), } - r.processListenerConfig(tctx, gateway, ns) - if err := r.processInfrastructure(tctx, gateway, ns); err != nil { + r.processListenerConfig(tctx, gateway) + if err := r.processInfrastructure(tctx, gateway); err != nil { acceptStatus = status{ status: false, msg: err.Error(), @@ -208,7 +195,8 @@ func (r *GatewayReconciler) listGatewayForGatewayClass(ctx context.Context, gate return reconcileGatewaysMatchGatewayClass(gatewayClass, gatewayList.Items) } -func (r *GatewayReconciler) checkGatewayClass(gateway *gatewayv1.Gateway) bool { +func (r *GatewayReconciler) checkGatewayClass(obj client.Object) bool { + gateway := obj.(*gatewayv1.Gateway) gatewayClass := &gatewayv1.GatewayClass{} if err := r.Client.Get(context.Background(), client.ObjectKey{Name: string(gateway.Spec.GatewayClassName)}, gatewayClass); err != nil { r.Log.Error(err, "failed to get gateway class", "gateway", gateway.GetName(), "gatewayclass", gateway.Spec.GatewayClassName) @@ -281,12 +269,13 @@ func (r *GatewayReconciler) listGatewaysForHTTPRoute(_ context.Context, obj clie return recs } -func (r *GatewayReconciler) processInfrastructure(tctx *provider.TranslateContext, gateway *gatewayv1.Gateway, ns string) error { +func (r *GatewayReconciler) processInfrastructure(tctx *provider.TranslateContext, gateway *gatewayv1.Gateway) error { infra := gateway.Spec.Infrastructure if infra == nil || infra.ParametersRef == nil { return nil } + ns := gateway.GetNamespace() paramRef := infra.ParametersRef if string(paramRef.Group) == v1alpha1.GroupVersion.Group && string(paramRef.Kind) == "GatewayProxy" { gatewayProxy := &v1alpha1.GatewayProxy{} @@ -305,7 +294,7 @@ func (r *GatewayReconciler) processInfrastructure(tctx *provider.TranslateContex return nil } -func (r *GatewayReconciler) processListenerConfig(tctx *provider.TranslateContext, gateway *gatewayv1.Gateway, ns string) { +func (r *GatewayReconciler) processListenerConfig(tctx *provider.TranslateContext, gateway *gatewayv1.Gateway) { listeners := gateway.Spec.Listeners for _, listener := range listeners { if listener.TLS == nil || listener.TLS.CertificateRefs == nil { @@ -313,6 +302,7 @@ func (r *GatewayReconciler) processListenerConfig(tctx *provider.TranslateContex } secret := corev1.Secret{} for _, ref := range listener.TLS.CertificateRefs { + ns := gateway.GetNamespace() if ref.Namespace != nil { ns = string(*ref.Namespace) } diff --git a/internal/controller/httproute_controller.go b/internal/controller/httproute_controller.go index 00043f202..89d1fd9c0 100644 --- a/internal/controller/httproute_controller.go +++ b/internal/controller/httproute_controller.go @@ -38,9 +38,6 @@ type HTTPRouteReconciler struct { //nolint:revive // SetupWithManager sets up the controller with the Manager. func (r *HTTPRouteReconciler) SetupWithManager(mgr ctrl.Manager) error { - if err := r.setupIndexer(mgr); err != nil { - return err - } return ctrl.NewControllerManagedBy(mgr). For(&gatewayv1.HTTPRoute{}). WithEventFilter(predicate.GenerationChangedPredicate{}). @@ -137,27 +134,6 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return ctrl.Result{}, nil } -// SetupWithManager sets up the controller with the Manager. -func (r *HTTPRouteReconciler) setupIndexer(mgr ctrl.Manager) error { - if err := mgr.GetFieldIndexer().IndexField( - context.Background(), - &gatewayv1.HTTPRoute{}, - indexer.ExtensionRef, - indexer.HTTPRouteExtensionIndexFunc, - ); err != nil { - return err - } - if err := mgr.GetFieldIndexer().IndexField( - context.Background(), - &gatewayv1.HTTPRoute{}, - indexer.ServiceIndexRef, - indexer.HTTPRouteServiceIndexFunc, - ); err != nil { - return err - } - return nil -} - func (r *HTTPRouteReconciler) listHTTPRoutesByServiceBef(ctx context.Context, obj client.Object) []reconcile.Request { endpointSlice, ok := obj.(*discoveryv1.EndpointSlice) if !ok { diff --git a/internal/controller/indexer/indexer.go b/internal/controller/indexer/indexer.go index f35e04c5f..58872e086 100644 --- a/internal/controller/indexer/indexer.go +++ b/internal/controller/indexer/indexer.go @@ -1,16 +1,72 @@ package indexer import ( + "context" + + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" ) const ( - ServiceIndexRef = "serviceRef" + ServiceIndexRef = "serviceRefs" ExtensionRef = "extensionRef" ParametersRef = "parametersRef" + ParentRefs = "parentRefs" ) +func SetupIndexer(mgr ctrl.Manager) error { + if err := setupGatewayIndexer(mgr); err != nil { + return err + } + if err := setupHTTPRouteIndexer(mgr); err != nil { + return err + } + return nil +} + +func setupGatewayIndexer(mgr ctrl.Manager) error { + if err := mgr.GetFieldIndexer().IndexField( + context.Background(), + &gatewayv1.Gateway{}, + ParametersRef, + GatewayParametersRefIndexFunc, + ); err != nil { + return err + } + return nil +} + +func setupHTTPRouteIndexer(mgr ctrl.Manager) error { + if err := mgr.GetFieldIndexer().IndexField( + context.Background(), + &gatewayv1.HTTPRoute{}, + ParentRefs, + HTTPRouteParentRefsIndexFunc, + ); err != nil { + return err + } + + if err := mgr.GetFieldIndexer().IndexField( + context.Background(), + &gatewayv1.HTTPRoute{}, + ExtensionRef, + HTTPRouteExtensionIndexFunc, + ); err != nil { + return err + } + + if err := mgr.GetFieldIndexer().IndexField( + context.Background(), + &gatewayv1.HTTPRoute{}, + ServiceIndexRef, + HTTPRouteServiceIndexFunc, + ); err != nil { + return err + } + return nil +} + func GenIndexKey(namespace, name string) string { return client.ObjectKey{ Namespace: namespace, @@ -18,9 +74,22 @@ func GenIndexKey(namespace, name string) string { }.String() } +func HTTPRouteParentRefsIndexFunc(rawObj client.Object) []string { + hr := rawObj.(*gatewayv1.HTTPRoute) + keys := make([]string, 0, len(hr.Spec.ParentRefs)) + for _, ref := range hr.Spec.ParentRefs { + ns := hr.GetNamespace() + if ref.Namespace != nil { + ns = string(*ref.Namespace) + } + keys = append(keys, GenIndexKey(ns, string(ref.Name))) + } + return keys +} + func HTTPRouteServiceIndexFunc(rawObj client.Object) []string { hr := rawObj.(*gatewayv1.HTTPRoute) - var keys []string + keys := make([]string, 0, len(hr.Spec.Rules)) for _, rule := range hr.Spec.Rules { for _, backend := range rule.BackendRefs { namespace := hr.GetNamespace() @@ -38,7 +107,7 @@ func HTTPRouteServiceIndexFunc(rawObj client.Object) []string { func HTTPRouteExtensionIndexFunc(rawObj client.Object) []string { hr := rawObj.(*gatewayv1.HTTPRoute) - var keys []string + keys := make([]string, 0, len(hr.Spec.Rules)) for _, rule := range hr.Spec.Rules { for _, filter := range rule.Filters { if filter.Type != gatewayv1.HTTPRouteFilterExtensionRef || filter.ExtensionRef == nil { diff --git a/internal/manager/controllers.go b/internal/manager/controllers.go index 292193cbb..5c17c5848 100644 --- a/internal/manager/controllers.go +++ b/internal/manager/controllers.go @@ -7,6 +7,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "github.com/api7/api7-ingress-controller/internal/controller" + "github.com/api7/api7-ingress-controller/internal/controller/indexer" "github.com/api7/api7-ingress-controller/internal/provider" ) @@ -23,7 +24,10 @@ type Controller interface { SetupWithManager(mgr manager.Manager) error } -func setupControllers(ctx context.Context, mgr manager.Manager, pro provider.Provider) []Controller { +func setupControllers(ctx context.Context, mgr manager.Manager, pro provider.Provider) ([]Controller, error) { + if err := indexer.SetupIndexer(mgr); err != nil { + return nil, err + } return []Controller{ &controller.GatewayClassReconciler{ Client: mgr.GetClient(), @@ -42,5 +46,5 @@ func setupControllers(ctx context.Context, mgr manager.Manager, pro provider.Pro Log: ctrl.LoggerFrom(ctx).WithName("controllers").WithName("HTTPRoute"), Provider: pro, }, - } + }, nil } diff --git a/internal/manager/run.go b/internal/manager/run.go index 56490b1bb..317608a0f 100644 --- a/internal/manager/run.go +++ b/internal/manager/run.go @@ -124,7 +124,11 @@ func Run(ctx context.Context, logger logr.Logger) error { } setupLog.Info("setting up controllers") - controllers := setupControllers(ctx, mgr, pro) + controllers, err := setupControllers(ctx, mgr, pro) + if err != nil { + setupLog.Error(err, "unable to set up controllers") + return err + } for _, c := range controllers { if err := c.SetupWithManager(mgr); err != nil { return err