Skip to content

Commit

Permalink
Add support for user auth introduced in Redis 6.0 (oliver006#392)
Browse files Browse the repository at this point in the history
That also changes redigo/redis dependency to v1.8.2 which
is actually newer than 2.0.x tag and supports Redis ACL logins.

Co-authored-by: Mario Hros <[email protected]>
  • Loading branch information
k3a and Mario Hros authored Jun 12, 2020
1 parent 1d4340c commit 602a120
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 19 deletions.
10 changes: 9 additions & 1 deletion .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ services:
ports:
- 6380

- name: pwd-redis6
image: redis:6
commands:
- "/usr/local/bin/redis-server --port 6390 --requirepass dummy --user exporter on +INFO +SELECT +SLOWLOG +LATENCY '>exporter-password' --dbfilename dump6-pwd.rdb"
ports:
- 6380

- name: redis-2-8
image: redis:2.8
commands:
Expand Down Expand Up @@ -72,7 +79,8 @@ steps:
TEST_REDIS_2_8_URI: "redis://redis-2-8:6381"
TEST_KEYDB01_URI: "redis://keydb-01:6401"
TEST_KEYDB02_URI: "redis://keydb-02:6402"
TEST_PWD_REDIS_URI: "redis://h:redis-password@pwd-redis5:6380"
TEST_PWD_REDIS_URI: "redis://:redis-password@pwd-redis5:6380"
TEST_USER_PWD_REDIS_URI: "redis://exporter:exporter-password@pwd-redis6:6390"
TEST_REDIS_CLUSTER_MASTER_URI: "redis://redis-cluster:7000"
TEST_REDIS_CLUSTER_SLAVE_URI: "redis://redis-cluster:7005"
TEST_TILE38_URI: "redis://tile38:9851"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Prometheus uses file watches and all changes to the json file are applied immedi
Name | Environment Variable Name | Description
-----------------------|--------------------------------------|-----------------
redis.addr | REDIS_ADDR | Address of the Redis instance, defaults to `redis://localhost:6379`.
redis.user | REDIS_USER | User name to use for authentication (Redis ACL for Redis 6.0 and newer).
redis.password | REDIS_PASSWORD | Password of the Redis instance, defaults to `""` (no password).
check-keys | REDIS_EXPORTER_CHECK_KEYS | Comma separated list of key patterns to export value and length/size, eg: `db3=user_count` will export key `user_count` from db `3`. db defaults to `0` if omitted. The key patterns specified with this flag will be found using [SCAN](https://redis.io/commands/scan). Use this option if you need glob pattern matching; `check-single-keys` is faster for non-pattern keys. Warning: using `--check-keys` to match a very large number of keys can slow down the exporter to the point where it doesn't finish scraping the redis instance.
check-single-keys | REDIS_EXPORTER_CHECK_SINGLE_KEYS | Comma separated list of keys to export value and length/size, eg: `db3=user_count` will export key `user_count` from db `3`. db defaults to `0` if omitted. The keys specified with this flag will be looked up directly without any glob pattern matching. Use this option if you don't need glob pattern matching; it is faster than `check-keys`.
Expand Down
6 changes: 6 additions & 0 deletions exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type Exporter struct {
}

type Options struct {
User string
Password string
Namespace string
ConfigCommandName string
Expand Down Expand Up @@ -1189,6 +1190,10 @@ func (e *Exporter) connectToRedis() (redis.Conn, error) {
}),
}

if e.options.User != "" {
options = append(options, redis.DialUsername(e.options.User))
}

if e.options.Password != "" {
options = append(options, redis.DialPassword(e.options.Password))
}
Expand All @@ -1197,6 +1202,7 @@ func (e *Exporter) connectToRedis() (redis.Conn, error) {
if !strings.Contains(uri, "://") {
uri = "redis://" + uri
}

log.Debugf("Trying DialURL(): %s", uri)
c, err := redis.DialURL(uri, options...)
if err != nil {
Expand Down
37 changes: 22 additions & 15 deletions exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1251,26 +1251,33 @@ func TestClusterMaster(t *testing.T) {
}

func TestPasswordProtectedInstance(t *testing.T) {
if os.Getenv("TEST_PWD_REDIS_URI") == "" {
t.Skipf("TEST_PWD_REDIS_URI not set - skipping")
uriEnvs := []string{
"TEST_PWD_REDIS_URI",
"TEST_USER_PWD_REDIS_URI",
}
uri := os.Getenv("TEST_PWD_REDIS_URI")
setupDBKeys(t, uri)

e, _ := NewRedisExporter(uri, Options{Namespace: "test", Registry: prometheus.NewRegistry()})
ts := httptest.NewServer(e)
defer ts.Close()
for _, uriEnvName := range uriEnvs {
if os.Getenv(uriEnvName) == "" {
t.Logf("%s not set - skipping", uriEnvName)
continue
}

chM := make(chan prometheus.Metric, 10000)
go func() {
e.Collect(chM)
close(chM)
}()
uri := os.Getenv(uriEnvName)

body := downloadURL(t, ts.URL+"/metrics")
e, _ := NewRedisExporter(uri, Options{Namespace: "test", Registry: prometheus.NewRegistry()})
ts := httptest.NewServer(e)
defer ts.Close()

chM := make(chan prometheus.Metric, 10000)
go func() {
e.Collect(chM)
close(chM)
}()

if !strings.Contains(body, "test_up") {
t.Errorf("error, missing test_up")
body := downloadURL(t, ts.URL+"/metrics")
if !strings.Contains(body, "test_up") {
t.Errorf("%s - response to /metric doesn't contain test_up", uriEnvName)
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/oliver006/redis_exporter
go 1.13

require (
github.com/gomodule/redigo v2.0.1-0.20200211073029-7ac8ae1ada9f+incompatible
github.com/gomodule/redigo v1.8.2
github.com/prometheus/client_golang v1.6.0
github.com/prometheus/client_model v0.2.0
github.com/sirupsen/logrus v1.6.0
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/gomodule/redigo v2.0.1-0.20200211073029-7ac8ae1ada9f+incompatible h1:7uFn3ABPk3VN7vbcd4KFo3PExEw/O5/MuxB6ofAkUeQ=
github.com/gomodule/redigo v2.0.1-0.20200211073029-7ac8ae1ada9f+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
Expand Down Expand Up @@ -87,6 +87,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func getEnvBool(key string, defaultVal bool) bool {
func main() {
var (
redisAddr = flag.String("redis.addr", getEnv("REDIS_ADDR", "redis://localhost:6379"), "Address of the Redis instance to scrape")
redisUser = flag.String("redis.user", getEnv("REDIS_USER", ""), "User name to use for authentication (Redis ACL for Redis 6.0 and newer)")
redisPwd = flag.String("redis.password", getEnv("REDIS_PASSWORD", ""), "Password of the Redis instance to scrape")
namespace = flag.String("namespace", getEnv("REDIS_EXPORTER_NAMESPACE", "redis"), "Namespace for metrics")
checkKeys = flag.String("check-keys", getEnv("REDIS_EXPORTER_CHECK_KEYS", ""), "Comma separated list of key-patterns to export value and length/size, searched for with SCAN")
Expand Down Expand Up @@ -122,6 +123,7 @@ func main() {
exp, err := NewRedisExporter(
*redisAddr,
Options{
User: *redisUser,
Password: *redisPwd,
Namespace: *namespace,
ConfigCommandName: *configCommand,
Expand Down

0 comments on commit 602a120

Please sign in to comment.