From b277e6e2d789716ff679cd8c70bdc0a39874c1dd Mon Sep 17 00:00:00 2001 From: Daniel Nelson Date: Thu, 8 Jun 2017 16:52:01 -0700 Subject: [PATCH] Fix support for mongodb/leofs urls without scheme (#2900) 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. --- plugins/inputs/leofs/leofs.go | 32 ++++++++++++++++++--------- plugins/inputs/mongodb/README.md | 19 ++++++---------- plugins/inputs/mongodb/mongodb.go | 36 +++++++++++++++++++------------ 3 files changed, 50 insertions(+), 37 deletions(-) diff --git a/plugins/inputs/leofs/leofs.go b/plugins/inputs/leofs/leofs.go index e1daf7034..55a727ef8 100644 --- a/plugins/inputs/leofs/leofs.go +++ b/plugins/inputs/leofs/leofs.go @@ -3,6 +3,7 @@ package leofs import ( "bufio" "fmt" + "log" "net/url" "os/exec" "strconv" @@ -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 @@ -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 { @@ -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 diff --git a/plugins/inputs/mongodb/README.md b/plugins/inputs/mongodb/README.md index 678fe0777..f09457821 100644 --- a/plugins/inputs/mongodb/README.md +++ b/plugins/inputs/mongodb/README.md @@ -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:auth_key@10.10.3.30: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 @@ -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:password@10.XX.XX.XX: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 ``` diff --git a/plugins/inputs/mongodb/mongodb.go b/plugins/inputs/mongodb/mongodb.go index 510a313c1..8db9451b0 100644 --- a/plugins/inputs/mongodb/mongodb.go +++ b/plugins/inputs/mongodb/mongodb.go @@ -4,8 +4,10 @@ import ( "crypto/tls" "crypto/x509" "fmt" + "log" "net" "net/url" + "strings" "sync" "time" @@ -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:auth_key@10.10.3.30: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 @@ -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). @@ -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()