1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """CIM operations over HTTP.
25
26 The `WBEMConnection` class in this module opens a connection to a remote
27 WBEM server. Across this connection you can run various CIM operations.
28 Each method of this class corresponds fairly directly to a single CIM
29 operation.
30 """
31
32
33
34 import string
35 import re
36 from types import StringTypes
37 from xml.dom import minidom
38 from datetime import datetime, timedelta
39 from xml.parsers.expat import ExpatError
40
41 from pywbem import cim_obj, cim_xml, cim_http, cim_types, tupletree, tupleparse
42 from pywbem.cim_obj import CIMInstance, CIMInstanceName, CIMClass, \
43 CIMClassName, NocaseDict
44 from pywbem.tupleparse import ParseError
45
46 __all__ = ['DEFAULT_NAMESPACE', 'check_utf8_xml_chars',
47 'CIMError', 'WBEMConnection', 'is_subclass',
48 'PegasusUDSConnection', 'SFCBUDSConnection',
49 'OpenWBEMUDSConnection']
50
51 DEFAULT_NAMESPACE = 'root/cimv2'
52
53 if len(u'\U00010122') == 2:
54
55 _ILLEGAL_XML_CHARS_RE = re.compile(
56 u'([\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE\uFFFF])')
57 else:
58
59 _ILLEGAL_XML_CHARS_RE = re.compile(
60 u'([\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE\uFFFF])')
61
62 _ILL_FORMED_UTF8_RE = re.compile(
63 '(\xED[\xA0-\xBF][\x80-\xBF])')
64
65
67 """
68 Validate a classname.
69
70 At this point, only the type is validated to be a string.
71 """
72 if not isinstance(val, StringTypes):
73 raise ValueError("string expected for classname, not %s" % `val`)
74
76 """
77 Examine a UTF-8 encoded XML string and raise a `pywbem.ParseError`
78 exception if the response contains Bytes that are invalid UTF-8
79 sequences (incorrectly encoded or ill-formed) or that are invalid XML
80 characters.
81
82 This function works in both "wide" and "narrow" Unicode builds of Python
83 and supports the full range of Unicode characters from U+0000 to U+10FFFF.
84
85 This function is just a workaround for the bad error handling of Python's
86 `xml.dom.minidom` package. It replaces the not very informative
87 `ExpatError` "not well-formed (invalid token): line: x, column: y" with a
88 `pywbem.ParseError` providing more useful information.
89
90 :Parameters:
91
92 utf8_xml : string
93 The UTF-8 encoded XML string to be examined.
94
95 meaning : string
96 Short text with meaning of the XML string, for messages in exceptions.
97
98 :Exceptions:
99
100 `TypeError`, if invoked with incorrect Python object type for `utf8_xml`.
101
102 `pywbem.ParseError`, if `utf8_xml` contains Bytes that are invalid UTF-8
103 sequences (incorrectly encoded or ill-formed) or invalid XML characters.
104
105 Notes on Unicode support in Python:
106
107 (1) For internally representing Unicode characters in the unicode type, a
108 "wide" Unicode build of Python uses UTF-32, while a "narrow" Unicode
109 build uses UTF-16. The difference is visible to Python programs for
110 Unicode characters assigned to code points above U+FFFF: The "narrow"
111 build uses 2 characters (a surrogate pair) for them, while the "wide"
112 build uses just 1 character. This affects all position- and
113 length-oriented functions, such as `len()` or string slicing.
114
115 (2) In a "wide" Unicode build of Python, the Unicode characters assigned to
116 code points U+10000 to U+10FFFF are represented directly (using code
117 points U+10000 to U+10FFFF) and the surrogate code points
118 U+D800...U+DFFF are never used; in a "narrow" Unicode build of Python,
119 the Unicode characters assigned to code points U+10000 to U+10FFFF are
120 represented using pairs of the surrogate code points U+D800...U+DFFF.
121
122 Notes on the Unicode code points U+D800...U+DFFF ("surrogate code points"):
123
124 (1) These code points have no corresponding Unicode characters assigned,
125 because they are reserved for surrogates in the UTF-16 encoding.
126
127 (2) The UTF-8 encoding can technically represent the surrogate code points.
128 ISO/IEC 10646 defines that a UTF-8 sequence containing the surrogate
129 code points is ill-formed, but it is technically possible that such a
130 sequence is in a UTF-8 encoded XML string.
131
132 (3) The Python escapes ``\\u`` and ``\\U`` used in literal strings can
133 represent the surrogate code points (as well as all other code points,
134 regardless of whether they are assigned to Unicode characters).
135
136 (4) The Python `str.encode()` and `str.decode()` functions successfully
137 translate the surrogate code points back and forth for encoding UTF-8.
138
139 For example, ``'\\xed\\xb0\\x80'.decode("utf-8") = u'\\udc00'``.
140
141 (5) Because Python supports the encoding and decoding of UTF-8 sequences
142 also for the surrogate code points, the "narrow" Unicode build of
143 Python can be (mis-)used to transport each surrogate unit separately
144 encoded in (ill-formed) UTF-8.
145
146 For example, code point U+10122 can be (illegally) created from a
147 sequence of code points U+D800,U+DD22 represented in UTF-8:
148
149 ``'\\xED\\xA0\\x80\\xED\\xB4\\xA2'.decode("utf-8") = u'\\U00010122'``
150
151 while the correct UTF-8 sequence for this code point is:
152
153 ``u'\\U00010122'.encode("utf-8") = '\\xf0\\x90\\x84\\xa2'``
154
155 Notes on XML characters:
156
157 (1) The legal XML characters are defined in W3C XML 1.0 (Fith Edition):
158
159 ::
160
161 Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] |
162 [#x10000-#x10FFFF]
163
164 These are the code points of Unicode characters using a non-surrogate
165 representation.
166 """
167
168 context_before = 16
169 context_after = 16
170
171 if not isinstance(utf8_xml, str):
172 raise TypeError("utf8_xml argument does not have str type, but %s" % \
173 type(utf8_xml))
174
175
176
177
178
179 ic_list = list()
180 for m in _ILL_FORMED_UTF8_RE.finditer(utf8_xml):
181 ic_pos = m.start(1)
182 ic_seq = m.group(1)
183 ic_list.append((ic_pos,ic_seq))
184 if len(ic_list) > 0:
185 exc_txt = "Ill-formed (surrogate) UTF-8 Byte sequences found in %s:" %\
186 meaning
187 for (ic_pos,ic_seq) in ic_list:
188 exc_txt += "\n At offset %d:" % ic_pos
189 for c in ic_seq:
190 exc_txt += " 0x%02X" % ord(c)
191 cpos1 = max(ic_pos-context_before,0)
192 cpos2 = min(ic_pos+context_after,len(utf8_xml))
193 exc_txt += ", CIM-XML snippet: %r" % utf8_xml[cpos1:cpos2]
194 raise ParseError(exc_txt)
195
196
197
198 try:
199 utf8_xml_u = utf8_xml.decode("utf-8")
200 except UnicodeDecodeError as exc:
201
202
203
204
205
206
207 _codec, _str, _p1, _p2, _msg = exc.args
208 exc_txt = "Incorrectly encoded UTF-8 Byte sequences found in %s" %\
209 meaning
210 exc_txt += "\n At offset %d:" % _p1
211 for c in utf8_xml[_p1:_p2+1]:
212 exc_txt += " 0x%02X" % ord(c)
213 cpos1 = max(_p1-context_before,0)
214 cpos2 = min(_p2+context_after,len(utf8_xml))
215 exc_txt += ", CIM-XML snippet: %r" % utf8_xml[cpos1:cpos2]
216 raise ParseError(exc_txt)
217
218
219
220
221 ic_list = list()
222 last_ic_pos = -2
223 for m in _ILLEGAL_XML_CHARS_RE.finditer(utf8_xml_u):
224 ic_pos = m.start(1)
225 ic_char = m.group(1)
226 if ic_pos > last_ic_pos + 1:
227 ic_list.append((ic_pos,ic_char))
228 last_ic_pos = ic_pos
229 if len(ic_list) > 0:
230 exc_txt = "Invalid XML characters found in %s:" % meaning
231 for (ic_pos,ic_char) in ic_list:
232 cpos1 = max(ic_pos-context_before,0)
233 cpos2 = min(ic_pos+context_after,len(utf8_xml_u))
234 exc_txt += "\n At offset %d: U+%04X, CIM-XML snippet: %r" % \
235 (ic_pos, ord(ic_char), utf8_xml_u[cpos1:cpos2])
236 raise ParseError(exc_txt)
237
238 return utf8_xml
239
240
242 """
243 Exception indicating that the WBEM server has returned an error response
244 with a CIM status code.
245
246 The exception value is a tuple of
247 ``(error_code, description, exception_obj)``, where:
248
249 * ``error_code``: the numeric CIM status code. See `cim_constants` for
250 constants defining CIM status code values.
251
252 * ``description``: a string (`unicode` or UTF-8 encoded `str`)
253 that is the CIM status description text returned by the server,
254 representing a human readable message describing the error.
255
256 * ``exception_obj``: the underlying exception object that caused this
257 exception to be raised, or ``None``. Will always be ``None``.
258 """
259 pass
260
262 """
263 A client's connection to a WBEM server. This is the main class of the
264 PyWBEM client.
265
266 The connection object knows a default CIM namespace, which is used when no
267 namespace is specified on subsequent CIM operations (that support
268 specifying namespaces). Thus, the connection object can be used as a
269 connection to multiple CIM namespaces on a WBEM server (when the namespace
270 is specified on subsequent operations), or as a connection to only the
271 default namespace (this allows omitting the namespace on subsequent
272 operations).
273
274 As usual in HTTP, there is no persistent TCP connection; the connectedness
275 provided by this class is only conceptual. That is, the creation of the
276 connection object does not cause any interaction with the WBEM server, and
277 each subsequent CIM operation performs an independent, state-less
278 HTTP/HTTPS request.
279
280 After creating a `WBEMConnection` object, various methods may be called on
281 the object, which cause CIM operations to be invoked on the WBEM server.
282 All these methods take regular Python objects or objects defined in
283 `cim_types` as arguments, and return the same.
284 The caller does not need to know about the CIM-XML encoding that is used
285 underneath (It should be possible to use a different transport below this
286 layer without disturbing any callers).
287
288 The connection remembers the XML of the last request and last reply if
289 debugging is turned on via the `debug` instance variable of the connection
290 object.
291 This may be useful in debugging: If a problem occurs, you can examine the
292 `last_request` and `last_reply` instance variables of the connection
293 object. These are the prettified XML of request and response, respectively.
294 The real request and response that are sent and received are available in
295 the `last_raw_request` and `last_raw_reply` instance variables of the
296 connection object.
297
298 The methods of this class may raise the following exceptions:
299
300 * Exceptions indicating processing errors:
301
302 - `pywbem.ConnectionError` - A connection with the WBEM server could not
303 be established or broke down.
304
305 - `pywbem.AuthError` - Authentication failed with the WBEM server.
306
307 - `pywbem.ParseError` - The response from the WBEM server cannot be
308 parsed (for example, invalid characters or UTF-8 sequences, ill-formed
309 XML, or invalid CIM-XML).
310
311 - `pywbem.CIMError` - The WBEM server returned an error response with a
312 CIM status code.
313
314 - `pywbem.TimeoutError` - The WBEM server did not respond in time and the
315 client timed out.
316
317 * Exceptions indicating programming errors:
318
319 - `TypeError`
320 - `KeyError`
321 - `ValueError`
322 - ... possibly others ...
323
324 Exceptions indicating programming errors should not happen and should be
325 reported as bugs, unless caused by the code using this class.
326
327 :Ivariables:
328
329 ...
330 All parameters of `__init__` are set as instance variables.
331
332 debug : `bool`
333 A boolean indicating whether logging of the last request and last reply
334 is enabled.
335
336 The initial value of this instance variable is `False`.
337 Debug logging can be enabled for future operations by setting this
338 instance variable to `True`.
339
340 last_request : `unicode`
341 CIM-XML data of the last request sent to the WBEM server
342 on this connection, formatted as prettified XML. Prior to sending the
343 very first request on this connection object, it is `None`.
344
345 last_raw_request : `unicode`
346 CIM-XML data of the last request sent to the WBEM server
347 on this connection, formatted as it was sent. Prior to sending the
348 very first request on this connection object, it is `None`.
349
350 last_reply : `unicode`
351 CIM-XML data of the last response received from the WBEM server
352 on this connection, formatted as prettified XML. Prior to sending the
353 very first request on this connection object, while waiting for any
354 response, it is `None`.
355
356 last_raw_reply : `unicode`
357 CIM-XML data of the last response received from the WBEM server
358 on this connection, formatted as it was received. Prior to sending the
359 very first request on this connection object, while waiting for any
360 response, it is `None`.
361 """
362
363 - def __init__(self, url, creds=None, default_namespace=DEFAULT_NAMESPACE,
364 x509=None, verify_callback=None, ca_certs=None,
365 no_verification=False, timeout=None):
366 """
367 Initialize the `WBEMConnection` object.
368
369 :Parameters:
370
371 url : string
372 URL of the WBEM server (e.g. ``"https://10.11.12.13:6988"``).
373
374 TODO: Describe supported formats.
375
376 creds
377 Credentials for authenticating with the WBEM server. Currently,
378 that is always a tuple of ``(userid, password)``, where:
379
380 * ``userid`` is a string that is the userid to be used for
381 authenticating with the WBEM server.
382
383 * ``password`` is a string that is the password for that userid.
384
385 default_namespace : string
386 Optional: Name of the CIM namespace to be used by default (if no
387 namespace is specified for an operation).
388
389 Default: See method definition.
390
391 x509 : dictionary
392 Optional: X.509 certificates for HTTPS to be used instead of the
393 credentials provided in the `creds` parameter. This parameter is
394 used only when the `url` parameter specifies a scheme of ``https``.
395
396 If `None`, certificates are not used (and credentials are used
397 instead).
398
399 Otherwise, certificates are used instead of the credentials, and
400 this parameter must be a dictionary containing the following
401 key/value pairs:
402
403 * ``'cert_file'`` : The file path of a file containing an X.509
404 certificate.
405
406 * ``'key_file'`` : The file path of a file containing the private
407 key belonging to the public key that is part of the X.509
408 certificate file.
409
410 Default: `None`.
411
412 verify_callback : function
413 Optional: Registers a callback function that will be called to
414 verify the certificate returned by the WBEM server during the SSL
415 handshake, in addition to the verification alreay performed by
416 `M2Crypto`.
417
418 If `None`, no such callback function will be registered.
419
420 The specified function will be called for the returned certificate,
421 and for each of the certificates in its chain of trust.
422
423 See `M2Crypto.SSL.Context.set_verify` for details, as well as
424 http://blog.san-ss.com.ar/2012/05/validating-ssl-certificate-in-python.html):
425
426 The callback function must take five parameters:
427
428 * the `M2Crypto.SSL.Connection` object that triggered the
429 verification.
430
431 * an `OpenSSL.crypto.X509` object representing the certificate
432 to be validated (the returned certificate or one of the
433 certificates in its chain of trust).
434
435 * an integer containing the error number (0 in case no error) of
436 any validation error detected by `M2Crypto`.
437 You can find their meaning in the OpenSSL documentation.
438
439 * an integer indicating the depth (=position) of the certificate to
440 be validated (the one in the second parameter) in the chain of
441 trust of the returned certificate. A value of 0 indicates
442 that the returned is currently validated; any other value
443 indicates the distance of the currently validated certificate to
444 the returned certificate in its chain of trust.
445
446 * an integer that indicates whether the validation of the
447 certificate specified in the second argument passed or did not
448 pass the validation by `M2Crypto`. A value of 1 indicates a
449 successful validation and 0 an unsuccessful one.
450
451 The callback function must return `True` if the verification
452 passes and `False` otherwise.
453
454 Default: `None`.
455
456 ca_certs : string
457 Optional: Location of CA certificates (trusted certificates) for
458 verification purposes.
459
460 The parameter value is either the directory path of a directory
461 prepared using the ``c_rehash`` tool included with OpenSSL, or the
462 file path of a file in PEM format.
463
464 If `None`, the default system path will be used.
465
466 Default: `None`.
467
468 no_verification : `bool`
469 Optional: Indicates that verification of the certificate returned
470 by the WBEM server is disabled (both by `M2Crypto` and by the
471 callback function specified in `verify_callback`).
472
473 Disabling the verification is insecure and should be avoided.
474
475 If `True`, verification is disabled; otherwise, it is enabled.
476
477 Default: `False`.
478
479 timeout : number
480 Timeout in seconds, for requests sent to the server. If the server
481 did not respond within the timeout duration, the socket for the
482 connection will be closed, causing a `TimeoutError` to be raised.
483
484 A value of ``None`` means there is no timeout.
485
486 A value of ``0`` means the timeout is very short, and does not
487 really make any sense.
488
489 Note that not all situations can be handled within this timeout, so
490 for some issues, operations may take longer before raising an
491 exception.
492
493 :Exceptions:
494
495 See the list of exceptions described in `WBEMConnection`.
496 """
497
498 self.url = url
499 self.creds = creds
500 self.x509 = x509
501 self.verify_callback = verify_callback
502 self.ca_certs = ca_certs
503 self.no_verification = no_verification
504 self.default_namespace = default_namespace
505 self.timeout = timeout
506
507 self.debug = False
508 self.last_raw_request = None
509 self.last_raw_reply = None
510 self.last_request = None
511 self.last_reply = None
512
514 """
515 Return a representation of the connection object with the major
516 instance variables, except for the password in the credentials.
517
518 TODO: Change to show all instance variables.
519 """
520 if self.creds is None:
521 user = 'anonymous'
522 else:
523 user = 'user=%s' % `self.creds[0]`
524 return "%s(%s, %s, namespace=%s)" % \
525 (self.__class__.__name__, `self.url`, user,
526 `self.default_namespace`)
527
528 - def imethodcall(self, methodname, namespace, **params):
529 """
530 Perform an intrinsic method call (= CIM operation).
531
532 This is a low-level function that is used by the operation-specific
533 methods of this class (e.g. `EnumerateInstanceNames`). In general,
534 clients should call these operation-specific methods instead of this
535 function.
536
537 The parameters are automatically converted to the right CIM-XML
538 elements.
539
540 :Returns:
541
542 A tupletree (see `tupletree` module) with an ``IRETURNVALUE``
543 element at the root.
544
545 :Exceptions:
546
547 See the list of exceptions described in `WBEMConnection`.
548 """
549
550
551
552 headers = ['CIMOperation: MethodCall',
553 'CIMMethod: %s' % methodname,
554 cim_http.get_object_header(namespace)]
555
556
557
558 plist = map(lambda x:
559 cim_xml.IPARAMVALUE(x[0], cim_obj.tocimxml(x[1])),
560 params.items())
561
562
563
564 req_xml = cim_xml.CIM(
565 cim_xml.MESSAGE(
566 cim_xml.SIMPLEREQ(
567 cim_xml.IMETHODCALL(
568 methodname,
569 cim_xml.LOCALNAMESPACEPATH(
570 [cim_xml.NAMESPACE(ns)
571 for ns in string.split(namespace, '/')]),
572 plist)),
573 '1001', '1.0'),
574 '2.0', '2.0')
575
576 if self.debug:
577 self.last_raw_request = req_xml.toxml()
578 self.last_request = req_xml.toprettyxml(indent=' ')
579
580 self.last_raw_reply = None
581 self.last_reply = None
582
583
584
585 try:
586 reply_xml = cim_http.wbem_request(
587 self.url, req_xml.toxml(), self.creds, headers,
588 x509=self.x509,
589 verify_callback=self.verify_callback,
590 ca_certs=self.ca_certs,
591 no_verification=self.no_verification,
592 timeout=self.timeout)
593 except (cim_http.AuthError, cim_http.ConnectionError,
594 cim_http.TimeoutError, cim_http.Error):
595 raise
596
597
598 if self.debug:
599 self.last_raw_reply = reply_xml
600
601 try:
602 reply_dom = minidom.parseString(reply_xml)
603 except ParseError as exc:
604 msg = str(exc)
605 parsing_error = True
606 except ExpatError as exc:
607
608
609
610 parsed_line = str(reply_xml).splitlines()[exc.lineno-1]
611 msg = "ExpatError %s: %s: %r" % (str(exc.code), str(exc),
612 parsed_line)
613 parsing_error = True
614 else:
615 parsing_error = False
616
617 if parsing_error or self.debug:
618
619
620
621
622 try:
623 check_utf8_xml_chars(reply_xml, "CIM-XML response")
624 except ParseError:
625 raise
626 else:
627 if parsing_error:
628
629
630 raise ParseError(msg)
631
632 if self.debug:
633 pretty_reply = reply_dom.toprettyxml(indent=' ')
634 self.last_reply = re.sub(r'>( *[\r\n]+)+( *)<', r'>\n\2<',
635 pretty_reply)
636
637
638
639 tt = tupleparse.parse_cim(tupletree.dom_to_tupletree(reply_dom))
640
641 if tt[0] != 'CIM':
642 raise ParseError('Expecting CIM element, got %s' % tt[0])
643 tt = tt[2]
644
645 if tt[0] != 'MESSAGE':
646 raise ParseError('Expecting MESSAGE element, got %s' % tt[0])
647 tt = tt[2]
648
649 if len(tt) != 1 or tt[0][0] != 'SIMPLERSP':
650 raise ParseError('Expecting one SIMPLERSP element')
651 tt = tt[0][2]
652
653 if tt[0] != 'IMETHODRESPONSE':
654 raise ParseError('Expecting IMETHODRESPONSE element, got %s' %\
655 tt[0])
656
657 if tt[1]['NAME'] != methodname:
658 raise ParseError('Expecting attribute NAME=%s, got %s' %\
659 (methodname, tt[1]['NAME']))
660 tt = tt[2]
661
662
663
664
665
666 if tt is None:
667 return None
668
669 if tt[0] == 'ERROR':
670 code = int(tt[1]['CODE'])
671 if tt[1].has_key('DESCRIPTION'):
672 raise CIMError(code, tt[1]['DESCRIPTION'])
673 raise CIMError(code, 'Error code %s' % tt[1]['CODE'])
674
675 if tt[0] != 'IRETURNVALUE':
676 raise ParseError('Expecting IRETURNVALUE element, got %s' % tt[0])
677
678 return tt
679
680 - def methodcall(self, methodname, localobject, Params=None, **params):
681 """
682 Perform an extrinsic method call (= CIM method invocation).
683
684 This is a low-level function that is used by the 'InvokeMethod'
685 method of this class. In general, clients should use 'InvokeMethod'
686 instead of this function.
687
688 The Python method parameters are automatically converted to the right
689 CIM-XML elements. See `InvokeMethod` for details.
690
691 :Returns:
692
693 A tupletree (see `tupletree` module) with a ``RETURNVALUE``
694 element at the root.
695
696 :Exceptions:
697
698 See the list of exceptions described in `WBEMConnection`.
699 """
700
701
702 if hasattr(localobject, 'host') and localobject.host is not None:
703 localobject = localobject.copy()
704 localobject.host = None
705
706
707
708 headers = ['CIMOperation: MethodCall',
709 'CIMMethod: %s' % methodname,
710 cim_http.get_object_header(localobject)]
711
712
713
714 def paramtype(obj):
715 """Return a string to be used as the CIMTYPE for a parameter."""
716 if isinstance(obj, cim_types.CIMType):
717 return obj.cimtype
718 elif type(obj) == bool:
719 return 'boolean'
720 elif isinstance(obj, StringTypes):
721 return 'string'
722 elif isinstance(obj, (datetime, timedelta)):
723 return 'datetime'
724 elif isinstance(obj, (CIMClassName, CIMInstanceName)):
725 return 'reference'
726 elif isinstance(obj, (CIMClass, CIMInstance)):
727 return 'string'
728 elif isinstance(obj, list):
729 if obj:
730 return paramtype(obj[0])
731 else:
732 return None
733 raise TypeError('Unsupported parameter type "%s"' % type(obj))
734
735 def paramvalue(obj):
736 """Return a cim_xml node to be used as the value for a
737 parameter."""
738 if isinstance(obj, (datetime, timedelta)):
739 obj = cim_types.CIMDateTime(obj)
740 if isinstance(obj, (cim_types.CIMType, bool, StringTypes)):
741 return cim_xml.VALUE(cim_types.atomic_to_cim_xml(obj))
742 if isinstance(obj, (CIMClassName, CIMInstanceName)):
743 return cim_xml.VALUE_REFERENCE(obj.tocimxml())
744 if isinstance(obj, (CIMClass, CIMInstance)):
745 return cim_xml.VALUE(obj.tocimxml().toxml())
746 if isinstance(obj, list):
747 if obj and isinstance(obj[0], (CIMClassName, CIMInstanceName)):
748 return cim_xml.VALUE_REFARRAY([paramvalue(x) for x in obj])
749 return cim_xml.VALUE_ARRAY([paramvalue(x) for x in obj])
750 raise TypeError('Unsupported parameter type "%s"' % type(obj))
751
752 def is_embedded(obj):
753 """Determine if an object requires an EmbeddedObject attribute"""
754 if isinstance(obj, list) and obj:
755 return is_embedded(obj[0])
756 elif isinstance(obj, CIMClass):
757 return 'object'
758 elif isinstance(obj, CIMInstance):
759 return 'instance'
760 return None
761
762 if Params is None:
763 Params = []
764 plist = [cim_xml.PARAMVALUE(x[0],
765 paramvalue(x[1]),
766 paramtype(x[1]),
767 embedded_object=is_embedded(x[1]))
768 for x in Params]
769 plist += [cim_xml.PARAMVALUE(x[0],
770 paramvalue(x[1]),
771 paramtype(x[1]),
772 embedded_object=is_embedded(x[1]))
773 for x in params.items()]
774
775
776
777 req_xml = cim_xml.CIM(
778 cim_xml.MESSAGE(
779 cim_xml.SIMPLEREQ(
780 cim_xml.METHODCALL(
781 methodname,
782 localobject.tocimxml(),
783 plist)),
784 '1001', '1.0'),
785 '2.0', '2.0')
786
787 if self.debug:
788 self.last_raw_request = req_xml.toxml()
789 self.last_request = req_xml.toprettyxml(indent=' ')
790
791 self.last_raw_reply = None
792 self.last_reply = None
793
794
795
796 try:
797 reply_xml = cim_http.wbem_request(
798 self.url, req_xml.toxml(), self.creds, headers,
799 x509=self.x509,
800 verify_callback=self.verify_callback,
801 ca_certs=self.ca_certs,
802 no_verification=self.no_verification,
803 timeout=self.timeout)
804 except (cim_http.AuthError, cim_http.ConnectionError,
805 cim_http.TimeoutError, cim_http.Error):
806 raise
807
808
809 if self.debug:
810 self.last_raw_reply = reply_xml
811
812 try:
813 reply_dom = minidom.parseString(reply_xml)
814 except ParseError as exc:
815 msg = str(exc)
816 parsing_error = True
817 except ExpatError as exc:
818
819
820
821 parsed_line = str(reply_xml).splitlines()[exc.lineno-1]
822 msg = "ExpatError %s: %s: %r" % (str(exc.code), str(exc),
823 parsed_line)
824 parsing_error = True
825 else:
826 parsing_error = False
827
828 if parsing_error or self.debug:
829
830
831
832
833 try:
834 check_utf8_xml_chars(reply_xml, "CIM-XML response")
835 except ParseError:
836 raise
837 else:
838 if parsing_error:
839
840
841 raise ParseError(msg)
842
843 if self.debug:
844 pretty_reply = reply_dom.toprettyxml(indent=' ')
845 self.last_reply = re.sub(r'>( *[\r\n]+)+( *)<', r'>\n\2<',
846 pretty_reply)
847
848
849
850 tt = tupleparse.parse_cim(tupletree.dom_to_tupletree(reply_dom))
851
852 if tt[0] != 'CIM':
853 raise ParseError('Expecting CIM element, got %s' % tt[0])
854 tt = tt[2]
855
856 if tt[0] != 'MESSAGE':
857 raise ParseError('Expecting MESSAGE element, got %s' % tt[0])
858 tt = tt[2]
859
860 if len(tt) != 1 or tt[0][0] != 'SIMPLERSP':
861 raise ParseError('Expecting one SIMPLERSP element')
862 tt = tt[0][2]
863
864 if tt[0] != 'METHODRESPONSE':
865 raise ParseError('Expecting METHODRESPONSE element, got %s' %\
866 tt[0])
867
868 if tt[1]['NAME'] != methodname:
869 raise ParseError('Expecting attribute NAME=%s, got %s' %\
870 (methodname, tt[1]['NAME']))
871 tt = tt[2]
872
873
874
875
876 if len(tt) > 0 and tt[0][0] == 'ERROR':
877 code = int(tt[0][1]['CODE'])
878 if tt[0][1].has_key('DESCRIPTION'):
879 raise CIMError(code, tt[0][1]['DESCRIPTION'])
880 raise CIMError(code, 'Error code %s' % tt[0][1]['CODE'])
881
882 return tt
883
884
885
886
887
889
890 """
891 Enumerate the instance paths of instances of a class (including
892 instances of its subclasses).
893
894 This method performs the EnumerateInstanceNames CIM-XML operation.
895 If the operation succeeds, this method returns.
896 Otherwise, this method raises an exception.
897
898 :Parameters:
899
900 ClassName : string
901 Name of the class to be enumerated.
902
903 namespace : string
904 Optional: Name of the CIM namespace to be used. The value `None`
905 causes the default namespace of the connection object to be used.
906
907 Default: `None`.
908
909 :Returns:
910
911 A list of `CIMInstanceName` objects that are the enumerated
912 instance paths.
913
914 :Exceptions:
915
916 See the list of exceptions described in `WBEMConnection`.
917 """
918
919 if namespace is None:
920 namespace = self.default_namespace
921
922 result = self.imethodcall(
923 'EnumerateInstanceNames',
924 namespace,
925 ClassName=CIMClassName(ClassName),
926 **params)
927
928 names = []
929
930 if result is not None:
931 names = result[2]
932
933 [setattr(n, 'namespace', namespace) for n in names]
934
935 return names
936
938
939 """
940 Enumerate the instances of a class (including instances of its
941 subclasses).
942
943 This method performs the EnumerateInstances CIM-XML operation.
944 If the operation succeeds, this method returns.
945 Otherwise, this method raises an exception.
946
947 :Parameters:
948
949 ClassName : string
950 Name of the class to be enumerated.
951
952 namespace : string
953 Optional: Name of the CIM namespace to be used. The value `None`
954 causes the default namespace of the connection object to be used.
955
956 Default: `None`.
957
958 LocalOnly : `bool`
959 Optional: Controls the exclusion of inherited properties from the
960 returned instances, as follows:
961
962 * If `False`, inherited properties are not excluded.
963 * If `True`, the behavior is WBEM server specific.
964
965 Default: `True`.
966
967 This parameter has been deprecated in CIM-XML and should be set to
968 `False` by the caller.
969
970 DeepInheritance : `bool`
971 Optional: Indicates that properties added by subclasses of the
972 specified class are to be included in the returned instances.
973 Note, the semantics of this parameter differs between instance and
974 class level operations.
975
976 Default: `True`.
977
978 IncludeQualifiers : `bool`
979 Optional: Indicates that qualifiers are to be included in the
980 returned instance.
981
982 Default: `False`.
983
984 This parameter has been deprecated in CIM-XML. Clients cannot rely
985 on it being implemented by WBEM servers.
986
987 IncludeClassOrigin : `bool`
988 Optional: Indicates that class origin information is to be included
989 on each property in the returned instances.
990
991 Default: `False`.
992
993 PropertyList : iterable of string
994 Optional: An iterable specifying the names of the properties to be
995 included in the returned instances. An empty iterable indicates to
996 include no properties. A value of `None` for this parameter
997 indicates to include all properties.
998
999 Default: `None`.
1000
1001 :Returns:
1002
1003 A list of `CIMInstance` objects that are representations of
1004 the enumerated instances.
1005
1006 :Exceptions:
1007
1008 See the list of exceptions described in `WBEMConnection`.
1009 """
1010
1011 if namespace is None:
1012 namespace = self.default_namespace
1013
1014 result = self.imethodcall(
1015 'EnumerateInstances',
1016 namespace,
1017 ClassName=CIMClassName(ClassName),
1018 **params)
1019
1020 instances = []
1021
1022 if result is not None:
1023 instances = result[2]
1024
1025 [setattr(i.path, 'namespace', namespace) for i in instances]
1026
1027 return instances
1028
1030
1031 """
1032 Retrieve an instance.
1033
1034 This method performs the GetInstance CIM-XML operation.
1035 If the operation succeeds, this method returns.
1036 Otherwise, this method raises an exception.
1037
1038 :Parameters:
1039
1040 InstanceName : `CIMInstanceName`
1041 Instance path of the instance to be retrieved.
1042
1043 LocalOnly : `bool`
1044 Optional: Controls the exclusion of inherited properties from the
1045 returned instance, as follows:
1046
1047 * If `False`, inherited properties are not excluded.
1048 * If `True`, the behavior is WBEM server specific.
1049
1050 Default: `True`.
1051
1052 This parameter has been deprecated in CIM-XML and should be set to
1053 `False` by the caller.
1054
1055 IncludeQualifiers : `bool`
1056 Optional: Indicates that qualifiers are to be included in the
1057 returned instance.
1058
1059 Default: `False`.
1060
1061 This parameter has been deprecated in CIM-XML. Clients cannot rely
1062 on it being implemented by WBEM servers.
1063
1064 IncludeClassOrigin : `bool`
1065 Optional: Indicates that class origin information is to be included
1066 on each property in the returned instance.
1067
1068 Default: `False`.
1069
1070 PropertyList : iterable of string
1071 Optional: An iterable specifying the names of the properties to be
1072 included in the returned instances. An empty iterable indicates to
1073 include no properties. A value of `None` for this parameter
1074 indicates to include all properties.
1075
1076 Default: `None`.
1077
1078 :Returns:
1079
1080 A `CIMInstance` object that is a representation of the
1081 retrieved instance.
1082
1083 :Exceptions:
1084
1085 See the list of exceptions described in `WBEMConnection`.
1086 """
1087
1088
1089
1090 iname = InstanceName.copy()
1091 iname.host = None
1092 iname.namespace = None
1093
1094 if InstanceName.namespace is None:
1095 namespace = self.default_namespace
1096 else:
1097 namespace = InstanceName.namespace
1098
1099 result = self.imethodcall(
1100 'GetInstance',
1101 namespace,
1102 InstanceName=iname,
1103 **params)
1104
1105 instance = result[2][0]
1106 instance.path = InstanceName
1107 instance.path.namespace = namespace
1108
1109 return instance
1110
1112
1113 """
1114 Delete an instance.
1115
1116 This method performs the DeleteInstance CIM-XML operation.
1117 If the operation succeeds, this method returns.
1118 Otherwise, this method raises an exception.
1119
1120 :Parameters:
1121
1122 InstanceName : `CIMInstanceName`
1123 Instance path of the instance to be deleted.
1124
1125 :Exceptions:
1126
1127 See the list of exceptions described in `WBEMConnection`.
1128 """
1129
1130
1131
1132 iname = InstanceName.copy()
1133 iname.host = None
1134 iname.namespace = None
1135
1136 if InstanceName.namespace is None:
1137 namespace = self.default_namespace
1138 else:
1139 namespace = InstanceName.namespace
1140
1141 self.imethodcall(
1142 'DeleteInstance',
1143 namespace,
1144 InstanceName=iname,
1145 **params)
1146
1148
1149 """
1150 Create an instance.
1151
1152 This method performs the CreateInstance CIM-XML operation.
1153 If the operation succeeds, this method returns.
1154 Otherwise, this method raises an exception.
1155
1156 :Parameters:
1157
1158 NewInstance : `CIMInstance`
1159 A representation of the instance to be created.
1160
1161 The `namespace` and `classname` instance variables of this object
1162 specify CIM namespace and creation class for the new instance,
1163 respectively.
1164 An instance path specified using the `path` instance variable of
1165 this object will be ignored.
1166
1167 The `properties` instance variable of this object specifies initial
1168 property values for the new instance.
1169
1170 Instance-level qualifiers have been deprecated in CIM, so any
1171 qualifier values specified using the `qualifiers` instance variable
1172 of this object will be ignored.
1173
1174 :Returns:
1175
1176 `CIMInstanceName` object that is the instance path of the new
1177 instance.
1178
1179 :Exceptions:
1180
1181 See the list of exceptions described in `WBEMConnection`.
1182 """
1183
1184
1185
1186 if NewInstance.path is not None and \
1187 NewInstance.path.namespace is not None:
1188 namespace = NewInstance.path.namespace
1189 else:
1190 namespace = self.default_namespace
1191
1192
1193
1194
1195 instance = NewInstance.copy()
1196 instance.path = None
1197
1198 result = self.imethodcall(
1199 'CreateInstance',
1200 namespace,
1201 NewInstance=instance,
1202 **params)
1203
1204 name = result[2][0]
1205 name.namespace = namespace
1206
1207 return name
1208
1210
1211 """
1212 Modify the property values of an instance.
1213
1214 This method performs the ModifyInstance CIM-XML operation.
1215 If the operation succeeds, this method returns.
1216 Otherwise, this method raises an exception.
1217
1218 :Parameters:
1219
1220 ModifiedInstance : `CIMInstance`
1221 A representation of the modified instance. This object needs to
1222 contain any new property values and the instance path of the
1223 instance to be modified. Missing properties (relative to the class
1224 declaration) and properties provided with a value of `None` will be
1225 set to NULL. Typically, this object has been retrieved by other
1226 operations, such as GetInstance.
1227
1228 IncludeQualifiers : `bool`
1229 Optional: Indicates that qualifiers are to be modified as specified
1230 in the `ModifiedInstance` parameter.
1231
1232 Default: `True`.
1233
1234 This parameter has been deprecated in CIM-XML. Clients cannot rely
1235 on it being implemented by WBEM servers.
1236
1237 PropertyList : iterable of string
1238 Optional: An iterable specifying the names of the properties to be
1239 modified. An empty iterable indicates to modify no properties. A
1240 value of `None` for this parameter indicates to modify all
1241 properties.
1242
1243 Default: `None`.
1244
1245 :Exceptions:
1246
1247 See the list of exceptions described in `WBEMConnection`.
1248 """
1249
1250
1251
1252 if ModifiedInstance.path is None:
1253 raise ValueError(
1254 'ModifiedInstance parameter must have path attribute set')
1255
1256
1257
1258 if ModifiedInstance.path.namespace is None:
1259 namespace = self.default_namespace
1260 else:
1261 namespace = ModifiedInstance.path.namespace
1262
1263 instance = ModifiedInstance.copy()
1264 instance.path.namespace = None
1265
1266 self.imethodcall(
1267 'ModifyInstance',
1268 namespace,
1269 ModifiedInstance=instance,
1270 **params)
1271
1272 - def ExecQuery(self, QueryLanguage, Query, namespace=None):
1273
1274 """
1275 Execute a query in a namespace.
1276
1277 This method performs the ExecQuery CIM-XML operation.
1278 If the operation succeeds, this method returns.
1279 Otherwise, this method raises an exception.
1280
1281 :Parameters:
1282
1283 QueryLanguage : string
1284 Name of the query language used in the `Query` parameter.
1285
1286 Query : string
1287 Query string in the query language specified in the `QueryLanguage`
1288 parameter.
1289
1290 namespace : string
1291 Optional: Name of the CIM namespace to be used. The value `None`
1292 causes the default namespace of the connection object to be used.
1293
1294 Default: `None`.
1295
1296 :Returns:
1297
1298 A list of `CIMInstance` objects that represents the query
1299 result.
1300 These instances have their `path` instance variable set to identify
1301 their creation class and the target namespace of the query, but
1302 they are not addressable instances.
1303
1304 :Exceptions:
1305
1306 See the list of exceptions described in `WBEMConnection`.
1307 """
1308
1309 if namespace is None:
1310 namespace = self.default_namespace
1311
1312 result = self.imethodcall(
1313 'ExecQuery',
1314 namespace,
1315 QueryLanguage=QueryLanguage,
1316 Query=Query)
1317
1318 instances = []
1319
1320 if result is not None:
1321 instances = [tt[2] for tt in result[2]]
1322
1323 [setattr(i.path, 'namespace', namespace) for i in instances]
1324
1325 return instances
1326
1327
1328
1329
1330
1332 """Convert string ClassName parameter to a CIMClassName."""
1333
1334 if params.has_key('ClassName') and \
1335 isinstance(params['ClassName'], StringTypes):
1336 params['ClassName'] = CIMClassName(params['ClassName'])
1337
1338 return params
1339
1341
1342 """
1343 Enumerate the names of subclasses of a class, or of the top-level
1344 classes in a namespace.
1345
1346 This method performs the EnumerateClassNames CIM-XML operation.
1347 If the operation succeeds, this method returns.
1348 Otherwise, this method raises an exception.
1349
1350 :Parameters:
1351
1352 namespace : string
1353 Optional: Name of the namespace of the class, as a string.
1354 The value `None` causes the default namespace of the connection to
1355 be used.
1356
1357 Default: `None`
1358
1359 ClassName : string
1360 Optional: Name of the class whose subclasses are to be retrieved.
1361 The value `None` causes the top-level classes in the namespace to
1362 be retrieved.
1363
1364 Default: `None`
1365
1366 DeepInheritance : `bool`
1367 Optional: Indicates that all (direct and indirect) subclasses of
1368 the specified class or of the top-level classes are to be included
1369 in the result.
1370 `False` indicates that only direct subclasses of the specified
1371 class or ony top-level classes are to be included in the result.
1372
1373 Note, the semantics of this parameter differs between instance and
1374 class level operations.
1375
1376 Default: `False`.
1377
1378 :Returns:
1379
1380 A list of strings that are the class names of the enumerated
1381 classes.
1382
1383 :Exceptions:
1384
1385 See the list of exceptions described in `WBEMConnection`.
1386 """
1387
1388 params = self._map_classname_param(params)
1389
1390 if namespace is None:
1391 namespace = self.default_namespace
1392
1393 result = self.imethodcall(
1394 'EnumerateClassNames',
1395 namespace,
1396 **params)
1397
1398 if result is None:
1399 return []
1400 else:
1401 return map(lambda x: x.classname, result[2])
1402
1404
1405 """
1406 Enumerate the subclasses of a class, or the top-level classes in a
1407 namespace.
1408
1409 This method performs the EnumerateClasses CIM-XML operation.
1410 If the operation succeeds, this method returns.
1411 Otherwise, this method raises an exception.
1412
1413 :Parameters:
1414
1415 namespace : string
1416 Optional: Name of the namespace of the class, as a string.
1417 The value `None` causes the default namespace of the connection to
1418 be used.
1419
1420 Default: `None`
1421
1422 ClassName : string
1423 Optional: Name of the class whose subclasses are to be retrieved.
1424 The value `None` causes the top-level classes in the namespace to
1425 be retrieved.
1426
1427 Default: `None`
1428
1429 DeepInheritance : `bool`
1430 Optional: Indicates that all (direct and indirect) subclasses of
1431 the specified class or of the top-level classes are to be included
1432 in the result.
1433 `False` indicates that only direct subclasses of the specified
1434 class or ony top-level classes are to be included in the result.
1435
1436 Note, the semantics of this parameter differs between instance and
1437 class level operations.
1438
1439 Default: `False`.
1440
1441 LocalOnly : `bool`
1442 Optional: Indicates that inherited properties, methods, and
1443 qualifiers are to be excluded from the returned classes.
1444
1445 Default: `True`.
1446
1447 IncludeQualifiers : `bool`
1448 Optional: Indicates that qualifiers are to be included in the
1449 returned classes.
1450
1451 Default: `False`.
1452
1453 IncludeClassOrigin : `bool`
1454 Optional: Indicates that class origin information is to be included
1455 on each property and method in the returned classes.
1456
1457 Default: `False`.
1458
1459 :Returns:
1460
1461 A list of `CIMClass` objects that are representations of the
1462 enumerated classes.
1463
1464 :Exceptions:
1465
1466 See the list of exceptions described in `WBEMConnection`.
1467 """
1468
1469 params = self._map_classname_param(params)
1470
1471 if namespace is None:
1472 namespace = self.default_namespace
1473
1474 result = self.imethodcall(
1475 'EnumerateClasses',
1476 namespace,
1477 **params)
1478
1479 if result is None:
1480 return []
1481
1482 return result[2]
1483
1484 - def GetClass(self, ClassName, namespace=None, **params):
1485
1486 """
1487 Retrieve a class.
1488
1489 This method performs the GetClass CIM-XML operation.
1490 If the operation succeeds, this method returns.
1491 Otherwise, this method raises an exception.
1492
1493 :Parameters:
1494
1495 ClassName : string
1496 Name of the class to be retrieved.
1497
1498 namespace : string
1499 Optional: Name of the namespace of the class, as a string.
1500 The value `None` causes the default namespace of the connection to
1501 be used.
1502
1503 Default: `None`
1504
1505 LocalOnly : `bool`
1506 Optional: Indicates that inherited properties, methods, and
1507 qualifiers are to be excluded from the returned class.
1508
1509 Default: `True`.
1510
1511 IncludeQualifiers : `bool`
1512 Optional: Indicates that qualifiers are to be included in the
1513 returned class.
1514
1515 Default: `False`.
1516
1517 IncludeClassOrigin : `bool`
1518 Optional: Indicates that class origin information is to be included
1519 on each property and method in the returned class.
1520
1521 Default: `False`.
1522
1523 PropertyList : iterable of string
1524 Optional: An iterable specifying the names of the properties to be
1525 included in the returned class. An empty iterable indicates to
1526 include no properties. A value of `None` for this parameter
1527 indicates to include all properties.
1528
1529 Default: `None`.
1530
1531 :Returns:
1532
1533 A `CIMClass` object that is a representation of the
1534 retrieved class.
1535
1536 :Exceptions:
1537
1538 See the list of exceptions described in `WBEMConnection`.
1539 """
1540
1541 params = self._map_classname_param(params)
1542
1543 if namespace is None:
1544 namespace = self.default_namespace
1545
1546 result = self.imethodcall(
1547 'GetClass',
1548 namespace,
1549 ClassName=CIMClassName(ClassName),
1550 **params)
1551
1552 return result[2][0]
1553
1554 - def DeleteClass(self, ClassName, namespace=None, **params):
1555
1556 """
1557 Delete a class.
1558
1559 This method performs the DeleteClass CIM-XML operation.
1560 If the operation succeeds, this method returns.
1561 Otherwise, this method raises an exception.
1562
1563 TODO This method is UNSUPPORTED right now. Test and verify description.
1564
1565 :Parameters:
1566
1567 ClassName : string
1568 Name of the class to be deleted.
1569
1570 namespace : string
1571 Optional: Name of the namespace of the class, as a string.
1572 The value `None` causes the default namespace of the connection to
1573 be used.
1574
1575 Default: `None`
1576
1577 :Exceptions:
1578
1579 See the list of exceptions described in `WBEMConnection`.
1580 """
1581
1582 params = self._map_classname_param(params)
1583
1584 if namespace is None:
1585 namespace = self.default_namespace
1586
1587 self.imethodcall(
1588 'DeleteClass',
1589 namespace,
1590 ClassName=CIMClassName(ClassName),
1591 **params)
1592
1593 - def ModifyClass(self, ModifiedClass, namespace=None, **params):
1594
1595 """
1596 Modify a class.
1597
1598 This method performs the ModifyClass CIM-XML operation.
1599 If the operation succeeds, this method returns.
1600 Otherwise, this method raises an exception.
1601
1602 TODO This method is UNSUPPORTED right now. Test and verify description.
1603
1604 :Parameters:
1605
1606 ModifiedClass : `CIMClass`
1607 A representation of the modified class. This object needs to
1608 contain any modified properties, methods and qualifiers and the
1609 class path of the class to be modified.
1610 Typically, this object has been retrieved by other operations, such
1611 as GetClass.
1612
1613 :Exceptions:
1614
1615 See the list of exceptions described in `WBEMConnection`.
1616 """
1617
1618 if namespace is None:
1619 namespace = self.default_namespace
1620
1621 self.imethodcall(
1622 'ModifyClass',
1623 namespace,
1624 ModifiedClass=ModifiedClass,
1625 **params)
1626
1627 - def CreateClass(self, NewClass, namespace=None, **params):
1628
1629 """
1630 Create a class.
1631
1632 This method performs the ModifyClass CIM-XML operation.
1633 If the operation succeeds, this method returns.
1634 Otherwise, this method raises an exception.
1635
1636 TODO This method is UNSUPPORTED right now. Test and verify description.
1637
1638 :Parameters:
1639
1640 NewClass : `CIMClass`
1641 A representation of the class to be created. This object needs to
1642 contain any properties, methods, qualifiers, superclass name, and
1643 the class name of the class to be created.
1644 The class path in this object (`path` instance variable) will be
1645 ignored.
1646
1647 namespace : string
1648 Optional: Name of the namespace in which the class is to be
1649 created. The value `None` causes the default namespace of the
1650 connection to be used.
1651
1652 Default: `None`
1653
1654 :Exceptions:
1655
1656 See the list of exceptions described in `WBEMConnection`.
1657 """
1658
1659 if namespace is None:
1660 namespace = self.default_namespace
1661
1662 self.imethodcall(
1663 'CreateClass',
1664 namespace,
1665 NewClass=NewClass,
1666 **params)
1667
1668
1669
1670
1671
1673 """Add an object name (either a class name or an instance
1674 name) to a dictionary of parameter names."""
1675
1676 if isinstance(object, (CIMClassName, CIMInstanceName)):
1677 params['ObjectName'] = object.copy()
1678 params['ObjectName'].namespace = None
1679 elif isinstance(object, StringTypes):
1680 params['ObjectName'] = CIMClassName(object)
1681 else:
1682 raise ValueError('Expecting a classname, CIMClassName or '
1683 'CIMInstanceName object')
1684
1685 return params
1686
1688 """Convert various convenience parameters and types into their
1689 correct form for passing to the imethodcall() function."""
1690
1691
1692
1693
1694 if params.has_key('ResultClass') and \
1695 isinstance(params['ResultClass'], StringTypes):
1696 params['ResultClass'] = CIMClassName(params['ResultClass'])
1697
1698 if params.has_key('AssocClass') and \
1699 isinstance(params['AssocClass'], StringTypes):
1700 params['AssocClass'] = CIMClassName(params['AssocClass'])
1701
1702 return params
1703
1705
1706 """
1707 Retrieve the instances (or classes) associated to a source instance
1708 (or source class).
1709
1710 This method performs the Associators CIM-XML operation.
1711 If the operation succeeds, this method returns.
1712 Otherwise, this method raises an exception.
1713
1714 :Parameters:
1715
1716 ObjectName
1717 For instance level usage: The instance path of the source instance,
1718 as a `CIMInstanceName` object. If that object does not
1719 specify a namespace, the default namespace of the connection is
1720 used.
1721
1722 For class level usage: The class path of the source class, as a
1723 string or as a `CIMClassName` object.
1724 If specified as a string, the string is interpreted as a class name
1725 in the default namespace of the connection.
1726 If specified as a `CIMClassName` object that does not
1727 specify a namespace, the default namespace of the connection is
1728 used.
1729
1730 AssocClass : string or `CIMClassName`
1731 Optional: Class name of an association class, to filter the result
1732 to include only traversals of that association class (or
1733 subclasses).
1734
1735 Default: `None` (no filtering).
1736
1737 ResultClass : string or `CIMClassName`
1738 Optional: Class name of an associated class, to filter the result
1739 to include only traversals to that associated class (or
1740 subclasses).
1741
1742 Default: `None` (no filtering).
1743
1744 Role : string
1745 Optional: Role name (= property name) of the source end, to filter
1746 the result to include only traversals from that source role.
1747
1748 Default: `None` (no filtering).
1749
1750 ResultRole
1751 Optional: Role name (= property name) of the far end, to filter
1752 the result to include only traversals to that far role.
1753
1754 Default: `None` (no filtering).
1755
1756 IncludeQualifiers : `bool`
1757 Optional: Indicates that qualifiers are to be included in the
1758 returned instances (or classes).
1759
1760 Default: `False`.
1761
1762 This parameter has been deprecated in CIM-XML. Clients cannot rely
1763 on it being implemented by WBEM servers.
1764
1765 IncludeClassOrigin : `bool`
1766 Optional: Indicates that class origin information is to be included
1767 on each property or method in the returned instances (or classes).
1768
1769 Default: `False`.
1770
1771 PropertyList : iterable of string
1772 Optional: An iterable specifying the names of the properties to be
1773 included in the returned instances (or classes). An empty iterable
1774 indicates to include no properties. A value of `None` for this
1775 parameter indicates to include all properties.
1776
1777 Default: `None`.
1778
1779 :Returns:
1780
1781 For instance level usage, a list of `CIMInstance` objects
1782 that are representations of the associated instances.
1783
1784 For class level usage, a list of `CIMClass` objects
1785 that are representations the associated classes.
1786
1787 :Exceptions:
1788
1789 See the list of exceptions described in `WBEMConnection`.
1790 """
1791
1792 params = self._map_association_params(params)
1793 params = self._add_objectname_param(params, ObjectName)
1794
1795 namespace = self.default_namespace
1796
1797 if isinstance(ObjectName, CIMInstanceName) and \
1798 ObjectName.namespace is not None:
1799 namespace = ObjectName.namespace
1800
1801 result = self.imethodcall(
1802 'Associators',
1803 namespace,
1804 **params)
1805
1806 if result is None:
1807 return []
1808
1809 return map(lambda x: x[2], result[2])
1810
1812
1813 """
1814 Retrieve the instance paths of the instances (or class paths of the
1815 classes) associated to a source instance (or source class).
1816
1817 This method performs the AssociatorNames CIM-XML operation.
1818 If the operation succeeds, this method returns.
1819 Otherwise, this method raises an exception.
1820
1821 :Parameters:
1822
1823 ObjectName
1824 For instance level usage: The instance path of the source instance,
1825 as a `CIMInstanceName` object. If that object does not
1826 specify a namespace, the default namespace of the connection is
1827 used.
1828
1829 For class level usage: The class path of the source class, as a
1830 string or as a `CIMClassName` object.
1831 If specified as a string, the string is interpreted as a class name
1832 in the default namespace of the connection.
1833 If specified as a `CIMClassName` object that does not
1834 specify a namespace, the default namespace of the connection is
1835 used.
1836
1837 AssocClass : string or `CIMClassName`
1838 Optional: Class name of an association class, to filter the result
1839 to include only traversals of that association class (or
1840 subclasses).
1841
1842 Default: `None` (no filtering).
1843
1844 ResultClass : string or `CIMClassName`
1845 Optional: Class name of an associated class, to filter the result
1846 to include only traversals to that associated class (or
1847 subclasses).
1848
1849 Default: `None` (no filtering).
1850
1851 Role : string
1852 Optional: Role name (= property name) of the source end, to filter
1853 the result to include only traversals from that source role.
1854
1855 Default: `None` (no filtering).
1856
1857 ResultRole
1858 Optional: Role name (= property name) of the far end, to filter
1859 the result to include only traversals to that far role.
1860
1861 Default: `None` (no filtering).
1862
1863 :Returns:
1864
1865 For instance level usage, a list of `CIMInstanceName`
1866 objects that are the instance paths of the associated instances.
1867
1868 For class level usage, a list of `CIMClassName` objects
1869 that are the class paths of the associated classes.
1870
1871 :Exceptions:
1872
1873 See the list of exceptions described in `WBEMConnection`.
1874 """
1875
1876 params = self._map_association_params(params)
1877 params = self._add_objectname_param(params, ObjectName)
1878
1879 namespace = self.default_namespace
1880
1881 if isinstance(ObjectName, CIMInstanceName) and \
1882 ObjectName.namespace is not None:
1883 namespace = ObjectName.namespace
1884
1885 result = self.imethodcall(
1886 'AssociatorNames',
1887 namespace,
1888 **params)
1889
1890 if result is None:
1891 return []
1892
1893 return map(lambda x: x[2], result[2])
1894
1896
1897 """
1898 Retrieve the association instances (or association classes) that
1899 reference a source instance (or source class).
1900
1901 This method performs the References CIM-XML operation.
1902 If the operation succeeds, this method returns.
1903 Otherwise, this method raises an exception.
1904
1905 :Parameters:
1906
1907 ObjectName
1908 For instance level usage: The instance path of the source instance,
1909 as a `CIMInstanceName` object. If that object does not
1910 specify a namespace, the default namespace of the connection is
1911 used.
1912
1913 For class level usage: The class path of the source class, as a
1914 string or as a `CIMClassName` object.
1915 If specified as a string, the string is interpreted as a class name
1916 in the default namespace of the connection.
1917 If specified as a `CIMClassName` object that does not
1918 specify a namespace, the default namespace of the connection is
1919 used.
1920
1921 ResultClass : string or `CIMClassName`
1922 Optional: Class name of an association class, to filter the result
1923 to include only traversals of that association class (or
1924 subclasses).
1925
1926 Default: `None` (no filtering).
1927
1928 Role : string
1929 Optional: Role name (= property name) of the source end, to filter
1930 the result to include only traversals from that source role.
1931
1932 Default: `None` (no filtering).
1933
1934 IncludeQualifiers : `bool`
1935 Optional: Indicates that qualifiers are to be included in the
1936 returned instances (or classes).
1937
1938 Default: `False`.
1939
1940 This parameter has been deprecated in CIM-XML. Clients cannot rely
1941 on it being implemented by WBEM servers.
1942
1943 IncludeClassOrigin : `bool`
1944 Optional: Indicates that class origin information is to be included
1945 on each property or method in the returned instances (or classes).
1946
1947 Default: `False`.
1948
1949 PropertyList : iterable of string
1950 Optional: An iterable specifying the names of the properties to be
1951 included in the returned instances (or classes). An empty iterable
1952 indicates to include no properties. A value of `None` for this
1953 parameter indicates to include all properties.
1954
1955 Default: `None`.
1956
1957 :Returns:
1958
1959 For instance level usage, a list of `CIMInstance` objects
1960 that are representations of the referencing association instances.
1961
1962 For class level usage, a list of `CIMClass` objects
1963 that are representations the referencing association classes.
1964
1965 :Exceptions:
1966
1967 See the list of exceptions described in `WBEMConnection`.
1968 """
1969
1970 params = self._map_association_params(params)
1971 params = self._add_objectname_param(params, ObjectName)
1972
1973 namespace = self.default_namespace
1974
1975 if isinstance(ObjectName, CIMInstanceName) and \
1976 ObjectName.namespace is not None:
1977 namespace = ObjectName.namespace
1978
1979 result = self.imethodcall(
1980 'References',
1981 namespace,
1982 **params)
1983
1984 if result is None:
1985 return []
1986
1987 return map(lambda x: x[2], result[2])
1988
1990
1991 """
1992 Retrieve the instance paths of the association instances (or class
1993 paths of the association classes) that reference a source instance
1994 (or source class).
1995
1996 This method performs the ReferenceNames CIM-XML operation.
1997 If the operation succeeds, this method returns.
1998 Otherwise, this method raises an exception.
1999
2000 :Parameters:
2001
2002 ObjectName
2003 For instance level usage: The instance path of the source instance,
2004 as a `CIMInstanceName` object. If that object does not
2005 specify a namespace, the default namespace of the connection is
2006 used.
2007
2008 For class level usage: The class path of the source class, as a
2009 string or as a `CIMClassName` object.
2010 If specified as a string, the string is interpreted as a class name
2011 in the default namespace of the connection.
2012 If specified as a `CIMClassName` object that does not
2013 specify a namespace, the default namespace of the connection is
2014 used.
2015
2016 ResultClass : string or `CIMClassName`
2017 Optional: Class name of an association class, to filter the result
2018 to include only traversals of that association class (or
2019 subclasses).
2020
2021 Default: `None` (no filtering).
2022
2023 Role : string
2024 Optional: Role name (= property name) of the source end, to filter
2025 the result to include only traversals from that source role.
2026
2027 Default: `None` (no filtering).
2028
2029 :Returns:
2030
2031 For instance level usage, a list of `CIMInstanceName`
2032 objects that are the instance paths of the referencing association
2033 instances.
2034
2035 For class level usage, a list of `CIMClassName` objects
2036 that are the class paths of the referencing association classes.
2037
2038 :Exceptions:
2039
2040 See the list of exceptions described in `WBEMConnection`.
2041 """
2042
2043 params = self._map_association_params(params)
2044 params = self._add_objectname_param(params, ObjectName)
2045
2046 namespace = self.default_namespace
2047
2048 if isinstance(ObjectName, CIMInstanceName) and \
2049 ObjectName.namespace is not None:
2050 namespace = ObjectName.namespace
2051
2052 result = self.imethodcall(
2053 'ReferenceNames',
2054 namespace,
2055 **params)
2056
2057 if result is None:
2058 return []
2059
2060 return map(lambda x: x[2], result[2])
2061
2062
2063
2064
2065
2066 - def InvokeMethod(self, MethodName, ObjectName, Params=None, **params):
2067
2068 """
2069 Invoke a method on a target instance or on a target class.
2070
2071 The methods that can be invoked are static and non-static methods
2072 defined in a class (also known as *extrinsic* methods).
2073 Static methods can be invoked on instances and on classes.
2074 Non-static methods can be invoked only on instances.
2075
2076 This method performs the InvokeMethod CIM-XML operation.
2077 If the operation succeeds, this method returns.
2078 Otherwise, this method raises an exception.
2079
2080 Input parameters for the CIM method can be specified in a
2081 order-preserving way using the ``Params`` parameter, and in a
2082 order-agnostic way using the ``**params`` keyword parameters.
2083
2084 :Parameters:
2085
2086 MethodName : string
2087 Name of the method to be invoked (without parenthesis or any
2088 parameter signature).
2089
2090 ObjectName
2091 For instance level usage: The instance path of the target instance,
2092 as a `CIMInstanceName` object. If that object does not
2093 specify a namespace, the default namespace of the connection is
2094 used.
2095
2096 For class level usage: The class path of the target class, as a
2097 string or as a `CIMClassName` object.
2098 If specified as a string, the string is interpreted as a class name
2099 in the default namespace of the connection.
2100 If specified as a `CIMClassName` object that does not
2101 specify a namespace, the default namespace of the connection is
2102 used.
2103
2104 Params
2105 A list of input parameters for the CIM method.
2106
2107 Each list item represents a single input parameter for the CIM
2108 method and must be a ``tuple(name,value)``, where ``name`` is the
2109 parameter name in any lexical case, and ``value`` is the parameter
2110 value as a CIM typed value as described in `cim_types`.
2111
2112 **params
2113 Keyword parameters for the input parameters for the CIM method.
2114
2115 Each keyword parameter represents a single input parameter for the
2116 CIM method, where the key is the parameter name in any lexical
2117 case, and the value is the parameter value as a CIM typed value as
2118 described in `cim_types`.
2119
2120 The overall list of input parameters represented in the CIM-XML
2121 request message that is sent to the WBEM server is formed from
2122 the list of parameters specified in ``Params`` preserving its
2123 order, followed by the set of parameters specified in ``**params``
2124 in any order. There is no checking for duplicate parameter names
2125 in the PyWBEM client.
2126
2127
2128 :Returns:
2129
2130 A tuple of ``(returnvalue, outparams)``, where:
2131
2132 - ``returnvalue`` : Return value of the CIM method, as a CIM typed
2133 value as described in `cim_types`.
2134 - ``outparams`` : Output parameters of the CIM method, as a
2135 `NocaseDict` dictionary containing all CIM method output
2136 parameters, where the dictionary items have:
2137
2138 * a key that is the CIM parameter name, as a string.
2139 * a value that is the CIM parameter value, as a CIM typed value
2140 as described in `cim_types`.
2141
2142 :Exceptions:
2143
2144 See the list of exceptions described in `WBEMConnection`.
2145 """
2146
2147
2148
2149 obj = ObjectName
2150
2151 if isinstance(obj, StringTypes):
2152 obj = CIMClassName(obj, namespace=self.default_namespace)
2153
2154 if isinstance(obj, CIMInstanceName) and obj.namespace is None:
2155 obj = ObjectName.copy()
2156 obj.namespace = self.default_namespace
2157
2158
2159
2160 result = self.methodcall(MethodName, obj, Params, **params)
2161
2162
2163
2164 returnvalue = None
2165
2166 if len(result) > 0 and result[0][0] == 'RETURNVALUE':
2167
2168 returnvalue = cim_obj.tocimobj(result[0][1]['PARAMTYPE'],
2169 result[0][2])
2170 result = result[1:]
2171
2172
2173
2174 output_params = NocaseDict()
2175
2176 for p in result:
2177 if p[1] == 'reference':
2178 output_params[p[0]] = p[2]
2179 else:
2180 output_params[p[0]] = cim_obj.tocimobj(p[1], p[2])
2181
2182 return returnvalue, output_params
2183
2184
2185
2186
2187
2189
2190 """
2191 Enumerate qualifier types.
2192
2193 Returns a list of `CIMQualifier` objects.
2194
2195 TODO Complete this description.
2196 """
2197
2198 if namespace is None:
2199 namespace = self.default_namespace
2200
2201 result = self.imethodcall(
2202 'EnumerateQualifiers',
2203 namespace,
2204 **params)
2205
2206 qualifiers = []
2207
2208 if result is not None:
2209 names = result[2]
2210 else:
2211 names = []
2212
2213 return names
2214
2215 - def GetQualifier(self, QualifierName, namespace=None, **params):
2216
2217 """
2218 Retrieve a qualifier type.
2219
2220 Returns a `CIMQualifier` object.
2221
2222 TODO Complete this description.
2223 """
2224
2225 if namespace is None:
2226 namespace = self.default_namespace
2227
2228 result = self.imethodcall(
2229 'GetQualifier',
2230 namespace,
2231 QualifierName=QualifierName,
2232 **params)
2233
2234 if result is not None:
2235 names = result[2][0]
2236
2237 return names
2238
2239 - def SetQualifier(self, QualifierDeclaration, namespace=None, **params):
2240
2241 """
2242 Create or modify a qualifier type.
2243
2244 TODO Complete this description.
2245 """
2246
2247 if namespace is None:
2248 namespace = self.default_namespace
2249
2250 result = self.imethodcall(
2251 'SetQualifier',
2252 namespace,
2253 QualifierDeclaration=QualifierDeclaration,
2254 **params)
2255
2257
2258 """
2259 Delete a qualifier type.
2260
2261 TODO Complete this description.
2262 """
2263
2264 if namespace is None:
2265 namespace = self.default_namespace
2266
2267 result = self.imethodcall(
2268 'DeleteQualifier',
2269 namespace,
2270 QualifierName=QualifierName,
2271 **params)
2272
2274 """Determine if one class is a subclass of another
2275
2276 Keyword Arguments:
2277 ch -- A CIMOMHandle. Either a pycimmb.CIMOMHandle or a
2278 pywbem.WBEMConnection.
2279 ns -- Namespace.
2280 super -- A string containing the super class name.
2281 sub -- The subclass. This can either be a string or a pywbem.CIMClass.
2282
2283 """
2284
2285 lsuper = super.lower()
2286 if isinstance(sub, CIMClass):
2287 subname = sub.classname
2288 subclass = sub
2289 else:
2290 subname = sub
2291 subclass = None
2292 if subname.lower() == lsuper:
2293 return True
2294 if subclass is None:
2295 subclass = ch.GetClass(subname,
2296 ns,
2297 LocalOnly=True,
2298 IncludeQualifiers=False,
2299 PropertyList=[],
2300 IncludeClassOrigin=False)
2301 while subclass.superclass is not None:
2302 if subclass.superclass.lower() == lsuper:
2303 return True
2304 subclass = ch.GetClass(subclass.superclass,
2305 ns,
2306 LocalOnly=True,
2307 IncludeQualifiers=False,
2308 PropertyList=[],
2309 IncludeClassOrigin=False)
2310 return False
2311
2313
2314 return WBEMConnection('/var/run/tog-pegasus/cimxml.socket', creds, **kwargs)
2315
2317
2318 return WBEMConnection('/tmp/sfcbHttpSocket', creds, **kwargs)
2319
2321
2322 return WBEMConnection('/tmp/OW@LCL@APIIPC_72859_Xq47Bf_P9r761-5_J-7_Q',
2323 creds, **kwargs)
2324