sensu-cli 0.7.1 → 0.8.0

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 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.