sensu-cli-compat 0.6.3.2
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 +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
|
+
|