istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/kube/multicluster/clusterstore.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package multicluster 16 17 import ( 18 "sync" 19 20 "istio.io/istio/pkg/cluster" 21 "istio.io/istio/pkg/log" 22 "istio.io/istio/pkg/util/sets" 23 ) 24 25 // ClusterStore is a collection of clusters 26 type ClusterStore struct { 27 sync.RWMutex 28 // keyed by secret key(ns/name)->clusterID 29 remoteClusters map[string]map[cluster.ID]*Cluster 30 clusters sets.String 31 } 32 33 // newClustersStore initializes data struct to store clusters information 34 func newClustersStore() *ClusterStore { 35 return &ClusterStore{ 36 remoteClusters: make(map[string]map[cluster.ID]*Cluster), 37 clusters: sets.New[string](), 38 } 39 } 40 41 func (c *ClusterStore) Store(secretKey string, clusterID cluster.ID, value *Cluster) { 42 c.Lock() 43 defer c.Unlock() 44 if _, ok := c.remoteClusters[secretKey]; !ok { 45 c.remoteClusters[secretKey] = make(map[cluster.ID]*Cluster) 46 } 47 c.remoteClusters[secretKey][clusterID] = value 48 c.clusters.Insert(string(clusterID)) 49 } 50 51 func (c *ClusterStore) Delete(secretKey string, clusterID cluster.ID) { 52 c.Lock() 53 defer c.Unlock() 54 delete(c.remoteClusters[secretKey], clusterID) 55 c.clusters.Delete(string(clusterID)) 56 if len(c.remoteClusters[secretKey]) == 0 { 57 delete(c.remoteClusters, secretKey) 58 } 59 } 60 61 func (c *ClusterStore) Get(secretKey string, clusterID cluster.ID) *Cluster { 62 c.RLock() 63 defer c.RUnlock() 64 if _, ok := c.remoteClusters[secretKey]; !ok { 65 return nil 66 } 67 return c.remoteClusters[secretKey][clusterID] 68 } 69 70 func (c *ClusterStore) Contains(clusterID cluster.ID) bool { 71 c.RLock() 72 defer c.RUnlock() 73 return c.clusters.Contains(string(clusterID)) 74 } 75 76 func (c *ClusterStore) GetByID(clusterID cluster.ID) *Cluster { 77 c.RLock() 78 defer c.RUnlock() 79 for _, clusters := range c.remoteClusters { 80 c, ok := clusters[clusterID] 81 if ok { 82 return c 83 } 84 } 85 return nil 86 } 87 88 // All returns a copy of the current remote clusters. 89 func (c *ClusterStore) All() map[string]map[cluster.ID]*Cluster { 90 if c == nil { 91 return nil 92 } 93 c.RLock() 94 defer c.RUnlock() 95 out := make(map[string]map[cluster.ID]*Cluster, len(c.remoteClusters)) 96 for secret, clusters := range c.remoteClusters { 97 out[secret] = make(map[cluster.ID]*Cluster, len(clusters)) 98 for cid, c := range clusters { 99 outCluster := *c 100 out[secret][cid] = &outCluster 101 } 102 } 103 return out 104 } 105 106 // GetExistingClustersFor return existing clusters registered for the given secret 107 func (c *ClusterStore) GetExistingClustersFor(secretKey string) []*Cluster { 108 c.RLock() 109 defer c.RUnlock() 110 out := make([]*Cluster, 0, len(c.remoteClusters[secretKey])) 111 for _, cluster := range c.remoteClusters[secretKey] { 112 out = append(out, cluster) 113 } 114 return out 115 } 116 117 func (c *ClusterStore) Len() int { 118 c.Lock() 119 defer c.Unlock() 120 out := 0 121 for _, clusterMap := range c.remoteClusters { 122 out += len(clusterMap) 123 } 124 return out 125 } 126 127 func (c *ClusterStore) HasSynced() bool { 128 c.RLock() 129 defer c.RUnlock() 130 for _, clusterMap := range c.remoteClusters { 131 for _, cl := range clusterMap { 132 if !cl.HasSynced() { 133 log.Debugf("remote cluster %s registered informers have not been synced up yet", cl.ID) 134 return false 135 } 136 } 137 } 138 139 return true 140 }