@@ -18,6 +18,7 @@ import (
1818 "sigs.k8s.io/controller-runtime/pkg/handler"
1919 "sigs.k8s.io/controller-runtime/pkg/predicate"
2020 "sigs.k8s.io/controller-runtime/pkg/reconcile"
21+ "sigs.k8s.io/controller-runtime/pkg/source"
2122 gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
2223
2324 "github.com/api7/api7-ingress-controller/api/v1alpha1"
@@ -33,10 +34,14 @@ type HTTPRouteReconciler struct { //nolint:revive
3334 Log logr.Logger
3435
3536 Provider provider.Provider
37+
38+ genericEvent chan event.GenericEvent
3639}
3740
3841// SetupWithManager sets up the controller with the Manager.
3942func (r * HTTPRouteReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
43+ r .genericEvent = make (chan event.GenericEvent , 100 )
44+
4045 return ctrl .NewControllerManagedBy (mgr ).
4146 For (& gatewayv1.HTTPRoute {}).
4247 WithEventFilter (predicate.GenerationChangedPredicate {}).
@@ -65,9 +70,100 @@ func (r *HTTPRouteReconciler) SetupWithManager(mgr ctrl.Manager) error {
6570 },
6671 ),
6772 ).
73+ Watches (& v1alpha1.BackendTrafficPolicy {},
74+ handler .EnqueueRequestsFromMapFunc (r .listHTTPRoutesForBackendTrafficPolicy ),
75+ builder .WithPredicates (
76+ predicate.Funcs {
77+ GenericFunc : func (e event.GenericEvent ) bool {
78+ return false
79+ },
80+ DeleteFunc : func (e event.DeleteEvent ) bool {
81+ return true
82+ },
83+ CreateFunc : func (e event.CreateEvent ) bool {
84+ return true
85+ },
86+ UpdateFunc : func (e event.UpdateEvent ) bool {
87+ oldObj , ok := e .ObjectOld .(* v1alpha1.BackendTrafficPolicy )
88+ newObj , ok2 := e .ObjectNew .(* v1alpha1.BackendTrafficPolicy )
89+ if ! ok || ! ok2 {
90+ return false
91+ }
92+ oldRefs := oldObj .Spec .TargetRefs
93+ newRefs := newObj .Spec .TargetRefs
94+
95+ oldRefMap := make (map [string ]v1alpha1.BackendPolicyTargetReferenceWithSectionName )
96+ for _ , ref := range oldRefs {
97+ key := fmt .Sprintf ("%s/%s/%s" , ref .Group , ref .Kind , ref .Name )
98+ oldRefMap [key ] = ref
99+ }
100+
101+ for _ , ref := range newRefs {
102+ key := fmt .Sprintf ("%s/%s/%s" , ref .Group , ref .Kind , ref .Name )
103+ delete (oldRefMap , key )
104+ }
105+ if len (oldRefMap ) > 0 {
106+ targetRefs := make ([]v1alpha1.BackendPolicyTargetReferenceWithSectionName , 0 , len (oldRefs ))
107+ for _ , ref := range oldRefMap {
108+ targetRefs = append (targetRefs , ref )
109+ }
110+ dump := oldObj .DeepCopy ()
111+ dump .Spec .TargetRefs = targetRefs
112+ r .genericEvent <- event.GenericEvent {
113+ Object : dump ,
114+ }
115+ }
116+ return true
117+ },
118+ },
119+ ),
120+ ).
121+ WatchesRawSource (
122+ source .Channel (
123+ r .genericEvent ,
124+ handler .EnqueueRequestsFromMapFunc (r .listHTTPRouteForGenericEvent ),
125+ ),
126+ ).
68127 Complete (r )
69128}
70129
130+ func (r * HTTPRouteReconciler ) listHTTPRouteForGenericEvent (ctx context.Context , obj client.Object ) []reconcile.Request {
131+ var namespacedNameMap = make (map [types.NamespacedName ]struct {})
132+ requests := []reconcile.Request {}
133+ switch v := obj .(type ) {
134+ case * v1alpha1.BackendTrafficPolicy :
135+ httprouteAll := []gatewayv1.HTTPRoute {}
136+ for _ , ref := range v .Spec .TargetRefs {
137+ httprouteList := & gatewayv1.HTTPRouteList {}
138+ if err := r .List (ctx , httprouteList , client.MatchingFields {
139+ indexer .ServiceIndexRef : indexer .GenIndexKey (v .GetNamespace (), string (ref .Name )),
140+ }); err != nil {
141+ r .Log .Error (err , "failed to list HTTPRoutes for BackendTrafficPolicy" , "namespace" , v .GetNamespace (), "ref" , ref .Name )
142+ return nil
143+ }
144+ httprouteAll = append (httprouteAll , httprouteList .Items ... )
145+ }
146+ for _ , hr := range httprouteAll {
147+ key := types.NamespacedName {
148+ Namespace : hr .Namespace ,
149+ Name : hr .Name ,
150+ }
151+ if _ , ok := namespacedNameMap [key ]; ! ok {
152+ namespacedNameMap [key ] = struct {}{}
153+ requests = append (requests , reconcile.Request {
154+ NamespacedName : client.ObjectKey {
155+ Namespace : hr .Namespace ,
156+ Name : hr .Name ,
157+ },
158+ })
159+ }
160+ }
161+ default :
162+ r .Log .Error (fmt .Errorf ("unexpected object type" ), "failed to convert object to BackendTrafficPolicy" )
163+ }
164+ return requests
165+ }
166+
71167func (r * HTTPRouteReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
72168 hr := new (gatewayv1.HTTPRoute )
73169 if err := r .Get (ctx , req .NamespacedName , hr ); err != nil {
@@ -114,6 +210,7 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
114210
115211 tctx := provider .NewDefaultTranslateContext (ctx )
116212
213+ tctx .RouteParentRefs = hr .Spec .ParentRefs
117214 rk := provider.ResourceKind {
118215 Kind : hr .Kind ,
119216 Namespace : hr .Namespace ,
@@ -138,6 +235,8 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
138235 }
139236 }
140237
238+ ProcessBackendTrafficPolicy (r .Client , r .Log , tctx )
239+
141240 if err := r .Provider .Update (ctx , tctx , hr ); err != nil {
142241 acceptStatus .status = false
143242 acceptStatus .msg = err .Error ()
@@ -161,6 +260,7 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
161260 if err := r .Status ().Update (ctx , hr ); err != nil {
162261 return ctrl.Result {}, err
163262 }
263+ UpdateStatus (r .Client , r .Log , tctx )
164264 return ctrl.Result {}, nil
165265}
166266
@@ -220,6 +320,54 @@ func (r *HTTPRouteReconciler) listHTTPRoutesByExtensionRef(ctx context.Context,
220320 return requests
221321}
222322
323+ func (r * HTTPRouteReconciler ) listHTTPRoutesForBackendTrafficPolicy (ctx context.Context , obj client.Object ) []reconcile.Request {
324+ policy , ok := obj .(* v1alpha1.BackendTrafficPolicy )
325+ if ! ok {
326+ r .Log .Error (fmt .Errorf ("unexpected object type" ), "failed to convert object to BackendTrafficPolicy" )
327+ return nil
328+ }
329+
330+ httprouteList := []gatewayv1.HTTPRoute {}
331+ for _ , targetRef := range policy .Spec .TargetRefs {
332+ service := & corev1.Service {}
333+ if err := r .Get (ctx , client.ObjectKey {
334+ Namespace : policy .Namespace ,
335+ Name : string (targetRef .Name ),
336+ }, service ); err != nil {
337+ if client .IgnoreNotFound (err ) != nil {
338+ r .Log .Error (err , "failed to get service" , "namespace" , policy .Namespace , "name" , targetRef .Name )
339+ }
340+ continue
341+ }
342+ hrList := & gatewayv1.HTTPRouteList {}
343+ if err := r .List (ctx , hrList , client.MatchingFields {
344+ indexer .ServiceIndexRef : indexer .GenIndexKey (policy .Namespace , string (targetRef .Name )),
345+ }); err != nil {
346+ r .Log .Error (err , "failed to list httproutes by service reference" , "service" , targetRef .Name )
347+ return nil
348+ }
349+ httprouteList = append (httprouteList , hrList .Items ... )
350+ }
351+ var namespacedNameMap = make (map [types.NamespacedName ]struct {})
352+ requests := make ([]reconcile.Request , 0 , len (httprouteList ))
353+ for _ , hr := range httprouteList {
354+ key := types.NamespacedName {
355+ Namespace : hr .Namespace ,
356+ Name : hr .Name ,
357+ }
358+ if _ , ok := namespacedNameMap [key ]; ! ok {
359+ namespacedNameMap [key ] = struct {}{}
360+ requests = append (requests , reconcile.Request {
361+ NamespacedName : client.ObjectKey {
362+ Namespace : hr .Namespace ,
363+ Name : hr .Name ,
364+ },
365+ })
366+ }
367+ }
368+ return requests
369+ }
370+
223371func (r * HTTPRouteReconciler ) listHTTPRoutesForGateway (ctx context.Context , obj client.Object ) []reconcile.Request {
224372 gateway , ok := obj .(* gatewayv1.Gateway )
225373 if ! ok {
0 commit comments