@@ -9,63 +9,74 @@ import (
99
1010 "github.com/argoproj-labs/argocd-operator/common"
1111 "github.com/argoproj-labs/argocd-operator/pkg/cacheutils"
12+ logf "sigs.k8s.io/controller-runtime/pkg/log"
1213)
1314
15+ var log = logf .Log .WithName ("clientwrapper" )
16+
1417// ClientWrapper wraps a cached client and only falls back to
1518// live GET when the cached object appears stripped OR is missing required labels.
19+ // We currently override GET only, but could extend to other methods if needed.
1620type ClientWrapper struct {
1721 ctrlclient.Client // cached client
1822 liveClient ctrlclient.Client // direct API client
1923}
2024
25+ // NewClientWrapper creates a new ClientWrapper instance.
2126func NewClientWrapper (cached , live ctrlclient.Client ) * ClientWrapper {
2227 return & ClientWrapper {
2328 Client : cached ,
2429 liveClient : live ,
2530 }
2631}
2732
33+ // Get first tries to get from the cached client, and only falls back to live GET
34+ // if the cached object appears stripped or is missing required labels.
35+ // After a live GET, it also ensures the object has the tracking label (best-effort).
2836func (cw * ClientWrapper ) Get (ctx context.Context , key types.NamespacedName , obj ctrlclient.Object , opts ... ctrlclient.GetOption ) error {
29- // 1) Cache read (no live fallback here on error)
37+
3038 if err := cw .Client .Get (ctx , key , obj , opts ... ); err != nil {
3139 return err
3240 }
3341
34- // 2) Post-read check: only specific kinds may need live refresh
3542 switch o := obj .(type ) {
3643 case * corev1.Secret :
3744 if secretNeedsLiveRefresh (o ) {
38- // Re-fetch from live to get the full object
45+
3946 if err := cw .liveClient .Get (ctx , key , obj , opts ... ); err != nil {
4047 return err
4148 }
42- // Ensure it becomes tracked for future full-caching (best-effort)
49+
4350 cw .ensureTrackedLabel (ctx , obj )
4451 }
52+
4553 case * corev1.ConfigMap :
4654 if configmapNeedsLiveRefresh (o ) {
47- // Re-fetch from live to get the full object
55+
4856 if err := cw .liveClient .Get (ctx , key , obj , opts ... ); err != nil {
4957 return err
5058 }
51- // Ensure it becomes tracked for future full-caching (best-effort)
59+
5260 cw .ensureTrackedLabel (ctx , obj )
5361 }
5462
55- // add more kinds here (e.g., *corev1.ConfigMap) if you apply similar striping
63+ // add more kinds here (e.g., *corev1.Deployment) if applying similar striping
64+
5665 }
5766
5867 return nil
5968}
6069
6170// secretNeedsLiveRefresh returns true if the cached secret looks stripped or untracked.
6271func secretNeedsLiveRefresh (s * corev1.Secret ) bool {
63- // Untracked → we likely cached a slimmed object; refresh live.
72+
6473 if ! cacheutils .IsTrackedByOperator (s .GetLabels ()) {
6574 return true
6675 }
67- // Heuristic: a "slimmed" secret from our transform has nil Data/StringData.
68- // (Note: a legitimately empty secret may also match; adjust if you add a marker label/annotation.)
76+
77+ // Heuristic: a "stripped" Secret from our transform has nil Data/StringData.
78+ // A truly empty Secret may also match, but that only triggers an extra live GET,
79+ // which is rare and acceptable.
6980 if s .Data == nil && s .StringData == nil {
7081 return true
7182 }
@@ -77,13 +88,17 @@ func configmapNeedsLiveRefresh(cm *corev1.ConfigMap) bool {
7788 if ! cacheutils .IsTrackedByOperator (cm .GetLabels ()) {
7889 return true
7990 }
91+
92+ // Heuristic: a "stripped" ConfigMap from our transform has nil Data/BinaryData.
93+ // A truly empty ConfigMap may also match, but that only triggers an extra live GET,
94+ // which is rare and acceptable.
8095 if cm .Data == nil && cm .BinaryData == nil {
8196 return true
8297 }
8398 return false
8499}
85100
86- // ensureTrackedLabel adds the operator tracking label (best-effort, ignores patch error) .
101+ // ensureTrackedLabel adds the operator tracking label.
87102func (cw * ClientWrapper ) ensureTrackedLabel (ctx context.Context , obj ctrlclient.Object ) {
88103 if cacheutils .IsTrackedByOperator (obj .GetLabels ()) {
89104 return
@@ -97,5 +112,10 @@ func (cw *ClientWrapper) ensureTrackedLabel(ctx context.Context, obj ctrlclient.
97112 labels [common .ArgoCDTrackedByOperatorLabel ] = common .ArgoCDAppName
98113 obj .SetLabels (labels )
99114
100- _ = cw .liveClient .Patch (ctx , obj , ctrlclient .MergeFrom (orig )) // best-effort
115+ // Best-effort patch to add the operator tracking label.
116+ // Non-fatal: a later reconcile will reattempt if this fails.
117+ err := cw .liveClient .Patch (ctx , obj , ctrlclient .MergeFrom (orig ))
118+ if err != nil {
119+ log .Error (err , "failed to add operator tracking label to object" , "name" , obj .GetName (), "namespace" , obj .GetNamespace ())
120+ }
101121}
0 commit comments