Skip to content

Commit d56a253

Browse files
committed
Update HTTPRoutePolicy and Reconciler for Improved Handling
Remove unnecessary `kind` fields and list map keys in the HTTPRoutePolicy CRD. Add a new generic event channel and update predicates for more efficient event handling in the HTTPRouteReconciler.
1 parent 7752729 commit d56a253

File tree

4 files changed

+92
-22
lines changed

4 files changed

+92
-22
lines changed

api/v1alpha1/httproutepolicy_types.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ type HTTPRoutePolicySpec struct {
2727
// TargetRef identifies an API object (enum: HTTPRoute, Ingress) to apply HTTPRoutePolicy to.
2828
//
2929
// target references.
30-
// +listType=map
31-
// +listMapKey=group
32-
// +listMapKey=kind
33-
// +listMapKey=name
3430
// +kubebuilder:validation:MinItems=1
3531
// +kubebuilder:validation:MaxItems=16
3632
TargetRefs []gatewayv1alpha2.LocalPolicyTargetReferenceWithSectionName `json:"targetRefs"`

config/crd/bases/gateway.apisix.io_httproutepolicies.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,6 @@ spec:
104104
maxItems: 16
105105
minItems: 1
106106
type: array
107-
x-kubernetes-list-map-keys:
108-
- group
109-
- kind
110-
- name
111-
x-kubernetes-list-type: map
112107
vars:
113108
items:
114109
x-kubernetes-preserve-unknown-fields: true

internal/controller/httproute_controller.go

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
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.
3943
func (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+
74126
func (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+
303389
func (r *HTTPRouteReconciler) processHTTPRouteBackendRefs(tctx *provider.TranslateContext) error {
304390
var terr error
305391
for _, backend := range tctx.BackendRefs {

internal/controller/httproutepolicy.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ func (r *HTTPRouteReconciler) clearHTTPRoutePolicyRedundantAncestor(policy *v1al
8484
for _, ref := range policy.Spec.TargetRefs {
8585
key := ancestorRefKey{
8686
Group: ref.Group,
87-
Kind: ref.Kind,
8887
Namespace: gatewayv1.Namespace(policy.GetNamespace()),
8988
Name: ref.Name,
9089
}
@@ -103,9 +102,6 @@ func (r *HTTPRouteReconciler) clearHTTPRoutePolicyRedundantAncestor(policy *v1al
103102
if ancestor.AncestorRef.Group != nil {
104103
key.Group = *ancestor.AncestorRef.Group
105104
}
106-
if ancestor.AncestorRef.Kind != nil {
107-
key.Kind = *ancestor.AncestorRef.Kind
108-
}
109105
if ancestor.AncestorRef.SectionName != nil {
110106
key.SectionName = *ancestor.AncestorRef.SectionName
111107
}
@@ -129,7 +125,7 @@ func (r *HTTPRouteReconciler) modifyHTTPRoutePolicyStatus(key ancestorRefKey, po
129125
}
130126
var hasAncestor bool
131127
for i, ancestor := range policy.Status.Ancestors {
132-
if ancestor.AncestorRef.Kind != nil && *ancestor.AncestorRef.Kind == key.Kind && ancestor.AncestorRef.Name == key.Name {
128+
if ancestor.AncestorRef.Name == key.Name {
133129
ancestor.ControllerName = v1alpha2.GatewayController(config.GetControllerName())
134130
ancestor.Conditions = []metav1.Condition{condition}
135131
hasAncestor = true
@@ -139,7 +135,6 @@ func (r *HTTPRouteReconciler) modifyHTTPRoutePolicyStatus(key ancestorRefKey, po
139135
if !hasAncestor {
140136
ref := v1alpha2.ParentReference{
141137
Group: &key.Group,
142-
Kind: &key.Kind,
143138
Namespace: &key.Namespace,
144139
Name: key.Name,
145140
}
@@ -162,7 +157,6 @@ type conflictChecker struct {
162157

163158
type ancestorRefKey struct {
164159
Group gatewayv1.Group
165-
Kind gatewayv1.Kind
166160
Namespace gatewayv1.Namespace
167161
Name gatewayv1.ObjectName
168162
SectionName gatewayv1.SectionName
@@ -171,7 +165,6 @@ type ancestorRefKey struct {
171165
func (c *conflictChecker) append(sectionName string, policy v1alpha1.HTTPRoutePolicy) {
172166
key := ancestorRefKey{
173167
Group: gatewayv1.GroupName,
174-
Kind: "HTTPRoute",
175168
Namespace: gatewayv1.Namespace(c.httpRoute.GetNamespace()),
176169
Name: gatewayv1.ObjectName(c.httpRoute.GetName()),
177170
SectionName: gatewayv1.SectionName(sectionName),

0 commit comments

Comments
 (0)