From 375710488df06ce5f2b6af4d234a65a64585fae8 Mon Sep 17 00:00:00 2001 From: Matt Jones Date: Tue, 19 Jul 2016 05:24:06 -0400 Subject: [PATCH] Add support for self-signed certs to RabbitMQ input plugin (#1503) * add initial support to allow self-signed certs When using self-signed the metrics collection will fail, this will allow the user to specify in the input configuration file if they want to skip certificate verification. This is functionally identical to `curl -k` At some point this functionality should be moved to the agent as it is already implemented identically in several different input plugins. * Add initial comment strings to remove noise These should be properly fleshed out at some point to ensure code completeness * refactor to use generic helper function * fix import statement against fork * update changelog --- CHANGELOG.md | 1 + plugins/inputs/rabbitmq/rabbitmq.go | 57 ++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aa149a89..517abea96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ should now look like: ### Features +- [#1503](https://github.com/influxdata/telegraf/pull/1503): Add tls support for certs to RabbitMQ input plugin - [#1289](https://github.com/influxdata/telegraf/pull/1289): webhooks input plugin. Thanks @francois2metz and @cduez! - [#1247](https://github.com/influxdata/telegraf/pull/1247): rollbar webhook plugin. - [#1408](https://github.com/influxdata/telegraf/pull/1408): mandrill webhook plugin. diff --git a/plugins/inputs/rabbitmq/rabbitmq.go b/plugins/inputs/rabbitmq/rabbitmq.go index 18d666a08..8a879d179 100644 --- a/plugins/inputs/rabbitmq/rabbitmq.go +++ b/plugins/inputs/rabbitmq/rabbitmq.go @@ -9,35 +9,59 @@ import ( "time" "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/internal/errchan" "github.com/influxdata/telegraf/plugins/inputs" ) +// DefaultUsername will set a default value that corrasponds to the default +// value used by Rabbitmq const DefaultUsername = "guest" + +// DefaultPassword will set a default value that corrasponds to the default +// value used by Rabbitmq const DefaultPassword = "guest" + +// DefaultURL will set a default value that corrasponds to the default value +// used by Rabbitmq const DefaultURL = "http://localhost:15672" +// RabbitMQ defines the configuration necessary for gathering metrics, +// see the sample config for further details type RabbitMQ struct { URL string Name string Username string Password string - Nodes []string - Queues []string + // Path to CA file + SSLCA string `toml:"ssl_ca"` + // Path to host cert file + SSLCert string `toml:"ssl_cert"` + // Path to cert key file + SSLKey string `toml:"ssl_key"` + // Use SSL but skip chain & host verification + InsecureSkipVerify bool + + // InsecureSkipVerify bool + Nodes []string + Queues []string Client *http.Client } +// OverviewResponse ... type OverviewResponse struct { MessageStats *MessageStats `json:"message_stats"` ObjectTotals *ObjectTotals `json:"object_totals"` QueueTotals *QueueTotals `json:"queue_totals"` } +// Details ... type Details struct { Rate float64 } +// MessageStats ... type MessageStats struct { Ack int64 AckDetails Details `json:"ack_details"` @@ -51,6 +75,7 @@ type MessageStats struct { RedeliverDetails Details `json:"redeliver_details"` } +// ObjectTotals ... type ObjectTotals struct { Channels int64 Connections int64 @@ -59,6 +84,7 @@ type ObjectTotals struct { Queues int64 } +// QueueTotals ... type QueueTotals struct { Messages int64 MessagesReady int64 `json:"messages_ready"` @@ -66,10 +92,11 @@ type QueueTotals struct { MessageBytes int64 `json:"message_bytes"` MessageBytesReady int64 `json:"message_bytes_ready"` MessageBytesUnacknowledged int64 `json:"message_bytes_unacknowledged"` - MessageRam int64 `json:"message_bytes_ram"` + MessageRAM int64 `json:"message_bytes_ram"` MessagePersistent int64 `json:"message_bytes_persistent"` } +// Queue ... type Queue struct { QueueTotals // just to not repeat the same code MessageStats `json:"message_stats"` @@ -83,6 +110,7 @@ type Queue struct { AutoDelete bool `json:"auto_delete"` } +// Node ... type Node struct { Name string @@ -99,6 +127,7 @@ type Node struct { SocketsUsed int64 `json:"sockets_used"` } +// gatherFunc ... type gatherFunc func(r *RabbitMQ, acc telegraf.Accumulator, errChan chan error) var gatherFunctions = []gatherFunc{gatherOverview, gatherNodes, gatherQueues} @@ -109,22 +138,40 @@ var sampleConfig = ` # username = "guest" # password = "guest" + ## Optional SSL Config + # ssl_ca = "/etc/telegraf/ca.pem" + # ssl_cert = "/etc/telegraf/cert.pem" + # ssl_key = "/etc/telegraf/key.pem" + ## Use SSL but skip chain & host verification + # insecure_skip_verify = false + ## A list of nodes to pull metrics about. If not specified, metrics for ## all nodes are gathered. # nodes = ["rabbit@node1", "rabbit@node2"] ` +// SampleConfig ... func (r *RabbitMQ) SampleConfig() string { return sampleConfig } +// Description ... func (r *RabbitMQ) Description() string { return "Read metrics from one or many RabbitMQ servers via the management API" } +// Gather ... func (r *RabbitMQ) Gather(acc telegraf.Accumulator) error { if r.Client == nil { - tr := &http.Transport{ResponseHeaderTimeout: time.Duration(3 * time.Second)} + tlsCfg, err := internal.GetTLSConfig( + r.SSLCert, r.SSLKey, r.SSLCA, r.InsecureSkipVerify) + if err != nil { + return err + } + tr := &http.Transport{ + ResponseHeaderTimeout: time.Duration(3 * time.Second), + TLSClientConfig: tlsCfg, + } r.Client = &http.Client{ Transport: tr, Timeout: time.Duration(4 * time.Second), @@ -286,7 +333,7 @@ func gatherQueues(r *RabbitMQ, acc telegraf.Accumulator, errChan chan error) { "message_bytes": queue.MessageBytes, "message_bytes_ready": queue.MessageBytesReady, "message_bytes_unacked": queue.MessageBytesUnacknowledged, - "message_bytes_ram": queue.MessageRam, + "message_bytes_ram": queue.MessageRAM, "message_bytes_persist": queue.MessagePersistent, "messages": queue.Messages, "messages_ready": queue.MessagesReady,