Skip to content

Commit

Permalink
Fix support for mongodb/leofs urls without scheme (#2900)
Browse files Browse the repository at this point in the history
This was broken by changes in go 1.8 to url.Parse.  This change allows
the string but prompts the user to move to the correct url string.
  • Loading branch information
danielnelson authored Jun 8, 2017
1 parent d2eddec commit f944bd1
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 37 deletions.
32 changes: 22 additions & 10 deletions plugins/inputs/leofs/leofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package leofs
import (
"bufio"
"fmt"
"log"
"net/url"
"os/exec"
"strconv"
Expand All @@ -18,7 +19,7 @@ import (
const oid = ".1.3.6.1.4.1.35450"

// For Manager Master
const defaultEndpoint = "127.0.0.1:4020"
const defaultEndpoint = "udp://127.0.0.1:4020"

type ServerType int

Expand Down Expand Up @@ -135,9 +136,9 @@ var serverTypeMapping = map[string]ServerType{
}

var sampleConfig = `
## An array of URI to gather stats about LeoFS.
## Specify an ip or hostname with port. ie 127.0.0.1:4020
servers = ["127.0.0.1:4021"]
## An array of URLs of the form:
## "udp://" host [ ":" port]
servers = ["udp://127.0.0.1:4020"]
`

func (l *LeoFS) SampleConfig() string {
Expand All @@ -154,17 +155,28 @@ func (l *LeoFS) Gather(acc telegraf.Accumulator) error {
return nil
}
var wg sync.WaitGroup
for _, endpoint := range l.Servers {
_, err := url.Parse(endpoint)
for i, endpoint := range l.Servers {
if !strings.HasPrefix(endpoint, "udp://") {
// Preserve backwards compatibility for hostnames without a
// scheme, broken in go 1.8. Remove in Telegraf 2.0
endpoint = "udp://" + endpoint
log.Printf("W! [inputs.mongodb] Using %q as connection URL; please update your configuration to use an URL", endpoint)
l.Servers[i] = endpoint
}
u, err := url.Parse(endpoint)
if err != nil {
acc.AddError(fmt.Errorf("Unable to parse the address:%s, err:%s", endpoint, err))
acc.AddError(fmt.Errorf("Unable to parse address %q: %s", endpoint, err))
continue
}
port, err := retrieveTokenAfterColon(endpoint)
if err != nil {
acc.AddError(err)
if u.Host == "" {
acc.AddError(fmt.Errorf("Unable to parse address %q", endpoint))
continue
}

port := u.Port()
if port == "" {
port = "4020"
}
st, ok := serverTypeMapping[port]
if !ok {
st = ServerTypeStorage
Expand Down
19 changes: 6 additions & 13 deletions plugins/inputs/mongodb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

```toml
[[inputs.mongodb]]
## An array of URI to gather stats about. Specify an ip or hostname
## with optional port add password. ie,
## An array of URLs of the form:
## "mongodb://" [user ":" pass "@"] host [ ":" port]
## For example:
## mongodb://user:[email protected]:27017,
## mongodb://10.10.3.33:18832,
## 10.0.0.1:10000, etc.
servers = ["127.0.0.1:27017"]
servers = ["mongodb://127.0.0.1:27017"]
gather_perdb_stats = false

## Optional SSL Config
Expand All @@ -19,15 +19,8 @@
## Use SSL but skip chain & host verification
# insecure_skip_verify = false
```

For authenticated mongodb instances use `mongodb://` connection URI

```toml
[[inputs.mongodb]]
servers = ["mongodb://username:[email protected]:27101/mydatabase?authSource=admin"]
```
This connection uri may be different based on your environement and mongodb
setup. If the user doesn't have the required privilege to execute serverStatus
This connection uri may be different based on your environment and mongodb
setup. If the user doesn't have the required privilege to execute serverStatus
command the you will get this error on telegraf

```
Expand Down
36 changes: 22 additions & 14 deletions plugins/inputs/mongodb/mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"net"
"net/url"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -37,12 +39,12 @@ type Ssl struct {
}

var sampleConfig = `
## An array of URI to gather stats about. Specify an ip or hostname
## with optional port add password. ie,
## An array of URLs of the form:
## "mongodb://" [user ":" pass "@"] host [ ":" port]
## For example:
## mongodb://user:[email protected]:27017,
## mongodb://10.10.3.33:18832,
## 10.0.0.1:10000, etc.
servers = ["127.0.0.1:27017"]
servers = ["mongodb://127.0.0.1:27017"]
gather_perdb_stats = false
## Optional SSL Config
Expand All @@ -61,7 +63,7 @@ func (*MongoDB) Description() string {
return "Read metrics from one or many MongoDB servers"
}

var localhost = &url.URL{Host: "127.0.0.1:27017"}
var localhost = &url.URL{Host: "mongodb://127.0.0.1:27017"}

// Reads stats from all configured servers accumulates stats.
// Returns one of the errors encountered while gather stats (if any).
Expand All @@ -72,19 +74,25 @@ func (m *MongoDB) Gather(acc telegraf.Accumulator) error {
}

var wg sync.WaitGroup
for _, serv := range m.Servers {
for i, serv := range m.Servers {
if !strings.HasPrefix(serv, "mongodb://") {
// Preserve backwards compatibility for hostnames without a
// scheme, broken in go 1.8. Remove in Telegraf 2.0
serv = "mongodb://" + serv
log.Printf("W! [inputs.mongodb] Using %q as connection URL; please update your configuration to use an URL", serv)
m.Servers[i] = serv
}

u, err := url.Parse(serv)
if err != nil {
acc.AddError(fmt.Errorf("Unable to parse to address '%s': %s", serv, err))
acc.AddError(fmt.Errorf("Unable to parse address %q: %s", serv, err))
continue
} else if u.Scheme == "" {
u.Scheme = "mongodb"
// fallback to simple string based address (i.e. "10.0.0.1:10000")
u.Host = serv
if u.Path == u.Host {
u.Path = ""
}
}
if u.Host == "" {
acc.AddError(fmt.Errorf("Unable to parse address %q", serv))
continue
}

wg.Add(1)
go func(srv *Server) {
defer wg.Done()
Expand Down

0 comments on commit f944bd1

Please sign in to comment.