sensu-cli 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b31028364300b102bb6e93d2b2e9ad975f8584dd
4
- data.tar.gz: 90d6965b752621f42420c930db92fad2a65d10a5
3
+ metadata.gz: 546537d8a2709dc4b64d0bd982ffe216a09d91cf
4
+ data.tar.gz: 178295249672c82615cf7ad97d410d93bb5fd128
5
5
  SHA512:
6
- metadata.gz: 38a34f132d4a8b5799bc05faea57b075fc58b6a375985fd334ddd4274a417100de259ad21f98cc26fe1966c94ecbe2f4f22dedd98d5dc92237b7acc3b9653200
7
- data.tar.gz: 77d84377e361fc299680a37a0e9a22edc9ef3aeab5ded344e9576cd8c3c6d3bf45325dd1d842e8c5339e33ff5df8d222ed7ad2fd459c26821c5b857e35b5137a
6
+ metadata.gz: d8b38cb52fef977e61637ebdc7061bcd46d071c434090d74caeb2b0b64bed0471ea31cd657363973316bbe80bb74ad1dab6da903009428ca817936a16794a7db
7
+ data.tar.gz: bcdd5b0965bae88c8220f83315da775c36085966774f576d87a83bf33a31fd3637e6762f3d02fed13e40d7f27f1b483e7e5a8afe17702dd20bb466794a135940
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- sensu-cli
2
- =========
1
+ # sensu-cli
3
2
  ```
4
3
  #
5
4
  # Welcome to the sensu-cli.
@@ -17,8 +16,8 @@ A sensu-cli for interacting with the sensu api.
17
16
 
18
17
  What is Sensu? http://sensuapp.org/
19
18
 
20
- Features
21
- --------
19
+ ## Features
20
+
22
21
  * API interaction with info, health, stashes, events, clients, aggregates and checks
23
22
  * Resolve Events
24
23
  * Silence clients and checks
@@ -26,12 +25,14 @@ Features
26
25
  * Delete Requests (delete clients, stashes, aggregates and events)
27
26
 
28
27
 
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.
28
+ ## Usage and Configuration
34
29
 
30
+ * Installation: `gem install sensu-cli`
31
+ * Installation using the embedded Sensu ruby: `/opt/sensu/embedded/bin/gem install sensu-cli && ln -s /opt/sensu/embedded/bin/sensu-cli /usr/local/bin/`
32
+ * There is one settings file for host, port, ssl, and HTTP timeout that lives
33
+ in your user directory `~/.sensu/settings.rb`. You can alternatively place
34
+ this in `/etc/sensu/sensu-cli/settings.rb`.
35
+ * An example config file:
35
36
  ````
36
37
  host "127.0.0.1"
37
38
  port "4567"
@@ -40,23 +41,26 @@ api_endpoint "/api"
40
41
  read_timeout 20
41
42
  open_timeout 20
42
43
  ````
43
- 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)
44
-
45
- * All Configuration Settings
46
- `host` String - Required - Host of the Sensu API
47
- `port` String/Integer - Required - Port of the Sensu API
48
- `ssl` Boolean - Optional - Defaults False
49
- `api_endpoint` String - Optional - Default ''
50
- `read_timeout` Integer - Optional - Default 15 (seconds)
51
- `open_timeout` Integer - Optional - Default 5 (seconds)
52
- `pretty_colors` Boolean - Optional - Default True
53
- `proxy_address` String - Optional
54
- `proxy_port` Integer - Optional
55
- `user` String - Optional - User for the Sensu API
56
- `password` String - Optional - Password for the Sensu API
57
-
58
- Examples
59
- -----------
44
+
45
+ This format was chosen so you can do some ENV magic via your profile and
46
+ setting up an alias. For details see the
47
+ [wiki](https://github.com/agent462/sensu-cli/wiki)
48
+
49
+ All Configuration Settings:
50
+ * `host` String - Required - Host of the Sensu API
51
+ * `port` String/Integer - Required - Port of the Sensu API
52
+ * `ssl` Boolean - Optional - Defaults False
53
+ * `api_endpoint` String - Optional - Default ''
54
+ * `read_timeout` Integer - Optional - Default 15 (seconds)
55
+ * `open_timeout` Integer - Optional - Default 5 (seconds)
56
+ * `pretty_colors` Boolean - Optional - Default True
57
+ * `proxy_address` String - Optional
58
+ * `proxy_port` Integer - Optional
59
+ * `user` String - Optional - User for the Sensu API
60
+ * `password` String - Optional - Password for the Sensu API
61
+
62
+ ## Examples
63
+
60
64
  ````
61
65
  Available subcommands: (for details, sensu SUB-COMMAND --help)
62
66
 
@@ -107,8 +111,7 @@ sensu-cli socket raw INPUT
107
111
  --help, -h: Show this message
108
112
  ````
109
113
 
110
- Filters
111
- -------
114
+ ### Filters
112
115
 
113
116
  Filters are strings in 'key,value' format.
114
117
 
@@ -122,24 +125,73 @@ sensu-cli event list -i name,foo
122
125
  sensu-cli event list -i output,foo
123
126
  ````
124
127
 
125
- Socket
126
- -------
127
- This command can only be used on a host that is running sensu-client. sensu-client exposes a socket for arbritary check results. For more information you can see the [sensu client documentation](https://sensuapp.org/docs/0.18/clients#client-socket-input).
128
+ ### Socket
129
+
130
+ This command can only be used on a host that is running sensu-client.
131
+ The sensu-client exposes a socket for arbritary check results. For more
132
+ information you can see the [sensu client documentation](https://sensuapp.org/docs/0.25/reference/clients.html#client-socket-input).
133
+
134
+ Examples:
128
135
  ````
129
136
  # send a check result to the sensu server
130
- sensu-cli socket create -name "host33" --output "Something broke really bad" --status 1
137
+ sensu-cli socket create --name "check33" --output "Warn: Something broke really bad" --status 1
131
138
 
132
139
  # send raw json check result to the sensu server
133
- sensu-cli socket raw '{"name": "host34", "output": "Something broke even worse than on host33", "status": 1}'
140
+ sensu-cli socket raw '{"name": "check34", "output": "Crit: Something broke even worse than on check33", "status": 2}'
141
+
142
+ # send raw json check result to the sensu server, faking the source
143
+ sensu-cli socket raw '{"name": "snmp", "output": "Crit: SNMP is bad on this switch", "status": 2, "source": "switch01"}'
134
144
  ````
135
145
 
136
- Contributions
137
- -------------
138
- 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.
146
+ ### Advanced Examples
147
+
148
+ These advanced examples show off the power of being able to use the
149
+ sensu-cli tool in combination with other command line tools. Some use
150
+ the [jq](https://stedolan.github.io/jq/) command to do JSON parsing.
151
+
152
+ #### Have a host silence itself
153
+
154
+ ```bash
155
+ sensu-cli silence `hostname -f` --owner root --reason "This server was just created" --expire 3600
156
+ ```
157
+
158
+ #### Silence any client that has the word "test" in the name
159
+
160
+ ```bash
161
+ sensu-cli client list -f json |
162
+ jq -r .[].name |
163
+ grep "test" |
164
+ xargs --verbose --no-run-if-empty -n1 sensu-cli silence
165
+ ```
166
+
167
+ #### Delete sliences older than 3 days
168
+
169
+ ```bash
170
+ THRESHOLD=$(date +%s --date="3 days ago")
171
+ sensu-cli stash list --format json |
172
+ jq -r "map(select( .[\"content\"][\"timestamp\"] < $THRESHOLD )) | .[].path " |
173
+ xargs --verbose --no-run-if-empty -n1 sensu-cli stash delete
174
+ ```
175
+
176
+ #### Resolve any checks that haven't checked in in a month
177
+
178
+ ```bash
179
+ THRESHOLD=$(date +%s --date="1 month ago")
180
+ sensu-cli event list --format json |
181
+ jq --raw-output "map(select( .[\"check\"][\"issued\"] < $THRESHOLD )) | .[] | .client.name + \" \" + .check.name " |
182
+ xargs --verbose --no-run-if-empty -n2 sensu-cli resolve
183
+ ```
184
+
185
+
186
+ ### Contributions
187
+
188
+ Please provide a pull request. I'm an ops guy, not a developer, so if you're
189
+ submitting code cleanup, all I ask is that you explain the improvement so I can
190
+ learn.
191
+
139
192
 
193
+ ## License and Author
140
194
 
141
- License and Author
142
- ==================
143
195
  I'm releasing this under the MIT or Apache 2.0 license. You pick.
144
196
 
145
197
  Author:: Bryan Brandau <agent462@gmail.com>
@@ -39,11 +39,13 @@ module SensuCli
39
39
  JSON.parse(body)
40
40
  when '201'
41
41
  puts 'The stash has been created.' if command == 'stashes' || command == 'silence'
42
+ puts 'The silence has been created.' if command == 'silenced'
42
43
  when '202'
43
44
  puts 'The item was submitted for processing.'
44
45
  when '204'
45
46
  puts 'Sensu is healthy' if command == 'health'
46
47
  puts 'The item was successfully deleted.' if command == 'aggregates' || command == 'stashes'
48
+ puts 'The silence has been cleared.' if command == 'silenced'
47
49
  when '400'
48
50
  puts 'The payload is malformed.'.color(:red)
49
51
  when '401'
@@ -31,7 +31,11 @@ module SensuCli
31
31
  else
32
32
  settings.create(directory, file)
33
33
  end
34
- Rainbow.enabled = Config.pretty_colors == false ? false : true
34
+ if $stdout.isatty and not Config.pretty_colors == false
35
+ Rainbow.enabled = true
36
+ else
37
+ Rainbow.enabled = false
38
+ end
35
39
  end
36
40
 
37
41
  def api_path(cli)
@@ -4,17 +4,18 @@ require 'rainbow/ext/string'
4
4
 
5
5
  module SensuCli
6
6
  class Cli # rubocop:disable ClassLength
7
- SUB_COMMANDS = %w(info client check event stash aggregate silence resolve health socket)
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
- SOCKET_COMMANDS = %w(create raw)
7
+ SUB_COMMANDS = %w[info client check event stash aggregate silence silenced resolve health socket].freeze
8
+ CLIENT_COMMANDS = %w[list show delete history].freeze
9
+ CHECK_COMMANDS = %w[list show request].freeze
10
+ EVENT_COMMANDS = %w[list show delete].freeze
11
+ STASH_COMMANDS = %w[list show delete create].freeze
12
+ AGG_COMMANDS = %w[list show delete].freeze
13
+ SIL_COMMANDS = ''.freeze
14
+ SILD_COMMANDS = %w[list create clear].freeze
15
+ RES_COMMANDS = ''.freeze
16
+ INFO_COMMANDS = ''.freeze
17
+ HEALTH_COMMANDS = ''.freeze
18
+ SOCKET_COMMANDS = %w[create raw].freeze
18
19
 
19
20
  CLIENT_BANNER = <<-EOS.gsub(/^ {10}/, '')
20
21
  ** Client Commands **
@@ -60,6 +61,14 @@ module SensuCli
60
61
  ** Silence Commands **
61
62
  sensu-cli silence NODE (OPTIONS)\n\r
62
63
  EOS
64
+ SILD_BANNER = <<-EOS.gsub(/^ {10}/, '')
65
+ ** Silenced Commands **
66
+ sensu-cli silenced list (OPTIONS)
67
+ sensu-cli silenced create (OPTIONS)
68
+ sensu-cli silenced clear (OPTIONS)
69
+
70
+ Supported only in Sensu 0.26+\n\r
71
+ EOS
63
72
  RES_BANNER = <<-EOS.gsub(/^ {10}/, '')
64
73
  ** Resolve Commands **
65
74
  sensu-cli resolve NODE CHECK\n\r
@@ -93,17 +102,16 @@ module SensuCli
93
102
  banner HEALTH_BANNER
94
103
  banner INFO_BANNER
95
104
  banner SIL_BANNER
105
+ banner SILD_BANNER
96
106
  banner STASH_BANNER
97
107
  banner RES_BANNER
98
108
  banner SOCKET_BANNER
99
109
  stop_on SUB_COMMANDS
100
110
  end
101
-
102
111
  Trollop::with_standard_exception_handling global_opts do
103
112
  global_opts.parse ARGV
104
113
  raise Trollop::HelpNeeded if ARGV.empty? # show help screen
105
114
  end
106
-
107
115
  cmd = next_argv
108
116
  self.respond_to?(cmd) ? send(cmd) : explode(global_opts)
109
117
  end
@@ -302,12 +310,52 @@ module SensuCli
302
310
  opt :owner, 'The owner of the stash', :short => 'o', :type => :string
303
311
  opt :reason, 'The reason this check/node is being silenced', :short => 'r', :type => :string
304
312
  opt :expire, 'The number of seconds the silenced event is valid', :short => 'e', :type => :integer
313
+ opt :source, 'The name of the source of the silence', :short => 's', :type => :string, :default => 'sensu-cli'
305
314
  end
306
315
  command = next_argv
307
316
  explode(opts) if command.nil?
308
317
  deep_merge({ :command => 'silence', :method => 'Post', :fields => { :client => command } }, { :fields => p })
309
318
  end
310
319
 
320
+ def silenced
321
+ opts = parser('SILD')
322
+ command = next_argv
323
+ explode_if_empty(opts, command)
324
+ case command
325
+ when 'list'
326
+ p = Trollop::options do
327
+ opt :check, 'The check entries to return', :short => 'c', :type => :string
328
+ opt :subscription, 'The subscription entries to return', :short => 's', :type => :string
329
+ opt :limit, 'The number of aggregates to return', :short => 'l', :type => :string
330
+ opt :offset, 'The number of aggregates to offset before returning', :short => 'o', :type => :string
331
+ end
332
+ Trollop::die :offset, 'Offset depends on the limit option --limit ( -l )'.color(:red) if p[:offset] && !p[:limit]
333
+ { :command => 'silenced', :method => 'Get', :fields => p }
334
+ when 'create'
335
+ p = Trollop::options do
336
+ opt :check, 'The check to silence', :short => 'c', :type => :string
337
+ opt :creator, 'The owner of the stash', :short => 'o', :type => :string
338
+ opt :reason, 'The reason this check/node is being silenced', :short => 'r', :type => :string, :default => 'Silenced via API - no reason given'
339
+ opt :expire, 'The number of seconds the silenced event is valid', :short => 'e', :type => :integer
340
+ opt :expire_on_resolve, 'Entry will be automatically cleared once resolved', :short => 'f', :type => :boolean
341
+ opt :source, 'The name of the source of the silence', :short => 's', :type => :string, :default => 'sensu-cli'
342
+ opt :subscription, 'The name of the subscription to silence', :short => 'n', :type => :string
343
+ end
344
+ Trollop::die :check, 'Check or Subscription is required'.color(:red) if !p[:check] && !p[:subscription]
345
+ deep_merge({ :command => 'silenced', :method => 'Post', :fields => { :create => true } }, { :fields => p })
346
+ when 'clear'
347
+ p = Trollop::options do
348
+ opt :id, 'The id of the silenced item', :short => 'i', :type => :string
349
+ opt :check, 'The check of the silenced item', :short => 'c', :type => :string
350
+ opt :subscription, 'The subscription of the silenced item', :short => 's', :type => :string
351
+ end
352
+ Trollop::die :id, 'ID, Check or Subscription is required'.color(:red) if !p[:check] && !p[:subscription] && !p[:id]
353
+ { :command => 'silenced', :method => 'Post', :clear => true, :fields => p }
354
+ else
355
+ explode(opts)
356
+ end
357
+ end
358
+
311
359
  def resolve
312
360
  opts = parser('RES')
313
361
  command = next_argv
@@ -330,7 +378,7 @@ module SensuCli
330
378
  end
331
379
  { :command => 'socket', :method => 'create', :fields => p }
332
380
  when 'raw'
333
- p = Trollop::options
381
+ Trollop::options
334
382
  { :command => 'socket', :method => 'raw', :raw => next_argv }
335
383
  else
336
384
  explode(opts)
@@ -58,6 +58,7 @@ module SensuCli
58
58
  content = { :timestamp => Time.now.to_i }
59
59
  content.merge!(:owner => cli[:fields][:owner]) if cli[:fields][:owner]
60
60
  content.merge!(:reason => cli[:fields][:reason]) if cli[:fields][:reason]
61
+ content.merge!(:source => cli[:fields][:source]) if cli[:fields][:source]
61
62
  payload = { :content => content }
62
63
  payload.merge!(:expire => cli[:fields][:expire].to_i) if cli[:fields][:expire]
63
64
  silence_path = 'silence'
@@ -67,6 +68,25 @@ module SensuCli
67
68
  respond('/stashes', payload)
68
69
  end
69
70
 
71
+ def silenced(cli)
72
+ payload = {}
73
+ if !cli[:fields][:creator] && cli[:method] == 'Post'
74
+ cli[:fields][:creator] = `whoami`.strip if %w[darwin linux].any? { |word| RUBY_PLATFORM.include?(word) }
75
+ end
76
+ payload.merge!(:creator => cli[:fields][:creator]) if cli[:fields][:creator]
77
+ payload.merge!(:reason => cli[:fields][:reason]) if cli[:fields][:reason]
78
+ payload.merge!(:expire => cli[:fields][:expire].to_i) if cli[:fields][:expire]
79
+ payload.merge!(:expire_on_resolve => cli[:fields][:expire_on_resolve]) if cli[:fields][:expire_on_resolve]
80
+ payload.merge!(:check => cli[:fields][:check]) if cli[:fields][:check]
81
+ payload.merge!(:subscription => cli[:fields][:subscription]) if cli[:fields][:subscription]
82
+ silenced_path = '/silenced'
83
+ silenced_path << "/subscriptions/#{cli[:fields][:subscription]}" if cli[:fields][:subscription] && cli[:method] == 'Get'
84
+ silenced_path << "/checks/#{cli[:fields][:check]}" if cli[:fields][:check] && cli[:method] == 'Get'
85
+ silenced_path << "/clear" if cli[:clear]
86
+ silenced_path << pagination(cli)
87
+ respond(silenced_path, payload.to_json)
88
+ end
89
+
70
90
  def aggregates(cli)
71
91
  path = '/aggregates'
72
92
  path << "/#{cli[:fields][:check]}" if cli[:fields][:check]
@@ -90,7 +110,7 @@ module SensuCli
90
110
  end
91
111
 
92
112
  def respond(path, payload = false)
93
- { :path => "#{Config.api_endpoint}#{path}", :payload => payload }
113
+ { :path => ::File.join(Config.api_endpoint.to_s, path), :payload => payload }
94
114
  end
95
115
  end
96
116
  end
@@ -11,7 +11,13 @@
11
11
  <%= "interval:".color(:cyan) %> <%= check['interval'].to_s.color(:green) %>
12
12
  <%= "subscribers:".color(:cyan) %> <%= check['subscribers'].to_s.color(:green) %>
13
13
  <%= "issued:".color(:cyan) %> <%= check['issued'].to_s.color(:green) %>
14
+ <% if check['issued'] -%>
15
+ <%= "issued_s:".color(:cyan) %> <%= Time.at(check['issued']).to_s.color(:green) %>
16
+ <% end -%>
14
17
  <%= "executed:".color(:cyan) %> <%= check['executed'].to_s.color(:green) %>
18
+ <% if check['executed'] -%>
19
+ <%= "executed_s:".color(:cyan) %> <%= Time.at(check['executed']).to_s.color(:green) %>
20
+ <% end -%>
15
21
  <%= "duration:".color(:cyan) %> <%= check['duration'].to_s.color(:green) %>
16
22
  <%= "output:".color(:cyan) %> <%= check['output'].rstrip.to_s.color(:green) %>
17
23
  <%= "status:".color(:cyan) %> <%= check['status'].to_s.color(:green) %>
@@ -1,3 +1,3 @@
1
1
  module SensuCli
2
- VERSION = '0.7.1'
2
+ VERSION = '0.8.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Brandau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-23 00:00:00.000000000 Z
11
+ date: 2017-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: mixlib-config
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 2.1.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.1.0
55
55
  - !ruby/object:Gem::Dependency
@@ -84,28 +84,28 @@ dependencies:
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  description: A command line utility for interacting with the Sensu api.
@@ -144,17 +144,17 @@ require_paths:
144
144
  - lib
145
145
  required_ruby_version: !ruby/object:Gem::Requirement
146
146
  requirements:
147
- - - '>='
147
+ - - ">="
148
148
  - !ruby/object:Gem::Version
149
149
  version: '0'
150
150
  required_rubygems_version: !ruby/object:Gem::Requirement
151
151
  requirements:
152
- - - '>='
152
+ - - ">="
153
153
  - !ruby/object:Gem::Version
154
154
  version: '0'
155
155
  requirements: []
156
156
  rubyforge_project:
157
- rubygems_version: 2.2.2
157
+ rubygems_version: 2.6.10
158
158
  signing_key:
159
159
  specification_version: 4
160
160
  summary: A command line utility for Sensu.