ovirt-engine-sdk 4.0.2 → 4.0.3

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.
@@ -0,0 +1,34 @@
1
+ /*
2
+ Copyright (c) 2016 Red Hat, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ #ifndef __OV_HTTP_RESPONSE_H__
18
+ #define __OV_HTTP_RESPONSE_H__
19
+
20
+ /* Classes: */
21
+ VALUE ov_http_response_class;
22
+
23
+ /* Content: */
24
+ typedef struct {
25
+ VALUE body; /* String */
26
+ VALUE code; /* Integer */
27
+ VALUE headers; /* Hash<String, String> */
28
+ VALUE message; /* String */
29
+ } ov_http_response_object;
30
+
31
+ /* Initialization function: */
32
+ extern void ov_http_response_define(void);
33
+
34
+ #endif
@@ -18,15 +18,21 @@ limitations under the License.
18
18
 
19
19
  #include "ov_module.h"
20
20
  #include "ov_error.h"
21
+ #include "ov_http_client.h"
22
+ #include "ov_http_request.h"
23
+ #include "ov_http_response.h"
21
24
  #include "ov_xml_reader.h"
22
25
  #include "ov_xml_writer.h"
23
26
 
24
27
  void Init_ovirtsdk4c(void) {
25
- // Define the module:
28
+ /* Define the module: */
26
29
  ov_module_define();
27
30
 
28
- // Define the classes:
31
+ /* Define the classes: */
29
32
  ov_error_define();
33
+ ov_http_client_define();
34
+ ov_http_request_define();
35
+ ov_http_response_define();
30
36
  ov_xml_reader_define();
31
37
  ov_xml_writer_define();
32
38
  }
@@ -14,76 +14,27 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'curb'
18
17
  require 'json'
19
18
  require 'uri'
20
19
 
21
20
  module OvirtSDK4
22
21
 
23
- #
24
- # This class represents an HTTP request.
25
- #
26
- # @api private
27
- #
28
- class Request
29
- attr_accessor :method
30
- attr_accessor :path
31
- attr_accessor :query
32
- attr_accessor :headers
33
- attr_accessor :body
34
-
35
- #
36
- # Creates a new HTTP request.
37
- #
38
- def initialize(opts = {})
39
- self.method = opts[:method] || :GET
40
- self.path = opts[:path] || ''
41
- self.headers = opts[:headers] || {}
42
- self.query = opts[:query] || {}
43
- self.body = opts[:body]
44
- end
45
-
46
- end
47
-
48
- #
49
- # This class represents an HTTP response.
50
- #
51
- # @api private
52
- #
53
- class Response
54
- attr_accessor :body
55
- attr_accessor :code
56
- attr_accessor :headers
57
- attr_accessor :message
58
-
59
- #
60
- # Creates a new HTTP response.
61
- #
62
- def initialize(opts = {})
63
- self.body = opts[:body]
64
- self.code = opts[:code]
65
- self.headers = opts[:headers]
66
- self.message = opts[:message]
67
- end
68
- end
69
-
70
22
  #
71
23
  # This class is responsible for managing an HTTP connection to the engine server. It is intended as the entry
72
24
  # point for the SDK, and it provides access to the `system` service and, from there, to the rest of the services
73
25
  # provided by the API.
74
26
  #
75
27
  class Connection
76
-
77
28
  #
78
29
  # Creates a new connection to the API server.
79
30
  #
80
31
  # [source,ruby]
81
32
  # ----
82
33
  # connection = OvirtSDK4::Connection.new(
83
- # :url => 'https://engine.example.com/ovirt-engine/api',
34
+ # :url => 'https://engine.example.com/ovirt-engine/api',
84
35
  # :username => 'admin@internal',
85
36
  # :password => '...',
86
- # :ca_file => '/etc/pki/ovirt-engine/ca.pem',
37
+ # :ca_file => '/etc/pki/ovirt-engine/ca.pem',
87
38
  # )
88
39
  # ----
89
40
  #
@@ -92,11 +43,11 @@ module OvirtSDK4
92
43
  # @option opts [String] :url A string containing the base URL of the server, usually something like
93
44
  # `\https://server.example.com/ovirt-engine/api`.
94
45
  #
95
- # @option opts [String] :user The name of the user, something like `admin@internal`.
46
+ # @option opts [String] :username The name of the user, something like `admin@internal`.
96
47
  #
97
48
  # @option opts [String] :password The password of the user.
98
49
  #
99
- # @options opts [String] :token The token used to authenticate. Optionally the caller can explicitly provide
50
+ # @option opts [String] :token The token used to authenticate. Optionally the caller can explicitly provide
100
51
  # the token, instead of the user name and password. If the token isn't provided then it will be automatically
101
52
  # created.
102
53
  #
@@ -113,8 +64,8 @@ module OvirtSDK4
113
64
  #
114
65
  # @option opts [Logger] :log The logger where the log messages will be written.
115
66
  #
116
- # @option opts [Boolean] :kerberos (false) A boolean flag indicating if Kerberos uthentication should be used
117
- # instead of the default basic authentication.
67
+ # @option opts [Boolean] :kerberos (false) A boolean flag indicating if Kerberos authentication should be used
68
+ # instead of user name and password to obtain the OAuth token.
118
69
  #
119
70
  # @option opts [Integer] :timeout (0) The maximun total time to wait for the response, in seconds. A value of zero
120
71
  # (the default) means wait for ever. If the timeout expires before the response is received an exception will be
@@ -137,58 +88,16 @@ module OvirtSDK4
137
88
  @kerberos = opts[:kerberos] || false
138
89
  @timeout = opts[:timeout] || 0
139
90
  @compress = opts[:compress] || false
140
- @auth = opts[:auth] || :oauth
141
-
142
- # Check mandatory parameters:
143
- if url.nil?
144
- raise ArgumentError.new("The 'url' parameter is mandatory.")
145
- end
146
-
147
- # Save the URL:
148
- @url = URI(@url)
149
-
150
- # Create the cURL handle:
151
- @curl = Curl::Easy.new
152
-
153
- # Configure TLS parameters:
154
- if @url.scheme == 'https'
155
- if @insecure
156
- @curl.ssl_verify_peer = false
157
- @curl.ssl_verify_host = false
158
- elsif !@ca_file.nil?
159
- raise ArgumentError.new("The CA file '#{@ca_file}' doesn't exist.") unless ::File.file?(@ca_file)
160
- @curl.cacert = @ca_file
161
- end
162
- end
163
-
164
- # Configure the timeout:
165
- @curl.timeout = @timeout
166
91
 
167
- # Configure compression of responses (setting the value to a zero length string means accepting all the
168
- # compression types that libcurl supports):
169
- if @compress
170
- @curl.encoding = ''
171
- end
172
-
173
- # Configure debug mode:
174
- if @debug && @log
175
- @curl.verbose = true
176
- @curl.on_debug do |_, data|
177
- lines = data.gsub("\r\n", "\n").strip.split("\n")
178
- lines.each do |line|
179
- @log.debug(line)
180
- end
181
- end
182
- end
183
- end
184
-
185
- #
186
- # Returns the base URL of this connection.
187
- #
188
- # @return [String]
189
- #
190
- def url
191
- return @url
92
+ # Create the HTTP client:
93
+ @client = HttpClient.new(
94
+ :insecure => @insecure,
95
+ :ca_file => @ca_file,
96
+ :debug => @debug,
97
+ :log => @log,
98
+ :timeout => @timeout,
99
+ :compress => @compress,
100
+ )
192
101
  end
193
102
 
194
103
  #
@@ -198,7 +107,6 @@ module OvirtSDK4
198
107
  #
199
108
  def system_service
200
109
  @system_service ||= SystemService.new(self, "")
201
- return @system_service
202
110
  end
203
111
 
204
112
  #
@@ -217,40 +125,38 @@ module OvirtSDK4
217
125
  #
218
126
  # Sends an HTTP request and waits for the response.
219
127
  #
220
- # @param request [Request] The Request object containing the details of the HTTP request to send.
128
+ # @param request [HttpRequest] The request object containing the details of the HTTP request to send.
221
129
  # @return [Response] A request object containing the details of the HTTP response received.
222
130
  #
223
131
  # @api private
224
132
  #
225
133
  def send(request)
226
- # Build the URL:
227
- @curl.url = build_url({
228
- :path => request.path,
229
- :query => request.query,
230
- })
231
-
232
- set_headers!(request)
233
- set_authentication!
234
- # Clear any data that may be in the buffers:
235
- @curl.post_body = nil
236
- # Send the request and wait for the response:
237
- case request.method
238
- when :DELETE
239
- @curl.http_delete
240
- when :GET
241
- @curl.http_get
242
- when :PUT
243
- @curl.http_put(request.body)
244
- when :HEAD
245
- @curl.http_head
246
- when :POST
247
- @curl.http_post(request.body)
134
+ # Add the base URL to the request:
135
+ if request.url.nil?
136
+ request.url = @url
137
+ else
138
+ request.url = "#{@url}#{request.url}"
248
139
  end
249
140
 
141
+ # Set the headers:
142
+ request.headers.merge!(
143
+ 'User-Agent' => "RubySDK/#{VERSION}",
144
+ 'Version' => '4',
145
+ 'Content-Type' => 'application/xml',
146
+ 'Accept' => 'application/xml',
147
+ )
148
+
149
+ # Set the authentication token:
150
+ @token ||= get_access_token
151
+ request.token = @token
152
+
153
+ # Create an empty response:
154
+ response = HttpResponse.new
155
+
156
+ # Send the request and wait for the response:
157
+ @client.send(request, response)
158
+
250
159
  # Return the response:
251
- response = Response.new
252
- response.body = @curl.body_str
253
- response.code = @curl.response_code
254
160
  return response
255
161
  end
256
162
 
@@ -273,7 +179,7 @@ module OvirtSDK4
273
179
  end
274
180
 
275
181
  unless response['error'].nil?
276
- raise Error.new("Error during SSO authentication #{response['error_code']}: #{response['error']}")
182
+ raise Error.new("Error during SSO authentication: #{response['error_code']}: #{response['error']}")
277
183
  end
278
184
 
279
185
  response['access_token']
@@ -295,7 +201,7 @@ module OvirtSDK4
295
201
  end
296
202
 
297
203
  unless response['error'].nil?
298
- raise Error.new("Error during SSO revoke #{response['error_code']}: #{response['error']}")
204
+ raise Error.new("Error during SSO revoke: #{response['error_code']}: #{response['error']}")
299
205
  end
300
206
  end
301
207
 
@@ -311,56 +217,26 @@ module OvirtSDK4
311
217
  # @api private
312
218
  #
313
219
  def get_sso_response(url, parameters)
314
- # Create the cURL handle for SSO:
315
- sso_curl = Curl::Easy.new
316
-
317
- # Configure the timeout:
318
- sso_curl.timeout = @timeout
319
-
320
- # Configure debug mode:
321
- if @debug && @log
322
- sso_curl.verbose = true
323
- sso_curl.on_debug do |_, data|
324
- lines = data.gsub("\r\n", "\n").strip.split("\n")
325
- lines.each do |line|
326
- @log.debug(line)
327
- end
328
- end
329
- end
220
+ # Create the request:
221
+ request = HttpRequest.new(
222
+ :method => :POST,
223
+ :url => url,
224
+ :headers => {
225
+ 'User-Agent' => "RubySDK/#{VERSION}",
226
+ 'Content-Type' => 'application/x-www-form-urlencoded',
227
+ 'Accept' => 'application/json',
228
+ },
229
+ :body => URI.encode_www_form(parameters),
230
+ )
231
+
232
+ # Create an empty response:
233
+ response = HttpResponse.new
330
234
 
331
- begin
332
- # Configure TLS parameters:
333
- if url.scheme == 'https'
334
- if @insecure
335
- sso_curl.ssl_verify_peer = false
336
- sso_curl.ssl_verify_host = false
337
- elsif !@ca_file.nil?
338
- raise ArgumentError.new("The CA file \"#{@ca_file}\" doesn't exist.") unless ::File.file?(@ca_file)
339
- sso_curl.cacert = @ca_file
340
- end
341
- end
342
-
343
- # Configure authentication:
344
- sso_curl.http_auth_types = @kerberos ? :gssnegotiate : 0
345
-
346
- # Build the SSO access_token request url:
347
- sso_curl.url = url.to_s
348
-
349
- # Add headers:
350
- sso_curl.headers['User-Agent'] = "RubySDK/#{VERSION}"
351
- sso_curl.headers['Content-Type'] = 'application/x-www-form-urlencoded'
352
- sso_curl.headers['Accept'] = 'application/json'
353
-
354
- # Request access token:
355
- body = URI.encode_www_form(parameters)
356
- sso_curl.http_post(body)
357
-
358
- # Parse and return the JSON response:
359
- body = sso_curl.body_str
360
- return JSON.parse(body)
361
- ensure
362
- sso_curl.close
363
- end
235
+ # Send the request and wait for the response:
236
+ @client.send(request, response)
237
+
238
+ # Parse and return the JSON response:
239
+ JSON.parse(response.body)
364
240
  end
365
241
 
366
242
  #
@@ -393,6 +269,7 @@ module OvirtSDK4
393
269
  # Compute the URL:
394
270
  url = URI(@url.to_s)
395
271
  url.path = "/ovirt-engine/sso/oauth/#{entry_point}"
272
+ url = url.to_s
396
273
 
397
274
  # Return the pair containing the URL and the parameters:
398
275
  [url, parameters]
@@ -416,6 +293,7 @@ module OvirtSDK4
416
293
  # Compute the URL:
417
294
  url = URI(@url.to_s)
418
295
  url.path = '/ovirt-engine/services/sso-logout'
296
+ url = url.to_s
419
297
 
420
298
  # Return the pair containing the URL and the parameters:
421
299
  [url, parameters]
@@ -432,10 +310,10 @@ module OvirtSDK4
432
310
  def test(raise_exception = false)
433
311
  begin
434
312
  system_service.get
435
- return true
313
+ true
436
314
  rescue Exception
437
315
  raise if raise_exception
438
- return false
316
+ false
439
317
  end
440
318
  end
441
319
 
@@ -457,7 +335,7 @@ module OvirtSDK4
457
335
  # @return [Boolean]
458
336
  #
459
337
  def is_link?(object)
460
- return !object.href.nil?
338
+ !object.href.nil?
461
339
  end
462
340
 
463
341
  #
@@ -474,7 +352,7 @@ module OvirtSDK4
474
352
  end
475
353
 
476
354
  # Check that the value of the "href" attribute is compatible with the base URL of the connection:
477
- prefix = @url.path
355
+ prefix = URI(@url).path
478
356
  if !prefix.end_with?('/')
479
357
  prefix += '/'
480
358
  end
@@ -498,68 +376,11 @@ module OvirtSDK4
498
376
  #
499
377
  def close
500
378
  # Revoke the SSO access token:
501
- revoke_access_token unless @token.nil?
379
+ revoke_access_token if @token
502
380
 
503
- # Release resources used by the cURL handle:
504
- @curl.close
381
+ # Close the HTTP client:
382
+ @client.close if @client
505
383
  end
506
384
 
507
- #
508
- # Builds a request URL from a path, and the set of query parameters.
509
- #
510
- # @params opts [Hash] The options used to build the URL.
511
- #
512
- # @option opts [String] :path The path that will be added to the base URL. The default is an empty string.
513
- #
514
- # @option opts [Hash<String, String>] :query ({}) A hash containing the query parameters to add to the URL. The
515
- # keys of the hash should be strings containing the names of the parameters, and the values should be strings
516
- # containing the values.
517
- #
518
- # @return [String] The URL.
519
- #
520
- # @api private
521
- #
522
- def build_url(opts = {})
523
- # Get the values of the parameters and assign default values:
524
- path = opts[:path] || ''
525
- query = opts[:query] || {}
526
-
527
- # Add the path and the parameters:
528
- url = @url.to_s + path
529
- if not query.empty?
530
- url = url + '?' + URI.encode_www_form(query)
531
- end
532
- return url
533
- end
534
-
535
- private
536
-
537
- # @api private
538
- def set_authentication!
539
- case @auth
540
- when :oauth
541
- # Check if we already have an SSO access token:
542
- @token ||= get_access_token
543
- @curl.headers['Authorization'] = "Bearer #{@token}"
544
- when :basic
545
- @curl.http_auth_types = :basic
546
- @curl.username = @username
547
- @curl.password = @password
548
- end
549
- end
550
-
551
- # @api private
552
- def set_headers!(request)
553
- # Add headers, avoiding those that have no value:
554
- @curl.headers.clear
555
- @curl.headers['user-agent'] = "RubySDK/#{VERSION}"
556
- @curl.headers['content-type'] = 'application/xml'
557
- @curl.headers['accept'] = 'application/xml'
558
- @curl.headers['version'] = 4
559
- request.headers.each do |k,v|
560
- @curl.headers[k.to_s.downcase] = v
561
- end
562
- end
563
385
  end
564
-
565
386
  end