@@ -27,6 +27,7 @@ import (
2727 "go.uber.org/zap"
2828 corev1 "k8s.io/api/core/v1"
2929 apierrors "k8s.io/apimachinery/pkg/api/errors"
30+ "k8s.io/apimachinery/pkg/types"
3031 "k8s.io/client-go/rest"
3132 "sigs.k8s.io/controller-runtime/pkg/client"
3233
@@ -44,7 +45,7 @@ type ManagementCluster interface {
4445
4546 GetMachinesForCluster (ctx context.Context , cluster * clusterv1.Cluster , filters ... collections.Func ) (collections.Machines , error )
4647 GetMachinePoolsForCluster (ctx context.Context , cluster * clusterv1.Cluster ) (* clusterv1.MachinePoolList , error )
47- GetWorkloadCluster (ctx context.Context , clusterKey client. ObjectKey , keyEncryptionAlgorithm bootstrapv1.EncryptionAlgorithmType ) (WorkloadCluster , error )
48+ GetWorkloadCluster (ctx context.Context , cluster * clusterv1. Cluster , keyEncryptionAlgorithm bootstrapv1.EncryptionAlgorithmType ) (WorkloadCluster , error )
4849}
4950
5051// Management holds operations on the management cluster.
@@ -61,13 +62,14 @@ type Management struct {
6162// ClientCertEntry is an Entry for the Cache that stores the client cert.
6263type ClientCertEntry struct {
6364 Cluster client.ObjectKey
65+ ClusterUID types.UID
6466 ClientCert * tls.Certificate
6567 EncryptionAlgorithm bootstrapv1.EncryptionAlgorithmType
6668}
6769
6870// Key returns the cache key of a ClientCertEntry.
6971func (r ClientCertEntry ) Key () string {
70- return fmt .Sprintf ("%s/%s" , r .Cluster .String (), r .EncryptionAlgorithm )
72+ return fmt .Sprintf ("%s/%s/%s " , r .Cluster .String (), r . ClusterUID , r .EncryptionAlgorithm )
7173}
7274
7375// RemoteClusterConnectionError represents a failure to connect to a remote cluster.
@@ -113,7 +115,9 @@ func (m *Management) GetMachinePoolsForCluster(ctx context.Context, cluster *clu
113115
114116// GetWorkloadCluster builds a cluster object.
115117// The cluster comes with an etcd client generator to connect to any etcd pod living on a managed machine.
116- func (m * Management ) GetWorkloadCluster (ctx context.Context , clusterKey client.ObjectKey , keyEncryptionAlgorithm bootstrapv1.EncryptionAlgorithmType ) (WorkloadCluster , error ) {
118+ func (m * Management ) GetWorkloadCluster (ctx context.Context , cluster * clusterv1.Cluster , keyEncryptionAlgorithm bootstrapv1.EncryptionAlgorithmType ) (WorkloadCluster , error ) {
119+ clusterKey := client .ObjectKeyFromObject (cluster )
120+
117121 // TODO(chuckha): Inject this dependency.
118122 // TODO(chuckha): memoize this function. The workload client only exists as long as a reconciliation loop.
119123 restConfig , err := m .ClusterCache .GetRESTConfig (ctx , clusterKey )
@@ -142,15 +146,16 @@ func (m *Management) GetWorkloadCluster(ctx context.Context, clusterKey client.O
142146 var clientCert tls.Certificate
143147 if keyData != nil {
144148 // Get client cert from cache if possible, otherwise generate it and add it to the cache.
145- if entry , ok := m .ClientCertCache .Has (ClientCertEntry {Cluster : clusterKey , EncryptionAlgorithm : keyEncryptionAlgorithm }.Key ()); ok {
149+ // Note: The caching assumes that the etcd CA is not rotated during the lifetime of a Cluster.
150+ if entry , ok := m .ClientCertCache .Has (ClientCertEntry {Cluster : clusterKey , ClusterUID : cluster .UID , EncryptionAlgorithm : keyEncryptionAlgorithm }.Key ()); ok {
146151 clientCert = * entry .ClientCert
147152 } else {
148153 // The client cert expires after 10 years, but that's okay as the cache has a TTL of 1 day.
149154 clientCert , err = generateClientCert (crtData , keyData , keyEncryptionAlgorithm )
150155 if err != nil {
151156 return nil , err
152157 }
153- m .ClientCertCache .Add (ClientCertEntry {Cluster : clusterKey , ClientCert : & clientCert , EncryptionAlgorithm : keyEncryptionAlgorithm })
158+ m .ClientCertCache .Add (ClientCertEntry {Cluster : clusterKey , ClusterUID : cluster . UID , ClientCert : & clientCert , EncryptionAlgorithm : keyEncryptionAlgorithm })
154159 }
155160 } else {
156161 clientCert , err = m .getAPIServerEtcdClientCert (ctx , clusterKey )
0 commit comments