vagrant-openstack-provider 0.1.2 → 0.2.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 +13 -5
- data/.rubocop.yml +28 -0
- data/Appraisals +3 -3
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -0
- data/Rakefile +6 -2
- data/Vagrantfile +4 -15
- data/gemfiles/latest_stable.gemfile +2 -0
- data/gemfiles/oldest_current.gemfile +2 -0
- data/gemfiles/previous_release.gemfile +2 -0
- data/lib/vagrant-openstack-provider.rb +18 -13
- data/lib/vagrant-openstack-provider/action.rb +112 -46
- data/lib/vagrant-openstack-provider/action/connect_openstack.rb +9 -10
- data/lib/vagrant-openstack-provider/action/create_server.rb +86 -57
- data/lib/vagrant-openstack-provider/action/delete_server.rb +5 -6
- data/lib/vagrant-openstack-provider/action/{is_created.rb → message.rb} +4 -3
- data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +7 -27
- data/lib/vagrant-openstack-provider/action/read_state.rb +7 -9
- data/lib/vagrant-openstack-provider/action/resume.rb +20 -0
- data/lib/vagrant-openstack-provider/action/start_server.rb +22 -0
- data/lib/vagrant-openstack-provider/action/stop_server.rb +22 -0
- data/lib/vagrant-openstack-provider/action/suspend.rb +20 -0
- data/lib/vagrant-openstack-provider/action/sync_folders.rb +27 -38
- data/lib/vagrant-openstack-provider/action/wait_stop.rb +29 -0
- data/lib/vagrant-openstack-provider/client/keystone.rb +76 -0
- data/lib/vagrant-openstack-provider/client/neutron.rb +32 -0
- data/lib/vagrant-openstack-provider/client/nova.rb +166 -0
- data/lib/vagrant-openstack-provider/client/openstack.rb +41 -0
- data/lib/vagrant-openstack-provider/client/utils.rb +38 -0
- data/lib/vagrant-openstack-provider/config.rb +38 -110
- data/lib/vagrant-openstack-provider/errors.rb +7 -3
- data/lib/vagrant-openstack-provider/plugin.rb +8 -8
- data/lib/vagrant-openstack-provider/provider.rb +6 -6
- data/lib/vagrant-openstack-provider/version.rb +1 -1
- data/locales/en.yml +83 -5
- data/numergyrc +22 -0
- data/spec/vagrant-openstack-provider/action/create_server_spec.rb +89 -0
- data/spec/vagrant-openstack-provider/client/keystone_spec.rb +140 -0
- data/spec/vagrant-openstack-provider/client/neutron_spec.rb +53 -0
- data/spec/vagrant-openstack-provider/client/nova_spec.rb +373 -0
- data/spec/vagrant-openstack-provider/client/utils_spec.rb +125 -0
- data/spec/vagrant-openstack-provider/config_spec.rb +117 -0
- data/spec/vagrant-openstack-provider/provider_spec.rb +13 -0
- data/spec/vagrant-openstack-provider/spec_helper.rb +23 -0
- data/vagrant-openstack-provider.gemspec +13 -14
- metadata +40 -30
- data/features/provision.feature +0 -35
- data/features/steps/sdk_steps.rb +0 -13
- data/features/steps/server_steps.rb +0 -25
- data/features/support/env.rb +0 -37
- data/features/support/fog_mock.rb +0 -19
- data/features/vagrant-openstack-provider.feature +0 -70
- data/lib/vagrant-openstack-provider/action/message_already_created.rb +0 -16
- data/lib/vagrant-openstack-provider/action/message_not_created.rb +0 -16
- data/lib/vagrant-openstack-provider/openstack_client.rb +0 -98
- data/spec/vagrant-openstack/config_spec.rb +0 -184
- data/stackrc +0 -31
data/numergyrc
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
export OS_AUTH_URL=https://cloud.numergy.com/identity/v2.0/tokens
|
4
|
+
export OS_COMPUTE_URL=https://cloud.numergy.com/compute/v2
|
5
|
+
|
6
|
+
if [ -z "$OS_USERNAME" ]; then
|
7
|
+
echo "Please enter your OpenStack tenant name: "
|
8
|
+
read -sr OS_TENANT_NAME_INPUT
|
9
|
+
export OS_TENANT_NAME=$OS_TENANT_NAME_INPUT
|
10
|
+
fi
|
11
|
+
|
12
|
+
if [ -z "$OS_USERNAME" ]; then
|
13
|
+
echo "Please enter your OpenStack username: "
|
14
|
+
read -sr OS_USERNAME_INPUT
|
15
|
+
export OS_USERNAME=$OS_USERNAME_INPUT
|
16
|
+
fi
|
17
|
+
|
18
|
+
if [ -z "$OS_PASSWORD" ]; then
|
19
|
+
echo "Please enter your OpenStack Password: "
|
20
|
+
read -sr OS_PASSWORD_INPUT
|
21
|
+
export OS_PASSWORD=$OS_PASSWORD_INPUT
|
22
|
+
fi
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
|
3
|
+
include VagrantPlugins::Openstack::Action
|
4
|
+
|
5
|
+
describe VagrantPlugins::Openstack::Action::CreateServer do
|
6
|
+
|
7
|
+
let(:config) do
|
8
|
+
double('config').tap do |config|
|
9
|
+
config.stub(:openstack_auth_url) { 'http://keystoneAuthV2' }
|
10
|
+
config.stub(:openstack_compute_url) { nil }
|
11
|
+
config.stub(:openstack_network_url) { nil }
|
12
|
+
config.stub(:tenant_name) { 'testTenant' }
|
13
|
+
config.stub(:username) { 'username' }
|
14
|
+
config.stub(:password) { 'password' }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:neutron) do
|
19
|
+
double('neutron').tap do |neutron|
|
20
|
+
neutron.stub(:get_private_networks).with(anything) do
|
21
|
+
[{ id: 'net-id-1', name: 'net-1' }, { id: 'net-id-2', name: 'net-2' }]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:env) do
|
27
|
+
Hash.new.tap do |env|
|
28
|
+
env[:ui] = double('ui')
|
29
|
+
env[:ui].stub(:info).with(anything)
|
30
|
+
env[:machine] = double('machine')
|
31
|
+
env[:machine].stub(:provider_config) { config }
|
32
|
+
env[:openstack_client] = double('openstack_client')
|
33
|
+
env[:openstack_client].stub(:neutron) { neutron }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
before :each do
|
38
|
+
CreateServer.send(:public, *CreateServer.private_instance_methods)
|
39
|
+
@action = CreateServer.new(nil, nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'resolve_networks' do
|
43
|
+
|
44
|
+
context 'with only ids of existing networks' do
|
45
|
+
it 'return the ids array' do
|
46
|
+
config.stub(:networks) { %w(net-id-1 net-id-2) }
|
47
|
+
@action.resolve_networks(env).should eq(%w(net-id-1 net-id-2))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with only names of existing networks' do
|
52
|
+
it 'return the ids array' do
|
53
|
+
config.stub(:networks) { %w(net-1 net-2) }
|
54
|
+
@action.resolve_networks(env).should eq(%w(net-id-1 net-id-2))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with only names and ids of existing networks' do
|
59
|
+
it 'return the ids array' do
|
60
|
+
config.stub(:networks) { %w(net-1 net-id-2) }
|
61
|
+
@action.resolve_networks(env).should eq(%w(net-id-1 net-id-2))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with not existing networks' do
|
66
|
+
it 'return the ids array' do
|
67
|
+
config.stub(:networks) { %w(net-1 net-id-3) }
|
68
|
+
expect { @action.resolve_networks(env) }.to raise_error
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with no network returned by neutron and no network specified in vagrant provider' do
|
73
|
+
it 'return the ids array' do
|
74
|
+
neutron.stub(:get_private_networks).with(anything) { [] }
|
75
|
+
config.stub(:networks) { [] }
|
76
|
+
@action.resolve_networks(env).should eq([])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with no network returned by neutron and one network specified in vagrant provider' do
|
81
|
+
it 'return the ids array' do
|
82
|
+
neutron.stub(:get_private_networks).with(anything) { [] }
|
83
|
+
config.stub(:networks) { ['net-id-1'] }
|
84
|
+
expect { @action.resolve_networks(env) }.to raise_error
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
|
3
|
+
describe VagrantPlugins::Openstack::KeystoneClient do
|
4
|
+
|
5
|
+
let(:config) do
|
6
|
+
double('config').tap do |config|
|
7
|
+
config.stub(:openstack_auth_url) { 'http://keystoneAuthV2' }
|
8
|
+
config.stub(:openstack_compute_url) { nil }
|
9
|
+
config.stub(:openstack_network_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
|
+
describe 'authenticate' do
|
30
|
+
|
31
|
+
let(:keystone_request_headers) do
|
32
|
+
{
|
33
|
+
'Accept' => 'application/json',
|
34
|
+
'Content-Type' => 'application/json'
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:keystone_request_body) do
|
39
|
+
'{"auth":{"tenantName":"testTenant","passwordCredentials":{"username":"username","password":"password"}}}'
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:keystone_response_body) do
|
43
|
+
'{"access":{"token":{"id":"0123456789","tenant":{"id":"testTenantId"}},"serviceCatalog":[
|
44
|
+
{"endpoints":[{"id":"eid1","publicURL":"http://nova"}],"type":"compute"},
|
45
|
+
{"endpoints":[{"id":"eid2","publicURL":"http://neutron"}],"type":"network"}
|
46
|
+
]}}'
|
47
|
+
end
|
48
|
+
|
49
|
+
before :each do
|
50
|
+
@keystone_client = VagrantPlugins::Openstack::KeystoneClient.instance
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with good credentials' do
|
54
|
+
|
55
|
+
it 'store token and tenant id' do
|
56
|
+
stub_request(:post, 'http://keystoneAuthV2')
|
57
|
+
.with(
|
58
|
+
body: keystone_request_body,
|
59
|
+
headers: keystone_request_headers)
|
60
|
+
.to_return(
|
61
|
+
status: 200,
|
62
|
+
body: keystone_response_body,
|
63
|
+
headers: keystone_request_headers)
|
64
|
+
|
65
|
+
@keystone_client.authenticate(env)
|
66
|
+
|
67
|
+
session.token.should eq('0123456789')
|
68
|
+
session.project_id.should eq('testTenantId')
|
69
|
+
session.endpoints[:compute].should eq('http://nova')
|
70
|
+
session.endpoints[:network].should eq('http://neutron')
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with compute endpoint override' do
|
74
|
+
it 'store token and tenant id' do
|
75
|
+
config.stub(:openstack_compute_url) { 'http://novaOverride' }
|
76
|
+
|
77
|
+
stub_request(:post, 'http://keystoneAuthV2')
|
78
|
+
.with(
|
79
|
+
body: keystone_request_body,
|
80
|
+
headers: keystone_request_headers)
|
81
|
+
.to_return(
|
82
|
+
status: 200,
|
83
|
+
body: keystone_response_body,
|
84
|
+
headers: keystone_request_headers)
|
85
|
+
|
86
|
+
@keystone_client.authenticate(env)
|
87
|
+
|
88
|
+
session.token.should eq('0123456789')
|
89
|
+
session.project_id.should eq('testTenantId')
|
90
|
+
session.endpoints[:compute].should eq('http://novaOverride')
|
91
|
+
session.endpoints[:network].should eq('http://neutron')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'with network endpoint override' do
|
96
|
+
it 'store token and tenant id' do
|
97
|
+
config.stub(:openstack_network_url) { 'http://neutronOverride' }
|
98
|
+
|
99
|
+
stub_request(:post, 'http://keystoneAuthV2')
|
100
|
+
.with(
|
101
|
+
body: keystone_request_body,
|
102
|
+
headers: keystone_request_headers)
|
103
|
+
.to_return(
|
104
|
+
status: 200,
|
105
|
+
body: keystone_response_body,
|
106
|
+
headers: keystone_request_headers)
|
107
|
+
|
108
|
+
@keystone_client.authenticate(env)
|
109
|
+
|
110
|
+
session.token.should eq('0123456789')
|
111
|
+
session.project_id.should eq('testTenantId')
|
112
|
+
session.endpoints[:compute].should eq('http://nova')
|
113
|
+
session.endpoints[:network].should eq('http://neutronOverride')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'with wrong credentials' do
|
119
|
+
it 'raise an unauthorized error' do
|
120
|
+
stub_request(:post, 'http://keystoneAuthV2')
|
121
|
+
.with(
|
122
|
+
body: keystone_request_body,
|
123
|
+
headers: keystone_request_headers)
|
124
|
+
.to_return(
|
125
|
+
status: 401,
|
126
|
+
body: '{
|
127
|
+
"error": {
|
128
|
+
"message": "The request you have made requires authentication.",
|
129
|
+
"code": 401,
|
130
|
+
"title": "Unauthorized"
|
131
|
+
}
|
132
|
+
}',
|
133
|
+
headers: keystone_request_headers)
|
134
|
+
|
135
|
+
expect { @keystone_client.authenticate(env) }.to raise_error(RestClient::Unauthorized)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
|
3
|
+
describe VagrantPlugins::Openstack::NeutronClient 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 = { network: 'http://neutron' }
|
17
|
+
@neutron_client = VagrantPlugins::Openstack::NeutronClient.instance
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'get_private_networks' do
|
21
|
+
context 'with token' do
|
22
|
+
it 'returns only private networks for project in session' do
|
23
|
+
|
24
|
+
stub_request(:get, 'http://neutron/networks')
|
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
|
+
"networks": [
|
36
|
+
{ "name": "PublicNetwork", "tenant_id": "admin-tenant-id", "id": "net-pub" },
|
37
|
+
{ "name": "net1", "tenant_id": "a1b2c3", "id": "net-1" },
|
38
|
+
{ "name": "net2", "tenant_id": "a1b2c3", "id": "net-2" }
|
39
|
+
]
|
40
|
+
}
|
41
|
+
')
|
42
|
+
|
43
|
+
networks = @neutron_client.get_private_networks(env)
|
44
|
+
|
45
|
+
expect(networks.length).to eq(2)
|
46
|
+
expect(networks[0][:id]).to eq('net-1')
|
47
|
+
expect(networks[0][:name]).to eq('net1')
|
48
|
+
expect(networks[1][:id]).to eq('net-2')
|
49
|
+
expect(networks[1][:name]).to eq('net2')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,373 @@
|
|
1
|
+
require 'vagrant-openstack-provider/spec_helper'
|
2
|
+
|
3
|
+
describe VagrantPlugins::Openstack::NovaClient do
|
4
|
+
|
5
|
+
let(:config) do
|
6
|
+
double('config').tap do |config|
|
7
|
+
config.stub(:openstack_auth_url) { 'http://novaAuthV2' }
|
8
|
+
config.stub(:openstack_compute_url) { nil }
|
9
|
+
config.stub(:tenant_name) { 'testTenant' }
|
10
|
+
config.stub(:username) { 'username' }
|
11
|
+
config.stub(:password) { 'password' }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:env) do
|
16
|
+
Hash.new.tap do |env|
|
17
|
+
env[:ui] = double('ui')
|
18
|
+
env[:ui].stub(:info).with(anything)
|
19
|
+
env[:machine] = double('machine')
|
20
|
+
env[:machine].stub(:provider_config) { config }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:session) do
|
25
|
+
VagrantPlugins::Openstack.session
|
26
|
+
end
|
27
|
+
|
28
|
+
before :each do
|
29
|
+
session.token = '123456'
|
30
|
+
session.project_id = 'a1b2c3'
|
31
|
+
session.endpoints = { compute: 'http://nova/a1b2c3' }
|
32
|
+
@nova_client = VagrantPlugins::Openstack::NovaClient.instance
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'get_all_flavors' do
|
36
|
+
context 'with token and project_id acquainted' do
|
37
|
+
it 'returns all flavors' do
|
38
|
+
stub_request(:get, 'http://nova/a1b2c3/flavors')
|
39
|
+
.with(
|
40
|
+
headers:
|
41
|
+
{
|
42
|
+
'Accept' => 'application/json',
|
43
|
+
'X-Auth-Token' => '123456'
|
44
|
+
})
|
45
|
+
.to_return(
|
46
|
+
status: 200,
|
47
|
+
body: '{ "flavors": [ { "id": "f1", "name": "flavor1"}, { "id": "f2", "name": "flavor2"} ] }')
|
48
|
+
|
49
|
+
flavors = @nova_client.get_all_flavors(env)
|
50
|
+
|
51
|
+
expect(flavors.length).to eq(2)
|
52
|
+
expect(flavors[0].id).to eq('f1')
|
53
|
+
expect(flavors[0].name).to eq('flavor1')
|
54
|
+
expect(flavors[1].id).to eq('f2')
|
55
|
+
expect(flavors[1].name).to eq('flavor2')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'get_all_images' do
|
61
|
+
context 'with token and project_id acquainted' do
|
62
|
+
it 'returns all images' do
|
63
|
+
stub_request(:get, 'http://nova/a1b2c3/images')
|
64
|
+
.with(
|
65
|
+
headers:
|
66
|
+
{
|
67
|
+
'Accept' => 'application/json',
|
68
|
+
'X-Auth-Token' => '123456'
|
69
|
+
})
|
70
|
+
.to_return(
|
71
|
+
status: 200,
|
72
|
+
body: '{ "images": [ { "id": "i1", "name": "image1"}, { "id": "i2", "name": "image2"} ] }')
|
73
|
+
|
74
|
+
images = @nova_client.get_all_images(env)
|
75
|
+
|
76
|
+
expect(images.length).to eq(2)
|
77
|
+
expect(images[0].id).to eq('i1')
|
78
|
+
expect(images[0].name).to eq('image1')
|
79
|
+
expect(images[1].id).to eq('i2')
|
80
|
+
expect(images[1].name).to eq('image2')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'create_server' do
|
86
|
+
context 'with token and project_id acquainted' do
|
87
|
+
it 'returns new instance id' do
|
88
|
+
|
89
|
+
stub_request(:post, 'http://nova/a1b2c3/servers')
|
90
|
+
.with(
|
91
|
+
body: '{"server":{"name":"inst","imageRef":"img","flavorRef":"flav","key_name":"key"}}',
|
92
|
+
headers:
|
93
|
+
{
|
94
|
+
'Accept' => 'application/json',
|
95
|
+
'Content-Type' => 'application/json',
|
96
|
+
'X-Auth-Token' => '123456'
|
97
|
+
})
|
98
|
+
.to_return(status: 202, body: '{ "server": { "id": "o1o2o3" } }')
|
99
|
+
|
100
|
+
instance_id = @nova_client.create_server(env, 'inst', 'img', 'flav', nil, 'key')
|
101
|
+
|
102
|
+
expect(instance_id).to eq('o1o2o3')
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'with one two networks' do
|
106
|
+
it 'returns new instance id' do
|
107
|
+
|
108
|
+
stub_request(:post, 'http://nova/a1b2c3/servers')
|
109
|
+
.with(
|
110
|
+
body: '{"server":{"name":"inst","imageRef":"img","flavorRef":"flav","key_name":"key","networks":[{"uuid":"net1"},{"uuid":"net2"}]}}',
|
111
|
+
headers:
|
112
|
+
{
|
113
|
+
'Accept' => 'application/json',
|
114
|
+
'Content-Type' => 'application/json',
|
115
|
+
'X-Auth-Token' => '123456'
|
116
|
+
})
|
117
|
+
.to_return(status: 202, body: '{ "server": { "id": "o1o2o3" } }')
|
118
|
+
|
119
|
+
instance_id = @nova_client.create_server(env, 'inst', 'img', 'flav', %w(net1 net2), 'key')
|
120
|
+
|
121
|
+
expect(instance_id).to eq('o1o2o3')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'delete_server' do
|
129
|
+
context 'with token and project_id acquainted' do
|
130
|
+
it 'returns new instance id' do
|
131
|
+
|
132
|
+
stub_request(:delete, 'http://nova/a1b2c3/servers/o1o2o3')
|
133
|
+
.with(
|
134
|
+
headers: {
|
135
|
+
'Accept' => 'application/json',
|
136
|
+
'X-Auth-Token' => '123456'
|
137
|
+
})
|
138
|
+
.to_return(status: 204)
|
139
|
+
|
140
|
+
@nova_client.delete_server(env, 'o1o2o3')
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'suspend_server' do
|
147
|
+
context 'with token and project_id acquainted' do
|
148
|
+
it 'returns new instance id' do
|
149
|
+
|
150
|
+
stub_request(:post, 'http://nova/a1b2c3/servers/o1o2o3/action')
|
151
|
+
.with(
|
152
|
+
body: '{ "suspend": null }',
|
153
|
+
headers:
|
154
|
+
{
|
155
|
+
'Accept' => 'application/json',
|
156
|
+
'Content-Type' => 'application/json',
|
157
|
+
'X-Auth-Token' => '123456'
|
158
|
+
})
|
159
|
+
.to_return(status: 202)
|
160
|
+
|
161
|
+
@nova_client.suspend_server(env, 'o1o2o3')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe 'resume_server' do
|
167
|
+
context 'with token and project_id acquainted' do
|
168
|
+
it 'returns new instance id' do
|
169
|
+
|
170
|
+
stub_request(:post, 'http://nova/a1b2c3/servers/o1o2o3/action')
|
171
|
+
.with(
|
172
|
+
body: '{ "resume": null }',
|
173
|
+
headers:
|
174
|
+
{
|
175
|
+
'Accept' => 'application/json',
|
176
|
+
'Content-Type' => 'application/json',
|
177
|
+
'X-Auth-Token' => '123456'
|
178
|
+
})
|
179
|
+
.to_return(status: 202)
|
180
|
+
|
181
|
+
@nova_client.resume_server(env, 'o1o2o3')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe 'stop_server' do
|
187
|
+
context 'with token and project_id acquainted' do
|
188
|
+
it 'returns new instance id' do
|
189
|
+
|
190
|
+
stub_request(:post, 'http://nova/a1b2c3/servers/o1o2o3/action')
|
191
|
+
.with(
|
192
|
+
body: '{ "os-stop": null }',
|
193
|
+
headers:
|
194
|
+
{
|
195
|
+
'Accept' => 'application/json',
|
196
|
+
'Content-Type' => 'application/json',
|
197
|
+
'X-Auth-Token' => '123456'
|
198
|
+
})
|
199
|
+
.to_return(status: 202)
|
200
|
+
|
201
|
+
@nova_client.stop_server(env, 'o1o2o3')
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe 'start_server' do
|
208
|
+
context 'with token and project_id acquainted' do
|
209
|
+
it 'returns new instance id' do
|
210
|
+
|
211
|
+
stub_request(:post, 'http://nova/a1b2c3/servers/o1o2o3/action')
|
212
|
+
.with(
|
213
|
+
body: '{ "os-start": null }',
|
214
|
+
headers:
|
215
|
+
{
|
216
|
+
'Accept' => 'application/json',
|
217
|
+
'Content-Type' => 'application/json',
|
218
|
+
'X-Auth-Token' => '123456'
|
219
|
+
})
|
220
|
+
.to_return(status: 202)
|
221
|
+
|
222
|
+
@nova_client.start_server(env, 'o1o2o3')
|
223
|
+
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe 'get_server_details' do
|
229
|
+
context 'with token and project_id acquainted' do
|
230
|
+
it 'returns server details' do
|
231
|
+
|
232
|
+
stub_request(:get, 'http://nova/a1b2c3/servers/o1o2o3')
|
233
|
+
.with(headers:
|
234
|
+
{
|
235
|
+
'Accept' => 'application/json',
|
236
|
+
'X-Auth-Token' => '123456'
|
237
|
+
})
|
238
|
+
.to_return(status: 200, body: '
|
239
|
+
{
|
240
|
+
"server": {
|
241
|
+
"addresses": { "private": [ { "addr": "192.168.0.3", "version": 4 } ] },
|
242
|
+
"created": "2012-08-20T21:11:09Z",
|
243
|
+
"flavor": { "id": "1" },
|
244
|
+
"id": "o1o2o3",
|
245
|
+
"image": { "id": "i1" },
|
246
|
+
"name": "new-server-test",
|
247
|
+
"progress": 0,
|
248
|
+
"status": "ACTIVE",
|
249
|
+
"tenant_id": "openstack",
|
250
|
+
"updated": "2012-08-20T21:11:09Z",
|
251
|
+
"user_id": "fake"
|
252
|
+
}
|
253
|
+
}
|
254
|
+
')
|
255
|
+
|
256
|
+
server = @nova_client.get_server_details(env, 'o1o2o3')
|
257
|
+
|
258
|
+
expect(server['id']).to eq('o1o2o3')
|
259
|
+
expect(server['status']).to eq('ACTIVE')
|
260
|
+
expect(server['tenant_id']).to eq('openstack')
|
261
|
+
expect(server['image']['id']).to eq('i1')
|
262
|
+
expect(server['flavor']['id']).to eq('1')
|
263
|
+
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe 'add_floating_ip' do
|
269
|
+
|
270
|
+
context 'with token and project_id acquainted and IP available' do
|
271
|
+
it 'returns server details' do
|
272
|
+
|
273
|
+
stub_request(:get, 'http://nova/a1b2c3/os-floating-ips')
|
274
|
+
.with(headers:
|
275
|
+
{
|
276
|
+
'Accept' => 'application/json',
|
277
|
+
'X-Auth-Token' => '123456'
|
278
|
+
})
|
279
|
+
.to_return(status: 200, body: '
|
280
|
+
{
|
281
|
+
"floating_ips": [
|
282
|
+
{
|
283
|
+
"fixed_ip": null,
|
284
|
+
"id": 1,
|
285
|
+
"instance_id": null,
|
286
|
+
"ip": "1.2.3.4",
|
287
|
+
"pool": "nova"
|
288
|
+
},
|
289
|
+
{
|
290
|
+
"fixed_ip": null,
|
291
|
+
"id": 2,
|
292
|
+
"instance_id": null,
|
293
|
+
"ip": "5.6.7.8",
|
294
|
+
"pool": "nova"
|
295
|
+
}
|
296
|
+
]
|
297
|
+
}')
|
298
|
+
|
299
|
+
stub_request(:post, 'http://nova/a1b2c3/servers/o1o2o3/action')
|
300
|
+
.with(body: '{"addFloatingIp":{"address":"1.2.3.4"}}',
|
301
|
+
headers:
|
302
|
+
{
|
303
|
+
'Accept' => 'application/json',
|
304
|
+
'Content-Type' => 'application/json',
|
305
|
+
'X-Auth-Token' => '123456'
|
306
|
+
})
|
307
|
+
.to_return(status: 202)
|
308
|
+
|
309
|
+
@nova_client.add_floating_ip(env, 'o1o2o3', '1.2.3.4')
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context 'with token and project_id acquainted and IP already in use' do
|
314
|
+
it 'raise an error' do
|
315
|
+
|
316
|
+
stub_request(:get, 'http://nova/a1b2c3/os-floating-ips')
|
317
|
+
.with(headers:
|
318
|
+
{
|
319
|
+
'Accept' => 'application/json',
|
320
|
+
'X-Auth-Token' => '123456'
|
321
|
+
})
|
322
|
+
.to_return(status: 200, body: '
|
323
|
+
{
|
324
|
+
"floating_ips": [
|
325
|
+
{
|
326
|
+
"fixed_ip": null,
|
327
|
+
"id": 1,
|
328
|
+
"instance_id": "inst",
|
329
|
+
"ip": "1.2.3.4",
|
330
|
+
"pool": "nova"
|
331
|
+
},
|
332
|
+
{
|
333
|
+
"fixed_ip": null,
|
334
|
+
"id": 2,
|
335
|
+
"instance_id": null,
|
336
|
+
"ip": "5.6.7.8",
|
337
|
+
"pool": "nova"
|
338
|
+
}
|
339
|
+
]
|
340
|
+
}')
|
341
|
+
|
342
|
+
expect { @nova_client.add_floating_ip(env, 'o1o2o3', '1.2.3.4') }.to raise_error(RuntimeError)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
context 'with token and project_id acquainted and IP not allocated' do
|
347
|
+
it 'raise an error' do
|
348
|
+
|
349
|
+
stub_request(:get, 'http://nova/a1b2c3/os-floating-ips')
|
350
|
+
.with(headers:
|
351
|
+
{
|
352
|
+
'Accept' => 'application/json',
|
353
|
+
'X-Auth-Token' => '123456'
|
354
|
+
})
|
355
|
+
.to_return(status: 200, body: '
|
356
|
+
{
|
357
|
+
"floating_ips": [
|
358
|
+
{
|
359
|
+
"fixed_ip": null,
|
360
|
+
"id": 2,
|
361
|
+
"instance_id": null,
|
362
|
+
"ip": "5.6.7.8",
|
363
|
+
"pool": "nova"
|
364
|
+
}
|
365
|
+
]
|
366
|
+
}')
|
367
|
+
|
368
|
+
expect { @nova_client.add_floating_ip(env, 'o1o2o3', '1.2.3.4') }.to raise_error(RuntimeError)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
end
|
373
|
+
end
|