kitchen-openstack 0.5.0 → 1.0.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/CHANGELOG.md +24 -1
- data/README.md +15 -6
- data/Rakefile +1 -1
- data/lib/kitchen/driver/openstack.rb +80 -6
- data/lib/kitchen/driver/openstack_version.rb +1 -1
- data/spec/kitchen/driver/openstack_spec.rb +176 -29
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,20 @@
|
|
1
|
-
#
|
1
|
+
# 1.0.0 / 2013-10-16
|
2
|
+
|
3
|
+
### New Features
|
4
|
+
|
5
|
+
* PR [#26][] - Support image and flavor names and regexes; via [@jgawor][]
|
6
|
+
* PR [#25][] - Support specific floating IPs, in addition to named pools
|
7
|
+
* PR [#14][] - Add support for floating IP pools; via [@hufman][]
|
8
|
+
|
9
|
+
### Improvements
|
10
|
+
|
11
|
+
* PR [#15][] - Improved SSH key support, support RSA and DSA; via [@hufman][]
|
12
|
+
|
13
|
+
### Bug Fixes
|
14
|
+
|
15
|
+
* PR [#27][] - Prevent IP contention in TK parallel mode; via [@jgawor][]
|
16
|
+
|
17
|
+
# 0.5.0 / 2013-09-23
|
2
18
|
|
3
19
|
### Improvements
|
4
20
|
|
@@ -36,8 +52,13 @@
|
|
36
52
|
|
37
53
|
* Initial release! Woo!
|
38
54
|
|
55
|
+
[#27]: https://github.com/RoboticCheese/kitchen-openstack/pull/27
|
56
|
+
[#26]: https://github.com/RoboticCheese/kitchen-openstack/pull/26
|
57
|
+
[#25]: https://github.com/RoboticCheese/kitchen-openstack/pull/25
|
39
58
|
[#20]: https://github.com/RoboticCheese/kitchen-openstack/pull/20
|
40
59
|
[#19]: https://github.com/RoboticCheese/kitchen-openstack/pull/19
|
60
|
+
[#15]: https://github.com/RoboticCheese/kitchen-openstack/pull/15
|
61
|
+
[#14]: https://github.com/RoboticCheese/kitchen-openstack/pull/14
|
41
62
|
[#12]: https://github.com/RoboticCheese/kitchen-openstack/pull/12
|
42
63
|
[#11]: https://github.com/RoboticCheese/kitchen-openstack/pull/11
|
43
64
|
[#10]: https://github.com/RoboticCheese/kitchen-openstack/pull/10
|
@@ -45,5 +66,7 @@
|
|
45
66
|
[#7]: https://github.com/RoboticCheese/kitchen-openstack/pull/7
|
46
67
|
[#2]: https://github.com/RoboticCheese/kitchen-openstack/pull/2
|
47
68
|
|
69
|
+
[@jgawor]: https://github.com/jgawor
|
70
|
+
[@hufman]: https://github.com/hufman
|
48
71
|
[@saketoba]: https://github.com/saketoba
|
49
72
|
[@stevendanna]: https://github.com/stevendanna
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[](https://travis-ci.org/RoboticCheese/kitchen-openstack) [](https://codeclimate.com/github/RoboticCheese/kitchen-openstack)
|
1
|
+
[](http://badge.fury.io/rb/kitchen-openstack) [](https://gemnasium.com/RoboticCheese/kitchen-openstack) [](https://travis-ci.org/RoboticCheese/kitchen-openstack) [](https://codeclimate.com/github/RoboticCheese/kitchen-openstack)
|
2
2
|
|
3
3
|
# Kitchen::OpenStack
|
4
4
|
|
@@ -34,12 +34,15 @@ Provide, at a minimum, the required driver options in your `.kitchen.yml` file:
|
|
34
34
|
image_ref: [SERVER IMAGE ID]
|
35
35
|
flavor_ref: [SERVER FLAVOR ID]
|
36
36
|
|
37
|
+
The `image_ref` and `flavor_ref` options can be specified as an exact id,
|
38
|
+
an exact name, or as a regular expression matching the name of the image or flavor.
|
39
|
+
|
37
40
|
By default, a unique server name will be generated and the current user's SSH
|
38
|
-
key will be used
|
39
|
-
options:
|
41
|
+
key will be used (with an RSA key taking precedence over a DSA), though that
|
42
|
+
behavior can be overridden with additional options:
|
40
43
|
|
41
44
|
name: [A UNIQUE SERVER NAME]
|
42
|
-
|
45
|
+
private_key_path: [PATH TO YOUR PRIVATE SSH KEY]
|
43
46
|
public_key_path: [PATH TO YOUR SSH PUBLIC KEY]
|
44
47
|
username: [SSH USER]
|
45
48
|
port: [SSH PORT]
|
@@ -48,9 +51,15 @@ options:
|
|
48
51
|
openstack_region: [A VALID OPENSTACK REGION]
|
49
52
|
openstack_service_name: [YOUR OPENSTACK COMPUTE SERVICE NAME]
|
50
53
|
openstack_network_name: [YOUR OPENSTACK NETWORK NAME]
|
54
|
+
floating_ip: [A SPECIFIC FLOATING IP TO ASSIGN]
|
55
|
+
floating_ip_pool: [AN OPENSTACK POOL NAME TO ASSIGN THE NEXT IP FROM]
|
56
|
+
|
57
|
+
If a `key_name` is provided it will be used instead of any
|
58
|
+
`public_key_path` that is specified.
|
51
59
|
|
52
|
-
If a
|
53
|
-
|
60
|
+
If a `key_name` is provided without any `private_key_path`, unexpected
|
61
|
+
behavior may result if your local RSA/DSA private key doesn't match that
|
62
|
+
OpenStack key.
|
54
63
|
|
55
64
|
disable_ssl_validation: true
|
56
65
|
|
data/Rakefile
CHANGED
@@ -29,8 +29,19 @@ module Kitchen
|
|
29
29
|
#
|
30
30
|
# @author Jonathan Hartman <j@p4nt5.com>
|
31
31
|
class Openstack < Kitchen::Driver::SSHBase
|
32
|
+
@@ip_pool_lock = Mutex.new
|
33
|
+
|
32
34
|
default_config :name, nil
|
33
|
-
default_config :
|
35
|
+
default_config :key_name, nil
|
36
|
+
default_config :private_key_path do |driver|
|
37
|
+
%w{id_rsa id_dsa}.collect do |k|
|
38
|
+
f = File.expand_path "~/.ssh/#{k}"
|
39
|
+
f if File.exists? f
|
40
|
+
end.compact.first
|
41
|
+
end
|
42
|
+
default_config :public_key_path do |driver|
|
43
|
+
driver[:private_key_path] + '.pub'
|
44
|
+
end
|
34
45
|
default_config :username, 'root'
|
35
46
|
default_config :port, '22'
|
36
47
|
default_config :use_ipv6, false
|
@@ -38,6 +49,8 @@ module Kitchen
|
|
38
49
|
default_config :openstack_region, nil
|
39
50
|
default_config :openstack_service_name, nil
|
40
51
|
default_config :openstack_network_name, nil
|
52
|
+
default_config :floating_ip_pool, nil
|
53
|
+
default_config :floating_ip, nil
|
41
54
|
|
42
55
|
def create(state)
|
43
56
|
config[:name] ||= generate_name(instance.name)
|
@@ -45,10 +58,21 @@ module Kitchen
|
|
45
58
|
server = create_server
|
46
59
|
state[:server_id] = server.id
|
47
60
|
info "OpenStack instance <#{state[:server_id]}> created."
|
48
|
-
server.wait_for { print '.'; ready? } ;
|
61
|
+
server.wait_for { print '.'; ready? } ; info "\n(server ready)"
|
62
|
+
if config[:floating_ip_pool]
|
63
|
+
attach_ip_from_pool(server, config[:floating_ip_pool])
|
64
|
+
elsif config[:floating_ip]
|
65
|
+
attach_ip(server, config[:floating_ip])
|
66
|
+
end
|
49
67
|
state[:hostname] = get_ip(server)
|
50
|
-
|
51
|
-
|
68
|
+
state[:ssh_key] = config[:private_key_path]
|
69
|
+
wait_for_sshd(state[:hostname]) ; info '(ssh ready)'
|
70
|
+
if config[:key_name]
|
71
|
+
info "Using OpenStack keypair <#{config[:key_name]}>"
|
72
|
+
end
|
73
|
+
info "Using public SSH key <#{config[:public_key_path]}>"
|
74
|
+
info "Using private SSH key <#{config[:private_key_path]}>"
|
75
|
+
unless config[:key_name]
|
52
76
|
do_ssh_setup(state, config, server)
|
53
77
|
end
|
54
78
|
rescue Fog::Errors::Error, Excon::Errors::Error => ex
|
@@ -85,10 +109,18 @@ module Kitchen
|
|
85
109
|
end
|
86
110
|
|
87
111
|
def create_server
|
112
|
+
image = find_matching(compute.images, config[:image_ref])
|
113
|
+
raise ActionFailed, "Image not found" if !image
|
114
|
+
debug "Selected image: #{image.id} #{image.name}"
|
115
|
+
|
116
|
+
flavor = find_matching(compute.flavors, config[:flavor_ref])
|
117
|
+
raise ActionFailed, "Flavor not found" if !flavor
|
118
|
+
debug "Selected flavor: #{flavor.id} #{flavor.name}"
|
119
|
+
|
88
120
|
server_def = {
|
89
121
|
:name => config[:name],
|
90
|
-
:image_ref =>
|
91
|
-
:flavor_ref =>
|
122
|
+
:image_ref => image.id,
|
123
|
+
:flavor_ref => flavor.id
|
92
124
|
}
|
93
125
|
if config[:public_key_path]
|
94
126
|
server_def[:public_key_path] = config[:public_key_path]
|
@@ -121,6 +153,25 @@ module Kitchen
|
|
121
153
|
pieces.join sep
|
122
154
|
end
|
123
155
|
|
156
|
+
def attach_ip_from_pool(server, pool)
|
157
|
+
@@ip_pool_lock.synchronize do
|
158
|
+
info "Attaching floating IP from <#{pool}> pool"
|
159
|
+
free_addrs = compute.addresses.collect do |i|
|
160
|
+
i.ip if i.fixed_ip.nil? and i.instance_id.nil? and i.pool == pool
|
161
|
+
end.compact
|
162
|
+
if free_addrs.empty?
|
163
|
+
raise ActionFailed, "No available IPs in pool <#{pool}>"
|
164
|
+
end
|
165
|
+
attach_ip(server, free_addrs[0])
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def attach_ip(server, ip)
|
170
|
+
info "Attaching floating IP <#{ip}>"
|
171
|
+
server.associate_address ip
|
172
|
+
(server.addresses['public'] ||= []) << { 'version' => 4, 'addr' => ip }
|
173
|
+
end
|
174
|
+
|
124
175
|
def get_ip(server)
|
125
176
|
if config[:openstack_network_name]
|
126
177
|
debug "Using configured network: #{config[:openstack_network_name]}"
|
@@ -149,6 +200,7 @@ module Kitchen
|
|
149
200
|
end
|
150
201
|
|
151
202
|
def do_ssh_setup(state, config, server)
|
203
|
+
info "Setting up SSH access for key <#{config[:public_key_path]}>"
|
152
204
|
ssh = Fog::SSH.new(state[:hostname], config[:username],
|
153
205
|
{ :password => server.password })
|
154
206
|
pub_key = open(config[:public_key_path]).read
|
@@ -163,6 +215,28 @@ module Kitchen
|
|
163
215
|
require 'excon'
|
164
216
|
Excon.defaults[:ssl_verify_peer] = false
|
165
217
|
end
|
218
|
+
|
219
|
+
def find_matching(collection, name)
|
220
|
+
name = name.to_s
|
221
|
+
if name.start_with?('/')
|
222
|
+
regex = eval(name)
|
223
|
+
# check for regex name match
|
224
|
+
collection.each do |single|
|
225
|
+
return single if regex =~ single.name
|
226
|
+
end
|
227
|
+
else
|
228
|
+
# check for exact id match
|
229
|
+
collection.each do |single|
|
230
|
+
return single if single.id == name
|
231
|
+
end
|
232
|
+
# check for exact name match
|
233
|
+
collection.each do |single|
|
234
|
+
return single if single.name == name
|
235
|
+
end
|
236
|
+
end
|
237
|
+
nil
|
238
|
+
end
|
239
|
+
|
166
240
|
end
|
167
241
|
end
|
168
242
|
end
|
@@ -27,6 +27,8 @@ describe Kitchen::Driver::Openstack do
|
|
27
27
|
let(:logger) { Logger.new(logged_output) }
|
28
28
|
let(:config) { Hash.new }
|
29
29
|
let(:state) { Hash.new }
|
30
|
+
let(:dsa) { File.expand_path('~/.ssh/id_dsa') }
|
31
|
+
let(:rsa) { File.expand_path('~/.ssh/id_rsa') }
|
30
32
|
|
31
33
|
let(:instance) do
|
32
34
|
double(:name => 'potatoes', :logger => logger, :to_str => 'instance')
|
@@ -38,32 +40,73 @@ describe Kitchen::Driver::Openstack do
|
|
38
40
|
d
|
39
41
|
end
|
40
42
|
|
43
|
+
before(:each) do
|
44
|
+
File.stub(:exists?).and_call_original
|
45
|
+
File.stub(:exists?).with(dsa).and_return(true)
|
46
|
+
File.stub(:exists?).with(rsa).and_return(true)
|
47
|
+
end
|
48
|
+
|
41
49
|
describe '#initialize'do
|
42
50
|
context 'default options' do
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
51
|
+
context 'both DSA and RSA SSH keys available for the user' do
|
52
|
+
it 'prefers the local user\'s RSA private key' do
|
53
|
+
expect(driver[:private_key_path]).to eq(rsa)
|
54
|
+
end
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
56
|
+
it 'prefers the local user\'s RSA public key' do
|
57
|
+
expect(driver[:public_key_path]).to eq(rsa + '.pub')
|
58
|
+
end
|
51
59
|
end
|
52
60
|
|
53
|
-
|
54
|
-
|
61
|
+
context 'only a DSA SSH key available for the user' do
|
62
|
+
before(:each) do
|
63
|
+
File.unstub(:exists?)
|
64
|
+
File.stub(:exists?).and_return(false)
|
65
|
+
File.stub(:exists?).with(dsa).and_return(true)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'uses the local user\'s DSA private key' do
|
69
|
+
expect(driver[:private_key_path]).to eq(dsa)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'uses the local user\'s DSA public key' do
|
73
|
+
expect(driver[:public_key_path]).to eq(dsa + '.pub')
|
74
|
+
end
|
55
75
|
end
|
56
76
|
|
57
|
-
|
58
|
-
|
77
|
+
context 'only a RSA SSH key available for the user' do
|
78
|
+
before(:each) do
|
79
|
+
File.unstub(:exists?)
|
80
|
+
File.stub(:exists?).and_return(false)
|
81
|
+
File.stub(:exists?).with(rsa).and_return(true)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'uses the local user\'s RSA private key' do
|
85
|
+
expect(driver[:private_key_path]).to eq(rsa)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'uses the local user\'s RSA public key' do
|
89
|
+
expect(driver[:public_key_path]).to eq(rsa + '.pub')
|
90
|
+
end
|
59
91
|
end
|
60
92
|
|
61
|
-
it 'defaults to
|
62
|
-
expect(driver[:
|
93
|
+
it 'defaults to SSH with root user on port 22' do
|
94
|
+
expect(driver[:username]).to eq('root')
|
95
|
+
expect(driver[:port]).to eq('22')
|
63
96
|
end
|
64
97
|
|
65
|
-
|
66
|
-
|
98
|
+
nils = [
|
99
|
+
:name,
|
100
|
+
:openstack_tenant,
|
101
|
+
:openstack_region,
|
102
|
+
:openstack_service_name,
|
103
|
+
:floating_ip_pool,
|
104
|
+
:floating_ip
|
105
|
+
]
|
106
|
+
nils.each do |i|
|
107
|
+
it "defaults to no #{i}" do
|
108
|
+
expect(driver[i]).to eq(nil)
|
109
|
+
end
|
67
110
|
end
|
68
111
|
end
|
69
112
|
|
@@ -79,7 +122,9 @@ describe Kitchen::Driver::Openstack do
|
|
79
122
|
:openstack_tenant => 'that_one',
|
80
123
|
:openstack_region => 'atlantis',
|
81
124
|
:openstack_service_name => 'the_service',
|
82
|
-
:
|
125
|
+
:private_key_path => '/path/to/id_rsa',
|
126
|
+
:floating_ip_pool => 'swimmers',
|
127
|
+
:floating_ip => '11111'
|
83
128
|
}
|
84
129
|
end
|
85
130
|
|
@@ -89,10 +134,6 @@ describe Kitchen::Driver::Openstack do
|
|
89
134
|
expect(drv[k]).to eq(v)
|
90
135
|
end
|
91
136
|
end
|
92
|
-
|
93
|
-
it 'SSH with user-specified private key' do
|
94
|
-
expect(driver[:ssh_key]).to eq('/path/to/id_rsa')
|
95
|
-
end
|
96
137
|
end
|
97
138
|
end
|
98
139
|
|
@@ -263,8 +304,8 @@ describe Kitchen::Driver::Openstack do
|
|
263
304
|
let(:config) do
|
264
305
|
{
|
265
306
|
:name => 'hello',
|
266
|
-
:image_ref => '
|
267
|
-
:flavor_ref => '
|
307
|
+
:image_ref => '111',
|
308
|
+
:flavor_ref => '1',
|
268
309
|
:public_key_path => 'tarpals'
|
269
310
|
}
|
270
311
|
end
|
@@ -273,7 +314,14 @@ describe Kitchen::Driver::Openstack do
|
|
273
314
|
s.stub(:create) { |arg| arg }
|
274
315
|
s
|
275
316
|
end
|
276
|
-
let(:
|
317
|
+
let(:ubuntu_image) { double(:id => '111', :name => 'ubuntu') }
|
318
|
+
let(:fedora_image) { double(:id => '222', :name => 'fedora') }
|
319
|
+
let(:tiny_flavor) { double(:id => '1', :name => 'tiny') }
|
320
|
+
let(:small_flavor) { double(:id => '2', :name => 'small') }
|
321
|
+
let(:compute) do
|
322
|
+
double(:servers => servers, :images => [ubuntu_image, fedora_image],
|
323
|
+
:flavors => [tiny_flavor, small_flavor])
|
324
|
+
end
|
277
325
|
let(:driver) do
|
278
326
|
d = Kitchen::Driver::Openstack.new(config)
|
279
327
|
d.instance = instance
|
@@ -293,8 +341,8 @@ describe Kitchen::Driver::Openstack do
|
|
293
341
|
let(:config) do
|
294
342
|
{
|
295
343
|
:name => 'hello',
|
296
|
-
:image_ref => '
|
297
|
-
:flavor_ref => '
|
344
|
+
:image_ref => '111',
|
345
|
+
:flavor_ref => '1',
|
298
346
|
:public_key_path => 'tarpals'
|
299
347
|
}
|
300
348
|
end
|
@@ -309,8 +357,8 @@ describe Kitchen::Driver::Openstack do
|
|
309
357
|
let(:config) do
|
310
358
|
{
|
311
359
|
:name => 'hello',
|
312
|
-
:image_ref => '
|
313
|
-
:flavor_ref => '
|
360
|
+
:image_ref => '111',
|
361
|
+
:flavor_ref => '1',
|
314
362
|
:public_key_path => 'montgomery',
|
315
363
|
:key_name => 'tarpals'
|
316
364
|
}
|
@@ -321,6 +369,61 @@ describe Kitchen::Driver::Openstack do
|
|
321
369
|
expect(driver.send(:create_server)).to eq(@config)
|
322
370
|
end
|
323
371
|
end
|
372
|
+
|
373
|
+
context 'image/flavor specifies id' do
|
374
|
+
let(:config) do
|
375
|
+
{
|
376
|
+
:name => 'hello',
|
377
|
+
:image_ref => '111',
|
378
|
+
:flavor_ref => '1',
|
379
|
+
:public_key_path => 'tarpals'
|
380
|
+
}
|
381
|
+
end
|
382
|
+
|
383
|
+
it 'exact id match' do
|
384
|
+
servers.should_receive(:create).with(:name => 'hello',
|
385
|
+
:image_ref => '111', :flavor_ref => '1',
|
386
|
+
:public_key_path => 'tarpals')
|
387
|
+
driver.send(:create_server)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
context 'image/flavor specifies name' do
|
392
|
+
let(:config) do
|
393
|
+
{
|
394
|
+
:name => 'hello',
|
395
|
+
:image_ref => 'fedora',
|
396
|
+
:flavor_ref => 'small',
|
397
|
+
:public_key_path => 'tarpals'
|
398
|
+
}
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'exact name match' do
|
402
|
+
servers.should_receive(:create).with(:name => 'hello',
|
403
|
+
:image_ref => '222', :flavor_ref => '2',
|
404
|
+
:public_key_path => 'tarpals')
|
405
|
+
driver.send(:create_server)
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
context 'image/flavor specifies regex' do
|
410
|
+
let(:config) do
|
411
|
+
{
|
412
|
+
:name => 'hello',
|
413
|
+
# pass regex as string as yml returns string values
|
414
|
+
:image_ref => '/edo/',
|
415
|
+
:flavor_ref => '/in/',
|
416
|
+
:public_key_path => 'tarpals'
|
417
|
+
}
|
418
|
+
end
|
419
|
+
|
420
|
+
it 'regex name match' do
|
421
|
+
servers.should_receive(:create).with(:name => 'hello',
|
422
|
+
:image_ref => '222', :flavor_ref => '1',
|
423
|
+
:public_key_path => 'tarpals')
|
424
|
+
driver.send(:create_server)
|
425
|
+
end
|
426
|
+
end
|
324
427
|
end
|
325
428
|
|
326
429
|
describe '#generate_name' do
|
@@ -346,6 +449,50 @@ describe Kitchen::Driver::Openstack do
|
|
346
449
|
end
|
347
450
|
end
|
348
451
|
|
452
|
+
describe '#attach_ip_from_pool' do
|
453
|
+
let(:server) { nil }
|
454
|
+
let(:pool) { 'swimmers' }
|
455
|
+
let(:ip) { '1.1.1.1' }
|
456
|
+
let(:address) { double(:ip => ip, :fixed_ip => nil, :instance_id => nil,
|
457
|
+
:pool => pool) }
|
458
|
+
let(:compute) { double(:addresses => [address]) }
|
459
|
+
|
460
|
+
before(:each) do
|
461
|
+
driver.stub(:attach_ip).with(server, ip).and_return('bing!')
|
462
|
+
driver.stub(:compute).and_return(compute)
|
463
|
+
end
|
464
|
+
|
465
|
+
it 'determines an IP to attempt to attach' do
|
466
|
+
expect(driver.send(:attach_ip_from_pool, server, pool)).to eq('bing!')
|
467
|
+
end
|
468
|
+
|
469
|
+
context 'no free addresses in the specified pool' do
|
470
|
+
let(:address) { double(:ip => ip, :fixed_ip => nil, :instance_id => nil,
|
471
|
+
:pool => 'some_other_pool') }
|
472
|
+
|
473
|
+
it 'raises an exception' do
|
474
|
+
expect { driver.send(:attach_ip_from_pool, server, pool) }.to \
|
475
|
+
raise_error
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
describe '#attach_ip' do
|
481
|
+
let(:ip) { '1.1.1.1' }
|
482
|
+
let(:addresses) { {} }
|
483
|
+
let(:server) do
|
484
|
+
s = double('server')
|
485
|
+
s.should_receive(:associate_address).with(ip).and_return(true)
|
486
|
+
s.stub(:addresses).and_return(addresses)
|
487
|
+
s
|
488
|
+
end
|
489
|
+
|
490
|
+
it 'associates the IP address with the server' do
|
491
|
+
expect(driver.send(:attach_ip, server, ip)).to eq(
|
492
|
+
[{ 'version' => 4, 'addr' => ip }])
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
349
496
|
describe '#get_ip' do
|
350
497
|
let(:addresses) { nil }
|
351
498
|
let(:public_ip_addresses) { nil }
|
@@ -543,6 +690,7 @@ describe Kitchen::Driver::Openstack do
|
|
543
690
|
end
|
544
691
|
|
545
692
|
describe '#do_ssh_setup' do
|
693
|
+
let(:config) { { :public_key_path => '/pub_key' } }
|
546
694
|
let(:server) { double(:password => 'aloha') }
|
547
695
|
let(:state) { { :hostname => 'host' } }
|
548
696
|
let(:read) { double(:read => 'a_key') }
|
@@ -555,8 +703,7 @@ describe Kitchen::Driver::Openstack do
|
|
555
703
|
it 'opens an SSH session to the server' do
|
556
704
|
Fog::SSH.stub(:new).with('host', 'root',
|
557
705
|
{ :password => 'aloha' }).and_return(ssh)
|
558
|
-
driver.stub(:open).with(
|
559
|
-
'~/.ssh/id_dsa.pub')).and_return(read)
|
706
|
+
driver.stub(:open).with('/pub_key').and_return(read)
|
560
707
|
read.stub(:read).and_return('a_key')
|
561
708
|
res = driver.send(:do_ssh_setup, state, config, server)
|
562
709
|
expected = [
|
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.
|
4
|
+
version: 1.0.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-
|
12
|
+
date: 2013-10-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-kitchen
|