Skip to content

Commit e9f9fc3

Browse files
committed
ClusterCache: Deprecate GetClientCertificatePrivateKey and stop using it in KCP
Signed-off-by: Stefan Büringer [email protected]
1 parent 3fe6f96 commit e9f9fc3

File tree

5 files changed

+37
-9
lines changed

5 files changed

+37
-9
lines changed

controllers/clustercache/cluster_cache.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ type ClusterCache interface {
147147
// cert to communicate with etcd.
148148
// This private key is stored and cached in the ClusterCache because it's expensive to generate a new
149149
// private key in every single Reconcile.
150+
//
151+
// Deprecated: This method is deprecated and will be removed in a future release as caching a rsa.PrivateKey
152+
// is outside the scope of the ClusterCache.
150153
GetClientCertificatePrivateKey(ctx context.Context, cluster client.ObjectKey) (*rsa.PrivateKey, error)
151154

152155
// Watch watches a workload cluster for events.

controlplane/kubeadm/internal/cluster.go

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232

3333
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
3434
"sigs.k8s.io/cluster-api/controllers/clustercache"
35+
"sigs.k8s.io/cluster-api/util/cache"
3536
"sigs.k8s.io/cluster-api/util/collections"
3637
"sigs.k8s.io/cluster-api/util/secret"
3738
)
@@ -53,6 +54,18 @@ type Management struct {
5354
EtcdDialTimeout time.Duration
5455
EtcdCallTimeout time.Duration
5556
EtcdLogger *zap.Logger
57+
ClientCertCache cache.Cache[ClientCertEntry]
58+
}
59+
60+
// ClientCertEntry is an Entry for the Cache that stores the client cert.
61+
type ClientCertEntry struct {
62+
Cluster client.ObjectKey
63+
ClientCert *tls.Certificate
64+
}
65+
66+
// Key returns the cache key of a ClientCertEntry.
67+
func (r ClientCertEntry) Key() string {
68+
return r.Cluster.String()
5669
}
5770

5871
// RemoteClusterConnectionError represents a failure to connect to a remote cluster.
@@ -126,14 +139,18 @@ func (m *Management) GetWorkloadCluster(ctx context.Context, clusterKey client.O
126139
// TODO: consider if we can detect if we are using external etcd in a more explicit way (e.g. looking at the config instead of deriving from the existing certificates)
127140
var clientCert tls.Certificate
128141
if keyData != nil {
129-
clientKey, err := m.ClusterCache.GetClientCertificatePrivateKey(ctx, clusterKey)
130-
if err != nil {
131-
return nil, err
132-
}
133-
134-
clientCert, err = generateClientCert(crtData, keyData, clientKey)
135-
if err != nil {
136-
return nil, err
142+
// Get client cert from cache if possible, otherwise generate it and add it to the cache.
143+
// TODO: When we implement ClusterConfiguration.EncryptionAlgorithm we should add it to
144+
// the ClientCertEntries and make it part of the key.
145+
if entry, ok := m.ClientCertCache.Has(ClientCertEntry{Cluster: clusterKey}.Key()); ok {
146+
clientCert = *entry.ClientCert
147+
} else {
148+
// The client cert expires after 10 years, but that's okay as the cache has a TTL of 1 day.
149+
clientCert, err = generateClientCert(crtData, keyData)
150+
if err != nil {
151+
return nil, err
152+
}
153+
m.ClientCertCache.Add(ClientCertEntry{Cluster: clusterKey, ClientCert: &clientCert})
137154
}
138155
} else {
139156
clientCert, err = m.getAPIServerEtcdClientCert(ctx, clusterKey)

controlplane/kubeadm/internal/cluster_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
4343
"sigs.k8s.io/cluster-api/controllers/clustercache"
4444
"sigs.k8s.io/cluster-api/controllers/remote"
45+
"sigs.k8s.io/cluster-api/util/cache"
4546
"sigs.k8s.io/cluster-api/util/certs"
4647
"sigs.k8s.io/cluster-api/util/collections"
4748
"sigs.k8s.io/cluster-api/util/kubeconfig"
@@ -239,6 +240,7 @@ func TestGetWorkloadCluster(t *testing.T) {
239240
Client: env.GetClient(),
240241
SecretCachingClient: secretCachingClient,
241242
ClusterCache: clusterCache,
243+
ClientCertCache: cache.New[ClientCertEntry](24 * time.Hour),
242244
}
243245

244246
// Ensure the ClusterCache reconciled at least once (and if possible created a clusterAccessor).

controlplane/kubeadm/internal/controllers/controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import (
5050
"sigs.k8s.io/cluster-api/internal/contract"
5151
"sigs.k8s.io/cluster-api/internal/util/ssa"
5252
"sigs.k8s.io/cluster-api/util"
53+
"sigs.k8s.io/cluster-api/util/cache"
5354
"sigs.k8s.io/cluster-api/util/collections"
5455
"sigs.k8s.io/cluster-api/util/conditions"
5556
v1beta1conditions "sigs.k8s.io/cluster-api/util/conditions/deprecated/v1beta1"
@@ -149,6 +150,7 @@ func (r *KubeadmControlPlaneReconciler) SetupWithManager(ctx context.Context, mg
149150
EtcdDialTimeout: r.EtcdDialTimeout,
150151
EtcdCallTimeout: r.EtcdCallTimeout,
151152
EtcdLogger: r.EtcdLogger,
153+
ClientCertCache: cache.New[internal.ClientCertEntry](24 * time.Hour),
152154
}
153155
}
154156

controlplane/kubeadm/internal/workload_cluster.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ func calculateAPIServerPort(config *bootstrapv1.KubeadmConfig) int32 {
347347
return 6443
348348
}
349349

350-
func generateClientCert(caCertEncoded, caKeyEncoded []byte, clientKey *rsa.PrivateKey) (tls.Certificate, error) {
350+
func generateClientCert(caCertEncoded, caKeyEncoded []byte) (tls.Certificate, error) {
351351
caCert, err := certs.DecodeCertPEM(caCertEncoded)
352352
if err != nil {
353353
return tls.Certificate{}, err
@@ -356,6 +356,10 @@ func generateClientCert(caCertEncoded, caKeyEncoded []byte, clientKey *rsa.Priva
356356
if err != nil {
357357
return tls.Certificate{}, err
358358
}
359+
clientKey, err := certs.NewPrivateKey()
360+
if err != nil {
361+
return tls.Certificate{}, err
362+
}
359363
x509Cert, err := newClientCert(caCert, clientKey, caKey)
360364
if err != nil {
361365
return tls.Certificate{}, err

0 commit comments

Comments
 (0)