Forum Discussion

Ethan_Erchinger's avatar
Ethan_Erchinger
Icon for Nimbostratus rankNimbostratus
Apr 04, 2006

Using Python and SOAPpy with iControl

Hello,

 

 

I'm definetly a newby when it comes to SOAP, and using SOAPpy. I can call simple functions in the LocalLB/Class wsdl, like get_address_class_list(). But when trying to call something like get_external_class_file_name I get an emtpy array returned. Any help would REALLY be appreciated.

 


import sys
import SOAPpy
User = 'admin'
Pwd =  sys.argv[1]
SOAPpy.Config.debug = 1
Location = 'https://admin:%s@10.10.1.1/iControl/iControlPortal.cgi' %( Pwd )
server = SOAPpy.SOAPProxy(Location, namespace = "urn:iControl:LocalLB/Class")
print server.get_external_class_file_name(
   SOAPpy.NameType('', 'class_names', 0,  {'items': ['myList']})
)

 

 

Output:

 


In build.
In dump. obj= 
In dump_instance. obj=  tag= None
*** Outgoing HTTP headers **********************************************
POST /iControl/iControlPortal.cgi HTTP/1.0
Host: 10.1.4.2
User-agent: SOAPpy 0.12.0 (http://pywebsvcs.sf.net)
Content-type: text/xml; charset="UTF-8"
Content-length: 515
SOAPAction: "get_external_class_file_name"
************************************************************************
*** Outgoing SOAP ******************************************************  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>
************************************************************************
code= 200
msg= OK
headers= Date: Tue, 04 Apr 2006 05:15:39 GMT
Server: Apache
SOAPServer: EasySoap++/0.6
Connection: close
Content-Type: text/xml; charset="UTF-8"
content-type= text/xml; charset="UTF-8"
data=         xmlns:E="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:A="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:s="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:y="http://www.w3.org/2001/XMLSchema"
        xmlns:iControl="urn:iControl"
        E:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">        xmlns:m="urn:iControl:LocalLB/Class">        s:type="A:Array"
        A:arrayType="y:string[0]">
*** Incoming HTTP headers **********************************************
HTTP/1.? 200 OK
Date: Tue, 04 Apr 2006 05:15:39 GMT
Server: Apache
SOAPServer: EasySoap++/0.6
Connection: close
Content-Type: text/xml; charset="UTF-8"
************************************************************************
*** Incoming SOAP ******************************************************        xmlns:E="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:A="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:s="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:y="http://www.w3.org/2001/XMLSchema"
        xmlns:iControl="urn:iControl"
        E:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">        xmlns:m="urn:iControl:LocalLB/Class">        s:type="A:Array"
        A:arrayType="y:string[0]">
************************************************************************: []

 

 

Any ideas?

 

Ethan

3 Replies

  • We don't officially support Python as a dev language but I do know that several users out there are using it. One thing that I've heard is that SOAPpy doesn't support 2-dimensional arrays which we use in a large majority of our methods.

     

     

    As for your issue, since I don't know Python, I'm going solely by the SOAP trace. In your request, the signature for get_external_calss_file_name is the following

     

     

    String[] LocalLB::Class::get_external_class_file_name(
        in String[] class_names
    );

     

     

    Your code:

     

     

    print server.get_external_class_file_name(
       SOAPpy.NameType('', 'class_names', 0,  {'items': ['myList']})
    )

     

     

    resulted in this message

     

     

      xmlns:ns1="urn:iControl:LocalLB/Class" SOAP-ENC:root="1">
          items="">
      

     

     

    The class_names parameter needs to be a single dimentional array of type string with the requested class names passed in the array. Your python code is making the class_names parameter a single type with empty value. It should result in something like this:

     

     

      xmlns:ns1="urn:iControl:LocalLB/Class" SOAP-ENC:root="1">
          SOAP-ENC:arrayType="SOAP-ENC:Array[1]">
        class_name_goes_here
      

     

     

    -Joe

     

     

  • This was just passed along to me from a co-worker. Give this a shot.

    server.get_external_class_file_name(class_names = ['name1','name2'])

    -Joe
  • Mark_Atkinson_5's avatar
    Mark_Atkinson_5
    Historic F5 Account
    You can use the following patch against SOAPBuilder.py to allow SOAPpy to serialize arrays of arrays...

    
    --- SOAPBuilder.py      2005-02-21 12:24:13.000000000 -0800
    +++ /tmp/SOAPBuilder.py 2006-03-31 13:53:49.000000000 -0800
    @@ -496,7 +496,10 @@
                 elemsname = tag
             for i in data:
    -            self.dump(i, elemsname, not same_type, ns_map)
    +            if type(i) == type([]):
    +                self.dump(i,'item')
    +            else:
    +                self.dump(i, elemsname, not same_type, ns_map)
             if typed: self.out.append('\n' % tag)

    Then you can succesfully use SOAPpy 100% of iControl (haven't found a call that didn't work yet):

    
    url = '%%s://%s:%s@%s/iControl/iControlPortal.cgi' % (admin,passwd,bigip)
    ProxyBuilder = lambda x: SOAPProxy(url % 'https', namespace='urn:iControl:' + x)
    sysinfo = ProxyBuilder('System/SystemInfo')
    ver = sysinfo.get_version()
    print "version: %s" % ver
    pool = ProxyBuilder('LocalLB/Pool')
    try:
        pool.create(pool_names = ['test_pool'],
                    lb_methods = ['LB_METHOD_ROUND_ROBIN'],
                    members = [[{'address':'172.16.17.1','port':'80'}]])
    except faultType, (ErrorFrom, ErrorMessage):      faultType is defined by SOAPpy
            if ErrorMessage.find("already exists") > 0:
                print "pool test_pool already exists..."
            else:
                print "unhandled exception:", ErrorMessage
                raise