lita-sensu2 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bd12fc09f8c401d36d276dda600ea9652fa97cc3
4
+ data.tar.gz: 20016274d623a717deb675ba5e68396671b8e101
5
+ SHA512:
6
+ metadata.gz: 0ea4f4ef132fb9e072195f5c2368b8c172475afa4f773788fdab8fbd0cf5c31acc2347147c5d802e42fbe04fc8100be733115a135bc73466996cecaff652bac4
7
+ data.tar.gz: 4d68a0749b9e9172cdc3a9749b42398331180910e1ed26b13d6040e99cd0d1b8421e147995aebc51c7d488edfb463c7cee84ed22aecac83b7a27f3ed1ae43fbf
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .idea
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ lita_config.rb
data/.rubocop.yml ADDED
@@ -0,0 +1,35 @@
1
+ Documentation:
2
+ Exclude:
3
+ - lib/lita/handlers/sensu2.rb
4
+
5
+ FileName:
6
+ Exclude:
7
+ - lib/lita-sensu2.rb
8
+
9
+ Metrics/LineLength:
10
+ Max: 100
11
+ Exclude:
12
+ - 'spec/**/*_spec.rb'
13
+
14
+ Metrics/AbcSize:
15
+ Max: 27
16
+
17
+ Metrics/CyclomaticComplexity:
18
+ Max: 8
19
+
20
+ Metrics/PerceivedComplexity:
21
+ Max: 10
22
+
23
+ Metrics/MethodLength:
24
+ Max: 30
25
+
26
+ Metrics/ClassLength:
27
+ Max: 200
28
+
29
+ Metrics/BlockLength:
30
+ Max: 30
31
+ Exclude:
32
+ - '*.gemspec'
33
+ - Rakefile
34
+ - 'spec/**/*_spec.rb'
35
+ - 'spec/spec_helper.rb'
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ sudo: required
3
+ rvm:
4
+ - 2.3.3
5
+ script: bundle exec rake
6
+ before_install:
7
+ - gem update --system
8
+ services:
9
+ - redis-server
data/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+ 20150506 - v0.2.0
2
+ Remove Hipchat HTML templates
3
+ Add support for HTTP basic auth
4
+ 20150417 - v0.1.1
5
+ Initial release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2017 KnuEdge
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # lita-sensu2
2
+
3
+ [![Gem Version](http://img.shields.io/gem/v/lita-sensu2.svg)](https://rubygems.org/gems/lita-sensu2)
4
+ [![Build Status](https://travis-ci.org/knuedge/lita-sensu2.png?branch=master)](https://travis-ci.org/knuedge/lita-sensu2)
5
+ [![Coverage Status](https://coveralls.io/repos/knuedge/lita-sensu2/badge.png)](https://coveralls.io/r/knuedge/lita-sensu2)
6
+
7
+ A maintained Lita handler for working with the [Sensu](http://sensuapp.org) monitoring framework.
8
+
9
+ **Note**: This handler requires Lita >= 4.7.
10
+ ## Installation
11
+
12
+ Add lita-sensu2 to your Lita instance's Gemfile:
13
+
14
+ ``` ruby
15
+ gem 'lita-sensu2'
16
+ ```
17
+
18
+ ## Configuration
19
+
20
+ The sensu handler needs to be configured with information about your sensu
21
+ installation. Add the following configuration to your `lita_config.rb`. All
22
+ parameters are optional, by default the handler will connect to 127.0.0.1:4567
23
+ for the sensu API service.
24
+
25
+ ```ruby
26
+ config.handlers.sensu2.api_url = '127.0.0.1'
27
+ config.handlers.sensu2.api_port = 4567
28
+ config.handlers.sensu2.domain = 'mydomain.com'
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ Available commands:
34
+
35
+ `sensu client <client>` - Shows information on a specific client
36
+ `sensu client <client> history` - Shows history information for a specific client
37
+ `sensu clients` - List sensu clients
38
+ `sensu events` [for <client>] - Shows current events, optionally for only a specific client
39
+ `sensu info` - Displays sensu information
40
+ `sensu remove client <client>` - Remove client from sensu
41
+ `sensu resolve event <client>[/service]` - Resolve event/all events for client
42
+ `sensu silence <hostname>[/<check>][ for <duration><units>]` - Silence event
43
+ `sensu stashes` - Displays current sensu stashes
44
+
45
+ ## License
46
+
47
+ [Apache-2.0](http://opensource.org/licenses/Apache-2.0)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new(:rubocop)
7
+
8
+ task default: %i[spec rubocop]
@@ -0,0 +1,14 @@
1
+ require 'lita'
2
+
3
+ Lita.load_locales Dir[File.expand_path(
4
+ File.join('..', '..', 'locales', '*.yml'), __FILE__
5
+ )]
6
+
7
+ require 'utils/sensu_http'
8
+ require 'utils/sensu'
9
+ require 'lita/handlers/sensu2'
10
+
11
+ Lita::Handlers::Sensu2.template_root File.expand_path(
12
+ File.join('..', '..', 'templates'),
13
+ __FILE__
14
+ )
@@ -0,0 +1,221 @@
1
+ require 'time'
2
+
3
+ module Lita
4
+ module Handlers
5
+ class Sensu2 < Handler
6
+ include Utils::Sensu
7
+ include Utils::SensuHTTP
8
+ # Handle errors
9
+ # https://github.com/MrTin/lita-chuck_norris/blob/master/lib/lita/handlers/chuck_norris.rb
10
+
11
+ config :api_url, default: '127.0.0.1', type: String
12
+ config :api_port, default: 4567, type: Integer
13
+ config :domain, type: String
14
+ config :api_user, type: String
15
+ config :api_pass, type: String
16
+
17
+ route(
18
+ /sensu client ([^\s]*$)/,
19
+ :client,
20
+ help: { 'sensu client <client>' => 'Shows information on a specific client' }
21
+ )
22
+
23
+ route(
24
+ /sensu client ([^\s]*) history/,
25
+ :client_history,
26
+ help: {
27
+ 'sensu client <client> history' => 'Shows history information for a specific client'
28
+ }
29
+ )
30
+
31
+ route(
32
+ /sensu clients/,
33
+ :clients,
34
+ help: { 'sensu clients' => 'List sensu clients' }
35
+ )
36
+
37
+ route(
38
+ /sensu events(?: for (.*))?/,
39
+ :events,
40
+ help: {
41
+ 'sensu events [for <client>]' => 'Shows current events, optionally for a specific client'
42
+ }
43
+ )
44
+
45
+ route(
46
+ /sensu info/,
47
+ :info,
48
+ help: { 'sensu info' => 'Displays sensu information' }
49
+ )
50
+
51
+ route(
52
+ /(?:sensu\s+)?remove client (.*)/,
53
+ :remove_client,
54
+ help: { 'sensu remove client <client>' => 'Remove client from sensu' }
55
+ )
56
+
57
+ route(
58
+ %r{(?:sensu\s+)?resolve event (.*)(?:/)(.*)},
59
+ :resolve,
60
+ help: { 'sensu resolve event <client>[/service]' => 'Resolve event/all events for client' }
61
+ )
62
+
63
+ route(
64
+ %r{(?:sensu\s+)?silence ([^\s/]*)(?:/)?([^\s]*)?(?: for (\d+)(\w))?},
65
+ :silence,
66
+ help: { 'sensu silence <hostname>[/<check>][ for <duration><units>]' => 'Silence event' }
67
+ )
68
+
69
+ route(
70
+ /sensu stash(es)?/,
71
+ :stashes,
72
+ help: { 'sensu stashes' => 'Displays current sensu stashes' }
73
+ )
74
+
75
+ def client(response)
76
+ client = add_domain(response.matches[0][0])
77
+ client_url = "#{config.api_url}:#{config.api_port}/clients/#{client}"
78
+ resp = http_get(client_url)
79
+ if resp.status == 200
80
+ client = MultiJson.load(resp.body, symbolize_keys: true)
81
+ response.reply(MultiJson.dump(client, pretty: true))
82
+ elsif resp.status == 404
83
+ response.reply("#{client} was not found")
84
+ else
85
+ log.warn "Sensu returned an internal error fetching #{client_url}"
86
+ response.reply("An error occurred fetching client #{client}")
87
+ end
88
+ end
89
+
90
+ def client_history(response)
91
+ client = add_domain(response.matches[0][0])
92
+ client_url = "#{config.api_url}:#{config.api_port}/clients/#{client}/history"
93
+ resp = http_get(client_url)
94
+ if resp.status == 200
95
+ response.reply(render_template('client_history', history: sorted_by(resp.body, :check)))
96
+ else
97
+ log.warn("Sensu returned an internal error fetching #{client_url}")
98
+ response.reply("An error occurred fetching client #{client} history")
99
+ end
100
+ end
101
+
102
+ def clients(response)
103
+ clients_url = "#{config.api_url}:#{config.api_port}/clients"
104
+ resp = http_get(clients_url)
105
+ if resp.status == 200
106
+ response.reply(render_template('clients', clients: sorted_by(resp.body, :name)))
107
+ else
108
+ log.warn("Sensu returned an internal error fetching #{clients_url}")
109
+ response.reply('An error occurred fetching clients')
110
+ end
111
+ end
112
+
113
+ def events(response)
114
+ client = response.matches[0][0] ? '/' + add_domain(response.matches[0][0]) : ''
115
+ client_url = "#{config.api_url}:#{config.api_port}/events#{client}"
116
+
117
+ resp = http_get(client_url)
118
+ response.reply(
119
+ if resp.status == 200
120
+ render_template('events', events: sorted_events(resp.body))
121
+ else
122
+ log.warn("Sensu returned an internal error fetching #{client_url}")
123
+ 'An error occurred fetching clients'
124
+ end
125
+ )
126
+ end
127
+
128
+ def info(response)
129
+ resp = http_get("#{config.api_url}:#{config.api_port}/info")
130
+ raise RequestError unless resp.status == 200
131
+ info = MultiJson.load(resp.body, symbolize_keys: true)
132
+ response.reply(MultiJson.dump(info, pretty: true))
133
+ end
134
+
135
+ def remove_client(response)
136
+ client = add_domain(response.matches[0][0])
137
+ client_url = "#{config.api_url}:#{config.api_port}/clients/#{client}"
138
+ resp = http_delete(client_url)
139
+ if resp.status == 202
140
+ response.reply("#{client} removed")
141
+ elsif resp.status == 404
142
+ response.reply("#{client} was not found")
143
+ else
144
+ log.warn("Sensu returned an internal error deleting #{client_url}")
145
+ response.reply("An error occurred removing #{client}")
146
+ end
147
+ end
148
+
149
+ def resolve(response)
150
+ client = add_domain(response.matches[0][0])
151
+ check = response.matches[0][1]
152
+ res_url = "#{config.api_url}:#{config.api_port}/resolve"
153
+
154
+ data = { client: client, check: check }
155
+ post_data = MultiJson.dump(data)
156
+ resp = http_post(res_url, post_data)
157
+ if resp.status == 202
158
+ response.reply("#{client}/#{check} resolved")
159
+ elsif resp.status == 400
160
+ response.reply("Resolve message was malformed: #{post_data}")
161
+ elsif resp.status == 404
162
+ response.reply("#{client}/#{check} was not found")
163
+ else
164
+ log.warn(
165
+ "Sensu returned an internal error resolving #{res_url} with #{post_data}"
166
+ )
167
+ response.reply("There was an error resolving #{client}/#{check}")
168
+ end
169
+ end
170
+
171
+ def silence(response)
172
+ client = add_domain(response.matches[0][0])
173
+ check = response.matches[0][1]
174
+ duration = response.matches[0][2]
175
+ units = response.matches[0][3]
176
+
177
+ expiration, human_duration = calculate_expiration(duration.to_i, units)
178
+
179
+ return false unless valid_expiration(response, expiration, units)
180
+
181
+ post_data = silence_post_data(response.user, expiration, client, check)
182
+ resp = http_post(silence_url, post_data)
183
+ response.reply silence_post_msg(resp, post_data, human_duration, check_alias(client, check))
184
+ end
185
+
186
+ def stashes(response)
187
+ stashes_url = "#{config.api_url}:#{config.api_port}/stashes"
188
+ resp = http_get(stashes_url)
189
+ if resp.status == 200
190
+ response.reply(render_template('stashes', stashes: sorted_by(resp.body, :name)))
191
+ else
192
+ log.warn("Sensu returned an internal error resolving #{stashes_url}")
193
+ response.reply('An error occurred fetching stashes')
194
+ end
195
+ end
196
+
197
+ private
198
+
199
+ def silence_post_msg(resp, post_data, human_duration, chk_alias)
200
+ if resp.status == 201
201
+ "#{chk_alias} silenced for #{human_duration}"
202
+ else
203
+ log.warn(
204
+ "Sensu returned an internal error posting '#{post_data}' to #{silence_url}"
205
+ )
206
+ "An error occurred silencing to #{chk_alias}"
207
+ end
208
+ end
209
+
210
+ def valid_expiration(response, exp, units)
211
+ return true if exp
212
+ response.reply(
213
+ "Unknown unit (#{units}). I know s (seconds), m (minutes), h (hours), and d(days)"
214
+ )
215
+ false
216
+ end
217
+ end
218
+
219
+ Lita.register_handler(Sensu2)
220
+ end
221
+ end
@@ -0,0 +1,65 @@
1
+ module Utils
2
+ # Utility methods for interacting with Sensu
3
+ module Sensu
4
+ def calculate_expiration(duration, units)
5
+ if units
6
+ expiration = case units
7
+ when 's'
8
+ duration
9
+ when 'm'
10
+ duration * 60
11
+ when 'h'
12
+ duration * 3600
13
+ when 'd'
14
+ duration * 3600 * 24
15
+ end
16
+ human_duration = "#{duration}#{units}"
17
+ else
18
+ expiration = 3600
19
+ human_duration = '1h'
20
+ end
21
+ [expiration, human_duration]
22
+ end
23
+
24
+ def check_alias(client, check)
25
+ "#{client}:#{check && !check.empty? ? check : '*'}"
26
+ end
27
+
28
+ def sorted_by(body, attribute)
29
+ MultiJson.load(body, symbolize_keys: true).sort do |a, b|
30
+ a[attribute.to_sym] <=> b[attribute.to_sym]
31
+ end
32
+ end
33
+
34
+ def sorted_events(body)
35
+ MultiJson.load(body, symbolize_keys: true).sort do |a, b|
36
+ a[:client][:name] <=> b[:client][:name]
37
+ end
38
+ end
39
+
40
+ def silence_post_data(user, expiration, client, check)
41
+ data = {
42
+ creator: user.name,
43
+ expire: expiration,
44
+ reason: 'Because Lita says so!',
45
+ subscription: "client:#{client}"
46
+ }
47
+ data[:check] = check if !check.nil? && check != ''
48
+ MultiJson.dump(data)
49
+ end
50
+
51
+ private
52
+
53
+ def add_domain(client)
54
+ if config.domain && !client.include?(config.domain)
55
+ if config.domain[0, 1] == '.'
56
+ client + config.domain
57
+ else
58
+ client + '.' + config.domain
59
+ end
60
+ else
61
+ client
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,35 @@
1
+ module Utils
2
+ # Utility methods for making HTTP requests for Sensu
3
+ module SensuHTTP
4
+ def headers
5
+ headers = {}
6
+ if config.api_user
7
+ creds = Base64.encode64("#{config.api_user.chomp}:#{config.api_pass.chomp}")
8
+ headers['Authorization'] = "Basic #{creds}"
9
+ end
10
+ headers
11
+ end
12
+
13
+ def http_get(url)
14
+ http.get(url) do |req|
15
+ req.headers = headers
16
+ end
17
+ end
18
+
19
+ def http_delete(url)
20
+ http.delete(url) do |req|
21
+ req.headers = headers
22
+ end
23
+ end
24
+
25
+ def http_post(url, data)
26
+ http.post(url, data) do |req|
27
+ req.headers = headers
28
+ end
29
+ end
30
+
31
+ def silence_url
32
+ "#{config.api_url}:#{config.api_port}/silenced"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'lita-sensu2'
3
+ spec.version = '0.3.0'
4
+ spec.authors = ['Jonathan Gnagy']
5
+ spec.email = ['jgnagy@knuedge.com']
6
+ spec.description = 'Lita plugin to interact with sensu'
7
+ spec.summary = 'Lita plugin to interact with sensu'
8
+ spec.homepage = 'https://github.com/knuedge/lita-sensu2'
9
+ spec.license = 'Apache-2.0'
10
+ spec.metadata = { 'lita_plugin_type' => 'handler' }
11
+
12
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
13
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.require_paths = ['lib']
16
+
17
+ spec.add_runtime_dependency 'lita', '>= 4.7'
18
+
19
+ spec.add_development_dependency 'bundler', '~> 1.3'
20
+ spec.add_development_dependency 'pry-byebug'
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'rack-test'
23
+ spec.add_development_dependency 'rspec', '>= 3.0.0'
24
+ spec.add_development_dependency 'simplecov'
25
+ spec.add_development_dependency 'coveralls'
26
+ spec.add_development_dependency 'byebug'
27
+ spec.add_development_dependency 'rubocop'
28
+ spec.add_development_dependency 'travis', '~> 1.8'
29
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,4 @@
1
+ en:
2
+ lita:
3
+ handlers:
4
+ sensu:
@@ -0,0 +1,304 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lita::Handlers::Sensu2, lita_handler: true do
4
+ it { is_expected.to route_command('sensu client test1').to(:client) }
5
+ it { is_expected.to route_command('sensu client test1 history').to(:client_history) }
6
+ it { is_expected.to route_command('sensu clients').to(:clients) }
7
+ it { is_expected.to route_command('sensu events').to(:events) }
8
+ it { is_expected.to route_command('sensu events for test1').to(:events) }
9
+ it { is_expected.to route_command('sensu info').to(:info) }
10
+ it { is_expected.to route_command('sensu remove client test1').to(:remove_client) }
11
+ it { is_expected.to route_command('remove client test1').to(:remove_client) }
12
+ it { is_expected.to route_command('sensu resolve event test1/check2').to(:resolve) }
13
+ it { is_expected.to route_command('resolve event test1/check2').to(:resolve) }
14
+ it { is_expected.to route_command('resolve event test1/check2').to(:resolve) }
15
+ it { is_expected.to route_command('sensu silence test1').to(:silence) }
16
+ it { is_expected.to route_command('silence test1').to(:silence) }
17
+ it { is_expected.to route_command('sensu silence test1 check2').to(:silence) }
18
+ it { is_expected.to route_command('sensu silence test1/check2').to(:silence) }
19
+ it { is_expected.to route_command('sensu stashes').to(:stashes) }
20
+
21
+ let(:response) { double('Faraday::Response') }
22
+
23
+ before do
24
+ registry.config.handlers.sensu2.api_url = 'http://sensu.example.com'
25
+ registry.config.handlers.sensu2.api_port = 5678
26
+ registry.config.handlers.sensu2.domain = 'example.com'
27
+ end
28
+
29
+ describe '#client' do
30
+ client_response = '{"subscriptions":["apache","all"],"name":"test1.example.com","address":"172.31.64.55","bind":"127.0.0.1","safe_mode":false,"keepalive":{},"version":"0.14.0","timestamp":1427859223}'
31
+
32
+ before do
33
+ allow_any_instance_of(Faraday::Connection).to receive(:get).with('http://sensu.example.com:5678/clients/test1.example.com').and_return(response)
34
+ end
35
+
36
+ it 'should fetch client info' do
37
+ allow(response).to receive(:status).and_return(200)
38
+ allow(response).to receive(:body).and_return(client_response)
39
+ send_message('sensu client test1.example.com')
40
+ expect(replies.last).to eq("{\n \"subscriptions\": [\n \"apache\",\n \"all\"\n ],\n \"name\": \"test1.example.com\",\n \"address\": \"172.31.64.55\",\n \"bind\": \"127.0.0.1\",\n \"safe_mode\": false,\n \"keepalive\": {\n },\n \"version\": \"0.14.0\",\n \"timestamp\": 1427859223\n}")
41
+ end
42
+
43
+ it 'should fetch client info appending domain name' do
44
+ allow(response).to receive(:status).and_return(200)
45
+ allow(response).to receive(:body).and_return(client_response)
46
+ send_message('sensu client test1')
47
+ expect(replies.last).to eq("{\n \"subscriptions\": [\n \"apache\",\n \"all\"\n ],\n \"name\": \"test1.example.com\",\n \"address\": \"172.31.64.55\",\n \"bind\": \"127.0.0.1\",\n \"safe_mode\": false,\n \"keepalive\": {\n },\n \"version\": \"0.14.0\",\n \"timestamp\": 1427859223\n}")
48
+ end
49
+
50
+ it 'should handle client not found' do
51
+ allow(response).to receive(:status).and_return(404)
52
+ send_message('sensu client test1')
53
+ expect(replies.last).to eq('test1.example.com was not found')
54
+ end
55
+
56
+ it 'should handle internal sensu errors' do
57
+ allow(response).to receive(:status).and_return(500)
58
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
59
+ send_message('sensu client test1')
60
+ expect(replies.last).to eq('An error occurred fetching client test1.example.com')
61
+ end
62
+ end # client
63
+
64
+ describe '#client_history' do
65
+ history_response = '[{"check":"postfix-running","history":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"last_execution":1427885448,"last_status":0},{"check":"postfix-mailq","history":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"last_execution":1427885448,"last_status":0},{"check":"disk-metrics","history":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"last_execution":1427885481,"last_status":0},{"check":"puppet-last_run","history":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"last_execution":1427884845,"last_status":0},{"check":"keepalive","history":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"last_execution":1427885501,"last_status":0}]'
66
+
67
+ before do
68
+ allow_any_instance_of(Faraday::Connection).to receive(:get).with('http://sensu.example.com:5678/clients/test1.example.com/history').and_return(response)
69
+ end
70
+
71
+ it 'should fetch client info' do
72
+ allow(response).to receive(:status).and_return(200)
73
+ allow(response).to receive(:body).and_return(history_response)
74
+ send_message('sensu client test1.example.com history')
75
+ expect(replies.last).to eq("disk-metrics: status - 0; last checked - #{localtime('2015-04-01 04:51:21 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\nkeepalive: status - 0; last checked - #{localtime('2015-04-01 04:51:41 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\npostfix-mailq: status - 0; last checked - #{localtime('2015-04-01 04:50:48 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\npostfix-running: status - 0; last checked - #{localtime('2015-04-01 04:50:48 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\npuppet-last_run: status - 0; last checked - #{localtime('2015-04-01 04:40:45 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n")
76
+ end
77
+
78
+ it 'should fetch client info appending domain name' do
79
+ allow(response).to receive(:status).and_return(200)
80
+ allow(response).to receive(:body).and_return(history_response)
81
+ send_message('sensu client test1 history')
82
+ expect(replies.last).to eq("disk-metrics: status - 0; last checked - #{localtime('2015-04-01 04:51:21 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\nkeepalive: status - 0; last checked - #{localtime('2015-04-01 04:51:41 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\npostfix-mailq: status - 0; last checked - #{localtime('2015-04-01 04:50:48 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\npostfix-running: status - 0; last checked - #{localtime('2015-04-01 04:50:48 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\npuppet-last_run: status - 0; last checked - #{localtime('2015-04-01 04:40:45 -0600')}; history - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n")
83
+ end
84
+
85
+ it 'should handle internal sensu errors' do
86
+ allow(response).to receive(:status).and_return(500)
87
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
88
+ send_message('sensu client test1 history')
89
+ expect(replies.last).to eq('An error occurred fetching client test1.example.com history')
90
+ end
91
+ end # client_history
92
+
93
+ describe '#clients' do
94
+ clients_response = '[{"subscriptions":["tomcat","all"],"name":"test2.example.com","safe_mode":false,"address":"172.31.0.2","bind":"127.0.0.1","keepalive":{},"version":"0.14.0","timestamp":1427887539},{"subscriptions":["apache","all"],"keepalive":{},"name":"test1.example.com","safe_mode":false,"address":"172.31.0.1","bind":"127.0.0.1","version":"0.14.0","timestamp":1427887548}]'
95
+
96
+ before do
97
+ allow_any_instance_of(Faraday::Connection).to receive(:get).with('http://sensu.example.com:5678/clients').and_return(response)
98
+ end
99
+
100
+ it 'should list all clients' do
101
+ allow(response).to receive(:status).and_return(200)
102
+ allow(response).to receive(:body).and_return(clients_response)
103
+ send_message('sensu clients')
104
+ expect(replies.last).to eq("test1.example.com (172.31.0.1) subscriptions: all, apache\ntest2.example.com (172.31.0.2) subscriptions: all, tomcat\n")
105
+ end
106
+
107
+ it 'should handle internal sensu errors' do
108
+ allow(response).to receive(:status).and_return(500)
109
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
110
+ send_message('sensu clients')
111
+ expect(replies.last).to eq('An error occurred fetching clients')
112
+ end
113
+ end # clients
114
+
115
+ describe '#events' do
116
+ events_response = '[{"id":"a622267d-88bf-4eea-9455-ec8f001ca916","client":{"bind":"127.0.0.1","safe_mode":false,"name":"test1.example.com","subscriptions":["provisioner","all","apache"],"keepalive":{},"address":"172.31.0.1","version":"0.14.0","timestamp":1416007406},"check":{"command":"/etc/sensu/plugins/check-procs.rb -p /usr/sbin/pdns_server -w 2 -c 2 -W 2 -C 1","subscribers":[""],"handlers":["default"],"standalone":true,"interval":60,"name":"pdns-server-running","issued":1416007420,"executed":1416007420,"duration":2.107,"output":"CheckProcs CRITICAL: Found 0 matching processes; cmd //usr/sbin/pdns_server/\\n","status":2,"history":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","2","2","2"]},"occurrences":3,"action":"create"},{"id":"4b107db0-f7be-4dc3-a5ba-76a5b9dba4dd","client":{"bind":"127.0.0.1","safe_mode":false,"name":"test2.example.com","subscriptions":["provisioner","all","apache"],"keepalive":{},"address":"172.31.0.2","version":"0.14.0","timestamp":1416007406},"check":{"subscribers":[""],"handlers":["default"],"command":"/etc/sensu/plugins/check-procs.rb -p /usr/sbin/pdns_puppetdb -w 25 -c 30 -C 1","interval":600,"standalone":true,"name":"pdns_puppetdb_running","issued":1416007418,"executed":1416007418,"duration":1.507,"output":"CheckProcs CRITICAL: Found 0 matching processes; cmd //usr/sbin/pdns_puppetdb/\\n","status":2,"history":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","2"]},"occurrences":1,"action":"create"}]'
117
+ test1_events_response = '[{"id":"a622267d-88bf-4eea-9455-ec8f001ca916","client":{"bind":"127.0.0.1","safe_mode":false,"name":"test1.example.com","subscriptions":["provisioner","all","apache"],"keepalive":{},"address":"172.31.0.1","version":"0.14.0","timestamp":1416007406},"check":{"command":"/etc/sensu/plugins/check-procs.rb -p /usr/sbin/pdns_server -w 2 -c 2 -W 2 -C 1","subscribers":[""],"handlers":["default"],"standalone":true,"interval":60,"name":"pdns-server-running","issued":1416007420,"executed":1416007420,"duration":2.107,"output":"CheckProcs CRITICAL: Found 0 matching processes; cmd //usr/sbin/pdns_server/\\n","status":2,"history":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","2","2","2"]},"occurrences":3,"action":"create"}]'
118
+
119
+ before do
120
+ allow_any_instance_of(Faraday::Connection).to receive(:get).with('http://sensu.example.com:5678/events').and_return(response)
121
+ allow_any_instance_of(Faraday::Connection).to receive(:get).with('http://sensu.example.com:5678/events/test1.example.com').and_return(response)
122
+ end
123
+
124
+ it 'should list all events' do
125
+ allow(response).to receive(:status).and_return(200)
126
+ allow(response).to receive(:body).and_return(events_response)
127
+ send_message('sensu events')
128
+ expect(replies.last).to eq("test1.example.com (pdns-server-running) - CheckProcs CRITICAL: Found 0 matching processes; cmd //usr/sbin/pdns_server/\ntest2.example.com (pdns_puppetdb_running) - CheckProcs CRITICAL: Found 0 matching processes; cmd //usr/sbin/pdns_puppetdb/\n")
129
+ end
130
+
131
+ it 'should list all events for a specific client' do
132
+ allow(response).to receive(:status).and_return(200)
133
+ allow(response).to receive(:body).and_return(test1_events_response)
134
+ send_message('sensu events for test1')
135
+ expect(replies.last).to eq("test1.example.com (pdns-server-running) - CheckProcs CRITICAL: Found 0 matching processes; cmd //usr/sbin/pdns_server/\n")
136
+ end
137
+
138
+ it 'should handle internal sensu errors' do
139
+ allow(response).to receive(:status).and_return(500)
140
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
141
+ send_message('sensu events for test1')
142
+ expect(replies.last).to eq('An error occurred fetching clients')
143
+ end
144
+ end # events
145
+
146
+ describe '#info' do
147
+ info_response = '{"sensu":{"version":"0.14.0"},"transport":{"keepalives":{"messages":0,"consumers":1},"results":{"messages":0,"consumers":1},"connected":true},"redis":{"connected":true}}'
148
+
149
+ before do
150
+ allow_any_instance_of(Faraday::Connection).to receive(:get).with('http://sensu.example.com:5678/info').and_return(response)
151
+ end
152
+
153
+ it 'should return api info' do
154
+ allow(response).to receive(:status).and_return(200)
155
+ allow(response).to receive(:body).and_return(info_response)
156
+ send_message('sensu info')
157
+ expect(replies.last).to eq("{\n \"sensu\": {\n \"version\": \"0.14.0\"\n },\n \"transport\": {\n \"keepalives\": {\n \"messages\": 0,\n \"consumers\": 1\n },\n \"results\": {\n \"messages\": 0,\n \"consumers\": 1\n },\n \"connected\": true\n },\n \"redis\": {\n \"connected\": true\n }\n}")
158
+ end
159
+ end # info
160
+
161
+ describe '#remove_client' do
162
+ remove_response = '[{"subscriptions":["tomcat","all"],"name":"test2.example.com","safe_mode":false,"address":"172.31.0.2","bind":"127.0.0.1","keepalive":{},"version":"0.14.0","timestamp":1427887539},{"subscriptions":["apache","all"],"keepalive":{},"name":"test1.example.com","safe_mode":false,"address":"172.31.0.1","bind":"127.0.0.1","version":"0.14.0","timestamp":1427887548}]'
163
+
164
+ before do
165
+ allow_any_instance_of(Faraday::Connection).to receive(:delete).with('http://sensu.example.com:5678/clients/test1.example.com').and_return(response)
166
+ end
167
+
168
+ it 'should remove a client' do
169
+ allow(response).to receive(:status).and_return(202)
170
+ allow(response).to receive(:body).and_return(remove_response)
171
+ send_message('sensu remove client test1')
172
+ expect(replies.last).to eq('test1.example.com removed')
173
+ end
174
+
175
+ it 'should handle 404' do
176
+ allow(response).to receive(:status).and_return(404)
177
+ send_message('sensu remove client test1')
178
+ expect(replies.last).to eq('test1.example.com was not found')
179
+ end
180
+
181
+ it 'should handle internal sensu errors' do
182
+ allow(response).to receive(:status).and_return(500)
183
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
184
+ send_message('sensu remove client test1')
185
+ expect(replies.last).to eq('An error occurred removing test1.example.com')
186
+ end
187
+ end # remove_client
188
+
189
+ describe '#resolve' do
190
+ before do
191
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/resolve', '{"client":"test1.example.com","check":"pdns-server-running"}').and_return(response)
192
+ end
193
+
194
+ it 'should resolve an event' do
195
+ allow(response).to receive(:status).and_return(202)
196
+ send_message('sensu resolve event test1/pdns-server-running')
197
+ expect(replies.last).to eq('test1.example.com/pdns-server-running resolved')
198
+ end
199
+
200
+ it 'should handle malformed messages' do
201
+ allow(response).to receive(:status).and_return(400)
202
+ send_message('sensu resolve event test1/pdns-server-running')
203
+ expect(replies.last).to eq('Resolve message was malformed: {"client":"test1.example.com","check":"pdns-server-running"}')
204
+ end
205
+
206
+ it 'should handle 404' do
207
+ allow(response).to receive(:status).and_return(404)
208
+ send_message('sensu resolve event test1/pdns-server-running')
209
+ expect(replies.last).to eq('test1.example.com/pdns-server-running was not found')
210
+ end
211
+
212
+ it 'should handle internal sensu errors' do
213
+ allow(response).to receive(:status).and_return(500)
214
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
215
+ send_message('sensu resolve event test1/pdns-server-running')
216
+ expect(replies.last).to eq('There was an error resolving test1.example.com/pdns-server-running')
217
+ end
218
+ end # resolve
219
+
220
+ describe '#silence' do
221
+ it 'should silence an event on a specific client' do
222
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/silenced', '{"creator":"Test User","expire":3600,"reason":"Because Lita says so!","subscription":"client:test1.example.com","check":"disk-free"}').and_return(response)
223
+ allow(response).to receive(:status).and_return(201)
224
+ send_message('sensu silence test1/disk-free')
225
+ expect(replies.last).to eq('test1.example.com:disk-free silenced for 1h')
226
+ end
227
+
228
+ it 'should silence for seconds' do
229
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/silenced', '{"creator":"Test User","expire":1,"reason":"Because Lita says so!","subscription":"client:test1.example.com","check":"disk-free"}').and_return(response)
230
+ allow(response).to receive(:status).and_return(201)
231
+ send_message('sensu silence test1/disk-free for 1s')
232
+ expect(replies.last).to eq('test1.example.com:disk-free silenced for 1s')
233
+ end
234
+
235
+ it 'should silence a client' do
236
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/silenced', '{"creator":"Test User","expire":3600,"reason":"Because Lita says so!","subscription":"client:test1.example.com"}').and_return(response)
237
+ allow(response).to receive(:status).and_return(201)
238
+ send_message('sensu silence test1')
239
+ expect(replies.last).to eq('test1.example.com:* silenced for 1h')
240
+ end
241
+
242
+ it 'should silence for minutes' do
243
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/silenced', '{"creator":"Test User","expire":60,"reason":"Because Lita says so!","subscription":"client:test1.example.com"}').and_return(response)
244
+ allow(response).to receive(:status).and_return(201)
245
+ send_message('sensu silence test1 for 1m')
246
+ expect(replies.last).to eq('test1.example.com:* silenced for 1m')
247
+ end
248
+
249
+ it 'should silence for hours' do
250
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/silenced', '{"creator":"Test User","expire":3600,"reason":"Because Lita says so!","subscription":"client:test1.example.com"}').and_return(response)
251
+ allow(response).to receive(:status).and_return(201)
252
+ send_message('sensu silence test1 for 1h')
253
+ expect(replies.last).to eq('test1.example.com:* silenced for 1h')
254
+ end
255
+
256
+ it 'should silence for days' do
257
+ allow_any_instance_of(Faraday::Connection).to receive(:post)
258
+ .with(
259
+ 'http://sensu.example.com:5678/silenced',
260
+ '{"creator":"Test User","expire":86400,"reason":"Because Lita says so!","subscription":"client:test1.example.com"}'
261
+ ).and_return(response)
262
+ allow(response).to receive(:status).and_return(201)
263
+ send_message('sensu silence test1 for 1d')
264
+ expect(replies.last).to eq('test1.example.com:* silenced for 1d')
265
+ end
266
+
267
+ it 'should provide feedback for invalid duration' do
268
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/stashes', '{"content":{"by":"Test User"},"expire":3600,"path":"silence/test1.example.com"}').and_return(response)
269
+ allow(response).to receive(:status).and_return(201)
270
+ send_message('sensu silence test1 for 1z')
271
+ expect(replies.last).to eq('Unknown unit (z). I know s (seconds), m (minutes), h (hours), and d(days)')
272
+ end
273
+
274
+ it 'should handle internal sensu errors' do
275
+ allow_any_instance_of(Faraday::Connection).to receive(:post).with('http://sensu.example.com:5678/silenced', '{"creator":"Test User","expire":3600,"reason":"Because Lita says so!","subscription":"client:test1.example.com","check":"disk-free"}').and_return(response)
276
+ allow(response).to receive(:status).and_return(500)
277
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
278
+ send_message('sensu silence test1/disk-free')
279
+ expect(replies.last).to eq('An error occurred silencing to test1.example.com:disk-free')
280
+ end
281
+ end # silence
282
+
283
+ describe '#stashes' do
284
+ stashes_response = '[{"path":"silence/test1.example.com/disk-free","content":{"timestamp":1383441836},"expire":3600}]'
285
+
286
+ before do
287
+ allow_any_instance_of(Faraday::Connection).to receive(:get).with('http://sensu.example.com:5678/stashes').and_return(response)
288
+ end
289
+
290
+ it 'should list all clients' do
291
+ allow(response).to receive(:status).and_return(200)
292
+ allow(response).to receive(:body).and_return(stashes_response)
293
+ send_message('sensu stashes')
294
+ expect(replies.last).to eq("silence/test1.example.com/disk-free added on #{localtime('2013-11-02 19:23:56 -0600')} expires in 3600 seconds\n")
295
+ end
296
+
297
+ it 'should handle internal sensu errors' do
298
+ allow(response).to receive(:status).and_return(500)
299
+ expect(Lita.logger).to receive(:warn).with(/internal error/)
300
+ send_message('sensu stashes')
301
+ expect(replies.last).to eq('An error occurred fetching stashes')
302
+ end
303
+ end # stashes
304
+ end
@@ -0,0 +1,23 @@
1
+ require 'time'
2
+
3
+ def localtime(string)
4
+ Time.parse(string).to_time
5
+ end
6
+
7
+ require 'simplecov'
8
+ require 'coveralls'
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ Coveralls::SimpleCov::Formatter
12
+ ]
13
+ SimpleCov.start do
14
+ add_filter '/spec/'
15
+ add_filter '/.bundle/'
16
+ end
17
+
18
+ require 'lita-sensu2'
19
+ require 'lita/rspec'
20
+
21
+ # A compatibility mode is provided for older plugins upgrading from Lita 3. Since this plugin
22
+ # was generated with Lita 4, the compatibility mode should be left disabled.
23
+ Lita.version_3_compatibility_mode = false
File without changes
@@ -0,0 +1,4 @@
1
+ <% @history.each do |check| %>
2
+ <%= check[:check] %>: status - <%= check[:last_status] %>; last checked - <%= Time.at(check[:last_execution]) %>; history - <%= check[:history].join(',') %>
3
+
4
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <% @clients.each do |client| %>
2
+ <%= client[:name] %> (<%= client[:address] %>) subscriptions: <%= client[:subscriptions].sort().join(', ') %>
3
+
4
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% @events.each do |event| %>
2
+ <%= event[:client][:name] %> (<%= event[:check][:name] %>) - <%= event[:check][:output] %>
3
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <% @stashes.each do |stash| %>
2
+ <%= stash[:path] %> added on <%= Time.at(stash[:content][:timestamp]) %>
3
+ <% if stash[:content][:by] %>
4
+ by <%= stash[:content][:by] %>
5
+ <% end %>
6
+ <% if stash[:expire] %>
7
+ expires in <%= stash[:expire] %> seconds
8
+ <% end %>
9
+ <% end %>
metadata ADDED
@@ -0,0 +1,222 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-sensu2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Gnagy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lita
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.0.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 3.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: coveralls
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: travis
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.8'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.8'
167
+ description: Lita plugin to interact with sensu
168
+ email:
169
+ - jgnagy@knuedge.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - ".gitignore"
175
+ - ".rubocop.yml"
176
+ - ".travis.yml"
177
+ - CHANGELOG
178
+ - Gemfile
179
+ - LICENSE
180
+ - README.md
181
+ - Rakefile
182
+ - lib/lita-sensu2.rb
183
+ - lib/lita/handlers/sensu2.rb
184
+ - lib/utils/sensu.rb
185
+ - lib/utils/sensu_http.rb
186
+ - lita-sensu2.gemspec
187
+ - locales/en.yml
188
+ - spec/lita/handlers/sensu2_spec.rb
189
+ - spec/spec_helper.rb
190
+ - templates/.gitkeep
191
+ - templates/client_history.erb
192
+ - templates/clients.erb
193
+ - templates/events.erb
194
+ - templates/stashes.erb
195
+ homepage: https://github.com/knuedge/lita-sensu2
196
+ licenses:
197
+ - Apache-2.0
198
+ metadata:
199
+ lita_plugin_type: handler
200
+ post_install_message:
201
+ rdoc_options: []
202
+ require_paths:
203
+ - lib
204
+ required_ruby_version: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ required_rubygems_version: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ requirements: []
215
+ rubyforge_project:
216
+ rubygems_version: 2.5.1
217
+ signing_key:
218
+ specification_version: 4
219
+ summary: Lita plugin to interact with sensu
220
+ test_files:
221
+ - spec/lita/handlers/sensu2_spec.rb
222
+ - spec/spec_helper.rb