From abe5e28575926ae2ed46ac02ccf1e41fc74bee56 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. (cherry picked from commit b277e6e2d789716ff679cd8c70bdc0a39874c1dd) --- 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()