Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow URL format in Metricbeat Redis module #12408

Merged
merged 11 commits into from
Jun 14, 2019
Merged

Allow URL format in Metricbeat Redis module #12408

merged 11 commits into from
Jun 14, 2019

Conversation

kaiyan-sheng
Copy link
Contributor

Continues with #10920

Original commit message:

Potential fix for #10917

This change will keep the usual functionality when using this approach:

- module: redis
  period: 10s
  # Redis hosts
  hosts: ["127.0.0.1:6379", "127.0.0.2:6379"]

Additionally allowing the use of Redis URL syntax:

- module: redis
  period: 10s
  # Redis hosts
  hosts: ["127.0.0.1:6379", "redis://:testpassword@127.0.0.2:6379"]

The password field will be used for all host:port values. On URL values, the password set in the scheme will have priority.

Co-authored-by: Matias Insaurralde matias@insaurral.de

@kaiyan-sheng kaiyan-sheng requested review from a team as code owners June 4, 2019 03:25
@kaiyan-sheng kaiyan-sheng self-assigned this Jun 4, 2019
@exekias exekias closed this Jun 4, 2019
@exekias exekias reopened this Jun 4, 2019
@exekias
Copy link
Contributor

exekias commented Jun 4, 2019

Tests seem to be failing.

Is this change backwards compatible? I think so but want to confirm

@kaiyan-sheng
Copy link
Contributor Author

Tests seem to be failing.

Is this change backwards compatible? I think so but want to confirm

Thanks for reviewing. The failing test is fixed and also added a test to prove it is backwards compatible.

@exekias
Copy link
Contributor

exekias commented Jun 5, 2019

LGTM, this will need a changelog

@jsoriano
Copy link
Member

jsoriano commented Jun 5, 2019

It seems that the password in redis URIs can be defined as parameter too (redis://HOST[:PORT][?db=DATABASE[&password=PASSWORD]]), should we just replace the dialer function to use redis.DialURI so we don't have to care about all valid URIs?

@kaiyan-sheng
Copy link
Contributor Author

kaiyan-sheng commented Jun 5, 2019

It seems that the password in redis URIs can be defined as parameter too (redis://HOST[:PORT][?db=DATABASE[&password=PASSWORD]]), should we just replace the dialer function to use redis.DialURI so we don't have to care about all valid URIs?

Good point, thank you @jsoriano ! I just changed the CreatePool method to call rd.DialURL directly. But when I was testing this, redis://:password@127.0.0.1:6379 works.

But the parameter way redis://127.0.0.1:6379?password=test does not work. I got an error 2019-06-05T15:37:53.885-0600 ERROR redis/redis.go:70 Error retrieving INFO stats: NOAUTH Authentication required.

When I look for documentation on URL format, I see this: https://www.npmjs.com/package/redis-url#url-format hmmm is the parameter way officially supported or I'm doing something wrong here? 😬

@kaiyan-sheng
Copy link
Contributor Author

@jsoriano I added some 'nasty' parsing in order to make redis://HOST[:PORT][?password=PASSWORD[&db=DATABASE]] format URL working. Turned out redis.DialURL does not recognize the PASSWORD and DATABASE as a part of the query parameters. I had to manually parse PASSWORD and DATABASE out and pass them as DialOptions into DialURL function.

Copy link
Member

@andrewkroh andrewkroh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick drive-by review. 😄 (I may have commented on things that were already discussed, so sorry if I did.)

metricbeat/module/redis/_meta/docs.asciidoc Outdated Show resolved Hide resolved
metricbeat/module/redis/_meta/docs.asciidoc Outdated Show resolved Hide resolved
metricbeat/module/redis/info/info.go Show resolved Hide resolved
metricbeat/module/redis/metricset.go Outdated Show resolved Hide resolved
metricbeat/module/redis/metricset.go Outdated Show resolved Hide resolved
@kaiyan-sheng kaiyan-sheng added in progress Pull request is currently in progress. and removed [zube]: In Review review labels Jun 12, 2019
Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turned out redis.DialURL does not recognize the PASSWORD and DATABASE as a part of the query parameters. I had to manually parse PASSWORD and DATABASE out and pass them as DialOptions into DialURL function.

Ouch 🙁 docs misguided me, thanks for investigating this! And great you found a solution. Maybe we can contribute back the support for query parameters to the client library we use? 🙂

Is there any reason to don't use URL.Query() or url.ParseQuery() to parse the query arguments?

metricbeat/module/redis/metricset.go Outdated Show resolved Hide resolved
metricbeat/module/redis/redis.go Outdated Show resolved Hide resolved
metricbeat/module/redis/info/info_test.go Show resolved Hide resolved
Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, a few more small things... mainly about handing of database configuration, and some details in error messages and tests.

metricbeat/module/redis/metricset_test.go Outdated Show resolved Hide resolved
metricbeat/module/redis/metricset_test.go Show resolved Hide resolved
metricbeat/module/redis/redis.go Outdated Show resolved Hide resolved
metricbeat/module/redis/metricset.go Outdated Show resolved Hide resolved
metricbeat/module/redis/metricset.go Outdated Show resolved Hide resolved
metricbeat/module/redis/metricset.go Outdated Show resolved Hide resolved
metricbeat/module/redis/metricset.go Show resolved Hide resolved
err := base.Module().UnpackConfig(&config)
if err != nil {
return nil, errors.Wrap(err, "failed to read configuration")
}

password, database, err := getPasswordDatabase(base.HostData().URI, base.HostData().Password)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Database can be also in the path of the url (redis://[:password@]host[:port][/db-number][?option=value]). For an URL like redis://host/16, will it use the 0 returned here instead of the 16? I think we should add the DialDatabase option only if the database is set as an option.
If it complicates things a lot I am also ok with giving some working examples in the documentation.
In any case it wouldn't be a regression because I think that we cannot configure the database now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed it!! Thanks!!
I added a part in the same function to check db-number from URI itself. Please let me know what you think 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks! We should contribute these things to redigo so all this is done by DialURL 😄

@kaiyan-sheng kaiyan-sheng added review and removed in progress Pull request is currently in progress. labels Jun 14, 2019
Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the work here to cover all the cases! 👍

},
{
"test redis uri with db number in URI and query field",
mb.HostData{URI: "redis://:password1@127.0.0.2:6379/1?password=password2&db=2", Password: "password1"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😄

@kaiyan-sheng
Copy link
Contributor Author

Thanks for all the reviews!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review Team:Integrations Label for the Integrations team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants