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.
- checksums.yaml +4 -4
- data/CHANGES.adoc +6 -0
- data/ext/ovirtsdk4c/extconf.rb +6 -0
- data/ext/ovirtsdk4c/ov_http_client.c +680 -0
- data/ext/ovirtsdk4c/ov_http_client.h +26 -0
- data/ext/ovirtsdk4c/ov_http_request.c +321 -0
- data/ext/ovirtsdk4c/ov_http_request.h +45 -0
- data/ext/ovirtsdk4c/ov_http_response.c +180 -0
- data/ext/ovirtsdk4c/ov_http_response.h +34 -0
- data/ext/ovirtsdk4c/ovirtsdk4c.c +8 -2
- data/lib/ovirtsdk4/http.rb +69 -248
- data/lib/ovirtsdk4/probe.rb +117 -111
- data/lib/ovirtsdk4/services.rb +934 -934
- data/lib/ovirtsdk4/version.rb +1 -1
- metadata +8 -16
@@ -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
|
data/ext/ovirtsdk4c/ovirtsdk4c.c
CHANGED
@@ -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
|
-
|
28
|
+
/* Define the module: */
|
26
29
|
ov_module_define();
|
27
30
|
|
28
|
-
|
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
|
}
|
data/lib/ovirtsdk4/http.rb
CHANGED
@@ -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
|
34
|
+
# :url => 'https://engine.example.com/ovirt-engine/api',
|
84
35
|
# :username => 'admin@internal',
|
85
36
|
# :password => '...',
|
86
|
-
# :ca_file
|
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] :
|
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
|
-
# @
|
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
|
117
|
-
# instead of the
|
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
|
-
#
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
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 [
|
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
|
-
#
|
227
|
-
|
228
|
-
|
229
|
-
|
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
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
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
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
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
|
-
|
313
|
+
true
|
436
314
|
rescue Exception
|
437
315
|
raise if raise_exception
|
438
|
-
|
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
|
-
|
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
|
379
|
+
revoke_access_token if @token
|
502
380
|
|
503
|
-
#
|
504
|
-
@
|
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
|