Forum Discussion
smp_86112
Cirrostratus
Apr 28, 2010v9 matchclass and v10 class match iRule commands
I've got a v9 irule that takes action based on whether or not the client IP address is in a data class. The v9 iRule looks like this:
if { [matchclass [IP::remote_addr] equals $::allowed_clients] } {
if I read the v10 doc:
For v10 users: Classes (data groups) used to be accessible as a global TCL list. Starting in v10, accessing a data group as a global variable ($::class_name) simply returns the name of the data group and is no longer a TCL list. You must now use the "class" command for all data group access.
, my interpretation is that this match class statement should be replaced with "class match", like this:
if { [class match [IP::remote_addr] equals $::allowed_clients] } {
However both statements return the same value which I've validated by logging it - they both return the index number of the class which holds the matching record. Based on the doc I expected the "$::allowed_clients" statement to return the name of the class "allowed_clients", which [IP::remote_addr] obviously will never match. However the matchclass statement seems to be working the same way in v10 as it did in v9. Am I just not understanding the doc properly?
11 Replies
- hoolio
Cirrostratus
I think the issue with using the $:: prefix for a datagroup is if you're trying to use a TCL list command with it. Instead you should use [class get v10_datagroup] to get the class contents as a list. I expect using $:: in class match or matchclass will just break CMP if the platform/module combo you're using supports it.
This should work fine in v10:
if { [class match [IP::remote_addr] equals allowed_clients] } {
Aaron - smp_86112
Cirrostratus
Thanks for responding. I don't get this... Are you saying that it works in v10 because I am not using a TCL list statement (I'm still a TCL newbie)? And are you saying everywhere in v9 that I use $:: I should be replacing with was I upgrade?
Can you give an example of a TCL list statement, or of an iRule command that would require a change from "matchclass" to "class match"? Maybe this just a TCL distinction that I don't quite understand yet, and I'm not even using. - hoolio
Cirrostratus
Hey SMP,
Sorry that wasn't very clear. The matchclass command does work in all current versions, so if you're using matchclass in v9, you could continue using it in v10. But as it (and findclass) have been deprecated you could change these commands to the new 'class' command. For any reference to a datagroup in v9.4.4 or higher you should remove the $:: prefix from the datagroup name to ensure the iRule won't break CMP compatibility.
Using TCL list commands like lindex, llength, lsort, etc will not work in v10. If you want to convert the datagroup contents to a TCL list, you can use [class get datagroup_name]. Here are a couple of quick examples:when HTTP_REQUEST { This method works but prevents CMP from being used on any VIP the iRule is enabled on See http://devcentral.f5.com/Wiki/default.aspx/iRules/CMPCompatibility for related info log local0. "\[class get $::my_test_class\]: [class get $::my_test_class]" Correct way to retrieve the contents of a datagroup as a TCL list log local0. "\[class get my_test_class\]: [class get my_test_class]" Some TCL list commands run against a datagroup which has been retrieved as a TCL list log local0. "\[llength \[class get my_test_class\]\]: [llength [class get my_test_class]]" log local0. "\[lindex \[class get my_test_class\] 0\]: [lindex [class get my_test_class] 0]" This TCL list command example just returns the datagroup name because of the $:: prefix on the datagroup name log local0. "\[lindex $::my_test_class 0\]: [lindex $::my_test_class 0]" }: [class get my_test_class]: {item2 {}} {item1 {}} {item10 {}} {item4 {}} : [class get my_test_class]: {item2 {}} {item1 {}} {item10 {}} {item4 {}} : [llength [class get my_test_class]]: 4 : [lindex [class get my_test_class] 0]: item2 {} : [lindex my_test_class 0]: my_test_class
So long story short: you would do well to replace all matchclass and findclass commands with the new 'class' command equivalents. Remove $:: from any datagroup reference. And replace any TCL list commands that you might have been running directly against a datagroup, like [lindex $::datagroup_name 0], with [lindex [class get datagroup_name] 0].
Aaron - hoolio
Cirrostratus
Actually, regarding the last sentence, using the 'class element' command would probably be more efficient than using lindex against the 'class get' output.
Aaron - smp_86112
Cirrostratus
Hey, can you help me understand what you meant by your second chunk of output? Is that supposed to be the output from the log statements? If that's the case, why do the item numbers jump around from item2 -> item1 -> item10->item4? Is that supposed to be literal text, i.e. the contents of the class? - hoolio
Cirrostratus
Hi SMP,
The class contents aren't normally stored in the same order they are listed in the bigip.conf. That was supposed to be the literal log output, but I think I copied a line incorrectly. The first line should have $:: in the datagroup name. The first two log lines of the iRule were intended to show that you could access the datagroup by name with $:: as a prefix when not using TCL list commands. Doing so would break CMP compatibility for the VIP though, so it's better to not use $:: at all in 9.4.4 or higher.
Aaron - smp_86112
Cirrostratus
I get the point regarding the "$::" syntax. I guess my question is in the "my_test_class" class in your example, are "item2 {}", "item1 {}", "item10 {}", and "item4 {}" the literal values of the class contents? Or are they intended as variables representing the literal class values? - hoolio
Cirrostratus
This was the test class I was using on 10.1:class my_test_class { { "item1" "item10" "item2" "item4" } }
Using 'class get' seems to retrieve the "names" and null values for each class element. If I set a value for one of the class elements, the class looks like this:class my_test_class { { "item1" { "item1_value" } "item10" "item2" "item4" } }
And class get returns:
[class get my_test_class]: {item10 {}} {item2 {}} {item4 {}} {item1 item1_value}
So if you wanted to just get the value for item1 you could use something like this:
[lindex [class get my_test_class "item1"] 1]"
Aaron - smp_86112
Cirrostratus
Ah, OK great - I got it. Thanks very much for clarifying. - brad_11480
Nimbostratus
okay so when upgrading from v9 to v10 the class definitions are not altered?
at least that is what I have observed.
So in v9 i am using a 'findclass' command to return the value for a string.
does this still work when going to v10 or is a code change required??
class class_table {
{
"/testit pool_testit"
"/othertest pool_anothertest"
}
}
commands:
when HTTP_REQUEST {
set myURI [string tolower [URI::decode [HTTP::uri]]]
set target [findclass $myURI $::class_table ""]
:
so is the value of target returned in v10 the same as v9?
in v9 if $myURI is the value of /testit
$target would be pool_testit
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
