66 "strings"
77
88 "github.com/go-logr/logr"
9+ "github.com/pkg/errors"
910 corev1 "k8s.io/api/core/v1"
1011 discoveryv1 "k8s.io/api/discovery/v1"
1112 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -20,6 +21,7 @@ import (
2021 "sigs.k8s.io/controller-runtime/pkg/reconcile"
2122 "sigs.k8s.io/controller-runtime/pkg/source"
2223 gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
24+ "sigs.k8s.io/gateway-api/apis/v1alpha2"
2325
2426 "github.com/api7/api7-ingress-controller/api/v1alpha1"
2527 "github.com/api7/api7-ingress-controller/internal/controller/indexer"
@@ -118,6 +120,23 @@ func (r *HTTPRouteReconciler) SetupWithManager(mgr ctrl.Manager) error {
118120 },
119121 ),
120122 ).
123+ Watches (& v1alpha1.HTTPRoutePolicy {},
124+ handler .EnqueueRequestsFromMapFunc (r .listHTTPRouteByHTTPRoutePolicy ),
125+ builder .WithPredicates (
126+ predicate.Funcs {
127+ CreateFunc : func (e event.CreateEvent ) bool {
128+ return true
129+ },
130+ DeleteFunc : func (e event.DeleteEvent ) bool {
131+ return true
132+ },
133+ UpdateFunc : r .httpRoutePolicyPredicateOnUpdate ,
134+ GenericFunc : func (e event.GenericEvent ) bool {
135+ return false
136+ },
137+ },
138+ ),
139+ ).
121140 WatchesRawSource (
122141 source .Channel (
123142 r .genericEvent ,
@@ -127,43 +146,6 @@ func (r *HTTPRouteReconciler) SetupWithManager(mgr ctrl.Manager) error {
127146 Complete (r )
128147}
129148
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-
167149func (r * HTTPRouteReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
168150 hr := new (gatewayv1.HTTPRoute )
169151 if err := r .Get (ctx , req .NamespacedName , hr ); err != nil {
@@ -228,6 +210,11 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
228210 acceptStatus .msg = err .Error ()
229211 }
230212
213+ if err := r .processHTTPRoutePolicies (tctx , hr ); err != nil {
214+ acceptStatus .status = false
215+ acceptStatus .msg = err .Error ()
216+ }
217+
231218 if err := r .processHTTPRouteBackendRefs (tctx ); err != nil {
232219 resolveRefStatus = status {
233220 status : false ,
@@ -392,6 +379,105 @@ func (r *HTTPRouteReconciler) listHTTPRoutesForGateway(ctx context.Context, obj
392379 return requests
393380}
394381
382+ func (r * HTTPRouteReconciler ) listHTTPRouteByHTTPRoutePolicy (ctx context.Context , obj client.Object ) (requests []reconcile.Request ) {
383+ httpRoutePolicy , ok := obj .(* v1alpha1.HTTPRoutePolicy )
384+ if ! ok {
385+ r .Log .Error (fmt .Errorf ("unexpected object type" ), "failed to convert object to HTTPRoutePolicy" )
386+ return nil
387+ }
388+
389+ var keys = make (map [types.NamespacedName ]struct {})
390+ for _ , ref := range httpRoutePolicy .Spec .TargetRefs {
391+ if ref .Kind != "HTTPRoute" {
392+ continue
393+ }
394+ key := types.NamespacedName {
395+ Namespace : obj .GetNamespace (),
396+ Name : string (ref .Name ),
397+ }
398+ if _ , ok := keys [key ]; ok {
399+ continue
400+ }
401+
402+ var httpRoute gatewayv1.HTTPRoute
403+ if err := r .Get (ctx , client.ObjectKey {Namespace : key .Namespace , Name : key .Name }, & httpRoute ); err != nil {
404+ r .Log .Error (err , "failed to get HTTPRoute by HTTPRoutePolicy targetRef" , "namespace" , key .Namespace , "name" , key .Name )
405+ continue
406+ }
407+ if ref .SectionName != nil {
408+ var matchRuleName bool
409+ for _ , rule := range httpRoute .Spec .Rules {
410+ if rule .Name != nil && * rule .Name == * ref .SectionName {
411+ matchRuleName = true
412+ break
413+ }
414+ }
415+ if ! matchRuleName {
416+ r .Log .Error (errors .Errorf ("failed to get HTTPRoute rule by HTTPRoutePolicy targetRef" ), "namespace" , key .Namespace , "name" , key .Name , "sectionName" , * ref .SectionName )
417+ continue
418+ }
419+ }
420+ keys [key ] = struct {}{}
421+ requests = append (requests , reconcile.Request {
422+ NamespacedName : types.NamespacedName {
423+ Namespace : key .Namespace ,
424+ Name : key .Name ,
425+ },
426+ })
427+ }
428+
429+ return requests
430+ }
431+
432+ func (r * HTTPRouteReconciler ) listHTTPRouteForGenericEvent (ctx context.Context , obj client.Object ) (requests []reconcile.Request ) {
433+ var namespacedNameMap = make (map [types.NamespacedName ]struct {})
434+
435+ switch v := obj .(type ) {
436+ case * v1alpha1.BackendTrafficPolicy :
437+ httprouteAll := []gatewayv1.HTTPRoute {}
438+ for _ , ref := range v .Spec .TargetRefs {
439+ httprouteList := & gatewayv1.HTTPRouteList {}
440+ if err := r .List (ctx , httprouteList , client.MatchingFields {
441+ indexer .ServiceIndexRef : indexer .GenIndexKey (v .GetNamespace (), string (ref .Name )),
442+ }); err != nil {
443+ r .Log .Error (err , "failed to list HTTPRoutes for BackendTrafficPolicy" , "namespace" , v .GetNamespace (), "ref" , ref .Name )
444+ return nil
445+ }
446+ httprouteAll = append (httprouteAll , httprouteList .Items ... )
447+ }
448+ for _ , hr := range httprouteAll {
449+ key := types.NamespacedName {
450+ Namespace : hr .Namespace ,
451+ Name : hr .Name ,
452+ }
453+ if _ , ok := namespacedNameMap [key ]; ! ok {
454+ namespacedNameMap [key ] = struct {}{}
455+ requests = append (requests , reconcile.Request {
456+ NamespacedName : client.ObjectKey {
457+ Namespace : hr .Namespace ,
458+ Name : hr .Name ,
459+ },
460+ })
461+ }
462+ }
463+ case * v1alpha1.HTTPRoutePolicy :
464+ for _ , ref := range v .Spec .TargetRefs {
465+ namespacedName := types.NamespacedName {Namespace : v .GetNamespace (), Name : string (ref .Name )}
466+ if _ , ok := namespacedNameMap [namespacedName ]; ! ok {
467+ namespacedNameMap [namespacedName ] = struct {}{}
468+ if err := r .Get (ctx , namespacedName , new (gatewayv1.HTTPRoute )); err != nil {
469+ r .Log .Info ("failed to Get HTTPRoute" , "namespace" , namespacedName .Namespace , "name" , namespacedName .Name )
470+ continue
471+ }
472+ requests = append (requests , reconcile.Request {NamespacedName : namespacedName })
473+ }
474+ }
475+ default :
476+ r .Log .Error (fmt .Errorf ("unexpected object type" ), "failed to convert object to BackendTrafficPolicy" )
477+ }
478+ return requests
479+ }
480+
395481func (r * HTTPRouteReconciler ) processHTTPRouteBackendRefs (tctx * provider.TranslateContext ) error {
396482 var terr error
397483 for _ , backend := range tctx .BackendRefs {
@@ -454,7 +540,7 @@ func (r *HTTPRouteReconciler) processHTTPRouteBackendRefs(tctx *provider.Transla
454540 return terr
455541}
456542
457- func (t * HTTPRouteReconciler ) processHTTPRoute (tctx * provider.TranslateContext , httpRoute * gatewayv1.HTTPRoute ) error {
543+ func (r * HTTPRouteReconciler ) processHTTPRoute (tctx * provider.TranslateContext , httpRoute * gatewayv1.HTTPRoute ) error {
458544 var terror error
459545 for _ , rule := range httpRoute .Spec .Rules {
460546 for _ , filter := range rule .Filters {
@@ -463,7 +549,7 @@ func (t *HTTPRouteReconciler) processHTTPRoute(tctx *provider.TranslateContext,
463549 }
464550 if filter .ExtensionRef .Kind == "PluginConfig" {
465551 pluginconfig := new (v1alpha1.PluginConfig )
466- if err := t .Get (context .Background (), client.ObjectKey {
552+ if err := r .Get (context .Background (), client.ObjectKey {
467553 Namespace : httpRoute .GetNamespace (),
468554 Name : string (filter .ExtensionRef .Name ),
469555 }, pluginconfig ); err != nil {
@@ -508,3 +594,29 @@ func (t *HTTPRouteReconciler) processHTTPRoute(tctx *provider.TranslateContext,
508594
509595 return terror
510596}
597+
598+ func (r * HTTPRouteReconciler ) httpRoutePolicyPredicateOnUpdate (e event.UpdateEvent ) bool {
599+ oldPolicy , ok0 := e .ObjectOld .(* v1alpha1.HTTPRoutePolicy )
600+ newPolicy , ok1 := e .ObjectNew .(* v1alpha1.HTTPRoutePolicy )
601+ if ! ok0 || ! ok1 {
602+ return false
603+ }
604+ var discardsRefs = make (map [string ]v1alpha2.LocalPolicyTargetReferenceWithSectionName )
605+ for _ , ref := range oldPolicy .Spec .TargetRefs {
606+ key := indexer .GenHTTPRoutePolicyIndexKey (string (ref .Group ), string (ref .Kind ), e .ObjectOld .GetNamespace (), string (ref .Name ), "" )
607+ discardsRefs [key ] = ref
608+ }
609+ for _ , ref := range newPolicy .Spec .TargetRefs {
610+ key := indexer .GenHTTPRoutePolicyIndexKey (string (ref .Group ), string (ref .Kind ), e .ObjectOld .GetNamespace (), string (ref .Name ), "" )
611+ delete (discardsRefs , key )
612+ }
613+ if len (discardsRefs ) > 0 {
614+ dump := oldPolicy .DeepCopy ()
615+ dump .Spec .TargetRefs = make ([]v1alpha2.LocalPolicyTargetReferenceWithSectionName , 0 , len (discardsRefs ))
616+ for _ , ref := range discardsRefs {
617+ dump .Spec .TargetRefs = append (dump .Spec .TargetRefs , ref )
618+ }
619+ r .genericEvent <- event.GenericEvent {Object : dump }
620+ }
621+ return true
622+ }
0 commit comments