vagrant-openstack-illuin-provider 0.12.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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rubocop.yml +40 -0
- data/CHANGELOG.md +282 -0
- data/Gemfile +18 -0
- data/RELEASE.md +15 -0
- data/Rakefile +25 -0
- data/Vagrantfile +20 -0
- data/dummy.box +0 -0
- data/example_box/README.md +13 -0
- data/example_box/metadata.json +3 -0
- data/functional_tests/Vagrantfile +58 -0
- data/functional_tests/keys/vagrant-openstack +27 -0
- data/functional_tests/keys/vagrant-openstack.pub +1 -0
- data/functional_tests/run_tests.sh +142 -0
- data/lib/vagrant-openstack-illuin-provider.rb +29 -0
- data/lib/vagrant-openstack-illuin-provider/action.rb +344 -0
- data/lib/vagrant-openstack-illuin-provider/action/abstract_action.rb +22 -0
- data/lib/vagrant-openstack-illuin-provider/action/connect_openstack.rb +60 -0
- data/lib/vagrant-openstack-illuin-provider/action/create_server.rb +187 -0
- data/lib/vagrant-openstack-illuin-provider/action/create_stack.rb +76 -0
- data/lib/vagrant-openstack-illuin-provider/action/delete_server.rb +53 -0
- data/lib/vagrant-openstack-illuin-provider/action/delete_stack.rb +73 -0
- data/lib/vagrant-openstack-illuin-provider/action/message.rb +19 -0
- data/lib/vagrant-openstack-illuin-provider/action/provision.rb +60 -0
- data/lib/vagrant-openstack-illuin-provider/action/read_ssh_info.rb +74 -0
- data/lib/vagrant-openstack-illuin-provider/action/read_state.rb +43 -0
- data/lib/vagrant-openstack-illuin-provider/action/resume.rb +24 -0
- data/lib/vagrant-openstack-illuin-provider/action/snapshot_cleanup.rb +32 -0
- data/lib/vagrant-openstack-illuin-provider/action/snapshot_delete.rb +32 -0
- data/lib/vagrant-openstack-illuin-provider/action/snapshot_list.rb +22 -0
- data/lib/vagrant-openstack-illuin-provider/action/snapshot_restore.rb +29 -0
- data/lib/vagrant-openstack-illuin-provider/action/snapshot_save.rb +51 -0
- data/lib/vagrant-openstack-illuin-provider/action/start_server.rb +24 -0
- data/lib/vagrant-openstack-illuin-provider/action/stop_server.rb +25 -0
- data/lib/vagrant-openstack-illuin-provider/action/suspend.rb +24 -0
- data/lib/vagrant-openstack-illuin-provider/action/sync_folders.rb +138 -0
- data/lib/vagrant-openstack-illuin-provider/action/wait_active.rb +33 -0
- data/lib/vagrant-openstack-illuin-provider/action/wait_stop.rb +33 -0
- data/lib/vagrant-openstack-illuin-provider/cap/snapshot_list.rb +15 -0
- data/lib/vagrant-openstack-illuin-provider/catalog/openstack_catalog.rb +90 -0
- data/lib/vagrant-openstack-illuin-provider/client/cinder.rb +39 -0
- data/lib/vagrant-openstack-illuin-provider/client/domain.rb +163 -0
- data/lib/vagrant-openstack-illuin-provider/client/glance.rb +65 -0
- data/lib/vagrant-openstack-illuin-provider/client/heat.rb +49 -0
- data/lib/vagrant-openstack-illuin-provider/client/http_utils.rb +116 -0
- data/lib/vagrant-openstack-illuin-provider/client/keystone.rb +128 -0
- data/lib/vagrant-openstack-illuin-provider/client/neutron.rb +48 -0
- data/lib/vagrant-openstack-illuin-provider/client/nova.rb +303 -0
- data/lib/vagrant-openstack-illuin-provider/client/openstack.rb +59 -0
- data/lib/vagrant-openstack-illuin-provider/client/request_logger.rb +23 -0
- data/lib/vagrant-openstack-illuin-provider/client/rest_utils.rb +28 -0
- data/lib/vagrant-openstack-illuin-provider/command/abstract_command.rb +51 -0
- data/lib/vagrant-openstack-illuin-provider/command/flavor_list.rb +24 -0
- data/lib/vagrant-openstack-illuin-provider/command/floatingip_list.rb +32 -0
- data/lib/vagrant-openstack-illuin-provider/command/image_list.rb +29 -0
- data/lib/vagrant-openstack-illuin-provider/command/main.rb +52 -0
- data/lib/vagrant-openstack-illuin-provider/command/network_list.rb +25 -0
- data/lib/vagrant-openstack-illuin-provider/command/openstack_command.rb +16 -0
- data/lib/vagrant-openstack-illuin-provider/command/reset.rb +20 -0
- data/lib/vagrant-openstack-illuin-provider/command/subnet_list.rb +22 -0
- data/lib/vagrant-openstack-illuin-provider/command/utils.rb +22 -0
- data/lib/vagrant-openstack-illuin-provider/command/volume_list.rb +25 -0
- data/lib/vagrant-openstack-illuin-provider/config.rb +505 -0
- data/lib/vagrant-openstack-illuin-provider/config/http.rb +39 -0
- data/lib/vagrant-openstack-illuin-provider/config_resolver.rb +334 -0
- data/lib/vagrant-openstack-illuin-provider/errors.rb +187 -0
- data/lib/vagrant-openstack-illuin-provider/logging.rb +39 -0
- data/lib/vagrant-openstack-illuin-provider/plugin.rb +58 -0
- data/lib/vagrant-openstack-illuin-provider/provider.rb +50 -0
- data/lib/vagrant-openstack-illuin-provider/utils.rb +81 -0
- data/lib/vagrant-openstack-illuin-provider/version.rb +15 -0
- data/lib/vagrant-openstack-illuin-provider/version_checker.rb +76 -0
- data/locales/en.yml +412 -0
- data/spec/vagrant-openstack-illuin-provider/action/connect_openstack_spec.rb +770 -0
- data/spec/vagrant-openstack-illuin-provider/action/create_server_spec.rb +260 -0
- data/spec/vagrant-openstack-illuin-provider/action/create_stack_spec.rb +99 -0
- data/spec/vagrant-openstack-illuin-provider/action/delete_server_spec.rb +89 -0
- data/spec/vagrant-openstack-illuin-provider/action/delete_stack_spec.rb +63 -0
- data/spec/vagrant-openstack-illuin-provider/action/message_spec.rb +33 -0
- data/spec/vagrant-openstack-illuin-provider/action/provision_spec.rb +97 -0
- data/spec/vagrant-openstack-illuin-provider/action/read_ssh_info_spec.rb +202 -0
- data/spec/vagrant-openstack-illuin-provider/action/read_state_spec.rb +81 -0
- data/spec/vagrant-openstack-illuin-provider/action/resume_server_spec.rb +49 -0
- data/spec/vagrant-openstack-illuin-provider/action/start_server_spec.rb +49 -0
- data/spec/vagrant-openstack-illuin-provider/action/stop_server_spec.rb +49 -0
- data/spec/vagrant-openstack-illuin-provider/action/suspend_server_spec.rb +49 -0
- data/spec/vagrant-openstack-illuin-provider/action/sync_folders_spec.rb +155 -0
- data/spec/vagrant-openstack-illuin-provider/action/wait_active_spec.rb +53 -0
- data/spec/vagrant-openstack-illuin-provider/action/wait_stop_spec.rb +53 -0
- data/spec/vagrant-openstack-illuin-provider/action_spec.rb +120 -0
- data/spec/vagrant-openstack-illuin-provider/client/cinder_spec.rb +129 -0
- data/spec/vagrant-openstack-illuin-provider/client/glance_spec.rb +145 -0
- data/spec/vagrant-openstack-illuin-provider/client/heat_spec.rb +130 -0
- data/spec/vagrant-openstack-illuin-provider/client/keystone_spec.rb +226 -0
- data/spec/vagrant-openstack-illuin-provider/client/neutron_spec.rb +173 -0
- data/spec/vagrant-openstack-illuin-provider/client/nova_spec.rb +760 -0
- data/spec/vagrant-openstack-illuin-provider/client/utils_spec.rb +176 -0
- data/spec/vagrant-openstack-illuin-provider/command/flavor_list_spec.rb +43 -0
- data/spec/vagrant-openstack-illuin-provider/command/floatingip_list_spec.rb +74 -0
- data/spec/vagrant-openstack-illuin-provider/command/image_list_spec.rb +95 -0
- data/spec/vagrant-openstack-illuin-provider/command/network_list_spec.rb +65 -0
- data/spec/vagrant-openstack-illuin-provider/command/reset_spec.rb +24 -0
- data/spec/vagrant-openstack-illuin-provider/command/subnet_list_spec.rb +45 -0
- data/spec/vagrant-openstack-illuin-provider/command/volume_list_spec.rb +40 -0
- data/spec/vagrant-openstack-illuin-provider/config_resolver_spec.rb +879 -0
- data/spec/vagrant-openstack-illuin-provider/config_spec.rb +416 -0
- data/spec/vagrant-openstack-illuin-provider/e2e_spec.rb.save +27 -0
- data/spec/vagrant-openstack-illuin-provider/provider_spec.rb +13 -0
- data/spec/vagrant-openstack-illuin-provider/spec_helper.rb +37 -0
- data/spec/vagrant-openstack-illuin-provider/utils_spec.rb +197 -0
- data/spec/vagrant-openstack-illuin-provider/version_checker_spec.rb +39 -0
- data/stackrc +25 -0
- data/vagrant-openstack-illuin-provider.gemspec +35 -0
- metadata +379 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'vagrant-openstack-illuin-provider/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe VagrantPlugins::Openstack::Command::Reset do
|
|
4
|
+
describe 'cmd' do
|
|
5
|
+
let(:env) do
|
|
6
|
+
{}.tap do |env|
|
|
7
|
+
env[:ui] = double('ui')
|
|
8
|
+
env[:ui].stub(:info).with(anything)
|
|
9
|
+
env[:machine] = double('machine')
|
|
10
|
+
env[:machine].stub(:data_dir) { '/my/data/dir' }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
before :each do
|
|
15
|
+
@reset_cmd = VagrantPlugins::Openstack::Command::Reset.new(nil, env)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'resets vagrant openstack machines' do
|
|
19
|
+
expect(env[:ui]).to receive(:info).with('Vagrant OpenStack Provider has been reset')
|
|
20
|
+
expect(FileUtils).to receive(:remove_dir).with('/my/data/dir')
|
|
21
|
+
@reset_cmd.cmd('reset', [], env)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'vagrant-openstack-illuin-provider/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe VagrantPlugins::Openstack::Command::SubnetList do
|
|
4
|
+
describe 'cmd' do
|
|
5
|
+
let(:neutron) do
|
|
6
|
+
double('neutron').tap do |neutron|
|
|
7
|
+
neutron.stub(:get_subnets) do
|
|
8
|
+
[
|
|
9
|
+
Subnet.new('subnet-01', 'Subnet 1', '192.168.1.0/24', true, 'net-01'),
|
|
10
|
+
Subnet.new('subnet-02', 'Subnet 2', '192.168.2.0/24', false, 'net-01'),
|
|
11
|
+
Subnet.new('subnet-03', 'Subnet 3', '192.168.100.0/24', true, 'net-02')
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
let(:env) do
|
|
18
|
+
{}.tap do |env|
|
|
19
|
+
env[:ui] = double('ui')
|
|
20
|
+
env[:ui].stub(:info).with(anything)
|
|
21
|
+
env[:openstack_client] = double
|
|
22
|
+
env[:openstack_client].stub(:neutron) { neutron }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
before :each do
|
|
27
|
+
@subnet_list_cmd = VagrantPlugins::Openstack::Command::SubnetList.new(nil, env)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'prints subnet list from server' do
|
|
31
|
+
neutron.should_receive(:get_subnets).with(env)
|
|
32
|
+
|
|
33
|
+
expect(env[:ui]).to receive(:info).with('
|
|
34
|
+
+-----------+----------+------------------+-------+------------+
|
|
35
|
+
| ID | Name | CIDR | DHCP | Network ID |
|
|
36
|
+
+-----------+----------+------------------+-------+------------+
|
|
37
|
+
| subnet-01 | Subnet 1 | 192.168.1.0/24 | true | net-01 |
|
|
38
|
+
| subnet-02 | Subnet 2 | 192.168.2.0/24 | false | net-01 |
|
|
39
|
+
| subnet-03 | Subnet 3 | 192.168.100.0/24 | true | net-02 |
|
|
40
|
+
+-----------+----------+------------------+-------+------------+')
|
|
41
|
+
|
|
42
|
+
@subnet_list_cmd.cmd('subnet-list', [], env)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'vagrant-openstack-illuin-provider/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe VagrantPlugins::Openstack::Command::VolumeList do
|
|
4
|
+
describe 'cmd' do
|
|
5
|
+
let(:cinder) do
|
|
6
|
+
double('cinder').tap do |cinder|
|
|
7
|
+
cinder.stub(:get_all_volumes) do
|
|
8
|
+
[Volume.new('987', 'vol-01', '2', 'available', 'true', nil, nil),
|
|
9
|
+
Volume.new('654', 'vol-02', '4', 'in-use', 'false', 'inst-01', '/dev/vdc')]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:env) do
|
|
15
|
+
{}.tap do |env|
|
|
16
|
+
env[:ui] = double('ui')
|
|
17
|
+
env[:ui].stub(:info).with(anything)
|
|
18
|
+
env[:openstack_client] = double
|
|
19
|
+
env[:openstack_client].stub(:cinder) { cinder }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
before :each do
|
|
24
|
+
@volume_list_cmd = VagrantPlugins::Openstack::Command::VolumeList.new(nil, env)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'prints volumes list from server' do
|
|
28
|
+
cinder.should_receive(:get_all_volumes).with(env)
|
|
29
|
+
expect(env[:ui]).to receive(:info).with('
|
|
30
|
+
+-----+--------+-----------+-----------+-------------------------------------+
|
|
31
|
+
| ID | Name | Size (Go) | Status | Attachment (instance ID and device) |
|
|
32
|
+
+-----+--------+-----------+-----------+-------------------------------------+
|
|
33
|
+
| 987 | vol-01 | 2 | available | |
|
|
34
|
+
| 654 | vol-02 | 4 | in-use | inst-01 (/dev/vdc) |
|
|
35
|
+
+-----+--------+-----------+-----------+-------------------------------------+')
|
|
36
|
+
|
|
37
|
+
@volume_list_cmd.cmd('volume-list', [], env)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,879 @@
|
|
|
1
|
+
require 'vagrant-openstack-illuin-provider/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe VagrantPlugins::Openstack::ConfigResolver do
|
|
4
|
+
let(:config) do
|
|
5
|
+
double('config').tap do |config|
|
|
6
|
+
config.stub(:tenant_name) { 'testTenant' }
|
|
7
|
+
config.stub(:server_name) { 'testName' }
|
|
8
|
+
config.stub(:floating_ip) { nil }
|
|
9
|
+
config.stub(:floating_ip_pool) { nil }
|
|
10
|
+
config.stub(:floating_ip_pool_always_allocate) { false }
|
|
11
|
+
config.stub(:keypair_name) { nil }
|
|
12
|
+
config.stub(:public_key_path) { nil }
|
|
13
|
+
config.stub(:networks) { nil }
|
|
14
|
+
config.stub(:volumes) { nil }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
let(:ssh_key) do
|
|
19
|
+
double('ssh_key').tap do |key|
|
|
20
|
+
key.stub(:ssh_public_key) { 'ssh public key' }
|
|
21
|
+
key.stub(:private_key) { 'private key' }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
let(:neutron) do
|
|
26
|
+
double('neutron').tap do |neutron|
|
|
27
|
+
neutron.stub(:get_all_networks).with(anything) do
|
|
28
|
+
[Item.new('001', 'net-01'),
|
|
29
|
+
Item.new('002', 'net-02'),
|
|
30
|
+
Item.new('003', 'net-03'),
|
|
31
|
+
Item.new('004', 'net-04'),
|
|
32
|
+
Item.new('005', 'net-05'),
|
|
33
|
+
Item.new('006', 'net-06'),
|
|
34
|
+
Item.new('007', 'net-07-08'),
|
|
35
|
+
Item.new('008', 'net-07-08')]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
let(:nova) do
|
|
41
|
+
double('nova').tap do |nova|
|
|
42
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
43
|
+
[FloatingIP.new('80.81.82.83', 'pool-1', nil), FloatingIP.new('30.31.32.33', 'pool-2', '1234')]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let(:cinder) do
|
|
49
|
+
double('cinder').tap do |cinder|
|
|
50
|
+
cinder.stub(:get_all_volumes).with(anything) do
|
|
51
|
+
[Volume.new('001', 'vol-01', '1', 'available', 'true', nil, nil),
|
|
52
|
+
Volume.new('002', 'vol-02', '2', 'available', 'true', nil, nil),
|
|
53
|
+
Volume.new('003', 'vol-03', '3', 'available', 'true', nil, nil),
|
|
54
|
+
Volume.new('004', 'vol-04', '4', 'available', 'false', nil, nil),
|
|
55
|
+
Volume.new('005', 'vol-05', '5', 'available', 'false', nil, nil),
|
|
56
|
+
Volume.new('006', 'vol-06', '6', 'available', 'false', nil, nil),
|
|
57
|
+
Volume.new('007', 'vol-07-08', '6', 'available', 'false', nil, nil),
|
|
58
|
+
Volume.new('008', 'vol-07-08', '6', 'available', 'false', nil, nil)]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
let(:session) do
|
|
64
|
+
double('session').tap do |s|
|
|
65
|
+
s.stub(:endpoints) do
|
|
66
|
+
{
|
|
67
|
+
identity: 'http://keystone',
|
|
68
|
+
compute: 'http://nova',
|
|
69
|
+
volume: 'http://cinder',
|
|
70
|
+
network: 'http://neutron'
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
let(:env) do
|
|
77
|
+
{}.tap do |env|
|
|
78
|
+
env[:ui] = double('ui')
|
|
79
|
+
env[:ui].stub(:info).with(anything)
|
|
80
|
+
env[:machine] = double('machine')
|
|
81
|
+
env[:machine].stub(:provider_config) { config }
|
|
82
|
+
env[:machine].stub(:data_dir) { '/data/dir' }
|
|
83
|
+
env[:machine].stub(:config) { machine_config }
|
|
84
|
+
env[:openstack_client] = double('openstack_client')
|
|
85
|
+
env[:openstack_client].stub(:neutron) { neutron }
|
|
86
|
+
env[:openstack_client].stub(:nova) { nova }
|
|
87
|
+
env[:openstack_client].stub(:cinder) { cinder }
|
|
88
|
+
env[:openstack_client].stub(:session) { session }
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
let(:ssh_config) do
|
|
93
|
+
double('ssh_config').tap do |config|
|
|
94
|
+
config.stub(:username) { nil }
|
|
95
|
+
config.stub(:port) { nil }
|
|
96
|
+
config.stub(:insert_key) { true }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
let(:machine_config) do
|
|
101
|
+
double('machine_config').tap do |config|
|
|
102
|
+
config.stub(:ssh) { ssh_config }
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
before :each do
|
|
107
|
+
ConfigResolver.send(:public, *ConfigResolver.private_instance_methods)
|
|
108
|
+
@action = ConfigResolver.new
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe 'resolve_ssh_username' do
|
|
112
|
+
context 'with machine.ssh.username' do
|
|
113
|
+
it 'returns machine.ssh.username' do
|
|
114
|
+
ssh_config.stub(:username) { 'machine ssh username' }
|
|
115
|
+
config.stub(:ssh_username) { nil }
|
|
116
|
+
expect(@action.resolve_ssh_username(env)).to eq('machine ssh username')
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
context 'with machine.ssh.username and config.ssh_username' do
|
|
120
|
+
it 'returns machine.ssh.username' do
|
|
121
|
+
ssh_config.stub(:username) { 'machine ssh username' }
|
|
122
|
+
config.stub(:ssh_username) { 'provider ssh username' }
|
|
123
|
+
expect(@action.resolve_ssh_username(env)).to eq('machine ssh username')
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
context 'with config.ssh_username' do
|
|
127
|
+
it 'returns config.ssh_username' do
|
|
128
|
+
ssh_config.stub(:username) { nil }
|
|
129
|
+
config.stub(:ssh_username) { 'provider ssh username' }
|
|
130
|
+
expect(@action.resolve_ssh_username(env)).to eq('provider ssh username')
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
context 'with no ssh username config' do
|
|
134
|
+
it 'fails' do
|
|
135
|
+
ssh_config.stub(:username) { nil }
|
|
136
|
+
config.stub(:ssh_username) { nil }
|
|
137
|
+
expect { @action.resolve_ssh_username(env) }.to raise_error(Errors::NoMatchingSshUsername)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe 'resolve_flavor' do
|
|
143
|
+
context 'with id' do
|
|
144
|
+
it 'returns the specified flavor' do
|
|
145
|
+
config.stub(:flavor) { 'fl-001' }
|
|
146
|
+
nova.stub(:get_all_flavors).with(anything) do
|
|
147
|
+
[Flavor.new('fl-001', 'flavor-01', 2, 1024, 10),
|
|
148
|
+
Flavor.new('fl-002', 'flavor-02', 4, 2048, 50)]
|
|
149
|
+
end
|
|
150
|
+
@action.resolve_flavor(env).should eq(Flavor.new('fl-001', 'flavor-01', 2, 1024, 10))
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
context 'with name' do
|
|
154
|
+
it 'returns the specified flavor' do
|
|
155
|
+
config.stub(:flavor) { 'flavor-02' }
|
|
156
|
+
nova.stub(:get_all_flavors).with(anything) do
|
|
157
|
+
[Flavor.new('fl-001', 'flavor-01', 2, 1024, 10),
|
|
158
|
+
Flavor.new('fl-002', 'flavor-02', 4, 2048, 50)]
|
|
159
|
+
end
|
|
160
|
+
@action.resolve_flavor(env).should eq(Flavor.new('fl-002', 'flavor-02', 4, 2048, 50))
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
context 'with list' do
|
|
164
|
+
it 'returns the first matching flavor' do
|
|
165
|
+
config.stub(:flavor) { %w(not-existing flavor-02 flavor-01) }
|
|
166
|
+
nova.stub(:get_all_flavors).with(anything) do
|
|
167
|
+
[Flavor.new('fl-001', 'flavor-01', 2, 1024, 10),
|
|
168
|
+
Flavor.new('fl-002', 'flavor-02', 4, 2048, 50)]
|
|
169
|
+
end
|
|
170
|
+
@action.resolve_flavor(env).should eq(Flavor.new('fl-002', 'flavor-02', 4, 2048, 50))
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
context 'with invalid identifier' do
|
|
174
|
+
it 'raise an error' do
|
|
175
|
+
config.stub(:flavor) { 'not-existing' }
|
|
176
|
+
nova.stub(:get_all_flavors).with(anything) do
|
|
177
|
+
[Flavor.new('fl-001', 'flavor-01', 2, 1024, 10),
|
|
178
|
+
Flavor.new('fl-002', 'flavor-02', 4, 2048, 50)]
|
|
179
|
+
end
|
|
180
|
+
expect { @action.resolve_flavor(env) }.to raise_error(Errors::NoMatchingFlavor)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
describe 'resolve_image' do
|
|
186
|
+
context 'with id' do
|
|
187
|
+
it 'returns the specified flavor' do
|
|
188
|
+
config.stub(:image) { 'img-001' }
|
|
189
|
+
config.stub(:volume_boot) { nil }
|
|
190
|
+
nova.stub(:get_all_images).with(anything) do
|
|
191
|
+
[Item.new('img-001', 'image-01'),
|
|
192
|
+
Item.new('img-002', 'image-02')]
|
|
193
|
+
end
|
|
194
|
+
@action.resolve_image(env).should eq(Item.new('img-001', 'image-01'))
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
context 'with name' do
|
|
198
|
+
it 'returns the specified flavor' do
|
|
199
|
+
config.stub(:image) { 'image-02' }
|
|
200
|
+
config.stub(:volume_boot) { nil }
|
|
201
|
+
nova.stub(:get_all_images).with(anything) do
|
|
202
|
+
[Item.new('img-001', 'image-01'),
|
|
203
|
+
Item.new('img-002', 'image-02')]
|
|
204
|
+
end
|
|
205
|
+
@action.resolve_image(env).should eq(Item.new('img-002', 'image-02'))
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
context 'with invalid identifier' do
|
|
209
|
+
it 'raise an error' do
|
|
210
|
+
config.stub(:image) { 'not-existing' }
|
|
211
|
+
config.stub(:volume_boot) { nil }
|
|
212
|
+
nova.stub(:get_all_images).with(anything) do
|
|
213
|
+
[Item.new('img-001', 'image-01'),
|
|
214
|
+
Item.new('img-002', 'image-02')]
|
|
215
|
+
end
|
|
216
|
+
expect { @action.resolve_image(env) }.to raise_error(Errors::NoMatchingImage)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
context 'with no images in config' do
|
|
220
|
+
it 'return nil' do
|
|
221
|
+
config.stub(:image) { nil }
|
|
222
|
+
config.stub(:volume_boot) { nil }
|
|
223
|
+
nova.stub(:get_all_images).with(anything) do
|
|
224
|
+
[Item.new('img-001', 'image-01'),
|
|
225
|
+
Item.new('img-002', 'image-02')]
|
|
226
|
+
end
|
|
227
|
+
@action.resolve_image(env).should eq(nil)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
describe 'resolve_floating_ip' do
|
|
233
|
+
context 'with config.floating_ip specified' do
|
|
234
|
+
it 'return the specified floating ip' do
|
|
235
|
+
config.stub(:floating_ip) { '80.80.80.80' }
|
|
236
|
+
@action.resolve_floating_ip(env).should eq('80.80.80.80')
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
context 'with only one config.floating_ip_pool specified' do
|
|
241
|
+
context 'if an ip in the same pool is available' do
|
|
242
|
+
context 'with config.floating_ip_pool_always_allocate true' do
|
|
243
|
+
it 'allocate a new floating_ip from the pool' do
|
|
244
|
+
config.stub(:floating_ip_pool_always_allocate) { true }
|
|
245
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
246
|
+
[FloatingIP.new('80.81.82.84', 'pool-1', '1234'),
|
|
247
|
+
FloatingIP.new('80.81.82.83', 'pool-1', nil)]
|
|
248
|
+
end
|
|
249
|
+
nova.stub(:allocate_floating_ip).with(env, 'pool-1') do
|
|
250
|
+
FloatingIP.new('80.81.82.85', 'pool-1', nil)
|
|
251
|
+
end
|
|
252
|
+
config.stub(:floating_ip_pool) { ['pool-1'] }
|
|
253
|
+
config.stub(:floating_ip=) { nil }
|
|
254
|
+
@action.resolve_floating_ip(env).should eq('80.81.82.85')
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
context 'with config.floating_ip_pool_always_allocate false' do
|
|
259
|
+
it 'return one of the available ips' do
|
|
260
|
+
config.stub(:floating_ip_pool_always_allocate) { false }
|
|
261
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
262
|
+
[FloatingIP.new('80.81.82.84', 'pool-1', '1234'),
|
|
263
|
+
FloatingIP.new('80.81.82.83', 'pool-1', nil)]
|
|
264
|
+
end
|
|
265
|
+
config.stub(:floating_ip_pool) { ['pool-1'] }
|
|
266
|
+
config.stub(:floating_ip=) { nil }
|
|
267
|
+
@action.resolve_floating_ip(env).should eq('80.81.82.83')
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
context 'if no ip in the same pool is available' do
|
|
273
|
+
it 'allocate a new floating_ip from the pool' do
|
|
274
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
275
|
+
[FloatingIP.new('80.81.82.83', 'pool-1', '1234')]
|
|
276
|
+
end
|
|
277
|
+
nova.stub(:allocate_floating_ip).with(env, 'pool-1') do
|
|
278
|
+
FloatingIP.new('80.81.82.84', 'pool-1', nil)
|
|
279
|
+
end
|
|
280
|
+
config.stub(:floating_ip_pool) { ['pool-1'] }
|
|
281
|
+
config.stub(:floating_ip=) { nil }
|
|
282
|
+
@action.resolve_floating_ip(env).should eq('80.81.82.84')
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context 'with several floating_ip_pool defined' do
|
|
288
|
+
context 'if an ip in a pool is available' do
|
|
289
|
+
context 'with config.floating_ip_pool_always_allocate true' do
|
|
290
|
+
it 'allocate a new floating_ip from the first pool defined' do
|
|
291
|
+
config.stub(:floating_ip_pool_always_allocate) { true }
|
|
292
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
293
|
+
[FloatingIP.new('80.81.82.84', 'pool-1', '1234'),
|
|
294
|
+
FloatingIP.new('80.81.82.83', 'pool-1', nil),
|
|
295
|
+
FloatingIP.new('80.81.82.82', 'pool-2', '5678')]
|
|
296
|
+
end
|
|
297
|
+
nova.stub(:allocate_floating_ip).with(env, 'pool-1') do
|
|
298
|
+
FloatingIP.new('80.81.82.85', 'pool-1', nil)
|
|
299
|
+
end
|
|
300
|
+
config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
|
|
301
|
+
config.stub(:floating_ip=) { nil }
|
|
302
|
+
@action.resolve_floating_ip(env).should eq('80.81.82.85')
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
context 'with config.floating_ip_pool_always_allocate false' do
|
|
307
|
+
it 'return one of the available ips' do
|
|
308
|
+
config.stub(:floating_ip_pool_always_allocate) { false }
|
|
309
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
310
|
+
[FloatingIP.new('80.81.82.84', 'pool-1', '1234'),
|
|
311
|
+
FloatingIP.new('80.81.82.83', 'pool-2', nil)]
|
|
312
|
+
end
|
|
313
|
+
config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
|
|
314
|
+
config.stub(:floating_ip=) { nil }
|
|
315
|
+
@action.resolve_floating_ip(env).should eq('80.81.82.83')
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
context 'if no ip in the pools is available' do
|
|
321
|
+
context 'if allocate an ip in first pool is possible' do
|
|
322
|
+
it 'allocate a new floating_ip from first pool' 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') do
|
|
328
|
+
FloatingIP.new('80.81.82.84', 'pool-1', nil)
|
|
329
|
+
end
|
|
330
|
+
config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
|
|
331
|
+
config.stub(:floating_ip=) { nil }
|
|
332
|
+
@action.resolve_floating_ip(env).should eq('80.81.82.84')
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
context 'if allocate an ip in first pool is not possible' do
|
|
337
|
+
it 'allocate a new floating_ip from second pool' do
|
|
338
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
339
|
+
[FloatingIP.new('80.81.82.83', 'pool-1', '1234'),
|
|
340
|
+
FloatingIP.new('80.81.82.82', 'pool-2', '5678')]
|
|
341
|
+
end
|
|
342
|
+
nova.stub(:allocate_floating_ip).with(env, 'pool-1').and_raise Errors::VagrantOpenstackError, message: 'error', code: 404
|
|
343
|
+
nova.stub(:allocate_floating_ip).with(env, 'pool-2') do
|
|
344
|
+
FloatingIP.new('80.81.82.84', 'pool-2', nil)
|
|
345
|
+
end
|
|
346
|
+
config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
|
|
347
|
+
config.stub(:floating_ip=) { nil }
|
|
348
|
+
@action.resolve_floating_ip(env).should eq('80.81.82.84')
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
context 'if allocate an ip in either first and second pool is not possible' do
|
|
353
|
+
it 'shoud raise an error', :simon do
|
|
354
|
+
nova.stub(:get_all_floating_ips).with(anything) do
|
|
355
|
+
[FloatingIP.new('80.81.82.83', 'pool-1', '1234'),
|
|
356
|
+
FloatingIP.new('80.81.82.82', 'pool-2', '5678')]
|
|
357
|
+
end
|
|
358
|
+
nova.stub(:allocate_floating_ip).with(env, 'pool-1').and_raise Errors::VagrantOpenstackError, message: 'error', code: 404
|
|
359
|
+
nova.stub(:allocate_floating_ip).with(env, 'pool-2').and_raise Errors::VagrantOpenstackError, message: 'error', code: 404
|
|
360
|
+
config.stub(:floating_ip_pool) { %w(pool-1 pool-2) }
|
|
361
|
+
config.stub(:floating_ip=) { nil }
|
|
362
|
+
expect { @action.resolve_floating_ip(env) }.to raise_error(Errors::VagrantOpenstackError)
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
context 'with neither floating_ip nor floating_ip_pool' do
|
|
369
|
+
it 'fails with an UnableToResolveFloatingIP error' do
|
|
370
|
+
config.stub(:floating_ip) { nil }
|
|
371
|
+
config.stub(:floating_ip_pool) { nil }
|
|
372
|
+
expect { @action.resolve_floating_ip(env) }.to raise_error(Errors::UnableToResolveFloatingIP)
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
describe 'resolve_keypair' do
|
|
378
|
+
context 'with keypair_name provided' do
|
|
379
|
+
it 'return the provided keypair_name' do
|
|
380
|
+
config.stub(:keypair_name) { 'my-keypair' }
|
|
381
|
+
@action.resolve_keypair(env).should eq('my-keypair')
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
context 'with keypair_name and public_key_path provided' do
|
|
386
|
+
it 'return the provided keypair_name' do
|
|
387
|
+
config.stub(:keypair_name) { 'my-keypair' }
|
|
388
|
+
config.stub(:public_key_path) { '/path/to/key' }
|
|
389
|
+
@action.resolve_keypair(env).should eq('my-keypair')
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
context 'with public_key_path provided' do
|
|
394
|
+
it 'return the keypair_name created into nova' do
|
|
395
|
+
config.stub(:public_key_path) { '/path/to/key' }
|
|
396
|
+
nova.stub(:import_keypair_from_file).with(env, '/path/to/key') { 'my-keypair-imported' }
|
|
397
|
+
@action.resolve_keypair(env).should eq('my-keypair-imported')
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
context 'with no keypair_name and no public_key_path provided' do
|
|
402
|
+
it 'generates a new keypair and return the keypair name imported into nova' do
|
|
403
|
+
config.stub(:keypair_name) { nil }
|
|
404
|
+
config.stub(:public_key_path) { nil }
|
|
405
|
+
@action.stub(:generate_keypair) { 'my-keypair-imported' }
|
|
406
|
+
@action.resolve_keypair(env).should eq('my-keypair-imported')
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
context 'with insert_key false' do
|
|
411
|
+
it 'does nothing and return nil' do
|
|
412
|
+
config.stub(:keypair_name) { 'my-keypair' }
|
|
413
|
+
ssh_config.stub(:insert_key) { false }
|
|
414
|
+
nova.should_not_receive(:import_keypair_from_file)
|
|
415
|
+
@action.should_not_receive(:generate_keypair)
|
|
416
|
+
@action.resolve_keypair(env).should be_nil
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
describe 'generate_keypair' do
|
|
422
|
+
it 'returns a generated keypair name imported into nova' do
|
|
423
|
+
nova.stub(:import_keypair) { 'my-keypair-imported' }
|
|
424
|
+
SSHKey.stub(:generate) { ssh_key }
|
|
425
|
+
File.should_receive(:write).with('/data/dir/my-keypair-imported', 'private key')
|
|
426
|
+
File.should_receive(:chmod).with(0600, '/data/dir/my-keypair-imported')
|
|
427
|
+
@action.generate_keypair(env).should eq('my-keypair-imported')
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
describe 'resolve_networks' do
|
|
432
|
+
context 'neutron service is available' do
|
|
433
|
+
context 'with network configured in all possible ways' do
|
|
434
|
+
it 'returns normalized network list' do
|
|
435
|
+
config.stub(:networks) do
|
|
436
|
+
['001',
|
|
437
|
+
'net-02',
|
|
438
|
+
{ id: '003', address: '1.2.3.4' },
|
|
439
|
+
{ name: 'net-04', address: '5.6.7.8' },
|
|
440
|
+
{ name: 'net-05' },
|
|
441
|
+
{ id: '006' }]
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
expect(@action.resolve_networks(env)).to eq [{ uuid: '001' },
|
|
445
|
+
{ uuid: '002' },
|
|
446
|
+
{ uuid: '003', fixed_ip: '1.2.3.4' },
|
|
447
|
+
{ uuid: '004', fixed_ip: '5.6.7.8' },
|
|
448
|
+
{ uuid: '005' },
|
|
449
|
+
{ uuid: '006' }]
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
context 'with invalid network object' do
|
|
454
|
+
it 'raises an error' do
|
|
455
|
+
config.stub(:networks) { [1] }
|
|
456
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::InvalidNetworkObject)
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
context 'with string that is neither an id nor name matching a network' do
|
|
461
|
+
it 'raises an error' do
|
|
462
|
+
config.stub(:networks) { ['not-exist'] }
|
|
463
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::UnresolvedNetwork)
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
context 'with hash containing a bad id' do
|
|
468
|
+
it 'raises an error' do
|
|
469
|
+
config.stub(:networks) { [{ id: 'not-exist' }] }
|
|
470
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::UnresolvedNetworkId)
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
context 'with hash containing a bad name' do
|
|
475
|
+
it 'raises an error' do
|
|
476
|
+
config.stub(:networks) { [{ name: 'not-exist' }] }
|
|
477
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::UnresolvedNetworkName)
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
context 'with empty hash' do
|
|
482
|
+
it 'raises an error' do
|
|
483
|
+
config.stub(:networks) { [{}] }
|
|
484
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::ConflictNetworkNameId)
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
context 'with hash containing both id and name' do
|
|
489
|
+
it 'raises an error' do
|
|
490
|
+
config.stub(:networks) { [{ id: '001', name: 'net-01' }] }
|
|
491
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::ConflictNetworkNameId)
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
context 'with hash containing a name matching more than one network' do
|
|
496
|
+
it 'raises an error' do
|
|
497
|
+
config.stub(:networks) { [{ name: 'net-07-08' }] }
|
|
498
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::MultipleNetworkName)
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
context 'neutron service is not available' do
|
|
504
|
+
context 'with network configured in all possible ways' do
|
|
505
|
+
it 'returns normalized network list' do
|
|
506
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
507
|
+
config.stub(:networks) do
|
|
508
|
+
['001',
|
|
509
|
+
{ id: '003', address: '1.2.3.4' },
|
|
510
|
+
{ id: '006' }]
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
expect(@action.resolve_networks(env)).to eq [{ uuid: '001' },
|
|
514
|
+
{ uuid: '003', fixed_ip: '1.2.3.4' },
|
|
515
|
+
{ uuid: '006' }]
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
context 'with hash containing both id and name' do
|
|
520
|
+
it 'raises an error' do
|
|
521
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
522
|
+
config.stub(:networks) { [{ id: '001', name: 'net-01' }] }
|
|
523
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::ConflictNetworkNameId)
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
context 'with hash containing name' do
|
|
528
|
+
it 'raises an error' do
|
|
529
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
530
|
+
config.stub(:networks) { [{ name: 'net-01' }] }
|
|
531
|
+
expect { @action.resolve_networks(env) }.to raise_error(Errors::NetworkServiceUnavailable)
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
describe 'resolve_volume_boot' do
|
|
538
|
+
context 'cinder service is available' do
|
|
539
|
+
context 'with string volume id' do
|
|
540
|
+
it 'returns normalized volume' do
|
|
541
|
+
config.stub(:volume_boot) { '001' }
|
|
542
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vda'
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
context 'with string volume name' do
|
|
547
|
+
it 'returns normalized volume' do
|
|
548
|
+
config.stub(:volume_boot) { 'vol-01' }
|
|
549
|
+
nova.stub(:get_all_images).with(anything) do
|
|
550
|
+
[Item.new('img-001', 'image-01'),
|
|
551
|
+
Item.new('img-002', 'image-02')]
|
|
552
|
+
end
|
|
553
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vda'
|
|
554
|
+
end
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
context 'with hash volume id' do
|
|
558
|
+
it 'returns normalized volume' do
|
|
559
|
+
config.stub(:volume_boot) { { id: '001' } }
|
|
560
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vda'
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
context 'with hash volume name' do
|
|
565
|
+
it 'returns normalized volume' do
|
|
566
|
+
config.stub(:volume_boot) { { name: 'vol-01' } }
|
|
567
|
+
nova.stub(:get_all_images).with(anything) do
|
|
568
|
+
[Item.new('img-001', 'image-01'),
|
|
569
|
+
Item.new('img-002', 'image-02')]
|
|
570
|
+
end
|
|
571
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vda'
|
|
572
|
+
end
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
context 'with hash volume id and device' do
|
|
576
|
+
it 'returns normalized volume' do
|
|
577
|
+
config.stub(:volume_boot) { { id: '001', device: 'vdb' } }
|
|
578
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vdb'
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
context 'with hash volume name and device' do
|
|
583
|
+
it 'returns normalized volume' do
|
|
584
|
+
config.stub(:volume_boot) { { name: 'vol-01', device: 'vdb' } }
|
|
585
|
+
nova.stub(:get_all_images).with(anything) do
|
|
586
|
+
[Item.new('img-001', 'image-01'),
|
|
587
|
+
Item.new('img-002', 'image-02')]
|
|
588
|
+
end
|
|
589
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vdb'
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
context 'with empty hash' do
|
|
594
|
+
it 'raises an error' do
|
|
595
|
+
config.stub(:volume_boot) { {} }
|
|
596
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
597
|
+
end
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
context 'with invalid volume object' do
|
|
601
|
+
it 'raises an error' do
|
|
602
|
+
config.stub(:volume_boot) { 1 }
|
|
603
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::InvalidVolumeObject)
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
context 'with hash containing a bad id' do
|
|
608
|
+
it 'raises an error' do
|
|
609
|
+
config.stub(:volume_boot) { { id: 'not-exist' } }
|
|
610
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::UnresolvedVolumeId)
|
|
611
|
+
end
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
context 'with hash containing a bad name' do
|
|
615
|
+
it 'raises an error' do
|
|
616
|
+
config.stub(:volume_boot) { { name: 'not-exist' } }
|
|
617
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::UnresolvedVolumeName)
|
|
618
|
+
end
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
context 'with hash containing both id and name' do
|
|
622
|
+
it 'raises an error' do
|
|
623
|
+
config.stub(:volume_boot) { { id: '001', name: 'vol-01' } }
|
|
624
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictVolumeNameId)
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
context 'with hash containing a name matching more than one volume' do
|
|
629
|
+
it 'raises an error' do
|
|
630
|
+
config.stub(:volume_boot) { { name: 'vol-07-08' } }
|
|
631
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::MultipleVolumeName)
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
context 'with hash containing a name and an image_name' do
|
|
636
|
+
it 'raises an error' do
|
|
637
|
+
config.stub(:volume_boot) { { name: 'vol-01', image: 'img_001' } }
|
|
638
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
639
|
+
end
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
context 'with hash containing a name and a size' do
|
|
643
|
+
it 'raises an error' do
|
|
644
|
+
config.stub(:volume_boot) { { name: 'vol-01', size: '10' } }
|
|
645
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
646
|
+
end
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
context 'with hash containing a name and a delete_on_destroy indication' do
|
|
650
|
+
it 'raises an error' do
|
|
651
|
+
config.stub(:volume_boot) { { name: 'vol-01', delete_on_destroy: 'true' } }
|
|
652
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
653
|
+
end
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
context 'with hash containing a volume_id and an image_name' do
|
|
657
|
+
it 'raises an error' do
|
|
658
|
+
config.stub(:volume_boot) { { id: 'id', image: 'img_001' } }
|
|
659
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
660
|
+
end
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
context 'with hash containing a volume_id and a size' do
|
|
664
|
+
it 'raises an error' do
|
|
665
|
+
config.stub(:volume_boot) { { id: 'id', size: '10' } }
|
|
666
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
667
|
+
end
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
context 'with hash containing a volume_id and a delete_on_destroy indication' do
|
|
671
|
+
it 'raises an error' do
|
|
672
|
+
config.stub(:volume_boot) { { id: 'id', delete_on_destroy: 'true' } }
|
|
673
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
context 'with hash containing an image_name without size' do
|
|
678
|
+
it 'raises an error' do
|
|
679
|
+
config.stub(:volume_boot) { { image: 'img-001' } }
|
|
680
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::UnresolvedVolume)
|
|
681
|
+
end
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
context 'with hash containing an image_name with a size' do
|
|
685
|
+
it 'return normalized volume' do
|
|
686
|
+
config.stub(:volume_boot) { { image: 'image-01', size: '10' } }
|
|
687
|
+
nova.stub(:get_all_images).with(anything) do
|
|
688
|
+
[Item.new('img-001', 'image-01'),
|
|
689
|
+
Item.new('img-002', 'image-02')]
|
|
690
|
+
end
|
|
691
|
+
expect(@action.resolve_volume_boot(env)).to eq image: 'img-001', device: 'vda', size: '10', delete_on_destroy: 'true'
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
context 'with hash containing an image_name, size, device and delete_on_destroy' do
|
|
696
|
+
it 'return normalized volume' do
|
|
697
|
+
config.stub(:volume_boot) { { image: 'image-01', size: '10', device: 'vdb', delete_on_destroy: 'false' } }
|
|
698
|
+
nova.stub(:get_all_images).with(anything) do
|
|
699
|
+
[Item.new('img-001', 'image-01'),
|
|
700
|
+
Item.new('img-002', 'image-02')]
|
|
701
|
+
end
|
|
702
|
+
expect(@action.resolve_volume_boot(env)).to eq image: 'img-001', device: 'vdb', size: '10', delete_on_destroy: 'false'
|
|
703
|
+
end
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
context 'cinder service is not available' do
|
|
708
|
+
context 'with string volume id' do
|
|
709
|
+
it 'returns normalized volume' do
|
|
710
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
711
|
+
config.stub(:volume_boot) { '001' }
|
|
712
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vda'
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
context 'with hash volume id' do
|
|
717
|
+
it 'returns normalized volume' do
|
|
718
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
719
|
+
config.stub(:volume_boot) { { id: '001' } }
|
|
720
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vda'
|
|
721
|
+
end
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
context 'with hash volume name' do
|
|
725
|
+
it 'raise an error' do
|
|
726
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
727
|
+
config.stub(:volume_boot) { { name: 'vol-01' } }
|
|
728
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::VolumeServiceUnavailable)
|
|
729
|
+
end
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
context 'with hash volume id and device' do
|
|
733
|
+
it 'returns normalized volume' do
|
|
734
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
735
|
+
config.stub(:volume_boot) { { id: '001', device: 'vdb' } }
|
|
736
|
+
expect(@action.resolve_volume_boot(env)).to eq id: '001', device: 'vdb'
|
|
737
|
+
end
|
|
738
|
+
end
|
|
739
|
+
|
|
740
|
+
context 'with hash volume name and device' do
|
|
741
|
+
it 'raise an error' do
|
|
742
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
743
|
+
config.stub(:volume_boot) { { name: 'vol-01', device: 'vdb' } }
|
|
744
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::VolumeServiceUnavailable)
|
|
745
|
+
end
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
context 'with invalid volume object' do
|
|
749
|
+
it 'raises an error' do
|
|
750
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
751
|
+
config.stub(:volume_boot) { 1 }
|
|
752
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::InvalidVolumeObject)
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
context 'with hash containing both id and name' do
|
|
757
|
+
it 'raises an error' do
|
|
758
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
759
|
+
config.stub(:volume_boot) { { id: '001', name: 'vol-01' } }
|
|
760
|
+
expect { @action.resolve_volume_boot(env) }.to raise_error(Errors::ConflictVolumeNameId)
|
|
761
|
+
end
|
|
762
|
+
end
|
|
763
|
+
end
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
describe 'resolve_volumes' do
|
|
767
|
+
context 'cinder service is available' do
|
|
768
|
+
context 'with volume attached in all possible ways' do
|
|
769
|
+
it 'returns normalized volume list' do
|
|
770
|
+
config.stub(:volumes) do
|
|
771
|
+
['001',
|
|
772
|
+
'vol-02',
|
|
773
|
+
{ id: '003', device: '/dev/vdz' },
|
|
774
|
+
{ name: 'vol-04', device: '/dev/vdy' },
|
|
775
|
+
{ name: 'vol-05' },
|
|
776
|
+
{ id: '006' }]
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
expect(@action.resolve_volumes(env)).to eq [{ id: '001', device: nil },
|
|
780
|
+
{ id: '002', device: nil },
|
|
781
|
+
{ id: '003', device: '/dev/vdz' },
|
|
782
|
+
{ id: '004', device: '/dev/vdy' },
|
|
783
|
+
{ id: '005', device: nil },
|
|
784
|
+
{ id: '006', device: nil }]
|
|
785
|
+
end
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
context 'with invalid volume object' do
|
|
789
|
+
it 'raises an error' do
|
|
790
|
+
config.stub(:volumes) { [1] }
|
|
791
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::InvalidVolumeObject)
|
|
792
|
+
end
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
context 'with string that is neither an id nor name matching a volume' do
|
|
796
|
+
it 'raises an error' do
|
|
797
|
+
config.stub(:volumes) { ['not-exist'] }
|
|
798
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::UnresolvedVolume)
|
|
799
|
+
end
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
context 'with hash containing a bad id' do
|
|
803
|
+
it 'raises an error' do
|
|
804
|
+
config.stub(:volumes) { [{ id: 'not-exist' }] }
|
|
805
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::UnresolvedVolumeId)
|
|
806
|
+
end
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
context 'with hash containing a bad name' do
|
|
810
|
+
it 'raises an error' do
|
|
811
|
+
config.stub(:volumes) { [{ name: 'not-exist' }] }
|
|
812
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::UnresolvedVolumeName)
|
|
813
|
+
end
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
context 'with empty hash' do
|
|
817
|
+
it 'raises an error' do
|
|
818
|
+
config.stub(:volumes) { [{}] }
|
|
819
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::ConflictBootVolume)
|
|
820
|
+
end
|
|
821
|
+
end
|
|
822
|
+
|
|
823
|
+
context 'with hash containing both id and name' do
|
|
824
|
+
it 'raises an error' do
|
|
825
|
+
config.stub(:volumes) { [{ id: '001', name: 'vol-01' }] }
|
|
826
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::ConflictVolumeNameId)
|
|
827
|
+
end
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
context 'with hash containing a name matching more than one volume' do
|
|
831
|
+
it 'raises an error' do
|
|
832
|
+
config.stub(:volumes) { [{ name: 'vol-07-08' }] }
|
|
833
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::MultipleVolumeName)
|
|
834
|
+
end
|
|
835
|
+
end
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
context 'cinder service is not available' do
|
|
839
|
+
context 'with volume attached in all possible ways' do
|
|
840
|
+
it 'returns normalized volume list' do
|
|
841
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
842
|
+
config.stub(:volumes) do
|
|
843
|
+
['001',
|
|
844
|
+
{ id: '003', device: '/dev/vdz' },
|
|
845
|
+
{ id: '006' }]
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
expect(@action.resolve_volumes(env)).to eq [{ id: '001', device: nil },
|
|
849
|
+
{ id: '003', device: '/dev/vdz' },
|
|
850
|
+
{ id: '006', device: nil }]
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
context 'with hash containing both id and name' do
|
|
854
|
+
it 'raises an error' do
|
|
855
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
856
|
+
config.stub(:volumes) { [{ id: '001', name: 'vol-01' }] }
|
|
857
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::ConflictVolumeNameId)
|
|
858
|
+
end
|
|
859
|
+
end
|
|
860
|
+
context 'with hash containing name' do
|
|
861
|
+
it 'raises an error' do
|
|
862
|
+
session.stub(:endpoints) { { identity: 'http://keystone', compute: 'http://nova' } }
|
|
863
|
+
config.stub(:volumes) { [{ name: 'vol-01' }] }
|
|
864
|
+
expect { @action.resolve_volumes(env) }.to raise_error(Errors::VolumeServiceUnavailable)
|
|
865
|
+
end
|
|
866
|
+
end
|
|
867
|
+
end
|
|
868
|
+
end
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
describe 'resolve_security_groups' do
|
|
872
|
+
context 'with Hash and String objects' do
|
|
873
|
+
it 'returns normalized Hash list' do
|
|
874
|
+
config.stub(:security_groups) { ['group1', { name: 'group2' }] }
|
|
875
|
+
expect(@action.resolve_security_groups(env)).to eq([{ name: 'group1' }, { name: 'group2' }])
|
|
876
|
+
end
|
|
877
|
+
end
|
|
878
|
+
end
|
|
879
|
+
end
|