kitchen-openstack 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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