kitchen-openstack 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -16,3 +16,5 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .kitchen
19
+ *.sw?
20
+ *~
data/.travis.yml CHANGED
@@ -4,7 +4,6 @@ gemfile:
4
4
  - Gemfile
5
5
 
6
6
  rvm:
7
- - 1.8.7
8
7
  - 1.9.2
9
8
  - 1.9.3
10
9
  - 2.0.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ # 0.2.0 / 2013-05-11
2
+
3
+ ### Bug Fixes
4
+
5
+ * PR [#7][] - `disable_ssl_validation` wasn't being respected on destroy
6
+
7
+ ### New Features
8
+
9
+ * PR [#10][] - Support optional `openstack_region` and `openstack_service_name`
10
+ * PR [#2][] - Support `key_name:` option; via [@stevendanna][]
11
+
12
+ ### Improvements
13
+
14
+ * PR [#7][] - Clean up/refactor to pass style checks
15
+ * PR [#9][] - Add some (probably overkill) RSpec tests
16
+
17
+ # 0.1.0 / 2013-03-12
18
+
19
+ * Initial release! Woo!
20
+
21
+ [#10]: https://github.com/RoboticCheese/kitchen-openstack/pull/10
22
+ [#9]: https://github.com/RoboticCheese/kitchen-openstack/pull/9
23
+ [#7]: https://github.com/RoboticCheese/kitchen-openstack/pull/7
24
+ [#2]: https://github.com/RoboticCheese/kitchen-openstack/pull/2
25
+
26
+ [@stevendanna]: https://github.com/stevendanna
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://travis-ci.org/RoboticCheese/kitchen-openstack.png?branch=master)](https://travis-ci.org/RoboticCheese/kitchen-openstack) [![Code Climate](https://codeclimate.com/github/RoboticCheese/kitchen-openstack.png)](https://codeclimate.com/github/RoboticCheese/kitchen-openstack)
2
+
1
3
  # Kitchen::OpenStack
2
4
 
3
5
  An OpenStack Nova driver for Test Kitchen 1.0!
@@ -28,7 +30,6 @@ Provide, at a minimum, the required driver options in your `.kitchen.yml` file:
28
30
  openstack_username: [YOUR OPENSTACK USERNAME]
29
31
  openstack_api_key: [YOUR OPENSTACK API KEY]
30
32
  openstack_auth_url: [YOUR OPENSTACK AUTH URL]
31
- openstack_tenant: [YOUR OPENSTACK TENANT ID]
32
33
  require_chef_omnibus: latest (if you'll be using Chef)
33
34
  image_ref: [SERVER IMAGE ID]
34
35
  flavor_ref: [SERVER FLAVOR ID]
@@ -41,12 +42,19 @@ options:
41
42
  public_key_path: [PATH TO YOUR SSH PUBLIC KEY]
42
43
  username: [SSH USER]
43
44
  port: [SSH PORT]
45
+ key_name: [SSH KEY NAME]
46
+ openstack_tenant: [YOUR OPENSTACK TENANT ID]
47
+ openstack_region: [A VALID OPENSTACK REGION]
48
+ openstack_service_name: [YOUR OPENSTACK COMPUTE SERVICE NAME]
44
49
 
45
- Only disable SSL cert validation if you absolutely know what you are doing,
46
- but are stuck with an OpenStack deployment without valid SSL certs.
50
+ If a key\_name is provided it will be used instead of any
51
+ public\_key\_path that is specified.
47
52
 
48
53
  disable_ssl_validation: true
49
54
 
55
+ Only disable SSL cert validation if you absolutely know what you are doing,
56
+ but are stuck with an OpenStack deployment without valid SSL certs.
57
+
50
58
  ## Contributing
51
59
 
52
60
  1. Fork it
data/Rakefile CHANGED
@@ -1,12 +1,15 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'tailor/rake_task'
3
3
  require 'cane/rake_task'
4
+ require 'rspec/core/rake_task'
4
5
 
5
6
  desc 'Run Cane to check quality metrics'
6
7
  Cane::RakeTask.new
7
8
 
8
9
  desc 'Run Tailor to lint check code'
9
- Tailor::RakeTask.new
10
+ Tailor::RakeTask.new do |task|
11
+ task.file_set '**/**/*.rb'
12
+ end
10
13
 
11
14
  desc 'Display LOC stats'
12
15
  task :loc do
@@ -14,6 +17,9 @@ task :loc do
14
17
  sh 'countloc -r lib/kitchen'
15
18
  end
16
19
 
17
- task :default => [ :cane, :tailor, :loc ]
20
+ desc 'Run RSpec unit tests'
21
+ RSpec::Core::RakeTask.new(:spec)
22
+
23
+ task :default => [ :cane, :tailor, :loc, :spec ]
18
24
 
19
25
  # vim: ai et ts=2 sts=2 sw=2 ft=ruby fdm=marker
@@ -19,12 +19,14 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_dependency 'test-kitchen', '~> 1.0.0.alpha'
22
+ spec.add_dependency 'fog', '~> 1.11'
22
23
 
23
- spec.add_development_dependency 'bundler', '~> 1.3'
24
+ spec.add_development_dependency 'bundler'
24
25
  spec.add_development_dependency 'rake'
25
26
  spec.add_development_dependency 'tailor'
26
27
  spec.add_development_dependency 'cane'
27
28
  spec.add_development_dependency 'countloc'
29
+ spec.add_development_dependency 'rspec'
28
30
  end
29
31
 
30
32
  # vim: ai et ts=2 sts=2 sw=2 ft=ruby
@@ -28,42 +28,26 @@ module Kitchen
28
28
  #
29
29
  # @author Jonathan Hartman <j@p4nt5.com>
30
30
  class Openstack < Kitchen::Driver::SSHBase
31
- default_config :name, nil
32
- default_config :public_key_path, File.expand_path('~/.ssh/id_dsa.pub')
33
- default_config :username, 'root'
34
- default_config :port, '22'
31
+ default_config :name, nil
32
+ default_config :public_key_path, File.expand_path('~/.ssh/id_dsa.pub')
33
+ default_config :username, 'root'
34
+ default_config :port, '22'
35
+ default_config :openstack_tenant, nil
36
+ default_config :openstack_region, nil
37
+ default_config :openstack_service_name, nil
35
38
 
36
39
  def create(state)
37
- if not config[:name]
38
- # Generate what should be a unique server name
39
- config[:name] = "#{instance.name}-#{Etc.getlogin}-" +
40
- "#{Socket.gethostname}-#{Array.new(8){rand(36).to_s(36)}.join}"
41
- end
42
- if config[:disable_ssl_validation]
43
- require 'excon'
44
- Excon.defaults[:ssl_verify_peer] = false
45
- end
40
+ config[:name] ||= generate_name(instance.name)
41
+ config[:disable_ssl_validation] and disable_ssl_validation
46
42
  server = create_server
47
43
  state[:server_id] = server.id
48
44
  info("OpenStack instance <#{state[:server_id]}> created.")
49
45
  server.wait_for { print '.'; ready? } ; puts "\n(server ready)"
50
- if server.addresses['public'] and !server.addresses['public'].empty?
51
- # server.public_ip_address stopped working in Fog 1.10.0
52
- state[:hostname] = server.addresses['public'].first['addr']
53
- else
54
- state[:hostname] = server.addresses['private'].first['addr']
55
- end
46
+ state[:hostname] = get_ip(server)
56
47
  # As a consequence of IP weirdness, the OpenStack setup() method is
57
48
  # also borked
58
- ssh = Fog::SSH.new(state[:hostname], config[:username],
59
- {:password => server.password})
60
- pub_key = open(config[:public_key_path]).read
61
- ssh.run([
62
- %{mkdir .ssh},
63
- %{echo "#{pub_key}" >> ~/.ssh/authorized_keys},
64
- %{passwd -l #{config[:username]}}
65
- ])
66
49
  wait_for_sshd(state[:hostname]) ; puts '(ssh ready)'
50
+ config[:key_name] or do_ssh_setup(state, config, server)
67
51
  rescue Fog::Errors::Error, Excon::Errors::Error => ex
68
52
  raise ActionFailed, ex.message
69
53
  end
@@ -71,6 +55,7 @@ module Kitchen
71
55
  def destroy(state)
72
56
  return if state[:server_id].nil?
73
57
 
58
+ config[:disable_ssl_validation] and disable_ssl_validation
74
59
  server = compute.servers.get(state[:server_id])
75
60
  server.destroy unless server.nil?
76
61
  info("OpenStack instance <#{state[:server_id]}> destroyed.")
@@ -81,22 +66,63 @@ module Kitchen
81
66
  private
82
67
 
83
68
  def compute
84
- Fog::Compute.new(
69
+ server_def = {
85
70
  :provider => 'OpenStack',
86
71
  :openstack_username => config[:openstack_username],
87
72
  :openstack_api_key => config[:openstack_api_key],
88
- :openstack_auth_url => config[:openstack_auth_url],
89
- :openstack_tenant => config[:openstack_tenant]
90
- )
73
+ :openstack_auth_url => config[:openstack_auth_url]
74
+ }
75
+ optional = [
76
+ :openstack_tenant, :openstack_region, :openstack_service_name
77
+ ]
78
+ optional.each do |o|
79
+ config[o] and server_def[o] = config[o]
80
+ end
81
+ Fog::Compute.new(server_def)
91
82
  end
92
83
 
93
84
  def create_server
94
- compute.servers.create(
95
- :name => config[:name],
96
- :image_ref => config[:image_ref],
97
- :flavor_ref => config[:flavor_ref],
98
- :public_key_path => config[:public_key_path]
99
- )
85
+ server_def = {
86
+ :name => config[:name],
87
+ :image_ref => config[:image_ref],
88
+ :flavor_ref => config[:flavor_ref]
89
+ }
90
+ if config[:public_key_path]
91
+ server_def[:public_key_path] = config[:public_key_path]
92
+ end
93
+ server_def[:key_name] = config[:key_name] if config[:key_name]
94
+ compute.servers.create(server_def)
95
+ end
96
+
97
+ def generate_name(base)
98
+ # Generate what should be a unique server name
99
+ rand_str = Array.new(8) { rand(36).to_s(36) }.join
100
+ "#{base}-#{Etc.getlogin}-#{Socket.gethostname}-#{rand_str}"
101
+ end
102
+
103
+ def get_ip(server)
104
+ if server.addresses['public'] and !server.addresses['public'].empty?
105
+ # server.public_ip_address stopped working in Fog 1.10.0
106
+ return server.addresses['public'].first['addr']
107
+ else
108
+ return server.addresses['private'].first['addr']
109
+ end
110
+ end
111
+
112
+ def do_ssh_setup(state, config, server)
113
+ ssh = Fog::SSH.new(state[:hostname], config[:username],
114
+ { :password => server.password })
115
+ pub_key = open(config[:public_key_path]).read
116
+ ssh.run([
117
+ %{mkdir .ssh},
118
+ %{echo "#{pub_key}" >> ~/.ssh/authorized_keys},
119
+ %{passwd -l #{config[:username]}}
120
+ ])
121
+ end
122
+
123
+ def disable_ssl_validation
124
+ require 'excon'
125
+ Excon.defaults[:ssl_verify_peer] = false
100
126
  end
101
127
  end
102
128
  end
@@ -19,7 +19,7 @@
19
19
  module Kitchen
20
20
  module Driver
21
21
  # Version string for OpenStack Kitchen driver
22
- OPENSTACK_VERSION = '0.1.0'
22
+ OPENSTACK_VERSION = '0.2.0'
23
23
  end
24
24
  end
25
25
 
@@ -0,0 +1,404 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Jonathan Hartman (<j@p4nt5.com>)
4
+ #
5
+ # Copyright (C) 2013, Jonathan Hartman
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'logger'
20
+ require 'stringio'
21
+ require 'rspec'
22
+ require 'kitchen'
23
+ require_relative '../../spec_helper'
24
+
25
+ describe Kitchen::Driver::Openstack do
26
+ let(:logged_output) { StringIO.new }
27
+ let(:logger) { Logger.new(logged_output) }
28
+ let(:config) { Hash.new }
29
+ let(:state) { Hash.new }
30
+
31
+ let(:instance) do
32
+ stub(:name => 'potatoes', :logger => logger, :to_str => 'instance')
33
+ end
34
+
35
+ let(:driver) do
36
+ d = Kitchen::Driver::Openstack.new(config)
37
+ d.instance = instance
38
+ d
39
+ end
40
+
41
+ describe '#initialize'do
42
+ context 'default options' do
43
+ it 'defaults to local user\'s SSH public key' do
44
+ expect(driver[:public_key_path]).to eq(File.expand_path(
45
+ '~/.ssh/id_dsa.pub'))
46
+ end
47
+
48
+ it 'defaults to SSH with root user on port 22' do
49
+ expect(driver[:username]).to eq('root')
50
+ expect(driver[:port]).to eq('22')
51
+ end
52
+
53
+ it 'defaults to no server name' do
54
+ expect(driver[:name]).to eq(nil)
55
+ end
56
+
57
+ it 'defaults to no tenant' do
58
+ expect(driver[:openstack_tenant]).to eq(nil)
59
+ end
60
+
61
+ it 'defaults to no region' do
62
+ expect(driver[:openstack_region]).to eq(nil)
63
+ end
64
+
65
+ it 'defaults to no service name' do
66
+ expect(driver[:openstack_service_name]).to eq(nil)
67
+ end
68
+ end
69
+
70
+ context 'overridden options' do
71
+ let(:config) do
72
+ {
73
+ :image_ref => '22',
74
+ :flavor_ref => '33',
75
+ :public_key_path => '/tmp',
76
+ :username => 'admin',
77
+ :port => '2222',
78
+ :name => 'puppy',
79
+ :openstack_tenant => 'that_one',
80
+ :openstack_region => 'atlantis',
81
+ :openstack_service_name => 'the_service'
82
+ }
83
+ end
84
+
85
+ it 'uses all the overridden options' do
86
+ drv = driver
87
+ config.each do |k, v|
88
+ expect(drv[k]).to eq(v)
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '#create' do
95
+ let(:server) do
96
+ stub(:id => 'test123', :wait_for => true,
97
+ :public_ip_address => '1.2.3.4')
98
+ end
99
+ let(:driver) do
100
+ d = Kitchen::Driver::Openstack.new(config)
101
+ d.instance = instance
102
+ d.stub(:generate_name).with('potatoes').and_return('a_monkey!')
103
+ d.stub(:create_server).and_return(server)
104
+ d.stub(:wait_for_sshd).with('1.2.3.4').and_return(true)
105
+ d.stub(:get_ip).and_return('1.2.3.4')
106
+ d.stub(:do_ssh_setup).and_return(true)
107
+ d
108
+ end
109
+
110
+ context 'required options provided' do
111
+ let(:config) do
112
+ {
113
+ :openstack_username => 'hello',
114
+ :openstack_api_key => 'world',
115
+ :openstack_auth_url => 'http:',
116
+ :openstack_tenant => 'www'
117
+ }
118
+ end
119
+
120
+ it 'generates a server name in the absence of one' do
121
+ driver.create(state)
122
+ expect(driver[:name]).to eq('a_monkey!')
123
+ end
124
+
125
+ it 'gets a proper server ID' do
126
+ driver.create(state)
127
+ expect(state[:server_id]).to eq('test123')
128
+ end
129
+
130
+ it 'gets a proper hostname (IP)' do
131
+ driver.create(state)
132
+ expect(state[:hostname]).to eq('1.2.3.4')
133
+ end
134
+
135
+ it 'does not disable SSL validation' do
136
+ driver.should_not_receive(:disable_ssl_validation)
137
+ driver.create(state)
138
+ end
139
+ end
140
+
141
+ context 'SSL validation disabled' do
142
+ let(:config) { { :disable_ssl_validation => true } }
143
+
144
+ it 'disables SSL cert validation' do
145
+ driver.should_receive(:disable_ssl_validation)
146
+ driver.create(state)
147
+ end
148
+ end
149
+ end
150
+
151
+ describe '#destroy' do
152
+ let(:server_id) { '12345' }
153
+ let(:hostname) { 'example.com' }
154
+ let(:state) { { :server_id => server_id, :hostname => hostname } }
155
+ let(:server) { stub(:nil? => false, :destroy => true) }
156
+ let(:servers) { stub(:get => server) }
157
+ let(:compute) { stub(:servers => servers) }
158
+
159
+ let(:driver) do
160
+ d = Kitchen::Driver::Openstack.new(config)
161
+ d.instance = instance
162
+ d.stub(:compute).and_return(compute)
163
+ d
164
+ end
165
+
166
+ context 'a live server that needs to be destroyed' do
167
+ it 'destroys the server' do
168
+ state.should_receive(:delete).with(:server_id)
169
+ state.should_receive(:delete).with(:hostname)
170
+ driver.destroy(state)
171
+ end
172
+
173
+ it 'does not disable SSL cert validation' do
174
+ driver.should_not_receive(:disable_ssl_validation)
175
+ driver.destroy(state)
176
+ end
177
+ end
178
+
179
+ context 'no server ID present' do
180
+ let(:state) { Hash.new }
181
+
182
+ it 'does nothing' do
183
+ driver.stub(:compute)
184
+ driver.should_not_receive(:compute)
185
+ state.should_not_receive(:delete)
186
+ driver.destroy(state)
187
+ end
188
+ end
189
+
190
+ context 'a server that was already destroyed' do
191
+ let(:servers) do
192
+ s = double('servers')
193
+ s.stub(:get).with('12345').and_return(nil)
194
+ s
195
+ end
196
+ let(:compute) { stub(:servers => servers) }
197
+ let(:driver) do
198
+ d = Kitchen::Driver::Openstack.new(config)
199
+ d.instance = instance
200
+ d.stub(:compute).and_return(compute)
201
+ d
202
+ end
203
+
204
+ it 'does not try to destroy the server again' do
205
+ allow_message_expectations_on_nil
206
+ driver.destroy(state)
207
+ end
208
+ end
209
+
210
+ context 'SSL validation disabled' do
211
+ let(:config) { { :disable_ssl_validation => true } }
212
+
213
+ it 'disables SSL cert validation' do
214
+ driver.should_receive(:disable_ssl_validation)
215
+ driver.destroy(state)
216
+ end
217
+ end
218
+ end
219
+
220
+ describe '#compute' do
221
+ let(:config) do
222
+ {
223
+ :openstack_username => 'monkey',
224
+ :openstack_api_key => 'potato',
225
+ :openstack_auth_url => 'http:',
226
+ :openstack_tenant => 'link',
227
+ :openstack_region => 'ord',
228
+ :openstack_service_name => 'the_service'
229
+ }
230
+ end
231
+
232
+ context 'all requirements provided' do
233
+ it 'creates a new compute connection' do
234
+ Fog::Compute.stub(:new) { |arg| arg }
235
+ res = config.merge({ :provider => 'OpenStack' })
236
+ expect(driver.send(:compute)).to eq(res)
237
+ end
238
+ end
239
+
240
+ context 'only an API key provided' do
241
+ let(:config) { { :openstack_api_key => '1234' } }
242
+
243
+ it 'raises an error' do
244
+ expect { driver.send(:compute) }.to raise_error(ArgumentError)
245
+ end
246
+ end
247
+
248
+ context 'only a username provided' do
249
+ let(:config) { { :openstack_username => 'monkey' } }
250
+
251
+ it 'raises an error' do
252
+ expect { driver.send(:compute) }.to raise_error(ArgumentError)
253
+ end
254
+ end
255
+ end
256
+
257
+ describe '#create_server' do
258
+ let(:config) do
259
+ {
260
+ :name => 'hello',
261
+ :image_ref => 'there',
262
+ :flavor_ref => 'captain',
263
+ :public_key_path => 'tarpals'
264
+ }
265
+ end
266
+ let(:servers) do
267
+ s = double('servers')
268
+ s.stub(:create) { |arg| arg }
269
+ s
270
+ end
271
+ let(:compute) { stub(:servers => servers) }
272
+ let(:driver) do
273
+ d = Kitchen::Driver::Openstack.new(config)
274
+ d.instance = instance
275
+ d.stub(:compute).and_return(compute)
276
+ d
277
+ end
278
+
279
+ context 'a default config' do
280
+ before(:each) { @config = config.dup }
281
+
282
+ it 'creates the server using a compute connection' do
283
+ expect(driver.send(:create_server)).to eq(@config)
284
+ end
285
+ end
286
+
287
+ context 'a provided public key path' do
288
+ let(:config) do
289
+ {
290
+ :name => 'hello',
291
+ :image_ref => 'there',
292
+ :flavor_ref => 'captain',
293
+ :public_key_path => 'tarpals'
294
+ }
295
+ end
296
+ before(:each) { @config = config.dup }
297
+
298
+ it 'passes that public key path to Fog' do
299
+ expect(driver.send(:create_server)).to eq(@config)
300
+ end
301
+ end
302
+
303
+ context 'a provided key name' do
304
+ let(:config) do
305
+ {
306
+ :name => 'hello',
307
+ :image_ref => 'there',
308
+ :flavor_ref => 'captain',
309
+ :public_key_path => 'montgomery',
310
+ :key_name => 'tarpals'
311
+ }
312
+ end
313
+ before(:each) { @config = config.dup }
314
+
315
+ it 'passes that key name to Fog' do
316
+ expect(driver.send(:create_server)).to eq(@config)
317
+ end
318
+ end
319
+ end
320
+
321
+ describe '#generate_name' do
322
+ before(:each) do
323
+ Etc.stub(:getlogin).and_return('user')
324
+ Socket.stub(:gethostname).and_return('host')
325
+ end
326
+
327
+ it 'generates a name' do
328
+ expect(driver.send(:generate_name, 'monkey')).to match(
329
+ /^monkey-user-host-/)
330
+ end
331
+ end
332
+
333
+ describe '#get_ip' do
334
+ let(:addresses) { { 'public' => [], 'private' => [] } }
335
+ let(:server) { stub(:addresses => addresses) }
336
+
337
+ context 'both public and private IPs' do
338
+ let(:addresses) do
339
+ {
340
+ 'public' => [
341
+ { 'addr' => '1.2.3.4' },
342
+ { 'addr' => '1.2.3.5' }
343
+ ],
344
+ 'private' => [
345
+ { 'addr' => '5.5.5.5' },
346
+ { 'addr' => '6.6.6.6' }
347
+ ]
348
+ }
349
+ end
350
+
351
+ it 'returns a public IP' do
352
+ expect(driver.send(:get_ip, server)).to eq('1.2.3.4')
353
+ end
354
+ end
355
+
356
+ context 'only private IPs' do
357
+ let(:addresses) do
358
+ {
359
+ 'private' => [
360
+ { 'addr' => '5.5.5.5' },
361
+ { 'addr' => '6.6.6.6' }
362
+ ]
363
+ }
364
+ end
365
+ it 'returns a private IP' do
366
+ expect(driver.send(:get_ip, server)).to eq('5.5.5.5')
367
+ end
368
+ end
369
+ end
370
+
371
+ describe '#do_ssh_setup' do
372
+ let(:server) { stub(:password => 'aloha') }
373
+ let(:state) { { :hostname => 'host' } }
374
+ let(:read) { stub(:read => 'a_key') }
375
+ let(:ssh) do
376
+ s = double('ssh')
377
+ s.stub(:run) { |args| args }
378
+ s
379
+ end
380
+
381
+ it 'opens an SSH session to the server' do
382
+ Fog::SSH.stub(:new).with('host', 'root',
383
+ { :password => 'aloha' }).and_return(ssh)
384
+ driver.stub(:open).with(File.expand_path(
385
+ '~/.ssh/id_dsa.pub')).and_return(read)
386
+ read.stub(:read).and_return('a_key')
387
+ res = driver.send(:do_ssh_setup, state, config, server)
388
+ expected = [
389
+ 'mkdir .ssh',
390
+ 'echo "a_key" >> ~/.ssh/authorized_keys',
391
+ 'passwd -l root'
392
+ ]
393
+ expect(res).to eq(expected)
394
+ end
395
+ end
396
+
397
+ describe '#disable_ssl_validation' do
398
+ it 'turns off Excon SSL cert validation' do
399
+ expect(driver.send(:disable_ssl_validation)).to eq(false)
400
+ end
401
+ end
402
+ end
403
+
404
+ # vim: ai et ts=2 sts=2 sw=2 ft=ruby
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Jonathan Hartman (<j@p4nt5.com>)
4
+ #
5
+ # Copyright (C) 2013, Jonathan Hartman
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'rspec'
20
+ require_relative '../lib/kitchen/driver/openstack'
21
+
22
+ # vim: ai et ts=2 sts=2 sw=2 ft=ruby
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-openstack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-12 00:00:00.000000000 Z
12
+ date: 2013-05-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: test-kitchen
@@ -28,21 +28,37 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: 1.0.0.alpha
30
30
  - !ruby/object:Gem::Dependency
31
- name: bundler
31
+ name: fog
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: '1.3'
38
- type: :development
37
+ version: '1.11'
38
+ type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: '1.3'
45
+ version: '1.11'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: rake
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +123,22 @@ dependencies:
107
123
  - - ! '>='
108
124
  - !ruby/object:Gem::Version
109
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec
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'
110
142
  description: A Test Kitchen OpenStack Nova driver
111
143
  email:
112
144
  - j@p4nt5.com
@@ -116,6 +148,7 @@ extra_rdoc_files: []
116
148
  files:
117
149
  - .gitignore
118
150
  - .travis.yml
151
+ - CHANGELOG.md
119
152
  - Gemfile
120
153
  - LICENSE.txt
121
154
  - README.md
@@ -123,6 +156,8 @@ files:
123
156
  - kitchen-openstack.gemspec
124
157
  - lib/kitchen/driver/openstack.rb
125
158
  - lib/kitchen/driver/openstack_version.rb
159
+ - spec/kitchen/driver/openstack_spec.rb
160
+ - spec/spec_helper.rb
126
161
  homepage: https://github.com/RoboticCheese/kitchen-openstack
127
162
  licenses:
128
163
  - Apache
@@ -148,5 +183,6 @@ rubygems_version: 1.8.23
148
183
  signing_key:
149
184
  specification_version: 3
150
185
  summary: A Test Kitchen OpenStack Nova driver
151
- test_files: []
152
- has_rdoc:
186
+ test_files:
187
+ - spec/kitchen/driver/openstack_spec.rb
188
+ - spec/spec_helper.rb