-
Notifications
You must be signed in to change notification settings - Fork 428
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
add user and password to uri if the uri does not contain user password #560
Changes from 6 commits
5419d8e
b793c84
1cdf1a6
d2fb77d
36b3fa7
6c101da
c9cddd9
24987e4
1b44f72
7803f17
94de219
bd3922c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,14 +71,25 @@ Connecting user should have sufficient rights to query needed stats: | |
More info about roles in MongoDB [documentation](https://docs.mongodb.com/manual/reference/built-in-roles/#mongodb-authrole-clusterMonitor). | ||
|
||
#### Example | ||
``` | ||
```sh | ||
mongodb_exporter_linux_amd64/mongodb_exporter --mongodb.uri=mongodb://127.0.0.1:17001 | ||
``` | ||
|
||
#### MongoDB Authentication | ||
You can supply the mongodb user/password direct in the `--mongodb.uri=` like `--mongodb.uri=mongodb://user:[email protected]:17001`, you can also supply the mongodb user/password with `--mongodb.user=`, `--mongodb.password=` | ||
but the user and password info will be leaked via `ps` or `top` command, for security issue, you can use `MONGODB_USER` and `MONGODB_PASSWORD` env variable to set user/password for given uri | ||
```sh | ||
MONGODB_USER=XXX MONGODB_PASSWORD=YYY mongodb_exporter_linux_amd64/mongodb_exporter --mongodb.uri=mongodb://127.0.0.1:17001 --mongodb.collstats-colls=db1.c1,db2.c2 | ||
# or | ||
export MONGODB_USER=XXX | ||
export MONGODB_PASSWORD=YYY | ||
mongodb_exporter_linux_amd64/mongodb_exporter --mongodb.uri=mongodb://127.0.0.1:17001 --mongodb.collstats-colls=db1.c1,db2.c2 | ||
``` | ||
|
||
#### Enabling collstats metrics gathering | ||
`--mongodb.collstats-colls` receives a list of databases and collections to monitor using collstats. | ||
Usage example: `--mongodb.collstats-colls=database1.collection1,database2.collection2` | ||
``` | ||
```sh | ||
mongodb_exporter_linux_amd64/mongodb_exporter --mongodb.uri=mongodb://127.0.0.1:17001 --mongodb.collstats-colls=db1.c1,db2.c2 | ||
``` | ||
#### Enabling compatibility mode. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,8 @@ | |
|
||
// GlobalFlags has command line flags to configure the exporter. | ||
type GlobalFlags struct { | ||
User string `name:"mongodb.user" help:"monitor user, need clusterMonitor role in admin db and read role in local db" env:"MONGODB_USER" placeholder:"monitorUser"` | ||
Check failure on line 37 in main.go GitHub Actions / Lint Check
|
||
Password string `name:"mongodb.password" help:"monitor user password" env:"MONGODB_PASSWORD" placeholder:"monitorPassword"` | ||
Check failure on line 38 in main.go GitHub Actions / Lint Check
|
||
CollStatsNamespaces string `name:"mongodb.collstats-colls" help:"List of comma separared databases.collections to get $collStats" placeholder:"db1,db2.col2"` | ||
IndexStatsCollections string `name:"mongodb.indexstats-colls" help:"List of comma separared databases.collections to get $indexStats" placeholder:"db1.col1,db2.col2"` | ||
URI string `name:"mongodb.uri" help:"MongoDB connection URI" env:"MONGODB_URI" placeholder:"mongodb://user:[email protected]:27017/admin?ssl=true"` | ||
|
@@ -89,6 +91,22 @@ | |
e.Run() | ||
} | ||
|
||
func buildURI(uri string, user string, password string) string { | ||
// IF user@pass not contained in uri AND custom user and pass supplied in arguments | ||
// DO concat a new uri with user and pass arguments value | ||
if !strings.Contains(uri, "@") && user != "" && password != "" { | ||
// trim mongodb:// prefix to handle user and pass logic | ||
uri = strings.TrimPrefix(uri, "mongodb://") | ||
|
||
// log.Debugf("add user and pass to the uri") | ||
uri = fmt.Sprintf("%s:%s@%s", user, password, uri) | ||
|
||
// add back mongodb:// | ||
uri = "mongodb://" + uri | ||
} | ||
return uri | ||
} | ||
|
||
func buildExporter(opts GlobalFlags) *exporter.Exporter { | ||
log := logrus.New() | ||
|
||
|
@@ -103,10 +121,7 @@ | |
|
||
log.Debugf("Compatible mode: %v", opts.CompatibleMode) | ||
|
||
if !strings.HasPrefix(opts.URI, "mongodb") { | ||
log.Debugf("Prepending mongodb:// to the URI") | ||
opts.URI = "mongodb://" + opts.URI | ||
} | ||
opts.URI = buildURI(opts.URI, opts.User, opts.Password) | ||
|
||
log.Debugf("Connection URI: %s", opts.URI) | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -37,3 +37,100 @@ | |||||
|
||||||
buildExporter(opts) | ||||||
} | ||||||
|
||||||
func TestBuildURI(t *testing.T) { | ||||||
Check failure on line 41 in main_test.go GitHub Actions / Lint Check
|
||||||
const newUser = "xxx" | ||||||
const newPass = "yyy" | ||||||
|
||||||
const originalBareURI = "127.0.0.1" | ||||||
const originalAuthURI = "usr:[email protected]" | ||||||
|
||||||
const originalPrefixBareURI = "mongodb://127.0.0.1" | ||||||
const originalPrefixAuthURI = "mongodb://usr:[email protected]" | ||||||
const changedPrefixAuthURI = "mongodb://xxx:[email protected]" | ||||||
|
||||||
var newUri string | ||||||
resetNewUri := func() { | ||||||
Check failure on line 53 in main_test.go GitHub Actions / Lint Check
|
||||||
newUri = "" | ||||||
} | ||||||
|
||||||
t.Log("\nuri with prefix and auth, and auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalPrefixAuthURI, newUser, newPass) | ||||||
t.Logf("Origin: %s", originalPrefixAuthURI) | ||||||
t.Logf("Expect: %s", originalPrefixAuthURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != originalPrefixAuthURI { | ||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
|
||||||
t.Log("\nuri with prefix and auth, no auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalPrefixAuthURI, "", "") | ||||||
t.Logf("Origin: %s", originalPrefixAuthURI) | ||||||
t.Logf("Expect: %s", originalPrefixAuthURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != originalPrefixAuthURI { | ||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
|
||||||
t.Log("\nuri with no prefix and auth, and auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalAuthURI, newUser, newPass) | ||||||
t.Logf("Origin: %s", originalAuthURI) | ||||||
t.Logf("Expect: %s", originalAuthURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != originalAuthURI { | ||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
|
||||||
t.Log("\nuri with no prefix and auth, no auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalAuthURI, "", "") | ||||||
t.Logf("Origin: %s", originalAuthURI) | ||||||
t.Logf("Expect: %s", originalAuthURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != originalAuthURI { | ||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
|
||||||
t.Log("\nuri with prefix and no auth, and auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalPrefixBareURI, newUser, newPass) | ||||||
t.Logf("Origin: %s", originalPrefixBareURI) | ||||||
t.Logf("Expect: %s", changedPrefixAuthURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != changedPrefixAuthURI { | ||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
|
||||||
t.Log("\nuri with prefix and no auth, no auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalPrefixBareURI, "", "") | ||||||
t.Logf("Origin: %s", originalPrefixBareURI) | ||||||
t.Logf("Expect: %s", originalPrefixBareURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != originalPrefixBareURI { | ||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
|
||||||
t.Log("\nuri with no prefix and no auth, and auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalBareURI, newUser, newPass) | ||||||
t.Logf("Origin: %s", originalBareURI) | ||||||
t.Logf("Expect: %s", changedPrefixAuthURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != changedPrefixAuthURI { | ||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
|
||||||
t.Log("\nuri with no prefix and no auth, no auth supplied in opt.User/Password") | ||||||
newUri = buildURI(originalBareURI, "", "") | ||||||
t.Logf("Origin: %s", originalBareURI) | ||||||
t.Logf("Expect: %s", originalBareURI) | ||||||
t.Logf("Result: %s", newUri) | ||||||
if newUri != originalBareURI { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This is the expected behavior. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i have reorgnized the test code, 24987e4 could you review it again, thanks |
||||||
t.Fail() | ||||||
} | ||||||
resetNewUri() | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's remove it, anyway we do it a few lines later