Forum Discussion

andy_12_5042's avatar
Icon for Nimbostratus rankNimbostratus
Jan 03, 2011

f5 connection string with pycontrol

I have written a class and defined some methods that work great so far. I am wondering however how I can get around having to pass in the connection string for wsdls on every call though??let me try to explain better:



At present if I want to operate on lots of F5's, I have to do something like below and then feed into a for loop where the ip/hostname for the F5 is a varaible that can be iterated over. I have to do this inside each function though and it is ugly. I know this must not be the best way......



b = pc.BIGIP(


hostname = 'ip',


username = 'user',


password = 'pass',


fromurl = True,


wsdls = ['LocalLB.ProfileClientSSL'])


s = b.LocalLB.ProfileClientSSL



However, it would be nicer if I could create a function for the connection to the F5 and call this in main. This way I can interate over a bunch of F5's to do different things and dont have to deal with calling the s. every time I want to do something.



I cant figure out how to acomplish this because if I make the above a function, the variable s = b.LocalLB.ProfileClientSSL is not available to any other functions in the same class as its not global scope. There must be a better way to do this ... If I am working with a DB for example I can create a connect function and do whatever I want without this headache....



I know icontrol is different and I am still learning as I go, so maybe I am missing something here.




thanks for any help.





9 Replies

  • I suppose ,as I am thinking ,I could just make calls to multiple functions within a function to accomplish a given task. For example to create a virtual server and profile. I am probably trying to overcomplicated things and not thinking in a object oriented way......



  • sorry for the flurry here but maybe someone could explain how the actual connection to the F5 works when calling wsdls and performing some action. I know it is ssl and uses authentication but wonder if anyone could give any more details..




  • Andy: to call against multiple systems, you've got a few options. Note that the actual transport is good ol' urllib2, handled by suds - nothing too fancy there. Your design concerns are valid, because it's super inefficient to call against and instantiate a BigIP object for each one of your systems. In a large environment this wouldn't scale well at all. Fortunately though, you've got some options.



    1) Instantiate a single BIGIP object, then call against the suds.set_options() method to change the location - it's something that you can change on the fly, and it'll allow you to use a single pycontrol object to call against multiple systems. This has a distinct disadvantage of blocking for each request/response cycle though. This means that you'd loop over a set of systems, make a call against each one, etc. But you have to wait for one call to finish before you can make the next. This is the simplest option, though...



    2) Use threads. This is much more complicated code wise, but it gives you real concurrency so you can call against multiple systems at the same time, without blocking. For this, suds exposes a super handy method, clone() that will clone an object. Then you simply call set_options(location='https:///iControl/iControlPortal.cgi') against each cloned object that you want. This method has a bunch of advantages and works well, but programming threads is complicated.



    3) Use the multiprocessing module via the exact same techniques that you'd use for threads.



    4) Use something like the AWESOME celery module for a formal job queue with nice Django integration. This is likely to change your design in pretty major ways though.



    At the heart of all of these techniques though is your set_options() call. This method works for ALL suds options and is super handy. print out the options for your object and you'll see all of the stuff that is exposed, e.g. 'print b.LocalLB.Pool.suds.options'.



    This should keep you busy for a while!



  • wow thanks for all the data!! It will take me a bit to check all this stuff out but lets see if I can get something from one of these options.... I will post back here after I have investigated all of this and tried a few things..




  • Hey Matt.....



    Can you give me a hint as how to change the transport method in the BIGIP object ? I don't want to deal with having all the WSDLS locally and use directory and I keep getting a 401 error when I try to change the location with suds.set_options.



    I think I will eventually go to using threads but for now I will go with creating a single instance of BIGIP and then changing options as I go...






  • I did figure out a way that I could use the local directory method for the WSDLS, which is good, but I would still like to know how to do it the other way. I think I will post another thread on this .



  • The location option is tied to the endpoint (bigip) that you call methods against, and you change it after you've parsed the wsdl. So, for example, you'd load up LocalLB.Pool (locally or via fromurl=True). Once that happens, you can change the system that you want to call against, as opposed to the transport method itself. An example of this is in the


    url = 'https://' + host + '/iControl/iControlPortal.cgi'


    c.set_options(location = url)



    Which simply points the cloned object to another BigIP, as opposed to changing the transport method. Can you paste some code that shows what you're trying to do?



  • hey thanks Matt. I actually found a video tutorial that you have here, which was great and explained everything.





    That is where I also got the reference to look at your sample code that comes with pycontrol. I seemed to miss that and did not even think to check in the samples. That also gives me a great start to playing with threads. I have been able to get method 1 (from your suggestions above) to work great. Now, I want to see if I can get the thread design to work as it would be better. However, as you have stated it is complex and to do it correctly, I need to consider lots of different variables, so it may take me some time to do the right way...



    One thing to mention, in your video you mentioned a bug with the clone() method in python 2.6... I actually was playing around with something else and got the depth error. I recall finding some solution to that but since the project went another direction, I did not end up using it... I will see if I can dig that up again and find what it was.



    Unless you have already found something as that was a few months old..





  • Please dig that up if you can! I found that error on 2.6 but it was fixed at some point leading up to 2.7 - the fix that I tried, without success, was to import sys and increase the recursion limit via sys.setrecursionlimit. No luck at all.



    Also, I've got a sample of threading that works fairly well in the SSL TPS reporting tool that I worked on a while back. You can have a look at that code here:




    At some point Suds will support async frameworks like twisted, but that's a whole other ball of wax. It'll be handy when it's there, but for now threads are totally the way to go.