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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/lib/vagrant-openstack-provider.rb +2 -31
- data/lib/vagrant-openstack-provider/action.rb +21 -7
- data/lib/vagrant-openstack-provider/action/abstract_action.rb +22 -0
- data/lib/vagrant-openstack-provider/action/connect_openstack.rb +19 -40
- data/lib/vagrant-openstack-provider/action/create_server.rb +10 -6
- data/lib/vagrant-openstack-provider/action/create_stack.rb +67 -0
- data/lib/vagrant-openstack-provider/action/delete_server.rb +28 -3
- data/lib/vagrant-openstack-provider/action/delete_stack.rb +72 -0
- data/lib/vagrant-openstack-provider/action/message.rb +4 -2
- data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +4 -2
- data/lib/vagrant-openstack-provider/action/read_state.rb +9 -4
- data/lib/vagrant-openstack-provider/action/resume.rb +4 -2
- data/lib/vagrant-openstack-provider/action/start_server.rb +4 -2
- data/lib/vagrant-openstack-provider/action/stop_server.rb +4 -2
- data/lib/vagrant-openstack-provider/action/suspend.rb +4 -2
- data/lib/vagrant-openstack-provider/action/sync_folders.rb +17 -13
- data/lib/vagrant-openstack-provider/action/wait_accessible.rb +5 -2
- data/lib/vagrant-openstack-provider/action/wait_active.rb +5 -3
- data/lib/vagrant-openstack-provider/action/wait_stop.rb +5 -3
- data/lib/vagrant-openstack-provider/catalog/openstack_catalog.rb +66 -0
- data/lib/vagrant-openstack-provider/client/domain.rb +41 -1
- data/lib/vagrant-openstack-provider/client/glance.rb +63 -0
- data/lib/vagrant-openstack-provider/client/heat.rb +50 -0
- data/lib/vagrant-openstack-provider/client/http_utils.rb +18 -0
- data/lib/vagrant-openstack-provider/client/neutron.rb +9 -15
- data/lib/vagrant-openstack-provider/client/nova.rb +3 -3
- data/lib/vagrant-openstack-provider/client/openstack.rb +10 -0
- data/lib/vagrant-openstack-provider/command/abstract_command.rb +7 -0
- data/lib/vagrant-openstack-provider/command/image_list.rb +12 -2
- data/lib/vagrant-openstack-provider/command/main.rb +1 -0
- data/lib/vagrant-openstack-provider/command/network_list.rb +3 -3
- data/lib/vagrant-openstack-provider/command/subnet_list.rb +25 -0
- data/lib/vagrant-openstack-provider/config.rb +78 -7
- data/lib/vagrant-openstack-provider/config_resolver.rb +36 -5
- data/lib/vagrant-openstack-provider/errors.rb +30 -2
- data/lib/vagrant-openstack-provider/logging.rb +39 -0
- data/lib/vagrant-openstack-provider/version.rb +1 -1
- data/locales/en.yml +107 -4
- data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +255 -8
- data/spec/vagrant-openstack-provider/action/create_server_spec.rb +6 -1
- data/spec/vagrant-openstack-provider/action/create_stack_spec.rb +97 -0
- data/spec/vagrant-openstack-provider/action/delete_server_spec.rb +34 -6
- data/spec/vagrant-openstack-provider/action/delete_stack_spec.rb +64 -0
- data/spec/vagrant-openstack-provider/action/read_state_spec.rb +13 -1
- data/spec/vagrant-openstack-provider/action/sync_folders_spec.rb +1 -0
- data/spec/vagrant-openstack-provider/action/wait_active_spec.rb +1 -1
- data/spec/vagrant-openstack-provider/action/wait_stop_spec.rb +1 -1
- data/spec/vagrant-openstack-provider/client/glance_spec.rb +128 -0
- data/spec/vagrant-openstack-provider/client/heat_spec.rb +124 -0
- data/spec/vagrant-openstack-provider/client/neutron_spec.rb +33 -1
- data/spec/vagrant-openstack-provider/client/nova_spec.rb +2 -2
- data/spec/vagrant-openstack-provider/command/image_list_spec.rb +75 -23
- data/spec/vagrant-openstack-provider/command/subnet_list_spec.rb +46 -0
- data/spec/vagrant-openstack-provider/config_resolver_spec.rb +85 -19
- data/spec/vagrant-openstack-provider/config_spec.rb +177 -1
- data/spec/vagrant-openstack-provider/spec_helper.rb +3 -0
- metadata +20 -2
@@ -200,7 +200,12 @@ describe VagrantPlugins::Openstack::Action::CreateServer do
|
|
200
200
|
it 'timeout before the server become active' do
|
201
201
|
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'BUILD' })
|
202
202
|
nova.should_receive(:get_server_details).with(env, 'server-01').at_least(2).times
|
203
|
-
expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Timeout
|
203
|
+
expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Errors::Timeout
|
204
|
+
end
|
205
|
+
it 'raise an error after one retry' do
|
206
|
+
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'ERROR' })
|
207
|
+
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
|
208
|
+
expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Errors::ServerStatusError
|
204
209
|
end
|
205
210
|
end
|
206
211
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'sshkey'
|
4
|
+
|
5
|
+
include VagrantPlugins::Openstack::Action
|
6
|
+
include VagrantPlugins::Openstack::HttpUtils
|
7
|
+
include VagrantPlugins::Openstack::Domain
|
8
|
+
|
9
|
+
describe VagrantPlugins::Openstack::Action::CreateStack do
|
10
|
+
|
11
|
+
let(:config) do
|
12
|
+
double('config').tap do |config|
|
13
|
+
config.stub(:stacks) do
|
14
|
+
[
|
15
|
+
{
|
16
|
+
name: 'stack1',
|
17
|
+
template: 'template.yml'
|
18
|
+
},
|
19
|
+
{
|
20
|
+
name: 'stack2',
|
21
|
+
template: 'template.yml'
|
22
|
+
}
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:heat) do
|
29
|
+
double('heat')
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:env) do
|
33
|
+
Hash.new.tap do |env|
|
34
|
+
env[:ui] = double('ui')
|
35
|
+
env[:ui].stub(:info).with(anything)
|
36
|
+
env[:machine] = double('machine')
|
37
|
+
env[:machine] = OpenStruct.new.tap do |m|
|
38
|
+
m.provider_config = config
|
39
|
+
m.id = nil
|
40
|
+
end
|
41
|
+
env[:openstack_client] = double('openstack_client')
|
42
|
+
env[:openstack_client].stub(:heat) { heat }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
before :each do
|
46
|
+
CreateStack.send(:public, *CreateStack.private_instance_methods)
|
47
|
+
app = double('app')
|
48
|
+
app.stub(:call).with(anything)
|
49
|
+
@action = CreateStack.new(app, nil)
|
50
|
+
YAML.stub(:load_file).with('template.yml').and_return(YAML.load('
|
51
|
+
heat_template_version: 2013-05-23
|
52
|
+
|
53
|
+
description: Simple template to deploy a single compute instance
|
54
|
+
|
55
|
+
resources:
|
56
|
+
my_instance:
|
57
|
+
type: OS::Nova::Server
|
58
|
+
properties:
|
59
|
+
key_name: julien-mac
|
60
|
+
image: CoreOS
|
61
|
+
flavor: 1_vCPU_RAM_512M_HD_10G
|
62
|
+
'))
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'call' do
|
67
|
+
it 'should create stacks on heat twice' do
|
68
|
+
heat.stub(:create_stack).and_return('idstack')
|
69
|
+
File.should_receive(:write).with('/stack_stack1_id', 'idstack')
|
70
|
+
File.should_receive(:write).with('/stack_stack2_id', 'idstack')
|
71
|
+
# TODO(julienvey) assert content of create call is correct
|
72
|
+
heat.should_receive(:create_stack).exactly(2).times
|
73
|
+
heat.stub(:get_stack_details).and_return('stack_status' => 'CREATE_COMPLETE')
|
74
|
+
@action.call(env)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'waiting_for_server_to_be_built' do
|
79
|
+
context 'when server is not yet active' do
|
80
|
+
it 'become active after one retry' do
|
81
|
+
heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_COMPLETE' })
|
82
|
+
heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').exactly(2).times
|
83
|
+
@action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 5)
|
84
|
+
end
|
85
|
+
it 'timeout before the server become active' do
|
86
|
+
heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_IN_PROGRESS' })
|
87
|
+
heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').at_least(2).times
|
88
|
+
expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 3) }.to raise_error Errors::Timeout
|
89
|
+
end
|
90
|
+
it 'raise an error after one retry' do
|
91
|
+
heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_FAILED' })
|
92
|
+
heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').exactly(2).times
|
93
|
+
expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 3) }.to raise_error Errors::StackStatusError
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -27,10 +27,11 @@ describe VagrantPlugins::Openstack::Action::DeleteServer do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
before :each do
|
31
|
+
DeleteServer.send(:public, *DeleteServer.private_instance_methods)
|
32
|
+
app = double('app')
|
33
|
+
app.stub(:call).with(anything)
|
34
|
+
@action = DeleteServer.new(app, nil)
|
34
35
|
end
|
35
36
|
|
36
37
|
describe 'call' do
|
@@ -38,17 +39,44 @@ describe VagrantPlugins::Openstack::Action::DeleteServer do
|
|
38
39
|
it 'delete server' do
|
39
40
|
expect(nova).to receive(:delete_server).with(env, 'server_id')
|
40
41
|
expect(nova).to receive(:delete_keypair_if_vagrant).with(env, 'server_id')
|
41
|
-
@action
|
42
|
+
expect(@action).to receive(:waiting_for_instance_to_be_deleted).with(env, 'server_id')
|
42
43
|
@action.call(env)
|
43
44
|
end
|
44
45
|
end
|
45
46
|
context 'when id is not present' do
|
46
47
|
it 'delete server' do
|
48
|
+
env[:machine].id = nil
|
47
49
|
expect(nova).should_not_receive(:delete_server)
|
48
50
|
expect(nova).should_not_receive(:delete_keypair_if_vagrant)
|
49
|
-
@action = DeleteServer.new(app, nil)
|
50
51
|
@action.call(env)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
55
|
+
|
56
|
+
describe 'waiting_for_instance_to_be_deleted' do
|
57
|
+
context 'when server is not yet active' do
|
58
|
+
it 'become deleted after one retry' do
|
59
|
+
nova.stub(:get_server_details).once.and_return('status' => 'ACTIVE')
|
60
|
+
nova.stub(:get_server_details).once.and_raise(Errors::InstanceNotFound)
|
61
|
+
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(1).times
|
62
|
+
@action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 5)
|
63
|
+
end
|
64
|
+
it 'become deleted after one retry' do
|
65
|
+
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'DELETED' })
|
66
|
+
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
|
67
|
+
@action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 5)
|
68
|
+
end
|
69
|
+
it 'timeout before the server become active' do
|
70
|
+
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ACTIVE' })
|
71
|
+
nova.should_receive(:get_server_details).with(env, 'server-01').at_least(2).times
|
72
|
+
expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 3) }.to raise_error Errors::Timeout
|
73
|
+
end
|
74
|
+
it 'raise an error after one retry' do
|
75
|
+
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ERROR' })
|
76
|
+
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
|
77
|
+
expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 3) }.to raise_error Errors::ServerStatusError
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
54
82
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
|
3
|
+
describe VagrantPlugins::Openstack::Action::DeleteStack do
|
4
|
+
|
5
|
+
let(:heat) do
|
6
|
+
double('heat').tap do |app|
|
7
|
+
app.stub(:delete_stack)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:openstack_client) do
|
12
|
+
double('openstack_client').tap do |os|
|
13
|
+
os.stub(:heat) { heat }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:env) do
|
18
|
+
Hash.new.tap do |env|
|
19
|
+
env[:ui] = double('ui')
|
20
|
+
env[:ui].stub(:info).with(anything)
|
21
|
+
env[:ui].stub(:error).with(anything)
|
22
|
+
env[:openstack_client] = openstack_client
|
23
|
+
env[:machine] = OpenStruct.new.tap do |m|
|
24
|
+
m.id = 'server_id'
|
25
|
+
m.data_dir = '/test'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
before :each do
|
31
|
+
DeleteStack.send(:public, *DeleteStack.private_instance_methods)
|
32
|
+
app = double('app')
|
33
|
+
app.stub(:call).with(anything)
|
34
|
+
@action = DeleteStack.new(app, nil)
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'call' do
|
38
|
+
context 'when id is present' do
|
39
|
+
it 'delete stack' do
|
40
|
+
expect(heat).to receive(:delete_stack).with(env, 'test1', '1234')
|
41
|
+
expect(heat).to receive(:delete_stack).with(env, 'test2', '2345')
|
42
|
+
@action.stub(:list_stack_files).with(env).and_return([
|
43
|
+
{
|
44
|
+
name: 'test1',
|
45
|
+
id: '1234'
|
46
|
+
}, {
|
47
|
+
name: 'test2',
|
48
|
+
id: '2345'
|
49
|
+
}])
|
50
|
+
expect(@action).to receive(:waiting_for_stack_to_be_deleted).with(env, 'test1', '1234')
|
51
|
+
expect(@action).to receive(:waiting_for_stack_to_be_deleted).with(env, 'test2', '2345')
|
52
|
+
@action.call(env)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
context 'when id is not present' do
|
56
|
+
it 'delete stack' do
|
57
|
+
@action.stub(:list_stack_files).with(env).and_return([])
|
58
|
+
expect(heat).should_not_receive(:delete_stack)
|
59
|
+
expect(heat).should_not_receive(:waiting_for_stack_to_be_deleted)
|
60
|
+
@action.call(env)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -27,7 +27,7 @@ describe VagrantPlugins::Openstack::Action::ReadState do
|
|
27
27
|
|
28
28
|
describe 'call' do
|
29
29
|
context 'when server id is present' do
|
30
|
-
it 'set the state to the
|
30
|
+
it 'set the state to the vm_state returned by nova' do
|
31
31
|
env[:machine].id = 'server_id'
|
32
32
|
nova.stub(:get_server_details).and_return('status' => 'ACTIVE')
|
33
33
|
|
@@ -39,6 +39,18 @@ describe VagrantPlugins::Openstack::Action::ReadState do
|
|
39
39
|
|
40
40
|
expect(env[:machine_state_id]).to eq(:active)
|
41
41
|
end
|
42
|
+
it 'set the state to the task_state returned by nova extension' do
|
43
|
+
env[:machine].id = 'server_id'
|
44
|
+
nova.stub(:get_server_details).and_return('OS-EXT-STS:task_state' => 'SUSPENDING')
|
45
|
+
|
46
|
+
expect(nova).to receive(:get_server_details).with(env, 'server_id')
|
47
|
+
expect(app).to receive(:call)
|
48
|
+
|
49
|
+
@action = ReadState.new(app, nil)
|
50
|
+
@action.call(env)
|
51
|
+
|
52
|
+
expect(env[:machine_state_id]).to eq(:suspending)
|
53
|
+
end
|
42
54
|
end
|
43
55
|
context 'when server id is not present' do
|
44
56
|
it 'set the state to :not_created' do
|
@@ -40,7 +40,7 @@ describe VagrantPlugins::Openstack::Action::WaitForServerToBeActive do
|
|
40
40
|
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'BUILD' })
|
41
41
|
expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
|
42
42
|
@action = WaitForServerToBeActive.new(app, nil, 1, 2)
|
43
|
-
expect { @action.call(env) }.to raise_error Timeout
|
43
|
+
expect { @action.call(env) }.to raise_error Errors::Timeout
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -40,7 +40,7 @@ describe VagrantPlugins::Openstack::Action::WaitForServerToStop do
|
|
40
40
|
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ACTIVE' })
|
41
41
|
expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
|
42
42
|
@action = WaitForServerToStop.new(app, nil, 1, 2)
|
43
|
-
expect { @action.call(env) }.to raise_error Timeout
|
43
|
+
expect { @action.call(env) }.to raise_error Errors::Timeout
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
|
3
|
+
describe VagrantPlugins::Openstack::GlanceClient do
|
4
|
+
|
5
|
+
let(:env) do
|
6
|
+
Hash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:session) do
|
10
|
+
VagrantPlugins::Openstack.session
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
session.token = '123456'
|
15
|
+
session.project_id = 'a1b2c3'
|
16
|
+
session.endpoints = { image: 'http://glance' }
|
17
|
+
@glance_client = VagrantPlugins::Openstack.glance
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'get_all_images' do
|
21
|
+
context 'with token and project_id acquainted' do
|
22
|
+
context 'and api version is v2' do
|
23
|
+
it 'returns all images with details' do
|
24
|
+
stub_request(:get, 'http://glance/images')
|
25
|
+
.with(
|
26
|
+
headers:
|
27
|
+
{
|
28
|
+
'Accept' => 'application/json',
|
29
|
+
'X-Auth-Token' => '123456'
|
30
|
+
})
|
31
|
+
.to_return(
|
32
|
+
status: 200,
|
33
|
+
body: '
|
34
|
+
{
|
35
|
+
"images": [
|
36
|
+
{ "id": "i1", "name": "image1", "visibility": "public", "size": "1024", "min_ram": "1", "min_disk": "10" },
|
37
|
+
{ "id": "i2", "name": "image2", "visibility": "private", "size": "2048", "min_ram": "2", "min_disk": "20" }
|
38
|
+
]
|
39
|
+
}')
|
40
|
+
|
41
|
+
images = @glance_client.get_all_images(env)
|
42
|
+
|
43
|
+
expect(images).to eq [Image.new('i1', 'image1', 'public', '1024', '1', '10'),
|
44
|
+
Image.new('i2', 'image2', 'private', '2048', '2', '20')]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'and api version is v1' do
|
49
|
+
it 'returns all images with details' do
|
50
|
+
stub_request(:get, 'http://glance/images')
|
51
|
+
.with(
|
52
|
+
headers:
|
53
|
+
{
|
54
|
+
'Accept' => 'application/json',
|
55
|
+
'X-Auth-Token' => '123456'
|
56
|
+
})
|
57
|
+
.to_return(
|
58
|
+
status: 200,
|
59
|
+
body: '
|
60
|
+
{
|
61
|
+
"images": [
|
62
|
+
{ "id": "i1", "name": "image1", "is_public": true },
|
63
|
+
{ "id": "i2", "name": "image2", "is_public": false }
|
64
|
+
]
|
65
|
+
}')
|
66
|
+
|
67
|
+
stub_request(:get, 'http://glance/images/detail')
|
68
|
+
.with(
|
69
|
+
headers:
|
70
|
+
{
|
71
|
+
'Accept' => 'application/json',
|
72
|
+
'X-Auth-Token' => '123456'
|
73
|
+
})
|
74
|
+
.to_return(
|
75
|
+
status: 200,
|
76
|
+
body: '
|
77
|
+
{
|
78
|
+
"images": [
|
79
|
+
{ "id": "i1", "name": "image1", "is_public": true, "size": "1024", "min_ram": "1", "min_disk": "10" },
|
80
|
+
{ "id": "i2", "name": "image2", "is_public": false, "size": "2048", "min_ram": "2", "min_disk": "20" }
|
81
|
+
]
|
82
|
+
}')
|
83
|
+
|
84
|
+
images = @glance_client.get_all_images(env)
|
85
|
+
|
86
|
+
expect(images).to eq [Image.new('i1', 'image1', 'public', '1024', '1', '10'),
|
87
|
+
Image.new('i2', 'image2', 'private', '2048', '2', '20')]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'get_api_version_list' do
|
94
|
+
it 'returns version list' do
|
95
|
+
stub_request(:get, 'http://glance/')
|
96
|
+
.with(header: { 'Accept' => 'application/json' })
|
97
|
+
.to_return(
|
98
|
+
status: 200,
|
99
|
+
body: '{
|
100
|
+
"versions": [
|
101
|
+
{
|
102
|
+
"status": "...",
|
103
|
+
"id": "v1.0",
|
104
|
+
"links": [
|
105
|
+
{
|
106
|
+
"href": "http://glance/v1.0",
|
107
|
+
"rel": "self"
|
108
|
+
}
|
109
|
+
]
|
110
|
+
},
|
111
|
+
{
|
112
|
+
"status": "CURRENT",
|
113
|
+
"id": "v2.0",
|
114
|
+
"links": [
|
115
|
+
{
|
116
|
+
"href": "http://glance/v2.0",
|
117
|
+
"rel": "self"
|
118
|
+
}
|
119
|
+
]
|
120
|
+
}
|
121
|
+
]}')
|
122
|
+
|
123
|
+
versions = @glance_client.get_api_version_list(:image)
|
124
|
+
|
125
|
+
expect(versions.size).to eq(2)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
|
3
|
+
describe VagrantPlugins::Openstack::NovaClient do
|
4
|
+
include FakeFS::SpecHelpers::All
|
5
|
+
|
6
|
+
let(:config) do
|
7
|
+
double('config').tap do |config|
|
8
|
+
config.stub(:openstack_auth_url) { 'http://heatAuthV2' }
|
9
|
+
config.stub(:openstack_orchestration_url) { nil }
|
10
|
+
config.stub(:tenant_name) { 'testTenant' }
|
11
|
+
config.stub(:username) { 'username' }
|
12
|
+
config.stub(:password) { 'password' }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:env) do
|
17
|
+
Hash.new.tap do |env|
|
18
|
+
env[:ui] = double('ui')
|
19
|
+
env[:ui].stub(:info).with(anything)
|
20
|
+
env[:machine] = double('machine')
|
21
|
+
env[:machine].stub(:provider_config) { config }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:session) do
|
26
|
+
VagrantPlugins::Openstack.session
|
27
|
+
end
|
28
|
+
|
29
|
+
before :each do
|
30
|
+
session.token = '123456'
|
31
|
+
session.project_id = 'a1b2c3'
|
32
|
+
session.endpoints = { orchestration: 'http://heat/a1b2c3' }
|
33
|
+
@heat_client = VagrantPlugins::Openstack.heat
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'stack_exists' do
|
37
|
+
context 'stack not found' do
|
38
|
+
it 'raise an StackNotFound error' do
|
39
|
+
stub_request(:get, 'http://heat/a1b2c3/stacks/stack_name/stack_id')
|
40
|
+
.with(
|
41
|
+
headers:
|
42
|
+
{
|
43
|
+
'Accept' => 'application/json',
|
44
|
+
'Accept-Encoding' => 'gzip, deflate',
|
45
|
+
'X-Auth-Token' => '123456'
|
46
|
+
})
|
47
|
+
.to_return(
|
48
|
+
status: 404,
|
49
|
+
body: '{"itemNotFound": {"message": "Stack could not be found", "code": 404}}')
|
50
|
+
|
51
|
+
expect { @heat_client.get_stack_details(env, 'stack_name', 'stack_id') }.to raise_error(VagrantPlugins::Openstack::Errors::StackNotFound)
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'create_stack' do
|
58
|
+
context 'with token and project_id acquainted' do
|
59
|
+
it 'returns new stack id' do
|
60
|
+
|
61
|
+
stub_request(:post, 'http://heat/a1b2c3/stacks')
|
62
|
+
.with(
|
63
|
+
body: '{"stack_name":"stck","template":"toto"}',
|
64
|
+
headers:
|
65
|
+
{
|
66
|
+
'Accept' => 'application/json',
|
67
|
+
'Content-Type' => 'application/json',
|
68
|
+
'X-Auth-Token' => '123456'
|
69
|
+
})
|
70
|
+
.to_return(status: 202, body: '{ "stack": { "id": "o1o2o3" } }')
|
71
|
+
|
72
|
+
stack_id = @heat_client.create_stack(env, name: 'stck', template: 'toto')
|
73
|
+
|
74
|
+
expect(stack_id).to eq('o1o2o3')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'get_stack_details' do
|
80
|
+
context 'with token and project_id acquainted' do
|
81
|
+
it 'returns stack details' do
|
82
|
+
|
83
|
+
stub_request(:get, 'http://heat/a1b2c3/stacks/stack_id/stack_name')
|
84
|
+
.with(headers:
|
85
|
+
{
|
86
|
+
'Accept' => 'application/json',
|
87
|
+
'X-Auth-Token' => '123456'
|
88
|
+
})
|
89
|
+
.to_return(status: 200, body: '
|
90
|
+
{
|
91
|
+
"stack": {
|
92
|
+
"description": "sample stack",
|
93
|
+
"disable_rollback": "True",
|
94
|
+
"id": "stack_id",
|
95
|
+
"stack_name": "stack_name",
|
96
|
+
"stack_status": "CREATE_COMPLETE"
|
97
|
+
}
|
98
|
+
}')
|
99
|
+
|
100
|
+
stack = @heat_client.get_stack_details(env, 'stack_id', 'stack_name')
|
101
|
+
|
102
|
+
expect(stack['id']).to eq('stack_id')
|
103
|
+
expect(stack['stack_name']).to eq('stack_name')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'delete_stack' do
|
109
|
+
context 'with token and project_id acquainted' do
|
110
|
+
it 'deletes the stack' do
|
111
|
+
|
112
|
+
stub_request(:delete, 'http://heat/a1b2c3/stacks/stack_id/stack_name')
|
113
|
+
.with(headers:
|
114
|
+
{
|
115
|
+
'Accept' => 'application/json',
|
116
|
+
'X-Auth-Token' => '123456'
|
117
|
+
})
|
118
|
+
.to_return(status: 204)
|
119
|
+
|
120
|
+
@heat_client.delete_stack(env, 'stack_id', 'stack_name')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|