Skip to content

Commit 5757c1c

Browse files
authored
[release-1.10] šŸ› Improve client cert/key rotation of the RuntimeSDK client (#13215)
* Improve client cert/key rotation of the RuntimeSDK client * Drop usage of t.Context() as it requires go1.24 Signed-off-by: Stefan Büringer buringerst@vmware.com --------- Signed-off-by: Stefan Büringer buringerst@vmware.com
1 parent c9f6f61 commit 5757c1c

File tree

7 files changed

+243
-36
lines changed

7 files changed

+243
-36
lines changed

ā€Žexp/runtime/internal/controllers/extensionconfig_controller_test.goā€Ž

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ func TestExtensionReconciler_Reconcile(t *testing.T) {
6161
g.Expect(fakev1alpha1.AddToCatalog(cat)).To(Succeed())
6262

6363
registry := runtimeregistry.New()
64-
runtimeClient := internalruntimeclient.New(internalruntimeclient.Options{
64+
runtimeClient, _, err := internalruntimeclient.New(internalruntimeclient.Options{
6565
Catalog: cat,
6666
Registry: registry,
6767
})
68+
g.Expect(err).ToNot(HaveOccurred())
6869

6970
g.Expect(runtimehooksv1.AddToCatalog(cat)).To(Succeed())
7071

@@ -241,10 +242,11 @@ func TestExtensionReconciler_discoverExtensionConfig(t *testing.T) {
241242
g.Expect(err).ToNot(HaveOccurred())
242243
defer srv1.Close()
243244

244-
runtimeClient := internalruntimeclient.New(internalruntimeclient.Options{
245+
runtimeClient, _, err := internalruntimeclient.New(internalruntimeclient.Options{
245246
Catalog: cat,
246247
Registry: registry,
247248
})
249+
g.Expect(err).ToNot(HaveOccurred())
248250

249251
extensionConfig := fakeExtensionConfigForURL(ns.Name, extensionName, srv1.URL)
250252
extensionConfig.Spec.ClientConfig.CABundle = testcerts.CACert
@@ -281,10 +283,11 @@ func TestExtensionReconciler_discoverExtensionConfig(t *testing.T) {
281283
// srv1 := fakeSecureExtensionServer(discoveryHandler("first"))
282284
// defer srv1.Close()
283285

284-
runtimeClient := internalruntimeclient.New(internalruntimeclient.Options{
286+
runtimeClient, _, err := internalruntimeclient.New(internalruntimeclient.Options{
285287
Catalog: cat,
286288
Registry: registry,
287289
})
290+
g.Expect(err).ToNot(HaveOccurred())
288291

289292
extensionConfig := fakeExtensionConfigForURL(ns.Name, extensionName, "https://localhost:31239")
290293
extensionConfig.Spec.ClientConfig.CABundle = testcerts.CACert

ā€Žexp/runtime/internal/controllers/warmup_test.goā€Ž

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ func Test_warmupRunnable_Start(t *testing.T) {
7272
}(ns.Name, name, server.URL)
7373
}
7474

75+
runtimeClient, _, err := internalruntimeclient.New(internalruntimeclient.Options{
76+
Catalog: cat,
77+
Registry: registry,
78+
})
79+
g.Expect(err).ToNot(HaveOccurred())
7580
r := &warmupRunnable{
76-
Client: env.GetClient(),
77-
APIReader: env.GetAPIReader(),
78-
RuntimeClient: internalruntimeclient.New(internalruntimeclient.Options{
79-
Catalog: cat,
80-
Registry: registry,
81-
}),
81+
Client: env.GetClient(),
82+
APIReader: env.GetAPIReader(),
83+
RuntimeClient: runtimeClient,
8284
}
8385

8486
if err := r.Start(ctx); err != nil {
@@ -137,13 +139,15 @@ func Test_warmupRunnable_Start(t *testing.T) {
137139
g.Expect(env.CreateAndWait(ctx, extensionConfig)).To(Succeed())
138140
}
139141

142+
runtimeClient, _, err := internalruntimeclient.New(internalruntimeclient.Options{
143+
Catalog: cat,
144+
Registry: registry,
145+
})
146+
g.Expect(err).ToNot(HaveOccurred())
140147
r := &warmupRunnable{
141-
Client: env.GetClient(),
142-
APIReader: env.GetAPIReader(),
143-
RuntimeClient: internalruntimeclient.New(internalruntimeclient.Options{
144-
Catalog: cat,
145-
Registry: registry,
146-
}),
148+
Client: env.GetClient(),
149+
APIReader: env.GetAPIReader(),
150+
RuntimeClient: runtimeClient,
147151
warmupInterval: 500 * time.Millisecond,
148152
warmupTimeout: 5 * time.Second,
149153
}

ā€Žinternal/runtime/client/client.goā€Ž

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package client
2020
import (
2121
"bytes"
2222
"context"
23+
"crypto/tls"
2324
"encoding/json"
2425
"fmt"
2526
"io"
@@ -43,6 +44,7 @@ import (
4344
"k8s.io/client-go/transport"
4445
"k8s.io/utils/ptr"
4546
ctrl "sigs.k8s.io/controller-runtime"
47+
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
4648
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
4749

4850
runtimev1 "sigs.k8s.io/cluster-api/exp/runtime/api/v1alpha1"
@@ -69,15 +71,28 @@ type Options struct {
6971
}
7072

7173
// New returns a new Client.
72-
func New(options Options) runtimeclient.Client {
74+
func New(options Options) (runtimeclient.Client, *certwatcher.CertWatcher, error) {
75+
httpClientCache := cache.New[httpClientEntry](24 * time.Hour)
76+
77+
var certWatcher *certwatcher.CertWatcher
78+
if options.CertFile != "" && options.KeyFile != "" {
79+
var err error
80+
certWatcher, err = certwatcher.New(options.CertFile, options.KeyFile)
81+
if err != nil {
82+
return nil, nil, errors.Wrapf(err, "failed to create RuntimeSDK client: failed to create cert-watcher")
83+
}
84+
certWatcher.RegisterCallback(func(_ tls.Certificate) {
85+
httpClientCache.DeleteAll()
86+
})
87+
}
7388
return &client{
7489
certFile: options.CertFile,
7590
keyFile: options.KeyFile,
7691
catalog: options.Catalog,
7792
registry: options.Registry,
7893
client: options.Client,
79-
httpClientsCache: cache.New[httpClientEntry](24 * time.Hour),
80-
}
94+
httpClientsCache: httpClientCache,
95+
}, certWatcher, nil
8196
}
8297

8398
var _ runtimeclient.Client = &client{}

0 commit comments

Comments
Ā (0)