A very small, very crappy go binary which wraps around shell commands and sends the result to a local sensu socket as an event.
It's heavily inspired by @solarkennedy's sensu-shell-helper but written in Go and with additional options like TTL support.
The original was in ruby, which didn't really suit the task.
The ruby version coding inspiration is from @agent462's sensu-cli so it may look familiar in certain parts.
NAME:
Sensu Wrapper - Execute a command and send the result to a sensu socket
USAGE:
main [global options] command [command options] [arguments...]
VERSION:
0.3.3
AUTHOR:
Lee Briggs
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--dry-run, -D, -d Output to stdout or not
--name value, -N value, -n value The name of the check
--ttl value, -t value The TTL for the check (default: 0)
--timeout value, -T value Amount of time before the command times out (default: 0)
--source value, -S value, -s value The source of the check
--handlers value, -H value The handlers to use for the check
--json-file value, -f value JSON file to read and add to output
--json value, -j value JSON string to add to output
--api-url value, -a value Send the result to the Sensu API
--api-port value Port for the sensu API (default: 4567)
--api-tls Whether to use TLS for calls to API
--api-username value, -u value Username for Sensu API
--api-password value, -p value Password for Sensu API [$SENSU_API_PASSWORD, $SENSU_PASSWORD]
--help, -h show help
--version, -v print the version
The minimum required is a name and a command to run. The command isn't a flag, it will just take any arguments from the invocation.
This will send a sensu event to localhost port 3030 for sensu's local socket to process.
$ sensu-wrapper -d -n "testing" /bin/echo hello
You can check the output of the JSON that it will send to sensu with --dry-run
$ sensu-wrapper -d -n "testing" /bin/echo hello
{"name":"testing","status":0,"output":"hello\n"}
If you want to send the event from a client different to the client the check is running on, use the source
option
$ sensu-wrapper -n "name" -d -s "mynewclientname" /bin/false
{"name":"name","command":"/bin/false","status":2,"output":"false","handler":[],"source":"mynewclientname","duration":0.0}
If you need to hear from your check every so often and it hasn't called, pass the TTL option (seconds) with -T
Sensu will create an event if it hasn't checked within its TTL.
$ sensu-wrapper -d -n "name" -d -t 60 /bin/echo hello
{"name":"name","status":0,"output":"hello\n","ttl":60}
By default, commands will continue to run until they finish. If you wish to adjust that, specify the timeout flag:
$ sensu-wrapper -d -n "name" -d -T 25 ping 8.8.8.8
{"name":"name","status":0,"output":"hello\n"}
If a command is killed due to timeout, it's assumed to have failed and will return exit code 2
Many people who use Sensu will add arbitrary JSON fields to their checks which are then used in handlers. sensu-wrapper
supports this in two ways.
First, you can add JSON by specifying the path to a file to read in which will then be sent in the check. For example you might have a file like so:
# /tmp/mycheck.json
{
"environment": "production",
"runbook": "http://url",
"message": "there is a problem"
}
You can specify this file with the -f
flag and it'll get appended to any output:
$ sensu-wrapper -n "testing" -f /tmp/json -H default -d --ttl 30 -source "mycheck" /bin/echo hello
{"command":"/bin/echo hello","environment":"production","handlers":["default"],"message":"there is a problem","name":"testing","output":"hello\n","runbook":"http://url","source":"mycheck","status":0,"ttl":30}
Alternatively, you can specify JSON directly as a string:
$ sensu-wrapper -d -n "testing" -j '{"test_field": "hello"}' /bin/echo 'hello'
{"command":"/bin/echo hello","name":"testing","output":"hello\n","status":0,"test_field":"hello"}
Sometimes, the place you choose to run sensu-wrapper may not have a local sensu client available.
For these clients, you can now post the result JSON to the Sensu Results API
$ sensu-wrapper -a "my-sensu-api.example.net" /bin/echo 'hello'
{"issued":1484052388}
If you need TLS, or you want to change the port to send API http requests to, you can do that too:
$ sensu-wrapper -a "my-sensu-api.example.net" --api-port 4568 --api-tls /bin/echo 'hello'
{"issued":1484052388}
Note: This doesn't take care of verification of the TLS endpoint. You'll need to trust the cert on the API
The Sensu API can be secured with a username and password. For these instances, you can specify a username and password:
$ sensu-wrapper -a "http://my-sensu-api.example.net:4567/results" -u sensu -p correct-horse-battery-staple /bin/echo 'hello'
{"issued":1484052384}
If you don't want to set the sensu api password on the command line, you can use environment variables. Just set either SENSU_API_PASSWORD
or SENSU_PASSWORD
$ export SENSU_API_PASSWORD="changeme"
$ sensu-wrapper -a "http://my-sensu-api.example.net:4567/results" -u sensu /bin/echo 'hello'
{"issued":1484052394}
The project uses glide for dependencies.
Make sure your $GOPATH
is set: https://github.com/golang/go/wiki/GOPATH
Install the dependencies
glide install
Build it!
go build main.go
That's it!
- This thing is designed to run arbitrary shell commands without any escaping or safety mechanisms. It's not very safe at all.
- This thing has absolutely no locking. If you need to lock commands, I suggest you use flock(2)
- The performance of this thing hasn't been tested at all. It's running shell commands from within golang, make of that what you will.
- This is terrible code.
Please sent pull requests, I am a terrible developer and anyone who can make this better will be thanked greatly. Also, spec tests. If you fancy helping me write tests, that would also be greatly appreciated, I'm kinda new to this game.