occi-api 4.3.14 → 4.3.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fce814d6c2a7c043db73c5541ea5c70b5fd2e288
4
- data.tar.gz: bc4d4c17d48337edf1cedaa721ca77d99ba17931
3
+ metadata.gz: f64a3d6fe0539314a30e9706b45f56ab47401377
4
+ data.tar.gz: 629ca876122fbafb32c9471cb281ffb01aa2f9df
5
5
  SHA512:
6
- metadata.gz: 0c0b46c1a5c0b70e73155194e663d75a43d2d3383d1d4b970398ac861b4b5559fb8e53425c7efe1b696e81465b7940b1b14313ad9eb6d80f5dad8a83b6685f6e
7
- data.tar.gz: 2d5242472689a59d10574c7228151abfc538a234f8c0e70530a2f0e9aed91f38410c6172f7e8d07a8b056adce276d4beb4037f10f93e0a68802e0191e7413030
6
+ metadata.gz: cf983b6653c70a5af66b962911aff1433dd72c9d3cfe9ff9ff6a511ee816ac69fd689e5ae2493cb6bce14329655f3a6c95f3d91e44646d643a997e1cc6ba070e
7
+ data.tar.gz: a47d841cc9af98dcc0bac4bde8ff630148490276c42f31e6b58990289fab2471f11e1d5b2d0631862a2360e9d9af6397a72eba596dbca67944ef77e711ec0289
@@ -1,9 +1,7 @@
1
1
  module Occi::Api::Client
2
2
  module Http
3
3
  module AuthnPlugins
4
-
5
4
  class Keystone < Base
6
-
7
5
  KEYSTONE_URI_REGEXP = /^(Keystone|snf-auth) uri=("|')(.+)("|')$/
8
6
  KEYSTONE_VERSION_REGEXP = /^v([0-9]).*$/
9
7
 
@@ -13,33 +11,33 @@ module Occi::Api::Client
13
11
 
14
12
  # discover Keystone API version
15
13
  @env_ref.class.headers.delete 'X-Auth-Token'
16
- if @options[:type] == 'oauth2'
17
- keystone_version = 3
18
- end
14
+
15
+ keystone_version = '3' if @options[:type] == 'oauth2'
19
16
  set_auth_token ENV['ROCCI_CLIENT_KEYSTONE_TENANT'], keystone_version
20
17
 
21
- raise ::Occi::Api::Client::Errors::AuthnError,
22
- "Unable to get a tenant from Keystone, fallback failed!" if @env_ref.class.headers['X-Auth-Token'].blank?
18
+ if @env_ref.class.headers['X-Auth-Token'].blank?
19
+ raise ::Occi::Api::Client::Errors::AuthnError, "Unable to get a tenant from Keystone, fallback failed!"
20
+ end
23
21
  end
24
22
 
25
23
  def authenticate(options = {})
26
24
  # OCCI-OS doesn't support HEAD method!
27
- response = @env_ref.class.get "#{@env_ref.endpoint.to_s}/-/"
25
+ response = @env_ref.class.get "#{@env_ref.endpoint}/-/"
28
26
  raise ::Occi::Api::Client::Errors::AuthnError,
29
- "Authentication failed with code #{response.code.to_s}!" unless response.success?
27
+ "Authentication failed with code #{response.code}!" unless response.success?
30
28
  end
31
29
 
32
30
  private
33
31
 
34
32
  def set_keystone_base_url
35
- response = @env_ref.class.get "#{@env_ref.endpoint.to_s}/-/"
33
+ response = @env_ref.class.get "#{@env_ref.endpoint}/-/"
36
34
  Occi::Api::Log.debug response.inspect
37
35
 
38
36
  return if response.success?
39
37
  raise ::Occi::Api::Client::Errors::AuthnError,
40
- "Keystone AuthN failed with #{response.code.to_s}!" unless response.code == 401
38
+ "Keystone AuthN failed with #{response.code}!" unless response.unauthorized?
41
39
 
42
- process_headers(response)
40
+ process_headers response
43
41
  end
44
42
 
45
43
  def process_headers(response)
@@ -58,48 +56,36 @@ module Occi::Api::Client
58
56
  end
59
57
 
60
58
  def set_auth_token(tenant = nil, keystone_version = nil)
61
- response = @env_ref.class.get @keystone_url
59
+ response = @env_ref.class.get(@keystone_url, :headers => get_req_headers)
62
60
  Occi::Api::Log.debug response.inspect
63
61
 
64
- raise ::Occi::Api::Client::Errors::AuthnError,
65
- "Unable to get Keystone API version from the response, fallback failed!" if (400..599).include?(response.code)
66
-
67
- # multiple choices, sort them by version id (preferred is v2)
68
- if response.code == 300
69
- versions = response['versions']['values'].sort_by { |v| v['id']}
70
- else
71
- # assume a single version
72
- versions = [response['version']]
62
+ unless response.success? || response.multiple_choices?
63
+ raise ::Occi::Api::Client::Errors::AuthnError,
64
+ 'Unable to get Keystone API version from the response, fallback failed!'
73
65
  end
74
66
 
67
+ versions = if response.multiple_choices?
68
+ response['versions']['values'].sort_by { |v| v['id'] } # multiple versions, sort by version id
69
+ else
70
+ [response['version']] # assume a single version
71
+ end
72
+
75
73
  versions.each do |v|
76
74
  match = KEYSTONE_VERSION_REGEXP.match(v['id'])
77
75
  raise ::Occi::Api::Client::Errors::AuthnError,
78
76
  "Unable to get Keystone API version from the response, fallback failed!" unless match && match[1]
79
- if match[1] == '2'
80
- if keystone_version == nil or keystone_version == 2
81
- Occi::Api::Log.debug "Selecting Keystone V2 interface"
82
- handler_class = KeystoneV2
83
- else
84
- next
85
- end
86
- elsif match[1] == '3'
87
- if keystone_version == nil or keystone_version == 3
88
- Occi::Api::Log.debug "Selecting Keystone V3 interface"
89
- handler_class = KeystoneV3
90
- else
91
- next
92
- end
93
- end
77
+ next if keystone_version && keystone_version != match[1]
78
+
79
+ handler_class = match[1] == '3' ? KeystoneV3 : KeystoneV2
94
80
  v['links'].each do |link|
95
81
  begin
96
- if link['rel'] == 'self'
97
- keystone_url = link['href'].chomp('/')
98
- keystone_handler = handler_class.new(keystone_url, @env_ref, @options)
99
- token = keystone_handler.set_auth_token(tenant)
100
- # found a working keystone, stop looking
101
- return
102
- end
82
+ next unless link['rel'] == 'self'
83
+
84
+ keystone_url = link['href'].chomp('/')
85
+ keystone_handler = handler_class.new(keystone_url, @env_ref, @options)
86
+ keystone_handler.set_auth_token tenant
87
+
88
+ return # found a working keystone, stop looking
103
89
  rescue ::Occi::Api::Client::Errors::AuthnError
104
90
  # ignore and try with next link
105
91
  end
@@ -107,6 +93,13 @@ module Occi::Api::Client
107
93
  end
108
94
  end
109
95
 
96
+ def get_req_headers
97
+ headers = @env_ref.class.headers.clone
98
+ headers['Content-Type'] = "application/json"
99
+ headers['Accept'] = headers['Content-Type']
100
+
101
+ headers
102
+ end
110
103
  end
111
104
 
112
105
  class KeystoneV2
@@ -117,14 +110,13 @@ module Occi::Api::Client
117
110
  end
118
111
 
119
112
  def set_auth_token(tenant = nil)
120
- if !tenant.blank?
121
- # get a scoped token for the specified tenant directly
122
- authenticate ENV['ROCCI_CLIENT_KEYSTONE_TENANT']
123
- else
113
+ if tenant.blank?
124
114
  # get an unscoped token, use the unscoped token
125
115
  # for tenant discovery and get a scoped token
126
116
  authenticate
127
117
  get_first_working_tenant
118
+ else
119
+ authenticate tenant
128
120
  end
129
121
  end
130
122
 
@@ -136,12 +128,12 @@ module Occi::Api::Client
136
128
  )
137
129
  Occi::Api::Log.debug response.inspect
138
130
 
139
- if response.success?
140
- @env_ref.class.headers['X-Auth-Token'] = response['access']['token']['id']
141
- else
131
+ if !response.success? || response['access'].blank?
142
132
  raise ::Occi::Api::Client::Errors::AuthnError,
143
133
  "Unable to get a token from Keystone, fallback failed!"
144
134
  end
135
+
136
+ @env_ref.class.headers['X-Auth-Token'] = response['access']['token']['id']
145
137
  end
146
138
 
147
139
  def get_keystone_req(tenant = nil)
@@ -173,16 +165,16 @@ module Occi::Api::Client
173
165
  )
174
166
  Occi::Api::Log.debug response.inspect
175
167
 
176
- raise ::Occi::Api::Client::Errors::AuthnError,
177
- "Keystone didn't return any tenants, fallback failed!" if response['tenants'].blank?
168
+ if !response.success? || response['tenants'].blank?
169
+ raise ::Occi::Api::Client::Errors::AuthnError,
170
+ "Keystone didn't return any tenants, fallback failed!"
171
+ end
178
172
 
179
173
  response['tenants'].each do |tenant|
180
174
  begin
181
175
  Occi::Api::Log.debug "Authenticating for tenant #{tenant['name'].inspect}"
182
- authenticate(tenant['name'])
183
-
184
- # found a working tenant, stop looking
185
- break
176
+ authenticate tenant['name']
177
+ break # found a working tenant, stop looking
186
178
  rescue ::Occi::Api::Client::Errors::AuthnError
187
179
  # ignoring and trying the next tenant
188
180
  end
@@ -214,15 +206,10 @@ module Occi::Api::Client
214
206
  passwd_authenticate
215
207
  else
216
208
  raise ::Occi::Api::Client::Errors::AuthnError,
217
- "Unable to request a token from Keystone! Chosen " \
218
- "AuthN is not supported, fallback failed!"
209
+ "Unable to request a token from Keystone! Chosen AuthN is not supported, fallback failed!"
219
210
  end
220
211
 
221
- if !tenant.blank?
222
- set_scoped_token(tenant)
223
- else
224
- get_first_working_project
225
- end
212
+ tenant.blank? ? get_first_working_project : set_scoped_token(tenant)
226
213
  end
227
214
 
228
215
  def passwd_authenticate
@@ -231,36 +218,37 @@ module Occi::Api::Client
231
218
  end
232
219
 
233
220
  def set_voms_unscoped_token
234
- response = @env_ref.class.post(
221
+ response = @env_ref.class.get(
235
222
  # FIXME(enolfc) egi.eu and mapped below should be configurable
236
223
  "#{@base_url}/OS-FEDERATION/identity_providers/egi.eu/protocols/mapped/auth",
224
+ :headers => get_req_headers
237
225
  )
238
226
  Occi::Api::Log.debug response.inspect
239
227
 
240
- if response.success?
241
- @env_ref.class.headers['X-Auth-Token'] = response.headers['x-subject-token']
242
- else
228
+ if !response.success? || response.headers['x-subject-token'].blank?
243
229
  raise ::Occi::Api::Client::Errors::AuthnError,
244
230
  "Unable to get a token from Keystone, fallback failed!"
245
231
  end
232
+
233
+ @env_ref.class.headers['X-Auth-Token'] = response.headers['x-subject-token']
246
234
  end
247
235
 
248
236
  def set_oauth2_unscoped_token
249
237
  headers = get_req_headers
250
238
  headers['Authorization'] = "Bearer #{@options[:token]}"
251
- response = @env_ref.class.post(
239
+ response = @env_ref.class.get(
252
240
  # FIXME(enolfc) egi.eu and oidc below should be configurable
253
241
  "#{@base_url}/OS-FEDERATION/identity_providers/egi.eu/protocols/oidc/auth",
254
242
  :headers => headers
255
243
  )
256
244
  Occi::Api::Log.debug response.inspect
257
245
 
258
- if response.success?
259
- @env_ref.class.headers['X-Auth-Token'] = response.headers['x-subject-token']
260
- else
246
+ if !response.success? || response.headers['x-subject-token'].blank?
261
247
  raise ::Occi::Api::Client::Errors::AuthnError,
262
248
  "Unable to get a token from Keystone, fallback failed!"
263
249
  end
250
+
251
+ @env_ref.class.headers['X-Auth-Token'] = response.headers['x-subject-token']
264
252
  end
265
253
 
266
254
  def get_first_working_project
@@ -270,16 +258,16 @@ module Occi::Api::Client
270
258
  )
271
259
  Occi::Api::Log.debug response.inspect
272
260
 
273
- raise ::Occi::Api::Client::Errors::AuthnError,
274
- "Keystone didn't return any projects, fallback failed!" if response['projects'].blank?
261
+ if !response.success? || response['projects'].blank?
262
+ raise ::Occi::Api::Client::Errors::AuthnError,
263
+ "Keystone didn't return any projects, fallback failed!"
264
+ end
275
265
 
276
266
  response['projects'].each do |project|
277
267
  begin
278
268
  Occi::Api::Log.debug "Authenticating for project #{project['name'].inspect}"
279
- set_scoped_token(project['id'])
280
-
281
- # found a working project, stop looking
282
- break
269
+ set_scoped_token project['id']
270
+ break # found a working project, stop looking
283
271
  rescue ::Occi::Api::Client::Errors::AuthnError
284
272
  # ignoring and trying the next tenant
285
273
  end
@@ -291,27 +279,27 @@ module Occi::Api::Client
291
279
  "auth" => {
292
280
  "identity" => {
293
281
  "methods" => ["token"],
294
- "token" => {"id" => @env_ref.class.headers['X-Auth-Token'] }
282
+ "token" => { "id" => @env_ref.class.headers['X-Auth-Token'] }
295
283
  },
296
284
  "scope" => {
297
- "project" => {"id" => project}
285
+ "project" => { "id" => project }
298
286
  }
299
287
  }
300
288
  }
289
+
301
290
  response = @env_ref.class.post(
302
291
  "#{@base_url}/auth/tokens",
303
292
  :body => body.to_json,
304
293
  :headers => get_req_headers
305
294
  )
306
-
307
295
  Occi::Api::Log.debug response.inspect
308
296
 
309
- if response.success?
310
- @env_ref.class.headers['X-Auth-Token'] = response.headers['x-subject-token']
311
- else
297
+ if !response.success? || response.headers['x-subject-token'].blank?
312
298
  raise ::Occi::Api::Client::Errors::AuthnError,
313
299
  "Unable to get a token from Keystone, fallback failed!"
314
300
  end
301
+
302
+ @env_ref.class.headers['X-Auth-Token'] = response.headers['x-subject-token']
315
303
  end
316
304
 
317
305
  def get_req_headers
@@ -321,9 +309,7 @@ module Occi::Api::Client
321
309
 
322
310
  headers
323
311
  end
324
-
325
312
  end
326
-
327
313
  end
328
314
  end
329
315
  end
@@ -1,5 +1,5 @@
1
1
  module Occi
2
2
  module Api
3
- VERSION = "4.3.14" unless defined?(::Occi::Api::VERSION)
3
+ VERSION = "4.3.15" unless defined?(::Occi::Api::VERSION)
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: occi-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.14
4
+ version: 4.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Feldhaus
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-08-15 00:00:00.000000000 Z
13
+ date: 2017-10-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: occi-core
@@ -463,7 +463,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
463
463
  version: '0'
464
464
  requirements: []
465
465
  rubyforge_project:
466
- rubygems_version: 2.6.12
466
+ rubygems_version: 2.6.13
467
467
  signing_key:
468
468
  specification_version: 4
469
469
  summary: OCCI development library providing a high-level client API