Tech Tips on DevCentral
   
You are here: Tutorials > Tech Tips

Current Articles | Search | Syndication

v.10 - New class features in iRules

by Colin Walker - 9884 views Article Rating

As of the release of version 10 there are some great new features built into classes and the way they work within iRules, as well as a very powerful new command to let you make use of them. Here's a little history on how things used to be (and still are in v9.x).

Prior to v10.0 the most common way to make use of a data group (class) within an iRule was with either matchclass or findclass. These were used to parse through a class file to search for a specific entry and return particular results, which worked fine. The example below shows a simple example of doing this:

class my_data_group {
  "/site1/"
  "/site2/"
}
rule myRule {
  when HTTP_REQUEST {
    if {[matchclass [HTTP::uri] starts_with $::my_data_group]}{
      log "requested URL starts with /site1/ or /site2/"
    }
  }
}

This example, and all others that make use of matchclass and findclass, continue to work the same way in v10.0. We aren't changing these just yet, so all of your iRules that make use of them will still function. There were some changes necessary though to allow for the new structures to be implemented and allow for the awesome new capabilities.

Prior to v10.0 it was possible to access the contents of a class in another way, without using matchclass or findclass, because class objects could also be treated as TCL lists.  In v10.0 and later, Data Group (class) objects can no longer be treated as TCL lists. This is becaues the class structure itself had to be changed to allow for the new commands and functionality. Our custom commands could be re-worked to function properly still, but the base TCL commands aren't built to work with the changes.

The following is an example of using a class as a TCL list from within an iRule:

when RULE_INIT {
  log "value of first element in my_data_group: [lindex $::my_data_group 0]"
  log "value of second element in my_data_group: [lindex $::my_data_group 1]"
}

Note that the TCL command 'lindex' was used to access the contents of the my_data_group class object (shown earlier).  In v10.0 calling the class name ($::my_data_group above) will just return the name of the class itself, making examples like the one above unusable. It's important to note that if you are making use of this functionality now, you will need to update your code before upgrading to v10, or your iRules will not function as expected. There are a number of commands that operate on TCL lists, which is why people have used this kind of referencing in the future.  The list of commands that people might be using in iRules to operate on class includes: foreach, join, lappend, lassign, lindex, linsert, llength, lrange, lrepeat, lreplace, lreverse, lsearch, lset, lsort, and possibly more.

To ensure that users don't lose this functionality, a new iRule command named 'class' is available to provide list-type access to data groups.  In the example above, instead of using '[lindex $::my_data_group 0]' you would now use: '[class element 0 my_data_group]'.  You can also return the  entire contents of a data group as a TCL list, and then operate on the returned list as before.  To return a data group as a list, you would use a command like this:  '[class get my_data_group]'

This change in behavior was necessary to make data groups compatible with CMP (Clustered Multi-Processing), and to add support for name-value lookups like the following example:

class images {
  "square.gif" := "<contents of image goes here>"
  "circle.gif" := "<contents of image goes here>"
}

Within an iRule you could then use the following to lookup the value of "square.gif" and place its contents in a variable named "image": set image [class lookup square.gif images].

That gets the history of how classes used to work out of the way, along with a few examples that show some of the new behavior and how to make it work for you. Now let's look at the new commands and how they work. The list is pretty long so rather than go through each command with commentary here, I'm going to drop in the entire syntax guide for the new class commands and leave discussion and commenting to the forums and wikis. Here is the new set of class commands, along with the available syntax for them:

class match [<options>] <item> <operator> <class>
  Returns 0 or 1 depending on whether <item> matches an element in <class> according to the <operator>.
  This command form is equivalent to the current iRule command:
  matchclass <item> <operator> <class>.
  Example:
    class match [HTTP::uri] ends_with image_class
    Read as: does the uri end with an element from image_class
class search [<options>] <class> <operator> <item>
  Returns 0 or 1 depending on whether an element in <class> matches <item> according to the <operator>.
  This command form is equivalent to the current iRule command: 	matchclass <class> <operator> <item>.
  Example:
    class search blocked_paths starts_with [HTTP::uri]
    Read as: does blocked_paths contain an element that starts with the uri.
  The options for both of the above forms of the class command can be:
    -index		Changes the return value to be the index of the matching class element.
    -name		Changes the return value to be the name of the matching class element.
    -value		Changes the return value to be the value of the matching class element.
    -element	Changes the return value to be a list of the name and value of the matching class element.
    -all		When used with the above options, returns a list of all matching elements, not just the first.
    --		Terminates option processing (useful if the item or '<class>' begins with a hyphen).
  The <operator> for both of the above forms can be:
    equals, starts_with, ends_with, contains
class lookup <item> <class>
  Equivalent to: class match -value <item> equals <class>.
class element [<options>] <index> <class>
  Returns a list containing the name and value of the element found at <index> in <class>.
  Note: class indexes are not guaranteed to be consistent and may change when a datagroup is modified.  
  This could happen if the event execution becomes suspended or across executions of different events.
  The <options> for this command can be:
    -name	Changes the return value to be the name of the class element at the index.
    -value	Changes the return value to be the value of the class element at the index.
    --	Terminates option processing.
class type <class>
  Returns the type of the <class>, currently only “string”, “IP”, or “value”.
class exists <class>
  Returns 1 or 0 depending on whether a class named <class> actually exists.
class size <class>
  Returns the number of elements currently found in <class>.
class names [-nocase] <class> [<pattern>]
class get [-nocase] <class> [<pattern>]
  Returns a list containing the names or a list of the name and value currently found in <class>.  
  An optional <pattern> may be specified to restrict the list to names that match the Tcl glob pattern.  
  Additionally, the switch -nocase may be specified to enable case-insensitive pattern matching.
  This command provides a way to access the class as a Tcl list similar to previously access the global 
  variable named the same as the list.

The following forms of the class command provide behavior similar to the native Tcl array command for iterating across the elements of a datagroup.

class startsearch <class>
  Returns a <search_id> to be used with each of the following commands.
  Note: the search is not guaranteed to iterate over every element and may miss elements if the datagroup is modified.  
  This could happen if the execution of the event becomes suspended or across executions of different events.
class nextelement [<options>] <class> <search_id>
  Returns a list containing the name and value of the next element in the current search.
  The <options> for this command can be:
    -index	Changes the return value to be the index of the next class element.
    -name	Changes the return value to be the name of the next class element.
    -value	Changes the return value to be the value of the next class element.
    --	Terminates option processing.
class anymore <class> <search_id>
  Returns 1 or 0 depending on whether there are more elements to iterate on in the <class>.
class donesearch <class> <search_id>
  Terminates the search.  After using this command, executing class anymore will return 0 
and executing class nextelement will cause an error.


Rate This Article:

COMMENTS

posted @ Sunday, February 28, 2010 10:23 PM by John Gruber   

If you cut and past:

class images {
"square.gif" := ""
"circle.gif" := ""
}

into a 10.1 config you can not load it. This syntax is wrong. In the wiki page for table it says 10.1 removed the requirement to use an external class file to do NVP lookups, but I am having problems getting my classes formated correctly for the class lookup command.

posted @ Sunday, September 19, 2010 9:31 PM by anthony@qut   

Prior to 10.x we were told
==
Can I modify a class real-time with my iRule?
Technically, yes. Once the configuration is loaded into memory, you can technically modify a class with TCL's list commands. Doing so, however, not only converts the data in the class from an efficient, hashed format into a simple list format, thereby slowing down queries; but the changes made are also not permanent, as they cannot be written back to the file that stores the class data. This makes the changes effective only until TMM is restarted. In general, there is usually another way of structuring your code to avoid this that would be preferred.
==

Is this still the case? I can't see new class commands to actually modify the data.

posted @ Sunday, September 19, 2010 9:33 PM by anthony@qut   

Prior to 10.x we were told
==
Can I modify a class real-time with my iRule?
Technically, yes. Once the configuration is loaded into memory, you can technically modify a class with TCL's list commands. Doing so, however, not only converts the data in the class from an efficient, hashed format into a simple list format, thereby slowing down queries; but the changes made are also not permanent, as they cannot be written back to the file that stores the class data. This makes the changes effective only until TMM is restarted. In general, there is usually another way of structuring your code to avoid this that would be preferred.
==

Is this still the case? I can't see new class commands to actually modify the data.

posted @ Monday, October 25, 2010 11:00 AM by f5   

class my_data_group {
"/site1/"
"/site2/"
}
rule myRule {
when HTTP_REQUEST {
if {[matchclass [HTTP::uri] starts_with $::my_data_group]}{
log "requested URL starts with /site1/ or /site2/"
}
}
}


Is this CMP compatible in v10? How about v9.4.7? I use this form in v9 and will soon upgrade to (v9.4.7 or v10.1.0). It works in v9.4.7 and v10.1.0 (i.e. it loads, and functions).

posted @ Wednesday, March 30, 2011 10:49 AM by hoolio   

Joe did a useful comparison of performance of the new class command with if/else, switch and matchclass:

http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086424/Comparing-iRule-Control-Statements.aspx

Aaron

posted @ Friday, February 03, 2012 11:54 AM by Vlan   

It would be helpful to have an example of the correct syntax to reference the data group/class via an iRule. As I understand it $:: is global and can disable CMP bu there is no reference to what is the correct method.

posted @ Friday, February 03, 2012 12:01 PM by Jason Rahm   

you just drop the $::

rule myRule {
when HTTP_REQUEST {
if {[matchclass [HTTP::uri] starts_with my_data_group]}{
log "requested URL starts with /site1/ or /site2/"
}
}
}
Only registered users may post comments.
  

TechTips by Category

Filter by:
ARX Import Restrictions for NetApp Volumes by jmccarron (30 Views)
Two-Factor Authentication With Google Authenticator And APM by watkins (297 Views)
Controlling a Pool Members Ratio and Priority Group with iControl by Joe (243 Views)
F5 ARX WAN Optimization with BIG-IP WAN Optimization Manager (WOM) by mfabiano (284 Views)
iRules Concepts: Tcl, The How and Why by Colin (957 Views)
Populating Tables With CSV Data Via Sideband Connections by watkins (958 Views)
Introduction to iStats Part 1: Overview by Colin (1069 Views)
Google reCAPTCHA Verification With Sideband Connections by watkins (1429 Views)
Transparent Web Application Bot Protection by Joe (1265 Views)
v11: iRules Data Group Updates by citizen_elah (2927 Views)
HTTP Request Cloning via iRules, Part 1 by Colin (1341 Views)
Managing Ramcache Entries with Pycontrol by citizen_elah (909 Views)
iRules Concepts: Connection States and Command Suspension by Colin (1727 Views)
v11.1: DNS Blackhole with iRules by citizen_elah (2089 Views)
CodeShare Refresh: HTTP Session Limit by Colin (1400 Views)
Page 1 of 4First   Previous   [1]  2  3  4  Next   Last   
  

Most Viewed Tech Tips

Mitigating Slow HTTP Post DDoS Attacks With iRules by watkins
(6045 Views) Published on Friday, November 05, 2010
APM Session Invalidation Using ASM by Colin
(6030 Views) Published on Monday, October 17, 2011
Web Application Login Integration with APM by Colin
(5800 Views) Published on Monday, April 18, 2011
iRules Data Group Formatting Rules by citizen_elah
(5490 Views) Published on Tuesday, March 29, 2011
Multiple Certs, One VIP: TLS Server Name Indication via iRules by Colin
(5422 Views) Published on Tuesday, April 05, 2011
One Time Passwords via an SMS Gateway with BIG-IP Access Policy Manager by citizen_elah
(5386 Views) Published on Tuesday, February 08, 2011
BIG-IP APM–Customized Logon Page by citizen_elah
(5104 Views) Published on Tuesday, June 21, 2011
SSL Profiles Part 3: Certificate Chain Implementation by citizen_elah
(5050 Views) Published on Wednesday, December 01, 2010
SSL Profiles: Part 1 by citizen_elah
(4747 Views) Published on Wednesday, November 17, 2010
v11: RDP Access via BIG-IP APM–Part 3 by citizen_elah
(4715 Views) Published on Tuesday, October 04, 2011
Automating Web App Deployments with Opscode Chef and iControl by watkins
(4565 Views) Published on Friday, July 08, 2011
  

 Top Contributors

Techgeeeg
fatmcgav
mikand
MarkM
Chris Phillips
genseek
K-Dubb
adiezma
Ankush Narang
Beinhard
  

93,050 Members in 191 Countries and Growing!

Join DevCentral Today!

About DevCentral

F5 DevCentral is your source for the best technical documentation, discussion forums, blogs, media and more related to application delivery networking.

So dive in, meet your peers, and get familiar with DevCentral. We hope it makes your job easier and helps you get more from your F5 investment. If new to DevCentral, check out the Getting Started section. And if you have any problems, or think something could be easier to use, let us know.

Got It !

We've received your comment and transmitted it directly to DevCentral HQ.

Thanks for taking time to let us know what's on your mind. At DevCentral | Community Matters!

Get In Touch With Us

Have questions, suggestions or just want to get something off your chest?

Use our handy form below to Direct Connect with DevCentral Mission Control.

Send Us Feedback      or