github.com/argoproj/argo-cd@v1.8.7/util/cache/cache.go (about)

     1  package cache
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  	"os"
     8  	"time"
     9  
    10  	"github.com/go-redis/redis/v8"
    11  	"github.com/spf13/cobra"
    12  
    13  	"github.com/argoproj/argo-cd/common"
    14  	"github.com/argoproj/argo-cd/util/env"
    15  )
    16  
    17  const (
    18  	// envRedisPassword is a env variable name which stores redis password
    19  	envRedisPassword = "REDIS_PASSWORD"
    20  	// envRedisRetryCount is a env variable name which stores redis retry count
    21  	envRedisRetryCount = "REDIS_RETRY_COUNT"
    22  	// defaultRedisRetryCount holds default number of retries
    23  	defaultRedisRetryCount = 3
    24  )
    25  
    26  func NewCache(client CacheClient) *Cache {
    27  	return &Cache{client}
    28  }
    29  
    30  // AddCacheFlagsToCmd adds flags which control caching to the specified command
    31  func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) func() (*Cache, error) {
    32  	redisAddress := ""
    33  	sentinelAddresses := make([]string, 0)
    34  	sentinelMaster := ""
    35  	redisDB := 0
    36  	var defaultCacheExpiration time.Duration
    37  
    38  	cmd.Flags().StringVar(&redisAddress, "redis", "", "Redis server hostname and port (e.g. argocd-redis:6379). ")
    39  	cmd.Flags().IntVar(&redisDB, "redisdb", 0, "Redis database.")
    40  	cmd.Flags().StringArrayVar(&sentinelAddresses, "sentinel", []string{}, "Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). ")
    41  	cmd.Flags().StringVar(&sentinelMaster, "sentinelmaster", "master", "Redis sentinel master group name.")
    42  	cmd.Flags().DurationVar(&defaultCacheExpiration, "default-cache-expiration", 24*time.Hour, "Cache expiration default")
    43  	return func() (*Cache, error) {
    44  		password := os.Getenv(envRedisPassword)
    45  		maxRetries := env.ParseNumFromEnv(envRedisRetryCount, defaultRedisRetryCount, 0, math.MaxInt32)
    46  		if len(sentinelAddresses) > 0 {
    47  			client := redis.NewFailoverClient(&redis.FailoverOptions{
    48  				MasterName:    sentinelMaster,
    49  				SentinelAddrs: sentinelAddresses,
    50  				DB:            redisDB,
    51  				Password:      password,
    52  				MaxRetries:    maxRetries,
    53  			})
    54  			for i := range opts {
    55  				opts[i](client)
    56  			}
    57  			return NewCache(NewRedisCache(client, defaultCacheExpiration)), nil
    58  		}
    59  
    60  		if redisAddress == "" {
    61  			redisAddress = common.DefaultRedisAddr
    62  		}
    63  		client := redis.NewClient(&redis.Options{
    64  			Addr:       redisAddress,
    65  			Password:   password,
    66  			DB:         redisDB,
    67  			MaxRetries: maxRetries,
    68  		})
    69  		for i := range opts {
    70  			opts[i](client)
    71  		}
    72  		return NewCache(NewRedisCache(client, defaultCacheExpiration)), nil
    73  	}
    74  }
    75  
    76  // Cache provides strongly types methods to store and retrieve values from shared cache
    77  type Cache struct {
    78  	client CacheClient
    79  }
    80  
    81  func (c *Cache) GetClient() CacheClient {
    82  	return c.client
    83  }
    84  
    85  func (c *Cache) SetClient(client CacheClient) {
    86  	c.client = client
    87  }
    88  
    89  func (c *Cache) SetItem(key string, item interface{}, expiration time.Duration, delete bool) error {
    90  	key = fmt.Sprintf("%s|%s", key, common.CacheVersion)
    91  	if delete {
    92  		return c.client.Delete(key)
    93  	} else {
    94  		if item == nil {
    95  			return fmt.Errorf("cannot set item to nil for key %s", key)
    96  		}
    97  		return c.client.Set(&Item{Object: item, Key: key, Expiration: expiration})
    98  	}
    99  }
   100  
   101  func (c *Cache) GetItem(key string, item interface{}) error {
   102  	if item == nil {
   103  		return fmt.Errorf("cannot get item into a nil for key %s", key)
   104  	}
   105  	key = fmt.Sprintf("%s|%s", key, common.CacheVersion)
   106  	return c.client.Get(key, item)
   107  }
   108  
   109  func (c *Cache) OnUpdated(ctx context.Context, key string, callback func() error) error {
   110  	return c.client.OnUpdated(ctx, fmt.Sprintf("%s|%s", key, common.CacheVersion), callback)
   111  }
   112  
   113  func (c *Cache) NotifyUpdated(key string) error {
   114  	return c.client.NotifyUpdated(fmt.Sprintf("%s|%s", key, common.CacheVersion))
   115  }