vagrant-openstack-provider 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/lib/vagrant-openstack-provider.rb +2 -31
  4. data/lib/vagrant-openstack-provider/action.rb +21 -7
  5. data/lib/vagrant-openstack-provider/action/abstract_action.rb +22 -0
  6. data/lib/vagrant-openstack-provider/action/connect_openstack.rb +19 -40
  7. data/lib/vagrant-openstack-provider/action/create_server.rb +10 -6
  8. data/lib/vagrant-openstack-provider/action/create_stack.rb +67 -0
  9. data/lib/vagrant-openstack-provider/action/delete_server.rb +28 -3
  10. data/lib/vagrant-openstack-provider/action/delete_stack.rb +72 -0
  11. data/lib/vagrant-openstack-provider/action/message.rb +4 -2
  12. data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +4 -2
  13. data/lib/vagrant-openstack-provider/action/read_state.rb +9 -4
  14. data/lib/vagrant-openstack-provider/action/resume.rb +4 -2
  15. data/lib/vagrant-openstack-provider/action/start_server.rb +4 -2
  16. data/lib/vagrant-openstack-provider/action/stop_server.rb +4 -2
  17. data/lib/vagrant-openstack-provider/action/suspend.rb +4 -2
  18. data/lib/vagrant-openstack-provider/action/sync_folders.rb +17 -13
  19. data/lib/vagrant-openstack-provider/action/wait_accessible.rb +5 -2
  20. data/lib/vagrant-openstack-provider/action/wait_active.rb +5 -3
  21. data/lib/vagrant-openstack-provider/action/wait_stop.rb +5 -3
  22. data/lib/vagrant-openstack-provider/catalog/openstack_catalog.rb +66 -0
  23. data/lib/vagrant-openstack-provider/client/domain.rb +41 -1
  24. data/lib/vagrant-openstack-provider/client/glance.rb +63 -0
  25. data/lib/vagrant-openstack-provider/client/heat.rb +50 -0
  26. data/lib/vagrant-openstack-provider/client/http_utils.rb +18 -0
  27. data/lib/vagrant-openstack-provider/client/neutron.rb +9 -15
  28. data/lib/vagrant-openstack-provider/client/nova.rb +3 -3
  29. data/lib/vagrant-openstack-provider/client/openstack.rb +10 -0
  30. data/lib/vagrant-openstack-provider/command/abstract_command.rb +7 -0
  31. data/lib/vagrant-openstack-provider/command/image_list.rb +12 -2
  32. data/lib/vagrant-openstack-provider/command/main.rb +1 -0
  33. data/lib/vagrant-openstack-provider/command/network_list.rb +3 -3
  34. data/lib/vagrant-openstack-provider/command/subnet_list.rb +25 -0
  35. data/lib/vagrant-openstack-provider/config.rb +78 -7
  36. data/lib/vagrant-openstack-provider/config_resolver.rb +36 -5
  37. data/lib/vagrant-openstack-provider/errors.rb +30 -2
  38. data/lib/vagrant-openstack-provider/logging.rb +39 -0
  39. data/lib/vagrant-openstack-provider/version.rb +1 -1
  40. data/locales/en.yml +107 -4
  41. data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +255 -8
  42. data/spec/vagrant-openstack-provider/action/create_server_spec.rb +6 -1
  43. data/spec/vagrant-openstack-provider/action/create_stack_spec.rb +97 -0
  44. data/spec/vagrant-openstack-provider/action/delete_server_spec.rb +34 -6
  45. data/spec/vagrant-openstack-provider/action/delete_stack_spec.rb +64 -0
  46. data/spec/vagrant-openstack-provider/action/read_state_spec.rb +13 -1
  47. data/spec/vagrant-openstack-provider/action/sync_folders_spec.rb +1 -0
  48. data/spec/vagrant-openstack-provider/action/wait_active_spec.rb +1 -1
  49. data/spec/vagrant-openstack-provider/action/wait_stop_spec.rb +1 -1
  50. data/spec/vagrant-openstack-provider/client/glance_spec.rb +128 -0
  51. data/spec/vagrant-openstack-provider/client/heat_spec.rb +124 -0
  52. data/spec/vagrant-openstack-provider/client/neutron_spec.rb +33 -1
  53. data/spec/vagrant-openstack-provider/client/nova_spec.rb +2 -2
  54. data/spec/vagrant-openstack-provider/command/image_list_spec.rb +75 -23
  55. data/spec/vagrant-openstack-provider/command/subnet_list_spec.rb +46 -0
  56. data/spec/vagrant-openstack-provider/config_resolver_spec.rb +85 -19
  57. data/spec/vagrant-openstack-provider/config_spec.rb +177 -1
  58. data/spec/vagrant-openstack-provider/spec_helper.rb +3 -0
  59. metadata +20 -2
@@ -87,6 +87,38 @@ describe VagrantPlugins::Openstack::NeutronClient do
87
87
  end
88
88
  end
89
89
 
90
+ describe 'get_subnets' do
91
+ context 'with token' do
92
+ it 'returns all available subnets' do
93
+
94
+ stub_request(:get, 'http://neutron/subnets')
95
+ .with(
96
+ headers:
97
+ {
98
+ 'Accept' => 'application/json',
99
+ 'X-Auth-Token' => '123456'
100
+ })
101
+ .to_return(
102
+ status: 200,
103
+ body: '
104
+ {
105
+ "subnets": [
106
+ { "id": "subnet-01", "name": "Subnet 1", "cidr": "192.168.1.0/24", "enable_dhcp": true, "network_id": "net-01" },
107
+ { "id": "subnet-02", "name": "Subnet 2", "cidr": "192.168.2.0/24", "enable_dhcp": false, "network_id": "net-01" },
108
+ { "id": "subnet-03", "name": "Subnet 3", "cidr": "192.168.100.0/24", "enable_dhcp": true, "network_id": "net-02" }
109
+ ]
110
+ }
111
+ ')
112
+
113
+ networks = @neutron_client.get_subnets(env)
114
+
115
+ expect(networks).to eq [Subnet.new('subnet-01', 'Subnet 1', '192.168.1.0/24', true, 'net-01'),
116
+ Subnet.new('subnet-02', 'Subnet 2', '192.168.2.0/24', false, 'net-01'),
117
+ Subnet.new('subnet-03', 'Subnet 3', '192.168.100.0/24', true, 'net-02')]
118
+ end
119
+ end
120
+ end
121
+
90
122
  describe 'get_api_version_list' do
91
123
  context 'basic' do
92
124
  it 'returns version list' do
@@ -118,7 +150,7 @@ describe VagrantPlugins::Openstack::NeutronClient do
118
150
  }
119
151
  ]}')
120
152
 
121
- versions = @neutron_client.get_api_version_list(env)
153
+ versions = @neutron_client.get_api_version_list(:network)
122
154
 
123
155
  expect(versions.size).to eq(2)
124
156
  end
@@ -590,7 +590,7 @@ describe VagrantPlugins::Openstack::NovaClient do
590
590
  ]
591
591
  }')
592
592
 
593
- expect { @nova_client.add_floating_ip(env, 'o1o2o3', '1.2.3.4') }.to raise_error(RuntimeError)
593
+ expect { @nova_client.add_floating_ip(env, 'o1o2o3', '1.2.3.4') }.to raise_error(Errors::FloatingIPAlreadyAssigned)
594
594
  end
595
595
  end
596
596
 
@@ -616,7 +616,7 @@ describe VagrantPlugins::Openstack::NovaClient do
616
616
  ]
617
617
  }')
618
618
 
619
- expect { @nova_client.add_floating_ip(env, 'o1o2o3', '1.2.3.4') }.to raise_error(RuntimeError)
619
+ expect { @nova_client.add_floating_ip(env, 'o1o2o3', '1.2.3.4') }.to raise_error(Errors::FloatingIPNotAvailable)
620
620
  end
621
621
  end
622
622
  end
@@ -1,40 +1,61 @@
1
1
  require 'vagrant-openstack-provider/spec_helper'
2
2
 
3
3
  describe VagrantPlugins::Openstack::Command::ImageList do
4
- describe 'cmd' do
5
4
 
6
- let(:nova) do
7
- double('nova').tap do |nova|
8
- nova.stub(:get_all_images) do
9
- [
10
- Item.new('0001', 'ubuntu'),
11
- Item.new('0002', 'centos'),
12
- Item.new('0003', 'debian')
13
- ]
14
- end
5
+ let(:nova) do
6
+ double('nova').tap do |nova|
7
+ nova.stub(:get_all_images) do
8
+ [
9
+ Image.new('0001', 'ubuntu'),
10
+ Image.new('0002', 'centos'),
11
+ Image.new('0003', 'debian')
12
+ ]
15
13
  end
16
14
  end
15
+ end
17
16
 
18
- let(:env) do
19
- Hash.new.tap do |env|
20
- env[:ui] = double('ui')
21
- env[:ui].stub(:info).with(anything)
22
- env[:openstack_client] = double
23
- env[:openstack_client].stub(:nova) { nova }
17
+ let(:glance) do
18
+ double('nova').tap do |nova|
19
+ nova.stub(:get_all_images) do
20
+ [
21
+ Image.new('0001', 'ubuntu', 'public', 700 * 1024 * 1024, 1, 10),
22
+ Image.new('0002', 'centos', 'private', 800 * 1024 * 1024, 2, 20),
23
+ Image.new('0003', 'debian', 'shared', 900 * 1024 * 1024, 4, 30)
24
+ ]
24
25
  end
25
26
  end
27
+ end
26
28
 
27
- before :each do
28
- @image_list_cmd = VagrantPlugins::Openstack::Command::ImageList.new(['--'], env)
29
+ let(:env) do
30
+ Hash.new.tap do |env|
31
+ env[:ui] = double('ui')
32
+ env[:ui].stub(:info).with(anything)
33
+ env[:openstack_client] = double
34
+ env[:openstack_client].stub(:nova) { nova }
35
+ env[:openstack_client].stub(:glance) { glance }
29
36
  end
37
+ end
30
38
 
31
- it 'prints image list from server' do
39
+ before :each do
40
+ @image_list_cmd = VagrantPlugins::Openstack::Command::ImageList.new(['--'], env)
41
+ end
42
+
43
+ describe 'cmd' do
44
+ context 'when glance is not available' do
45
+
46
+ let(:session) do
47
+ double('session').tap do |s|
48
+ s.stub(:endpoints) { {} }
49
+ end
50
+ end
32
51
 
33
- allow(@image_list_cmd).to receive(:with_target_vms).and_return(nil)
52
+ it 'prints image list with only the id and the name' do
34
53
 
35
- nova.should_receive(:get_all_images).with(env)
54
+ env[:openstack_client].stub(:session) { session }
55
+ allow(@image_list_cmd).to receive(:with_target_vms).and_return(nil)
56
+ nova.should_receive(:get_all_images).with(env)
36
57
 
37
- expect(env[:ui]).to receive(:info).with('
58
+ expect(env[:ui]).to receive(:info).with('
38
59
  +------+--------+
39
60
  | Id | Name |
40
61
  +------+--------+
@@ -42,7 +63,38 @@ describe VagrantPlugins::Openstack::Command::ImageList do
42
63
  | 0002 | centos |
43
64
  | 0003 | debian |
44
65
  +------+--------+')
45
- @image_list_cmd.cmd('image-list', [], env)
66
+ @image_list_cmd.cmd('image-list', [], env)
67
+ end
68
+ end
69
+
70
+ context 'when glance is available' do
71
+
72
+ let(:session) do
73
+ double('session').tap do |s|
74
+ s.stub(:endpoints) do
75
+ {
76
+ image: 'http://glance'
77
+ }
78
+ end
79
+ end
80
+ end
81
+
82
+ it 'prints image list with id, name and details' do
83
+
84
+ env[:openstack_client].stub(:session) { session }
85
+ allow(@image_list_cmd).to receive(:with_target_vms).and_return(nil)
86
+ glance.should_receive(:get_all_images).with(env)
87
+
88
+ expect(env[:ui]).to receive(:info).with('
89
+ +------+--------+------------+-----------+--------------+---------------+
90
+ | Id | Name | Visibility | Size (Mo) | Min RAM (Go) | Min Disk (Go) |
91
+ +------+--------+------------+-----------+--------------+---------------+
92
+ | 0001 | ubuntu | public | 700 | 1 | 10 |
93
+ | 0002 | centos | private | 800 | 2 | 20 |
94
+ | 0003 | debian | shared | 900 | 4 | 30 |
95
+ +------+--------+------------+-----------+--------------+---------------+')
96
+ @image_list_cmd.cmd('image-list', [], env)
97
+ end
46
98
  end
47
99
  end
48
100
  end
@@ -0,0 +1,46 @@
1
+ require 'vagrant-openstack-provider/spec_helper'
2
+
3
+ describe VagrantPlugins::Openstack::Command::SubnetList do
4
+ describe 'cmd' do
5
+
6
+ let(:neutron) do
7
+ double('neutron').tap do |neutron|
8
+ neutron.stub(:get_subnets) do
9
+ [
10
+ Subnet.new('subnet-01', 'Subnet 1', '192.168.1.0/24', true, 'net-01'),
11
+ Subnet.new('subnet-02', 'Subnet 2', '192.168.2.0/24', false, 'net-01'),
12
+ Subnet.new('subnet-03', 'Subnet 3', '192.168.100.0/24', true, 'net-02')
13
+ ]
14
+ end
15
+ end
16
+ end
17
+
18
+ let(:env) do
19
+ Hash.new.tap do |env|
20
+ env[:ui] = double('ui')
21
+ env[:ui].stub(:info).with(anything)
22
+ env[:openstack_client] = double
23
+ env[:openstack_client].stub(:neutron) { neutron }
24
+ end
25
+ end
26
+
27
+ before :each do
28
+ @subnet_list_cmd = VagrantPlugins::Openstack::Command::SubnetList.new(nil, env)
29
+ end
30
+
31
+ it 'prints subnet list from server' do
32
+ neutron.should_receive(:get_subnets).with(env)
33
+
34
+ expect(env[:ui]).to receive(:info).with('
35
+ +-----------+----------+------------------+-------+------------+
36
+ | Id | Name | CIDR | DHCP | Network Id |
37
+ +-----------+----------+------------------+-------+------------+
38
+ | subnet-01 | Subnet 1 | 192.168.1.0/24 | true | net-01 |
39
+ | subnet-02 | Subnet 2 | 192.168.2.0/24 | false | net-01 |
40
+ | subnet-03 | Subnet 3 | 192.168.100.0/24 | true | net-02 |
41
+ +-----------+----------+------------------+-------+------------+')
42
+
43
+ @subnet_list_cmd.cmd('subnet-list', [], env)
44
+ end
45
+ end
46
+ end
@@ -25,16 +25,6 @@ describe VagrantPlugins::Openstack::ConfigResolver do
25
25
 
26
26
  let(:neutron) do
27
27
  double('neutron').tap do |neutron|
28
- neutron.stub(:get_private_networks).with(anything) do
29
- [Item.new('001', 'net-01'),
30
- Item.new('002', 'net-02'),
31
- Item.new('003', 'net-03'),
32
- Item.new('004', 'net-04'),
33
- Item.new('005', 'net-05'),
34
- Item.new('006', 'net-06'),
35
- Item.new('007', 'net-07-08'),
36
- Item.new('008', 'net-07-08')]
37
- end
38
28
  neutron.stub(:get_all_networks).with(anything) do
39
29
  [Item.new('001', 'net-01'),
40
30
  Item.new('002', 'net-02'),
@@ -223,9 +213,9 @@ describe VagrantPlugins::Openstack::ConfigResolver do
223
213
  end
224
214
  end
225
215
 
226
- context 'with config.floating_pool specified' do
227
- context 'if any ip in the same pool is available' do
228
- context 'with config.floating_pool_always_allocate true' do
216
+ context 'with only one config.floating_ip_pool specified' do
217
+ context 'if an ip in the same pool is available' do
218
+ context 'with config.floating_ip_pool_always_allocate true' do
229
219
  it 'allocate a new floating_ip from the pool' do
230
220
  config.stub(:floating_ip_pool_always_allocate) { true }
231
221
  nova.stub(:get_all_floating_ips).with(anything) do
@@ -233,21 +223,21 @@ describe VagrantPlugins::Openstack::ConfigResolver do
233
223
  FloatingIP.new('80.81.82.83', 'pool-1', nil)]
234
224
  end
235
225
  nova.stub(:allocate_floating_ip).with(env, 'pool-1') do
236
- FloatingIP.new('80.81.82.84', 'pool-1', nil)
226
+ FloatingIP.new('80.81.82.85', 'pool-1', nil)
237
227
  end
238
- config.stub(:floating_ip_pool) { 'pool-1' }
239
- @action.resolve_floating_ip(env).should eq('80.81.82.84')
228
+ config.stub(:floating_ip_pool) { ['pool-1'] }
229
+ @action.resolve_floating_ip(env).should eq('80.81.82.85')
240
230
  end
241
231
  end
242
232
 
243
- context 'with config.floating_pool_always_allocate false' do
233
+ context 'with config.floating_ip_pool_always_allocate false' do
244
234
  it 'return one of the available ips' do
245
235
  config.stub(:floating_ip_pool_always_allocate) { false }
246
236
  nova.stub(:get_all_floating_ips).with(anything) do
247
237
  [FloatingIP.new('80.81.82.84', 'pool-1', '1234'),
248
238
  FloatingIP.new('80.81.82.83', 'pool-1', nil)]
249
239
  end
250
- config.stub(:floating_ip_pool) { 'pool-1' }
240
+ config.stub(:floating_ip_pool) { ['pool-1'] }
251
241
  @action.resolve_floating_ip(env).should eq('80.81.82.83')
252
242
  end
253
243
  end
@@ -261,12 +251,88 @@ describe VagrantPlugins::Openstack::ConfigResolver do
261
251
  nova.stub(:allocate_floating_ip).with(env, 'pool-1') do
262
252
  FloatingIP.new('80.81.82.84', 'pool-1', nil)
263
253
  end
264
- config.stub(:floating_ip_pool) { 'pool-1' }
254
+ config.stub(:floating_ip_pool) { ['pool-1'] }
265
255
  @action.resolve_floating_ip(env).should eq('80.81.82.84')
266
256
  end
267
257
  end
268
258
  end
269
259
 
260
+ context 'with several floating_ip_pool defined' do
261
+ context 'if an ip in a pool is available' do
262
+ context 'with config.floating_ip_pool_always_allocate true' do
263
+ it 'allocate a new floating_ip from the first pool defined' do
264
+ config.stub(:floating_ip_pool_always_allocate) { true }
265
+ nova.stub(:get_all_floating_ips).with(anything) do
266
+ [FloatingIP.new('80.81.82.84', 'pool-1', '1234'),
267
+ FloatingIP.new('80.81.82.83', 'pool-1', nil),
268
+ FloatingIP.new('80.81.82.82', 'pool-2', '5678')]
269
+ end
270
+ nova.stub(:allocate_floating_ip).with(env, 'pool-1') do
271
+ FloatingIP.new('80.81.82.85', 'pool-1', nil)
272
+ end
273
+ config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
274
+ @action.resolve_floating_ip(env).should eq('80.81.82.85')
275
+ end
276
+ end
277
+
278
+ context 'with config.floating_ip_pool_always_allocate false' do
279
+ it 'return one of the available ips' do
280
+ config.stub(:floating_ip_pool_always_allocate) { false }
281
+ nova.stub(:get_all_floating_ips).with(anything) do
282
+ [FloatingIP.new('80.81.82.84', 'pool-1', '1234'),
283
+ FloatingIP.new('80.81.82.83', 'pool-2', nil)]
284
+ end
285
+ config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
286
+ @action.resolve_floating_ip(env).should eq('80.81.82.83')
287
+ end
288
+ end
289
+ end
290
+
291
+ context 'if no ip in the pools is available' do
292
+ context 'if allocate an ip in first pool is possible' do
293
+ it 'allocate a new floating_ip from first pool' do
294
+ nova.stub(:get_all_floating_ips).with(anything) do
295
+ [FloatingIP.new('80.81.82.83', 'pool-1', '1234'),
296
+ FloatingIP.new('80.81.82.82', 'pool-2', '5678')]
297
+ end
298
+ nova.stub(:allocate_floating_ip).with(env, 'pool-1') do
299
+ FloatingIP.new('80.81.82.84', 'pool-1', nil)
300
+ end
301
+ config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
302
+ @action.resolve_floating_ip(env).should eq('80.81.82.84')
303
+ end
304
+ end
305
+
306
+ context 'if allocate an ip in first pool is not possible' do
307
+ it 'allocate a new floating_ip from second pool' do
308
+ nova.stub(:get_all_floating_ips).with(anything) do
309
+ [FloatingIP.new('80.81.82.83', 'pool-1', '1234'),
310
+ FloatingIP.new('80.81.82.82', 'pool-2', '5678')]
311
+ end
312
+ nova.stub(:allocate_floating_ip).with(env, 'pool-1').and_raise Errors::VagrantOpenstackError, message: 'error', code: 404
313
+ nova.stub(:allocate_floating_ip).with(env, 'pool-2') do
314
+ FloatingIP.new('80.81.82.84', 'pool-2', nil)
315
+ end
316
+ config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
317
+ @action.resolve_floating_ip(env).should eq('80.81.82.84')
318
+ end
319
+ end
320
+
321
+ context 'if allocate an ip in either first and second pool is not possible' do
322
+ it 'shoud raise an error', :simon do
323
+ nova.stub(:get_all_floating_ips).with(anything) do
324
+ [FloatingIP.new('80.81.82.83', 'pool-1', '1234'),
325
+ FloatingIP.new('80.81.82.82', 'pool-2', '5678')]
326
+ end
327
+ nova.stub(:allocate_floating_ip).with(env, 'pool-1').and_raise Errors::VagrantOpenstackError, message: 'error', code: 404
328
+ nova.stub(:allocate_floating_ip).with(env, 'pool-2').and_raise Errors::VagrantOpenstackError, message: 'error', code: 404
329
+ config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
330
+ expect { @action.resolve_floating_ip(env) }.to raise_error(Errors::VagrantOpenstackError)
331
+ end
332
+ end
333
+ end
334
+ end
335
+
270
336
  context 'with neither floating_ip nor floating_ip_pool' do
271
337
  it 'fails with an UnableToResolveFloatingIP error' do
272
338
  config.stub(:floating_ip) { nil }
@@ -13,6 +13,7 @@ describe VagrantPlugins::Openstack::Config do
13
13
  its(:password) { should be_nil }
14
14
  its(:openstack_compute_url) { should be_nil }
15
15
  its(:openstack_auth_url) { should be_nil }
16
+ its(:openstack_orchestration_url) { should be_nil }
16
17
  its(:flavor) { should be_nil }
17
18
  its(:image) { should be_nil }
18
19
  its(:server_name) { should be_nil }
@@ -43,6 +44,8 @@ describe VagrantPlugins::Openstack::Config do
43
44
  :floating_ip_pool_always_allocate,
44
45
  :scheduler_hints,
45
46
  :security_groups,
47
+ :openstack_orchestration_url,
48
+ :stacks,
46
49
  :user_data,
47
50
  :metadata,
48
51
  :availability_zone,
@@ -62,6 +65,146 @@ describe VagrantPlugins::Openstack::Config do
62
65
  end
63
66
  end
64
67
 
68
+ describe 'merge' do
69
+ let(:foo_class) do
70
+ Class.new(described_class) do
71
+ attr_accessor :networks
72
+ attr_accessor :floating_ip_pool
73
+ end
74
+ end
75
+
76
+ subject { foo_class.new }
77
+
78
+ context 'with original network not empty' do
79
+ it 'should overidde the config' do
80
+ one = foo_class.new
81
+ one.networks = ['foo']
82
+
83
+ two = foo_class.new
84
+ two.networks = ['bar']
85
+
86
+ result = one.merge(two)
87
+ result.networks.should =~ ['bar']
88
+ end
89
+ end
90
+
91
+ context 'with original network empty' do
92
+ it 'should add the network to the existing list' do
93
+ one = foo_class.new
94
+ one.networks = []
95
+
96
+ two = foo_class.new
97
+ two.networks = ['bar']
98
+
99
+ result = one.merge(two)
100
+ result.networks.should =~ ['bar']
101
+ end
102
+ end
103
+
104
+ context 'with original network not empty and new empty' do
105
+ it 'should keep the original network' do
106
+ one = foo_class.new
107
+ one.networks = ['foo']
108
+
109
+ two = foo_class.new
110
+ two.networks = []
111
+
112
+ result = one.merge(two)
113
+ result.networks.should =~ ['foo']
114
+ end
115
+ end
116
+
117
+ context 'with original floating_ip_pool as string' do
118
+ context 'and new as empty array' do
119
+ it 'should put original string in a single entry array' do
120
+ one = foo_class.new
121
+ one.floating_ip_pool = 'pool'
122
+
123
+ two = foo_class.new
124
+ two.floating_ip_pool = []
125
+
126
+ result = one.merge(two)
127
+ result.floating_ip_pool.should =~ ['pool']
128
+ end
129
+ end
130
+ context 'and new as empty string' do
131
+ it 'should put original string in a single entry array' do
132
+ one = foo_class.new
133
+ one.floating_ip_pool = 'pool'
134
+
135
+ two = foo_class.new
136
+ two.floating_ip_pool = ''
137
+
138
+ result = one.merge(two)
139
+ result.floating_ip_pool.should =~ ['']
140
+ end
141
+ end
142
+ context 'and new as string' do
143
+ it 'should put new string in a single entry array' do
144
+ one = foo_class.new
145
+ one.floating_ip_pool = 'pool'
146
+
147
+ two = foo_class.new
148
+ two.floating_ip_pool = 'new-pool'
149
+
150
+ result = one.merge(two)
151
+ result.floating_ip_pool.should =~ ['new-pool']
152
+ end
153
+ end
154
+ context 'and new as array' do
155
+ it 'should put new array' do
156
+ one = foo_class.new
157
+ one.floating_ip_pool = 'pool'
158
+
159
+ two = foo_class.new
160
+ two.floating_ip_pool = %w(pool-1 pool-2)
161
+
162
+ result = one.merge(two)
163
+ result.floating_ip_pool.should =~ %w(pool-1 pool-2)
164
+ end
165
+ end
166
+ end
167
+
168
+ context 'with original floating_ip_pool as array' do
169
+ context 'and new empty' do
170
+ it 'should put original array' do
171
+ one = foo_class.new
172
+ one.floating_ip_pool = %w(pool-1 pool-2)
173
+
174
+ two = foo_class.new
175
+ two.floating_ip_pool = []
176
+
177
+ result = one.merge(two)
178
+ result.floating_ip_pool.should =~ %w(pool-1 pool-2)
179
+ end
180
+ end
181
+ context 'and new as string' do
182
+ it 'should put new string in a single entry array' do
183
+ one = foo_class.new
184
+ one.floating_ip_pool = %w(pool-1 pool-2)
185
+
186
+ two = foo_class.new
187
+ two.floating_ip_pool = 'pool'
188
+
189
+ result = one.merge(two)
190
+ result.floating_ip_pool.should =~ ['pool']
191
+ end
192
+ end
193
+ context 'and new as array' do
194
+ it 'should put new array' do
195
+ one = foo_class.new
196
+ one.floating_ip_pool = %w(pool-1 pool-2)
197
+
198
+ two = foo_class.new
199
+ two.floating_ip_pool = %w(new-pool-1 new-pool-2)
200
+
201
+ result = one.merge(two)
202
+ result.floating_ip_pool.should =~ %w(new-pool-1 new-pool-2)
203
+ end
204
+ end
205
+ end
206
+ end
207
+
65
208
  describe 'validation' do
66
209
  let(:machine) { double('machine') }
67
210
  let(:validation_errors) { subject.validate(machine)['Openstack Provider'] }
@@ -88,6 +231,39 @@ describe VagrantPlugins::Openstack::Config do
88
231
  end
89
232
  end
90
233
 
234
+ context 'with invalid stack' do
235
+ it 'should raise an error' do
236
+ subject.stacks = [
237
+ {
238
+ name: 'test1'
239
+ }
240
+ ]
241
+ I18n.should_receive(:t).with('vagrant_openstack.config.invalid_stack').and_return error_message
242
+ validation_errors.first.should == error_message
243
+ end
244
+
245
+ it 'should raise an error' do
246
+ subject.stacks = [
247
+ {
248
+ name: 'test1',
249
+ tempslate: 'tes1'
250
+ }
251
+ ]
252
+ I18n.should_receive(:t).with('vagrant_openstack.config.invalid_stack').and_return error_message
253
+ validation_errors.first.should == error_message
254
+ end
255
+
256
+ it 'should not raise an error' do
257
+ subject.stacks = [
258
+ {
259
+ name: 'test1',
260
+ template: 'tes1'
261
+ }
262
+ ]
263
+ expect(validation_errors).to be_empty
264
+ end
265
+ end
266
+
91
267
  context 'with invalid key' do
92
268
  it 'should raise an error' do
93
269
  subject.nonsense1 = true
@@ -153,7 +329,7 @@ describe VagrantPlugins::Openstack::Config do
153
329
  end
154
330
  end
155
331
 
156
- [:openstack_compute_url, :openstack_auth_url].each do |url|
332
+ [:openstack_compute_url, :openstack_auth_url, :openstack_orchestration_url].each do |url|
157
333
  context "the #{url}" do
158
334
  it 'should not validate if the URL is invalid' do
159
335
  subject.send "#{url}=", 'baz'