99 "github.com/api7/api7-ingress-controller/internal/controller/indexer"
1010 "github.com/api7/api7-ingress-controller/internal/provider"
1111 "github.com/go-logr/logr"
12+ "github.com/pkg/errors"
1213 corev1 "k8s.io/api/core/v1"
1314 discoveryv1 "k8s.io/api/discovery/v1"
1415 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -21,6 +22,7 @@ import (
2122 "sigs.k8s.io/controller-runtime/pkg/handler"
2223 "sigs.k8s.io/controller-runtime/pkg/predicate"
2324 "sigs.k8s.io/controller-runtime/pkg/reconcile"
25+ "sigs.k8s.io/controller-runtime/pkg/source"
2426 gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
2527 "sigs.k8s.io/gateway-api/apis/v1alpha2"
2628)
@@ -33,10 +35,14 @@ type HTTPRouteReconciler struct { //nolint:revive
3335 Log logr.Logger
3436
3537 Provider provider.Provider
38+
39+ genericEvent chan event.GenericEvent
3640}
3741
3842// SetupWithManager sets up the controller with the Manager.
3943func (r * HTTPRouteReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
44+ r .genericEvent = make (chan event.GenericEvent , 100 )
45+
4046 return ctrl .NewControllerManagedBy (mgr ).
4147 For (& gatewayv1.HTTPRoute {}).
4248 WithEventFilter (predicate.GenerationChangedPredicate {}).
@@ -67,10 +73,56 @@ func (r *HTTPRouteReconciler) SetupWithManager(mgr ctrl.Manager) error {
6773 ).
6874 Watches (& v1alpha1.HTTPRoutePolicy {},
6975 handler .EnqueueRequestsFromMapFunc (r .listHTTPRouteByHTTPRoutePolicy ),
76+ builder .WithPredicates (
77+ predicate.Funcs {
78+ CreateFunc : func (e event.CreateEvent ) bool {
79+ return true
80+ },
81+ DeleteFunc : func (e event.DeleteEvent ) bool {
82+ return true
83+ },
84+ UpdateFunc : r .httpRoutePolicyPredicateOnUpdate ,
85+ GenericFunc : func (e event.GenericEvent ) bool {
86+ return false
87+ },
88+ },
89+ ),
90+ ).
91+ WatchesRawSource (
92+ source .Channel (
93+ r .genericEvent ,
94+ handler .EnqueueRequestsFromMapFunc (r .listHTTPRouteForGenericEvent ),
95+ ),
7096 ).
7197 Complete (r )
7298}
7399
100+ func (r * HTTPRouteReconciler ) httpRoutePolicyPredicateOnUpdate (e event.UpdateEvent ) bool {
101+ oldPolicy , ok0 := e .ObjectOld .(* v1alpha1.HTTPRoutePolicy )
102+ newPolicy , ok1 := e .ObjectNew .(* v1alpha1.HTTPRoutePolicy )
103+ if ! ok0 || ! ok1 {
104+ return false
105+ }
106+ var discardsRefs = make (map [string ]v1alpha2.LocalPolicyTargetReferenceWithSectionName )
107+ for _ , ref := range oldPolicy .Spec .TargetRefs {
108+ key := indexer .GenHTTPRoutePolicyIndexKey (string (ref .Group ), string (ref .Kind ), e .ObjectOld .GetNamespace (), string (ref .Name ), "" )
109+ discardsRefs [key ] = ref
110+ }
111+ for _ , ref := range newPolicy .Spec .TargetRefs {
112+ key := indexer .GenHTTPRoutePolicyIndexKey (string (ref .Group ), string (ref .Kind ), e .ObjectOld .GetNamespace (), string (ref .Name ), "" )
113+ delete (discardsRefs , key )
114+ }
115+ if len (discardsRefs ) > 0 {
116+ dump := oldPolicy .DeepCopy ()
117+ dump .Spec .TargetRefs = make ([]v1alpha2.LocalPolicyTargetReferenceWithSectionName , 0 , len (discardsRefs ))
118+ for _ , ref := range discardsRefs {
119+ dump .Spec .TargetRefs = append (dump .Spec .TargetRefs , ref )
120+ }
121+ r .genericEvent <- event.GenericEvent {Object : dump }
122+ }
123+ return true
124+ }
125+
74126func (r * HTTPRouteReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
75127 hr := new (gatewayv1.HTTPRoute )
76128 if err := r .Get (ctx , req .NamespacedName , hr ); err != nil {
@@ -264,7 +316,6 @@ func (r *HTTPRouteReconciler) listHTTPRouteByHTTPRoutePolicy(ctx context.Context
264316 if ref .Kind == "HTTPRoute" {
265317 key := ancestorRefKey {
266318 Group : gatewayv1 .GroupName ,
267- Kind : "HTTPRoute" ,
268319 Namespace : gatewayv1 .Namespace (obj .GetNamespace ()),
269320 Name : ref .Name ,
270321 }
@@ -277,11 +328,25 @@ func (r *HTTPRouteReconciler) listHTTPRouteByHTTPRoutePolicy(ctx context.Context
277328 for key := range keys {
278329 var httpRoute gatewayv1.HTTPRoute
279330 if err := r .Get (ctx , client.ObjectKey {Namespace : string (key .Namespace ), Name : string (key .Name )}, & httpRoute ); err != nil {
280- r .Log .Error (err , "failed to get HTTPRoute by HTTPRoutePolicy targetRef" , "namespace" , obj . GetNamespace () , "name" , obj . GetName () )
281- r .modifyHTTPRoutePolicyStatus (key , httpRoutePolicy , false , string (v1alpha2 .PolicyReasonTargetNotFound ), "not found HTTPRoute" )
331+ r .Log .Error (err , "failed to get HTTPRoute by HTTPRoutePolicy targetRef" , "namespace" , key . Namespace , "name" , key . Name )
332+ r .modifyHTTPRoutePolicyStatus (key , httpRoutePolicy , false , string (v1alpha2 .PolicyReasonTargetNotFound ), "not found target HTTPRoute" )
282333 r .Log .Info ("status after modified" , "key" , key , "status" , httpRoutePolicy .Status .Ancestors )
283334 continue
284335 }
336+ if key .SectionName != "" {
337+ var matchRuleName bool
338+ for _ , rule := range httpRoute .Spec .Rules {
339+ if rule .Name != nil && * rule .Name == key .SectionName {
340+ matchRuleName = true
341+ break
342+ }
343+ }
344+ if ! matchRuleName {
345+ r .Log .Error (errors .Errorf ("failed to get HTTPRoute rule by HTTPRoutePolicy targetRef" ), "namespace" , key .Namespace , "name" , key .Name , "sectionName" , key .SectionName )
346+ r .modifyHTTPRoutePolicyStatus (key , httpRoutePolicy , false , string (v1alpha2 .PolicyReasonTargetNotFound ), "not found target HTTPRoute rule" )
347+ continue
348+ }
349+ }
285350 requests = append (requests , reconcile.Request {
286351 NamespacedName : types.NamespacedName {
287352 Namespace : string (key .Namespace ),
@@ -293,13 +358,34 @@ func (r *HTTPRouteReconciler) listHTTPRouteByHTTPRoutePolicy(ctx context.Context
293358 r .Log .Info ("status before clear" , "status" , httpRoutePolicy .Status .Ancestors )
294359 r .clearHTTPRoutePolicyRedundantAncestor (httpRoutePolicy )
295360 r .Log .Info ("status after clear" , "status" , httpRoutePolicy .Status .Ancestors )
296- if err := r .Status ().Update (ctx , httpRoutePolicy ); err != nil {
297- r .Log .Error (err , "failed to update HTTPRoutePolicy status" , "namespace" , obj .GetNamespace (), "name" , obj .GetName ())
361+ if httpRoutePolicy .GetDeletionTimestamp ().IsZero () {
362+ if err := r .Status ().Update (ctx , httpRoutePolicy ); err != nil {
363+ r .Log .Error (err , "failed to update HTTPRoutePolicy status" , "namespace" , obj .GetNamespace (), "name" , obj .GetName ())
364+ }
298365 }
299366
300367 return requests
301368}
302369
370+ func (r * HTTPRouteReconciler ) listHTTPRouteForGenericEvent (ctx context.Context , obj client.Object ) []reconcile.Request {
371+ switch v := obj .(type ) {
372+ case * v1alpha1.HTTPRoutePolicy :
373+ var (
374+ namespacedNames = make (map [types.NamespacedName ]struct {})
375+ requests []reconcile.Request
376+ )
377+ for _ , ref := range v .Spec .TargetRefs {
378+ namespacedName := types.NamespacedName {Namespace : v .GetNamespace (), Name : string (ref .Name )}
379+ if _ , ok := namespacedNames [namespacedName ]; ! ok {
380+ namespacedNames [namespacedName ] = struct {}{}
381+ requests = append (requests , reconcile.Request {NamespacedName : namespacedName })
382+ }
383+ }
384+ return requests
385+ }
386+ return nil
387+ }
388+
303389func (r * HTTPRouteReconciler ) processHTTPRouteBackendRefs (tctx * provider.TranslateContext ) error {
304390 var terr error
305391 for _ , backend := range tctx .BackendRefs {
0 commit comments