ovirt-engine-sdk 4.0.2 → 4.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|