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  }