rubywbem 0.1.0
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.
- data/AUTHORS +1 -0
- data/CHANGELOG +3 -0
- data/LICENSE +339 -0
- data/README +28 -0
- data/Rakefile +146 -0
- data/lib/wbem.rb +23 -0
- data/lib/wbem/cim_constants.rb +50 -0
- data/lib/wbem/cim_http.rb +137 -0
- data/lib/wbem/cim_obj.rb +1148 -0
- data/lib/wbem/cim_operations.rb +571 -0
- data/lib/wbem/cim_types.rb +195 -0
- data/lib/wbem/cim_xml.rb +1428 -0
- data/lib/wbem/tupleparse.rb +1181 -0
- data/lib/wbem/tupletree.rb +138 -0
- data/ruby-wbem.spec +54 -0
- data/testsuite/CIM_DTD_V22.dtd +324 -0
- data/testsuite/comfychair.rb +442 -0
- data/testsuite/runtests.sh +56 -0
- data/testsuite/test_cim_obj.rb +1610 -0
- data/testsuite/test_cim_operations.rb +702 -0
- data/testsuite/test_cim_xml.rb +1495 -0
- data/testsuite/test_nocasehash.rb +248 -0
- data/testsuite/test_tupleparse.rb +208 -0
- data/testsuite/validate.rb +93 -0
- metadata +68 -0
@@ -0,0 +1,571 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2006, Red Hat, Inc
|
3
|
+
# Scott Seago <sseago@redhat.com>
|
4
|
+
#
|
5
|
+
# derived from pywbem, written by Tim Potter <tpot@hp.com>, Martin Pool <mbp@hp.com>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation; either version 2 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, write to the Free Software
|
14
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
15
|
+
#
|
16
|
+
|
17
|
+
require "rexml/document"
|
18
|
+
require "wbem/cim_obj"
|
19
|
+
require "wbem/cim_xml"
|
20
|
+
require "wbem/cim_http"
|
21
|
+
require "wbem/tupletree"
|
22
|
+
require "wbem/tupleparse"
|
23
|
+
|
24
|
+
#"""CIM-XML/HTTP operations.
|
25
|
+
#
|
26
|
+
#The WBEMConnection class opens a connection to a remote WBEM server.
|
27
|
+
#Across this you can run various CIM operations. Each method of this
|
28
|
+
#object corresponds fairly directly to a single CIM method call.
|
29
|
+
#"""
|
30
|
+
|
31
|
+
module WBEM
|
32
|
+
DEFAULT_NAMESPACE = 'root/cimv2'
|
33
|
+
|
34
|
+
# TODO: Many methods have more parameters that aren't set yet.
|
35
|
+
|
36
|
+
# helper functions for validating arguments
|
37
|
+
|
38
|
+
def WBEM._check_classname(val)
|
39
|
+
unless val.is_a?(String)
|
40
|
+
raise TypeError, "string expected for classname, not #{val}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class CIMError < Exception
|
45
|
+
#"""Raised when something bad happens. The associated value is a
|
46
|
+
#tuple of (error_code, description). An error code of zero
|
47
|
+
#indicates an XML parsing error in RubyWBEM."""
|
48
|
+
attr :code
|
49
|
+
def initialize(code)
|
50
|
+
@code = code
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class WBEMConnection
|
55
|
+
#"""Class representing a client's connection to a WBEM server.
|
56
|
+
|
57
|
+
#At the moment there is no persistent TCP connection; the
|
58
|
+
#connectedness is only conceptual.
|
59
|
+
|
60
|
+
#After creating a connection, various methods may be called on the
|
61
|
+
#object, which causes a remote call to the server. All these
|
62
|
+
#operations take regular Ruby or cim_types values for parameters,
|
63
|
+
#and return the same. The caller should not need to know about
|
64
|
+
#the XML encoding. (It should be possible to use a different
|
65
|
+
#transport below this layer without disturbing any clients.)
|
66
|
+
|
67
|
+
#The connection remembers the XML for the last request and last
|
68
|
+
#reply. This may be useful in debugging: if a problem occurs, you
|
69
|
+
#can examine the last_request and last_reply fields of the
|
70
|
+
#connection. These are the prettified request and response; the
|
71
|
+
#real request is sent without indents so as not to corrupt whitespace.
|
72
|
+
|
73
|
+
#The caller may also register callback functions which are passed
|
74
|
+
#the request before it is sent, and the reply before it is
|
75
|
+
#unpacked.
|
76
|
+
#"""
|
77
|
+
|
78
|
+
attr_reader :url, :creds, :x509, :last_request, :last_raw_request, :last_reply, :default_namespace
|
79
|
+
def initialize(url, creds = nil, default_namespace = DEFAULT_NAMESPACE,
|
80
|
+
x509 = nil)
|
81
|
+
@url = url
|
82
|
+
@creds = creds
|
83
|
+
@x509 = x509
|
84
|
+
@last_request = @last_reply = ''
|
85
|
+
@default_namespace = default_namespace
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_s
|
89
|
+
"#{self.class}(#{self.url}, user=#{self.creds[0]})"
|
90
|
+
end
|
91
|
+
|
92
|
+
def imethodcall(methodname, params)
|
93
|
+
#"""Make an intrinsic method call.
|
94
|
+
|
95
|
+
#Returns a tupletree with a IRETURNVALUE element at the root.
|
96
|
+
#A CIMError exception is thrown if there was an error parsing
|
97
|
+
#the call response, or an ERROR element was returned.
|
98
|
+
|
99
|
+
#The parameters are automatically converted to the right
|
100
|
+
#CIM_XML objects.
|
101
|
+
|
102
|
+
#In general clients should call one of the method-specific
|
103
|
+
#methods of the connection, such as EnumerateInstanceNames,
|
104
|
+
#etc."""
|
105
|
+
|
106
|
+
# If a LocalNamespacePath wasn't specified, use the default one
|
107
|
+
|
108
|
+
localnamespacepath = params.delete(:LocalNamespacePath)
|
109
|
+
localnamespacepath = self.default_namespace if localnamespacepath.nil?
|
110
|
+
|
111
|
+
# Create HTTP headers
|
112
|
+
|
113
|
+
headers = ["CIMOperation: MethodCall",
|
114
|
+
"CIMMethod: #{methodname}",
|
115
|
+
WBEM.get_object_header(localnamespacepath)]
|
116
|
+
|
117
|
+
# Create parameter list
|
118
|
+
plist = params.to_a.collect do |x|
|
119
|
+
IPARAMVALUE.new(x[0].to_s, WBEM.tocimxml(x[1]))
|
120
|
+
end
|
121
|
+
|
122
|
+
# Build XML request
|
123
|
+
|
124
|
+
req_xml = CIM.new(MESSAGE.new(SIMPLEREQ.new(IMETHODCALL.new(methodname,
|
125
|
+
LOCALNAMESPACEPATH.new(localnamespacepath.split("/").collect do |ns|
|
126
|
+
NAMESPACE.new(ns)
|
127
|
+
end
|
128
|
+
),
|
129
|
+
plist)),
|
130
|
+
'1001', '1.0'),
|
131
|
+
'2.0', '2.0')
|
132
|
+
|
133
|
+
@last_raw_request = ""
|
134
|
+
@last_request = ""
|
135
|
+
req_xml.write(@last_raw_request)
|
136
|
+
req_xml.write(@last_request, 2)
|
137
|
+
# Get XML response
|
138
|
+
|
139
|
+
begin
|
140
|
+
resp_xml = WBEM.wbem_request(self.url, @last_raw_request, self.creds,
|
141
|
+
headers, 0, self.x509)
|
142
|
+
rescue AuthError =>
|
143
|
+
raise
|
144
|
+
rescue CIMHttpError => arg
|
145
|
+
# Convert cim_http exceptions to CIMError exceptions
|
146
|
+
raise CIMError.new(0), arg.to_s
|
147
|
+
end
|
148
|
+
## TODO: Perhaps only compute this if it's required? Should not be
|
149
|
+
## all that expensive.
|
150
|
+
|
151
|
+
reply_dom = REXML::Document.new(resp_xml)
|
152
|
+
|
153
|
+
## We want to not insert any newline characters, because
|
154
|
+
## they're already present and we don't want them duplicated.
|
155
|
+
@last_reply = ""
|
156
|
+
@last_raw_reply = ""
|
157
|
+
reply_dom.write(@last_reply, 2)
|
158
|
+
reply_dom.write(@last_raw_reply)
|
159
|
+
# STDOUT << "response: #{@last_reply}\n"
|
160
|
+
|
161
|
+
# Parse response
|
162
|
+
tmptt = WBEM.dom_to_tupletree(reply_dom)
|
163
|
+
# STDOUT << "tmp tt: #{WBEM.tupletree_to_s(tmptt)}\n"
|
164
|
+
tt = WBEM.parse_cim(tmptt)
|
165
|
+
|
166
|
+
if (tt[0] != "CIM")
|
167
|
+
raise CIMError.new(0), "Expecting CIM element, got #{tt[0]}"
|
168
|
+
end
|
169
|
+
tt = tt[2]
|
170
|
+
|
171
|
+
if (tt[0] != "MESSAGE")
|
172
|
+
raise CIMError.new(0), "Expecting MESSAGE element, got #{tt[0]}"
|
173
|
+
end
|
174
|
+
tt = tt[2]
|
175
|
+
|
176
|
+
if (tt.length != 1)
|
177
|
+
raise CIMError.new(0), "Expecting one SIMPLERSP element: nelements: #{tt.length}"
|
178
|
+
end
|
179
|
+
if (tt[0][0] != "SIMPLERSP")
|
180
|
+
raise CIMError.new(0), "Expecting one SIMPLERSP element, found #{tt[0][0]}"
|
181
|
+
end
|
182
|
+
tt = tt[0][2]
|
183
|
+
|
184
|
+
if (tt[0] != "IMETHODRESPONSE")
|
185
|
+
raise CIMError.new(0), "Expecting IMETHODRESPONSE element, got #{tt[0]}"
|
186
|
+
end
|
187
|
+
|
188
|
+
if (tt[1]["NAME"] != methodname)
|
189
|
+
raise CIMError.new(0), "Expecting attribute NAME=#{methodname}, got #{tt[1]['NAME']}"
|
190
|
+
end
|
191
|
+
tt = tt[2]
|
192
|
+
|
193
|
+
# At this point we either have a IRETURNVALUE, ERROR element
|
194
|
+
# or None if there was no child nodes of the IMETHODRESPONSE
|
195
|
+
# element.
|
196
|
+
|
197
|
+
if (tt.nil?)
|
198
|
+
return nil
|
199
|
+
end
|
200
|
+
if (tt[0] == "ERROR")
|
201
|
+
code = tt[1]['CODE'].to_i
|
202
|
+
if tt[1].has_key?("DESCRIPTION")
|
203
|
+
raise CIMError.new(code), tt[1]["DESCRIPTION"]
|
204
|
+
end
|
205
|
+
raise CIMError.new(code), "Error code #{tt[1]['CODE']}"
|
206
|
+
|
207
|
+
if (tt[0] != "IRETURNVALUE")
|
208
|
+
raise CIMError,new(0), "Expecting IRETURNVALUE element, got #{tt[0]}"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
return tt
|
212
|
+
end
|
213
|
+
|
214
|
+
def methodcall(methodname, localobject, params)
|
215
|
+
#"""Make an extrinsic method call.
|
216
|
+
|
217
|
+
#Returns a tupletree with a RETURNVALUE element at the root.
|
218
|
+
#A CIMError exception is thrown if there was an error parsing
|
219
|
+
#the call response, or an ERROR element was returned.
|
220
|
+
|
221
|
+
#The parameters are automatically converted to the right
|
222
|
+
#CIM_XML objects."""
|
223
|
+
|
224
|
+
# Create HTTP headers
|
225
|
+
|
226
|
+
headers = ["CIMOperation: MethodCall",
|
227
|
+
"CIMMethod: #{methodname}",
|
228
|
+
WBEM.get_object_header(localobject)]
|
229
|
+
# Create parameter list
|
230
|
+
|
231
|
+
|
232
|
+
plist = params.to_a.collect do |x|
|
233
|
+
PARAMVALUE.new(x[0].to_s, WBEM.tocimxml(x[1], true), WBEM.cimtype(x[1]))
|
234
|
+
end
|
235
|
+
|
236
|
+
# Build XML request
|
237
|
+
|
238
|
+
req_xml = CIM.new(MESSAGE.new(SIMPLEREQ.new(METHODCALL.new(methodname,
|
239
|
+
localobject.tocimxml(),
|
240
|
+
plist)),
|
241
|
+
'1001', '1.0'),
|
242
|
+
'2.0', '2.0')
|
243
|
+
|
244
|
+
@last_raw_request = ""
|
245
|
+
@last_request = ""
|
246
|
+
req_xml.write(@last_raw_request)
|
247
|
+
req_xml.write(@last_request, 2)
|
248
|
+
|
249
|
+
# Get XML response
|
250
|
+
|
251
|
+
begin
|
252
|
+
resp_xml = WBEM.wbem_request(self.url, @last_raw_request, self.creds,
|
253
|
+
headers)
|
254
|
+
rescue CIMHttpError => arg
|
255
|
+
# Convert cim_http exceptions to CIMError exceptions
|
256
|
+
raise CIMError.new(0), arg.to_s
|
257
|
+
end
|
258
|
+
|
259
|
+
@last_reply = resp_xml
|
260
|
+
|
261
|
+
tt = WBEM.parse_cim(WBEM.xml_to_tupletree(resp_xml))
|
262
|
+
|
263
|
+
if (tt[0] != "CIM")
|
264
|
+
raise CIMError.new(0), "Expecting CIM element, got #{tt[0]}"
|
265
|
+
end
|
266
|
+
tt = tt[2]
|
267
|
+
|
268
|
+
if (tt[0] != "MESSAGE")
|
269
|
+
raise CIMError.new(0), "Expecting MESSAGE element, got #{tt[0]}"
|
270
|
+
end
|
271
|
+
tt = tt[2]
|
272
|
+
|
273
|
+
if (tt.length != 1 or tt[0][0] != "SIMPLERSP")
|
274
|
+
raise CIMError.new(0), "Expecting one SIMPLERSP element"
|
275
|
+
end
|
276
|
+
tt = tt[0][2]
|
277
|
+
|
278
|
+
if (tt[0] != "METHODRESPONSE")
|
279
|
+
raise CIMError.new(0), "Expecting METHODRESPONSE element, got #{tt[0]}"
|
280
|
+
end
|
281
|
+
|
282
|
+
if (tt[1]["NAME"] != methodname)
|
283
|
+
raise CIMError.new(0), "Expecting attribute NAME=#{methodname}, got #{tt[1]['NAME']}"
|
284
|
+
end
|
285
|
+
tt = tt[2]
|
286
|
+
|
287
|
+
# At this point we have an optional RETURNVALUE and zero or more PARAMVALUE
|
288
|
+
# elements representing output parameters.
|
289
|
+
if (!tt.empty? and tt[0][0] == "ERROR")
|
290
|
+
code = tt[0][1]["CODE"].to_i
|
291
|
+
if tt[0][1].has_key?("DESCRIPTION")
|
292
|
+
raise CIMError.new(code), tt[0][1]['DESCRIPTION']
|
293
|
+
end
|
294
|
+
raise CIMError.new(code), "Error code #{tt[0][1]['CODE']}"
|
295
|
+
end
|
296
|
+
|
297
|
+
return tt
|
298
|
+
end
|
299
|
+
|
300
|
+
#
|
301
|
+
# Instance provider API
|
302
|
+
#
|
303
|
+
def EnumerateInstanceNames(className, params = {})
|
304
|
+
#"""Enumerate instance names of a given classname. Returns a
|
305
|
+
#list of CIMInstanceName objects."""
|
306
|
+
result = self.imethodcall("EnumerateInstanceNames",
|
307
|
+
params.merge(Hash[:ClassName => CIMClassName.new(className)]))
|
308
|
+
|
309
|
+
return result[2] unless result.nil?
|
310
|
+
return []
|
311
|
+
end
|
312
|
+
|
313
|
+
def EnumerateInstances(className, params = {})
|
314
|
+
#"""Enumerate instances of a given classname. Returns a list
|
315
|
+
#of CIMInstance objects."""
|
316
|
+
|
317
|
+
result = self.imethodcall('EnumerateInstances',
|
318
|
+
params.merge(Hash[:ClassName => CIMClassName.new(className)]))
|
319
|
+
return result[2] unless result.nil?
|
320
|
+
return []
|
321
|
+
end
|
322
|
+
|
323
|
+
def GetInstance(instancename, params = {})
|
324
|
+
#"""Fetch an instance given by instancename. Returns a
|
325
|
+
#CIMInstance object."""
|
326
|
+
|
327
|
+
# Strip off host and namespace to make this a "local" object
|
328
|
+
iname = instancename.clone
|
329
|
+
iname.host = nil
|
330
|
+
iname.namespace = nil
|
331
|
+
|
332
|
+
result = self.imethodcall("GetInstance",
|
333
|
+
params.merge(Hash[:InstanceName => iname]))
|
334
|
+
return result[2][0]
|
335
|
+
end
|
336
|
+
|
337
|
+
def DeleteInstance(instancename, params = {})
|
338
|
+
#"""Delete the instance given by instancename."""
|
339
|
+
|
340
|
+
# Strip off host and namespace to make this a "local" object
|
341
|
+
iname = instancename.clone
|
342
|
+
iname.host = nil
|
343
|
+
iname.namespace = nil
|
344
|
+
|
345
|
+
self.imethodcall("DeleteInstance",
|
346
|
+
params.merge(Hash[:InstanceName => iname]))
|
347
|
+
end
|
348
|
+
|
349
|
+
def CreateInstance(newinstance, params = {})
|
350
|
+
#"""Create an instance. Returns the name for the instance."""
|
351
|
+
|
352
|
+
# Strip off path to avoid producing a VALUE.NAMEDINSTANCE
|
353
|
+
# element instead of an INSTANCE element.
|
354
|
+
|
355
|
+
instance = newinstance.clone
|
356
|
+
instance.path = nil
|
357
|
+
|
358
|
+
result = self.imethodcall("CreateInstance",
|
359
|
+
params.merge(Hash[:NewInstance => instance]))
|
360
|
+
return result[2][0]
|
361
|
+
end
|
362
|
+
|
363
|
+
def ModifyInstance(modifiedinstance, params = {})
|
364
|
+
#"""Modify properties of a named instance."""
|
365
|
+
# last arg is hash
|
366
|
+
|
367
|
+
if modifiedinstance.path.nil?
|
368
|
+
raise ArgumentError, 'modifiedinstance parameter must have path attribute set'
|
369
|
+
end
|
370
|
+
|
371
|
+
return self.imethodcall("ModifyInstance",
|
372
|
+
params.merge(Hash[:ModifiedInstance => modifiedinstance]))
|
373
|
+
end
|
374
|
+
|
375
|
+
#
|
376
|
+
# Schema management API
|
377
|
+
#
|
378
|
+
|
379
|
+
def EnumerateClassNames(params = {})
|
380
|
+
#"""Return a list of CIM class names. Names are returned as strings."""
|
381
|
+
|
382
|
+
result = self.imethodcall("EnumerateClassNames",
|
383
|
+
params)
|
384
|
+
|
385
|
+
return [] if result.nil?
|
386
|
+
return result[2].collect { |x| x.classname}
|
387
|
+
end
|
388
|
+
|
389
|
+
def EnumerateClasses(params = {})
|
390
|
+
#"""Return a list of CIM class objects."""
|
391
|
+
|
392
|
+
result = self.imethodcall("EnumerateClasses",
|
393
|
+
params)
|
394
|
+
|
395
|
+
return [] if result.nil?
|
396
|
+
|
397
|
+
return result[2]
|
398
|
+
end
|
399
|
+
|
400
|
+
def GetClass(className, params = {})
|
401
|
+
#"""Return a CIMClass representing the named class."""
|
402
|
+
|
403
|
+
result = self.imethodcall("GetClass",
|
404
|
+
params.merge(Hash[:ClassName => CIMClassName.new(className)]))
|
405
|
+
|
406
|
+
return result[2][0]
|
407
|
+
end
|
408
|
+
|
409
|
+
def DeleteClass(className, params = {})
|
410
|
+
#"""Delete a class by class name."""
|
411
|
+
|
412
|
+
# UNSUPPORTED (but actually works)
|
413
|
+
|
414
|
+
self.imethodcall("DeleteClass",
|
415
|
+
params.merge(Hash[:ClassName => CIMClassName.new(className)]))
|
416
|
+
end
|
417
|
+
|
418
|
+
def ModifyClass(modifiedClass, params = {})
|
419
|
+
#"""Modify a CIM class."""
|
420
|
+
|
421
|
+
# UNSUPPORTED
|
422
|
+
|
423
|
+
self.imethodcall('ModifyClass',
|
424
|
+
params.merge(Hash[:ModifiedClass => modifiedClass]))
|
425
|
+
end
|
426
|
+
|
427
|
+
def CreateClass(newClass, params = {})
|
428
|
+
#"""Create a CIM class."""
|
429
|
+
|
430
|
+
# UNSUPPORTED
|
431
|
+
|
432
|
+
self.imethodcall('CreateClass',
|
433
|
+
params.merge(Hash[:NewClass => newClass]))
|
434
|
+
end
|
435
|
+
#
|
436
|
+
# Association provider API
|
437
|
+
#
|
438
|
+
|
439
|
+
def _add_objectname_param(params, object)
|
440
|
+
#"""Add an object name (either a class name or an instance
|
441
|
+
#name) to a dictionary of parameter names."""
|
442
|
+
|
443
|
+
if (object.is_a?(CIMClassName) or object.is_a?(CIMInstanceName))
|
444
|
+
params[:ObjectName] = object
|
445
|
+
elsif (object.is_a?(String))
|
446
|
+
params[:ObjectName] = CIMClassName.new(object)
|
447
|
+
else
|
448
|
+
raise TypeError, "Expecting a classname, CIMClassName or CIMInstanceName object"
|
449
|
+
end
|
450
|
+
return params
|
451
|
+
end
|
452
|
+
|
453
|
+
def _map_association_params(params = {})
|
454
|
+
#"""Convert various convenience parameters and types into their
|
455
|
+
#correct form for passing to the imethodcall() function."""
|
456
|
+
|
457
|
+
# ResultClass and Role parameters that are strings should be
|
458
|
+
# mapped to CIMClassName objects.
|
459
|
+
|
460
|
+
if (params.has_key?(:ResultClass) and params[:ResultClass].is_a?(String))
|
461
|
+
params[:ResultClass] = CIMClassName.new(params[:ResultClass])
|
462
|
+
end
|
463
|
+
if (params.has_key?("AssocClass") and params["AssocClass"].is_a?(String))
|
464
|
+
params[:AssocClass] = CIMClassName.new(params[:AssocClass])
|
465
|
+
end
|
466
|
+
return params
|
467
|
+
end
|
468
|
+
|
469
|
+
def Associators(object_name, params = {})
|
470
|
+
#"""Enumerate CIM classes or instances that are associated to a
|
471
|
+
#particular source CIM Object. Pass a keyword parameter of
|
472
|
+
#'ClassName' to return associators for a CIM class, pass
|
473
|
+
#'InstanceName' to return the associators for a CIM instance."""
|
474
|
+
|
475
|
+
params = self._map_association_params(params)
|
476
|
+
params = self._add_objectname_param(params, object_name)
|
477
|
+
|
478
|
+
result = self.imethodcall("Associators",
|
479
|
+
params)
|
480
|
+
|
481
|
+
return [] if result.nil?
|
482
|
+
return result[2].collect { |x| x[2]}
|
483
|
+
end
|
484
|
+
|
485
|
+
def AssociatorNames(object_name, params = {})
|
486
|
+
#"""Enumerate the names of CIM classes or instances that are
|
487
|
+
#associated to a particular source CIM Object. Pass a keyword
|
488
|
+
#parameter of 'ClassName' to return associators for a CIM
|
489
|
+
#class, pass 'InstanceName' to return the associators for a CIM
|
490
|
+
#instance. Returns a list of CIMInstanceName objects with the
|
491
|
+
#host and namespace attributes set."""
|
492
|
+
|
493
|
+
params = self._map_association_params(params)
|
494
|
+
params = self._add_objectname_param(params, object_name)
|
495
|
+
|
496
|
+
result = self.imethodcall("AssociatorNames",
|
497
|
+
params)
|
498
|
+
return [] if result.nil?
|
499
|
+
return result[2].collect { |x| x[2]}
|
500
|
+
end
|
501
|
+
|
502
|
+
def References(object_name, params = {})
|
503
|
+
#"""Enumerate the association objects that refer to a
|
504
|
+
#particular target CIM class or instance. Pass a keyword
|
505
|
+
#parameter of 'ClassName' to return associators for a CIM
|
506
|
+
#class, pass 'InstanceName' to return the associators for a CIM
|
507
|
+
#instance."""
|
508
|
+
|
509
|
+
params = self._map_association_params(params)
|
510
|
+
params = self._add_objectname_param(params, object_name)
|
511
|
+
|
512
|
+
result = self.imethodcall("References",
|
513
|
+
params)
|
514
|
+
return [] if result.nil?
|
515
|
+
return result[2].collect { |x| x[2]}
|
516
|
+
end
|
517
|
+
|
518
|
+
def ReferenceNames(object_name, params = {})
|
519
|
+
#"""Enumerate the name of association objects that refer to a
|
520
|
+
#particular target CIM class or instance. Pass a keyword
|
521
|
+
#parameter of 'ClassName' to return associators for a CIM
|
522
|
+
#class, pass 'InstanceName' to return the associators for a CIM
|
523
|
+
#instance."""
|
524
|
+
|
525
|
+
params = self._map_association_params(params)
|
526
|
+
params = self._add_objectname_param(params, object_name)
|
527
|
+
|
528
|
+
result = self.imethodcall("ReferenceNames",
|
529
|
+
params)
|
530
|
+
return [] if result.nil?
|
531
|
+
return result[2].collect { |x| x[2]}
|
532
|
+
end
|
533
|
+
|
534
|
+
#
|
535
|
+
# Method provider API
|
536
|
+
#
|
537
|
+
|
538
|
+
def InvokeMethod(methodname, objectname, params = {})
|
539
|
+
|
540
|
+
obj = objectname.clone
|
541
|
+
|
542
|
+
if (obj.is_a?(String))
|
543
|
+
obj = CIMLocalClassPath.new(self.default_namespace, obj)
|
544
|
+
end
|
545
|
+
|
546
|
+
if obj.is_a?(CIMInstanceName) and obj.namespace.nil?
|
547
|
+
obj.namespace = DEFAULT_NAMESPACE
|
548
|
+
end
|
549
|
+
|
550
|
+
result = self.methodcall(methodname, obj, params)
|
551
|
+
|
552
|
+
# Convert the RETURNVALUE into a Ruby object
|
553
|
+
if (!result.empty? and result[0][0] == "RETURNVALUE")
|
554
|
+
returnvalue = tocimobj(result[0][1]["PARAMTYPE"],
|
555
|
+
result[0][2])
|
556
|
+
|
557
|
+
# Convert output parameters into a dictionary of Python
|
558
|
+
# objects.
|
559
|
+
|
560
|
+
output_params = {}
|
561
|
+
|
562
|
+
result[1..-1].each do |p|
|
563
|
+
output_params[p[0]] = tocimobj(p[1], p[2])
|
564
|
+
end
|
565
|
+
return returnvalue, output_params
|
566
|
+
else
|
567
|
+
return nil, {}
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|