silver_spurs 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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
+ \#*#
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in silver_spurs.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ end
10
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Christian Blades
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # SilverSpurs
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'silver_spurs'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install silver_spurs
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,55 @@
1
+ require 'sinatra/base'
2
+ require 'silver_spurs/knife_interface'
3
+ require 'json'
4
+
5
+
6
+ module SilverSpurs
7
+ class App < Sinatra::Base
8
+
9
+ set :deployment_key, "/etc/chef/deployment_key.pem"
10
+ set :deployment_user, "silverspurs"
11
+ # sane setting for AD subdomain
12
+ set :node_name_filter, /^[-A-Za-z0-9]{3,15}$/
13
+
14
+ get '/' do
15
+ %q| Ride 'em, cowboy |
16
+ end
17
+
18
+ get '/settings' do
19
+ important_settings =
20
+ [
21
+ :deployment_key,
22
+ :deployment_user,
23
+ :node_name_filter
24
+ ]
25
+
26
+ Hash[ important_settings.map {|key| [key, settings.send(key)]} ].to_json
27
+ end
28
+
29
+ put '/bootstrap/:ip' do
30
+ required_params = [:node_name]
31
+ unless required_vars? params, required_params
32
+ return 406, {:required_params => required_params}.to_json
33
+ end
34
+
35
+ node_name = params[:node_name].strip
36
+ return 406, {:bad_params => :node_name}.to_json unless node_name =~ settings.node_name_filter
37
+
38
+ bootstrap_options = Hash[KnifeInterface.supported_arguments.map do |arg|
39
+ value = params[arg]
40
+ next if value.nil?
41
+ [arg, params[arg]]
42
+ end]
43
+
44
+ result = KnifeInterface.bootstrap(params[:ip], node_name, settings.deployment_user, settings.deployment_key, bootstrap_options)
45
+ status_code = result[:exit_code] == 0 ? 201 : 500
46
+
47
+ return status_code, result.to_json
48
+ end
49
+
50
+ def required_vars?(params, requirement_list)
51
+ requirement_list.none? { |required_param| params[required_param].nil? }
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,12 @@
1
+ module SilverSpurs
2
+ class ClientException < Exception
3
+ attr_reader :message, :response
4
+
5
+ def initialize(message, response=nil)
6
+ @message = message
7
+ @response = response
8
+ end
9
+ end
10
+ end
11
+
12
+
@@ -0,0 +1,42 @@
1
+ require 'rest-client'
2
+ require 'addressable/uri'
3
+ require 'json'
4
+ require 'silver_spurs/knife_interface'
5
+ require 'silver_spurs/client/exceptions'
6
+
7
+ module SilverSpurs
8
+ class Client
9
+ def initialize(host_url, options={})
10
+ @host_url = host_url
11
+ end
12
+
13
+ def bootstrap(ip, node_name, options = {})
14
+ params = extract_extra_params(options).merge({:node_name => node_name})
15
+ payload = parameterize_hash params
16
+ headers = {:accept => :json, :content_type=> 'application/x-www-form-urlencoded'}
17
+
18
+ response = spur_host["bootstrap/#{ip}"].put(payload, headers)
19
+ throw ClientException("unexpected response", response) unless response.code == 201
20
+
21
+ JSON.parse response.body
22
+ end
23
+
24
+ private
25
+
26
+ def parameterize_hash(param_hash)
27
+ uri = Addressable::URI.new
28
+ uri.query_values = param_hash
29
+ uri.query
30
+ end
31
+
32
+ def extract_extra_params(options)
33
+ supported_arguments = KnifeInterface.supported_arguments
34
+ options.select {|k,v| supported_arguments.include? k}
35
+ end
36
+
37
+ def spur_host
38
+ RestClient::Resource.new(@host_url, :timeout => 15 * 60)
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,57 @@
1
+ module SilverSpurs
2
+ class KnifeInterface
3
+ BOOTSTRAP_ARGS_MAP = {
4
+ :identity_file => '-i',
5
+ :ssh_user => '-x',
6
+ :node_name => '-N',
7
+ :distro => '-d',
8
+ :bootstrap_version => '--bootstrap-version',
9
+ :bootstrap_proxy => '--bootstrap-proxy',
10
+ :gateway => '-G',
11
+ :json_attributes => '-j',
12
+ :ssh_port => '-p',
13
+ :ssh_password => '--ssh-password',
14
+ :run_list => '-r'
15
+ }
16
+
17
+ def self.supported_arguments
18
+ BOOTSTRAP_ARGS_MAP.map {|k,v| k}
19
+ end
20
+
21
+ def self.expand_bootstrap_args(arguments)
22
+ BOOTSTRAP_ARGS_MAP.map do |arg, flag|
23
+ value = arguments[arg]
24
+ next nil if value.nil?
25
+
26
+ "#{flag} '#{value}'"
27
+ end.reject {|arg| arg.nil?}
28
+ end
29
+
30
+ def self.bootstrap(ip, node_name, deployment_user, deployment_key, options = {})
31
+ bootstrap_options = {
32
+ :identity_file => deployment_key,
33
+ :ssh_user => deployment_user,
34
+ :node_name => node_name
35
+ }.merge options
36
+
37
+ arguments = expand_bootstrap_args bootstrap_options
38
+
39
+ strap_r, strap_w = IO.pipe
40
+
41
+ knife_pid = spawn('knife', 'bootstrap', *arguments, ip, :err => :out, :out => strap_w)
42
+
43
+ Process.waitpid(knife_pid)
44
+ exitcode = $?.exitstatus
45
+
46
+ strap_w.close
47
+ loglines = strap_r.read
48
+ strap_r.close
49
+
50
+ {
51
+ :exit_code => exitcode,
52
+ :log_lines => loglines
53
+ }
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module SilverSpurs
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,6 @@
1
+ require 'silver_spurs/version'
2
+ require 'silver_spurs/app'
3
+
4
+ module SilverSpurs
5
+ # I'm a module! Everything important is elsewhere
6
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/silver_spurs/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Christian Blades"]
6
+ gem.email = ["christian.blades@careerbuilder.com"]
7
+ gem.description = %q{This is a simple REST service to kick off bootstrap processes. It is intended for use in a VPC-type environment with limited access.}
8
+ gem.summary = %q{RESTful service to kick off chef bootstraps}
9
+ gem.homepage = "http://github.com/christian-blades-cb/silver_spurs"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "silver_spurs"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = SilverSpurs::VERSION
17
+
18
+ gem.add_dependency 'sinatra', '>= 1.3.5'
19
+ gem.add_dependency 'chef', '>= 10.18.2'
20
+ gem.add_dependency 'rest-client', '~> 1.6.7'
21
+ gem.add_dependency 'addressable', '~> 2.3.3'
22
+
23
+ gem.add_development_dependency 'guard'
24
+ gem.add_development_dependency 'guard-rspec'
25
+ gem.add_development_dependency 'simplecov'
26
+ gem.add_development_dependency 'growl'
27
+ gem.add_development_dependency 'rb-fsevent', '~> 0.9'
28
+ gem.add_development_dependency 'rack-test'
29
+
30
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe SilverSpurs::App do
4
+ include Rack::Test::Methods
5
+
6
+ def app
7
+ SilverSpurs::App
8
+ end
9
+
10
+ describe "/bootstrap/:ip" do
11
+
12
+ context "with bad node name" do
13
+
14
+ it "should reject node names with spaces" do
15
+ node_name = "your mom"
16
+ put "/bootstrap/10.0.0.0", :node_name => node_name
17
+ last_response.status.should be 406
18
+ end
19
+
20
+ it "should reject node names with underscores" do
21
+ node_name = "your_mom"
22
+ put "/bootstrap/10.0.0.0", :node_name => node_name
23
+ last_response.status.should eq 406
24
+ end
25
+
26
+ it "should reject node names with other chars" do
27
+ node_name = "node[name]*%$"
28
+ put "/bootstrap/10.0.0.0", :node_name => node_name
29
+ last_response.status.should eq 406
30
+ end
31
+
32
+ it "should reject empty node names" do
33
+ node_name = ""
34
+ put "/bootstrap/10.0.0.0", :node_name => node_name
35
+ last_response.status.should eq 406
36
+ end
37
+
38
+ it "should reject node names under 3 chars" do
39
+ node_name = "12"
40
+ put "/bootstrap/10.0.0.0", :node_name => node_name
41
+ last_response.status.should eq 406
42
+ end
43
+
44
+ it "should reject node names over 15 chars" do
45
+ node_name = "1234567890123456"
46
+ put "/bootstrap/10.0.0.0", :node_name => node_name
47
+ last_response.status.should eq 406
48
+ end
49
+
50
+ end
51
+
52
+ context "with good node name" do
53
+ before(:each) do
54
+ SilverSpurs::KnifeInterface.stub(:bootstrap).and_return({:exit_code => 0, :log_lines => "I'm a test!"})
55
+ end
56
+
57
+ it "should accept node names with dashes" do
58
+ node_name = "your-mom"
59
+ put "/bootstrap/10.0.0.0", :node_name => node_name
60
+ last_response.status.should eq 201
61
+ end
62
+
63
+ it "should accept one-word node names" do
64
+ node_name = "mom"
65
+ put "/bootstrap/10.0.0.0", :node_name => node_name
66
+ last_response.status.should eq 201
67
+ end
68
+
69
+ it "should accept node names with numbers" do
70
+ node_name = "mombot-3000"
71
+ put "/bootstrap/10.0.0.0", :node_name => node_name
72
+ last_response.status.should eq 201
73
+ end
74
+
75
+ it "should accept node names with 15 chars" do
76
+ node_name = "123456789012345"
77
+ put "/bootstrap/10.0.0.0", :node_name => node_name
78
+ last_response.status.should eq 201
79
+ end
80
+
81
+ it "should accept node names with 3 chars" do
82
+ node_name = "123"
83
+ put "/bootstrap/10.0.0.0", :node_name => node_name
84
+ last_response.status.should eq 201
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end
91
+
92
+
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe SilverSpurs::KnifeInterface do
4
+
5
+ describe "expand_bootstrap_options" do
6
+ it "expands :identity_file" do
7
+ args = {:identity_file => 'IDENTITY_FILE'}
8
+ expected = %q{-i 'IDENTITY_FILE'}
9
+
10
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
11
+ end
12
+
13
+ it "expands :ssh_user" do
14
+ args = {:ssh_user => 'SSH_USER'}
15
+ expected = %q{-x 'SSH_USER'}
16
+
17
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
18
+ end
19
+
20
+ it 'expands :node_name' do
21
+ args = {:node_name => 'NODE_NAME'}
22
+ expected = %q{-N 'NODE_NAME'}
23
+
24
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
25
+ end
26
+
27
+ it 'expands :distro' do
28
+ args = {:distro => 'DISTRO'}
29
+ expected = %q{-d 'DISTRO'}
30
+
31
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
32
+ end
33
+
34
+ it 'expands :bootstrap_version' do
35
+ args = {:bootstrap_version => 'BOOTSTRAP_VERSION'}
36
+ expected = %q{--bootstrap-version 'BOOTSTRAP_VERSION'}
37
+
38
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
39
+ end
40
+
41
+ it 'expands :bootstrap_proxy' do
42
+ args = {:bootstrap_proxy => 'BOOTSTRAP_PROXY'}
43
+ expected = %q{--bootstrap-proxy 'BOOTSTRAP_PROXY'}
44
+
45
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
46
+ end
47
+
48
+ it 'expands :gateway' do
49
+ args = {:gateway => 'GATEWAY'}
50
+ expected = %q{-G 'GATEWAY'}
51
+
52
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
53
+ end
54
+
55
+ it 'expands :json_attributes' do
56
+ args = {:json_attributes => 'JSON_ATTRIBUTES'}
57
+ expected = %q{-j 'JSON_ATTRIBUTES'}
58
+
59
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
60
+ end
61
+
62
+ it 'expands :ssh_port' do
63
+ args = {:ssh_port => 'SSH_PORT'}
64
+ expected = %q{-p 'SSH_PORT'}
65
+
66
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
67
+ end
68
+
69
+ it 'expands :ssh_password' do
70
+ args = {:ssh_password => 'SSH_PASSWORD'}
71
+ expected = %q{--ssh-password 'SSH_PASSWORD'}
72
+
73
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
74
+ end
75
+
76
+ it 'expands :run_list' do
77
+ args = {:run_list => 'RUN_LIST1,RUN_LIST2'}
78
+ expected = %q{-r 'RUN_LIST1,RUN_LIST2'}
79
+
80
+ SilverSpurs::KnifeInterface.expand_bootstrap_args(args).should eq [expected]
81
+ end
82
+
83
+ end
84
+ end
85
+
86
+
87
+
@@ -0,0 +1,5 @@
1
+ require_relative '../lib/silver_spurs'
2
+ require 'rack/test'
3
+
4
+ SilverSpurs::App.environment = :test
5
+
metadata ADDED
@@ -0,0 +1,226 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: silver_spurs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Christian Blades
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.5
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.3.5
30
+ - !ruby/object:Gem::Dependency
31
+ name: chef
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 10.18.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 10.18.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: rest-client
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.6.7
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.7
62
+ - !ruby/object:Gem::Dependency
63
+ name: addressable
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.3.3
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.3.3
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: simplecov
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
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
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: growl
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: rb-fsevent
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '0.9'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '0.9'
158
+ - !ruby/object:Gem::Dependency
159
+ name: rack-test
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ description: This is a simple REST service to kick off bootstrap processes. It is
175
+ intended for use in a VPC-type environment with limited access.
176
+ email:
177
+ - christian.blades@careerbuilder.com
178
+ executables: []
179
+ extensions: []
180
+ extra_rdoc_files: []
181
+ files:
182
+ - .gitignore
183
+ - Gemfile
184
+ - Guardfile
185
+ - LICENSE
186
+ - README.md
187
+ - Rakefile
188
+ - lib/silver_spurs.rb
189
+ - lib/silver_spurs/app.rb
190
+ - lib/silver_spurs/client.rb
191
+ - lib/silver_spurs/client/exceptions.rb
192
+ - lib/silver_spurs/knife_interface.rb
193
+ - lib/silver_spurs/version.rb
194
+ - silver_spurs.gemspec
195
+ - spec/lib/silver_spurs/app_spec.rb
196
+ - spec/lib/silver_spurs/knife_interface_spec.rb
197
+ - spec/spec_helper.rb
198
+ homepage: http://github.com/christian-blades-cb/silver_spurs
199
+ licenses: []
200
+ post_install_message:
201
+ rdoc_options: []
202
+ require_paths:
203
+ - lib
204
+ required_ruby_version: !ruby/object:Gem::Requirement
205
+ none: false
206
+ requirements:
207
+ - - ! '>='
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ required_rubygems_version: !ruby/object:Gem::Requirement
211
+ none: false
212
+ requirements:
213
+ - - ! '>='
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ requirements: []
217
+ rubyforge_project:
218
+ rubygems_version: 1.8.25
219
+ signing_key:
220
+ specification_version: 3
221
+ summary: RESTful service to kick off chef bootstraps
222
+ test_files:
223
+ - spec/lib/silver_spurs/app_spec.rb
224
+ - spec/lib/silver_spurs/knife_interface_spec.rb
225
+ - spec/spec_helper.rb
226
+ has_rdoc: