kitchen-openstack 3.6.1 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- # Encoding: UTF-8
2
-
3
- source "https://rubygems.org"
4
-
5
- # Specify your gem's dependencies in kitchen-openstack.gemspec
6
- gemspec
data/LICENSE.txt DELETED
@@ -1,17 +0,0 @@
1
- Author:: Jonathan Hartman (<j@p4nt5.com>)
2
- Author:: JJ Asghar (<jj@chef.io>)
3
-
4
- Copyright (c) 2013 Jonathan Hartman
5
- Copyright (c) 2015 Chef Software, Inc
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.
data/Rakefile DELETED
@@ -1,19 +0,0 @@
1
- # Encoding: UTF-8
2
-
3
- require "bundler/setup"
4
- require "bundler/gem_tasks"
5
- require "chefstyle"
6
- require "rubocop/rake_task"
7
- require "rspec/core/rake_task"
8
-
9
- RuboCop::RakeTask.new
10
-
11
- desc "Display LOC stats"
12
- task :loc do
13
- puts "\n## LOC Stats"
14
- sh "countloc -r lib/kitchen"
15
- end
16
-
17
- RSpec::Core::RakeTask.new(:spec)
18
-
19
- task default: %i{rubocop loc spec}
@@ -1,39 +0,0 @@
1
- # Encoding: UTF-8
2
-
3
- lib = File.expand_path("../lib", __FILE__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "kitchen/driver/openstack_version"
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = "kitchen-openstack"
9
- spec.version = Kitchen::Driver::OPENSTACK_VERSION
10
- spec.authors = ["Jonathan Hartman", "JJ Asghar"]
11
- spec.email = ["j@p4nt5.com", "jj@chef.io"]
12
- spec.description = "A Test Kitchen OpenStack Nova driver"
13
- spec.summary = spec.description
14
- spec.homepage = "https://github.com/test-kitchen/kitchen-openstack"
15
- spec.license = "Apache"
16
-
17
- spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
- spec.require_paths = ["lib"]
21
-
22
- spec.required_ruby_version = ">= 2.0.0"
23
-
24
- spec.add_dependency "test-kitchen", "~> 1.4", ">= 1.4.1"
25
- spec.add_dependency "fog-openstack", "~> 0.1"
26
- spec.add_dependency "unf"
27
- spec.add_dependency "ohai"
28
-
29
- spec.add_development_dependency "bundler"
30
- spec.add_development_dependency "rake"
31
- spec.add_development_dependency "chefstyle"
32
- spec.add_development_dependency "cane"
33
- spec.add_development_dependency "countloc"
34
- spec.add_development_dependency "rspec"
35
- spec.add_development_dependency "simplecov"
36
- spec.add_development_dependency "simplecov-console"
37
- spec.add_development_dependency "coveralls"
38
- spec.add_development_dependency "github_changelog_generator"
39
- end
@@ -1,126 +0,0 @@
1
- # Encoding: UTF-8
2
-
3
- require_relative "../../../spec_helper"
4
- require_relative "../../../../lib/kitchen/driver/openstack/volume"
5
-
6
- require "logger"
7
- require "stringio"
8
- require "rspec"
9
- require "kitchen"
10
- require "ohai"
11
-
12
- describe Kitchen::Driver::Openstack::Volume do
13
- let(:os) do
14
- {
15
- openstack_username: "twilight",
16
- openstack_domain_id: "default",
17
- openstack_api_key: "sparkle",
18
- openstack_auth_url: "http:",
19
- openstack_project_name: "trixie",
20
- openstack_region: "syd",
21
- openstack_service_name: "the_service",
22
- }
23
- end
24
- let(:logger_io) { StringIO.new }
25
- let(:logger) { Kitchen::Logger.new(logdev: logger_io) }
26
- describe "#volume" do
27
- let(:vol_driver) do
28
- described_class.new(logger)
29
- end
30
-
31
- it "creates a new block device connection" do
32
- allow(Fog::Volume).to receive(:new) { |arg| arg }
33
- expect(vol_driver.send(:volume, os)).to eq(os)
34
- end
35
- end
36
- describe "#create_volume" do
37
- let(:config) do
38
- {
39
- server_name: "applejack",
40
- block_device_mapping: {
41
- snapshot_id: "444",
42
- volume_size: "5",
43
- creation_timeout: "30",
44
- },
45
- }
46
- end
47
-
48
- let(:create_volume) do
49
- {
50
- body: { "volume" => { "id" => "555" } },
51
- }
52
- end
53
-
54
- let(:volume_model) do
55
- {
56
- id: "555",
57
- status: "ACTIVE"
58
- # wait_for: true
59
- # ready?: true
60
- }
61
- end
62
-
63
- let(:volume) do
64
- double(
65
- create_volume: create_volume,
66
- volumes: [volume_model]
67
- )
68
- end
69
-
70
- let(:wait_for) do
71
- {
72
- ready?: true,
73
- status: "ACTIVE",
74
- }
75
- end
76
-
77
- let(:vol_driver) do
78
- d = described_class.new(logger)
79
- allow(d).to receive(:volume).and_return(volume)
80
- allow(d).to receive(:volume_model).and_return(true)
81
- d
82
- end
83
-
84
- it "creates a volume" do
85
- # This seems like a hack
86
- # how would we do this on the volume_model instead?
87
- # This makes rspec work
88
- # but the vol_driver doesnt have these methods properties?
89
- allow(vol_driver).to receive(:status).and_return("ACTIVE")
90
- allow(vol_driver).to receive(:ready?).and_return(true)
91
- allow(volume_model).to receive(:wait_for)
92
- .with(an_instance_of(String)).and_yield
93
-
94
- # allow(vol_driver).a
95
- expect(vol_driver.send(:create_volume, config, os)).to eq("555")
96
- end
97
- end
98
-
99
- describe "#get_bdm" do
100
- let(:config) do
101
- {
102
- block_device_mapping: {
103
- make_volue: true,
104
- snapshot_id: "333",
105
- volume_id: "555",
106
- volume_size: "5",
107
- volume_device_name: "vda",
108
- delete_on_termination: true,
109
- },
110
- }
111
- end
112
-
113
- let(:vol_driver) do
114
- d = described_class.new(logger)
115
- allow(d).to receive(:create_volume).and_return("555")
116
- d
117
- end
118
-
119
- it "returns the block device mapping config" do
120
- expects = config[:block_device_mapping]
121
- expects.delete_if { |k, _| k == :make_volume }
122
- expects.delete_if { |k, _| k == :snapshot_id }
123
- expect(vol_driver.send(:get_bdm, config, os)).to eq(expects)
124
- end
125
- end
126
- end
@@ -1,1411 +0,0 @@
1
- # Encoding: UTF-8
2
-
3
- require_relative "../../spec_helper"
4
- require_relative "../../../lib/kitchen/driver/openstack"
5
-
6
- require "logger"
7
- require "stringio"
8
- require "rspec"
9
- require "kitchen"
10
- require "kitchen/driver/openstack"
11
- require "kitchen/provisioner/dummy"
12
- require "kitchen/transport/dummy"
13
- require "kitchen/verifier/dummy"
14
- require "ohai"
15
- require "excon"
16
- require "fog/openstack"
17
-
18
- describe Kitchen::Driver::Openstack do
19
- let(:logged_output) { StringIO.new }
20
- let(:logger) { Logger.new(logged_output) }
21
- let(:config) { {} }
22
- let(:state) { {} }
23
- let(:instance_name) { "potatoes" }
24
- let(:transport) { Kitchen::Transport::Dummy.new }
25
- let(:platform) { Kitchen::Platform.new(name: "fake_platform") }
26
- let(:driver) { Kitchen::Driver::Openstack.new(config) }
27
-
28
- let(:instance) do
29
- double(
30
- name: instance_name,
31
- transport: transport,
32
- logger: logger,
33
- platform: platform,
34
- to_str: "instance"
35
- )
36
- end
37
-
38
- let(:driver) { described_class.new(config) }
39
-
40
- before(:each) do
41
- allow_any_instance_of(described_class).to receive(:instance)
42
- .and_return(instance)
43
- allow(File).to receive(:exist?).and_call_original
44
- end
45
-
46
- describe "#finalize_config" do
47
- before(:each) { allow(File).to receive(:exist?).and_return(false) }
48
- end
49
-
50
- describe "#initialize" do
51
- context "default options" do
52
- it "uses the normal SSH status check" do
53
- expect(driver[:no_ssh_tcp_check]).to eq(false)
54
- end
55
-
56
- it "sets a default TCP check wait time" do
57
- expect(driver[:no_ssh_tcp_check_sleep]).to eq(120)
58
- end
59
-
60
- it "sets a default Openstack API read timeout" do
61
- expect(driver[:read_timeout]).to eq(60)
62
- end
63
-
64
- it "sets a default Openstack API write timeout" do
65
- expect(driver[:write_timeout]).to eq(60)
66
- end
67
-
68
- it "sets a default ssh connection timeout" do
69
- expect(driver[:connect_timeout]).to eq(60)
70
- end
71
-
72
- nils = %i{
73
- server_name
74
- openstack_project_name
75
- openstack_region
76
- openstack_service_name
77
- floating_ip_pool
78
- floating_ip
79
- availability_zone
80
- security_groups
81
- network_ref
82
- metadata
83
- }
84
- nils.each do |i|
85
- it "defaults to no #{i}" do
86
- expect(driver[i]).to eq(nil)
87
- end
88
- end
89
- end
90
-
91
- context "overridden options" do
92
- let(:config) do
93
- {
94
- image_ref: "22",
95
- image_id: "4391b03e-f7fb-46fd-a356-fa5e42f6d728",
96
- flavor_ref: "33",
97
- flavor_id: "19a2281e-591e-4b47-be06-631c3c7704e8",
98
- public_key_path: "/tmp",
99
- username: "admin",
100
- port: "2222",
101
- server_name: "puppy",
102
- server_name_prefix: "parsnip",
103
- openstack_project_name: "that_one",
104
- openstack_region: "atlantis",
105
- openstack_service_name: "the_service",
106
- floating_ip_pool: "swimmers",
107
- floating_ip: "11111",
108
- network_ref: "0xCAFFE",
109
- network_id: "57d6e41a-f369-4c92-9ebe-1fbf198bc783",
110
- use_ssh_agent: true,
111
- connect_timeout: 123,
112
- read_timeout: 234,
113
- write_timeout: 345,
114
- block_device_mapping: {
115
- make_volume: true,
116
- snapshot_id: "44",
117
- volume_id: "55",
118
- volume_size: "5",
119
- device_name: "vda",
120
- delete_on_termination: true,
121
- },
122
- metadata: {
123
- name: "test",
124
- ohai: "chef",
125
- },
126
- }
127
- end
128
-
129
- it "uses all the overridden options" do
130
- drv = driver
131
- config.each do |k, v|
132
- expect(drv[k]).to eq(v)
133
- end
134
- end
135
-
136
- it "overrides server name prefix with explicit server name, if given" do
137
- expect(driver[:server_name]).to eq(config[:server_name])
138
- end
139
- end
140
- end
141
-
142
- describe "#create" do
143
- let(:server) do
144
- double(id: "test123", wait_for: true, public_ip_addresses: %w{1.2.3.4})
145
- end
146
- let(:driver) do
147
- d = super()
148
- allow(d).to receive(:default_name).and_return("a_monkey!")
149
- allow(d).to receive(:create_server).and_return(server)
150
- allow(d).to receive(:wait_for_sshd).with("1.2.3.4", "root", port: "22")
151
- .and_return(true)
152
- allow(d).to receive(:get_ip).and_return("1.2.3.4")
153
- allow(d).to receive(:add_ohai_hint).and_return(true)
154
- allow(d).to receive(:do_ssh_setup).and_return(true)
155
- allow(d).to receive(:sleep)
156
- allow(d).to receive(:wait_for_ssh_key_access).and_return("SSH key authetication successful") # rubocop:disable Metrics/LineLength
157
- allow(d).to receive(:disable_ssl_validation).and_return(false)
158
- d
159
- end
160
-
161
- context "when a server is already created" do
162
- it "does not create a new instance" do
163
- state[:server_id] = "1"
164
- expect(driver).not_to receive(:create_server)
165
- driver.create(state)
166
- end
167
- end
168
-
169
- context "required options provided" do
170
- let(:config) do
171
- {
172
- openstack_username: "hello",
173
- openstack_domain_id: "default",
174
- openstack_api_key: "world",
175
- openstack_auth_url: "http:",
176
- openstack_project_name: "www",
177
- glance_cache_wait_timeout: 600,
178
- disable_ssl_validation: false,
179
- }
180
- end
181
- let(:server) do
182
- double(id: "test123", wait_for: true, public_ip_addresses: %w{1.2.3.4})
183
- end
184
-
185
- let(:driver) do
186
- d = described_class.new(config)
187
- allow(d).to receive(:config_server_name).and_return("a_monkey!")
188
- allow(d).to receive(:create_server).and_return(server)
189
- allow(server).to receive(:id).and_return("test123")
190
-
191
- # Inside the yield block we are calling ready? So we fake it here
192
- allow(d).to receive(:ready?).and_return(true)
193
- allow(server).to receive(:wait_for)
194
- .with(an_instance_of(Integer)).and_yield
195
-
196
- allow(d).to receive(:get_ip).and_return("1.2.3.4")
197
- allow(d).to receive(:bourne_shell?).and_return(false)
198
- d
199
- end
200
-
201
- it "returns nil, but modifies the state" do
202
- expect(driver.send(:create, state)).to eq(nil)
203
- expect(state[:server_id]).to eq("test123")
204
- end
205
-
206
- it "throws an Action error when trying to create_server" do
207
- allow(driver).to receive(:create_server).and_raise(Fog::Errors::Error)
208
- expect { driver.send(:create, state) }.to raise_error(Kitchen::ActionFailed) # rubocop:disable Metrics/LineLength
209
- end
210
- end
211
- end
212
-
213
- describe "#destroy" do
214
- let(:server_id) { "12345" }
215
- let(:hostname) { "example.com" }
216
- let(:state) { { server_id: server_id, hostname: hostname } }
217
- let(:server) { double(nil?: false, destroy: true) }
218
- let(:servers) { double(get: server) }
219
- let(:compute) { double(servers: servers) }
220
-
221
- let(:driver) do
222
- d = super()
223
- allow(d).to receive(:compute).and_return(compute)
224
- d
225
- end
226
-
227
- context "a live server that needs to be destroyed" do
228
- it "destroys the server" do
229
- expect(state).to receive(:delete).with(:server_id)
230
- expect(state).to receive(:delete).with(:hostname)
231
- driver.destroy(state)
232
- end
233
-
234
- it "does not disable SSL cert validation" do
235
- expect(driver).to_not receive(:disable_ssl_validation)
236
- driver.destroy(state)
237
- end
238
- end
239
-
240
- context "no server ID present" do
241
- let(:state) { {} }
242
-
243
- it "does nothing" do
244
- allow(driver).to receive(:compute)
245
- expect(driver).to_not receive(:compute)
246
- expect(state).to_not receive(:delete)
247
- driver.destroy(state)
248
- end
249
- end
250
-
251
- context "a server that was already destroyed" do
252
- let(:servers) do
253
- s = double("servers")
254
- allow(s).to receive(:get).with("12345").and_return(nil)
255
- s
256
- end
257
- let(:compute) { double(servers: servers) }
258
- let(:driver) do
259
- d = super()
260
- allow(d).to receive(:compute).and_return(compute)
261
- d
262
- end
263
-
264
- it "does not try to destroy the server again" do
265
- allow_message_expectations_on_nil
266
- driver.destroy(state)
267
- end
268
- end
269
-
270
- context "SSL validation disabled" do
271
- let(:config) { { disable_ssl_validation: true } }
272
-
273
- it "disables SSL cert validation" do
274
- expect(driver).to receive(:disable_ssl_validation)
275
- driver.destroy(state)
276
- end
277
- end
278
-
279
- context "Deallocate floating IP" do
280
- let(:config) do
281
- {
282
- floating_ip_pool: "swimmers",
283
- allocate_floating_ip: true,
284
- }
285
- end
286
- let(:ip) { "1.1.1.1" }
287
- let(:ip_id) { "123" }
288
-
289
- let(:network_response) do
290
- double(body: { "floatingips" => [{ "id" => ip_id }] })
291
- end
292
-
293
- let(:network) do
294
- s = double("network")
295
- expect(s).to receive(:list_floating_ips).with(floating_ip_address: ip).and_return(network_response) # rubocop:disable Metrics/LineLength
296
- expect(s).to receive(:delete_floating_ip).with(ip_id)
297
- s
298
- end
299
-
300
- let(:driver) do
301
- d = super()
302
- allow(d).to receive(:get_public_private_ips).and_return([ip, nil])
303
- allow(d).to receive(:compute).and_return(compute)
304
- allow(d).to receive(:network).and_return(network)
305
- d
306
- end
307
- it "deallocates the ip" do
308
- driver.destroy(state)
309
- end
310
- end
311
- end
312
-
313
- describe "#openstack_server" do
314
- let(:config) do
315
- {
316
- openstack_username: "a",
317
- openstack_domain_id: "default",
318
- openstack_api_key: "b",
319
- openstack_auth_url: "http://",
320
- openstack_project_name: "me",
321
- openstack_region: "ORD",
322
- openstack_service_name: "stack",
323
- connection_options:
324
- {
325
- read_timeout: 60,
326
- write_timeout: 60,
327
- connect_timeout: 60,
328
- },
329
- }
330
- end
331
-
332
- it "returns a hash of server settings" do
333
- expected = config.merge(provider: "OpenStack")
334
- expect(driver.send(:openstack_server)).to eq(expected)
335
- end
336
- end
337
-
338
- describe "#required_server_settings" do
339
- it "returns the required settings for an OpenStack server" do
340
- expected = %i{
341
- openstack_username openstack_api_key openstack_auth_url openstack_domain_id
342
- }
343
- expect(driver.send(:required_server_settings)).to eq(expected)
344
- end
345
- end
346
-
347
- describe "#optional_server_settings" do
348
- it "returns the optional settings for an OpenStack server" do
349
- excluded = %i{
350
- openstack_username openstack_api_key openstack_auth_url openstack_domain_id
351
- }
352
- expect(driver.send(:optional_server_settings)).not_to include(*excluded)
353
- end
354
- end
355
-
356
- describe "#compute" do
357
- let(:config) do
358
- {
359
- openstack_username: "monkey",
360
- openstack_domain_id: "default",
361
- openstack_api_key: "potato",
362
- openstack_auth_url: "http:",
363
- openstack_project_name: "link",
364
- openstack_region: "ord",
365
- openstack_service_name: "the_service",
366
- connection_options:
367
- {
368
- read_timeout: 60,
369
- write_timeout: 60,
370
- connect_timeout: 60,
371
- },
372
- }
373
- end
374
-
375
- context "all requirements provided" do
376
- it "creates a new compute connection" do
377
- allow(Fog::Compute).to receive(:new) { |arg| arg }
378
- res = config.merge(provider: "OpenStack")
379
- expect(driver.send(:compute)).to eq(res)
380
- end
381
-
382
- it "creates a new network connection" do
383
- allow(Fog::Network).to receive(:new) { |arg| arg }
384
- res = config.merge(provider: "OpenStack")
385
- expect(driver.send(:network)).to eq(res)
386
- end
387
- end
388
-
389
- context "only an API key provided" do
390
- let(:config) { { openstack_api_key: "1234" } }
391
-
392
- it "raises an error" do
393
- expect { driver.send(:compute) }.to raise_error(ArgumentError)
394
- end
395
- end
396
-
397
- context "only a username provided" do
398
- let(:config) { { openstack_username: "monkey" } }
399
-
400
- it "raises an error" do
401
- expect { driver.send(:compute) }.to raise_error(ArgumentError)
402
- end
403
- end
404
- end
405
-
406
- describe "#create_server" do
407
- let(:config) do
408
- {
409
- server_name: "hello",
410
- image_ref: "111",
411
- flavor_ref: "1",
412
- availability_zone: nil,
413
- block_device_mapping: {
414
- volume_size: "5",
415
- volume_id: "333",
416
- volume_device_name: "vda",
417
- delete_on_termination: "true",
418
- },
419
- }
420
- end
421
- let(:servers) do
422
- s = double("servers")
423
- allow(s).to receive(:create) { |arg| arg }
424
- s
425
- end
426
- let(:vlan1_net) { double(id: "1", name: "vlan1") }
427
- let(:vlan2_net) { double(id: "2", name: "vlan2") }
428
- let(:ubuntu_image) { double(id: "111", name: "ubuntu") }
429
- let(:fedora_image) { double(id: "222", name: "fedora") }
430
- let(:tiny_flavor) { double(id: "1", name: "tiny") }
431
- let(:small_flavor) { double(id: "2", name: "small") }
432
- let(:compute) do
433
- double(
434
- servers: servers,
435
- images: [ubuntu_image, fedora_image],
436
- flavors: [tiny_flavor, small_flavor]
437
- )
438
- end
439
- let(:network) do
440
- double(networks: double(all: [vlan1_net, vlan2_net]))
441
- end
442
- let(:block_device_mapping) do
443
- {
444
- volume_id: "333",
445
- volume_size: "5",
446
- volume_device_name: "vda",
447
- delete_on_termination: "true",
448
- }
449
- end
450
- let(:driver) do
451
- d = super()
452
- allow(d).to receive(:compute).and_return(compute)
453
- allow(d).to receive(:network).and_return(network)
454
- allow(d).to receive(:get_bdm).and_return(block_device_mapping)
455
- d
456
- end
457
-
458
- context "a default config" do
459
- before(:each) do
460
- @expected = config.merge(name: config[:server_name])
461
- @expected.delete_if { |k, _| k == :server_name }
462
- end
463
-
464
- it "creates the server using a compute connection" do
465
- expect(driver.send(:create_server)).to eq(@expected)
466
- end
467
- end
468
-
469
- context "a provided key name" do
470
- let(:config) do
471
- {
472
- server_name: "hello",
473
- image_ref: "111",
474
- flavor_ref: "1",
475
- availability_zone: nil,
476
- key_name: "tarpals",
477
- }
478
- end
479
-
480
- before(:each) do
481
- @expected = config.merge(name: config[:server_name])
482
- @expected.delete_if { |k, _| k == :server_name }
483
- end
484
-
485
- it "passes that key name to Fog" do
486
- expect(driver.send(:create_server)).to eq(@expected)
487
- end
488
- end
489
-
490
- context "a provided security group" do
491
- let(:config) do
492
- {
493
- server_name: "hello",
494
- image_ref: "111",
495
- flavor_ref: "1",
496
- availability_zone: nil,
497
- key_name: "tarpals",
498
- security_groups: ["ping-and-ssh"],
499
- }
500
- end
501
-
502
- before(:each) do
503
- @expected = config.merge(name: config[:server_name])
504
- @expected.delete_if { |k, _| k == :server_name }
505
- end
506
-
507
- it "passes that security group to Fog" do
508
- expect(driver.send(:create_server)).to eq(@expected)
509
- end
510
- end
511
-
512
- context "a provided availability zone" do
513
- let(:config) do
514
- {
515
- server_name: "hello",
516
- image_ref: "111",
517
- flavor_ref: "1",
518
- availability_zone: "elsewhere",
519
- key_name: "tarpals",
520
- }
521
- end
522
-
523
- before(:each) do
524
- @expected = config.merge(name: config[:server_name])
525
- @expected.delete_if { |k, _| k == :server_name }
526
- end
527
-
528
- it "passes that availability zone to Fog" do
529
- expect(driver.send(:create_server)).to eq(@expected)
530
- end
531
- end
532
-
533
- context "image_id specified" do
534
- let(:config) do
535
- {
536
- server_name: "hello",
537
- image_id: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
538
- flavor_ref: "1",
539
- }
540
- end
541
-
542
- it "exact id match" do
543
- expect(servers).to receive(:create).with(
544
- name: "hello",
545
- image_ref: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
546
- flavor_ref: "1",
547
- availability_zone: nil
548
- )
549
- driver.send(:create_server)
550
- end
551
- end
552
-
553
- context "image_id and image_ref specified" do
554
- let(:config) do
555
- {
556
- server_name: "hello",
557
- image_id: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
558
- image_ref: "111",
559
- flavor_ref: "1",
560
- }
561
- end
562
-
563
- it "raises an exception" do
564
- expect { driver.send(:create_server) }.to \
565
- raise_error(Kitchen::ActionFailed)
566
- end
567
- end
568
-
569
- context "flavor_id specified" do
570
- let(:config) do
571
- {
572
- server_name: "hello",
573
- flavor_id: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
574
- image_ref: "111",
575
- }
576
- end
577
-
578
- it "exact id match" do
579
- expect(servers).to receive(:create).with(
580
- name: "hello",
581
- flavor_ref: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
582
- image_ref: "111",
583
- availability_zone: nil
584
- )
585
- driver.send(:create_server)
586
- end
587
- end
588
-
589
- context "flavor_id and flavor_ref specified" do
590
- let(:config) do
591
- {
592
- server_name: "hello",
593
- image_id: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
594
- flavor_id: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
595
- flavor_ref: "1",
596
- }
597
- end
598
-
599
- it "raises an exception" do
600
- expect { driver.send(:create_server) }.to \
601
- raise_error(Kitchen::ActionFailed)
602
- end
603
- end
604
-
605
- context "image/flavor specifies id" do
606
- let(:config) do
607
- {
608
- server_name: "hello",
609
- image_ref: "111",
610
- flavor_ref: "1",
611
- }
612
- end
613
-
614
- it "exact id match" do
615
- expect(servers).to receive(:create).with(name: "hello",
616
- image_ref: "111",
617
- flavor_ref: "1",
618
- availability_zone: nil)
619
- driver.send(:create_server)
620
- end
621
- end
622
-
623
- context "image/flavor specifies name" do
624
- let(:config) do
625
- {
626
- server_name: "hello",
627
- image_ref: "fedora",
628
- flavor_ref: "small",
629
- }
630
- end
631
-
632
- it "exact name match" do
633
- expect(servers).to receive(:create).with(name: "hello",
634
- image_ref: "222",
635
- flavor_ref: "2",
636
- availability_zone: nil)
637
- driver.send(:create_server)
638
- end
639
- end
640
-
641
- context "image/flavor specifies regex" do
642
- let(:config) do
643
- {
644
- server_name: "hello",
645
- # pass regex as string as yml returns string values
646
- image_ref: "/edo/",
647
- flavor_ref: "/in/",
648
- }
649
- end
650
-
651
- it "regex name match" do
652
- expect(servers).to receive(:create).with(name: "hello",
653
- image_ref: "222",
654
- flavor_ref: "1",
655
- availability_zone: nil)
656
- driver.send(:create_server)
657
- end
658
- end
659
-
660
- context "network specifies network_id" do
661
- let(:config) do
662
- {
663
- server_name: "hello",
664
- image_ref: "111",
665
- flavor_ref: "1",
666
- network_id: "0922b7aa-0a2f-4e68-8ff7-2886c4fc472d",
667
- }
668
- end
669
-
670
- it "exact id match" do
671
- networks = [
672
- { "net_id" => "0922b7aa-0a2f-4e68-8ff7-2886c4fc472d" },
673
- ]
674
- expect(servers).to receive(:create).with(name: "hello",
675
- image_ref: "111",
676
- flavor_ref: "1",
677
- availability_zone: nil,
678
- nics: networks)
679
- driver.send(:create_server)
680
- end
681
- end
682
-
683
- context "network_id and network_ref specified" do
684
- let(:config) do
685
- {
686
- server_name: "hello",
687
- image_id: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
688
- flavor_id: "1e1f4346-e3ea-48ba-9d1b-0002bfcb8981",
689
- network_id: "0922b7aa-0a2f-4e68-8ff7-2886c4fc472d",
690
- network_ref: "1",
691
- }
692
- end
693
-
694
- it "raises an exception" do
695
- expect { driver.send(:create_server) }.to \
696
- raise_error(Kitchen::ActionFailed)
697
- end
698
- end
699
-
700
- context "network specifies id" do
701
- let(:config) do
702
- {
703
- server_name: "hello",
704
- image_ref: "111",
705
- flavor_ref: "1",
706
- network_ref: "1",
707
- }
708
- end
709
-
710
- it "exact id match" do
711
- networks = [
712
- { "net_id" => "1" },
713
- ]
714
- expect(servers).to receive(:create).with(
715
- name: "hello",
716
- image_ref: "111",
717
- flavor_ref: "1",
718
- availability_zone: nil,
719
- nics: networks
720
- )
721
- driver.send(:create_server)
722
- end
723
- end
724
-
725
- context "network specifies name" do
726
- let(:config) do
727
- {
728
- server_name: "hello",
729
- image_ref: "111",
730
- flavor_ref: "1",
731
- network_ref: "vlan1",
732
- }
733
- end
734
-
735
- it "exact id match" do
736
- networks = [
737
- { "net_id" => "1" },
738
- ]
739
- expect(servers).to receive(:create).with(
740
- name: "hello",
741
- image_ref: "111",
742
- flavor_ref: "1",
743
- availability_zone: nil,
744
- nics: networks
745
- )
746
- driver.send(:create_server)
747
- end
748
- end
749
-
750
- context "multiple networks specifies id" do
751
- let(:config) do
752
- {
753
- server_name: "hello",
754
- image_ref: "111",
755
- flavor_ref: "1",
756
- network_ref: %w{1 2},
757
- }
758
- end
759
-
760
- it "exact id match" do
761
- networks = [
762
- { "net_id" => "1" },
763
- { "net_id" => "2" },
764
- ]
765
- expect(servers).to receive(:create).with(
766
- name: "hello",
767
- image_ref: "111",
768
- flavor_ref: "1",
769
- availability_zone: nil,
770
- nics: networks
771
- )
772
- driver.send(:create_server)
773
- end
774
- end
775
-
776
- context "user_data specified" do
777
- let(:config) do
778
- {
779
- server_name: "hello",
780
- image_ref: "111",
781
- flavor_ref: "1",
782
- user_data: "cloud-init.txt",
783
- }
784
- end
785
- let(:data) { "#cloud-config\n" }
786
-
787
- before(:each) do
788
- allow(File).to receive(:exist?).and_return(true)
789
- allow(File).to receive(:open).and_return(data)
790
- end
791
-
792
- it "passes file contents" do
793
- expect(servers).to receive(:create).with(
794
- name: "hello",
795
- image_ref: "111",
796
- flavor_ref: "1",
797
- availability_zone: nil,
798
- user_data: data
799
- )
800
- driver.send(:create_server)
801
- end
802
- end
803
-
804
- context "config drive enabled" do
805
- let(:config) do
806
- {
807
- server_name: "hello",
808
- image_ref: "111",
809
- flavor_ref: "1",
810
- config_drive: true,
811
- }
812
- end
813
-
814
- it "enables config drive" do
815
- expect(servers).to receive(:create).with(
816
- name: "hello",
817
- image_ref: "111",
818
- flavor_ref: "1",
819
- availability_zone: nil,
820
- config_drive: true
821
- )
822
- driver.send(:create_server)
823
- end
824
- end
825
-
826
- context "metadata specified" do
827
- let(:config) do
828
- {
829
- server_name: "hello",
830
- image_ref: "111",
831
- flavor_ref: "1",
832
- metadata: {
833
- name: "hello",
834
- ohai: "chef",
835
- },
836
- }
837
- end
838
- let(:data) do
839
- {
840
- name: "hello",
841
- ohai: "chef",
842
- }
843
- end
844
-
845
- it "passes metadata contents" do
846
- expect(servers).to receive(:create).with(
847
- name: "hello",
848
- image_ref: "111",
849
- flavor_ref: "1",
850
- availability_zone: nil,
851
- metadata: data
852
- )
853
- driver.send(:create_server)
854
- end
855
- end
856
- end
857
-
858
- describe "#default_name" do
859
- let(:login) { "user" }
860
- let(:hostname) { "host" }
861
-
862
- before(:each) do
863
- allow(Etc).to receive(:getlogin).and_return(login)
864
- allow(Socket).to receive(:gethostname).and_return(hostname)
865
- end
866
-
867
- it "generates a name" do
868
- expect(driver.send(:default_name)).to match(/^potatoes-user-host-(\S*)/)
869
- end
870
-
871
- context "local node with a long hostname" do
872
- let(:hostname) { "ab.c" * 20 }
873
-
874
- it "limits the generated name to 63 characters" do
875
- expect(driver.send(:default_name).length).to be <= 63
876
- end
877
- end
878
-
879
- context "node with a long hostname, username, and base name" do
880
- let(:login) { "abcd" * 20 }
881
- let(:hostname) { "efgh" * 20 }
882
- let(:instance_name) { "ijkl" * 20 }
883
-
884
- it "limits the generated name to 63 characters" do
885
- expect(driver.send(:default_name).length).to eq(63)
886
- end
887
- end
888
-
889
- context "a login and hostname with punctuation in them" do
890
- let(:login) { "some.u-se-r" }
891
- let(:hostname) { "a.host-name" }
892
- let(:instance_name) { "a.instance-name" }
893
-
894
- it "strips out the dots to prevent bad server names" do
895
- expect(driver.send(:default_name)).to_not include(".")
896
- end
897
-
898
- it "strips out all but the three hyphen separators" do
899
- expect(driver.send(:default_name).count("-")).to eq(3)
900
- end
901
- end
902
-
903
- context "a non-login shell" do
904
- let(:login) { nil }
905
-
906
- it "subs in a placeholder login string" do
907
- expect(driver.send(:default_name)).to match(/^potatoes-nologin-/)
908
- end
909
- end
910
- end
911
-
912
- describe "#server_name_prefix" do
913
- let(:login) { "user" }
914
- let(:hostname) { "host" }
915
- let(:prefix) { "parsnip" }
916
-
917
- # These are still used in the "blank prefix" test
918
- before(:each) do
919
- allow(Etc).to receive(:getlogin).and_return(login)
920
- allow(Socket).to receive(:gethostname).and_return(hostname)
921
- end
922
-
923
- it "generates a name with the selected prefix" do
924
- expect(driver.send(:server_name_prefix, prefix))
925
- .to match(/^parsnip-(\S*)/)
926
- end
927
-
928
- context "very long prefix provided" do
929
- let(:long_prefix) { "a" * 70 }
930
-
931
- it "limits the generated name to 63 characters" do
932
- expect(driver.send(:server_name_prefix, long_prefix).length)
933
- .to be <= 63
934
- end
935
- end
936
-
937
- context "a prefix with punctuation" do
938
- let(:bad_char_prefix) { "pa-rsn.ip" }
939
-
940
- it "strips out the dots to prevent bad server names" do
941
- expect(driver.send(:server_name_prefix, bad_char_prefix))
942
- .to_not include(".")
943
- end
944
-
945
- it "strips out all but the one hyphen separator" do
946
- expect(driver.send(:server_name_prefix, bad_char_prefix)
947
- .count("-")).to eq(1)
948
- end
949
- end
950
-
951
- context "blank prefix" do
952
- it "generates fully random server name" do
953
- expect(driver.send(:server_name_prefix, ""))
954
- .to match(/potatoes-user-host-(\S*)/)
955
- end
956
- end
957
- end
958
-
959
- describe "#attach_ip_from_pool" do
960
- let(:server) { nil }
961
- let(:pool) { "swimmers" }
962
- let(:ip) { "1.1.1.1" }
963
- let(:address) do
964
- double(ip: ip, fixed_ip: nil, instance_id: nil, pool: pool)
965
- end
966
- let(:compute) { double(addresses: [address]) }
967
-
968
- before(:each) do
969
- allow(driver).to receive(:attach_ip).with(server, ip).and_return("bing!")
970
- allow(driver).to receive(:compute).and_return(compute)
971
- end
972
-
973
- it "determines an IP to attempt to attach" do
974
- expect(driver.send(:attach_ip_from_pool, server, pool)).to eq("bing!")
975
- end
976
-
977
- context "no free addresses in the specified pool" do
978
- let(:address) do
979
- double(ip: ip, fixed_ip: nil, instance_id: nil,
980
- pool: "some_other_pool")
981
- end
982
-
983
- it "raises an exception" do
984
- expect { driver.send(:attach_ip_from_pool, server, pool) }.to \
985
- raise_error(Kitchen::ActionFailed)
986
- end
987
- end
988
- end
989
-
990
- describe "#allocate_ip_from_pool" do
991
- let(:server) { nil }
992
- let(:pool) { "swimmers" }
993
- let(:config) { { allocate_floating_ip: true } }
994
- let(:network_id) { 123 }
995
- let(:ip) { "1.1.1.1" }
996
- let(:address) do
997
- double(ip: ip, fixed_ip: nil, instance_id: nil, pool: pool)
998
- end
999
- let(:list_networks_response) do
1000
- double(body: { "networks" => [{ "name" => pool, "id" => network_id }] })
1001
- end
1002
- let(:create_ip_network_response) do
1003
- double(body: { "floatingip" => { "floating_ip_address" => ip } })
1004
- end
1005
- let(:network) { double(list_networks: list_networks_response, create_floating_ip: create_ip_network_response) } # rubocop:disable Metrics/LineLength
1006
-
1007
- before(:each) do
1008
- allow(driver).to receive(:attach_ip).with(server, ip).and_return("bing!")
1009
- allow(driver).to receive(:network).and_return(network)
1010
- end
1011
-
1012
- it "determines an IP to attempt to attach" do
1013
- expect(driver.send(:attach_ip_from_pool, server, pool)).to eq("bing!")
1014
- end
1015
- end
1016
-
1017
- describe "#attach_ip" do
1018
- let(:ip) { "1.1.1.1" }
1019
- let(:addresses) { {} }
1020
- let(:server) do
1021
- s = double("server")
1022
- expect(s).to receive(:associate_address).with(ip).and_return(true)
1023
- allow(s).to receive(:addresses).and_return(addresses)
1024
- s
1025
- end
1026
-
1027
- it "associates the IP address with the server" do
1028
- expect(driver.send(:attach_ip, server, ip)).to eq(true)
1029
- end
1030
- end
1031
-
1032
- describe "#get_ip" do
1033
- let(:addresses) { nil }
1034
- let(:public_ip_addresses) { nil }
1035
- let(:private_ip_addresses) { nil }
1036
- let(:ip_addresses) { nil }
1037
- let(:parsed_ips) { [[], []] }
1038
- let(:driver) do
1039
- d = super()
1040
- allow(d).to receive(:parse_ips).and_return(parsed_ips)
1041
- d
1042
- end
1043
- let(:server) do
1044
- double(addresses: addresses,
1045
- public_ip_addresses: public_ip_addresses,
1046
- private_ip_addresses: private_ip_addresses,
1047
- ip_addresses: ip_addresses,
1048
- wait_for: { duration: 0 })
1049
- end
1050
-
1051
- context "both public and private IPs" do
1052
- let(:public_ip_addresses) { %w{1::1 1.2.3.4} }
1053
- let(:private_ip_addresses) { %w{5.5.5.5} }
1054
- let(:parsed_ips) { [%w{1.2.3.4}, %w{5.5.5.5}] }
1055
-
1056
- it "returns a public IPv4 address" do
1057
- expect(driver.send(:get_ip, server)).to eq("1.2.3.4")
1058
- end
1059
- end
1060
-
1061
- context "only public IPs" do
1062
- let(:public_ip_addresses) { %w{4.3.2.1 2::1} }
1063
- let(:parsed_ips) { [%w{4.3.2.1}, []] }
1064
-
1065
- it "returns a public IPv4 address" do
1066
- expect(driver.send(:get_ip, server)).to eq("4.3.2.1")
1067
- end
1068
- end
1069
-
1070
- context "only private IPs" do
1071
- let(:private_ip_addresses) { %w{3::1 5.5.5.5} }
1072
- let(:parsed_ips) { [[], %w{5.5.5.5}] }
1073
-
1074
- it "returns a private IPv4 address" do
1075
- expect(driver.send(:get_ip, server)).to eq("5.5.5.5")
1076
- end
1077
- end
1078
-
1079
- context "no predictable network name" do
1080
- let(:ip_addresses) { %w{3::1 5.5.5.5} }
1081
- let(:parsed_ips) { [[], %w{5.5.5.5}] }
1082
-
1083
- it "returns the first IP that matches the IP version" do
1084
- expect(driver.send(:get_ip, server)).to eq("5.5.5.5")
1085
- end
1086
- end
1087
-
1088
- context "IPs in user-defined network group" do
1089
- let(:config) { { openstack_network_name: "mynetwork" } }
1090
- let(:addresses) do
1091
- {
1092
- "mynetwork" => [
1093
- { "addr" => "7.7.7.7" },
1094
- { "addr" => "4::1" },
1095
- ],
1096
- }
1097
- end
1098
-
1099
- it "returns a IPv4 address in user-defined network group" do
1100
- expect(driver.send(:get_ip, server)).to eq("7.7.7.7")
1101
- end
1102
- end
1103
-
1104
- context "when a floating ip is provided" do
1105
- let(:config) { { floating_ip: "1.2.3.4" } }
1106
-
1107
- it "returns the floating ip and skips reloading" do
1108
- allow(driver).to receive(:config).and_return(config)
1109
-
1110
- expect(server).to_not receive(:wait_for)
1111
- expect(driver.send(:get_ip, server)).to eq("1.2.3.4")
1112
- end
1113
- end
1114
-
1115
- context "an OpenStack deployment without the floating IP extension" do
1116
- before do
1117
- allow(server).to receive(:public_ip_addresses).and_raise(
1118
- Fog::Compute::OpenStack::NotFound
1119
- )
1120
- allow(server).to receive(:private_ip_addresses).and_raise(
1121
- Fog::Compute::OpenStack::NotFound
1122
- )
1123
- end
1124
-
1125
- context "both public and private IPs in the addresses hash" do
1126
- let(:addresses) do
1127
- {
1128
- "public" => [{ "addr" => "6.6.6.6" }, { "addr" => "7.7.7.7" }],
1129
- "private" => [{ "addr" => "8.8.8.8" }, { "addr" => "9.9.9.9" }],
1130
- }
1131
- end
1132
- let(:parsed_ips) { [%w{6.6.6.6 7.7.7.7}, %w{8.8.8.8 9.9.9.9}] }
1133
-
1134
- it "selects the first public IP" do
1135
- expect(driver.send(:get_ip, server)).to eq("6.6.6.6")
1136
- end
1137
- end
1138
-
1139
- context "when openstack_network_name is provided" do
1140
- let(:addresses) do
1141
- {
1142
- "public" => [{ "addr" => "6.6.6.6" }, { "addr" => "7.7.7.7" }],
1143
- "private" => [{ "addr" => "8.8.8.8" }, { "addr" => "9.9.9.9" }],
1144
- }
1145
- end
1146
- let(:config) { { openstack_network_name: "public" } }
1147
-
1148
- it "should respond with the first address from the addresses" do
1149
- allow(driver).to receive(:config).and_return(config)
1150
-
1151
- expect(driver.send(:get_ip, server)).to eq("6.6.6.6")
1152
- end
1153
- end
1154
-
1155
- context "when openstack_network_name is provided and use_ipv6 is false" do
1156
- let(:addresses) do
1157
- {
1158
- "public" => [{ "addr" => "4::1" }, { "addr" => "7.7.7.7" }],
1159
- "private" => [{ "addr" => "5::1" }, { "addr" => "9.9.9.9" }],
1160
- }
1161
- end
1162
- let(:config) { { openstack_network_name: "public" } }
1163
-
1164
- it "should respond with the first IPv4 address from the addresses" do
1165
- allow(driver).to receive(:config).and_return(config)
1166
-
1167
- expect(driver.send(:get_ip, server)).to eq("7.7.7.7")
1168
- end
1169
- end
1170
-
1171
- context "when openstack_network_name is provided and use_ipv6 is true" do
1172
- let(:addresses) do
1173
- {
1174
- "public" => [{ "addr" => "4::1" }, { "addr" => "7.7.7.7" }],
1175
- "private" => [{ "addr" => "5::1" }, { "addr" => "9.9.9.9" }],
1176
- }
1177
- end
1178
- let(:config) { { openstack_network_name: "public", use_ipv6: true } }
1179
-
1180
- it "should respond with the first IPv6 address from the addresses" do
1181
- allow(driver).to receive(:config).and_return(config)
1182
-
1183
- expect(driver.send(:get_ip, server)).to eq("4::1")
1184
- end
1185
- end
1186
-
1187
- context "only public IPs in the address hash" do
1188
- let(:addresses) do
1189
- { "public" => [{ "addr" => "6.6.6.6" }, { "addr" => "7.7.7.7" }] }
1190
- end
1191
- let(:parsed_ips) { [%w{6.6.6.6 7.7.7.7}, []] }
1192
-
1193
- it "selects the first public IP" do
1194
- expect(driver.send(:get_ip, server)).to eq("6.6.6.6")
1195
- end
1196
- end
1197
-
1198
- context "only private IPs in the address hash" do
1199
- let(:addresses) do
1200
- { "private" => [{ "addr" => "8.8.8.8" }, { "addr" => "9.9.9.9" }] }
1201
- end
1202
- let(:parsed_ips) { [[], %w{8.8.8.8 9.9.9.9}] }
1203
-
1204
- it "selects the first private IP" do
1205
- expect(driver.send(:get_ip, server)).to eq("8.8.8.8")
1206
- end
1207
- end
1208
- end
1209
-
1210
- context "no IP addresses whatsoever" do
1211
- it "raises an exception" do
1212
- expected = Kitchen::ActionFailed
1213
- expect { driver.send(:get_ip, server) }.to raise_error(expected)
1214
- end
1215
- end
1216
-
1217
- context "when network information is not found" do
1218
- before do
1219
- allow(server).to receive(:wait_for).and_raise(Fog::Errors::TimeoutError)
1220
- end
1221
-
1222
- it "raises an exception" do
1223
- expected = Kitchen::ActionFailed
1224
- expect { driver.send(:get_ip, server) }.to raise_error(expected)
1225
- end
1226
- end
1227
- end
1228
-
1229
- describe "#parse_ips" do
1230
- let(:pub_v4) { %w{1.1.1.1 2.2.2.2} }
1231
- let(:pub_v6) { %w{1::1 2::2} }
1232
- let(:priv_v4) { %w{3.3.3.3 4.4.4.4} }
1233
- let(:priv_v6) { %w{3::3 4::4} }
1234
- let(:pub) { pub_v4 + pub_v6 }
1235
- let(:priv) { priv_v4 + priv_v6 }
1236
-
1237
- context "both public and private IPs" do
1238
- context "IPv4 (default)" do
1239
- it "returns only the v4 IPs" do
1240
- expect(driver.send(:parse_ips, pub, priv)).to eq([pub_v4, priv_v4])
1241
- end
1242
- end
1243
-
1244
- context "IPv6" do
1245
- let(:config) { { use_ipv6: true } }
1246
-
1247
- it "returns only the v6 IPs" do
1248
- expect(driver.send(:parse_ips, pub, priv)).to eq([pub_v6, priv_v6])
1249
- end
1250
- end
1251
- end
1252
-
1253
- context "only public IPs" do
1254
- let(:priv) { nil }
1255
-
1256
- context "IPv4 (default)" do
1257
- it "returns only the v4 IPs" do
1258
- expect(driver.send(:parse_ips, pub, priv)).to eq([pub_v4, []])
1259
- end
1260
- end
1261
-
1262
- context "IPv6" do
1263
- let(:config) { { use_ipv6: true } }
1264
-
1265
- it "returns only the v6 IPs" do
1266
- expect(driver.send(:parse_ips, pub, priv)).to eq([pub_v6, []])
1267
- end
1268
- end
1269
- end
1270
-
1271
- context "only private IPs" do
1272
- let(:pub) { nil }
1273
-
1274
- context "IPv4 (default)" do
1275
- it "returns only the v4 IPs" do
1276
- expect(driver.send(:parse_ips, pub, priv)).to eq([[], priv_v4])
1277
- end
1278
- end
1279
-
1280
- context "IPv6" do
1281
- let(:config) { { use_ipv6: true } }
1282
-
1283
- it "returns only the v6 IPs" do
1284
- expect(driver.send(:parse_ips, pub, priv)).to eq([[], priv_v6])
1285
- end
1286
- end
1287
- end
1288
-
1289
- context "no IPs whatsoever" do
1290
- let(:pub) { nil }
1291
- let(:priv) { nil }
1292
-
1293
- context "IPv4 (default)" do
1294
- it "returns empty lists" do
1295
- expect(driver.send(:parse_ips, pub, priv)).to eq([[], []])
1296
- end
1297
- end
1298
-
1299
- context "IPv6" do
1300
- let(:config) { { use_ipv6: true } }
1301
-
1302
- it "returns empty lists" do
1303
- expect(driver.send(:parse_ips, nil, nil)).to eq([[], []])
1304
- end
1305
- end
1306
- end
1307
- end
1308
-
1309
- describe "#add_ohai_hint" do
1310
- let(:state) { { hostname: "host" } }
1311
- let(:ssh) do
1312
- s = double("ssh")
1313
- allow(s).to receive(:run) { |args| args }
1314
- s
1315
- end
1316
- it "opens an SSH session to the server" do
1317
- driver.send(:add_ohai_hint, state)
1318
- end
1319
-
1320
- it "opens an Winrm session to the server" do
1321
- allow(driver).to receive(:bourne_shell?).and_return(false)
1322
- allow(driver).to receive(:windows_os?).and_return(true)
1323
- driver.send(:add_ohai_hint, state)
1324
- end
1325
- end
1326
-
1327
- describe "#disable_ssl_validation" do
1328
- it "turns off Excon SSL cert validation" do
1329
- expect(driver.send(:disable_ssl_validation)).to eq(false)
1330
- end
1331
- end
1332
-
1333
- describe "#countdown" do
1334
- it "counts down to future time with 0 seconds with almost no time" do
1335
- current = Time.now
1336
- driver.send(:countdown, 0)
1337
- after = Time.now
1338
- expect(after - current).to be >= 0
1339
- expect(after - current).to be < 10
1340
- end
1341
-
1342
- it "counts down to future time with 1 seconds with at least 9 seconds" do
1343
- current = Time.now
1344
- driver.send(:countdown, 1)
1345
- after = Time.now
1346
- expect(after - current).to be >= 9
1347
- end
1348
- end
1349
-
1350
- describe "#wait_for_server" do
1351
- let(:config) { { server_wait: 0 } }
1352
- let(:state) { { hostname: "host" } }
1353
-
1354
- it "waits for connection to be available" do
1355
- expect(driver.send(:wait_for_server, state)).to be(nil)
1356
- end
1357
-
1358
- it "Fails when calling transport but still destroys the created system" do
1359
- allow(instance.transport).to receive(:connection).and_raise(ArgumentError)
1360
- expect(driver).to receive(:destroy)
1361
-
1362
- expect { driver.send(:wait_for_server, state) }
1363
- .to raise_error(ArgumentError)
1364
- end
1365
- end
1366
-
1367
- describe "#get_bdm" do
1368
- let(:logger) { Logger.new(logged_output) }
1369
- let(:config) do
1370
- {
1371
- openstack_username: "a",
1372
- openstack_domain_id: "default",
1373
- openstack_api_key: "b",
1374
- openstack_auth_url: "http://",
1375
- openstack_project_name: "me",
1376
- openstack_region: "ORD",
1377
- openstack_service_name: "stack",
1378
- image_ref: "22",
1379
- flavor_ref: "33",
1380
- username: "admin",
1381
- port: "2222",
1382
- server_name: "puppy",
1383
- server_name_prefix: "parsnip",
1384
- floating_ip_pool: "swimmers",
1385
- floating_ip: "11111",
1386
- network_ref: "0xCAFFE",
1387
- block_device_mapping: {
1388
- volume_id: "55",
1389
- volume_size: "5",
1390
- device_name: "vda",
1391
- delete_on_termination: true,
1392
- },
1393
- }
1394
- end
1395
- it "returns just the BDM config" do
1396
- expect(driver.send(:get_bdm, config)).to eq(config[:block_device_mapping])
1397
- end
1398
- end
1399
-
1400
- describe "#config_server_name" do
1401
- let(:config) do
1402
- {
1403
- server_name_prefix: "parsnip",
1404
- }
1405
- end
1406
-
1407
- it "returns random string prefixed by servername_prefix attribute" do
1408
- expect(driver.send(:config_server_name)).to include("parsnip")
1409
- end
1410
- end
1411
- end