Skip to content

Commit 93865fe

Browse files
ronethingAlinsRan
andauthored
chore: update status only when changes occur (#2473) (#208)
Co-authored-by: AlinsRan <[email protected]>
1 parent 0bccc2d commit 93865fe

File tree

9 files changed

+228
-70
lines changed

9 files changed

+228
-70
lines changed

internal/controller/consumer_controller.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package controller
1919

2020
import (
2121
"context"
22-
"fmt"
2322

2423
"github.com/go-logr/logr"
2524
corev1 "k8s.io/api/core/v1"
@@ -276,13 +275,9 @@ func (r *ConsumerReconciler) updateStatus(consumer *v1alpha1.Consumer, err error
276275
NamespacedName: utils.NamespacedName(consumer),
277276
Resource: consumer.DeepCopy(),
278277
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
279-
t, ok := obj.(*v1alpha1.Consumer)
280-
if !ok {
281-
err := fmt.Errorf("unsupported object type %T", obj)
282-
panic(err)
283-
}
284-
t.Status = consumer.Status
285-
return t
278+
cp := obj.(*v1alpha1.Consumer).DeepCopy()
279+
cp.Status = consumer.Status
280+
return cp
286281
}),
287282
})
288283
}

internal/controller/gatewayclass_controller.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,9 @@ func (r *GatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request
121121
NamespacedName: utils.NamespacedName(gc),
122122
Resource: gc.DeepCopy(),
123123
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
124-
t, ok := obj.(*gatewayv1.GatewayClass)
125-
if !ok {
126-
err := fmt.Errorf("unsupported object type %T", obj)
127-
panic(err)
128-
}
129-
t.Status = gc.Status
130-
return t
124+
cp := obj.(*gatewayv1.GatewayClass).DeepCopy()
125+
cp.Status = gc.Status
126+
return cp
131127
}),
132128
})
133129
}

internal/controller/httproutepolicy.go

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package controller
2020
import (
2121
"cmp"
2222
"context"
23-
"fmt"
2423
"slices"
2524

2625
networkingv1 "k8s.io/api/networking/v1"
@@ -92,13 +91,9 @@ func (r *HTTPRouteReconciler) processHTTPRoutePolicies(tctx *provider.TranslateC
9291
NamespacedName: utils.NamespacedName(&policy),
9392
Resource: policy.DeepCopy(),
9493
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
95-
t, ok := obj.(*v1alpha1.HTTPRoutePolicy)
96-
if !ok {
97-
err := fmt.Errorf("unsupported object type %T", obj)
98-
panic(err)
99-
}
100-
t.Status = policy.Status
101-
return t
94+
cp := obj.(*v1alpha1.HTTPRoutePolicy).DeepCopy()
95+
cp.Status = policy.Status
96+
return cp
10297
}),
10398
})
10499
}
@@ -170,13 +165,9 @@ func (r *IngressReconciler) processHTTPRoutePolicies(tctx *provider.TranslateCon
170165
NamespacedName: utils.NamespacedName(&policy),
171166
Resource: policy.DeepCopy(),
172167
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
173-
t, ok := obj.(*v1alpha1.HTTPRoutePolicy)
174-
if !ok {
175-
err := fmt.Errorf("unsupported object type %T", obj)
176-
panic(err)
177-
}
178-
t.Status = policy.Status
179-
return t
168+
cp := obj.(*v1alpha1.HTTPRoutePolicy).DeepCopy()
169+
cp.Status = policy.Status
170+
return cp
180171
}),
181172
})
182173
}
@@ -282,13 +273,9 @@ func updateDeleteAncestors(updater status.Updater, policy v1alpha1.HTTPRoutePoli
282273
NamespacedName: utils.NamespacedName(&policy),
283274
Resource: policy.DeepCopy(),
284275
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
285-
t, ok := obj.(*v1alpha1.HTTPRoutePolicy)
286-
if !ok {
287-
err := fmt.Errorf("unsupported object type %T", obj)
288-
panic(err)
289-
}
290-
t.Status = policy.Status
291-
return t
276+
cp := obj.(*v1alpha1.HTTPRoutePolicy).DeepCopy()
277+
cp.Status = policy.Status
278+
return cp
292279
}),
293280
})
294281
}

internal/controller/ingress_controller.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -639,13 +639,9 @@ func (r *IngressReconciler) updateStatus(ctx context.Context, tctx *provider.Tra
639639
NamespacedName: utils.NamespacedName(ingress),
640640
Resource: ingress.DeepCopy(),
641641
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
642-
t, ok := obj.(*networkingv1.Ingress)
643-
if !ok {
644-
err := fmt.Errorf("unsupported object type %T", obj)
645-
panic(err)
646-
}
647-
t.Status = ingress.Status
648-
return t
642+
cp := obj.(*networkingv1.Ingress).DeepCopy()
643+
cp.Status = ingress.Status
644+
return cp
649645
}),
650646
})
651647
return nil

internal/controller/policies.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,9 @@ func ProcessBackendTrafficPolicy(
158158
NamespacedName: utils.NamespacedName(policy),
159159
Resource: policy.DeepCopy(),
160160
Mutator: status.MutatorFunc(func(obj client.Object) client.Object {
161-
t, ok := obj.(*v1alpha1.BackendTrafficPolicy)
162-
if !ok {
163-
err := fmt.Errorf("unsupported object type %T", obj)
164-
panic(err)
165-
}
166-
t.Status = policy.Status
167-
return t
161+
cp := obj.(*v1alpha1.BackendTrafficPolicy).DeepCopy()
162+
cp.Status = policy.Status
163+
return cp
168164
}),
169165
})
170166
}

internal/controller/status/updater.go

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,25 @@ import (
2222
"sync"
2323

2424
"github.com/go-logr/logr"
25+
"github.com/google/go-cmp/cmp"
26+
"github.com/google/go-cmp/cmp/cmpopts"
2527
k8serrors "k8s.io/apimachinery/pkg/api/errors"
26-
"k8s.io/apimachinery/pkg/types"
28+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29+
k8stypes "k8s.io/apimachinery/pkg/types"
2730
"k8s.io/client-go/util/retry"
2831
"sigs.k8s.io/controller-runtime/pkg/client"
32+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
2933

34+
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
35+
v2 "github.com/apache/apisix-ingress-controller/api/v2"
36+
types "github.com/apache/apisix-ingress-controller/internal/types"
3037
pkgmetrics "github.com/apache/apisix-ingress-controller/pkg/metrics"
3138
)
3239

3340
const UpdateChannelBufferSize = 1000
3441

3542
type Update struct {
36-
NamespacedName types.NamespacedName
43+
NamespacedName k8stypes.NamespacedName
3744
Resource client.Object
3845
Mutator Mutator
3946
}
@@ -52,6 +59,13 @@ func (m MutatorFunc) Mutate(obj client.Object) client.Object {
5259
return m(obj)
5360
}
5461

62+
var cmpIgnoreLastTT = cmp.Options{
63+
cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
64+
cmpopts.IgnoreMapEntries(func(k string, _ any) bool {
65+
return k == "lastTransitionTime"
66+
}),
67+
}
68+
5569
type UpdateHandler struct {
5670
log logr.Logger
5771
client client.Client
@@ -96,8 +110,20 @@ func (u *UpdateHandler) updateStatus(ctx context.Context, update Update) error {
96110
return nil
97111
}
98112

113+
if statusEqual(obj, newObj, cmpIgnoreLastTT) {
114+
u.log.V(1).Info("status is equal, skipping update", "name", update.NamespacedName.Name,
115+
"namespace", update.NamespacedName.Namespace,
116+
"kind", types.KindOf(obj))
117+
return nil
118+
}
119+
99120
newObj.SetUID(obj.GetUID())
100121

122+
u.log.Info("updating status", "name", update.NamespacedName.Name,
123+
"namespace", update.NamespacedName.Namespace,
124+
"kind", types.KindOf(newObj),
125+
)
126+
101127
return u.client.Status().Update(ctx, newObj)
102128
}
103129

@@ -114,8 +140,10 @@ func (u *UpdateHandler) Start(ctx context.Context) error {
114140
case update := <-u.updateChannel:
115141
// Decrement queue length after removing item from queue
116142
pkgmetrics.DecStatusQueueLength()
117-
u.log.Info("received a status update", "namespace", update.NamespacedName.Namespace,
118-
"name", update.NamespacedName.Name)
143+
u.log.V(1).Info("received a status update", "namespace", update.NamespacedName.Namespace,
144+
"name", update.NamespacedName.Name,
145+
"kind", types.KindOf(update.Resource),
146+
)
119147

120148
u.apply(ctx, update)
121149
}
@@ -144,3 +172,82 @@ func (u *UpdateWriter) Update(update Update) {
144172
// Increment queue length after adding new item
145173
pkgmetrics.IncStatusQueueLength()
146174
}
175+
176+
func statusEqual(a, b any, opts ...cmp.Option) bool {
177+
var statusA, statusB any
178+
179+
switch a := a.(type) {
180+
case *gatewayv1.GatewayClass:
181+
b, ok := b.(*gatewayv1.GatewayClass)
182+
if !ok {
183+
return false
184+
}
185+
statusA, statusB = a.Status, b.Status
186+
187+
case *gatewayv1.Gateway:
188+
b, ok := b.(*gatewayv1.Gateway)
189+
if !ok {
190+
return false
191+
}
192+
statusA, statusB = a.Status, b.Status
193+
194+
case *gatewayv1.HTTPRoute:
195+
b, ok := b.(*gatewayv1.HTTPRoute)
196+
if !ok {
197+
return false
198+
}
199+
statusA, statusB = a.Status, b.Status
200+
case *v2.ApisixRoute:
201+
b, ok := b.(*v2.ApisixRoute)
202+
if !ok {
203+
return false
204+
}
205+
statusA, statusB = a.Status, b.Status
206+
case *v2.ApisixGlobalRule:
207+
b, ok := b.(*v2.ApisixGlobalRule)
208+
if !ok {
209+
return false
210+
}
211+
statusA, statusB = a.Status, b.Status
212+
case *v2.ApisixPluginConfig:
213+
b, ok := b.(*v2.ApisixPluginConfig)
214+
if !ok {
215+
return false
216+
}
217+
statusA, statusB = a.Status, b.Status
218+
case *v2.ApisixTls:
219+
b, ok := b.(*v2.ApisixTls)
220+
if !ok {
221+
return false
222+
}
223+
statusA, statusB = a.Status, b.Status
224+
case *v2.ApisixConsumer:
225+
b, ok := b.(*v2.ApisixConsumer)
226+
if !ok {
227+
return false
228+
}
229+
statusA, statusB = a.Status, b.Status
230+
case *v1alpha1.HTTPRoutePolicy:
231+
b, ok := b.(*v1alpha1.HTTPRoutePolicy)
232+
if !ok {
233+
return false
234+
}
235+
statusA, statusB = a.Status, b.Status
236+
case *v1alpha1.BackendTrafficPolicy:
237+
b, ok := b.(*v1alpha1.BackendTrafficPolicy)
238+
if !ok {
239+
return false
240+
}
241+
statusA, statusB = a.Status, b.Status
242+
case *v1alpha1.Consumer:
243+
b, ok := b.(*v1alpha1.Consumer)
244+
if !ok {
245+
return false
246+
}
247+
statusA, statusB = a.Status, b.Status
248+
default:
249+
return false
250+
}
251+
252+
return cmp.Equal(statusA, statusB, opts...)
253+
}

internal/provider/adc/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ func (d *adcClient) updateConfigForGatewayProxy(tctx *provider.TranslateContext,
207207
for _, ref := range referrers {
208208
d.configs[ref] = *config
209209
}
210-
211210
return nil
212211
}
213212

internal/types/k8s.go

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,76 @@
1717

1818
package types
1919

20+
import (
21+
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
22+
v2 "github.com/apache/apisix-ingress-controller/api/v2"
23+
corev1 "k8s.io/api/core/v1"
24+
v1 "k8s.io/api/networking/v1"
25+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
26+
)
27+
2028
const DefaultIngressClassAnnotation = "ingressclass.kubernetes.io/is-default-class"
2129

2230
const (
23-
KindGateway = "Gateway"
24-
KindHTTPRoute = "HTTPRoute"
25-
KindGatewayClass = "GatewayClass"
26-
KindIngress = "Ingress"
27-
KindIngressClass = "IngressClass"
28-
KindGatewayProxy = "GatewayProxy"
29-
KindSecret = "Secret"
30-
KindService = "Service"
31-
KindApisixRoute = "ApisixRoute"
32-
KindApisixGlobalRule = "ApisixGlobalRule"
33-
KindApisixPluginConfig = "ApisixPluginConfig"
34-
KindPod = "Pod"
35-
KindApisixTls = "ApisixTls"
36-
KindApisixConsumer = "ApisixConsumer"
31+
KindGateway = "Gateway"
32+
KindHTTPRoute = "HTTPRoute"
33+
KindGatewayClass = "GatewayClass"
34+
KindIngress = "Ingress"
35+
KindIngressClass = "IngressClass"
36+
KindGatewayProxy = "GatewayProxy"
37+
KindSecret = "Secret"
38+
KindService = "Service"
39+
KindApisixRoute = "ApisixRoute"
40+
KindApisixGlobalRule = "ApisixGlobalRule"
41+
KindApisixPluginConfig = "ApisixPluginConfig"
42+
KindPod = "Pod"
43+
KindApisixTls = "ApisixTls"
44+
KindApisixConsumer = "ApisixConsumer"
45+
KindHTTPRoutePolicy = "HTTPRoutePolicy"
46+
KindBackendTrafficPolicy = "BackendTrafficPolicy"
47+
KindConsumer = "Consumer"
48+
KindPluginConfig = "PluginConfig"
3749
)
50+
51+
func KindOf(obj any) string {
52+
switch obj.(type) {
53+
case *gatewayv1.Gateway:
54+
return KindGateway
55+
case *gatewayv1.HTTPRoute:
56+
return KindHTTPRoute
57+
case *gatewayv1.GatewayClass:
58+
return KindGatewayClass
59+
case *v1.Ingress:
60+
return KindIngress
61+
case *v1.IngressClass:
62+
return KindIngressClass
63+
case *corev1.Secret:
64+
return KindSecret
65+
case *corev1.Service:
66+
return KindService
67+
case *v2.ApisixRoute:
68+
return KindApisixRoute
69+
case *v2.ApisixGlobalRule:
70+
return KindApisixGlobalRule
71+
case *v2.ApisixPluginConfig:
72+
return KindApisixPluginConfig
73+
case *corev1.Pod:
74+
return KindPod
75+
case *v2.ApisixTls:
76+
return KindApisixTls
77+
case *v2.ApisixConsumer:
78+
return KindApisixConsumer
79+
case *v1alpha1.HTTPRoutePolicy:
80+
return KindHTTPRoutePolicy
81+
case *v1alpha1.BackendTrafficPolicy:
82+
return KindBackendTrafficPolicy
83+
case *v1alpha1.GatewayProxy:
84+
return KindGatewayProxy
85+
case *v1alpha1.Consumer:
86+
return KindConsumer
87+
case *v1alpha1.PluginConfig:
88+
return KindPluginConfig
89+
default:
90+
return "Unknown"
91+
}
92+
}

0 commit comments

Comments
 (0)