ovirt-engine-sdk 4.1.8 → 4.1.9
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 +21 -0
- data/README.adoc +47 -20
- data/ext/ovirtsdk4c/ov_http_client.c +7 -3
- data/lib/ovirtsdk4/connection.rb +91 -55
- data/lib/ovirtsdk4/reader.rb +3 -3
- data/lib/ovirtsdk4/readers.rb +193 -0
- data/lib/ovirtsdk4/service.rb +65 -30
- data/lib/ovirtsdk4/services.rb +1131 -559
- data/lib/ovirtsdk4/types.rb +418 -0
- data/lib/ovirtsdk4/version.rb +1 -1
- data/lib/ovirtsdk4/writers.rb +69 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 818f63a1a783df790fbf5fc8f254ded435a90ac8
|
4
|
+
data.tar.gz: 2a51cba1a01c8a8c62647ee2c256f3a1684684a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9445021acbd41f225e882fe6ef4fc537bd97972ef9c978f0b4ed50c4b91ac53cb6f4ec5b116a7abef4f183b4764a94737fc730453278b094ff86aa7c72fbf5cd
|
7
|
+
data.tar.gz: 43097db69c7d043a11e147a55739e40a37455e4c2738714f451ca4b8f752a375f26be5575042643747fcd848f2639a4e6aa2c96ef4368175667e8d18bec15839
|
data/CHANGES.adoc
CHANGED
@@ -2,6 +2,27 @@
|
|
2
2
|
|
3
3
|
This document describes the relevant changes between releases of the SDK.
|
4
4
|
|
5
|
+
== 4.1.9 / Oct 13 2017
|
6
|
+
|
7
|
+
Update to model 4.1.39:
|
8
|
+
|
9
|
+
* Add a `refresh` parameter to `FilesService.list`.
|
10
|
+
|
11
|
+
* Add support for Link Layer Discovery Protocol (LLDP).
|
12
|
+
|
13
|
+
* Add support for listing cluster level features, and enabling/disabing
|
14
|
+
them for clusters.
|
15
|
+
|
16
|
+
New features:
|
17
|
+
|
18
|
+
* Improve log messages so that in addition to the response codes they
|
19
|
+
also contain the request method and URL.
|
20
|
+
|
21
|
+
Bug fixes:
|
22
|
+
|
23
|
+
* Add support for multiple threads
|
24
|
+
https://bugzilla.redhat.com/1496846[#1496846].
|
25
|
+
|
5
26
|
== 4.1.8 / Jul 17 2017
|
6
27
|
|
7
28
|
Update to model 4.1.37:
|
data/README.adoc
CHANGED
@@ -106,7 +106,7 @@ locators_ and _service methods_ (described later) may change in the
|
|
106
106
|
future.
|
107
107
|
|
108
108
|
There are other classes, like HTTP client classes, readers and writers.
|
109
|
-
These are used to implement the HTTP communication, and
|
109
|
+
These are used to implement the HTTP communication, and for XML
|
110
110
|
parsing and rendering. Refrain from using them, as they are internal
|
111
111
|
implementation details that may change in the future: backwards
|
112
112
|
compatibility isn't guaranteed.
|
@@ -127,6 +127,9 @@ connection = OvirtSDK4::Connection.new(
|
|
127
127
|
password: '...',
|
128
128
|
ca_file: 'ca.pem',
|
129
129
|
)
|
130
|
+
|
131
|
+
# Get the reference to the root of the tree of services:
|
132
|
+
system_service = connection.system_service
|
130
133
|
----
|
131
134
|
|
132
135
|
The connection holds expensive resources, including a pool of HTTP
|
@@ -139,7 +142,8 @@ important to free these resources when they are no longer in use:
|
|
139
142
|
connection.close
|
140
143
|
----
|
141
144
|
|
142
|
-
|
145
|
+
The connection and all the services that have been obtained from it
|
146
|
+
can't be used after the connection has been closed.
|
143
147
|
|
144
148
|
The `ca.pem` file is required when connecting to a server protected
|
145
149
|
with TLS. In an usual oVirt installation it will be in
|
@@ -156,9 +160,9 @@ The type classes are pure data containers, they don't have any logic or
|
|
156
160
|
operations. Instances can be created and modified at will.
|
157
161
|
|
158
162
|
Creating or modifying one of this instances does *not* have any effect
|
159
|
-
in the server side, unless
|
160
|
-
|
161
|
-
|
163
|
+
in the server side, unless they are explicitly passed to a call to one
|
164
|
+
of the service methods described below. Changes in the server side are
|
165
|
+
*not* automatically reflected in the instances that already exist in
|
162
166
|
memory.
|
163
167
|
|
164
168
|
The constructors of these classes have multiple optional arguments, one
|
@@ -181,6 +185,28 @@ vm = OvirtSDK4::Vm.new(
|
|
181
185
|
)
|
182
186
|
----
|
183
187
|
|
188
|
+
The hashes passed to these constructors are processed recursively. For
|
189
|
+
example, in the above code instead of explicitly calling the constructor
|
190
|
+
for the `Cluster` and `Template` classes it is also possible to use
|
191
|
+
plain hashes:
|
192
|
+
|
193
|
+
[source,ruby]
|
194
|
+
----
|
195
|
+
vm = OvirtSDK4::Vm.new(
|
196
|
+
name: 'myvm',
|
197
|
+
cluster: {
|
198
|
+
name: 'mycluster'
|
199
|
+
},
|
200
|
+
template: {
|
201
|
+
name: 'mytemplate'
|
202
|
+
},
|
203
|
+
memory: 1073741824
|
204
|
+
)
|
205
|
+
----
|
206
|
+
|
207
|
+
The SDK will internally convert those hashes to the required classes, so
|
208
|
+
the result will be exactly the same.
|
209
|
+
|
184
210
|
Using the constructors in this way is recommended, but not mandatory.
|
185
211
|
You can also create the instance with no arguments in the call to the
|
186
212
|
constructor, and then populate the object step by step, using the
|
@@ -192,7 +218,7 @@ vm = OvirtSDK4::Vm.new
|
|
192
218
|
vm.name = 'myvm'
|
193
219
|
vm.cluster = OvirtSDK4::Cluster.new(name: 'mycluster')
|
194
220
|
vm.template = OvirtSDK4::Template.new(name: 'mytemplate')
|
195
|
-
vm.memory=1073741824
|
221
|
+
vm.memory = 1073741824
|
196
222
|
----
|
197
223
|
|
198
224
|
Attributes that are defined as lists of objects in the specification of
|
@@ -299,7 +325,7 @@ manages the collection of virtual machines of the system lives in
|
|
299
325
|
|
300
326
|
In the SDK the root of that tree of services is implemented by the
|
301
327
|
_system service_. It is obtained calling the
|
302
|
-
{
|
328
|
+
{reference}/Connection#system_service-instance_method[system_service]
|
303
329
|
method of the connection:
|
304
330
|
|
305
331
|
[source,ruby]
|
@@ -352,7 +378,8 @@ The services that manage a single object usually have the `get`,
|
|
352
378
|
|
353
379
|
Both kinds of services can also have additional _action methods_, which
|
354
380
|
perform actions other than retrieving, creating, updating or removing.
|
355
|
-
Most frequently they available in services that manage a single
|
381
|
+
Most frequently they are available in services that manage a single
|
382
|
+
object.
|
356
383
|
|
357
384
|
==== Using the _get_ methods
|
358
385
|
|
@@ -427,7 +454,7 @@ vms_service = system_service.vms_service
|
|
427
454
|
vms = vms_service.list
|
428
455
|
----
|
429
456
|
|
430
|
-
The result will be a Ruby array containing the instances of
|
457
|
+
The result will be a Ruby array containing the instances of the
|
431
458
|
corresponding types. For example, in this case, the result will be a
|
432
459
|
list of instances of the Ruby class {reference}/Vm[Vm].
|
433
460
|
|
@@ -456,8 +483,8 @@ of the failure.
|
|
456
483
|
|
457
484
|
==== Using the _add_ methods
|
458
485
|
|
459
|
-
These service methods add new elements to
|
460
|
-
|
486
|
+
These service methods add new elements to collections. They receive an
|
487
|
+
instance of the relevant type describing the object to add, send the
|
461
488
|
request to add it, and return an instance of the type describing the
|
462
489
|
added object.
|
463
490
|
|
@@ -469,12 +496,12 @@ For example, to add a new virtual machine named `myvm`:
|
|
469
496
|
vm = vms_service.add(
|
470
497
|
OvirtSDK4::Vm.new(
|
471
498
|
name: 'myvm',
|
472
|
-
cluster:
|
499
|
+
cluster: {
|
473
500
|
name: 'mycluster'
|
474
|
-
|
475
|
-
template:
|
501
|
+
},
|
502
|
+
template: {
|
476
503
|
name: 'mytemplate'
|
477
|
-
|
504
|
+
}
|
478
505
|
)
|
479
506
|
)
|
480
507
|
----
|
@@ -539,10 +566,10 @@ updated.
|
|
539
566
|
|
540
567
|
==== Using the _update_ methods
|
541
568
|
|
542
|
-
These service methods update existing objects. They receive
|
543
|
-
|
544
|
-
|
545
|
-
|
569
|
+
These service methods update existing objects. They receive an instance
|
570
|
+
of the relevant type describing the update to perform, send the request
|
571
|
+
to update it, and return an instance of the type describing the updated
|
572
|
+
object.
|
546
573
|
|
547
574
|
For example, to update the name of a virtual machine from `myvm` to
|
548
575
|
`newvm`:
|
@@ -569,7 +596,7 @@ update. For example, try to *avoid* this:
|
|
569
596
|
[source,ruby]
|
570
597
|
----
|
571
598
|
# Retrieve the current representation:
|
572
|
-
vm = vm_service.get
|
599
|
+
vm = vm_service.get
|
573
600
|
|
574
601
|
# Update the representation, in memory, no request sent
|
575
602
|
# to the server:
|
@@ -587,6 +587,7 @@ static void* ov_http_client_complete_task(void* data) {
|
|
587
587
|
VALUE transfer;
|
588
588
|
long code;
|
589
589
|
ov_http_client_object* client_ptr;
|
590
|
+
ov_http_request_object* request_ptr;
|
590
591
|
ov_http_response_object* response_ptr;
|
591
592
|
ov_http_transfer_object* transfer_ptr;
|
592
593
|
|
@@ -600,6 +601,7 @@ static void* ov_http_client_complete_task(void* data) {
|
|
600
601
|
/* Get the pointers to the transfer, client and response: */
|
601
602
|
ov_http_transfer_ptr(transfer, transfer_ptr);
|
602
603
|
ov_http_client_ptr(transfer_ptr->client, client_ptr);
|
604
|
+
ov_http_request_ptr(transfer_ptr->request, request_ptr);
|
603
605
|
ov_http_response_ptr(transfer_ptr->response, response_ptr);
|
604
606
|
|
605
607
|
/* Remove the transfer from the pending hash: */
|
@@ -617,8 +619,10 @@ static void* ov_http_client_complete_task(void* data) {
|
|
617
619
|
/* Send a summary of the response to the log: */
|
618
620
|
ov_http_client_log_info(
|
619
621
|
client_ptr->log,
|
620
|
-
"Received response code '%"PRIsVALUE"'.",
|
621
|
-
response_ptr->code
|
622
|
+
"Received response code %"PRIsVALUE" for %"PRIsVALUE" request to URL '%"PRIsVALUE"'.",
|
623
|
+
response_ptr->code,
|
624
|
+
request_ptr->method,
|
625
|
+
request_ptr->url
|
622
626
|
);
|
623
627
|
}
|
624
628
|
else {
|
@@ -806,7 +810,7 @@ static void ov_http_client_prepare_handle(ov_http_client_object* client_ptr, ov_
|
|
806
810
|
/* Send a summary of the request to the log: */
|
807
811
|
ov_http_client_log_info(
|
808
812
|
client_ptr->log,
|
809
|
-
"Sending
|
813
|
+
"Sending %"PRIsVALUE" request to URL '%"PRIsVALUE"'.",
|
810
814
|
request_ptr->method,
|
811
815
|
url
|
812
816
|
);
|
data/lib/ovirtsdk4/connection.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
require 'json'
|
18
18
|
require 'tempfile'
|
19
|
+
require 'thread'
|
19
20
|
require 'uri'
|
20
21
|
|
21
22
|
module OvirtSDK4
|
@@ -145,6 +146,9 @@ module OvirtSDK4
|
|
145
146
|
@ca_store.close
|
146
147
|
end
|
147
148
|
|
149
|
+
# Create the mutex that will be used to prevents simultaneous access to the same HTTP client by multiple threads:
|
150
|
+
@mutex = Mutex.new
|
151
|
+
|
148
152
|
# Create the HTTP client:
|
149
153
|
@client = HttpClient.new(
|
150
154
|
insecure: @insecure,
|
@@ -184,65 +188,24 @@ module OvirtSDK4
|
|
184
188
|
end
|
185
189
|
|
186
190
|
#
|
187
|
-
# Sends an HTTP request.
|
191
|
+
# Sends an HTTP request, making sure that multiple threads are coordinated correctly.
|
188
192
|
#
|
189
193
|
# @param request [HttpRequest] The request object containing the details of the HTTP request to send.
|
190
194
|
#
|
191
195
|
# @api private
|
192
196
|
#
|
193
197
|
def send(request)
|
194
|
-
|
195
|
-
request.url = request.url.nil? ? request.url = @url : "#{@url}#{request.url}"
|
196
|
-
|
197
|
-
# Set the headers common to all requests:
|
198
|
-
request.headers.merge!(
|
199
|
-
'User-Agent' => "RubySDK/#{VERSION}",
|
200
|
-
'Version' => '4',
|
201
|
-
'Content-Type' => 'application/xml',
|
202
|
-
'Accept' => 'application/xml'
|
203
|
-
)
|
204
|
-
|
205
|
-
# Older versions of the engine (before 4.1) required the 'all_content' as an HTTP header instead of a query
|
206
|
-
# parameter. In order to better support those older versions of the engine we need to check if this parameter is
|
207
|
-
# included in the request, and add the corresponding header.
|
208
|
-
unless request.query.nil?
|
209
|
-
all_content = request.query['all_content']
|
210
|
-
request.headers['All-Content'] = all_content unless all_content.nil?
|
211
|
-
end
|
212
|
-
|
213
|
-
# Add the global headers, but without replacing the values that may already exist:
|
214
|
-
request.headers.merge!(@headers) { |_name, local, _global| local } if @headers
|
215
|
-
|
216
|
-
# Set the authentication token:
|
217
|
-
@token ||= create_access_token
|
218
|
-
request.token = @token
|
219
|
-
|
220
|
-
# Send the request:
|
221
|
-
@client.send(request)
|
198
|
+
@mutex.synchronize { internal_send(request) }
|
222
199
|
end
|
223
200
|
|
224
201
|
#
|
225
|
-
# Waits for the response to the given request.
|
202
|
+
# Waits for the response to the given request, making sure that multiple threads are coordinated correctly.
|
226
203
|
#
|
227
204
|
# @param request [HttpRequest] The request object whose corresponding response you want to wait for.
|
228
|
-
# @return [
|
205
|
+
# @return [HttpResponse] A request object containing the details of the HTTP response received.
|
229
206
|
#
|
230
207
|
def wait(request)
|
231
|
-
|
232
|
-
response = @client.wait(request)
|
233
|
-
raise response if response.is_a?(Exception)
|
234
|
-
|
235
|
-
# If the request failed because of authentication, and it wasn't a request to the SSO service, then the
|
236
|
-
# most likely cause is an expired SSO token. In this case we need to request a new token, and try the original
|
237
|
-
# request again, but only once. It if fails again, we just return the failed response.
|
238
|
-
if response.code == 401 && request.token
|
239
|
-
@token = create_access_token
|
240
|
-
request.token = @token
|
241
|
-
@client.send(request)
|
242
|
-
response = @client.wait(request)
|
243
|
-
end
|
244
|
-
|
245
|
-
response
|
208
|
+
@mutex.synchronize { internal_wait(request) }
|
246
209
|
end
|
247
210
|
|
248
211
|
#
|
@@ -466,17 +429,10 @@ module OvirtSDK4
|
|
466
429
|
end
|
467
430
|
|
468
431
|
#
|
469
|
-
# Releases the resources used by this connection.
|
432
|
+
# Releases the resources used by this connection, making sure that multiple threads are coordinated correctly.
|
470
433
|
#
|
471
434
|
def close
|
472
|
-
|
473
|
-
revoke_access_token if @token
|
474
|
-
|
475
|
-
# Close the HTTP client:
|
476
|
-
@client.close if @client
|
477
|
-
|
478
|
-
# Remove the temporary file that contains the trusted CA certificates:
|
479
|
-
@ca_store.unlink if @ca_store
|
435
|
+
@mutex.synchronize { internal_close }
|
480
436
|
end
|
481
437
|
|
482
438
|
#
|
@@ -596,5 +552,85 @@ module OvirtSDK4
|
|
596
552
|
end
|
597
553
|
raise_error(response, detail)
|
598
554
|
end
|
555
|
+
|
556
|
+
#
|
557
|
+
# Sends an HTTP request.
|
558
|
+
#
|
559
|
+
# @param request [HttpRequest] The request object containing the details of the HTTP request to send.
|
560
|
+
#
|
561
|
+
# @api private
|
562
|
+
#
|
563
|
+
def internal_send(request)
|
564
|
+
# Add the base URL to the request:
|
565
|
+
request.url = request.url.nil? ? request.url = @url : "#{@url}/#{request.url}"
|
566
|
+
|
567
|
+
# Set the headers common to all requests:
|
568
|
+
request.headers.merge!(
|
569
|
+
'User-Agent' => "RubySDK/#{VERSION}",
|
570
|
+
'Version' => '4',
|
571
|
+
'Content-Type' => 'application/xml',
|
572
|
+
'Accept' => 'application/xml'
|
573
|
+
)
|
574
|
+
|
575
|
+
# Older versions of the engine (before 4.1) required the 'all_content' as an HTTP header instead of a query
|
576
|
+
# parameter. In order to better support those older versions of the engine we need to check if this parameter is
|
577
|
+
# included in the request, and add the corresponding header.
|
578
|
+
unless request.query.nil?
|
579
|
+
all_content = request.query['all_content']
|
580
|
+
request.headers['All-Content'] = all_content unless all_content.nil?
|
581
|
+
end
|
582
|
+
|
583
|
+
# Add the global headers, but without replacing the values that may already exist:
|
584
|
+
request.headers.merge!(@headers) { |_name, local, _global| local } if @headers
|
585
|
+
|
586
|
+
# Set the authentication token:
|
587
|
+
@token ||= create_access_token
|
588
|
+
request.token = @token
|
589
|
+
|
590
|
+
# Send the request:
|
591
|
+
@client.send(request)
|
592
|
+
end
|
593
|
+
|
594
|
+
#
|
595
|
+
# Waits for the response to the given request.
|
596
|
+
#
|
597
|
+
# @param request [HttpRequest] The request object whose corresponding response you want to wait for.
|
598
|
+
# @return [Response] A request object containing the details of the HTTP response received.
|
599
|
+
#
|
600
|
+
# @api private
|
601
|
+
#
|
602
|
+
def internal_wait(request)
|
603
|
+
# Wait for the response:
|
604
|
+
response = @client.wait(request)
|
605
|
+
raise response if response.is_a?(Exception)
|
606
|
+
|
607
|
+
# If the request failed because of authentication, and it wasn't a request to the SSO service, then the
|
608
|
+
# most likely cause is an expired SSO token. In this case we need to request a new token, and try the original
|
609
|
+
# request again, but only once. It if fails again, we just return the failed response.
|
610
|
+
if response.code == 401 && request.token
|
611
|
+
@token = create_access_token
|
612
|
+
request.token = @token
|
613
|
+
@client.send(request)
|
614
|
+
response = @client.wait(request)
|
615
|
+
end
|
616
|
+
|
617
|
+
response
|
618
|
+
end
|
619
|
+
|
620
|
+
#
|
621
|
+
# Releases the resources used by this connection.
|
622
|
+
#
|
623
|
+
# @api private
|
624
|
+
#
|
625
|
+
def internal_close
|
626
|
+
# Revoke the SSO access token:
|
627
|
+
revoke_access_token if @token
|
628
|
+
|
629
|
+
# Close the HTTP client:
|
630
|
+
@client.close if @client
|
631
|
+
|
632
|
+
# Remove the temporary file that contains the trusted CA certificates:
|
633
|
+
@ca_store.unlink if @ca_store
|
634
|
+
end
|
599
635
|
end
|
600
636
|
end
|
data/lib/ovirtsdk4/reader.rb
CHANGED
@@ -92,7 +92,7 @@ module OvirtSDK4
|
|
92
92
|
return nil if text.nil?
|
93
93
|
begin
|
94
94
|
return Integer(text, 10)
|
95
|
-
rescue
|
95
|
+
rescue ArgumentError
|
96
96
|
raise Error, "The text '#{text}' isn't a valid integer value."
|
97
97
|
end
|
98
98
|
end
|
@@ -127,7 +127,7 @@ module OvirtSDK4
|
|
127
127
|
return nil if text.nil?
|
128
128
|
begin
|
129
129
|
return Float(text)
|
130
|
-
rescue
|
130
|
+
rescue ArgumentError
|
131
131
|
raise Error, "The text '#{text}' isn't a valid decimal value."
|
132
132
|
end
|
133
133
|
end
|
@@ -163,7 +163,7 @@ module OvirtSDK4
|
|
163
163
|
return nil if text.nil?
|
164
164
|
begin
|
165
165
|
return DateTime.xmlschema(text)
|
166
|
-
rescue
|
166
|
+
rescue ArgumentError
|
167
167
|
raise Error, "The text '#{text}' isn't a valid date."
|
168
168
|
end
|
169
169
|
end
|