github.com/argoproj/argo-cd@v1.8.7/controller/sharding/sharding.go (about)

     1  package sharding
     2  
     3  import (
     4  	"fmt"
     5  	"hash/fnv"
     6  	"os"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
    11  )
    12  
    13  func InferShard() (int, error) {
    14  	hostname, err := os.Hostname()
    15  	if err != nil {
    16  		return 0, err
    17  	}
    18  	parts := strings.Split(hostname, "-")
    19  	if len(parts) == 0 {
    20  		return 0, fmt.Errorf("hostname should ends with shard number separated by '-' but got: %s", hostname)
    21  	}
    22  	shard, err := strconv.Atoi(parts[len(parts)-1])
    23  	if err != nil {
    24  		return 0, fmt.Errorf("hostname should ends with shard number separated by '-' but got: %s", hostname)
    25  	}
    26  	return shard, nil
    27  }
    28  
    29  // getShardByID calculates cluster shard as `clusterSecret.UID % replicas count`
    30  func getShardByID(id string, replicas int) int {
    31  	if id == "" {
    32  		return 0
    33  	} else {
    34  		h := fnv.New32a()
    35  		_, _ = h.Write([]byte(id))
    36  		return int(h.Sum32() % uint32(replicas))
    37  	}
    38  }
    39  
    40  func GetClusterFilter(replicas int, shard int) func(c *v1alpha1.Cluster) bool {
    41  	return func(c *v1alpha1.Cluster) bool {
    42  		clusterShard := 0
    43  		//  cluster might be nil if app is using invalid cluster URL, assume shard 0 in this case.
    44  		if c != nil {
    45  			if c.Shard != nil {
    46  				clusterShard = int(*c.Shard)
    47  			} else {
    48  				clusterShard = getShardByID(c.ID, replicas)
    49  			}
    50  		}
    51  		return clusterShard == shard
    52  	}
    53  }