sensu-cli 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/README.md +127 -0
- data/bin/sensu +8 -0
- data/lib/sensu-cli.rb +2 -0
- data/lib/sensu-cli/cli.rb +289 -0
- data/lib/sensu-cli/sensu.rb +165 -0
- data/lib/sensu-cli/settings.rb +24 -0
- data/lib/sensu-cli/version.rb +3 -0
- data/sensu-cli.gemspec +22 -0
- data/settings.example.rb +3 -0
- metadata +94 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZDRkNzYxOGQyMmRkM2QzMjZhMmFhNDAyYjRjYWYzNWNkYmJmYWYyYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YjA0OGMyMTk2YjI4MTkyNjc1YmUwZTU3ZDQ1OWE5YTI2MjllZjMyMA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZTU0MTUxMjk5ODY0YjkxZDQ5ODY5ZjYxOGMzOWY1ZWFlOTZlZWY4NjFjMmFh
|
10
|
+
ODQ1MGYyNDk2ZTZiMDJhNDIwZTY4MzZhODJmMmNiYzQwZWQxOTg5OTgzNjRh
|
11
|
+
OTAwNmNhY2M1N2YyN2FiNmY1OGEzNTk3NjcwNjhhMzNjMGIxMGM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NzY1ZjEyNzRjZjEzOGRhYmIwZjcxM2Q2Mzk0OWU1NjU0MTFiYjc2YzY3YWFm
|
14
|
+
NDZiMjEyNGY1NjQ3NTMwOWFiYzI4ZTdhYjNhNzY1YTg2OGNkZmJiY2IxN2Mw
|
15
|
+
YjVjMDY3OGE4YzIyYmY3OTY2OTJjODBhNjMyZDVhNWMzYThlNGE=
|
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
|
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 and events)
|
27
|
+
|
28
|
+
|
29
|
+
Usage and Configuration
|
30
|
+
-----------------------
|
31
|
+
* gem build sensu-cli.gemspec
|
32
|
+
* gem install ./{gem file created}
|
33
|
+
|
34
|
+
* There is one settings file for host, port and ssl that lives in your user directory ~/.sensu/settings.rb. You can alternatively place this in /etc/sensu/sensu-cli/settings.rb.
|
35
|
+
|
36
|
+
````
|
37
|
+
host "127.0.0.1"
|
38
|
+
port "4567"
|
39
|
+
ssl false
|
40
|
+
````
|
41
|
+
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)
|
42
|
+
|
43
|
+
* If your Sensu API has basic auth, add the parameters to the config.
|
44
|
+
|
45
|
+
````
|
46
|
+
host "127.0.0.1"
|
47
|
+
port "4567"
|
48
|
+
ssl false
|
49
|
+
user "some_user"
|
50
|
+
password "some_secret_password"
|
51
|
+
````
|
52
|
+
|
53
|
+
|
54
|
+
Examples
|
55
|
+
-----------
|
56
|
+
````
|
57
|
+
Available subcommands: (for details, sensu SUB-COMMAND --help)
|
58
|
+
|
59
|
+
** Aggregate Commands **
|
60
|
+
sensu aggregate list (OPTIONS)
|
61
|
+
sensu aggregate show CHECK
|
62
|
+
|
63
|
+
** Check Commands **
|
64
|
+
sensu check list
|
65
|
+
sensu check show CHECK
|
66
|
+
sensu check request CHECK SUB1,SUB2
|
67
|
+
|
68
|
+
** Client Commands **
|
69
|
+
sensu client list (OPTIONS)
|
70
|
+
sensu client show NODE
|
71
|
+
sensu client delete NODE
|
72
|
+
sensu client history NODE
|
73
|
+
|
74
|
+
** Event Commands **
|
75
|
+
sensu event list
|
76
|
+
sensu event show NODE (OPTIONS)
|
77
|
+
sensu event delete NODE CHECK
|
78
|
+
|
79
|
+
** Health Commands **
|
80
|
+
sensu health (OPTIONS)
|
81
|
+
|
82
|
+
** Info Commands **
|
83
|
+
sensu info
|
84
|
+
|
85
|
+
** Silence Commands **
|
86
|
+
sensu silence NODE (OPTIONS)
|
87
|
+
|
88
|
+
** Stash Commands **
|
89
|
+
sensu stash list (OPTIONS)
|
90
|
+
sensu stash show STASHPATH
|
91
|
+
sensu stash delete STASHPATH
|
92
|
+
|
93
|
+
** Resolve Commands **
|
94
|
+
sensu resolve NODE CHECK
|
95
|
+
|
96
|
+
--version, -v: Print version and exit
|
97
|
+
--help, -h: Show this message
|
98
|
+
````
|
99
|
+
|
100
|
+
Contributions
|
101
|
+
-------------
|
102
|
+
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.
|
103
|
+
|
104
|
+
TODO
|
105
|
+
----
|
106
|
+
* support deletion of aggregate check
|
107
|
+
* cleanup the cli
|
108
|
+
* Once complete api support is implemented I'll add other features like filtering or issuing a event.
|
109
|
+
|
110
|
+
License and Author
|
111
|
+
==================
|
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/lib/sensu-cli.rb
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'sensu-cli/version'
|
3
|
+
|
4
|
+
module SensuCli
|
5
|
+
class Cli
|
6
|
+
SUB_COMMANDS = %w(info client check event stash aggregate silence resolve health)
|
7
|
+
CLIENT_COMMANDS = %w(list show delete history)
|
8
|
+
CHECK_COMMANDS = %w(list show request)
|
9
|
+
EVENT_COMMANDS = %w(list show delete)
|
10
|
+
STASH_COMMANDS = %w(list show delete)
|
11
|
+
AGG_COMMANDS = %w(list show)
|
12
|
+
SIL_COMMANDS = ""
|
13
|
+
RES_COMMANDS = ""
|
14
|
+
INFO_COMMANDS = ""
|
15
|
+
HEALTH_COMMANDS = ""
|
16
|
+
|
17
|
+
CLIENT_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
18
|
+
** Client Commands **
|
19
|
+
sensu client list (OPTIONS)
|
20
|
+
sensu client show NODE
|
21
|
+
sensu client delete NODE
|
22
|
+
sensu client history NODE\n\r
|
23
|
+
EOS
|
24
|
+
INFO_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
25
|
+
** Info Commands **
|
26
|
+
sensu info\n\r
|
27
|
+
EOS
|
28
|
+
HEALTH_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
29
|
+
** Health Commands **
|
30
|
+
sensu health (OPTIONS)\n\r
|
31
|
+
EOS
|
32
|
+
CHECK_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
33
|
+
** Check Commands **
|
34
|
+
sensu check list
|
35
|
+
sensu check show CHECK
|
36
|
+
sensu check request CHECK SUB1,SUB2\n\r
|
37
|
+
EOS
|
38
|
+
EVENT_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
39
|
+
** Event Commands **
|
40
|
+
sensu event list
|
41
|
+
sensu event show NODE (OPTIONS)
|
42
|
+
sensu event delete NODE CHECK\n\r
|
43
|
+
EOS
|
44
|
+
STASH_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
45
|
+
** Stash Commands **
|
46
|
+
sensu stash list (OPTIONS)
|
47
|
+
sensu stash show STASHPATH
|
48
|
+
sensu stash delete STASHPATH\n\r
|
49
|
+
EOS
|
50
|
+
#sensu stash create
|
51
|
+
#apost '/stashes'
|
52
|
+
AGG_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
53
|
+
** Aggregate Commands **
|
54
|
+
sensu aggregate list (OPTIONS)
|
55
|
+
sensu aggregate show CHECK\n\r
|
56
|
+
EOS
|
57
|
+
#sensu aggregate delete CHECK\n\r
|
58
|
+
#aget %r{/aggregates?/([\w\.-]+)/([\w\.-]+)$} do |check_name, check_issued|
|
59
|
+
SIL_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
60
|
+
** Silence Commands **
|
61
|
+
sensu silence NODE (OPTIONS)\n\r
|
62
|
+
EOS
|
63
|
+
RES_BANNER = <<-EOS.gsub(/^ {10}/, '')
|
64
|
+
** Resolve Commands **
|
65
|
+
sensu resolve NODE CHECK\n\r
|
66
|
+
EOS
|
67
|
+
|
68
|
+
def global
|
69
|
+
global_opts = Trollop::Parser.new do
|
70
|
+
version "sensu-cli version: #{SensuCli::VERSION}"
|
71
|
+
banner <<-'EOS'.gsub(/^ {10}/, '')
|
72
|
+
#
|
73
|
+
# Welcome to the sensu-cli.
|
74
|
+
# ______
|
75
|
+
# .-' '-.
|
76
|
+
# .' __ '.
|
77
|
+
# / / \ \
|
78
|
+
# ------------------
|
79
|
+
# /\
|
80
|
+
# '--'
|
81
|
+
# SENSU
|
82
|
+
#
|
83
|
+
EOS
|
84
|
+
banner "\n\rAvailable subcommands: (for details, sensu SUB-COMMAND --help)\n\r"
|
85
|
+
banner AGG_BANNER
|
86
|
+
banner CHECK_BANNER
|
87
|
+
banner CLIENT_BANNER
|
88
|
+
banner EVENT_BANNER
|
89
|
+
banner HEALTH_BANNER
|
90
|
+
banner INFO_BANNER
|
91
|
+
banner SIL_BANNER
|
92
|
+
banner STASH_BANNER
|
93
|
+
banner RES_BANNER
|
94
|
+
stop_on SUB_COMMANDS
|
95
|
+
end
|
96
|
+
|
97
|
+
opts = Trollop::with_standard_exception_handling global_opts do
|
98
|
+
global_opts.parse ARGV
|
99
|
+
raise Trollop::HelpNeeded if ARGV.empty? # show help screen
|
100
|
+
end
|
101
|
+
|
102
|
+
cmd = next_argv
|
103
|
+
self.respond_to?(cmd) ? send(cmd) : explode(global_opts)
|
104
|
+
end
|
105
|
+
|
106
|
+
def explode(opts)
|
107
|
+
explode = Trollop::with_standard_exception_handling opts do
|
108
|
+
raise Trollop::HelpNeeded # show help screen
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def deep_merge(hash_one, hash_two)
|
113
|
+
hash_one.merge(hash_two) {|key, hash_one_item, hash_two_item| deep_merge(hash_one_item, hash_two_item)}
|
114
|
+
end
|
115
|
+
|
116
|
+
def parser(cli)
|
117
|
+
opts = Trollop::Parser.new do
|
118
|
+
banner Cli.const_get("#{cli}_BANNER")
|
119
|
+
stop_on Cli.const_get("#{cli}_COMMANDS")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def explode_if_empty(opts,command)
|
124
|
+
explode(opts) if ARGV.empty? && command != 'list'
|
125
|
+
end
|
126
|
+
|
127
|
+
def next_argv
|
128
|
+
ARGV.shift
|
129
|
+
end
|
130
|
+
|
131
|
+
def client
|
132
|
+
opts = parser("CLIENT")
|
133
|
+
command = next_argv
|
134
|
+
explode_if_empty(opts,command)
|
135
|
+
case command
|
136
|
+
when 'list'
|
137
|
+
p = Trollop::options do
|
138
|
+
opt :limit, "The number if clients to return", :short => "l", :type => :string
|
139
|
+
opt :offset, "The number of clients to offset before returning", :short => "o", :type => :string
|
140
|
+
end
|
141
|
+
Trollop::die :offset, "Offset depends on the limit option --limit ( -l )".color(:red) if p[:offset] && !p[:limit]
|
142
|
+
cli = {:command => 'clients', :method => 'Get', :fields => p}
|
143
|
+
when 'delete'
|
144
|
+
p = Trollop::options
|
145
|
+
item = next_argv #the ARGV.shift needs to happen after Trollop::options to catch --help
|
146
|
+
deep_merge({:command => 'clients', :method => 'Delete', :fields => {:name => item}},{:fields => p})
|
147
|
+
when 'show'
|
148
|
+
p = Trollop::options
|
149
|
+
item = next_argv
|
150
|
+
deep_merge({:command => 'clients', :method => 'Get', :fields => {:name => item}},{:fields => p})
|
151
|
+
when 'history'
|
152
|
+
p = Trollop::options
|
153
|
+
item = next_argv
|
154
|
+
deep_merge({:command => 'clients', :method => 'Get', :fields => {:name => item, :history => true}},{:fields => p})
|
155
|
+
else
|
156
|
+
explode(opts)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def info
|
161
|
+
parser("INFO")
|
162
|
+
p = Trollop::options
|
163
|
+
cli = {:command => 'info', :method => 'Get', :fields => p}
|
164
|
+
end
|
165
|
+
|
166
|
+
def health
|
167
|
+
opts = parser("HEALTH")
|
168
|
+
p = Trollop::options do
|
169
|
+
opt :consumers, "The minimum number of consumers", :short => "c", :type => :string, :required => true
|
170
|
+
opt :messages, "The maximum number of messages", :short => "m", :type => :string, :required => true
|
171
|
+
end
|
172
|
+
cli = {:command => 'health', :method => 'Get', :fields => p}
|
173
|
+
end
|
174
|
+
|
175
|
+
def check
|
176
|
+
opts = parser("CHECK")
|
177
|
+
command = next_argv
|
178
|
+
explode_if_empty(opts,command)
|
179
|
+
p = Trollop::options
|
180
|
+
item = next_argv
|
181
|
+
case command
|
182
|
+
when 'list'
|
183
|
+
cli = {:command => 'checks', :method => 'Get', :fields => p}
|
184
|
+
when 'show'
|
185
|
+
deep_merge({:command => 'checks', :method => 'Get', :fields => {:name => item}},{:fields => p})
|
186
|
+
when 'request'
|
187
|
+
ARGV.empty? ? explode(opts) : subscribers = next_argv.split(",")
|
188
|
+
deep_merge({:command => 'checks', :method => 'Post', :fields => {:check => item, :subscribers => subscribers}},{:fields => p})
|
189
|
+
else
|
190
|
+
explode(opts)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def event
|
195
|
+
opts = parser("EVENT")
|
196
|
+
command = next_argv
|
197
|
+
explode_if_empty(opts,command)
|
198
|
+
case command
|
199
|
+
when 'list'
|
200
|
+
p = Trollop::options
|
201
|
+
cli = {:command => 'events', :method => 'Get', :fields => p}
|
202
|
+
when 'show'
|
203
|
+
p = Trollop::options do
|
204
|
+
opt :check, "Returns the check associated with the client", :short => "k", :type => :string
|
205
|
+
end
|
206
|
+
item = next_argv
|
207
|
+
deep_merge({:command => 'events', :method => 'Get', :fields => {:client => item}},{:fields => p})
|
208
|
+
when 'delete'
|
209
|
+
p = Trollop::options
|
210
|
+
item = next_argv
|
211
|
+
check = next_argv
|
212
|
+
explode(opts) if check == nil
|
213
|
+
deep_merge({:command => 'events', :method => 'Delete', :fields => {:client => item, :check => check}},{:fields => p})
|
214
|
+
else
|
215
|
+
explode(opts)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def stash
|
220
|
+
opts = parser("STASH")
|
221
|
+
command = next_argv
|
222
|
+
explode_if_empty(opts,command)
|
223
|
+
case command
|
224
|
+
when 'list'
|
225
|
+
p = Trollop::options do
|
226
|
+
opt :limit, "The number of stashes to return", :short => "l", :type => :string
|
227
|
+
opt :offset, "The number of stashes to offset before returning", :short => "o", :type => :string
|
228
|
+
end
|
229
|
+
Trollop::die :offset, "Offset depends on the limit option --limit ( -l )".color(:red) if p[:offset] && !p[:limit]
|
230
|
+
cli = {:command => 'stashes', :method => 'Get', :fields => p}
|
231
|
+
when 'show'
|
232
|
+
p = Trollop::options
|
233
|
+
item = next_argv
|
234
|
+
deep_merge({:command => 'stashes', :method => 'Get', :fields => {:path => item}},{:fields => p})
|
235
|
+
when 'delete'
|
236
|
+
p = Trollop::options
|
237
|
+
item = next_argv
|
238
|
+
deep_merge({:command => 'stashes', :method => 'Delete', :fields => {:path => item}},{:fields => p})
|
239
|
+
else
|
240
|
+
explode(opts)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def aggregate
|
245
|
+
opts = parser("AGG")
|
246
|
+
command = next_argv
|
247
|
+
explode_if_empty(opts,command)
|
248
|
+
case command
|
249
|
+
when 'list'
|
250
|
+
p = Trollop::options
|
251
|
+
cli = {:command => 'aggregates', :method => 'Get', :fields => p}
|
252
|
+
when 'show'
|
253
|
+
p = Trollop::options do
|
254
|
+
opt :limit, "The number of aggregates to return", :short => "l", :type => :string
|
255
|
+
opt :offset, "The number of aggregates to offset before returning", :short => "o", :type => :string
|
256
|
+
end
|
257
|
+
Trollop::die :offset, "Offset depends on the limit option --limit ( -l )".color(:red) if p[:offset] && !p[:limit]
|
258
|
+
item = next_argv
|
259
|
+
deep_merge({:command => 'aggregates', :method => 'Get', :fields => {:check => item}},{:fields => p})
|
260
|
+
when 'delete'
|
261
|
+
p = Trollop::options
|
262
|
+
item = next_argv
|
263
|
+
deep_merge({:command => 'aggregates', :method => 'Delete', :fields => {:check => item}},{:fields => p})
|
264
|
+
else
|
265
|
+
explode(opts)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def silence
|
270
|
+
opts = parser("SIL")
|
271
|
+
p = Trollop::options do
|
272
|
+
opt :check, "The check to silence (requires --client)", :short => 'k', :type => :string
|
273
|
+
opt :reason, "The reason this check/node is being silenced", :short => 'r', :type => :string
|
274
|
+
end
|
275
|
+
command = next_argv
|
276
|
+
explode(opts) if command == nil
|
277
|
+
deep_merge({:command => 'silence', :method => 'Post', :fields => {:client => command}},{:fields => p})
|
278
|
+
end
|
279
|
+
|
280
|
+
def resolve
|
281
|
+
opts = parser("RES")
|
282
|
+
command = next_argv
|
283
|
+
p = Trollop::options
|
284
|
+
ARGV.empty? ? explode(opts) : check = next_argv
|
285
|
+
deep_merge({:command => 'resolve', :method => 'Post', :fields => {:client => command, :check => check}},{:fields => p})
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
2
|
+
require 'net/https'
|
3
|
+
require 'json'
|
4
|
+
require 'sensu-cli/settings'
|
5
|
+
require 'sensu-cli/cli'
|
6
|
+
require 'rainbow'
|
7
|
+
|
8
|
+
module SensuCli
|
9
|
+
class Core
|
10
|
+
|
11
|
+
def setup
|
12
|
+
clis = Cli.new
|
13
|
+
cli = clis.global
|
14
|
+
settings
|
15
|
+
api_path(cli)
|
16
|
+
make_call
|
17
|
+
end
|
18
|
+
|
19
|
+
def settings
|
20
|
+
directory = "#{Dir.home}/.sensu"
|
21
|
+
file = "#{directory}/settings.rb"
|
22
|
+
alt = "/etc/sensu/sensu-cli/settings.rb"
|
23
|
+
settings = Settings.new
|
24
|
+
if settings.is_file?(file)
|
25
|
+
SensuCli::Config.from_file(file)
|
26
|
+
elsif settings.is_file?(alt)
|
27
|
+
SensuCli::Config.from_file(alt)
|
28
|
+
else
|
29
|
+
settings.create(directory,file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def api_path(cli)
|
34
|
+
@command = cli[:command]
|
35
|
+
case @command
|
36
|
+
when 'clients'
|
37
|
+
path = "/clients" << (cli[:fields][:name] ? "/#{cli[:fields][:name]}" : "") << (cli[:fields][:history] ? "/history" : "")
|
38
|
+
when 'info'
|
39
|
+
path = "/info"
|
40
|
+
when 'health'
|
41
|
+
path = "/health?consumers=#{cli[:fields][:consumers]}&messages=#{cli[:fields][:messages]}"
|
42
|
+
when 'stashes'
|
43
|
+
path = "/stashes" << (cli[:fields][:path] ? "/#{cli[:fields][:path]}" : "")
|
44
|
+
when 'checks'
|
45
|
+
if cli[:fields][:name]
|
46
|
+
path = "/check/#{cli[:fields][:name]}"
|
47
|
+
elsif cli[:fields][:subscribers]
|
48
|
+
path = "/check/request"
|
49
|
+
payload = {:check => cli[:fields][:check],:subscribers => cli[:fields][:subscribers]}.to_json
|
50
|
+
else
|
51
|
+
path = "/checks"
|
52
|
+
end
|
53
|
+
when 'events'
|
54
|
+
path = "/events" << (cli[:fields][:client] ? "/#{cli[:fields][:client]}" : "") << (cli[:fields][:check] ? "/#{cli[:fields][:check]}" : "")
|
55
|
+
when 'resolve'
|
56
|
+
payload = {:client => cli[:fields][:client], :check => cli[:fields][:check]}.to_json
|
57
|
+
path = "/event/resolve"
|
58
|
+
when 'silence'
|
59
|
+
cli[:fields][:reason] ? payload = ({:reason => cli[:fields][:reason],:timestamp => Time.now.to_i}).to_json : payload = {:timestamp => Time.now.to_i}.to_json
|
60
|
+
path = "/stashes/silence" << (cli[:fields][:client] ? "/#{cli[:fields][:client]}" : "") << (cli[:fields][:check] ? "/#{cli[:fields][:check]}" : "")
|
61
|
+
when 'aggregates'
|
62
|
+
path = "/aggregates" << (cli[:fields][:check] ? "/#{cli[:fields][:check]}" : "")
|
63
|
+
end
|
64
|
+
path << pagination(cli) if ["stashes","clients","aggregates"].include?(@command)
|
65
|
+
@api = {:path => path, :method => cli[:method], :command => cli[:command], :payload => (payload || false)}
|
66
|
+
end
|
67
|
+
|
68
|
+
def pagination(cli)
|
69
|
+
if cli[:fields].has_key?(:limit) && cli[:fields].has_key?(:offset)
|
70
|
+
page = "?limit=#{cli[:fields][:limit]}&offset=#{cli[:fields][:offset]}"
|
71
|
+
elsif cli[:fields].has_key?(:limit)
|
72
|
+
page = "?limit=#{cli[:fields][:limit]}"
|
73
|
+
else
|
74
|
+
page = ""
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def http_request
|
79
|
+
http = Net::HTTP.new(Config.host, Config.port)
|
80
|
+
http.read_timeout = 15
|
81
|
+
http.open_timeout = 5
|
82
|
+
if Config.ssl
|
83
|
+
http.use_ssl = true
|
84
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
85
|
+
end
|
86
|
+
case @api[:method]
|
87
|
+
when 'Get'
|
88
|
+
req = Net::HTTP::Get.new(@api[:path])
|
89
|
+
when 'Delete'
|
90
|
+
req = Net::HTTP::Delete.new(@api[:path])
|
91
|
+
when 'Post'
|
92
|
+
req = Net::HTTP::Post.new(@api[:path],initheader = {'Content-Type' =>'application/json'})
|
93
|
+
req.body = @api[:payload]
|
94
|
+
end
|
95
|
+
req.basic_auth(Config.user, Config.password) if Config.user && Config.password
|
96
|
+
begin
|
97
|
+
http.request(req)
|
98
|
+
rescue Timeout::Error
|
99
|
+
puts "HTTP request has timed out.".color(:red)
|
100
|
+
exit
|
101
|
+
rescue StandardError => e
|
102
|
+
puts "An HTTP error occurred. Check your settings. #{e}".color(:red)
|
103
|
+
exit
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def make_call
|
108
|
+
res = http_request
|
109
|
+
msg = response_codes(res.code,res.body)
|
110
|
+
res.code != '200' ? exit : pretty(msg)
|
111
|
+
count(msg)
|
112
|
+
end
|
113
|
+
|
114
|
+
def response_codes(code,body)
|
115
|
+
case code
|
116
|
+
when '200'
|
117
|
+
JSON.parse(body)
|
118
|
+
when '201'
|
119
|
+
puts "The stash has been created." if @command == "stashes"
|
120
|
+
when '202'
|
121
|
+
puts "The item was submitted for processing."
|
122
|
+
when '204'
|
123
|
+
puts "Sensu is healthy" if @command == 'health'
|
124
|
+
puts "The item was successfully deleted." if @command == 'aggregates' || @command == 'stashes'
|
125
|
+
when '400'
|
126
|
+
puts "The payload is malformed.".color(:red)
|
127
|
+
when '401'
|
128
|
+
puts "The request requires user authentication.".color(:red)
|
129
|
+
when '404'
|
130
|
+
puts "The item did not exist.".color(:cyan)
|
131
|
+
else
|
132
|
+
(@command == 'health') ? (puts "Sensu is not healthy.".color(:red)) : (puts "There was an error while trying to complete your request. Response code: #{code}".color(:red))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def pretty(res)
|
137
|
+
if !res.empty?
|
138
|
+
if res.is_a?(Hash)
|
139
|
+
res.each do |key,value|
|
140
|
+
puts "#{key}: ".color(:cyan) + "#{value}".color(:green)
|
141
|
+
end
|
142
|
+
elsif res.is_a?(Array)
|
143
|
+
res.each do |item|
|
144
|
+
puts "-------".color(:yellow)
|
145
|
+
if item.is_a?(Hash)
|
146
|
+
item.each do |key,value|
|
147
|
+
puts "#{key}: ".color(:cyan) + "#{value}".color(:green)
|
148
|
+
end
|
149
|
+
else
|
150
|
+
puts item.to_s.color(:cyan)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
else
|
155
|
+
puts "no values for this request".color(:cyan)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def count(res)
|
160
|
+
res.is_a?(Hash) ? count = res.length : count = res.count
|
161
|
+
puts "#{count} total items".color(:yellow) if count
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'mixlib/config'
|
3
|
+
|
4
|
+
module SensuCli
|
5
|
+
class Settings
|
6
|
+
|
7
|
+
def is_file?(file)
|
8
|
+
!File.readable?(file) ? false : true
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(directory,file)
|
12
|
+
FileUtils.mkdir_p(directory) if !File.directory?(directory)
|
13
|
+
FileUtils.cp(File.join(File.dirname(__FILE__),"../../settings.example.rb"), file)
|
14
|
+
puts "We created the configuration file for you at #{file}. You can also place this in /etc/sensu/sensu-cli. Edit the settings as needed.".color(:red)
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class Config
|
21
|
+
extend(Mixlib::Config)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/sensu-cli.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'lib', 'sensu-cli', 'version')
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'sensu-cli'
|
5
|
+
s.version = SensuCli::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.date = '2013-03-30'
|
8
|
+
s.summary = "A command line utility for Sensu."
|
9
|
+
s.description = "A command line utility for interacting with the Sensu api."
|
10
|
+
s.authors = ["Bryan Brandau"]
|
11
|
+
s.email = 'agent462@gmail.com'
|
12
|
+
s.has_rdoc = false
|
13
|
+
|
14
|
+
s.homepage ='http://github.com/agent462/sensu-cli'
|
15
|
+
s.add_dependency('rainbow', '1.1.4')
|
16
|
+
s.add_dependency('trollop', '2.0')
|
17
|
+
s.add_dependency('mixlib-config', '1.1.2')
|
18
|
+
|
19
|
+
s.files = Dir.glob('{bin,lib}/**/*') + %w[sensu-cli.gemspec README.md settings.example.rb]
|
20
|
+
s.executables = Dir.glob('bin/**/*').map { |file| File.basename(file) }
|
21
|
+
s.require_paths = ['lib']
|
22
|
+
end
|
data/settings.example.rb
ADDED
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sensu-cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bryan Brandau
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rainbow
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: trollop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mixlib-config
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.1.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.1.2
|
55
|
+
description: A command line utility for interacting with the Sensu api.
|
56
|
+
email: agent462@gmail.com
|
57
|
+
executables:
|
58
|
+
- sensu
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- bin/sensu
|
63
|
+
- lib/sensu-cli/cli.rb
|
64
|
+
- lib/sensu-cli/sensu.rb
|
65
|
+
- lib/sensu-cli/settings.rb
|
66
|
+
- lib/sensu-cli/version.rb
|
67
|
+
- lib/sensu-cli.rb
|
68
|
+
- sensu-cli.gemspec
|
69
|
+
- README.md
|
70
|
+
- settings.example.rb
|
71
|
+
homepage: http://github.com/agent462/sensu-cli
|
72
|
+
licenses: []
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 2.0.3
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: A command line utility for Sensu.
|
94
|
+
test_files: []
|