Skip to content

Commit f1adb78

Browse files
committed
WIP
Signed-off-by: Siddhesh Ghadi <sghadi1203@gmail.com>
1 parent 34b24f2 commit f1adb78

File tree

4 files changed

+183
-3
lines changed

4 files changed

+183
-3
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ COPY cmd/main.go cmd/main.go
1414
COPY api/ api/
1515
COPY common/ common/
1616
COPY controllers/ controllers/
17+
COPY pkg/ pkg/
1718
COPY version/ version/
1819

1920
# Build

cmd/main.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
3131
"k8s.io/client-go/kubernetes"
3232
"sigs.k8s.io/controller-runtime/pkg/cache"
33+
crclient "sigs.k8s.io/controller-runtime/pkg/client"
3334
"sigs.k8s.io/controller-runtime/pkg/client/config"
3435
"sigs.k8s.io/controller-runtime/pkg/manager"
3536
"sigs.k8s.io/controller-runtime/pkg/webhook"
@@ -56,8 +57,12 @@ import (
5657
"sigs.k8s.io/controller-runtime/pkg/healthz"
5758
"sigs.k8s.io/controller-runtime/pkg/log/zap"
5859

60+
corev1 "k8s.io/api/core/v1"
61+
5962
v1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1"
6063
v1beta1 "github.com/argoproj-labs/argocd-operator/api/v1beta1"
64+
"github.com/argoproj-labs/argocd-operator/pkg/cacheutils"
65+
wc "github.com/argoproj-labs/argocd-operator/pkg/clientwrapper"
6166
"github.com/argoproj-labs/argocd-operator/version"
6267
//+kubebuilder:scaffold:imports
6368
)
@@ -179,6 +184,13 @@ func main() {
179184
Controller: controllerconfig.Controller{
180185
SkipNameValidation: &skipControllerNameValidation,
181186
},
187+
Cache: cache.Options{
188+
Scheme: scheme,
189+
ByObject: map[crclient.Object]cache.ByObject{
190+
&corev1.Secret{}: {Transform: cacheutils.StripSecretDataTranform()},
191+
&corev1.ConfigMap{}: {Transform: cacheutils.StripConfigMapDataTransform()},
192+
},
193+
},
182194
}
183195

184196
if watchedNsCache := getDefaultWatchedNamespacesCacheOptions(); watchedNsCache != nil {
@@ -193,6 +205,10 @@ func main() {
193205
os.Exit(1)
194206
}
195207

208+
liveClient, _ := crclient.New(ctrl.GetConfigOrDie(), crclient.Options{Scheme: mgr.GetScheme()})
209+
client := wc.NewClientWrapper(mgr.GetClient(), liveClient)
210+
//print(client)
211+
196212
setupLog.Info("Registering Components.")
197213

198214
// Setup Scheme for all resources
@@ -236,7 +252,7 @@ func main() {
236252
os.Exit(1)
237253
}
238254
if err = (&argocd.ReconcileArgoCD{
239-
Client: mgr.GetClient(),
255+
Client: client,
240256
Scheme: mgr.GetScheme(),
241257
LabelSelector: labelSelectorFlag,
242258
K8sClient: k8sClient,
@@ -248,14 +264,14 @@ func main() {
248264
os.Exit(1)
249265
}
250266
if err = (&argocdexport.ReconcileArgoCDExport{
251-
Client: mgr.GetClient(),
267+
Client: client,
252268
Scheme: mgr.GetScheme(),
253269
}).SetupWithManager(mgr); err != nil {
254270
setupLog.Error(err, "unable to create controller", "controller", "ArgoCDExport")
255271
os.Exit(1)
256272
}
257273
if err = (&notificationsConfig.NotificationsConfigurationReconciler{
258-
Client: mgr.GetClient(),
274+
Client: client,
259275
Scheme: mgr.GetScheme(),
260276
}).SetupWithManager(mgr); err != nil {
261277
setupLog.Error(err, "unable to create controller", "controller", "NotificationsConfiguration")

pkg/cacheutils/utlis.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package cacheutils
2+
3+
import (
4+
v1 "k8s.io/api/core/v1"
5+
clientgotools "k8s.io/client-go/tools/cache"
6+
7+
"github.com/argoproj-labs/argocd-operator/common"
8+
)
9+
10+
func StripSecretDataTranform() clientgotools.TransformFunc {
11+
return func(in interface{}) (interface{}, error) {
12+
if s, ok := in.(*v1.Secret); ok {
13+
if IsTrackedByOperator(s.Labels) {
14+
// Keep full secret
15+
return in, nil
16+
}
17+
// Strip data for non-operator secrets
18+
return &v1.Secret{
19+
TypeMeta: s.TypeMeta,
20+
ObjectMeta: s.ObjectMeta,
21+
Type: s.Type,
22+
Immutable: s.Immutable,
23+
Data: nil,
24+
StringData: nil,
25+
}, nil
26+
}
27+
return in, nil
28+
}
29+
}
30+
31+
func StripConfigMapDataTransform() clientgotools.TransformFunc {
32+
return func(in interface{}) (interface{}, error) {
33+
if cm, ok := in.(*v1.ConfigMap); ok {
34+
if IsTrackedByOperator(cm.Labels) {
35+
// Keep full configmap
36+
return in, nil
37+
}
38+
// Strip data for non-operator configmaps
39+
return &v1.ConfigMap{
40+
TypeMeta: cm.TypeMeta,
41+
ObjectMeta: cm.ObjectMeta,
42+
Data: nil,
43+
BinaryData: nil,
44+
}, nil
45+
}
46+
return in, nil
47+
}
48+
}
49+
50+
func IsTrackedByOperator(labels map[string]string) bool {
51+
trackedLabels := []string{
52+
common.ArgoCDTrackedByOperatorLabel,
53+
common.ArgoCDSecretTypeLabel,
54+
}
55+
56+
for _, l := range trackedLabels {
57+
if _, exists := labels[l]; exists {
58+
return true
59+
}
60+
}
61+
return false
62+
}

pkg/clientwrapper/client.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package clientwrapper
2+
3+
import (
4+
"context"
5+
6+
corev1 "k8s.io/api/core/v1"
7+
"k8s.io/apimachinery/pkg/types"
8+
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
9+
10+
"github.com/argoproj-labs/argocd-operator/common"
11+
"github.com/argoproj-labs/argocd-operator/pkg/cacheutils"
12+
)
13+
14+
// ClientWrapper wraps a cached client and only falls back to
15+
// live GET when the cached object appears stripped OR is missing required labels.
16+
type ClientWrapper struct {
17+
ctrlclient.Client // cached client
18+
liveClient ctrlclient.Client // direct API client
19+
}
20+
21+
func NewClientWrapper(cached, live ctrlclient.Client) *ClientWrapper {
22+
return &ClientWrapper{
23+
Client: cached,
24+
liveClient: live,
25+
}
26+
}
27+
28+
func (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)
30+
if err := cw.Client.Get(ctx, key, obj, opts...); err != nil {
31+
return err
32+
}
33+
34+
// 2) Post-read check: only specific kinds may need live refresh
35+
switch o := obj.(type) {
36+
case *corev1.Secret:
37+
if secretNeedsLiveRefresh(o) {
38+
// Re-fetch from live to get the full object
39+
if err := cw.liveClient.Get(ctx, key, obj, opts...); err != nil {
40+
return err
41+
}
42+
// Ensure it becomes tracked for future full-caching (best-effort)
43+
cw.ensureTrackedLabel(ctx, obj)
44+
}
45+
case *corev1.ConfigMap:
46+
if configmapNeedsLiveRefresh(o) {
47+
// Re-fetch from live to get the full object
48+
if err := cw.liveClient.Get(ctx, key, obj, opts...); err != nil {
49+
return err
50+
}
51+
// Ensure it becomes tracked for future full-caching (best-effort)
52+
cw.ensureTrackedLabel(ctx, obj)
53+
}
54+
55+
// add more kinds here (e.g., *corev1.ConfigMap) if you apply similar striping
56+
}
57+
58+
return nil
59+
}
60+
61+
// secretNeedsLiveRefresh returns true if the cached secret looks stripped or untracked.
62+
func secretNeedsLiveRefresh(s *corev1.Secret) bool {
63+
// Untracked → we likely cached a slimmed object; refresh live.
64+
if !cacheutils.IsTrackedByOperator(s.GetLabels()) {
65+
return true
66+
}
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.)
69+
if s.Data == nil && s.StringData == nil {
70+
return true
71+
}
72+
return false
73+
}
74+
75+
// configmapNeedsLiveRefresh returns true if the cached cm looks stripped or untracked.
76+
func configmapNeedsLiveRefresh(cm *corev1.ConfigMap) bool {
77+
if !cacheutils.IsTrackedByOperator(cm.GetLabels()) {
78+
return true
79+
}
80+
if cm.Data == nil && cm.BinaryData == nil {
81+
return true
82+
}
83+
return false
84+
}
85+
86+
// ensureTrackedLabel adds the operator tracking label (best-effort, ignores patch error).
87+
func (cw *ClientWrapper) ensureTrackedLabel(ctx context.Context, obj ctrlclient.Object) {
88+
if cacheutils.IsTrackedByOperator(obj.GetLabels()) {
89+
return
90+
}
91+
orig := obj.DeepCopyObject().(ctrlclient.Object)
92+
93+
labels := obj.GetLabels()
94+
if labels == nil {
95+
labels = make(map[string]string, 1)
96+
}
97+
labels[common.ArgoCDTrackedByOperatorLabel] = common.ArgoCDAppName
98+
obj.SetLabels(labels)
99+
100+
_ = cw.liveClient.Patch(ctx, obj, ctrlclient.MergeFrom(orig)) // best-effort
101+
}

0 commit comments

Comments
 (0)