vagrant-openstack-provider 0.5.2 → 0.6.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 +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
@@ -40,11 +40,13 @@ module VagrantPlugins
|
|
40
40
|
config = env[:machine].provider_config
|
41
41
|
nova = env[:openstack_client].nova
|
42
42
|
return config.floating_ip if config.floating_ip
|
43
|
-
fail Errors::UnableToResolveFloatingIP
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
fail Errors::UnableToResolveFloatingIP if config.floating_ip_pool.nil? || config.floating_ip_pool.empty?
|
44
|
+
@logger.debug 'Searching for available ips'
|
45
|
+
free_ip = search_free_ip(config, nova, env)
|
46
|
+
return free_ip unless free_ip.nil?
|
47
|
+
@logger.debug 'Allocate new ip anyway'
|
48
|
+
allocated_ip = allocate_ip(config, nova, env)
|
49
|
+
return allocated_ip unless allocated_ip.nil?
|
48
50
|
end
|
49
51
|
|
50
52
|
def resolve_keypair(env)
|
@@ -133,6 +135,35 @@ module VagrantPlugins
|
|
133
135
|
|
134
136
|
private
|
135
137
|
|
138
|
+
def search_free_ip(config, nova, env)
|
139
|
+
@logger.debug 'Retrieving all allocated floating ips on tenant'
|
140
|
+
all_floating_ips = nova.get_all_floating_ips(env)
|
141
|
+
all_floating_ips.each do |floating_ip|
|
142
|
+
log_attach = floating_ip.instance_id ? "attached to #{floating_ip.instance_id}" : 'not attached'
|
143
|
+
@logger.debug "#{floating_ip.ip} #{log_attach}" if config.floating_ip_pool.include? floating_ip.pool
|
144
|
+
return floating_ip.ip if (config.floating_ip_pool.include? floating_ip.pool) && floating_ip.instance_id.nil?
|
145
|
+
end unless config.floating_ip_pool_always_allocate
|
146
|
+
@logger.debug 'No free ip found'
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
|
150
|
+
def allocate_ip(config, nova, env)
|
151
|
+
allocation_error = nil
|
152
|
+
config.floating_ip_pool.each do |floating_ip_pool|
|
153
|
+
begin
|
154
|
+
@logger.debug "Allocating ip in pool #{floating_ip_pool}"
|
155
|
+
return nova.allocate_floating_ip(env, floating_ip_pool).ip
|
156
|
+
rescue Errors::VagrantOpenstackError => e
|
157
|
+
@logger.warn "Error allocating ip in pool #{floating_ip_pool} : #{e}"
|
158
|
+
allocation_error = e
|
159
|
+
next if e.extra_data[:code] == 404
|
160
|
+
raise allocation_error
|
161
|
+
end
|
162
|
+
end
|
163
|
+
@logger.warn 'Impossible to allocate a new IP'
|
164
|
+
fail allocation_error
|
165
|
+
end
|
166
|
+
|
136
167
|
def generate_keypair(env)
|
137
168
|
key = SSHKey.generate
|
138
169
|
nova = env[:openstack_client].nova
|
@@ -8,6 +8,10 @@ module VagrantPlugins
|
|
8
8
|
error_key(:default)
|
9
9
|
end
|
10
10
|
|
11
|
+
class Timeout < VagrantOpenstackError
|
12
|
+
error_key(:timeout)
|
13
|
+
end
|
14
|
+
|
11
15
|
class AuthenticationRequired < VagrantOpenstackError
|
12
16
|
error_key(:authentication_required)
|
13
17
|
end
|
@@ -20,8 +24,8 @@ module VagrantPlugins
|
|
20
24
|
error_key(:bad_authentication_endpoint)
|
21
25
|
end
|
22
26
|
|
23
|
-
class
|
24
|
-
error_key(:
|
27
|
+
class NoMatchingApiVersion < VagrantOpenstackError
|
28
|
+
error_key(:no_matching_api_version)
|
25
29
|
end
|
26
30
|
|
27
31
|
class CreateBadState < VagrantOpenstackError
|
@@ -132,6 +136,10 @@ module VagrantPlugins
|
|
132
136
|
error_key(:instance_not_found)
|
133
137
|
end
|
134
138
|
|
139
|
+
class StackNotFound < VagrantOpenstackError
|
140
|
+
error_key(:stack_not_found)
|
141
|
+
end
|
142
|
+
|
135
143
|
class NetworkServiceUnavailable < VagrantOpenstackError
|
136
144
|
error_key(:nerwork_service_unavailable)
|
137
145
|
end
|
@@ -139,6 +147,26 @@ module VagrantPlugins
|
|
139
147
|
class VolumeServiceUnavailable < VagrantOpenstackError
|
140
148
|
error_key(:volume_service_unavailable)
|
141
149
|
end
|
150
|
+
|
151
|
+
class FloatingIPAlreadyAssigned < VagrantOpenstackError
|
152
|
+
error_key(:floating_ip_already_assigned)
|
153
|
+
end
|
154
|
+
|
155
|
+
class FloatingIPNotAvailable < VagrantOpenstackError
|
156
|
+
error_key(:floating_ip_not_available)
|
157
|
+
end
|
158
|
+
|
159
|
+
class ServerStatusError < VagrantOpenstackError
|
160
|
+
error_key(:server_status_error)
|
161
|
+
end
|
162
|
+
|
163
|
+
class StackStatusError < VagrantOpenstackError
|
164
|
+
error_key(:stack_status_error)
|
165
|
+
end
|
166
|
+
|
167
|
+
class MissingNovaEndpoint < VagrantOpenstackError
|
168
|
+
error_key(:missing_nova_endpoint)
|
169
|
+
end
|
142
170
|
end
|
143
171
|
end
|
144
172
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Openstack
|
3
|
+
module Logging
|
4
|
+
# This initializes the logging so that our logs are outputted at
|
5
|
+
# the same level as Vagrant core logs.
|
6
|
+
def self.init
|
7
|
+
# Initialize logging
|
8
|
+
level = nil
|
9
|
+
begin
|
10
|
+
level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
|
11
|
+
rescue NameError
|
12
|
+
# This means that the logging constant wasn't found,
|
13
|
+
# which is fine. We just keep `level` as `nil`. But
|
14
|
+
# we tell the user.
|
15
|
+
begin
|
16
|
+
level = Log4r.const_get(ENV['VAGRANT_OPENSTACK_LOG'].upcase)
|
17
|
+
rescue NameError
|
18
|
+
level = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Some constants, such as "true" resolve to booleans, so the
|
23
|
+
# above error checking doesn't catch it. This will check to make
|
24
|
+
# sure that the log level is an integer, as Log4r requires.
|
25
|
+
level = nil unless level.is_a?(Integer)
|
26
|
+
|
27
|
+
# Set the logging level
|
28
|
+
# logs as long as we have a valid level.
|
29
|
+
if level
|
30
|
+
logger = Log4r::Logger.new('vagrant_openstack')
|
31
|
+
out = Log4r::Outputter.stdout
|
32
|
+
out.formatter = Log4r::PatternFormatter.new(pattern: '%d | %5l | %m', date_pattern: '%Y-%m-%d %H:%M')
|
33
|
+
logger.outputters = out
|
34
|
+
logger.level = level
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/locales/en.yml
CHANGED
@@ -1,9 +1,32 @@
|
|
1
1
|
en:
|
2
2
|
vagrant_openstack:
|
3
|
+
global_error: |-
|
4
|
+
An unknow error happened in Vagrant OpenStack provider
|
5
|
+
|
6
|
+
To easily debug what happened, we recommend to set the environment
|
7
|
+
variable VAGRANT_OPENSTACK_LOG to debug
|
8
|
+
|
9
|
+
$ export VAGRANT_OPENSTACK_LOG=debug
|
10
|
+
|
11
|
+
If doing this does not help fixing your issue, there may be a bug
|
12
|
+
in the provider. Please submit an issue on Github at
|
13
|
+
https://github.com/ggiamarchi/vagrant-openstack-provider
|
14
|
+
with the stracktrace and the logs.
|
15
|
+
|
16
|
+
We are looking for feedback, so feel free to ask questions or
|
17
|
+
describe features you would like to see in this provider.
|
3
18
|
already_created: |-
|
4
19
|
The server is already created.
|
20
|
+
create_stack: |-
|
21
|
+
Creating Heat Stack.
|
22
|
+
delete_stack: |-
|
23
|
+
Deleting Heat Stack.
|
5
24
|
already_suspended: |-
|
6
|
-
The server is already suspended
|
25
|
+
The server is already suspended.
|
26
|
+
ongoing_task: |-
|
27
|
+
The server is currently running a task and cannot execute your request.
|
28
|
+
not_suspended: |-
|
29
|
+
The server is not currently "suspended" and cannot be resumed.
|
7
30
|
deleting_server: |-
|
8
31
|
Deleting server...
|
9
32
|
finding_flavor: |-
|
@@ -40,6 +63,12 @@ en:
|
|
40
63
|
Waiting for the server to stop...
|
41
64
|
waiting_start: |-
|
42
65
|
Waiting for the server to start...
|
66
|
+
waiting_deleted: |-
|
67
|
+
Waiting for the server to be deleted...
|
68
|
+
waiting_for_stack: |-
|
69
|
+
Waiting for Heat Stack to be created...
|
70
|
+
waiting_for_stack_deleted: |-
|
71
|
+
Waiting for Heat Stack to be created...
|
43
72
|
warn_networks: |-
|
44
73
|
Warning! The Openstack provider doesn't support any of the Vagrant
|
45
74
|
high-level network configurations (`config.vm.network`). They
|
@@ -48,6 +77,12 @@ en:
|
|
48
77
|
As Neutron endpoint is not available, the identifier '%{network}' is assumed to be an id (not a name).
|
49
78
|
warn_volume_identifier_is_assumed_to_be_an_id: |-
|
50
79
|
As Cinder endpoint is not available, the identifier '%{volume}' is assumed to be an id (not a name).
|
80
|
+
ssh_disabled_provisioning: |-
|
81
|
+
Provisioning will not be performed because provider config ssh_disabled is set to true
|
82
|
+
ssh_disabled_sync_folders: |-
|
83
|
+
Folders will not be synced because provider config ssh_disabled is set to true
|
84
|
+
disabled_sync_folders: |-
|
85
|
+
Sync folders are disabled in the provider configuration
|
51
86
|
|
52
87
|
config:
|
53
88
|
password_required: |-
|
@@ -56,6 +91,13 @@ en:
|
|
56
91
|
A username is required.
|
57
92
|
invalid_uri: |-
|
58
93
|
The value for %{key} is not a valid URI: %{uri}
|
94
|
+
invalid_stack: |-
|
95
|
+
One of the stacks in the stacks provider configuration is invalid
|
96
|
+
The configuration option should have the following format:
|
97
|
+
os.stacks = [{
|
98
|
+
name: 'mystack',
|
99
|
+
template: '/path/to/heat_template.yml',
|
100
|
+
}]
|
59
101
|
metadata_must_be_hash: |-
|
60
102
|
Metadata must be a hash.
|
61
103
|
keypair_name_required: |-
|
@@ -78,8 +120,14 @@ en:
|
|
78
120
|
errors:
|
79
121
|
default: |-
|
80
122
|
%{message}
|
123
|
+
timeout: |-
|
124
|
+
Timeout occurred
|
81
125
|
authentication_required: |-
|
82
126
|
Authentication token is missing or no longer valid.
|
127
|
+
floating_ip_already_assigned: |-
|
128
|
+
Floating IP %{floating_ip} already assigned to another server
|
129
|
+
floating_ip_not_available: |-
|
130
|
+
Floating IP %{floating_ip} not available for this tenant
|
83
131
|
authentication_failed: |-
|
84
132
|
Authentication failed.
|
85
133
|
bad_authentication_endpoint: |-
|
@@ -89,11 +137,11 @@ en:
|
|
89
137
|
state: '%{state}', instead of properly booting. Run `vagrant status`
|
90
138
|
to find out what can be done about this state, or `vagrant destroy`
|
91
139
|
if you want to start over.
|
92
|
-
|
93
|
-
|
140
|
+
no_matching_api_version: |-
|
141
|
+
No matching version found for %{api_name} API
|
94
142
|
|
95
143
|
%{version_list}
|
96
|
-
You must specify the desired
|
144
|
+
You must specify the desired %{api_name} API url by setting
|
97
145
|
the provider's property '%{url_property}'.
|
98
146
|
no_matching_flavor: |-
|
99
147
|
No matching flavor was found! Please check your flavor setting
|
@@ -158,12 +206,21 @@ en:
|
|
158
206
|
Dashboard instead of using vagrant commands.
|
159
207
|
We recommend using the command `vagrant openstack reset` to reset
|
160
208
|
vagrant to a clear state
|
209
|
+
stack_not_found: |-
|
210
|
+
Heat stack not found
|
161
211
|
nerwork_service_unavailable: |-
|
162
212
|
Neutron service endpoint is not available, thus there is not way to retrieve
|
163
213
|
network id from its name. You have to provide only ids in your Vagrantfile.
|
164
214
|
volume_service_unavailable: |-
|
165
215
|
Cinder service endpoint is not available, thus there is not way to retrieve
|
166
216
|
volume id from its name. You have to provide only ids in your Vagrantfile.
|
217
|
+
server_status_error: |-
|
218
|
+
Server '%{server}' is in error status.
|
219
|
+
stack_status_error: |-
|
220
|
+
Heat Stack '%{stack}' is in error status.
|
221
|
+
missing_nova_endpoint: |-
|
222
|
+
Nova endpoint must either be present in your keystone service catalog or be
|
223
|
+
specified using the provider's attribute 'openstack_compute_url'
|
167
224
|
|
168
225
|
states:
|
169
226
|
short_active: |-
|
@@ -239,6 +296,50 @@ en:
|
|
239
296
|
not created
|
240
297
|
long_not_created: |-
|
241
298
|
The server is not created. Run `vagrant up` to create it.
|
299
|
+
short_suspending: |-
|
300
|
+
suspending
|
301
|
+
long_suspending: |-
|
302
|
+
The server is active and currently suspending, either by request or necessity.
|
303
|
+
short_resuming: |-
|
304
|
+
resuming
|
305
|
+
long_resuming: |-
|
306
|
+
The server is suspended and currently resuming by request.
|
307
|
+
short_spawning: |-
|
308
|
+
spawning
|
309
|
+
long_spawning: |-
|
310
|
+
The server is not created yet but is currently spawning by request.
|
311
|
+
short_scheduling: |-
|
312
|
+
scheduling
|
313
|
+
long_scheduling: |-
|
314
|
+
The server is building and currently scheduling by necessity.
|
315
|
+
short_deleting: |-
|
316
|
+
deleting
|
317
|
+
long_deleting: |-
|
318
|
+
The server is created and currently deleting by request.
|
319
|
+
short_rebooting: |-
|
320
|
+
rebooting
|
321
|
+
long_rebooting: |-
|
322
|
+
The server is currently rebooting, either by request or necessity.
|
323
|
+
short_reboot_pending: |-
|
324
|
+
reboot_pending
|
325
|
+
long_reboot_pending: |-
|
326
|
+
The server reboot is pending by necessity.
|
327
|
+
short_reboot_started: |-
|
328
|
+
reboot_started
|
329
|
+
long_reboot_started: |-
|
330
|
+
The server is starting to reboot, either by request or necessity.
|
331
|
+
short_rebooting_hard: |-
|
332
|
+
rebooting_hard
|
333
|
+
long_rebooting_hard: |-
|
334
|
+
The server is currently hard rebooting, either by request.
|
335
|
+
short_reboot_pending_hard: |-
|
336
|
+
reboot_pending_hard
|
337
|
+
long_reboot_pending_hard: |-
|
338
|
+
The server hard reboot is pending by necessity.
|
339
|
+
short_reboot_started_hard: |-
|
340
|
+
reboot_started_hard
|
341
|
+
long_reboot_started_hard: |-
|
342
|
+
The server is starting to hard reboot by request.
|
242
343
|
|
243
344
|
client:
|
244
345
|
looking_for_available_endpoints: |-
|
@@ -261,6 +362,8 @@ en:
|
|
261
362
|
List available flavors
|
262
363
|
network_list_synopsis : |-
|
263
364
|
List private networks in project
|
365
|
+
subnet_list_synopsis : |-
|
366
|
+
List subnets for available networks
|
264
367
|
flaotingip_list_synopsis : |-
|
265
368
|
List floating IP and floating IP pools
|
266
369
|
volume_list_synopsis : |-
|
@@ -17,9 +17,11 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
17
17
|
config.stub(:openstack_compute_url) { nil }
|
18
18
|
config.stub(:openstack_network_url) { nil }
|
19
19
|
config.stub(:openstack_volume_url) { nil }
|
20
|
+
config.stub(:openstack_image_url) { nil }
|
20
21
|
config.stub(:tenant_name) { 'testTenant' }
|
21
22
|
config.stub(:username) { 'username' }
|
22
23
|
config.stub(:password) { 'password' }
|
24
|
+
config.stub(:region) { nil }
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -42,6 +44,82 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
47
|
+
let(:neutron_france) do
|
48
|
+
double.tap do |neutron|
|
49
|
+
neutron.stub(:get_api_version_list).with(anything) do
|
50
|
+
[
|
51
|
+
{
|
52
|
+
'status' => 'CURRENT',
|
53
|
+
'id' => 'v2.0',
|
54
|
+
'links' => [
|
55
|
+
{
|
56
|
+
'href' => 'http://france.neutron/v2.0',
|
57
|
+
'rel' => 'self'
|
58
|
+
}
|
59
|
+
]
|
60
|
+
}
|
61
|
+
]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:glance) do
|
67
|
+
double.tap do |glance|
|
68
|
+
glance.stub(:get_api_version_list).with(anything) do
|
69
|
+
[
|
70
|
+
{
|
71
|
+
'status' => 'CURRENT',
|
72
|
+
'id' => 'v2.1',
|
73
|
+
'links' => [
|
74
|
+
{
|
75
|
+
'href' => 'http://glance/v2.0',
|
76
|
+
'rel' => 'self'
|
77
|
+
}
|
78
|
+
]
|
79
|
+
}
|
80
|
+
]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
let(:glance_v1) do
|
86
|
+
double.tap do |glance|
|
87
|
+
glance.stub(:get_api_version_list).with(anything) do
|
88
|
+
[
|
89
|
+
{
|
90
|
+
'status' => 'CURRENT',
|
91
|
+
'id' => 'v1.0',
|
92
|
+
'links' => [
|
93
|
+
{
|
94
|
+
'href' => 'http://glance/v1',
|
95
|
+
'rel' => 'self'
|
96
|
+
}
|
97
|
+
]
|
98
|
+
}
|
99
|
+
]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
let(:glance_france) do
|
105
|
+
double.tap do |glance|
|
106
|
+
glance.stub(:get_api_version_list).with(anything) do
|
107
|
+
[
|
108
|
+
{
|
109
|
+
'status' => 'CURRENT',
|
110
|
+
'id' => 'v2.1',
|
111
|
+
'links' => [
|
112
|
+
{
|
113
|
+
'href' => 'http://france.glance/v2.0',
|
114
|
+
'rel' => 'self'
|
115
|
+
}
|
116
|
+
]
|
117
|
+
}
|
118
|
+
]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
45
123
|
let(:env) do
|
46
124
|
Hash.new.tap do |env|
|
47
125
|
env[:ui] = double
|
@@ -51,6 +129,7 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
51
129
|
env[:machine].stub(:provider_config) { config }
|
52
130
|
env[:openstack_client] = double('openstack_client')
|
53
131
|
env[:openstack_client].stub(:neutron) { neutron }
|
132
|
+
env[:openstack_client].stub(:glance) { glance }
|
54
133
|
end
|
55
134
|
end
|
56
135
|
|
@@ -86,6 +165,26 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
86
165
|
],
|
87
166
|
'type' => 'network',
|
88
167
|
'name' => 'neutron'
|
168
|
+
},
|
169
|
+
{
|
170
|
+
'endpoints' => [
|
171
|
+
{
|
172
|
+
'publicURL' => 'http://cinder/v2/projectId',
|
173
|
+
'id' => '2'
|
174
|
+
}
|
175
|
+
],
|
176
|
+
'type' => 'volume',
|
177
|
+
'name' => 'cinder'
|
178
|
+
},
|
179
|
+
{
|
180
|
+
'endpoints' => [
|
181
|
+
{
|
182
|
+
'publicURL' => 'http://glance',
|
183
|
+
'id' => '2'
|
184
|
+
}
|
185
|
+
],
|
186
|
+
'type' => 'image',
|
187
|
+
'name' => 'glance'
|
89
188
|
}
|
90
189
|
]
|
91
190
|
|
@@ -93,18 +192,103 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
93
192
|
keystone.stub(:authenticate).with(anything) { catalog }
|
94
193
|
env[:openstack_client].stub(:keystone) { keystone }
|
95
194
|
end
|
96
|
-
env[:openstack_client].stub(:neutron)
|
195
|
+
env[:openstack_client].stub(:neutron) { neutron }
|
196
|
+
env[:openstack_client].stub(:glance) { glance }
|
97
197
|
|
98
198
|
@action.call(env)
|
99
199
|
|
100
200
|
expect(env[:openstack_client].session.endpoints)
|
101
|
-
.to eq(compute: 'http://nova/v2/projectId',
|
201
|
+
.to eq(compute: 'http://nova/v2/projectId',
|
202
|
+
network: 'http://neutron/v2.0',
|
203
|
+
volume: 'http://cinder/v2/projectId',
|
204
|
+
image: 'http://glance/v2.0')
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'with multiple regions' do
|
209
|
+
it 'read service catalog and stores endpoints URL for desired regions in session' do
|
210
|
+
catalog = [
|
211
|
+
{
|
212
|
+
'endpoints' => [
|
213
|
+
{
|
214
|
+
'publicURL' => 'http://france.nova/v2/projectId',
|
215
|
+
'id' => '1',
|
216
|
+
'region' => 'france'
|
217
|
+
},
|
218
|
+
{
|
219
|
+
'publicURL' => 'http://us.nova/v2/projectId',
|
220
|
+
'id' => '4',
|
221
|
+
'region' => 'us'
|
222
|
+
}
|
223
|
+
],
|
224
|
+
'type' => 'compute',
|
225
|
+
'name' => 'nova'
|
226
|
+
},
|
227
|
+
{
|
228
|
+
'endpoints' => [
|
229
|
+
{
|
230
|
+
'publicURL' => 'http://france.neutron',
|
231
|
+
'id' => '2',
|
232
|
+
'region' => 'france'
|
233
|
+
},
|
234
|
+
{
|
235
|
+
'publicURL' => 'http://us.neutron',
|
236
|
+
'id' => '5',
|
237
|
+
'region' => 'us'
|
238
|
+
}
|
239
|
+
],
|
240
|
+
'type' => 'network',
|
241
|
+
'name' => 'neutron'
|
242
|
+
},
|
243
|
+
{
|
244
|
+
'endpoints' => [
|
245
|
+
{
|
246
|
+
'publicURL' => 'http://france.glance',
|
247
|
+
'id' => '3',
|
248
|
+
'region' => 'france'
|
249
|
+
},
|
250
|
+
{
|
251
|
+
'publicURL' => 'http://us.glance',
|
252
|
+
'id' => '6',
|
253
|
+
'region' => 'us'
|
254
|
+
}
|
255
|
+
],
|
256
|
+
'type' => 'image',
|
257
|
+
'name' => 'glance'
|
258
|
+
}
|
259
|
+
]
|
260
|
+
|
261
|
+
double.tap do |keystone|
|
262
|
+
keystone.stub(:authenticate).with(anything) { catalog }
|
263
|
+
env[:openstack_client].stub(:keystone) { keystone }
|
264
|
+
end
|
265
|
+
|
266
|
+
env[:openstack_client].stub(:neutron) { neutron_france }
|
267
|
+
env[:openstack_client].stub(:glance) { glance_france }
|
268
|
+
config.stub(:region) { 'france' }
|
269
|
+
|
270
|
+
@action.call(env)
|
271
|
+
|
272
|
+
expect(env[:openstack_client].session.endpoints)
|
273
|
+
.to eq(compute: 'http://france.nova/v2/projectId',
|
274
|
+
network: 'http://france.neutron/v2.0',
|
275
|
+
image: 'http://france.glance/v2.0')
|
102
276
|
end
|
103
277
|
end
|
104
278
|
|
105
279
|
context 'with multiple endpoints for a service' do
|
106
280
|
it 'takes the first one' do
|
107
281
|
catalog = [
|
282
|
+
{
|
283
|
+
'endpoints' => [
|
284
|
+
{
|
285
|
+
'publicURL' => 'http://nova',
|
286
|
+
'id' => '1'
|
287
|
+
}
|
288
|
+
],
|
289
|
+
'type' => 'compute',
|
290
|
+
'name' => 'nova'
|
291
|
+
},
|
108
292
|
{
|
109
293
|
'endpoints' => [
|
110
294
|
{
|
@@ -129,11 +313,74 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
129
313
|
|
130
314
|
@action.call(env)
|
131
315
|
|
132
|
-
expect(env[:openstack_client].session.endpoints).to eq(network: 'http://neutron/v2.0')
|
316
|
+
expect(env[:openstack_client].session.endpoints).to eq(compute: 'http://nova', network: 'http://neutron/v2.0')
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
context 'with glance v1 only' do
|
321
|
+
it 'read service catalog and stores endpoints URL in session', :focus do
|
322
|
+
catalog = [
|
323
|
+
{
|
324
|
+
'endpoints' => [
|
325
|
+
{
|
326
|
+
'publicURL' => 'http://nova/v2/projectId',
|
327
|
+
'id' => '1'
|
328
|
+
}
|
329
|
+
],
|
330
|
+
'type' => 'compute',
|
331
|
+
'name' => 'nova'
|
332
|
+
},
|
333
|
+
{
|
334
|
+
'endpoints' => [
|
335
|
+
{
|
336
|
+
'publicURL' => 'http://glance',
|
337
|
+
'id' => '2'
|
338
|
+
}
|
339
|
+
],
|
340
|
+
'type' => 'image',
|
341
|
+
'name' => 'glance'
|
342
|
+
}
|
343
|
+
]
|
344
|
+
|
345
|
+
double.tap do |keystone|
|
346
|
+
keystone.stub(:authenticate).with(anything) { catalog }
|
347
|
+
env[:openstack_client].stub(:keystone) { keystone }
|
348
|
+
end
|
349
|
+
env[:openstack_client].stub(:glance) { glance_v1 }
|
350
|
+
|
351
|
+
@action.call(env)
|
352
|
+
|
353
|
+
expect(env[:openstack_client].session.endpoints)
|
354
|
+
.to eq(compute: 'http://nova/v2/projectId',
|
355
|
+
image: 'http://glance/v1')
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
context 'with nova endpoint missing' do
|
360
|
+
it 'raise an error' do
|
361
|
+
catalog = [
|
362
|
+
{
|
363
|
+
'endpoints' => [
|
364
|
+
{
|
365
|
+
'publicURL' => 'http://keystone',
|
366
|
+
'id' => '1'
|
367
|
+
}
|
368
|
+
],
|
369
|
+
'type' => 'identity',
|
370
|
+
'name' => 'keystone'
|
371
|
+
}
|
372
|
+
]
|
373
|
+
|
374
|
+
double.tap do |keystone|
|
375
|
+
keystone.stub(:authenticate).with(anything) { catalog }
|
376
|
+
env[:openstack_client].stub(:keystone) { keystone }
|
377
|
+
end
|
378
|
+
|
379
|
+
expect { @action.call(env) }.to raise_error Errors::MissingNovaEndpoint
|
133
380
|
end
|
134
381
|
end
|
135
382
|
|
136
|
-
context 'with
|
383
|
+
context 'with no matching versions for network service' do
|
137
384
|
|
138
385
|
let(:neutron) do
|
139
386
|
double.tap do |neutron|
|
@@ -141,10 +388,10 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
141
388
|
[
|
142
389
|
{
|
143
390
|
'status' => 'CURRENT',
|
144
|
-
'id' => '
|
391
|
+
'id' => 'v1.1',
|
145
392
|
'links' => [
|
146
393
|
{
|
147
|
-
'href' => 'http://neutron/
|
394
|
+
'href' => 'http://neutron/v1.1',
|
148
395
|
'rel' => 'self'
|
149
396
|
}
|
150
397
|
]
|
@@ -164,7 +411,7 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
164
411
|
end
|
165
412
|
end
|
166
413
|
|
167
|
-
it 'raise
|
414
|
+
it 'raise an error' do
|
168
415
|
catalog = [
|
169
416
|
{
|
170
417
|
'endpoints' => [
|
@@ -184,7 +431,7 @@ describe VagrantPlugins::Openstack::Action::ConnectOpenstack do
|
|
184
431
|
end
|
185
432
|
env[:openstack_client].stub(:neutron) { neutron }
|
186
433
|
|
187
|
-
expect { @action.call(env) }.to raise_error(Errors::
|
434
|
+
expect { @action.call(env) }.to raise_error(Errors::NoMatchingApiVersion)
|
188
435
|
end
|
189
436
|
end
|
190
437
|
|