diff --git a/receiver/redisreceiver/README.md b/receiver/redisreceiver/README.md index 65c9410393fd..d1d71706dd46 100644 --- a/receiver/redisreceiver/README.md +++ b/receiver/redisreceiver/README.md @@ -56,6 +56,12 @@ Golang's `ParseDuration` function (example: `1h30m`). Valid time units are - `password` (no default): The password used to access the Redis instance; must match the password specified in the `requirepass` server configuration option. +- `transport` (default = `tcp`) Defines the network to use for connecting to the server. Valid Values are `tcp` or `Unix` +- `tls`: + - `insecure` (default = true): whether to disable client transport security for the exporter's connection. + - `ca_file`: path to the CA cert. For a client this verifies the server certificate. Should only be used if `insecure` is set to false. + - `cert_file`: path to the TLS cert to use for TLS required connections. Should only be used if `insecure` is set to false. + - `key_file`: path to the TLS key to use for TLS required connections. Should only be used if `insecure` is set to false. Example: diff --git a/receiver/redisreceiver/config.go b/receiver/redisreceiver/config.go index bbb4a94c24f1..facbf37c2ba1 100644 --- a/receiver/redisreceiver/config.go +++ b/receiver/redisreceiver/config.go @@ -15,6 +15,8 @@ package redisreceiver import ( + "go.opentelemetry.io/collector/config/confignet" + "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/receiver/scraperhelper" ) @@ -22,11 +24,13 @@ type Config struct { scraperhelper.ScraperControllerSettings `mapstructure:",squash"` // TODO: Use one of the configs from core. // The target endpoint. - Endpoint string `mapstructure:"endpoint"` + confignet.NetAddr `mapstructure:",squash"` // TODO allow users to add additional resource key value pairs? // Optional password. Must match the password specified in the // requirepass server configuration option. Password string `mapstructure:"password"` + + TLS configtls.TLSClientSetting `mapstructure:"tls,omitempty"` } diff --git a/receiver/redisreceiver/factory.go b/receiver/redisreceiver/factory.go index 77aded018e43..f1384d20acff 100644 --- a/receiver/redisreceiver/factory.go +++ b/receiver/redisreceiver/factory.go @@ -18,9 +18,10 @@ import ( "context" "time" - "github.com/go-redis/redis/v7" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/config/confignet" + "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver/receiverhelper" "go.opentelemetry.io/collector/receiver/scraperhelper" @@ -42,6 +43,12 @@ func createDefaultConfig() config.Receiver { scs := scraperhelper.DefaultScraperControllerSettings(typeStr) scs.CollectionInterval = 10 * time.Second return &Config{ + NetAddr: confignet.NetAddr{ + Transport: "tcp", + }, + TLS: configtls.TLSClientSetting{ + Insecure: true, + }, ScraperControllerSettings: scs, } } @@ -54,10 +61,7 @@ func createMetricsReceiver( ) (component.MetricsReceiver, error) { oCfg := cfg.(*Config) - scrp, err := newRedisScraper(newRedisClient(&redis.Options{ - Addr: oCfg.Endpoint, - Password: oCfg.Password, - }), set) + scrp, err := newRedisScraper(*oCfg, set) if err != nil { return nil, err } diff --git a/receiver/redisreceiver/go.mod b/receiver/redisreceiver/go.mod index a898e1b8ac36..15c9d429bd6a 100644 --- a/receiver/redisreceiver/go.mod +++ b/receiver/redisreceiver/go.mod @@ -42,8 +42,9 @@ require ( go.opentelemetry.io/otel/trace v1.0.1 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect - golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect + golang.org/x/net v0.0.0-20210917221730-978cfadd31cf // indirect golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71 // indirect + golang.org/x/text v0.3.7 // indirect google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 // indirect google.golang.org/grpc v1.41.0 // indirect google.golang.org/protobuf v1.27.1 // indirect diff --git a/receiver/redisreceiver/go.sum b/receiver/redisreceiver/go.sum index 768b25542640..20a1314fc178 100644 --- a/receiver/redisreceiver/go.sum +++ b/receiver/redisreceiver/go.sum @@ -934,8 +934,9 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210917221730-978cfadd31cf h1:R150MpwJIv1MpS0N/pc+NhTM8ajzvlmxlY5OYsrevXQ= +golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1061,8 +1062,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/receiver/redisreceiver/redis_scraper.go b/receiver/redisreceiver/redis_scraper.go index d37d4e6849f0..46613fa08f93 100644 --- a/receiver/redisreceiver/redis_scraper.go +++ b/receiver/redisreceiver/redis_scraper.go @@ -18,6 +18,7 @@ import ( "context" "time" + "github.com/go-redis/redis/v7" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/model/pdata" "go.opentelemetry.io/collector/receiver/scraperhelper" @@ -33,7 +34,21 @@ type redisScraper struct { timeBundle *timeBundle } -func newRedisScraper(client client, settings component.ReceiverCreateSettings) (scraperhelper.Scraper, error) { +func newRedisScraper(cfg Config, settings component.ReceiverCreateSettings) (scraperhelper.Scraper, error) { + opts := &redis.Options{ + Addr: cfg.Endpoint, + Password: cfg.Password, + Network: cfg.Transport, + } + + var err error + if opts.TLSConfig, err = cfg.TLS.LoadTLSConfig(); err != nil { + return nil, err + } + return newRedisScraperWithClient(newRedisClient(opts), settings) +} + +func newRedisScraperWithClient(client client, settings component.ReceiverCreateSettings) (scraperhelper.Scraper, error) { rs := &redisScraper{ redisSvc: newRedisSvc(client), redisMetrics: getDefaultRedisMetrics(), diff --git a/receiver/redisreceiver/redis_scraper_test.go b/receiver/redisreceiver/redis_scraper_test.go index 8f169006847e..4a2693aa7816 100644 --- a/receiver/redisreceiver/redis_scraper_test.go +++ b/receiver/redisreceiver/redis_scraper_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configtls" "go.uber.org/zap" ) @@ -28,7 +29,7 @@ func TestRedisRunnable(t *testing.T) { logger, _ := zap.NewDevelopment() settings := componenttest.NewNopReceiverCreateSettings() settings.Logger = logger - runner, err := newRedisScraper(newFakeClient(), settings) + runner, err := newRedisScraperWithClient(newFakeClient(), settings) require.NoError(t, err) md, err := runner.Scrape(context.Background()) require.NoError(t, err) @@ -38,5 +39,17 @@ func TestRedisRunnable(t *testing.T) { ilm := rm.InstrumentationLibraryMetrics().At(0) il := ilm.InstrumentationLibrary() assert.Equal(t, "otelcol/redis", il.Name()) +} +func TestNewReceiver_invalid_auth_error(t *testing.T) { + c := createDefaultConfig().(*Config) + c.TLS = configtls.TLSClientSetting{ + TLSSetting: configtls.TLSSetting{ + CAFile: "/invalid", + }, + } + r, err := createMetricsReceiver(context.Background(), componenttest.NewNopReceiverCreateSettings(), c, nil) + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to load TLS config") + assert.Nil(t, r) }