forked from zoni/nagios-check-runner
-
Notifications
You must be signed in to change notification settings - Fork 1
/
exec_publisher.go
94 lines (86 loc) · 2.23 KB
/
exec_publisher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package nca
import (
"bytes"
"errors"
"github.com/kballard/go-shellquote"
"github.com/mitchellh/mapstructure"
log "gopkg.in/inconshreveable/log15.v2"
"os/exec"
"text/template"
)
// ExecPublisherConfig describes the configuration used by the ExecPublisher.
type ExecPublisherConfig struct {
Cmd string // The command to execute on Publish
Stdin string // Template to use to format stdin to Cmd
}
// ExecPublisher is a Publisher which executes an external program whenever
// a check result is received.
type ExecPublisher struct {
config ExecPublisherConfig
log log.Logger
cmd []string // The command to execute on publishing
stdinTemplate *template.Template
}
// Start starts this publisher.
func (p *ExecPublisher) Start() error {
p.log = Log.New("component", "execpublisher")
p.log.Info("Publisher ready")
return nil
}
// Stop stops this publisher.
func (p *ExecPublisher) Stop() error {
p.log.Info("Publisher stopped")
return nil
}
// Publish prints the result of a check to stdout.
func (p *ExecPublisher) Publish(result *CheckResult) error {
var cmd *exec.Cmd
if len(p.cmd) > 1 {
cmd = exec.Command(p.cmd[0], p.cmd[1:]...)
} else {
cmd = exec.Command(p.cmd[0])
}
var b bytes.Buffer
cmd.Stdout = &b
cmd.Stderr = &b
stdin, err := cmd.StdinPipe()
if err != nil {
return err
}
if err = cmd.Start(); err != nil {
p.log.Error("Exec failed", "error", err)
return err
}
if err = p.stdinTemplate.Execute(stdin, result); err != nil {
p.log.Error("Failed to write template data to stdin", "error", err)
return err
}
stdin.Close()
if err = cmd.Wait(); err != nil {
p.log.Error("Exec failed", "error", err, "output", b.String())
return err
}
return nil
}
// Configure sets the configuration to be used by the publisher.
func (p *ExecPublisher) Configure(cfg map[string]interface{}) error {
var result ExecPublisherConfig
if err := mapstructure.Decode(cfg, &result); err != nil {
return err
}
if result.Cmd == "" {
return errors.New("cmd must be specified")
}
args, err := shellquote.Split(result.Cmd)
if err != nil {
return err
}
p.cmd = args
tmpl, err := template.New("stdin").Parse(result.Stdin)
if err != nil {
return nil
}
p.stdinTemplate = tmpl
p.config = result
return nil
}