sensu-cli-compat 0.6.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +127 -0
- data/bin/sensu +6 -0
- data/bin/sensu-cli +6 -0
- data/lib/sensu-cli.rb +16 -0
- data/lib/sensu-cli/api.rb +62 -0
- data/lib/sensu-cli/base.rb +66 -0
- data/lib/sensu-cli/cli.rb +313 -0
- data/lib/sensu-cli/editor.rb +28 -0
- data/lib/sensu-cli/filter.rb +39 -0
- data/lib/sensu-cli/path.rb +96 -0
- data/lib/sensu-cli/pretty.rb +136 -0
- data/lib/sensu-cli/settings.rb +21 -0
- data/lib/sensu-cli/templates/event.erb +20 -0
- data/lib/sensu-cli/version.rb +3 -0
- data/sensu-cli.gemspec +28 -0
- data/settings.example.rb +3 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 93c6437ccfa0bfec4c2ef12ae2fc7f795da9ea2f
|
4
|
+
data.tar.gz: 8d1b4470a3bb9248737fb91dc76eb9abcd106b00
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba28bd44a8487cf939f6f23892b6af8bb0186ee0cd790a6d230f5d30fcd6a3a15555961deb92c59ef9e67df9dde32fa617002c97d224bb635028c09458b8e9f0
|
7
|
+
data.tar.gz: a45e1623c30498a7114ab72194b87c6bb3ea826a439bb7a8607158e25593a1bb4cf72d8f6bc412218c1ca12a8355c83d0d0070b208b01ca4813028be4c057e4d
|
data/README.md
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
sensu-cli
|
2
|
+
=========
|
3
|
+
```
|
4
|
+
#
|
5
|
+
# Welcome to the sensu-cli.
|
6
|
+
# ______
|
7
|
+
# .-' '-.
|
8
|
+
# .' __ '.
|
9
|
+
# / / \ \
|
10
|
+
# ------------------
|
11
|
+
# /\
|
12
|
+
# '--'
|
13
|
+
# SENSU-CLI
|
14
|
+
#
|
15
|
+
```
|
16
|
+
A sensu-cli for interacting with the sensu api.
|
17
|
+
|
18
|
+
What is Sensu? http://sensuapp.org/
|
19
|
+
|
20
|
+
Features
|
21
|
+
--------
|
22
|
+
* API interaction with info, health, stashes, events, clients, aggregates and checks
|
23
|
+
* Resolve Events
|
24
|
+
* Silence clients and checks
|
25
|
+
* Get Requests (get clients, stashes, events, etc.)
|
26
|
+
* Delete Requests (delete clients, stashes, aggregates and events)
|
27
|
+
|
28
|
+
|
29
|
+
Usage and Configuration
|
30
|
+
-----------------------
|
31
|
+
* gem install sensu-cli
|
32
|
+
|
33
|
+
* There is one settings file for host, port, ssl, and HTTP timeout that lives in your user directory ~/.sensu/settings.rb. You can alternatively place this in /etc/sensu/sensu-cli/settings.rb.
|
34
|
+
|
35
|
+
````
|
36
|
+
host "127.0.0.1"
|
37
|
+
port "4567"
|
38
|
+
ssl false
|
39
|
+
read_timeout 20
|
40
|
+
open_timeout 20
|
41
|
+
````
|
42
|
+
This format was chosen so you can do some ENV magic via your profile and setting up an alias. For details see the [wiki](https://github.com/agent462/sensu-cli/wiki)
|
43
|
+
|
44
|
+
* All Configuration Settings
|
45
|
+
`host` String - Required
|
46
|
+
`port` String/Integer - Required
|
47
|
+
`ssl` Boolean - Optional - Defaults False
|
48
|
+
`read_timeout` Integer - Optional - Default 15 (seconds)
|
49
|
+
`open_timeout` Integer - Optional - Default 5 (seconds)
|
50
|
+
`pretty_colors` Boolean - Optional - Default True
|
51
|
+
`proxy_address` String - Optional
|
52
|
+
`proxy_port` Integer - Optional
|
53
|
+
`user` String - Optional
|
54
|
+
`password` String - Optional
|
55
|
+
|
56
|
+
Examples
|
57
|
+
-----------
|
58
|
+
````
|
59
|
+
Available subcommands: (for details, sensu SUB-COMMAND --help)
|
60
|
+
|
61
|
+
** Aggregate Commands **
|
62
|
+
sensu-cli aggregate list (OPTIONS)
|
63
|
+
sensu-cli aggregate show CHECK (OPTIONS)
|
64
|
+
sensu-cli aggregate delete CHECK
|
65
|
+
|
66
|
+
** Check Commands **
|
67
|
+
sensu-cli check list
|
68
|
+
sensu-cli check show CHECK
|
69
|
+
sensu-cli check request CHECK SUB1,SUB2
|
70
|
+
|
71
|
+
** Client Commands **
|
72
|
+
sensu-cli client list (OPTIONS)
|
73
|
+
sensu-cli client show NODE
|
74
|
+
sensu-cli client delete NODE
|
75
|
+
sensu-cli client history NODE
|
76
|
+
|
77
|
+
** Event Commands **
|
78
|
+
sensu-cli event list
|
79
|
+
sensu-cli event show NODE (OPTIONS)
|
80
|
+
sensu-cli event delete NODE CHECK
|
81
|
+
|
82
|
+
** Health Commands **
|
83
|
+
sensu-cli health (OPTIONS)
|
84
|
+
|
85
|
+
** Info Commands **
|
86
|
+
sensu-cli info
|
87
|
+
|
88
|
+
** Silence Commands **
|
89
|
+
sensu-cli silence NODE (OPTIONS)
|
90
|
+
|
91
|
+
** Stash Commands **
|
92
|
+
sensu-cli stash list (OPTIONS)
|
93
|
+
sensu-cli stash show STASHPATH
|
94
|
+
sensu-cli stash delete STASHPATH
|
95
|
+
sensu-cli stash create PATH
|
96
|
+
|
97
|
+
** Resolve Commands **
|
98
|
+
sensu-cli resolve NODE CHECK
|
99
|
+
|
100
|
+
--version, -v: Print version and exit
|
101
|
+
--help, -h: Show this message
|
102
|
+
````
|
103
|
+
|
104
|
+
Contributions
|
105
|
+
-------------
|
106
|
+
Please provide a pull request. I'm an ops guy, not a developer, so if you're submitting code cleanup, all I ask is that you explain the improvement so I can learn.
|
107
|
+
|
108
|
+
|
109
|
+
License and Author
|
110
|
+
==================
|
111
|
+
I'm releasing this under the MIT or Apache 2.0 license. You pick.
|
112
|
+
|
113
|
+
Author:: Bryan Brandau <agent462@gmail.com>
|
114
|
+
|
115
|
+
Copyright:: 2013, Bryan Brandau
|
116
|
+
|
117
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
118
|
+
you may not use this file except in compliance with the License.
|
119
|
+
You may obtain a copy of the License at
|
120
|
+
|
121
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
122
|
+
|
123
|
+
Unless required by applicable law or agreed to in writing, software
|
124
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
125
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
126
|
+
See the License for the specific language governing permissions and
|
127
|
+
limitations under the License.
|
data/bin/sensu
ADDED
data/bin/sensu-cli
ADDED
data/lib/sensu-cli.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'sensu-cli/settings'
|
2
|
+
require 'sensu-cli/cli'
|
3
|
+
require 'sensu-cli/editor'
|
4
|
+
require 'sensu-cli/pretty'
|
5
|
+
require 'sensu-cli/path.rb'
|
6
|
+
require 'sensu-cli/api.rb'
|
7
|
+
require 'sensu-cli/base.rb'
|
8
|
+
require 'sensu-cli/version.rb'
|
9
|
+
require 'sensu-cli/filter.rb'
|
10
|
+
|
11
|
+
module SensuCli
|
12
|
+
def self.die(code = 0, msg = nil)
|
13
|
+
at_exit { puts msg }
|
14
|
+
Kernel.exit(code)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'json'
|
3
|
+
require 'rainbow/ext/string'
|
4
|
+
|
5
|
+
module SensuCli
|
6
|
+
class Api
|
7
|
+
def request(opts)
|
8
|
+
http = Net::HTTP.new(opts[:host], opts[:port], opts[:proxy_address],
|
9
|
+
opts[:proxy_port])
|
10
|
+
http.read_timeout = opts[:read_timeout]
|
11
|
+
http.open_timeout = opts[:open_timeout]
|
12
|
+
if opts[:ssl]
|
13
|
+
http.use_ssl = true
|
14
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
15
|
+
end
|
16
|
+
proxy_header = { 'api-proxy' => 'true' }
|
17
|
+
case opts[:method]
|
18
|
+
when 'Get'
|
19
|
+
req = Net::HTTP::Get.new(opts[:path], proxy_header)
|
20
|
+
when 'Delete'
|
21
|
+
req = Net::HTTP::Delete.new(opts[:path], proxy_header)
|
22
|
+
when 'Post'
|
23
|
+
req = Net::HTTP::Post.new(opts[:path], proxy_header.merge!('Content-Type' => 'application/json'))
|
24
|
+
req.body = opts[:payload]
|
25
|
+
end
|
26
|
+
req.basic_auth(opts[:user], opts[:password]) if opts[:user] && opts[:password]
|
27
|
+
begin
|
28
|
+
http.request(req)
|
29
|
+
rescue Timeout::Error
|
30
|
+
SensuCli::die(1, 'HTTP request has timed out.'.color(:red))
|
31
|
+
rescue StandardError => e
|
32
|
+
SensuCli::die(1, "An HTTP error occurred. Check your settings. #{e}".color(:red))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def response(code, body, command = nil)
|
37
|
+
case code
|
38
|
+
when '200'
|
39
|
+
JSON.parse(body)
|
40
|
+
when '201'
|
41
|
+
puts 'The stash has been created.' if command == 'stashes' || command == 'silence'
|
42
|
+
when '202'
|
43
|
+
puts 'The item was submitted for processing.'
|
44
|
+
when '204'
|
45
|
+
puts 'Sensu is healthy' if command == 'health'
|
46
|
+
puts 'The item was successfully deleted.' if command == 'aggregates' || command == 'stashes'
|
47
|
+
when '400'
|
48
|
+
puts 'The payload is malformed.'.color(:red)
|
49
|
+
when '401'
|
50
|
+
puts 'The request requires user authentication.'.color(:red)
|
51
|
+
when '404'
|
52
|
+
puts 'The item did not exist.'.color(:cyan)
|
53
|
+
else
|
54
|
+
if command == 'health'
|
55
|
+
puts 'Sensu is not healthy.'.color(:red)
|
56
|
+
else
|
57
|
+
puts "There was an error while trying to complete your request. Response code: #{code}".color(:red)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module SensuCli
|
2
|
+
class Base
|
3
|
+
def setup
|
4
|
+
@cli = Cli.new.global
|
5
|
+
settings
|
6
|
+
api_path(@cli)
|
7
|
+
make_call
|
8
|
+
end
|
9
|
+
|
10
|
+
def settings
|
11
|
+
directory = "#{Dir.home}/.sensu"
|
12
|
+
file = "#{directory}/settings.rb"
|
13
|
+
alt = '/etc/sensu/sensu-cli/settings.rb'
|
14
|
+
settings = Settings.new
|
15
|
+
if settings.file?(file)
|
16
|
+
SensuCli::Config.from_file(file)
|
17
|
+
elsif settings.file?(alt)
|
18
|
+
SensuCli::Config.from_file(alt)
|
19
|
+
else
|
20
|
+
settings.create(directory, file)
|
21
|
+
end
|
22
|
+
Rainbow.enabled = Config.pretty_colors == false ? false : true
|
23
|
+
end
|
24
|
+
|
25
|
+
def api_path(cli)
|
26
|
+
p = PathCreator.new
|
27
|
+
p.respond_to?(cli[:command]) ? path = p.send(cli[:command], cli) : SensuCli::die(1, 'Something Bad Happened')
|
28
|
+
@api = { :path => path[:path], :method => cli[:method], :command => cli[:command], :payload => (path[:payload] || false) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def make_call
|
32
|
+
opts = {
|
33
|
+
:path => @api[:path],
|
34
|
+
:method => @api[:method],
|
35
|
+
:payload => @api[:payload],
|
36
|
+
:host => Config.host,
|
37
|
+
:port => Config.port,
|
38
|
+
:ssl => Config.ssl || false,
|
39
|
+
:user => Config.user || nil,
|
40
|
+
:read_timeout => Config.read_timeout || 15,
|
41
|
+
:open_timeout => Config.open_timeout || 5,
|
42
|
+
:password => Config.password || nil,
|
43
|
+
:proxy_address => Config.proxy_address || nil,
|
44
|
+
:proxy_port => Config.proxy_port || nil
|
45
|
+
}
|
46
|
+
api = Api.new
|
47
|
+
res = api.request(opts)
|
48
|
+
msg = api.response(res.code, res.body, @api[:command])
|
49
|
+
msg = Filter.new(@cli[:fields][:filter]).process(msg) if @cli[:fields][:filter]
|
50
|
+
endpoint = @api[:command]
|
51
|
+
if res.code != '200'
|
52
|
+
SensuCli::die(0)
|
53
|
+
elsif @cli[:fields][:format] == 'single'
|
54
|
+
Pretty.single(msg, endpoint)
|
55
|
+
elsif @cli[:fields][:format] == 'table'
|
56
|
+
fields = nil || @cli[:fields][:fields]
|
57
|
+
Pretty.table(msg, endpoint, fields)
|
58
|
+
elsif @cli[:fields][:format] == 'json'
|
59
|
+
Pretty.json(msg)
|
60
|
+
else
|
61
|
+
Pretty.print(msg, endpoint)
|
62
|
+
end
|
63
|
+
Pretty.count(msg) unless @cli[:fields][:format] == 'table' or @cli[:fields][:format] == 'json'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,313 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'sensu-cli/version'
|
3
|
+
require 'rainbow/ext/string'
|
4
|
+
|
5
|
+
module SensuCli
|
6
|
+
class Cli # rubocop:disable ClassLength
|
7
|
+
SUB_COMMANDS = %w(info client check event stash aggregate silence resolve health)
|
8
|
+
CLIENT_COMMANDS = %w(list show delete history)
|
9
|
+
CHECK_COMMANDS = %w(list show request)
|
10
|
+
EVENT_COMMANDS = %w(list show delete)
|
11
|
+
STASH_COMMANDS = %w(list show delete create)
|
12
|
+
AGG_COMMANDS = %w(list show delete)
|
13
|
+
SIL_COMMANDS = ''
|
14
|
+
RES_COMMANDS = ''
|
15
|
+
INFO_COMMANDS = ''
|
16
|
+
HEALTH_COMMANDS = ''
|
17
|
+
|
18
|
+
CLIENT_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
19
|
+
** Client Commands **
|
20
|
+
sensu-cli client list (OPTIONS)
|
21
|
+
sensu-cli client show NODE
|
22
|
+
sensu-cli client delete NODE
|
23
|
+
sensu-cli client history NODE\n\r
|
24
|
+
EOS
|
25
|
+
INFO_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
26
|
+
** Info Commands **
|
27
|
+
sensu-cli info\n\r
|
28
|
+
EOS
|
29
|
+
HEALTH_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
30
|
+
** Health Commands **
|
31
|
+
sensu-cli health (OPTIONS)\n\r
|
32
|
+
EOS
|
33
|
+
CHECK_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
34
|
+
** Check Commands **
|
35
|
+
sensu-cli check list
|
36
|
+
sensu-cli check show CHECK
|
37
|
+
sensu-cli check request CHECK SUB1,SUB2\n\r
|
38
|
+
EOS
|
39
|
+
EVENT_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
40
|
+
** Event Commands **
|
41
|
+
sensu-cli event list (OPTIONS)
|
42
|
+
sensu-cli event show NODE (OPTIONS)
|
43
|
+
sensu-cli event delete NODE CHECK\n\r
|
44
|
+
EOS
|
45
|
+
STASH_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
46
|
+
** Stash Commands **
|
47
|
+
sensu-cli stash list (OPTIONS)
|
48
|
+
sensu-cli stash show STASHPATH
|
49
|
+
sensu-cli stash delete STASHPATH
|
50
|
+
sensu-cli stash create PATH\n\r
|
51
|
+
EOS
|
52
|
+
AGG_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
53
|
+
** Aggregate Commands **
|
54
|
+
sensu-cli aggregate list (OPTIONS)
|
55
|
+
sensu-cli aggregate show CHECK (OPTIONS)
|
56
|
+
sensu-cli aggregate delete CHECK\n\r
|
57
|
+
EOS
|
58
|
+
SIL_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
59
|
+
** Silence Commands **
|
60
|
+
sensu-cli silence NODE (OPTIONS)\n\r
|
61
|
+
EOS
|
62
|
+
RES_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
63
|
+
** Resolve Commands **
|
64
|
+
sensu-cli resolve NODE CHECK\n\r
|
65
|
+
EOS
|
66
|
+
|
67
|
+
def global
|
68
|
+
global_opts = Trollop::Parser.new do
|
69
|
+
version "sensu-cli version: #{SensuCli::VERSION}"
|
70
|
+
banner <<-'EOS'.gsub(/^ {10}/, '')
|
71
|
+
#
|
72
|
+
# Welcome to the sensu-cli.
|
73
|
+
# ______
|
74
|
+
# .-' '-.
|
75
|
+
# .' __ '.
|
76
|
+
# / / \ \
|
77
|
+
# ------------------
|
78
|
+
# /\
|
79
|
+
# '--'
|
80
|
+
# SENSU-CLI
|
81
|
+
#
|
82
|
+
EOS
|
83
|
+
banner "\n\rAvailable subcommands: (for details, sensu-cli SUB-COMMAND --help)\n\r"
|
84
|
+
banner AGG_BANNER
|
85
|
+
banner CHECK_BANNER
|
86
|
+
banner CLIENT_BANNER
|
87
|
+
banner EVENT_BANNER
|
88
|
+
banner HEALTH_BANNER
|
89
|
+
banner INFO_BANNER
|
90
|
+
banner SIL_BANNER
|
91
|
+
banner STASH_BANNER
|
92
|
+
banner RES_BANNER
|
93
|
+
stop_on SUB_COMMANDS
|
94
|
+
end
|
95
|
+
|
96
|
+
Trollop::with_standard_exception_handling global_opts do
|
97
|
+
global_opts.parse ARGV
|
98
|
+
raise Trollop::HelpNeeded if ARGV.empty? # show help screen
|
99
|
+
end
|
100
|
+
|
101
|
+
cmd = next_argv
|
102
|
+
self.respond_to?(cmd) ? send(cmd) : explode(global_opts)
|
103
|
+
end
|
104
|
+
|
105
|
+
def explode(opts)
|
106
|
+
Trollop::with_standard_exception_handling opts do
|
107
|
+
raise Trollop::HelpNeeded # show help screen
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def deep_merge(hash_one, hash_two)
|
112
|
+
hash_one.merge(hash_two) { |_key, hash_one_item, hash_two_item| deep_merge(hash_one_item, hash_two_item) }
|
113
|
+
end
|
114
|
+
|
115
|
+
def parser(cli)
|
116
|
+
Trollop::Parser.new do
|
117
|
+
banner Cli.const_get("#{cli}_BANNER")
|
118
|
+
stop_on Cli.const_get("#{cli}_COMMANDS")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def explode_if_empty(opts, command)
|
123
|
+
explode(opts) if ARGV.empty? && command != 'list'
|
124
|
+
end
|
125
|
+
|
126
|
+
def next_argv
|
127
|
+
ARGV.shift
|
128
|
+
end
|
129
|
+
|
130
|
+
def client # rubocop:disable MethodLength
|
131
|
+
opts = parser('CLIENT')
|
132
|
+
command = next_argv
|
133
|
+
explode_if_empty(opts, command)
|
134
|
+
case command
|
135
|
+
when 'list'
|
136
|
+
p = Trollop::options do
|
137
|
+
opt :limit, 'The number if clients to return', :short => 'l', :type => :string
|
138
|
+
opt :offset, 'The number of clients to offset before returning', :short => 'o', :type => :string
|
139
|
+
opt :format, 'Available formats; single, table, json', :short => 'f', :type => :string
|
140
|
+
opt :fields, 'Fields for table ouput: -F name,address,subscriptions', :short => 'F', :type => :string
|
141
|
+
opt :filter, 'Field and value to filter on: name,graphite', :type => :string
|
142
|
+
end
|
143
|
+
Trollop::die :format, 'Available optional formats: single, table, json'.color(:red) if p[:format] != 'table' && p[:format] != 'single' && p[:format] != 'json' && p[:format]
|
144
|
+
Trollop::die :fields, 'Fields must be used in conjunction with --format table'.color(:red) if p[:format] != 'table' && p[:fields]
|
145
|
+
Trollop::die :offset, 'Offset depends on the limit option --limit ( -l )'.color(:red) if p[:offset] && !p[:limit]
|
146
|
+
{ :command => 'clients', :method => 'Get', :fields => p }
|
147
|
+
when 'delete'
|
148
|
+
p = Trollop::options
|
149
|
+
item = next_argv # the ARGV.shift needs to happen after Trollop::options to catch --help
|
150
|
+
deep_merge({ :command => 'clients', :method => 'Delete', :fields => { :name => item } }, { :fields => p })
|
151
|
+
when 'show'
|
152
|
+
p = Trollop::options
|
153
|
+
item = next_argv
|
154
|
+
deep_merge({ :command => 'clients', :method => 'Get', :fields => { :name => item } }, { :fields => p })
|
155
|
+
when 'history'
|
156
|
+
p = Trollop::options
|
157
|
+
item = next_argv
|
158
|
+
deep_merge({ :command => 'clients', :method => 'Get', :fields => { :name => item, :history => true } }, { :fields => p })
|
159
|
+
else
|
160
|
+
explode(opts)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def info
|
165
|
+
parser('INFO')
|
166
|
+
p = Trollop::options
|
167
|
+
{ :command => 'info', :method => 'Get', :fields => p }
|
168
|
+
end
|
169
|
+
|
170
|
+
def health
|
171
|
+
parser('HEALTH')
|
172
|
+
p = Trollop::options do
|
173
|
+
opt :consumers, 'The minimum number of consumers', :short => 'c', :type => :string, :required => true
|
174
|
+
opt :messages, 'The maximum number of messages', :short => 'm', :type => :string, :required => true
|
175
|
+
end
|
176
|
+
{ :command => 'health', :method => 'Get', :fields => p }
|
177
|
+
end
|
178
|
+
|
179
|
+
def check
|
180
|
+
opts = parser('CHECK')
|
181
|
+
command = next_argv
|
182
|
+
explode_if_empty(opts, command)
|
183
|
+
item = next_argv
|
184
|
+
case command
|
185
|
+
when 'list'
|
186
|
+
p = Trollop::options do
|
187
|
+
opt :filter, 'Field and value to filter on: command,procs', :type => :string
|
188
|
+
end
|
189
|
+
{ :command => 'checks', :method => 'Get', :fields => p }
|
190
|
+
when 'show'
|
191
|
+
p = Trollop::options
|
192
|
+
deep_merge({ :command => 'checks', :method => 'Get', :fields => { :name => item } }, { :fields => p })
|
193
|
+
when 'request'
|
194
|
+
p = Trollop::options
|
195
|
+
ARGV.empty? ? explode(opts) : subscribers = next_argv.split(',')
|
196
|
+
deep_merge({ :command => 'checks', :method => 'Post', :fields => { :check => item, :subscribers => subscribers } }, { :fields => p })
|
197
|
+
else
|
198
|
+
explode(opts)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def event
|
203
|
+
opts = parser('EVENT')
|
204
|
+
command = next_argv
|
205
|
+
explode_if_empty(opts, command)
|
206
|
+
case command
|
207
|
+
when 'list'
|
208
|
+
p = Trollop::options do
|
209
|
+
opt :filter, 'Field and value to filter on: client,graphite (use "name" as field for client or event name)', :type => :string
|
210
|
+
opt :format, 'Available formats; single, table, json', :short => 'f', :type => :string
|
211
|
+
end
|
212
|
+
Trollop::die :format, 'Available optional formats: single, table, json'.color(:red) if p[:format] != 'table' && p[:format] != 'single' && p[:format] != 'json' && p[:format]
|
213
|
+
{ :command => 'events', :method => 'Get', :fields => p }
|
214
|
+
when 'show'
|
215
|
+
p = Trollop::options do
|
216
|
+
opt :check, 'Returns the check associated with the client', :short => 'k', :type => :string
|
217
|
+
end
|
218
|
+
item = next_argv
|
219
|
+
deep_merge({ :command => 'events', :method => 'Get', :fields => { :client => item } }, { :fields => p })
|
220
|
+
when 'delete'
|
221
|
+
p = Trollop::options
|
222
|
+
item = next_argv
|
223
|
+
check = next_argv
|
224
|
+
explode(opts) if check.nil?
|
225
|
+
deep_merge({ :command => 'events', :method => 'Delete', :fields => { :client => item, :check => check } }, { :fields => p })
|
226
|
+
else
|
227
|
+
explode(opts)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def stash
|
232
|
+
opts = parser('STASH')
|
233
|
+
command = next_argv
|
234
|
+
explode_if_empty(opts, command)
|
235
|
+
case command
|
236
|
+
when 'list'
|
237
|
+
p = Trollop::options do
|
238
|
+
opt :limit, 'The number of stashes to return', :short => 'l', :type => :string
|
239
|
+
opt :offset, 'The number of stashes to offset before returning', :short => 'o', :type => :string
|
240
|
+
opt :format, 'Available formats; single, table, json', :short => 'f', :type => :string
|
241
|
+
opt :filter, 'Field and value to filter on: path,graphite', :type => :string
|
242
|
+
end
|
243
|
+
Trollop::die :offset, 'Offset depends on the limit option --limit ( -l )'.color(:red) if p[:offset] && !p[:limit]
|
244
|
+
Trollop::die :format, 'Available optional formats: single, table, json'.color(:red) if p[:format] != 'table' && p[:format] != 'single' && p[:format] != 'json' && p[:format]
|
245
|
+
{ :command => 'stashes', :method => 'Get', :fields => p }
|
246
|
+
when 'show'
|
247
|
+
p = Trollop::options
|
248
|
+
item = next_argv
|
249
|
+
deep_merge({ :command => 'stashes', :method => 'Get', :fields => { :path => item } }, { :fields => p })
|
250
|
+
when 'delete'
|
251
|
+
p = Trollop::options
|
252
|
+
item = next_argv
|
253
|
+
deep_merge({ :command => 'stashes', :method => 'Delete', :fields => { :path => item } }, { :fields => p })
|
254
|
+
when 'create'
|
255
|
+
p = Trollop::options
|
256
|
+
item = next_argv
|
257
|
+
deep_merge({ :command => 'stashes', :method => 'Post', :fields => { :create => true, :create_path => item } }, { :fields => p })
|
258
|
+
else
|
259
|
+
explode(opts)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def aggregate
|
264
|
+
opts = parser('AGG')
|
265
|
+
command = next_argv
|
266
|
+
explode_if_empty(opts, command)
|
267
|
+
case command
|
268
|
+
when 'list'
|
269
|
+
p = Trollop::options do
|
270
|
+
opt :filter, 'Field and value to filter on: issued,1399505890', :type => :string
|
271
|
+
end
|
272
|
+
{ :command => 'aggregates', :method => 'Get', :fields => p }
|
273
|
+
when 'show'
|
274
|
+
p = Trollop::options do
|
275
|
+
opt :id, 'The id of the check issued.', :short => 'i', :type => :integer
|
276
|
+
opt :limit, 'The number of aggregates to return', :short => 'l', :type => :string
|
277
|
+
opt :offset, 'The number of aggregates to offset before returning', :short => 'o', :type => :string
|
278
|
+
# opt :results, 'Include the check results', :short => 'r', :type => :boolean
|
279
|
+
end
|
280
|
+
Trollop::die :offset, 'Offset depends on the limit option --limit ( -l )'.color(:red) if p[:offset] && !p[:limit]
|
281
|
+
item = next_argv
|
282
|
+
deep_merge({ :command => 'aggregates', :method => 'Get', :fields => { :check => item } }, { :fields => p })
|
283
|
+
when 'delete'
|
284
|
+
p = Trollop::options
|
285
|
+
item = next_argv
|
286
|
+
deep_merge({ :command => 'aggregates', :method => 'Delete', :fields => { :check => item } }, { :fields => p })
|
287
|
+
else
|
288
|
+
explode(opts)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def silence
|
293
|
+
opts = parser('SIL')
|
294
|
+
p = Trollop::options do
|
295
|
+
opt :check, 'The check to silence', :short => 'k', :type => :string
|
296
|
+
opt :owner, 'The owner of the stash', :short => 'o', :type => :string
|
297
|
+
opt :reason, 'The reason this check/node is being silenced', :short => 'r', :type => :string
|
298
|
+
opt :expire, 'The number of seconds the silenced event is valid', :short => 'e', :type => :integer
|
299
|
+
end
|
300
|
+
command = next_argv
|
301
|
+
explode(opts) if command.nil?
|
302
|
+
deep_merge({ :command => 'silence', :method => 'Post', :fields => { :client => command } }, { :fields => p })
|
303
|
+
end
|
304
|
+
|
305
|
+
def resolve
|
306
|
+
opts = parser('RES')
|
307
|
+
command = next_argv
|
308
|
+
p = Trollop::options
|
309
|
+
ARGV.empty? ? explode(opts) : check = next_argv
|
310
|
+
deep_merge({ :command => 'resolve', :method => 'Post', :fields => { :client => command, :check => check } }, { :fields => p })
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module SensuCli
|
5
|
+
class Editor
|
6
|
+
def create_stash(create_path)
|
7
|
+
file = temp_file(:path => create_path, :content => { :timestamp => Time.now.to_i })
|
8
|
+
edit(file)
|
9
|
+
end
|
10
|
+
|
11
|
+
def edit(file)
|
12
|
+
editor = ENV['EDITOR'] ? ENV['EDITOR'] : 'vi'
|
13
|
+
system("#{editor} #{file}")
|
14
|
+
begin
|
15
|
+
JSON.parse(File.read(file))
|
16
|
+
rescue JSON::ParserError
|
17
|
+
SensuCli::die(1, 'The stash you created has invalid JSON.')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def temp_file(template)
|
22
|
+
file = Tempfile.new('sensu')
|
23
|
+
file.write(JSON.pretty_generate(template))
|
24
|
+
file.close
|
25
|
+
file.path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module SensuCli
|
2
|
+
class Filter
|
3
|
+
attr_reader :filter
|
4
|
+
|
5
|
+
def initialize(filter_data)
|
6
|
+
filter_split(filter_data)
|
7
|
+
end
|
8
|
+
|
9
|
+
def filter_split(filter)
|
10
|
+
@filter = filter.sub(' ', '').split(',')
|
11
|
+
end
|
12
|
+
|
13
|
+
def match?(data)
|
14
|
+
data.to_s.include? filter[1]
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect_hash(data)
|
18
|
+
data.any? do |key, value|
|
19
|
+
if value.is_a?(Array)
|
20
|
+
match?(value) if key == filter[0]
|
21
|
+
elsif value.is_a?(Hash)
|
22
|
+
process(value)
|
23
|
+
else
|
24
|
+
match?(value) if key == filter[0]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def process(data)
|
30
|
+
if data.is_a?(Array)
|
31
|
+
data.select do |value|
|
32
|
+
process(value)
|
33
|
+
end
|
34
|
+
elsif data.is_a?(Hash)
|
35
|
+
inspect_hash(data)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module SensuCli
|
2
|
+
class PathCreator
|
3
|
+
def clients(cli)
|
4
|
+
path = '/clients'
|
5
|
+
path << "/#{cli[:fields][:name]}" if cli[:fields][:name]
|
6
|
+
path << '/history' if cli[:fields][:history]
|
7
|
+
path << pagination(cli)
|
8
|
+
respond(path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def info(*)
|
12
|
+
path = '/info'
|
13
|
+
respond(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def health(cli)
|
17
|
+
path = "/health?consumers=#{cli[:fields][:consumers]}&messages=#{cli[:fields][:messages]}"
|
18
|
+
respond(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def stashes(cli)
|
22
|
+
if cli[:fields][:create]
|
23
|
+
e = Editor.new
|
24
|
+
payload = e.create_stash(cli[:fields][:create_path]).to_json
|
25
|
+
end
|
26
|
+
path = '/stashes'
|
27
|
+
path << "/#{cli[:fields][:path]}" if cli[:fields][:path]
|
28
|
+
path << pagination(cli)
|
29
|
+
respond(path, payload)
|
30
|
+
end
|
31
|
+
|
32
|
+
def checks(cli)
|
33
|
+
if cli[:fields][:name]
|
34
|
+
path = "/check/#{cli[:fields][:name]}"
|
35
|
+
elsif cli[:fields][:subscribers]
|
36
|
+
payload = { :check => cli[:fields][:check], :subscribers => cli[:fields][:subscribers] }.to_json
|
37
|
+
path = '/request'
|
38
|
+
else
|
39
|
+
path = '/checks'
|
40
|
+
end
|
41
|
+
respond(path, payload)
|
42
|
+
end
|
43
|
+
|
44
|
+
def events(cli)
|
45
|
+
path = '/events'
|
46
|
+
path << "/#{cli[:fields][:client]}" if cli[:fields][:client]
|
47
|
+
path << "/#{cli[:fields][:check]}" if cli[:fields][:check]
|
48
|
+
respond(path)
|
49
|
+
end
|
50
|
+
|
51
|
+
def resolve(cli)
|
52
|
+
payload = { :client => cli[:fields][:client], :check => cli[:fields][:check] }.to_json
|
53
|
+
path = '/resolve'
|
54
|
+
respond(path, payload)
|
55
|
+
end
|
56
|
+
|
57
|
+
def silence(cli)
|
58
|
+
content = { :timestamp => Time.now.to_i }
|
59
|
+
content.merge!(:owner => cli[:fields][:owner]) if cli[:fields][:owner]
|
60
|
+
content.merge!(:reason => cli[:fields][:reason]) if cli[:fields][:reason]
|
61
|
+
payload = { :content => content }
|
62
|
+
payload.merge!(:expire => cli[:fields][:expire].to_i) if cli[:fields][:expire]
|
63
|
+
silence_path = 'silence'
|
64
|
+
silence_path << "/#{cli[:fields][:client]}" if cli[:fields][:client]
|
65
|
+
silence_path << "/#{cli[:fields][:check]}" if cli[:fields][:check]
|
66
|
+
payload = payload.merge!(:path => silence_path).to_json
|
67
|
+
respond('/stashes', payload)
|
68
|
+
end
|
69
|
+
|
70
|
+
def aggregates(cli)
|
71
|
+
path = '/aggregates'
|
72
|
+
path << "/#{cli[:fields][:check]}" if cli[:fields][:check]
|
73
|
+
path << "/#{cli[:fields][:id]}" if cli[:fields][:id]
|
74
|
+
path << pagination(cli)
|
75
|
+
respond(path)
|
76
|
+
end
|
77
|
+
|
78
|
+
def pagination(cli)
|
79
|
+
if cli[:fields].key?(:limit) && cli[:fields].key?(:offset)
|
80
|
+
"?limit=#{cli[:fields][:limit]}&offset=#{cli[:fields][:offset]}"
|
81
|
+
elsif cli[:fields].key?(:limit)
|
82
|
+
"?limit=#{cli[:fields][:limit]}"
|
83
|
+
else
|
84
|
+
''
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def method_missing(method_name, *_args)
|
89
|
+
puts "Path method: #{method_name} does not exist. "
|
90
|
+
end
|
91
|
+
|
92
|
+
def respond(path, payload = false)
|
93
|
+
{ :path => path, :payload => payload }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'rainbow/ext/string'
|
2
|
+
require 'hirb'
|
3
|
+
require 'json'
|
4
|
+
require 'erubis'
|
5
|
+
|
6
|
+
module SensuCli
|
7
|
+
class Pretty
|
8
|
+
class << self
|
9
|
+
def print(res, endpoint = nil)
|
10
|
+
return no_values if res.empty?
|
11
|
+
case endpoint
|
12
|
+
when 'events'
|
13
|
+
template = File.read(File.expand_path(File.join(File.dirname(__FILE__), 'templates/event.erb')))
|
14
|
+
renderer = Erubis::Eruby.new(template)
|
15
|
+
res.each do |event|
|
16
|
+
puts renderer.result(event)
|
17
|
+
end
|
18
|
+
return
|
19
|
+
end
|
20
|
+
if res.is_a?(Hash)
|
21
|
+
res.each do |key, value|
|
22
|
+
puts "#{key}: ".color(:cyan) + "#{value}".color(:green)
|
23
|
+
end
|
24
|
+
elsif res.is_a?(Array)
|
25
|
+
res.each do |item|
|
26
|
+
puts '-------'.color(:yellow)
|
27
|
+
if item.is_a?(Hash)
|
28
|
+
item.each do |key, value|
|
29
|
+
puts "#{key}: ".color(:cyan) + "#{value}".color(:green)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
puts item.to_s.color(:cyan)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def json(res)
|
39
|
+
puts JSON.pretty_generate(res)
|
40
|
+
end
|
41
|
+
|
42
|
+
def count(res)
|
43
|
+
res.is_a?(Hash) ? count = res.length : count = res.count
|
44
|
+
puts "#{count} total items".color(:yellow) if count
|
45
|
+
end
|
46
|
+
|
47
|
+
def clean(thing)
|
48
|
+
thing = thing.gsub("\n", '/\n') if thing.is_a?(String)
|
49
|
+
thing
|
50
|
+
end
|
51
|
+
|
52
|
+
def no_values
|
53
|
+
puts 'no values for this request'.color(:cyan)
|
54
|
+
end
|
55
|
+
|
56
|
+
def single(res, endpoint = nil)
|
57
|
+
return no_values if res.empty?
|
58
|
+
case endpoint
|
59
|
+
when 'events'
|
60
|
+
res = event_data(res)
|
61
|
+
end
|
62
|
+
keys = res.map { |item| item.keys }.flatten.uniq.sort
|
63
|
+
|
64
|
+
# Remove fields with spaces (breaks awkage)
|
65
|
+
keys.select! do |key|
|
66
|
+
res.none? { |item| item[key].to_s.include?(' ') }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Find max value lengths
|
70
|
+
value_lengths = {}
|
71
|
+
keys.each do |key|
|
72
|
+
max_value_length = res.map { |item| item[key].to_s.length }.max
|
73
|
+
value_lengths[key] = [max_value_length, key.length].max
|
74
|
+
end
|
75
|
+
|
76
|
+
# Print header
|
77
|
+
lengths = keys.map { |key| "%-#{value_lengths[key]}s" }.join(' ')
|
78
|
+
puts format(lengths, *keys)
|
79
|
+
|
80
|
+
# Print value rows
|
81
|
+
res.each do |item|
|
82
|
+
if item.is_a?(Hash)
|
83
|
+
values = keys.map { |key| item[key] }
|
84
|
+
puts format(lengths, *values)
|
85
|
+
else
|
86
|
+
puts item.to_s.color(:cyan)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def parse_fields(fields)
|
92
|
+
fields.split(',')
|
93
|
+
end
|
94
|
+
|
95
|
+
def event_data(res)
|
96
|
+
events = []
|
97
|
+
res.each do |event|
|
98
|
+
events << {
|
99
|
+
'client' => event['client']['name'],
|
100
|
+
'address' => event['client']['address'],
|
101
|
+
'check' => event['check']['name'],
|
102
|
+
'interval' => event['check']['interval'],
|
103
|
+
'occurrences' => event['occurrences'],
|
104
|
+
'status' => event['check']['status'],
|
105
|
+
'handlers' => event['check']['handlers'],
|
106
|
+
'issued' => event['check']['issued'],
|
107
|
+
'executed' => event['check']['executed'],
|
108
|
+
'output' => event['check']['output'].rstrip
|
109
|
+
}
|
110
|
+
end
|
111
|
+
events
|
112
|
+
end
|
113
|
+
|
114
|
+
def table(res, endpoint = nil, fields = nil)
|
115
|
+
return no_values if res.empty?
|
116
|
+
case endpoint
|
117
|
+
when 'events'
|
118
|
+
keys = %w(check client address interval occurrences status handlers issued executed output)
|
119
|
+
render_table(event_data(res), keys)
|
120
|
+
else
|
121
|
+
if fields
|
122
|
+
keys = parse_fields(fields)
|
123
|
+
else
|
124
|
+
keys = res.map { |item| item.keys }.flatten.uniq
|
125
|
+
end
|
126
|
+
render_table(res, keys)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def render_table(data, keys)
|
131
|
+
terminal_size = Hirb::Util.detect_terminal_size
|
132
|
+
puts Hirb::Helpers::AutoTable.render(data, :max_width => terminal_size[0], :fields => keys)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'mixlib/config'
|
3
|
+
require 'rainbow/ext/string'
|
4
|
+
|
5
|
+
module SensuCli
|
6
|
+
class Settings
|
7
|
+
def file?(file)
|
8
|
+
!File.readable?(file) ? false : true # rubocop:disable FavorUnlessOverNegatedIf
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(directory, file)
|
12
|
+
FileUtils.mkdir_p(directory) unless File.directory?(directory)
|
13
|
+
FileUtils.cp(File.join(File.dirname(__FILE__), '../../settings.example.rb'), file)
|
14
|
+
SensuCli::die(0, "We created the configuration file for you at #{file}. You can also place this in /etc/sensu/sensu-cli/settings.rb. Edit the settings as needed.".color(:red))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Config
|
19
|
+
extend(Mixlib::Config)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%= "-------".color(:yellow) %>
|
2
|
+
<%= "id:".color(:blue).bright %> <%= id.to_s.color(:green) %>
|
3
|
+
<%= "client name:".color(:blue).bright %> <%= client['name'].to_s.color(:green) %>
|
4
|
+
<%= "address:".color(:cyan) %> <%= client['address'].to_s.color(:green) %>
|
5
|
+
<%= "subscriptions:".color(:cyan) %> <%= client['subscriptions'].to_s.color(:green) %>
|
6
|
+
<%= "version:".color(:cyan) %> <%= client['version'].to_s.color(:green) %>
|
7
|
+
<%= "timestamp:".color(:cyan) %> <%= client['timestamp'].to_s.color(:green) %>
|
8
|
+
<%= "check name:".color(:blue).bright %> <%= check['name'].to_s.color(:green) %>
|
9
|
+
<%= "command:".color(:cyan) %> <%= check['command'].to_s.color(:green) %>
|
10
|
+
<%= "handlers:".color(:cyan) %> <%= check['handlers'].to_s.color(:green) %>
|
11
|
+
<%= "interval:".color(:cyan) %> <%= check['interval'].to_s.color(:green) %>
|
12
|
+
<%= "subscribers:".color(:cyan) %> <%= check['subscribers'].to_s.color(:green) %>
|
13
|
+
<%= "issued:".color(:cyan) %> <%= check['issued'].to_s.color(:green) %>
|
14
|
+
<%= "executed:".color(:cyan) %> <%= check['executed'].to_s.color(:green) %>
|
15
|
+
<%= "duration:".color(:cyan) %> <%= check['duration'].to_s.color(:green) %>
|
16
|
+
<%= "output:".color(:cyan) %> <%= check['output'].rstrip.to_s.color(:green) %>
|
17
|
+
<%= "status:".color(:cyan) %> <%= check['status'].to_s.color(:green) %>
|
18
|
+
<%= "history:".color(:cyan) %> <%= check['history'].to_s.color(:green) %>
|
19
|
+
<%= "occurrences:".color(:blue).bright %> <%= occurrences.to_s.color(:green) %>
|
20
|
+
<%= "action:".color(:blue).bright %> <%= action.to_s.color(:green) %>
|
data/sensu-cli.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'lib', 'sensu-cli', 'version')
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'sensu-cli-compat'
|
5
|
+
s.version = SensuCli::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.summary = 'A command line utility for Sensu.'
|
8
|
+
s.description = 'A command line utility for interacting with the Sensu api.'
|
9
|
+
s.authors = ['Bryan Brandau', 'Rob Thomas']
|
10
|
+
s.email = ['agent462@gmail.com', 'xrobau@gmail.com']
|
11
|
+
s.has_rdoc = false
|
12
|
+
s.licenses = %w(MIT APACHE)
|
13
|
+
s.homepage = 'http://github.com/xrobau/sensu-cli'
|
14
|
+
|
15
|
+
s.add_dependency('rainbow', '1.99.2')
|
16
|
+
s.add_dependency('trollop', '2.0')
|
17
|
+
s.add_dependency('mixlib-config', '2.1.0')
|
18
|
+
s.add_dependency('hirb', '0.7.1')
|
19
|
+
s.add_dependency('erubis', '2.7.0')
|
20
|
+
s.add_dependency('json', '1.8.1')
|
21
|
+
|
22
|
+
s.add_development_dependency('rspec')
|
23
|
+
s.add_development_dependency('rubocop')
|
24
|
+
|
25
|
+
s.files = Dir.glob('{bin,lib}/**/*') + %w(sensu-cli.gemspec README.md settings.example.rb)
|
26
|
+
s.executables = Dir.glob('bin/**/*').map { |file| File.basename(file) }
|
27
|
+
s.require_paths = ['lib']
|
28
|
+
end
|
data/settings.example.rb
ADDED
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sensu-cli-compat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.3.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bryan Brandau
|
8
|
+
- Rob Thomas
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2014-12-04 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rainbow
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - "="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.99.2
|
23
|
+
type: :runtime
|
24
|
+
version_requirements: *id001
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: trollop
|
27
|
+
prerelease: false
|
28
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: "2.0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id002
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: mixlib-config
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - "="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 2.1.0
|
43
|
+
type: :runtime
|
44
|
+
version_requirements: *id003
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: hirb
|
47
|
+
prerelease: false
|
48
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - "="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.7.1
|
53
|
+
type: :runtime
|
54
|
+
version_requirements: *id004
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: erubis
|
57
|
+
prerelease: false
|
58
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 2.7.0
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id005
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: json
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - "="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.8.1
|
73
|
+
type: :runtime
|
74
|
+
version_requirements: *id006
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rspec
|
77
|
+
prerelease: false
|
78
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- &id008
|
81
|
+
- ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: "0"
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id007
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: rubocop
|
88
|
+
prerelease: false
|
89
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- *id008
|
92
|
+
type: :development
|
93
|
+
version_requirements: *id009
|
94
|
+
description: A command line utility for interacting with the Sensu api.
|
95
|
+
email:
|
96
|
+
- agent462@gmail.com
|
97
|
+
- xrobau@gmail.com
|
98
|
+
executables:
|
99
|
+
- sensu
|
100
|
+
- sensu-cli
|
101
|
+
extensions: []
|
102
|
+
|
103
|
+
extra_rdoc_files: []
|
104
|
+
|
105
|
+
files:
|
106
|
+
- README.md
|
107
|
+
- bin/sensu
|
108
|
+
- bin/sensu-cli
|
109
|
+
- lib/sensu-cli.rb
|
110
|
+
- lib/sensu-cli/api.rb
|
111
|
+
- lib/sensu-cli/base.rb
|
112
|
+
- lib/sensu-cli/cli.rb
|
113
|
+
- lib/sensu-cli/editor.rb
|
114
|
+
- lib/sensu-cli/filter.rb
|
115
|
+
- lib/sensu-cli/path.rb
|
116
|
+
- lib/sensu-cli/pretty.rb
|
117
|
+
- lib/sensu-cli/settings.rb
|
118
|
+
- lib/sensu-cli/templates/event.erb
|
119
|
+
- lib/sensu-cli/version.rb
|
120
|
+
- sensu-cli.gemspec
|
121
|
+
- settings.example.rb
|
122
|
+
homepage: http://github.com/xrobau/sensu-cli
|
123
|
+
licenses:
|
124
|
+
- MIT
|
125
|
+
- APACHE
|
126
|
+
metadata: {}
|
127
|
+
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- *id008
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- *id008
|
139
|
+
requirements: []
|
140
|
+
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 2.4.5
|
143
|
+
signing_key:
|
144
|
+
specification_version: 4
|
145
|
+
summary: A command line utility for Sensu.
|
146
|
+
test_files: []
|
147
|
+
|