pyControl v2 – Understanding the TypeFactory

I admit it—I’ve been away from pyControl working on some other hot stove projects.  When pyControl v2 launched in December, I ported some of the lighter scripts I’d written, but I put aside the scripts that required creating objects on the BIG-IP via iControl.  After receiving a request to create a region in GTM via pyControl, I figured it was time to spend some energy learning the new techniques.

Background

The GTM Region is a user-defined collection of records that an administrator can use for topology decisions.  I’ve created one in the GUI for use later in the article:

The Methods

Sometimes the methods are a little tricky to find, but in this case I know I need to create a GTM Region, so the GlobalLB::Region interface seemed like a pretty appropriate place to start.  The methods we’re interested in are in the list below, complete with any additional information we’ll need to write the script.

  • get_list – Gets a list of region definitions
    • parameters – none
  • get_region_item – Gets the list of region items that define the specified regions
    • parameters - regions
  • create – Creates the specified region definitions with the specified region items
    • parameters
      • regions
        • parameters
          • name (ie, myTestRegion)
          • db_type (REGION_DB_TYPE_USER_DEFINED)
      • items
        • parameters
          • content (ie, US/Colorado)
          • type (REGION_TYPE_STATE)
          • negate (False)

Retrieve the Current Regions

It’s always a little easier for me to work backwards, retrieving the data I’m going to set so I can get a feel for the format.  Let’s start with a simple query for the region I created in the GUI.  I removed the default regions returned for clarity

In [1]: import pycontrol.pycontrol as pc

In [2]: b = pc.BIGIP(hostname = '10.10.20.5', username = 'admin', password = 'ad
min', fromurl = True, wsdls = ['GlobalLB.Region'])
In [3]: reg = b.GlobalLB.Region

In [4]: reg.get_list()
Out[4]:
[(GlobalLB.Region.RegionDefinition){
   name = "myRegion_GUI"
   db_type = "REGION_DB_TYPE_USER_DEFINED"
}]

No rocket science here.  I initialized my BIG-IP and then used the get_list method to query the regions.  Now, I want to return the items in the myRegion_GUI region, so I’ll use the get_region_item method for that.  Again, the default region items are not shown here:

In [20]: regions = reg.get_list()

In [21]: regItems = reg.get_region_item(regions = regions)

In [22]: for x in regItems:
   ....:     print x

OUt [22]:

[(GlobalLB.Region.RegionItem){
   content = "US/Illinois"
   type = "REGION_TYPE_STATE"
   negate = False
}, (GlobalLB.Region.RegionItem){
   content = "US/Missouri"
   type = "REGION_TYPE_STATE"
   negate = False
}]

In both sets of returned data, you’ll notice the parameters are all populated with information that will be required for creation.  As provided in the method definitions above, we’ll set the same parameter values when we create a new region.

Creating the Region Items

First thing we need to do is look at the parameters required in building the typefactory

In [35]: reg.create.params
Out[35]:
[(regions, u'GlobalLB.Region.RegionDefinitionSequence'),
(items, u'GlobalLB.Region.RegionItemSequenceSequence')]

So, from this output, we’ll need to build a RegionItem, a RegionItemSequence, and a RegionDefinition.  The final script will require a file to be supplied for the region contents, one content entry per line with no quotes.  For now, we’ll just define them in a list.

In [25]: regions = ['US/Illinois', 'US/Missouri']

In [26]: print regions
-------> print(regions)
['US/Illinois', 'US/Missouri']

Next, we’ll build the region item type and populate with the type and negate parameters.

In [27]: reg_list = []

In [28]: for x in range(1,len(regions)+1):
   ....:     x = reg.typefactory.create('GlobalLB.Region.RegionItem')
   ....:     x.type = 'REGION_TYPE_STATE'
   ....:     x.negate = False
   ....:     reg_list.append(x)
   ....:
   ....:

In [29]: print reg_list
-------> print(reg_list)
[(GlobalLB.Region.RegionItem){
   content = None
   type = "REGION_TYPE_STATE"
   negate = False
}, (GlobalLB.Region.RegionItem){
   content = None
   type = "REGION_TYPE_STATE"
   negate = False
}]

Notice the content above is None.  Now we can loop through our items and populate the content attribute:

In [30]: for index,region in enumerate(regions):
   ....:     reg_list[index].content = region
   ....:
   ....:

In [31]: print reg_list
-------> print(reg_list)
[(GlobalLB.Region.RegionItem){
   content = "US/Illinois"
   type = "REGION_TYPE_STATE"
   negate = False
}, (GlobalLB.Region.RegionItem){
   content = "US/Missouri"
   type = "REGION_TYPE_STATE"
   negate = False
}]

Now that we have our content defined, we can create the sequence type and add the region items, then create the region definition type as well:

In [36]: reg_seq = reg.typefactory.create('GlobalLB.Region.RegionItemSequence')
In [37]: reg_seq.item = reg_list

In [38]: reg_def = reg.typefactory.create('GlobalLB.Region.RegionDefinition')
In [39]: reg_def.name = 'myRegion_pyControl'
In [40]: reg_def.db_type = 'REGION_DB_TYPE_USER_DEFINED'

Now that we have all our types created, we can now create the region! 

In [43]: reg.create(regions = [reg_def], items = [reg_seq])

In [44]: reg.get_list()
Out[44]:
[(GlobalLB.Region.RegionDefinition){
   name = "myRegion_pyControl"
   db_type = "REGION_DB_TYPE_USER_DEFINED"
},
(GlobalLB.Region.RegionDefinition){
   name = "myRegion_GUI"
   db_type = "REGION_DB_TYPE_USER_DEFINED"
}]

And that’s it!  For the full script, check out the pyControl_Create_GTM_Region codeshare sample.  Happy coding!

Published Apr 01, 2010
Version 1.0

Was this article helpful?