diff --git a/conf/defaults.ini b/conf/defaults.ini index 3cabe6c1aff..4b187d7e8be 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -116,9 +116,9 @@ type = database # cache connectionstring options # database: will use Grafana primary database. -# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana` +# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0`. Only addr is required. # memcache: 127.0.0.1:11211 -connstr = +;connstr = #################################### Data proxy ########################### [dataproxy] diff --git a/conf/sample.ini b/conf/sample.ini index 81c932a611d..fb1635713b4 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -112,7 +112,7 @@ # cache connectionstring options # database: will use Grafana primary database. -# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana` +# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0`. Only addr is required. # memcache: 127.0.0.1:11211 ;connstr = diff --git a/pkg/infra/remotecache/redis_storage.go b/pkg/infra/remotecache/redis_storage.go index 7448cb27697..7219ddbc21b 100644 --- a/pkg/infra/remotecache/redis_storage.go +++ b/pkg/infra/remotecache/redis_storage.go @@ -1,9 +1,13 @@ package remotecache import ( + "fmt" + "strconv" + "strings" "time" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/util/errutil" redis "gopkg.in/redis.v2" ) @@ -13,12 +17,47 @@ type redisStorage struct { c *redis.Client } -func newRedisStorage(opts *setting.RemoteCacheOptions) *redisStorage { - opt := &redis.Options{ - Network: "tcp", - Addr: opts.ConnStr, +// parseRedisConnStr parses k=v pairs in csv and builds a redis Options object +func parseRedisConnStr(connStr string) (*redis.Options, error) { + keyValueCSV := strings.Split(connStr, ",") + options := &redis.Options{Network: "tcp"} + for _, rawKeyValue := range keyValueCSV { + keyValueTuple := strings.Split(rawKeyValue, "=") + if len(keyValueTuple) != 2 { + return nil, fmt.Errorf("incorrect redis connection string format detected for '%v', format is key=value,key=value", rawKeyValue) + } + connKey := keyValueTuple[0] + connVal := keyValueTuple[1] + switch connKey { + case "addr": + options.Addr = connVal + case "password": + options.Password = connVal + case "db": + i, err := strconv.ParseInt(connVal, 10, 64) + if err != nil { + return nil, errutil.Wrap("value for db in redis connection string must be a number", err) + } + options.DB = i + case "pool_size": + i, err := strconv.Atoi(connVal) + if err != nil { + return nil, errutil.Wrap("value for pool_size in redis connection string must be a number", err) + } + options.PoolSize = i + default: + return nil, fmt.Errorf("unrecorgnized option '%v' in redis connection string", connVal) + } } - return &redisStorage{c: redis.NewClient(opt)} + return options, nil +} + +func newRedisStorage(opts *setting.RemoteCacheOptions) (*redisStorage, error) { + opt, err := parseRedisConnStr(opts.ConnStr) + if err != nil { + return nil, err + } + return &redisStorage{c: redis.NewClient(opt)}, nil } // Set sets value to given key in session. @@ -28,7 +67,6 @@ func (s *redisStorage) Set(key string, val interface{}, expires time.Duration) e if err != nil { return err } - status := s.c.SetEx(key, expires, string(value)) return status.Err() } diff --git a/pkg/infra/remotecache/redis_storage_integration_test.go b/pkg/infra/remotecache/redis_storage_integration_test.go index 8d54fc9ff14..7efaca8298b 100644 --- a/pkg/infra/remotecache/redis_storage_integration_test.go +++ b/pkg/infra/remotecache/redis_storage_integration_test.go @@ -10,7 +10,7 @@ import ( func TestRedisCacheStorage(t *testing.T) { - opts := &setting.RemoteCacheOptions{Name: redisCacheType, ConnStr: "localhost:6379"} + opts := &setting.RemoteCacheOptions{Name: redisCacheType, ConnStr: "addr=localhost:6379"} client := createTestClient(t, opts, nil) runTestsForClient(t, client) } diff --git a/pkg/infra/remotecache/remotecache.go b/pkg/infra/remotecache/remotecache.go index 0c04277192f..3ac3d06fa1f 100644 --- a/pkg/infra/remotecache/remotecache.go +++ b/pkg/infra/remotecache/remotecache.go @@ -91,7 +91,7 @@ func (ds *RemoteCache) Run(ctx context.Context) error { func createClient(opts *setting.RemoteCacheOptions, sqlstore *sqlstore.SqlStore) (CacheStorage, error) { if opts.Name == redisCacheType { - return newRedisStorage(opts), nil + return newRedisStorage(opts) } if opts.Name == memcachedCacheType {