fog-openstack 0.1.31 → 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 +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -1
- data/.travis.yml +5 -5
- data/.zuul.yaml +8 -8
- data/Rakefile +14 -4
- data/fog-openstack.gemspec +3 -2
- data/lib/fog/baremetal/openstack.rb +6 -24
- data/lib/fog/compute/openstack.rb +6 -27
- data/lib/fog/compute/openstack/requests/create_security_group.rb +1 -1
- data/lib/fog/compute/openstack/requests/create_server.rb +1 -1
- data/lib/fog/compute/openstack/requests/evacuate_server.rb +1 -5
- data/lib/fog/container_infra/openstack.rb +6 -25
- data/lib/fog/dns/openstack/v1.rb +5 -17
- data/lib/fog/dns/openstack/v2.rb +5 -22
- data/lib/fog/event/openstack.rb +5 -24
- data/lib/fog/identity/openstack.rb +24 -71
- data/lib/fog/identity/openstack/v2.rb +6 -4
- data/lib/fog/identity/openstack/v3.rb +5 -11
- data/lib/fog/image/openstack/v1.rb +8 -21
- data/lib/fog/image/openstack/v2.rb +8 -21
- data/lib/fog/image/openstack/v2/models/image.rb +1 -1
- data/lib/fog/introspection/openstack.rb +4 -19
- data/lib/fog/key_manager/openstack.rb +5 -47
- data/lib/fog/metering/openstack.rb +8 -23
- data/lib/fog/metric/openstack.rb +7 -26
- data/lib/fog/monitoring/openstack.rb +3 -12
- data/lib/fog/network/openstack.rb +5 -26
- data/lib/fog/network/openstack/requests/set_tenant.rb +0 -1
- data/lib/fog/nfv/openstack.rb +4 -24
- data/lib/fog/openstack.rb +17 -431
- data/lib/fog/openstack/auth/catalog.rb +64 -0
- data/lib/fog/openstack/auth/catalog/v2.rb +23 -0
- data/lib/fog/openstack/auth/catalog/v3.rb +23 -0
- data/lib/fog/openstack/auth/name.rb +65 -0
- data/lib/fog/openstack/auth/token.rb +69 -0
- data/lib/fog/openstack/auth/token/v2.rb +70 -0
- data/lib/fog/openstack/auth/token/v3.rb +116 -0
- data/lib/fog/openstack/core.rb +100 -76
- data/lib/fog/openstack/version.rb +1 -1
- data/lib/fog/orchestration/openstack.rb +4 -21
- data/lib/fog/planning/openstack.rb +13 -23
- data/lib/fog/shared_file_system/openstack.rb +10 -27
- data/lib/fog/storage/openstack.rb +6 -11
- data/lib/fog/volume/openstack.rb +1 -1
- data/lib/fog/volume/openstack/models/backup.rb +2 -2
- data/lib/fog/volume/openstack/requests/restore_backup.rb +2 -2
- data/lib/fog/volume/openstack/requests/update_volume.rb +12 -1
- data/lib/fog/volume/openstack/v1.rb +4 -21
- data/lib/fog/volume/openstack/v1/models/volume.rb +1 -2
- data/lib/fog/volume/openstack/v1/requests/update_volume.rb +0 -17
- data/lib/fog/volume/openstack/v2.rb +4 -21
- data/lib/fog/volume/openstack/v2/models/volume.rb +1 -1
- data/lib/fog/volume/openstack/v2/requests/update_volume.rb +0 -18
- data/lib/fog/workflow/openstack/v2.rb +5 -22
- data/playbooks/fog-openstack-unittest-spec/run.yaml +2 -1
- data/playbooks/fog-openstack-unittest-test/run.yaml +2 -1
- data/unit/auth/catalog_test.rb +252 -0
- data/unit/auth/name_test.rb +115 -0
- data/unit/auth/token_test.rb +478 -0
- data/unit/auth_helper.rb +102 -0
- data/unit/test_helper.rb +6 -0
- metadata +41 -16
- data/lib/fog/compute/openstack/requests/list_tenants.rb +0 -43
@@ -12,7 +12,7 @@ module Fog
|
|
12
12
|
:openstack_project_name, :openstack_project_id,
|
13
13
|
:openstack_project_domain, :openstack_user_domain, :openstack_domain_name,
|
14
14
|
:openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id,
|
15
|
-
:
|
15
|
+
:openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl
|
16
16
|
|
17
17
|
model_path 'fog/monitoring/openstack/models'
|
18
18
|
model :metric
|
@@ -78,17 +78,8 @@ module Fog
|
|
78
78
|
Fog::Monitoring::OpenStack::NotFound
|
79
79
|
end
|
80
80
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
@openstack_service_type = options[:openstack_service_type] || ['monitoring']
|
85
|
-
@openstack_service_name = options[:openstack_service_name]
|
86
|
-
|
87
|
-
@connection_options = options[:connection_options] || {}
|
88
|
-
|
89
|
-
authenticate
|
90
|
-
@persistent = options[:persistent] || false
|
91
|
-
@connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
81
|
+
def default_service_type
|
82
|
+
%w[monitoring]
|
92
83
|
end
|
93
84
|
end
|
94
85
|
end
|
@@ -3,8 +3,6 @@
|
|
3
3
|
module Fog
|
4
4
|
module Network
|
5
5
|
class OpenStack < Fog::Service
|
6
|
-
SUPPORTED_VERSIONS = /v2(\.0)*/
|
7
|
-
|
8
6
|
requires :openstack_auth_url
|
9
7
|
recognizes :openstack_auth_token, :openstack_management_url,
|
10
8
|
:persistent, :openstack_service_type, :openstack_service_name,
|
@@ -15,7 +13,7 @@ module Fog
|
|
15
13
|
:openstack_project_name, :openstack_project_id,
|
16
14
|
:openstack_project_domain, :openstack_user_domain, :openstack_domain_name,
|
17
15
|
:openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id,
|
18
|
-
:
|
16
|
+
:openstack_identity_api_version
|
19
17
|
|
20
18
|
## MODELS
|
21
19
|
#
|
@@ -429,8 +427,6 @@ module Fog
|
|
429
427
|
def initialize(options = {})
|
430
428
|
@auth_token = Fog::Mock.random_base64(64)
|
431
429
|
@auth_token_expiration = (Time.now.utc + 86400).iso8601
|
432
|
-
|
433
|
-
initialize_identity options
|
434
430
|
end
|
435
431
|
|
436
432
|
def data
|
@@ -449,29 +445,12 @@ module Fog
|
|
449
445
|
Fog::Network::OpenStack::NotFound
|
450
446
|
end
|
451
447
|
|
452
|
-
def
|
453
|
-
|
454
|
-
|
455
|
-
@openstack_service_type = options[:openstack_service_type] || ['network']
|
456
|
-
@openstack_service_name = options[:openstack_service_name]
|
457
|
-
|
458
|
-
@connection_options = options[:connection_options] || {}
|
459
|
-
|
460
|
-
authenticate
|
461
|
-
set_api_path
|
462
|
-
|
463
|
-
@persistent = options[:persistent] || false
|
464
|
-
@connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
448
|
+
def default_path_prefix
|
449
|
+
'v2.0'
|
465
450
|
end
|
466
451
|
|
467
|
-
def
|
468
|
-
|
469
|
-
unless @path.match(SUPPORTED_VERSIONS)
|
470
|
-
@path = Fog::OpenStack.get_supported_version_path(SUPPORTED_VERSIONS,
|
471
|
-
@openstack_management_uri,
|
472
|
-
@auth_token,
|
473
|
-
@connection_options)
|
474
|
-
end
|
452
|
+
def default_service_type
|
453
|
+
%w[network]
|
475
454
|
end
|
476
455
|
end
|
477
456
|
end
|
data/lib/fog/nfv/openstack.rb
CHANGED
@@ -82,8 +82,6 @@ module Fog
|
|
82
82
|
def initialize(options = {})
|
83
83
|
@auth_token = Fog::Mock.random_base64(64)
|
84
84
|
@auth_token_expiration = (Time.now.utc + 86_400).iso8601
|
85
|
-
|
86
|
-
initialize_identity options
|
87
85
|
end
|
88
86
|
|
89
87
|
def data
|
@@ -102,30 +100,12 @@ module Fog
|
|
102
100
|
Fog::NFV::OpenStack::NotFound
|
103
101
|
end
|
104
102
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
@openstack_service_type = options[:openstack_service_type] || ['servicevm']
|
109
|
-
@openstack_service_name = options[:openstack_service_name]
|
110
|
-
|
111
|
-
@connection_options = options[:connection_options] || {}
|
112
|
-
|
113
|
-
authenticate
|
114
|
-
set_api_path
|
115
|
-
|
116
|
-
@persistent = options[:persistent] || false
|
117
|
-
@connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
103
|
+
def default_path_prefix
|
104
|
+
'v1.0'
|
118
105
|
end
|
119
106
|
|
120
|
-
def
|
121
|
-
|
122
|
-
@path = "/" + Fog::OpenStack.get_supported_version(
|
123
|
-
SUPPORTED_VERSIONS,
|
124
|
-
@openstack_management_uri,
|
125
|
-
@auth_token,
|
126
|
-
@connection_options
|
127
|
-
)
|
128
|
-
end
|
107
|
+
def default_service_type
|
108
|
+
%w[servicevm]
|
129
109
|
end
|
130
110
|
end
|
131
111
|
end
|
data/lib/fog/openstack.rb
CHANGED
@@ -84,6 +84,8 @@ module Fog
|
|
84
84
|
end
|
85
85
|
|
86
86
|
module OpenStack
|
87
|
+
require 'fog/openstack/auth/token'
|
88
|
+
|
87
89
|
autoload :VERSION, 'fog/openstack/version'
|
88
90
|
|
89
91
|
autoload :Core, 'fog/openstack/core'
|
@@ -123,425 +125,10 @@ module Fog
|
|
123
125
|
Fog::OpenStack.token_cache = {}
|
124
126
|
end
|
125
127
|
|
126
|
-
def self.authenticate(options, connection_options = {})
|
127
|
-
case options[:openstack_auth_uri].path
|
128
|
-
when /v1(\.\d+)?/
|
129
|
-
authenticate_v1(options, connection_options)
|
130
|
-
when /v2(\.\d+)?/
|
131
|
-
authenticate_v2(options, connection_options)
|
132
|
-
when /v3(\.\d+)?/
|
133
|
-
authenticate_v3(options, connection_options)
|
134
|
-
else
|
135
|
-
authenticate_v2(options, connection_options)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# legacy v1.0 style auth
|
140
|
-
def self.authenticate_v1(options, connection_options = {})
|
141
|
-
uri = options[:openstack_auth_uri]
|
142
|
-
connection = Fog::Core::Connection.new(uri.to_s, false, connection_options)
|
143
|
-
@openstack_api_key = options[:openstack_api_key]
|
144
|
-
@openstack_username = options[:openstack_username]
|
145
|
-
|
146
|
-
response = connection.request({
|
147
|
-
:expects => [200, 204],
|
148
|
-
:headers => {
|
149
|
-
'X-Auth-Key' => @openstack_api_key,
|
150
|
-
'X-Auth-User' => @openstack_username
|
151
|
-
},
|
152
|
-
:method => 'GET',
|
153
|
-
:path => (uri.path and not uri.path.empty?) ? uri.path : 'v1.0'
|
154
|
-
})
|
155
|
-
|
156
|
-
return {
|
157
|
-
:token => response.headers['X-Auth-Token'],
|
158
|
-
:server_management_url => response.headers['X-Server-Management-Url'] || response.headers['X-Storage-Url'],
|
159
|
-
:identity_public_endpoint => response.headers['X-Keystone']
|
160
|
-
}
|
161
|
-
end
|
162
|
-
|
163
|
-
# Keystone Style Auth
|
164
|
-
def self.authenticate_v2(options, connection_options = {})
|
165
|
-
uri = options[:openstack_auth_uri]
|
166
|
-
tenant_name = options[:openstack_tenant]
|
167
|
-
service_type = options[:openstack_service_type]
|
168
|
-
service_name = options[:openstack_service_name]
|
169
|
-
identity_service_type = options[:openstack_identity_service_type]
|
170
|
-
endpoint_type = (options[:openstack_endpoint_type] || 'publicURL').to_s
|
171
|
-
openstack_region = options[:openstack_region]
|
172
|
-
|
173
|
-
body = retrieve_tokens_v2(options, connection_options)
|
174
|
-
service = get_service(body, service_type, service_name)
|
175
|
-
|
176
|
-
options[:unscoped_token] = body['access']['token']['id']
|
177
|
-
|
178
|
-
unless service
|
179
|
-
unless tenant_name
|
180
|
-
response = Fog::Core::Connection.new(
|
181
|
-
"#{uri.scheme}://#{uri.host}:#{uri.port}/v2.0/tenants", false, connection_options).request({
|
182
|
-
:expects => [200, 204],
|
183
|
-
:headers => {'Content-Type' => 'application/json',
|
184
|
-
'Accept' => 'application/json',
|
185
|
-
'X-Auth-Token' => body['access']['token']['id']},
|
186
|
-
:method => 'GET'
|
187
|
-
})
|
188
|
-
|
189
|
-
body = Fog::JSON.decode(response.body)
|
190
|
-
if body['tenants'].empty?
|
191
|
-
raise Fog::Errors::NotFound.new('No Tenant Found')
|
192
|
-
else
|
193
|
-
options[:openstack_tenant] = body['tenants'].first['name']
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
body = retrieve_tokens_v2(options, connection_options)
|
198
|
-
service = get_service(body, service_type, service_name)
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
|
-
unless service
|
203
|
-
available = body['access']['serviceCatalog'].map { |endpoint|
|
204
|
-
endpoint['type']
|
205
|
-
}.sort.join ', '
|
206
|
-
|
207
|
-
missing = service_type.join ', '
|
208
|
-
|
209
|
-
message = "Could not find service #{missing}. Have #{available}"
|
210
|
-
|
211
|
-
raise Fog::Errors::NotFound, message
|
212
|
-
end
|
213
|
-
|
214
|
-
service['endpoints'] = service['endpoints'].select do |endpoint|
|
215
|
-
endpoint['region'] == openstack_region
|
216
|
-
end if openstack_region
|
217
|
-
|
218
|
-
if service['endpoints'].empty?
|
219
|
-
raise Fog::Errors::NotFound.new("No endpoints available for region '#{openstack_region}'")
|
220
|
-
end if openstack_region
|
221
|
-
|
222
|
-
regions = service["endpoints"].map{ |e| e['region'] }.uniq
|
223
|
-
if regions.count > 1
|
224
|
-
raise Fog::Errors::NotFound.new("Multiple regions available choose one of these '#{regions.join(',')}'")
|
225
|
-
end
|
226
|
-
|
227
|
-
identity_service = get_service(body, identity_service_type) if identity_service_type
|
228
|
-
tenant = body['access']['token']['tenant']
|
229
|
-
user = body['access']['user']
|
230
|
-
|
231
|
-
management_url = service['endpoints'].find{|s| s[endpoint_type]}[endpoint_type]
|
232
|
-
identity_url = identity_service['endpoints'].find{|s| s['publicURL']}['publicURL'] if identity_service
|
233
|
-
|
234
|
-
{
|
235
|
-
:user => user,
|
236
|
-
:tenant => tenant,
|
237
|
-
:identity_public_endpoint => identity_url,
|
238
|
-
:server_management_url => management_url,
|
239
|
-
:token => body['access']['token']['id'],
|
240
|
-
:expires => body['access']['token']['expires'],
|
241
|
-
:current_user_id => body['access']['user']['id'],
|
242
|
-
:unscoped_token => options[:unscoped_token]
|
243
|
-
}
|
244
|
-
end
|
245
|
-
|
246
|
-
# Keystone Style Auth
|
247
|
-
def self.authenticate_v3(options, connection_options = {})
|
248
|
-
uri = options[:openstack_auth_uri]
|
249
|
-
project_name = options[:openstack_project_name]
|
250
|
-
service_type = options[:openstack_service_type]
|
251
|
-
service_name = options[:openstack_service_name]
|
252
|
-
identity_service_type = options[:openstack_identity_service_type]
|
253
|
-
endpoint_type = map_endpoint_type(options[:openstack_endpoint_type] || 'publicURL')
|
254
|
-
openstack_region = options[:openstack_region]
|
255
|
-
|
256
|
-
token, body = retrieve_tokens_v3 options, connection_options
|
257
|
-
|
258
|
-
service = get_service_v3(body, service_type, service_name, openstack_region, options)
|
259
|
-
|
260
|
-
options[:unscoped_token] = token
|
261
|
-
|
262
|
-
unless service
|
263
|
-
unless project_name
|
264
|
-
request_body = {
|
265
|
-
:expects => [200],
|
266
|
-
:headers => {'Content-Type' => 'application/json',
|
267
|
-
'Accept' => 'application/json',
|
268
|
-
'X-Auth-Token' => token},
|
269
|
-
:method => 'GET'
|
270
|
-
}
|
271
|
-
user_id = body['token']['user']['id']
|
272
|
-
project_uri = uri.clone
|
273
|
-
project_uri.path = uri.path.sub('/auth/tokens', "/users/#{user_id}/projects")
|
274
|
-
project_uri_param = "#{project_uri.scheme}://#{project_uri.host}:#{project_uri.port}#{project_uri.path}"
|
275
|
-
response = Fog::Core::Connection.new(project_uri_param, false, connection_options).request(request_body)
|
276
|
-
|
277
|
-
projects_body = Fog::JSON.decode(response.body)
|
278
|
-
if projects_body['projects'].empty?
|
279
|
-
options[:openstack_domain_id] = body['token']['user']['domain']['id']
|
280
|
-
else
|
281
|
-
options[:openstack_project_id] = projects_body['projects'].first['id']
|
282
|
-
options[:openstack_project_name] = projects_body['projects'].first['name']
|
283
|
-
options[:openstack_domain_id] = projects_body['projects'].first['domain_id']
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
token, body = retrieve_tokens_v3(options, connection_options)
|
288
|
-
service = get_service_v3(body, service_type, service_name, openstack_region, options)
|
289
|
-
end
|
290
|
-
|
291
|
-
# If no identity endpoint is found, try the auth uri (slicing /auth/tokens)
|
292
|
-
# It covers the case where identityv3 endpoint is not present in the catalog but we have to use it
|
293
|
-
unless service
|
294
|
-
if service_type.include? "identity"
|
295
|
-
identity_uri = uri.to_s.sub('/auth/tokens', '')
|
296
|
-
response = Fog::Core::Connection.new(identity_uri, false, connection_options).request({:method => 'GET'})
|
297
|
-
if response.status == 200
|
298
|
-
service = {
|
299
|
-
"endpoints" => [{
|
300
|
-
"url" => identity_uri,
|
301
|
-
"region" => openstack_region,
|
302
|
-
"interface" => endpoint_type
|
303
|
-
}],
|
304
|
-
"type" => service_type,
|
305
|
-
"name" => service_name
|
306
|
-
}
|
307
|
-
end
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
unless service
|
312
|
-
available_services = body['token']['catalog'].map { |service|
|
313
|
-
service['type']
|
314
|
-
}.sort.join ', '
|
315
|
-
|
316
|
-
available_regions = body['token']['catalog'].map { |service|
|
317
|
-
service['endpoints'].map { |endpoint|
|
318
|
-
endpoint['region']
|
319
|
-
}.uniq
|
320
|
-
}.uniq.sort.join ', '
|
321
|
-
|
322
|
-
missing = service_type.join ', '
|
323
|
-
|
324
|
-
message = "Could not find service #{missing}#{(' in region '+openstack_region) if openstack_region}."+
|
325
|
-
" Have #{available_services}#{(' in regions '+available_regions) if openstack_region}"
|
326
|
-
|
327
|
-
raise Fog::Errors::NotFound, message
|
328
|
-
end
|
329
|
-
|
330
|
-
service['endpoints'] = service['endpoints'].select do |endpoint|
|
331
|
-
endpoint['region'] == openstack_region && endpoint['interface'] == endpoint_type
|
332
|
-
end if openstack_region
|
333
|
-
|
334
|
-
if service['endpoints'].empty?
|
335
|
-
raise Fog::Errors::NotFound.new("No endpoints available for region '#{openstack_region}'")
|
336
|
-
end if openstack_region
|
337
|
-
|
338
|
-
regions = service["endpoints"].map { |e| e['region'] }.uniq
|
339
|
-
if regions.count > 1
|
340
|
-
raise Fog::Errors::NotFound.new("Multiple regions available choose one of these '#{regions.join(',')}'")
|
341
|
-
end
|
342
|
-
|
343
|
-
identity_service = get_service_v3(body, identity_service_type, nil, nil, :openstack_endpoint_path_matches => /\/v3/) if identity_service_type
|
344
|
-
|
345
|
-
management_url = service['endpoints'].find { |e| e['interface']==endpoint_type }['url']
|
346
|
-
identity_url = identity_service['endpoints'].find { |e| e['interface']=='public' }['url'] if identity_service
|
347
|
-
|
348
|
-
if body['token']['project']
|
349
|
-
tenant = body['token']['project']
|
350
|
-
elsif body['token']['user']['project']
|
351
|
-
tenant = body['token']['user']['project']
|
352
|
-
end
|
353
|
-
|
354
|
-
return {
|
355
|
-
:user => body['token']['user']['name'],
|
356
|
-
:tenant => tenant,
|
357
|
-
:identity_public_endpoint => identity_url,
|
358
|
-
:server_management_url => management_url,
|
359
|
-
:token => token,
|
360
|
-
:expires => body['token']['expires_at'],
|
361
|
-
:current_user_id => body['token']['user']['id'],
|
362
|
-
:unscoped_token => options[:unscoped_token]
|
363
|
-
}
|
364
|
-
end
|
365
|
-
|
366
|
-
def self.get_service(body, service_type=[], service_name=nil)
|
367
|
-
if not body['access'].nil?
|
368
|
-
body['access']['serviceCatalog'].find do |s|
|
369
|
-
if service_name.nil? or service_name.empty?
|
370
|
-
service_type.include?(s['type'])
|
371
|
-
else
|
372
|
-
service_type.include?(s['type']) and s['name'] == service_name
|
373
|
-
end
|
374
|
-
end
|
375
|
-
elsif not body['token']['catalog'].nil?
|
376
|
-
body['token']['catalog'].find do |s|
|
377
|
-
if service_name.nil? or service_name.empty?
|
378
|
-
service_type.include?(s['type'])
|
379
|
-
else
|
380
|
-
service_type.include?(s['type']) and s['name'] == service_name
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
def self.retrieve_tokens_v2(options, connection_options = {})
|
388
|
-
api_key = options[:openstack_api_key].to_s
|
389
|
-
username = options[:openstack_username].to_s
|
390
|
-
tenant_name = options[:openstack_tenant].to_s
|
391
|
-
auth_token = options[:openstack_auth_token] || options[:unscoped_token]
|
392
|
-
uri = options[:openstack_auth_uri]
|
393
|
-
omit_default_port = options[:openstack_auth_omit_default_port]
|
394
|
-
|
395
|
-
identity_v2_connection = Fog::Core::Connection.new(uri.to_s, false, connection_options)
|
396
|
-
request_body = {:auth => Hash.new}
|
397
|
-
|
398
|
-
if auth_token
|
399
|
-
request_body[:auth][:token] = {
|
400
|
-
:id => auth_token
|
401
|
-
}
|
402
|
-
else
|
403
|
-
request_body[:auth][:passwordCredentials] = {
|
404
|
-
:username => username,
|
405
|
-
:password => api_key
|
406
|
-
}
|
407
|
-
end
|
408
|
-
request_body[:auth][:tenantName] = tenant_name if tenant_name
|
409
|
-
|
410
|
-
request = {
|
411
|
-
:expects => [200, 204],
|
412
|
-
:headers => {'Content-Type' => 'application/json'},
|
413
|
-
:body => Fog::JSON.encode(request_body),
|
414
|
-
:method => 'POST',
|
415
|
-
:path => (uri.path and not uri.path.empty?) ? uri.path : 'v2.0'
|
416
|
-
}
|
417
|
-
request[:omit_default_port] = omit_default_port unless omit_default_port.nil?
|
418
|
-
|
419
|
-
response = identity_v2_connection.request(request)
|
420
|
-
|
421
|
-
Fog::JSON.decode(response.body)
|
422
|
-
end
|
423
|
-
|
424
|
-
def self.retrieve_tokens_v3(options, connection_options = {})
|
425
|
-
|
426
|
-
api_key = options[:openstack_api_key].to_s
|
427
|
-
username = options[:openstack_username].to_s
|
428
|
-
userid = options[:openstack_userid]
|
429
|
-
domain_id = options[:openstack_domain_id]
|
430
|
-
domain_name = options[:openstack_domain_name]
|
431
|
-
project_domain = options[:openstack_project_domain]
|
432
|
-
project_domain_id = options[:openstack_project_domain_id]
|
433
|
-
user_domain = options[:openstack_user_domain]
|
434
|
-
user_domain_id = options[:openstack_user_domain_id]
|
435
|
-
project_name = options[:openstack_project_name]
|
436
|
-
project_id = options[:openstack_project_id]
|
437
|
-
auth_token = options[:openstack_auth_token] || options[:unscoped_token]
|
438
|
-
uri = options[:openstack_auth_uri]
|
439
|
-
omit_default_port = options[:openstack_auth_omit_default_port]
|
440
|
-
cache_ttl = options[:openstack_cache_ttl] || 0
|
441
|
-
|
442
|
-
connection = Fog::Core::Connection.new(uri.to_s, false, connection_options)
|
443
|
-
request_body = {:auth => {}}
|
444
|
-
|
445
|
-
scope = {}
|
446
|
-
|
447
|
-
if project_name || project_id
|
448
|
-
scope[:project] = if project_id.nil? then
|
449
|
-
if project_domain || project_domain_id
|
450
|
-
{:name => project_name, :domain => project_domain_id.nil? ? {:name => project_domain} : {:id => project_domain_id}}
|
451
|
-
else
|
452
|
-
{:name => project_name, :domain => domain_id.nil? ? {:name => domain_name} : {:id => domain_id}}
|
453
|
-
end
|
454
|
-
else
|
455
|
-
{:id => project_id}
|
456
|
-
end
|
457
|
-
elsif domain_name || domain_id
|
458
|
-
scope[:domain] = domain_id.nil? ? {:name => domain_name} : {:id => domain_id}
|
459
|
-
else
|
460
|
-
# unscoped token
|
461
|
-
end
|
462
|
-
|
463
|
-
if auth_token
|
464
|
-
request_body[:auth][:identity] = {
|
465
|
-
:methods => %w{token},
|
466
|
-
:token => {
|
467
|
-
:id => auth_token
|
468
|
-
}
|
469
|
-
}
|
470
|
-
else
|
471
|
-
request_body[:auth][:identity] = {
|
472
|
-
:methods => %w{password},
|
473
|
-
:password => {
|
474
|
-
:user => {
|
475
|
-
:password => api_key
|
476
|
-
}
|
477
|
-
}
|
478
|
-
}
|
479
|
-
|
480
|
-
if userid
|
481
|
-
request_body[:auth][:identity][:password][:user][:id] = userid
|
482
|
-
else
|
483
|
-
if user_domain || user_domain_id
|
484
|
-
request_body[:auth][:identity][:password][:user].merge! :domain => user_domain_id.nil? ? {:name => user_domain} : {:id => user_domain_id}
|
485
|
-
elsif domain_name || domain_id
|
486
|
-
request_body[:auth][:identity][:password][:user].merge! :domain => domain_id.nil? ? {:name => domain_name} : {:id => domain_id}
|
487
|
-
end
|
488
|
-
request_body[:auth][:identity][:password][:user][:name] = username
|
489
|
-
end
|
490
|
-
|
491
|
-
end
|
492
|
-
request_body[:auth][:scope] = scope unless scope.empty?
|
493
|
-
|
494
|
-
path = (uri.path and not uri.path.empty?) ? uri.path : 'v3'
|
495
|
-
|
496
|
-
response, expires = Fog::OpenStack.token_cache[{:body => request_body, :path => path}] if cache_ttl > 0
|
497
|
-
|
498
|
-
unless response && expires > Time.now
|
499
|
-
request = {
|
500
|
-
:expects => [201],
|
501
|
-
:headers => {'Content-Type' => 'application/json'},
|
502
|
-
:body => Fog::JSON.encode(request_body),
|
503
|
-
:method => 'POST',
|
504
|
-
:path => path
|
505
|
-
}
|
506
|
-
request[:omit_default_port] = omit_default_port unless omit_default_port.nil?
|
507
|
-
|
508
|
-
response = connection.request(request)
|
509
|
-
if cache_ttl > 0
|
510
|
-
cache = Fog::OpenStack.token_cache
|
511
|
-
cache[{:body => request_body, :path => path}] = response, Time.now + cache_ttl
|
512
|
-
Fog::OpenStack.token_cache = cache
|
513
|
-
end
|
514
|
-
end
|
515
|
-
|
516
|
-
[response.headers["X-Subject-Token"], Fog::JSON.decode(response.body)]
|
517
|
-
end
|
518
|
-
|
519
|
-
def self.get_service_v3(hash, service_type=[], service_name=nil, region=nil, options={})
|
520
|
-
|
521
|
-
# Find all services matching any of the types in service_type, filtered by service_name if it's non-nil
|
522
|
-
services = hash['token']['catalog'].find_all do |s|
|
523
|
-
if service_name.nil? or service_name.empty?
|
524
|
-
service_type.include?(s['type'])
|
525
|
-
else
|
526
|
-
service_type.include?(s['type']) and s['name'] == service_name
|
527
|
-
end
|
528
|
-
end if hash['token']['catalog']
|
529
|
-
|
530
|
-
# Filter the found services by region (if specified) and whether the endpoint path matches the given regex (e.g. /\/v3/)
|
531
|
-
services.find do |s|
|
532
|
-
s['endpoints'].any? { |ep| endpoint_region?(ep, region) && endpoint_path_match?(ep, options[:openstack_endpoint_path_matches])}
|
533
|
-
end if services
|
534
|
-
|
535
|
-
end
|
536
|
-
|
537
128
|
def self.endpoint_region?(endpoint, region)
|
538
129
|
region.nil? || endpoint['region'] == region
|
539
130
|
end
|
540
131
|
|
541
|
-
def self.endpoint_path_match?(endpoint, match_regex)
|
542
|
-
match_regex.nil? || URI(endpoint['url']).path =~ match_regex
|
543
|
-
end
|
544
|
-
|
545
132
|
def self.get_supported_version(supported_versions, uri, auth_token, connection_options = {})
|
546
133
|
supported_version = get_version(supported_versions, uri, auth_token, connection_options)
|
547
134
|
version = supported_version['id'] if supported_version
|
@@ -571,22 +158,14 @@ module Fog
|
|
571
158
|
end
|
572
159
|
end
|
573
160
|
|
574
|
-
def self.map_endpoint_type type
|
575
|
-
case type
|
576
|
-
when "publicURL"
|
577
|
-
"public"
|
578
|
-
when "internalURL"
|
579
|
-
"internal"
|
580
|
-
when "adminURL"
|
581
|
-
"admin"
|
582
|
-
end
|
583
|
-
|
584
|
-
end
|
585
|
-
|
586
161
|
def self.get_version(supported_versions, uri, auth_token, connection_options = {})
|
587
162
|
version_cache = "#{uri}#{supported_versions}"
|
588
163
|
return @version[version_cache] if @version && @version[version_cache]
|
589
|
-
|
164
|
+
|
165
|
+
# To allow version discovery we need a "version less" endpoint
|
166
|
+
path = uri.path.gsub(/\/v([1-9]+\d*)(\.[1-9]+\d*)*.*$/, '/')
|
167
|
+
url = "#{uri.scheme}://#{uri.host}:#{uri.port}#{path}"
|
168
|
+
connection = Fog::Core::Connection.new(url, false, connection_options)
|
590
169
|
response = connection.request(
|
591
170
|
:expects => [200, 204, 300],
|
592
171
|
:headers => {'Content-Type' => 'application/json',
|
@@ -602,10 +181,17 @@ module Fog
|
|
602
181
|
end
|
603
182
|
|
604
183
|
def self.extract_version_from_body(body, supported_versions)
|
605
|
-
|
606
|
-
|
184
|
+
versions = []
|
185
|
+
unless body['versions'].nil? || body['versions'].empty?
|
186
|
+
versions = body['versions'].kind_of?(Array) ? body['versions'] : body['versions']['values']
|
187
|
+
end
|
188
|
+
# Some version API would return single endpoint rather than endpoints list, try to get it via 'version'.
|
189
|
+
unless body['version'].nil? or versions.length != 0
|
190
|
+
versions = [body['version']]
|
191
|
+
end
|
607
192
|
version = nil
|
608
|
-
|
193
|
+
|
194
|
+
# order is important, preferred status should be first
|
609
195
|
%w(CURRENT stable SUPPORTED DEPRECATED).each do |status|
|
610
196
|
version = versions.find { |x| x['id'].match(supported_versions) && (x['status'] == status) }
|
611
197
|
break if version
|