Skip to content

Commit

Permalink
plugins/inputs/dovecot: Add support for unix domain sockets (#9223)
Browse files Browse the repository at this point in the history
It's safer for dovecot to export metrics via a UDS instead of tcp port,
this will add support for that option.

### Required for all PRs:

<!-- Complete the tasks in the following list. Change [ ] to [x] to
show completion. -->

- [x] Updated associated README.md.
- [x] Wrote appropriate unit tests.

resolves #9215 

dovecot: Add support for unix domain sockets as well
  • Loading branch information
isodude authored May 4, 2021
1 parent 175cd16 commit 537bc9d
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 7 deletions.
3 changes: 3 additions & 0 deletions plugins/inputs/dovecot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ the [upgrading steps][upgrading].
## specify dovecot servers via an address:port list
## e.g.
## localhost:24242
## or as an UDS socket
## e.g.
## /var/run/dovecot/old-stats
##
## If no servers are specified, then localhost is used as the host.
servers = ["localhost:24242"]
Expand Down
23 changes: 18 additions & 5 deletions plugins/inputs/dovecot/dovecot.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,20 @@ func (d *Dovecot) Gather(acc telegraf.Accumulator) error {
}

func (d *Dovecot) gatherServer(addr string, acc telegraf.Accumulator, qtype string, filter string) error {
_, _, err := net.SplitHostPort(addr)
if err != nil {
return fmt.Errorf("%q on url %s", err.Error(), addr)
var proto string

if strings.HasPrefix(addr, "/") {
proto = "unix"
} else {
proto = "tcp"

_, _, err := net.SplitHostPort(addr)
if err != nil {
return fmt.Errorf("%q on url %s", err.Error(), addr)
}
}

c, err := net.DialTimeout("tcp", addr, defaultTimeout)
c, err := net.DialTimeout(proto, addr, defaultTimeout)
if err != nil {
return fmt.Errorf("enable to connect to dovecot server '%s': %s", addr, err)
}
Expand All @@ -108,7 +116,12 @@ func (d *Dovecot) gatherServer(addr string, acc telegraf.Accumulator, qtype stri
return fmt.Errorf("copying message failed for dovecot server '%s': %s", addr, err)
}

host, _, _ := net.SplitHostPort(addr)
var host string
if strings.HasPrefix(addr, "/") {
host = addr
} else {
host, _, _ = net.SplitHostPort(addr)
}

return gatherStats(&buf, acc, host, qtype)
}
Expand Down
47 changes: 45 additions & 2 deletions plugins/inputs/dovecot/dovecot_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package dovecot

import (
"bufio"
"bytes"
"io"
"net"
"net/textproto"
"os"
"testing"
"time"

Expand Down Expand Up @@ -42,11 +47,49 @@ func TestDovecotIntegration(t *testing.T) {

var acc testutil.Accumulator

// Test type=global server=unix
addr := "/tmp/socket"
wait := make(chan int)
go func() {
defer close(wait)

la, err := net.ResolveUnixAddr("unix", addr)
require.NoError(t, err)

l, err := net.ListenUnix("unix", la)
require.NoError(t, err)
defer l.Close()
defer os.Remove(addr)

wait <- 0
conn, err := l.Accept()
require.NoError(t, err)
defer conn.Close()

readertp := textproto.NewReader(bufio.NewReader(conn))
_, err = readertp.ReadLine()
require.NoError(t, err)

buf := bytes.NewBufferString(sampleGlobal)
_, err = io.Copy(conn, buf)
require.NoError(t, err)
}()

// Wait for server to start
<-wait

d := &Dovecot{Servers: []string{addr}, Type: "global"}
err := d.Gather(&acc)
require.NoError(t, err)

tags := map[string]string{"server": addr, "type": "global"}
acc.AssertContainsTaggedFields(t, "dovecot", fields, tags)

// Test type=global
tags := map[string]string{"server": "dovecot.test", "type": "global"}
tags = map[string]string{"server": "dovecot.test", "type": "global"}
buf := bytes.NewBufferString(sampleGlobal)

err := gatherStats(buf, &acc, "dovecot.test", "global")
err = gatherStats(buf, &acc, "dovecot.test", "global")
require.NoError(t, err)

acc.AssertContainsTaggedFields(t, "dovecot", fields, tags)
Expand Down

0 comments on commit 537bc9d

Please sign in to comment.