lita-salt 0.2.1.pre.beta

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: 38bbf17d0221465533511be02e3d4ff0c91996fe
4
+ data.tar.gz: 50b763e665c535666d2fbe2a9e611cde83ddd7c9
5
+ SHA512:
6
+ metadata.gz: 1a8cf9ad80f7741da52c89053b1bc37c298d0c085c226fed0c3c3efa91bdcad0ba61c0d7326ee32e360ebc7d8490ad1035f309050a9c07481bf5b3c3df8ee3d4
7
+ data.tar.gz: 335e4d043681e34e49beb925bc12063ed544d93f6f3b1f5b92f4f1c3bbf7af8e7820b899a9cee115037709da29dc91cac34411383b894e8ad896de5b0f7786cd
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015 Sophicware
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # lita-salt [![Gem Version](https://badge.fury.io/rb/lita-salt.svg)](http://badge.fury.io/rb/lita-salt)
2
+
3
+ **lita-salt** is an adapter for Lita that gives your bot the power to interact with your saltstack installation via salt-api.
4
+
5
+ ## Installation
6
+
7
+ Add lita-salt to your Lita instance's Gemfile:
8
+
9
+ ``` ruby
10
+ gem "lita-salt"
11
+ ```
12
+
13
+ ## Configuration
14
+
15
+ ### Required attributes
16
+
17
+ * `url` (String) – The location of the running salt-api service.
18
+ * `username` (String) – The username used to authenticate with salt-api.
19
+ * `password` (String) – The password used to authenticate with salt-api.
20
+
21
+ ### Example
22
+
23
+ ``` ruby
24
+ Lita.configure do |config|
25
+ config.handlers.salt.url = "https://api.example.com"
26
+ config.handlers.salt.username = ENV["SALT_USERNAME"]
27
+ config.handlers.salt.password = ENV["SALT_PASSWORD"]
28
+ end
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ Commands are called in the with the `salt` prefix what can be optionally with the `s` abbreviation.
34
+
35
+ ```shell
36
+ lita: salt minion service.restart nginx
37
+ @lita s minion schedule.run_job apt
38
+ lita: salt pillar get "some_key"
39
+ ```
40
+
41
+ ### Example
42
+
43
+ `lita: salt up` executes the `manage.up` runner and returns a list of up minions.
44
+
45
+ ## License
46
+
47
+ [MIT](http://opensource.org/licenses/MIT)
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,231 @@
1
+ require 'json'
2
+ require 'time'
3
+ require 'lita/utils/payload'
4
+ require 'lita/utils/decorate'
5
+
6
+
7
+
8
+ module Lita
9
+ module Handlers
10
+ class Salt < Handler
11
+ include Utils::Payload
12
+ include Utils::Decorate
13
+
14
+ config :url, required: true
15
+ config :username, required: true
16
+ config :password, required: true
17
+
18
+
19
+
20
+ class << self
21
+ attr_accessor :token, :expires, :command_prefix
22
+ end
23
+
24
+ def self.config(config)
25
+ self.token = nil
26
+ self.expires = nil
27
+ self.command_prefix = "^s(?:alt)?"
28
+ end
29
+
30
+ def self.abbreviate(term)
31
+ "#{term[0]}(?:#{term[1,term.length]})?"
32
+ end
33
+
34
+
35
+
36
+ route /^#{abbreviate("salt")} up$/i, :manage_up, command: true, help: {
37
+ 'salt up' => 'lists alive minions'
38
+ }
39
+
40
+ route /^#{abbreviate("salt")} down$/i, :manage_down, command: true, help: {
41
+ 'salt down' => 'lists dead minions'
42
+ }
43
+
44
+ route /^#{abbreviate("salt")} login$/i, :login, command: true, help: {
45
+ 'salt login' => 'renew auth token'
46
+ }
47
+
48
+ route /^#{abbreviate("salt")}\s(.+)\sservice\.(restart|start|stop)\s(.+)$/i, :service, command: true, help: {
49
+ 'salt minion service.(restart|start|stop)' => 'Performs defined action on service'
50
+ }
51
+
52
+ route /^#{abbreviate("salt")}\s(.+)\sschedule\.(run_job|enable_job|disable_job|list)(?:\s(.+))?$/i, :schedule, command: true, help: {
53
+ 'salt minion schedule.(run_job|enable_job|disable_job|list)' => 'Interacts with schduling system'
54
+ }
55
+
56
+ route /^#{abbreviate("salt")}\s(.+)\ssupervisord\.(status|start|stop|restart|add|remove)\s(.+)$/i, :supervisord, command: true, help: {
57
+ 'salt minion supervisord.(status|start|stop|restart|add|remove)' => 'Execute supervisor action'
58
+ }
59
+
60
+ route /^#{abbreviate("salt")} pillar(?: #{abbreviate("help")})$/i, :pillar, command: true, help: {
61
+ 'salt pillar get "some_key"' => 'get a pillar value'
62
+ }
63
+
64
+ route /^#{abbreviate("salt")} pillar (get|show)$/i, :pillar, command: true, help: {
65
+ 'salt pillar get "some_key"' => 'get a pillar value',
66
+ 'salt pillar show "some_minion"' => 'show pillar for given minion'
67
+ }
68
+
69
+ def authenticate
70
+ resp = http.post("#{config.url}/login") do |req|
71
+ req.body = {}
72
+ req.body['eauth'] = 'pam'
73
+ req.body['username'] = config.username
74
+ req.body['password'] = config.password
75
+ end
76
+ self.class.token = resp.headers['X-Auth-Token']
77
+ self.class.expires = JSON.parse(resp.body)['return'][0]['expire']
78
+ resp
79
+ end
80
+
81
+ def login(msg)
82
+ http_resp = authenticate
83
+
84
+ if http_resp.status == 200
85
+ msg.reply "login successful\ntoken: #{self.class.token}"
86
+ elsif http_resp.status == 500
87
+ msg.reply "#{http_resp.status}: login failed!!"
88
+ end
89
+
90
+ end
91
+
92
+ def headers
93
+ headers = {}
94
+ headers['Content-Type'] = 'application/json'
95
+ headers['X-Auth-Token'] = self.class.token
96
+ headers
97
+ end
98
+
99
+ def manage_up(msg)
100
+ if expired
101
+ authenticate
102
+ end
103
+ body = build_runner('manage.up')
104
+ response = make_request('/', body)
105
+ if response.status == 200
106
+ msg.reply response.body
107
+ else
108
+ msg.reply "Failed to run command: #{body}\nError: #{response.body}"
109
+ end
110
+ end
111
+
112
+ def manage_down(msg)
113
+ if expired
114
+ authenticate
115
+ end
116
+ body = build_runner('manage.down')
117
+ response = make_request('/', body)
118
+ if response.status == 200
119
+ msg.reply response.body
120
+ else
121
+ msg.reply "Failed to run command: #{body}\nError: #{response.body}"
122
+ end
123
+ end
124
+
125
+ def service(msg)
126
+ if expired
127
+ authenticate
128
+ end
129
+ where = msg.matches.flatten.first
130
+ task = msg.matches.flatten[1]
131
+ what = msg.matches.flatten[2]
132
+ if what.nil?
133
+ msg.reply "Missing service name"
134
+ else
135
+ body = build_local(where, "#{__callee__}.#{task}", what)
136
+ response = make_request('/', body)
137
+ msg.reply process_response(response)
138
+ end
139
+ end
140
+
141
+ def schedule(msg)
142
+ if expired
143
+ authenticate
144
+ end
145
+ where = msg.matches.flatten.first
146
+ task = msg.matches.flatten[1]
147
+ what = msg.matches.flatten[2]
148
+ if what.nil?
149
+ msg.reply "Missing job name"
150
+ else
151
+ body = build_local(where, "#{__callee__}.#{task}", what)
152
+ response = make_request('/', body)
153
+ msg.reply process_response(response)
154
+ end
155
+ end
156
+
157
+ def supervisord(msg)
158
+ if expired
159
+ authenticate
160
+ end
161
+ where = msg.matches.flatten.first
162
+ task = msg.matches.flatten[1]
163
+ what = msg.matches.flatten[2]
164
+ if what.nil?
165
+ msg.reply "Missing job name"
166
+ else
167
+ body = build_local(where, "#{__callee__}.#{task}", what)
168
+ response = make_request('/', body)
169
+ msg.reply process_response(response)
170
+ end
171
+ end
172
+
173
+ def process_response(response)
174
+ out = nil
175
+ case response.status
176
+ when 200
177
+ out = response.body
178
+ when 400..405
179
+ out = "You lack the permissions to perform this action"
180
+ else
181
+ out = "Failed to run command: #{body}\nError: #{response.body}"
182
+ end
183
+ out
184
+ end
185
+
186
+ def pillar(msg)
187
+ if expired
188
+ authenticate
189
+ end
190
+ where = msg.matches.flatten.first
191
+ task = msg.matches.flatten[1]
192
+ what = msg.matches.flatten[2]
193
+ if what.nil?
194
+ msg.reply "Missing job name"
195
+ else
196
+ body = build_local(where, "#{__callee__}.#{task}", what)
197
+ response = make_request('/', body)
198
+ msg.reply_privately process_response(response)
199
+ end
200
+ end
201
+
202
+ def expired
203
+ self.class.token.nil? || Time.now >= Time.at(self.class.expires)
204
+ end
205
+
206
+ def make_request(path, body)
207
+ resp = http.post("#{config.url}#{path}") do |req|
208
+ req.body = {}
209
+ req.headers = headers
210
+ req.body = body
211
+ end
212
+ resp
213
+ end
214
+
215
+ def url
216
+ config.url
217
+ end
218
+
219
+ def username
220
+ config.username
221
+ end
222
+
223
+ def password
224
+ config.password
225
+ end
226
+
227
+ end
228
+
229
+ Lita.register_handler(Salt)
230
+ end
231
+ end
@@ -0,0 +1,52 @@
1
+ module Utils
2
+ module Decorate
3
+ @@auth ||= []
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base
8
+ end
9
+ #def initialize(route)
10
+ # @route = route
11
+ #end
12
+
13
+ module ClassMethods
14
+ def check_auth(*methods)
15
+ methods.each do |method|
16
+ old = "_#{method}".to_sym
17
+ alias_method old, method
18
+ define_method method do |*args|
19
+ send(old, *args)
20
+ end
21
+ #if self.class_eval("expired")
22
+ # authenticate
23
+ #end
24
+ #unless self.respond_to?(arg)
25
+ # self.class.send(:define_method,arg,Proc.new {})
26
+ #self.class_eval(self.methods[arg])
27
+ end
28
+ end
29
+ end
30
+
31
+ def check_auth(*args)
32
+ args.each do |arg|
33
+ #if self.class_eval("expired")
34
+ # authenticate
35
+ #end
36
+ self.class_eval(arg.to_s)
37
+ end
38
+ end
39
+
40
+ =begin
41
+ def manage_up(msg)
42
+ if expired
43
+ authenticate
44
+ end
45
+ @route.manage_up(msg)
46
+ end
47
+
48
+ def manage_down
49
+ @route.manage_up(msg)
50
+ =end
51
+ end
52
+ end
@@ -0,0 +1,23 @@
1
+ require 'json'
2
+
3
+ module Utils
4
+ module Payload
5
+
6
+ def build_runner(function)
7
+ JSON.dump({
8
+ client: :runner,
9
+ fun: function
10
+ })
11
+ end
12
+
13
+ def build_local(target, function, arg=nil)
14
+ s = {
15
+ client: :local,
16
+ tgt: target,
17
+ fun: function,
18
+ }
19
+ s['arg'] = [arg] unless arg.nil?
20
+ JSON.dump(s)
21
+ end
22
+ end
23
+ end
data/lib/lita-salt.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "lita"
2
+
3
+ Lita.load_locales Dir[File.expand_path(
4
+ File.join("..", "..", "locales", "*.yml"), __FILE__
5
+ )]
6
+
7
+ require "lita/handlers/salt"
8
+ require "lita/utils/payload"
9
+
10
+ Lita::Handlers::Salt.template_root File.expand_path(
11
+ File.join("..", "..", "templates"),
12
+ __FILE__
13
+ )
data/lita-salt.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "lita-salt"
3
+ spec.version = "0.2.1-beta"
4
+ spec.authors = ["Jurnell Cockhren"]
5
+ spec.email = ["jurnell@sophicware.com"]
6
+ spec.description = %q{Salt handler for lita 4+}
7
+ spec.summary = spec.description
8
+ spec.homepage = "https://github.com/sophicware/lita-salt"
9
+ spec.license = "MIT"
10
+ spec.metadata = { "lita_plugin_type" => "handler" }
11
+
12
+ spec.files = `git ls-files`.split($/)
13
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
+ spec.require_paths = ["lib"]
15
+
16
+ spec.add_runtime_dependency "lita", "~> 4.2"
17
+
18
+ spec.add_development_dependency "bundler", "~> 1.3"
19
+ spec.add_development_dependency "rake"
20
+ spec.add_development_dependency "rack-test"
21
+ spec.add_development_dependency "rspec", ">= 3.0.0"
22
+ spec.add_development_dependency "simplecov"
23
+ spec.add_development_dependency "coveralls"
24
+ spec.add_development_dependency "webmock"
25
+ spec.add_development_dependency "guard-rake"
26
+ spec.add_development_dependency "guard-rspec"
27
+ end
@@ -0,0 +1,182 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Handlers::Salt, lita_handler: true do
4
+
5
+ let(:response) {double("Faraday::Response")}
6
+ let(:reply) {""}
7
+ let(:vals) { {url: "https://example.com", username: "timmy", password: "12345"} }
8
+ let(:token) {"122938u98j9r82u3r"}
9
+ let(:salt) { described_class.new }
10
+
11
+ describe "config" do
12
+ before do
13
+ Lita.config.handlers.salt.url = vals[:url]
14
+ Lita.config.handlers.salt.username = vals[:username]
15
+ Lita.config.handlers.salt.password = vals[:password]
16
+ described_class.any_instance.stub(:default_config).and_return(vals)
17
+ end
18
+
19
+ it "should wrap url config vars" do
20
+ expect(salt).to respond_to(:url)
21
+ expect(salt.url).to eql(vals[:url])
22
+ end
23
+ it "should wrap username config vars" do
24
+ expect(salt).to respond_to(:username)
25
+ expect(salt.username).to eql(vals[:username])
26
+ end
27
+ it "should wrap password config vars" do
28
+ expect(salt).to respond_to(:password)
29
+ expect(salt.password).to eql(vals[:password])
30
+ end
31
+
32
+ end
33
+
34
+ describe "#login" do
35
+ before do
36
+ stub_request(:post, "#{vals[:url]}/login").
37
+ to_return(status: 200,
38
+ body: JSON.dump(return: [{token: token, expire: 1424352200.50011}]),
39
+ headers: {'X-Auth-Token' => token}
40
+ )
41
+ end
42
+
43
+ it { is_expected.to route_command('salt login').to(:login) }
44
+ it "should greet user at successful login" do
45
+ allow(response).to receive(:status).and_return(200)
46
+ allow(response).to receive(:body).and_return(reply)
47
+ allow(response).to receive(:headers).and_return(token)
48
+ send_command('s login')
49
+ expect(replies.last).to eq("login successful\ntoken: #{token}")
50
+ end
51
+ end
52
+
53
+ describe "#manage_up" do
54
+ before do
55
+ stub_request(:post, "#{vals[:url]}/login").
56
+ with(body: {eauth: "pam", password: vals[:password], username: vals[:username]}).
57
+ to_return(status: 200,
58
+ body: JSON.dump(return: [{token: token, expire: 1424352200.50011}]),
59
+ headers: {'X-Auth-Token' => token}
60
+ )
61
+ stub_request(:post, vals[:url]).
62
+ to_return(status: 200,
63
+ body: JSON.dump(return: [[:main, :silly]])
64
+ )
65
+ end
66
+
67
+ it { is_expected.to route_command('salt up').to(:manage_up) }
68
+ it { is_expected.to route_command('s up').to(:manage_up) }
69
+ it "should return a list of alive minions" do
70
+ allow(response).to receive(:status).and_return(200)
71
+ allow(response).to receive(:body).and_return(reply)
72
+ allow(response).to receive(:headers).and_return(token)
73
+ send_command('s up')
74
+ expect(replies.last).to eq(JSON.dump(return: [['main','silly']]))
75
+ end
76
+ end
77
+
78
+ describe "#manage_down" do
79
+ before do
80
+ stub_request(:post, "#{vals[:url]}/login").
81
+ with(body: {eauth: "pam", password: vals[:password], username: vals[:username]}).
82
+ to_return(status: 200,
83
+ body: JSON.dump(return: [{token: token, expire: 1424352200.50011}]),
84
+ headers: {'X-Auth-Token' => token}
85
+ )
86
+ stub_request(:post, vals[:url]).
87
+ to_return(status: 200,
88
+ body: JSON.dump(return: [[:main, :silly]])
89
+ )
90
+ end
91
+
92
+ it { is_expected.to route_command('salt down').to(:manage_down) }
93
+ it { is_expected.to route_command('s down').to(:manage_down) }
94
+ it "should return a list of dead minions" do
95
+ allow(response).to receive(:status).and_return(200)
96
+ allow(response).to receive(:body).and_return(reply)
97
+ allow(response).to receive(:headers).and_return(token)
98
+ send_command('s down')
99
+ expect(replies.last).to eq(JSON.dump(return: [['main','silly']]))
100
+ end
101
+ end
102
+
103
+ describe "#service" do
104
+ before do
105
+ stub_request(:post, "#{vals[:url]}/login").
106
+ with(body: {eauth: "pam", password: vals[:password], username: vals[:username]}).
107
+ to_return(status: 200,
108
+ body: JSON.dump(return: [{token: token, expire: 1424352200.50011}]),
109
+ headers: {'X-Auth-Token' => token}
110
+ )
111
+ stub_request(:post, vals[:url]).
112
+ to_return(status: 200,
113
+ body: JSON.dump(return: [[:main, :silly]])
114
+ )
115
+ end
116
+
117
+ it { is_expected.to route_command('salt minion service.restart someservice').to(:service) }
118
+ it { is_expected.to route_command('s minion service.restart someservice').to(:service) }
119
+
120
+ end
121
+
122
+ describe "#schedule" do
123
+ before do
124
+ stub_request(:post, "#{vals[:url]}/login").
125
+ with(body: {eauth: "pam", password: vals[:password], username: vals[:username]}).
126
+ to_return(status: 200,
127
+ body: JSON.dump(return: [{token: token, expire: 1424352200.50011}]),
128
+ headers: {'X-Auth-Token' => token}
129
+ )
130
+ stub_request(:post, vals[:url]).
131
+ to_return(status: 200,
132
+ body: JSON.dump(return: [[:main, :silly]])
133
+ )
134
+ end
135
+
136
+ it { is_expected.to route_command('salt minion schedule.list').to(:schedule) }
137
+ it { is_expected.to route_command('s minion schedule.list').to(:schedule) }
138
+
139
+ end
140
+
141
+ describe "#supervisord" do
142
+ before do
143
+ stub_request(:post, "#{vals[:url]}/login").
144
+ with(body: {eauth: "pam", password: vals[:password], username: vals[:username]}).
145
+ to_return(status: 200,
146
+ body: JSON.dump(return: [{token: token, expire: 1424352200.50011}]),
147
+ headers: {'X-Auth-Token' => token}
148
+ )
149
+ stub_request(:post, vals[:url]).
150
+ to_return(status: 200,
151
+ body: JSON.dump(return: [[:main, :silly]])
152
+ )
153
+ end
154
+
155
+ it { is_expected.to route_command('salt minion supervisord.status nginx').to(:supervisord) }
156
+ it { is_expected.to route_command('s minion supervisord.status nginx').to(:supervisord) }
157
+
158
+ end
159
+
160
+ describe "#pillar_get" do
161
+ before do
162
+ stub_request(:post, "#{vals[:url]}/login").
163
+ with(body: {eauth: "pam", password: vals[:password], username: vals[:username]}).
164
+ to_return(status: 200,
165
+ body: JSON.dump(return: [{token: token, expire: 1424352200.50011}]),
166
+ headers: {'X-Auth-Token' => token}
167
+ )
168
+ stub_request(:post, vals[:url]).
169
+ to_return(status: 200,
170
+ body: JSON.dump(return: [[:main, :silly]])
171
+ )
172
+ end
173
+
174
+ #it { is_expected.to route_command('salt pillar').to(:pillar) }
175
+ it { is_expected.to route_command('salt pillar help').to(:pillar) }
176
+ it { is_expected.to route_command('salt pillar h').to(:pillar) }
177
+ it { is_expected.to route_command('s pillar help').to(:pillar) }
178
+ it { is_expected.to route_command('s pillar h').to(:pillar) }
179
+
180
+ end
181
+
182
+ end
@@ -0,0 +1,16 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+ require 'webmock/rspec'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
9
+ SimpleCov.start { add_filter "/spec/" }
10
+
11
+ require "lita-salt"
12
+ require "lita/rspec"
13
+
14
+ # A compatibility mode is provided for older plugins upgrading from Lita 3. Since this plugin
15
+ # was generated with Lita 4, the compatibility mode should be left disabled.
16
+ Lita.version_3_compatibility_mode = false
metadata ADDED
@@ -0,0 +1,199 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-salt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1.pre.beta
5
+ platform: ruby
6
+ authors:
7
+ - Jurnell Cockhren
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-31 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.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
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: rake
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: rack-test
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: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: coveralls
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: webmock
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: guard-rake
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: guard-rspec
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
+ description: Salt handler for lita 4+
154
+ email:
155
+ - jurnell@sophicware.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".gitignore"
161
+ - Gemfile
162
+ - LICENSE
163
+ - README.md
164
+ - Rakefile
165
+ - lib/lita-salt.rb
166
+ - lib/lita/handlers/salt.rb
167
+ - lib/lita/utils/decorate.rb
168
+ - lib/lita/utils/payload.rb
169
+ - lita-salt.gemspec
170
+ - spec/lita/handlers/salt_spec.rb
171
+ - spec/spec_helper.rb
172
+ homepage: https://github.com/sophicware/lita-salt
173
+ licenses:
174
+ - MIT
175
+ metadata:
176
+ lita_plugin_type: handler
177
+ post_install_message:
178
+ rdoc_options: []
179
+ require_paths:
180
+ - lib
181
+ required_ruby_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ required_rubygems_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - ">"
189
+ - !ruby/object:Gem::Version
190
+ version: 1.3.1
191
+ requirements: []
192
+ rubyforge_project:
193
+ rubygems_version: 2.4.5
194
+ signing_key:
195
+ specification_version: 4
196
+ summary: Salt handler for lita 4+
197
+ test_files:
198
+ - spec/lita/handlers/salt_spec.rb
199
+ - spec/spec_helper.rb