Skip to content

Commit 353eb96

Browse files
committed
chore: add secrets cache
Signed-off-by: Armando Ruocco <[email protected]>
1 parent 5d0038e commit 353eb96

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

internal/client/client.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"sync"
6+
"time"
7+
8+
corev1 "k8s.io/api/core/v1"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
)
11+
12+
type cachedSecret struct {
13+
secret *corev1.Secret
14+
fetchUnixTime int64
15+
}
16+
17+
type extendedClient struct {
18+
client.Client
19+
cachedSecrets []*cachedSecret
20+
// add a mux to lock the operations on the cache
21+
mux *sync.Mutex
22+
}
23+
24+
// NewExtendedClient returns an extended client capable of caching secrets on the 'Get' operation
25+
func NewExtendedClient(baseClient client.Client) client.Client {
26+
return &extendedClient{
27+
Client: baseClient,
28+
}
29+
}
30+
31+
func (e *extendedClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
32+
// if not secret use the get from the base client
33+
if _, ok := obj.(*corev1.Secret); !ok {
34+
return e.Client.Get(ctx, key, obj, opts...)
35+
}
36+
37+
// grab the lock if we get here
38+
e.mux.Lock()
39+
defer e.mux.Unlock()
40+
// check if in cache
41+
for _, cache := range e.cachedSecrets {
42+
if cache.secret.Namespace == key.Namespace && cache.secret.Name == key.Name {
43+
if time.Now().Unix()-cache.fetchUnixTime < 180 {
44+
cache.secret.DeepCopyInto(obj.(*corev1.Secret))
45+
return nil
46+
}
47+
break
48+
}
49+
}
50+
51+
if err := e.Client.Get(ctx, key, obj); err != nil {
52+
return err
53+
}
54+
55+
// check if the secret is already in cache if so replace it
56+
for _, cache := range e.cachedSecrets {
57+
if cache.secret.Namespace == key.Namespace && cache.secret.Name == key.Name {
58+
cache.secret = obj.(*corev1.Secret)
59+
cache.fetchUnixTime = time.Now().Unix()
60+
return nil
61+
}
62+
}
63+
64+
if secret, ok := obj.(*corev1.Secret); ok {
65+
e.cachedSecrets = append(e.cachedSecrets, &cachedSecret{
66+
secret: secret,
67+
fetchUnixTime: time.Now().Unix(),
68+
})
69+
}
70+
// unlock
71+
e.mux.Unlock()
72+
73+
return nil
74+
}

internal/client/doc.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Package client provides an extended client that is capable of caching multiple secrets without relying on
2+
// 'list and watch'
3+
package client

0 commit comments

Comments
 (0)