@@ -9,12 +9,16 @@ import (
9
9
"sync"
10
10
"time"
11
11
12
+ corev1 "k8s.io/api/core/v1"
12
13
"k8s.io/apimachinery/pkg/api/equality"
13
14
apierrors "k8s.io/apimachinery/pkg/api/errors"
14
15
"k8s.io/apimachinery/pkg/api/meta"
15
16
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
17
"k8s.io/apimachinery/pkg/labels"
17
18
"k8s.io/apimachinery/pkg/util/wait"
19
+ v1 "k8s.io/client-go/informers/core/v1"
20
+ "k8s.io/client-go/kubernetes"
21
+ corev1listers "k8s.io/client-go/listers/core/v1"
18
22
"k8s.io/client-go/tools/cache"
19
23
"k8s.io/client-go/util/retry"
20
24
"k8s.io/client-go/util/workqueue"
@@ -45,6 +49,8 @@ type Manager struct {
45
49
46
50
clusterpediaclient crdclientset.Interface
47
51
informerFactory externalversions.SharedInformerFactory
52
+ secretLister corev1listers.SecretNamespaceLister
53
+ secretInformer cache.SharedIndexInformer
48
54
49
55
shardingName string
50
56
queue workqueue.RateLimitingInterface
@@ -57,18 +63,20 @@ type Manager struct {
57
63
synchrolock sync.RWMutex
58
64
synchros map [string ]* clustersynchro.ClusterSynchro
59
65
synchroWaitGroup wait.Group
66
+
67
+ clusterSecretsMap sync.Map
60
68
}
61
69
62
70
var _ kubestatemetrics.ClusterMetricsWriterListGetter = & Manager {}
63
71
64
- func NewManager (client crdclientset.Interface , storage storage.StorageFactory , syncConfig clustersynchro.ClusterSyncConfig , shardingName string ) * Manager {
65
- factory := externalversions .NewSharedInformerFactory (client , 0 )
72
+ func NewManager (client kubernetes. Interface , clusterpediaClient crdclientset.Interface , storage storage.StorageFactory , syncConfig clustersynchro.ClusterSyncConfig , shardingName string , secretNamespace string ) * Manager {
73
+ factory := externalversions .NewSharedInformerFactory (clusterpediaClient , 0 )
66
74
clusterinformer := factory .Cluster ().V1alpha2 ().PediaClusters ()
67
75
clusterSyncResourcesInformer := factory .Cluster ().V1alpha2 ().ClusterSyncResources ()
68
76
69
77
manager := & Manager {
70
78
informerFactory : factory ,
71
- clusterpediaclient : client ,
79
+ clusterpediaclient : clusterpediaClient ,
72
80
shardingName : shardingName ,
73
81
74
82
storage : storage ,
@@ -83,6 +91,23 @@ func NewManager(client crdclientset.Interface, storage storage.StorageFactory, s
83
91
synchros : make (map [string ]* clustersynchro.ClusterSynchro ),
84
92
}
85
93
94
+ secretInformer := v1 .NewSecretInformer (client , secretNamespace , 0 , nil )
95
+ if _ , err := secretInformer .AddEventHandler (
96
+ cache.ResourceEventHandlerFuncs {
97
+ AddFunc : func (obj any ) { manager .handleSecret (nil , obj .(* corev1.Secret )) },
98
+ UpdateFunc : func (older , newer any ) { manager .handleSecret (older .(* corev1.Secret ), newer .(* corev1.Secret )) },
99
+ DeleteFunc : func (obj any ) {
100
+ objName , err := cache .DeletionHandlingObjectToName (obj )
101
+ if err != nil {
102
+ return
103
+ }
104
+ manager .handleDeletedSecret (objName .Name )
105
+ },
106
+ },
107
+ ); err != nil {
108
+ klog .ErrorS (err , "error when adding event handler to informer" )
109
+ }
110
+
86
111
if _ , err := clusterinformer .Informer ().AddEventHandler (
87
112
cache.ResourceEventHandlerFuncs {
88
113
AddFunc : manager .addCluster ,
@@ -130,6 +155,21 @@ func (manager *Manager) Run(workers int, stopCh <-chan struct{}) {
130
155
131
156
// informerFactory should not be controlled by stopCh
132
157
stopInformer := make (chan struct {})
158
+
159
+ // 优先启动 secret informer
160
+ manager .secretInformer .Run (stopInformer )
161
+ timeout := make (chan struct {})
162
+ go func () {
163
+ select {
164
+ case <- stopCh :
165
+ case <- time .After (60 * time .Second ):
166
+ }
167
+ close (timeout )
168
+ }()
169
+ if ! cache .WaitForCacheSync (timeout , manager .secretInformer .HasSynced ) {
170
+ klog .Fatal ("clustersynchro manager: wait for secret informer failed" )
171
+ }
172
+
133
173
manager .informerFactory .Start (stopInformer )
134
174
if ! cache .WaitForCacheSync (stopCh , manager .clusterInformer .HasSynced ) {
135
175
klog .Fatal ("clustersynchro manager: wait for informer factory failed" )
@@ -159,6 +199,31 @@ func (manager *Manager) Run(workers int, stopCh <-chan struct{}) {
159
199
klog .Info ("cluster synchro manager stopped." )
160
200
}
161
201
202
+ func (manager * Manager ) handleSecret (old * corev1.Secret , obj * corev1.Secret ) {
203
+ if old != nil && reflect .DeepEqual (old .Data , obj .Data ) {
204
+ return
205
+ }
206
+
207
+ // TODO(Iceber): 通过字段 Key 来优化 cluster 的查找
208
+ manager .clusterSecretsMap .Range (func (k , v any ) bool {
209
+ secrets := v .(map [string ]struct {})
210
+ if _ , ok := secrets [obj .Name ]; ok {
211
+ manager .enqueue (k .(string ))
212
+ }
213
+ return true
214
+ })
215
+ }
216
+
217
+ func (manager * Manager ) handleDeletedSecret (name string ) {
218
+ manager .clusterSecretsMap .Range (func (k , v any ) bool {
219
+ secrets := v .(map [string ]struct {})
220
+ if _ , ok := secrets [name ]; ok {
221
+ manager .enqueue (k .(string ))
222
+ }
223
+ return true
224
+ })
225
+ }
226
+
162
227
func (manager * Manager ) addCluster (obj interface {}) {
163
228
manager .enqueue (obj )
164
229
}
@@ -328,7 +393,23 @@ func (manager *Manager) reconcileCluster(cluster *clusterv1alpha2.PediaCluster)
328
393
synchro := manager .synchros [cluster .Name ]
329
394
manager .synchrolock .RUnlock ()
330
395
331
- config , err := utils .BuildClusterRestConfig (cluster )
396
+ // TODO(Iceber): Need to optimize and simplify the following code
397
+ secrets := make (map [string ]struct {})
398
+ if source := cluster .Spec .CertificationFrom .Cert ; source != nil {
399
+ secrets [source .Name ] = struct {}{}
400
+ }
401
+ if source := cluster .Spec .CertificationFrom .Token ; source != nil {
402
+ secrets [source .Name ] = struct {}{}
403
+ }
404
+ if source := cluster .Spec .CertificationFrom .KubeConfig ; source != nil {
405
+ secrets [source .Name ] = struct {}{}
406
+ }
407
+ if source := cluster .Spec .CertificationFrom .Key ; source != nil {
408
+ secrets [source .Name ] = struct {}{}
409
+ }
410
+ manager .clusterSecretsMap .Store (cluster .Name , secrets )
411
+
412
+ config , err := utils .BuildClusterRestConfig (cluster , manager .secretLister )
332
413
if err != nil {
333
414
klog .ErrorS (err , "Failed to build cluster config" , "cluster" , cluster .Name )
334
415
manager .UpdateClusterAPIServerAndValidatedCondition (cluster .Name , cluster .Spec .APIServer , synchro , clusterv1alpha2 .InvalidConfigReason ,
@@ -453,6 +534,8 @@ func (manager *Manager) stopClusterSynchro(name string) {
453
534
}
454
535
455
536
func (manager * Manager ) removeCluster (name string ) error {
537
+ manager .clusterSecretsMap .Delete (name )
538
+
456
539
manager .synchrolock .Lock ()
457
540
synchro := manager .synchros [name ]
458
541
delete (manager .synchros , name )
0 commit comments