[Libvirt-cim] cimtest - add SSL support to indication_tester.py

Sharad Mishra snmishra at linux.vnet.ibm.com
Mon Mar 19 21:39:35 UTC 2012


Dave,

	I assume that this patch is not going to be applied to the existing
indication_tester.py in cimtest. In that case, we can add this modified
indication_tester.py as a new file at the same location as current
indication_tester.py. We do need to give this script a new name. This
script is currently not used/invoked by any existing cimtests. Do you
want to write tests to use this script?

Regards
Sharad Mishra

On Mon, 2012-03-19 at 13:21 -0400, Dave Heller wrote:
> In the XenKvmLib directory in cimtest, there is a "indication_tester.py"
> module that is both a command-line program and a component of cimtest.  Here
> is a proposed patch that adds new functionality to the cmdline interface
> while preserving compatibility with cimtest.
> 
> The most significant new feature is support for SSL indications.  There is
> also a new --trigger mode to generate a test indication using the SFCB
> Test_Indication provider.  This allows the script to act as a completely
> stand-alone test tool (for SFCB) without the user having to rely on the
> "xmltest" files and wbemcat.
> 
> Below is a complete list of the new features.  I am looking for feedback and
> potentially, the correct process to check into "cimtest".
> 
> Best regards,
> Dave Heller
> 
> New features:
> 
> - Supports https indications. Adds new options --certFile and --keyFile to
> specify server certificate and private key for the SSL enabled indication
> listener.
> - Supports verification of indication sender (i.e. CIMOM) SSL certificate.
> New option --trustStore is used to specify the CA certificate file;
> alternately the --noverify option may be used to disable peer certificate
> checking. 
> - Adds new option --dest to specify handler destination. This same URL is
> used to register the subscription (at the CIMOM) and start the indication
> listener (locally). Via --dest one can specify scheme (http or https), IP or
> hostname, listener port, and optionally userid:password, all in a single
> parameter. 
> - New option --interop can be used to override the default interop namespace
> (i.e root/interop vs. root/PG_InterOp) allowing easy support for both
> openpegasus and sfcb.
> - Modifies the default value of existing --ns option (indication namespace);
> if not specified the indication namespace will default to the same value as
> the interop namespace.
> - New option --verbose can be used to display debugging info, such as
> details (subject, issuer) of the indication sender cert (when peer
> verification enabled).
> - Improved error handling (i.e. catch exceptions) for the following
> operations: starting listener locally, receiving incoming indications, POST
> operations (i.e. subscribe, unsubscribe) to CIMOM.
> - New option --trigger can be used to send a request to CIMOM to trigger an
> indication via the SFCB Test_Indication provider.
> 
> Limitations:
> 
> - Not tested on IPv6.
> - The --trigger option currently only supports the sfcb Test_Indication
> provider.  (It could be made more general by allowing the XML send to
> support an arbitrary namespace, classname and method call.  Open to
> suggestions here.)
> 
> 
> --- indication_tester.orig.py	2012-03-05 23:12:08.000000000 -0500
> +++ indication_tester.py	2012-03-19 13:12:55.000000000 -0400
> @@ -1,18 +1,25 @@
>  #!/usr/bin/python
> -# Copyright IBM Corp. 2007
> +# Copyright IBM Corp. 2007-2012
>  #
>  # indication_tester.py - Tool for testing indication subscription and
>  #                        delivery against a CIMOM
>  # Author: Dan Smith <danms at us.ibm.com>
> +# SSL support added by Dave Heller <hellerda at us.ibm.com>
> 
>  import sys
>  from optparse import OptionParser
> -import BaseHTTPServer
> +from urlparse import urlparse, urlunparse
> +from xml.dom.minidom import parse, parseString
>  import httplib
>  import base64
> -from xml.dom.minidom import parse, parseString
> +import errno, os, re
> +import socket
> +from SocketServer import BaseServer
> +from SimpleHTTPServer import SimpleHTTPRequestHandler
> +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
> +from OpenSSL import SSL
> 
> -def filter_xml(name, type, ns, sysname):
> +def filter_xml(name, type, ns, sysname, interopNS):
>      return """
>      <?xml version="1.0" encoding="utf-8"?>
>      <CIM CIMVERSION="2.0" DTDVERSION="2.0">
> @@ -20,8 +27,8 @@
>        <SIMPLEREQ>
>          <IMETHODCALL NAME="CreateInstance">
>            <LOCALNAMESPACEPATH>
> -            <NAMESPACE NAME="root"/>
> -            <NAMESPACE NAME="PG_InterOp"/>
> +            <NAMESPACE NAME="%s"/>
> +            <NAMESPACE NAME="%s"/>
>            </LOCALNAMESPACEPATH>
>            <IPARAMVALUE NAME="NewInstance">
>                <INSTANCE CLASSNAME="CIM_IndicationFilter">
> @@ -53,9 +60,9 @@
>          </SIMPLEREQ>
>        </MESSAGE>
>      </CIM>
> -    """ % (sysname, name, type, ns)
> +    """ % (interopNS[0], interopNS[1], sysname, name, type, ns)
> 
> -def handler_xml(name, port, sysname):
> +def handler_xml(name, destUrl, sysname, interopNS):
>      return """
>      <?xml version="1.0" encoding="utf-8"?>
>      <CIM CIMVERSION="2.0" DTDVERSION="2.0">
> @@ -63,8 +70,8 @@
>          <SIMPLEREQ>
>          <IMETHODCALL NAME="CreateInstance">
>              <LOCALNAMESPACEPATH>
> -              <NAMESPACE NAME="root"/>
> -              <NAMESPACE NAME="PG_InterOp"/>
> +              <NAMESPACE NAME="%s"/>
> +              <NAMESPACE NAME="%s"/>
>              </LOCALNAMESPACEPATH>
>              <IPARAMVALUE NAME="NewInstance">
>                <INSTANCE CLASSNAME="CIM_IndicationHandlerCIMXML">
> @@ -81,7 +88,7 @@
>                    <VALUE>%sHandler</VALUE>
>                  </PROPERTY>
>                  <PROPERTY NAME="Destination" TYPE="string">
> -                  <VALUE>http://localhost:%i</VALUE>
> +                  <VALUE>%s</VALUE>
>                  </PROPERTY>
>                </INSTANCE>
>              </IPARAMVALUE>
> @@ -89,9 +96,9 @@
>          </SIMPLEREQ>
>        </MESSAGE>
>        </CIM>
> -      """ % (sysname, name, port)
> +      """ % (interopNS[0], interopNS[1], sysname, name, destUrl)
> 
> -def subscription_xml(name, sysname):
> +def subscription_xml(name, sysname, interopNS):
>      return """
>      <?xml version="1.0" encoding="utf-8"?>
>      <CIM CIMVERSION="2.0" DTDVERSION="2.0">
> @@ -99,8 +106,8 @@
>          <SIMPLEREQ>
>            <IMETHODCALL NAME="CreateInstance">
>              <LOCALNAMESPACEPATH>
> -              <NAMESPACE NAME="root"/>
> -              <NAMESPACE NAME="PG_InterOp"/>
> +              <NAMESPACE NAME="%s"/>
> +              <NAMESPACE NAME="%s"/>
>              </LOCALNAMESPACEPATH>
>              <IPARAMVALUE NAME="NewInstance">
>                <INSTANCE CLASSNAME="CIM_IndicationSubscription">
> @@ -167,9 +174,9 @@
>          </SIMPLEREQ>
>        </MESSAGE>
>        </CIM>
> -      """ % (sysname, name, sysname, name)
> +      """ % (interopNS[0], interopNS[1], sysname, name, sysname, name)
> 
> -def delete_inst_xml(name, type, sysname, inst_name):
> +def delete_inst_xml(name, type, sysname, inst_name, interopNS):
>      return """
>      <?xml version="1.0" encoding="utf-8"?>
>      <CIM CIMVERSION="2.0" DTDVERSION="2.0">
> @@ -177,8 +184,8 @@
>          <SIMPLEREQ>
>            <IMETHODCALL NAME="DeleteInstance">
>              <LOCALNAMESPACEPATH>
> -              <NAMESPACE NAME="root"/>
> -              <NAMESPACE NAME="PG_InterOp"/>
> +              <NAMESPACE NAME="%s"/>
> +              <NAMESPACE NAME="%s"/>
>              </LOCALNAMESPACEPATH>
>              <IPARAMVALUE NAME="InstanceName">
>                <INSTANCENAME CLASSNAME="CIM_Indication%s">
> @@ -200,9 +207,9 @@
>          </SIMPLEREQ>
>        </MESSAGE>
>      </CIM>;
> -    """ % (type, sysname, type, inst_name);
> +    """ % (interopNS[0], interopNS[1], type, sysname, type, inst_name);
> 
> -def delete_sub_xml(name, sysname):
> +def delete_sub_xml(name, sysname, interopNS):
>      return """
>      <?xml version="1.0" encoding="utf-8"?>
>      <CIM CIMVERSION="2.0" DTDVERSION="2.0">
> @@ -210,8 +217,8 @@
>          <SIMPLEREQ>
>            <IMETHODCALL NAME="DeleteInstance">
>              <LOCALNAMESPACEPATH>
> -              <NAMESPACE NAME="root"/>
> -              <NAMESPACE NAME="PG_InterOp"/>
> +              <NAMESPACE NAME="%s"/>
> +              <NAMESPACE NAME="%s"/>
>              </LOCALNAMESPACEPATH>
>              <IPARAMVALUE NAME="InstanceName">
>                <INSTANCENAME CLASSNAME="CIM_IndicationSubscription">
> @@ -273,7 +280,45 @@
>          </SIMPLEREQ>
>        </MESSAGE>
>      </CIM>;
> -    """ % (sysname, name, sysname, name)
> +    """ % (interopNS[0], interopNS[1], sysname, name, sysname, name)
> +
> +def trigger_xml(type, interopNS):
> +    return """
> +    <?xml version="1.0" encoding="utf-8"?>
> +    <CIM CIMVERSION="2.0" DTDVERSION="2.0">
> +      <MESSAGE ID="4711" PROTOCOLVERSION="1.0">
> +        <SIMPLEREQ>
> +          <METHODCALL NAME="SendTestIndication">
> +            <LOCALCLASSPATH>
> +              <LOCALNAMESPACEPATH>
> +                <NAMESPACE NAME="%s"/>
> +                <NAMESPACE NAME="%s"/>
> +              </LOCALNAMESPACEPATH>
> +              <CLASSNAME NAME="%s"/>
> +            </LOCALCLASSPATH>
> +          </METHODCALL>
> +        </SIMPLEREQ>
> +      </MESSAGE>
> +    </CIM>
> +    """ % (interopNS[0], interopNS[1], type)
> +    # FIXME: this should really use indication NS, not interop NS.
> +
> +def update_url_port(parsedUrl, port):
> +    # Must manually reconstruct netloc to update the port value.
> +    if isinstance(parsedUrl.username, basestring):
> +      if isinstance(parsedUrl.password, basestring):
> +        netloc = "%s:%s@%s:%s" % (parsedUrl.username, parsedUrl.password,
> +                                  parsedUrl.hostname, port)
> +      else:
> +        netloc = "%s@%s:%s" % (parsedUrl.username,
> +                               parsedUrl.hostname, port)
> +    else:
> +      netloc = "%s:%s" % (parsedUrl.hostname, port)
> +
> +    # Reassemble url with the updated netloc. return a string.
> +    return urlunparse((parsedUrl.scheme, netloc,
> +                       parsedUrl.path, parsedUrl.params,
> +                       parsedUrl.query, parsedUrl.fragment))
> 
>  class CIMIndication:
>      def __init__(self, xmldata):
> @@ -286,50 +331,135 @@
>      def __str__(self):
>          return self.name
> 
> -class CIMSocketHandler(BaseHTTPServer.BaseHTTPRequestHandler):
> +def socket_handler_wrapper(*parms):
> +    try:
> +        CIMSocketHandler(*parms)
> +    except Exception as e:
> +        print "SSL error: %s" % str(e)
> +
> +class CIMSocketHandler(SimpleHTTPRequestHandler):
> +    def setup(self):
> +        self.connection = self.request
> +        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
> +        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
> +
>      def do_POST(self):
>          length = self.headers.getheader('content-length')
>          data = self.rfile.read(int(length))
> 
>          indication = CIMIndication(data)
> -        print "Got indication: %s" % indication
> +        print "Got indication: %s from %s" % (indication,
> self.client_address)
>          if self.server.print_ind:
> -            print "%s\n\n" % data
> +            print "%s\n" % data
>          self.server.indications.append(indication)
> +        # Silence the unwanted log output from send_response()
> +        realStderr = sys.stderr
> +        sys.stderr = open(os.devnull,'a')
> +        self.send_response(200)
> +        sys.stderr = realStderr
> +
> +class SecureHTTPServer(HTTPServer):
> +    def __init__(self, server_address, HandlerClass):
> +        BaseServer.__init__(self, server_address, HandlerClass)
> +
> +        def verify_cb(conn, cert, errnum, depth, ok):
> +          if options.verbose:
> +            print('Verify peer certificate chain: level %d:' % depth)
> +            print('subject=%s' % cert.get_subject())
> +            print('issuer =%s' % cert.get_issuer())
> +          return ok
> +
> +        ctx = SSL.Context(SSL.SSLv23_METHOD)
> +        #ctx.use_certificate_file(options.certFile)
> +        ctx.use_certificate_chain_file(options.certFile)
> +        ctx.use_privatekey_file(options.keyFile)
> +
> +        if options.noverify:
> +            ctx.set_verify(SSL.VERIFY_NONE, verify_cb)
> +        else:
> +            #ctx.set_verify(SSL.VERIFY_PEER, verify_cb)
> +            ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
> +                           verify_cb)
> +            ctx.load_verify_locations(options.trustStore)
> +
> +        self.socket = SSL.Connection(ctx,
> socket.socket(self.address_family,
> +                                                        self.socket_type))
> +        self.server_bind()
> +        self.server_activate()
> 
> +# The param defaults allow new options from main() w/o losing compat w/
> cimtest.
>  class CIMIndicationSubscription:
> -    def __init__(self, name, typ, ns, print_ind, sysname, port=0):
> +    def __init__(self, name, typ, ns, print_ind, sysname, port=0,
> +            interopNS=('root','PG_InterOp'),
> destUrl="http://localhost:8000",
> +            triggermode=False):
>          self.name = name
>          self.type = typ
>          self.ns = ns
>          self.sysname = sysname
> +        self.interopNS = interopNS
> +        self.print_ind = print_ind
> +
> +        # We do not want to open a listener socket in trigger mode.
> +        if triggermode:
> +          self.trigger_xml = trigger_xml(typ, interopNS)
> +          return
> +
> +        parsedUrl = urlparse(destUrl)
> +
> +        # Increment the listener port by the offset value.
> +        if isinstance(parsedUrl.port, int):
> +          listenerPort = parsedUrl.port + port
> +        else:
> +          listenerPort = 8000 + port
> +
> +        destUrl = update_url_port(parsedUrl, listenerPort)
> +
> +        try:
> +            if parsedUrl.scheme == "http":
> +                self.server = HTTPServer((parsedUrl.hostname,
> +                                          listenerPort),
> +                                          CIMSocketHandler)
> +            elif parsedUrl.scheme == "https":
> +                self.server = SecureHTTPServer((parsedUrl.hostname,
> +                                                listenerPort),
> +                                                socket_handler_wrapper)
> +        except IOError as e:
> +            print "Error creating listener socket: %s" % str(e)
> +            exit(e.errno)
> 
> -        self.port = 8000 + port
> -        self.server = BaseHTTPServer.HTTPServer(('', self.port),
> -                                                 CIMSocketHandler)
>          self.server.print_ind = print_ind
>          self.server.indications = []
> 
> -        self.filter_xml = filter_xml(name, typ, ns, sysname)
> -        self.handler_xml = handler_xml(name, self.port, sysname)
> -        self.subscription_xml = subscription_xml(name, sysname)
> +        self.filter_xml = filter_xml(name, typ, ns, sysname, interopNS)
> +        self.handler_xml = handler_xml(name, destUrl, sysname, interopNS)
> +        self.subscription_xml = subscription_xml(name, sysname, interopNS)
> 
>      def __do_cimpost(self, conn, body, method, auth_hdr=None):
>          headers = {"CIMOperation" : "MethodCall",
>                     "CIMMethod"    : method,
> -                   "CIMObject"    : "root/PG_Interop",
> +                  #"CIMObject"    : "root/PG_Interop",
> +                   "CIMObject"    : "%s/%s" % self.interopNS,
>                     "Content-Type" : 'application/xml; charset="utf-8"'}
> 
>          if auth_hdr:
>              headers["Authorization"] = "Basic %s" % auth_hdr
> 
> -        conn.request("POST", "/cimom", body, headers)
> -        resp = conn.getresponse()
> -        if not resp.getheader("content-length"):
> -            raise Exception("Request Failed: %d %s" %
> -                            (resp.status, resp.reason))
> -
> -        resp.read()
> +        try:
> +            conn.request("POST", "/cimom", body, headers)
> +            resp = conn.getresponse()
> +            if not resp.getheader("content-length"):
> +                raise Exception("Request Failed: %d %s" %
> +                                (resp.status, resp.reason))
> +        except IOError as e:
> +            print "Error connecting to CIMOM: %s" % str(e)
> +            exit(e.errno)
> +
> +        if self.print_ind:
> +            print "Reply from CIMOM:"
> +            #print resp.msg
> +            print resp.read()
> +        else:
> +            resp.read()
> 
>      def subscribe(self, url, cred=None):
>          self.conn = httplib.HTTPConnection(url)
> @@ -353,26 +483,39 @@
>          else:
>              auth_hdr = None
> 
> -        xml = delete_sub_xml(self.name, self.sysname)
> +        xml = delete_sub_xml(self.name, self.sysname, self.interopNS)
>          self.__do_cimpost(self.conn, xml,
>                            "DeleteInstance", auth_hdr)
>          xml = delete_inst_xml(self.name, "HandlerCIMXML", self.sysname,
> -                              "%sHandler" % self.name)
> +                              "%sHandler" % self.name, self.interopNS)
>          self.__do_cimpost(self.conn, xml,
>                            "DeleteInstance", auth_hdr)
>          xml = delete_inst_xml(self.name, "Filter", self.sysname,
> -                              "%sFilter" % self.name)
> +                              "%sFilter" % self.name, self.interopNS)
>          self.__do_cimpost(self.conn, xml,
>                            "DeleteInstance", auth_hdr)
> 
> -def dump_xml(name, typ, ns, sysname):
> -    filter_str = filter_xml(name, typ, ns, sysname)
> -    handler_str = handler_xml(name, 8000, sysname)
> -    subscript_str = subscription_xml(name, sysname)
> -    del_filter_str = delete_inst_xml(name, "Filter", sysname, "%sFilter" %
> name)
> +    def trigger(self, url, cred=None):
> +        self.conn = httplib.HTTPConnection(url)
> +        if cred:
> +            (u, p) = cred
> +            auth_hdr = base64.b64encode("%s:%s" % (u, p))
> +        else:
> +            auth_hdr = None
> +
> +        self.__do_cimpost(self.conn, self.trigger_xml,
> +                          "SendTestIndication", auth_hdr)
> +
> +def dump_xml(name, typ, ns, sysname, interopNS, destUrl):
> +    filter_str = filter_xml(name, typ, ns, sysname, interopNS)
> +    handler_str = handler_xml(name, destUrl, sysname, interopNS)
> +    subscript_str = subscription_xml(name, sysname, interopNS)
> +    del_filter_str = delete_inst_xml(name, "Filter", sysname, "%sFilter" %
> name,
> +                                     interopNS)
>      del_handler_str = delete_inst_xml(name, "HandlerCIMXML", sysname,
> -                                      "%sHandler" % name)
> -    del_subscript_str = delete_sub_xml(name, sysname)
> +                                      "%sHandler" % name, interopNS)
> +    del_subscript_str = delete_sub_xml(name, sysname, interopNS)
> +    trigger_str = trigger_xml(typ, interopNS)
> 
>      print "CreateFilter:\n%s\n" % filter_str
>      print "DeleteFilter:\n%s\n" % del_filter_str
> @@ -380,15 +523,20 @@
>      print "DeleteHandler:\n%s\n" % del_handler_str
>      print "CreateSubscription:\n%s\n" % subscript_str
>      print "DeleteSubscription:\n%s\n" % del_subscript_str
> +    print "Indication trigger:\n%s\n" % trigger_str
> 
>  def main():
>      usage = "usage: %prog [options] provider\nex: %prog
> CIM_InstModification"
>      parser = OptionParser(usage)
> 
> +    # FIXME: SecureHTTPServer still relies on this, need a better way.
> +    global options
> +
>      parser.add_option("-u", "--url", dest="url", default="localhost:5988",
>                        help="URL of CIMOM to connect to (host:port)")
> -    parser.add_option("-N", "--ns", dest="ns", default="root/virt",
> -                      help="Namespace (default is root/virt)")
> +    parser.add_option("-N", "--ns", dest="ns",
> +                      help="Namespace in which the register the indication
> \
> +                      (default is the same value as the interop
> namespace)")
>      parser.add_option("-n", "--name", dest="name", default="Test",
>                        help="Name for filter, handler, subscription \
>                        (default: Test)")
> @@ -398,16 +546,41 @@
>      parser.add_option("-p", "--print-ind", dest="print_ind", default=False,
>                        action="store_true",
>                        help="Print received indications to stdout.")
> +    parser.add_option("-v", "--verbose", dest="verbose", default=False,
> +                      action="store_true",
> +                      help="Print addtional debug info.")
>      parser.add_option("-U", "--user", dest="username", default=None,
> -                      help="HTTP Auth username")
> +                      help="HTTP Auth username (CIMOM)")
>      parser.add_option("-P", "--pass", dest="password", default=None,
> -                      help="HTTP Auth password")
> +                      help="HTTP Auth password (CIMOM)")
>      parser.add_option("--port", dest="port", default=0, type=int,
>                        help="Port increment value (server default: 8000)")
> +    parser.add_option("--dest", dest="destUrl", default="localhost:8000",
> +                      help="URL of destination handler \
> +                      (default: http://localhost:8000)")
> +    parser.add_option("--certFile", dest="certFile", default=None,
> +                      help="File containing the local certificate to use")
> +    parser.add_option("--keyFile", dest="keyFile", default=None,
> +                      help="File containing private key for local cert \
> +                      (if none provided, assume key is in the certFile)")
> +    parser.add_option("--trustStore", dest="trustStore", default=None,
> +                      help="File containing trusted certificates for \
> +                      remote endpoint verification")
> +    parser.add_option("--noverify", dest="noverify", default=False,
> +                      action="store_true",
> +                      help="Skip verification of remote endpoint
> certificate \
> +                      for incoming https indications")
> +    parser.add_option("-i", "--interop", dest="interop",
> +                      default="root/interop",
> +                      help="Interop namespace name (default:
> root/interop)")
> +    parser.add_option("-t", "--trigger", dest="trigger", default=False,
> +                      action="store_true",
> +                      help="Trigger mode: send a request to CIMOM to
> trigger \
> +                      an indication via a method call ")
> 
>      (options, args) = parser.parse_args()
> 
> -    if len(args) == 0:
> +    if not options.trigger and len(args)==0:
>          print "Fatal: no indication type provided."
>          sys.exit(1)
> 
> @@ -421,20 +594,75 @@
>      else:
>          sysname = options.url
> 
> +    if "/" in options.interop:
> +        options.interopNS = tuple(options.interop.split("/"))
> +    else:
> +        options.interopNS = ("root", options.interop)
> +
> +    # If no value provided for indication NS, default is same as interopNS.
> +    if not options.ns:
> +        options.ns = "%s/%s" % options.interopNS
> +
> +    if options.verbose:
> +        print "Interop namespace = %s/%s" % options.interopNS
> +        print "Indication namespace = %s" % options.ns
> +
> +    # If url does not begin with http or https, assume http.
> +    parsedUrl = urlparse(options.destUrl)
> +    if not re.search(parsedUrl.scheme, "https"):
> +        destUrl = "http://" + options.destUrl
> +    else:
> +        destUrl = options.destUrl
> +
> +    if parsedUrl.scheme == "https":
> +        if not options.trustStore and not options.noverify:
> +            print "Error: must provide --trustStore or --noverify with
> https."
> +            sys.exit(1)
> +        elif options.trustStore and options.noverify:
> +            print "Error: options --trustStore and --noverify are
> exclusive."
> +            sys.exit(1)
> +        if not options.certFile:
> +            print "Error: no certificate file provided."
> +            sys.exit(1)
> +        elif not options.keyFile:
> +            print "No keyFile provided; assuming private key \
> +            contained in certFile."
> +            options.keyFile = options.certFile
> +
>      if options.dump:
> -        dump_xml(options.name, args[0], options.ns, sysname)
> +        if isinstance(parsedUrl.port, int):
> +          listenerPort = parsedUrl.port + options.port
> +        else:
> +          listenerPort = 8000 + options.port
> +
> +        destUrl = update_url_port(parsedUrl, listenerPort)
> +        dump_xml(options.name, args[0], options.ns, sysname,
> options.interopNS,
> +                 destUrl)
> +        sys.exit(0)
> +
> +    # Trigger mode: currently only supports SFCB Test_Indication provider.
> +    if options.trigger:
> +        classname = "Test_Indication"
> +        sub = CIMIndicationSubscription(options.name, classname,
> options.ns,
> +                                    options.print_ind, sysname,
> options.port,
> +                                    options.interopNS, destUrl, True)
> +        print "Triggering indication for %s" % classname
> +        sub.trigger(options.url, auth)
>          sys.exit(0)
> 
>      sub = CIMIndicationSubscription(options.name, args[0], options.ns,
> -                                    options.print_ind, sysname,
> options.port)
> +                                    options.print_ind, sysname,
> options.port,
> +                                    options.interopNS, destUrl)
> +
> +    print "Creating subscription for %s" % args[0]
>      sub.subscribe(options.url, auth)
>      print "Watching for %s" % args[0]
> 
>      try:
>          sub.server.serve_forever()
> -    except KeyboardInterrupt,e:
> -        sub.unsubscribe(auth)
> +    except KeyboardInterrupt as e:
>          print "Cancelling subscription for %s" % args[0]
> +        sub.unsubscribe(auth)
> 
>  if __name__=="__main__":
>      sys.exit(main())
> 
> _______________________________________________
> Libvirt-cim mailing list
> Libvirt-cim at redhat.com
> https://www.redhat.com/mailman/listinfo/libvirt-cim
> 





More information about the Libvirt-cim mailing list