kitchen-openstack 3.6.1 → 6.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/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