Forum Discussion
Al_Carandang_11
Nimbostratus
Sep 20, 2008problem with findclass
I have an iRule which uses the following statement
set myData [findclass [virtual] myClass] where the class entries are as follows
class myClass {
"icmrdc2_80 field1 field2 field3"
"icmrdc2_8081 field1 field2 field3"
} when the virtual name is icmrdc2_80, findclass always returns
"icmrdc2_8081 field1 field2 field3"However, if the class entries are as follows
class myClass {
"icmrdc_80 field1 field2 field3"
"icmrdc_8081 field1 field2 field3"
} when the virtual name is icmrdc_80, findclass always returns the entry "icmrdc_80 field1 field2 field3"
How do I make the findclass always search for an exact match?
thanks,
Al
8 Replies
- hoolio
Cirrostratus
Hello Al,
finclass does a hardcoded wildcard match of the string against each line of the datagroup. I don't think there is a way around this. Perhaps you could make a feature request through F5 Support to provide an option for glob or specific matching against just the first "field" of the datagroup. In the meantime, you could use a for loop and getfield to perform an exact match against the class:when RULE_INIT { Create a test class (actually a list in this case). This could also be defined as a class/datagroup. set ::test_class [list {field1 value1} {field1* value1} {field2 value2} {field11 value11}] Loop through the datagroup line by line. foreach element $::test_class { Log the current line. log local0. "Current \$element: $element" Compare the element against the string. If the datagroup entry has a wildcard, it should be listed first in the string compare statement. if {[string match -nocase [getfield $element " " 1] "field11"]}{ Found a match, so log it and break out of the foreach loop. log local0. "Matched \$element: $element. Value: [getfield $element " " 2]. Exiting loop." break } } }
Log output:
Rule : Current $element: field1 value1
Rule : Current $element: field1* value1
Rule : Matched $element: field1* value1. Value: value1. Exiting loop.
If you don't want wildcard matching, you can test with this version which doesn't have a wildcard in the datagroup:when RULE_INIT { Create a test class (actually a list in this case). This could also be defined as a class/datagroup. set ::test_class [list {field1 value1} {field2 value2} {field11 value11}] Loop through the datagroup line by line. foreach element $::test_class { Log the current line. log local0. "Current \$element: $element" Compare the element against the string. If the datagroup entry has a wildcard, it should be listed first in the string compare statement. if {[string match -nocase [getfield $element " " 1] "field11"]}{ Found a match, so log it and break out of the foreach loop. log local0. "Matched \$element: $element. Value: [getfield $element " " 2]. Exiting loop." break } } }
Rule : Current $element: field1 value1
Rule : Current $element: field2 value2
Rule : Current $element: field11 value11
Rule : Matched $element: field11 value11. Value: value11. Exiting loop.
Aaron - Al_Carandang_11
Nimbostratus
Got an answer from F5. The value returned when there are multiple matches is arbitrary and depends on how the class gets loaded in memory.
To solve the problem, the code should be written asset myData [findclass "[virtual] " myClass]
-Al - Al_Carandang_11
Nimbostratus
Ran into some strange behaviour again. If the statement is
myData is always emptyset Base [virtual] set myData [findclass "$Base " myClass " "]
-Al - Al_Carandang_11
Nimbostratus
found the answer... I was specifying the " " separator in the last case wherease I wasn't specifying one in the first. - hoolio
Cirrostratus
Don't you need to refer to the class as ::class (or $::class in pre-9.4.2)?
Aaron - hoolio
Cirrostratus
It's been tossed around for a while... all of the forms (class, ::class, $class, $::class) seem to work as far as matching goes. I don't have a CMP enabled box to test on so I can't check which forms allow you to use CMP.log local0. "\[findclass 10.0.0.1 private_net\]: [findclass 10.0.0.1 private_net]" log local0. "\[findclass 10.0.0.1 \$private_net\]: [findclass 10.0.0.1 $private_net]" log local0. "\[findclass 10.0.0.1 ::private_net\]: [findclass 10.0.0.1 ::private_net]" log local0. "\[findclass 10.0.0.1 \$::private_net\]: [findclass 10.0.0.1 $::private_net]" log local0. "\[matchclass 10.0.0.1 equals private_net\]: [matchclass 10.0.0.1 equals private_net]" log local0. "\[matchclass 10.0.0.1 equals \$private_net\]: [matchclass 10.0.0.1 equals $private_net]" log local0. "\[matchclass 10.0.0.1 equals ::private_net\]: [matchclass 10.0.0.1 equals ::private_net]" log local0. "\[matchclass 10.0.0.1 equals \$::private_net\]: [matchclass 10.0.0.1 equals $::private_net]" log local0. "\[findclass 205.0.0.1 private_net\]: [findclass 205.0.0.1 private_net]" log local0. "\[findclass 205.0.0.1 \$private_net\]: [findclass 205.0.0.1 $private_net]" log local0. "\[findclass 205.0.0.1 ::private_net\]: [findclass 205.0.0.1 ::private_net]" log local0. "\[findclass 205.0.0.1 \$::private_net\]: [findclass 205.0.0.1 $::private_net]" log local0. "\[matchclass 205.0.0.1 equals private_net\]: [matchclass 205.0.0.1 equals private_net]" log local0. "\[matchclass 205.0.0.1 equals \$private_net\]: [matchclass 205.0.0.1 equals $private_net]" log local0. "\[matchclass 205.0.0.1 equals ::private_net\]: [matchclass 205.0.0.1 equals ::private_net]" log local0. "\[matchclass 205.0.0.1 equals \$::private_net\]: [matchclass 205.0.0.1 equals $::private_net]"
Log output:
Rule : [findclass 10.0.0.1 private_net]: 10.0.0.0/8
Rule : [findclass 10.0.0.1 $private_net]: 10.0.0.0/8
Rule : [findclass 10.0.0.1 ::private_net]: 10.0.0.0/8
Rule : [findclass 10.0.0.1 $::private_net]: 10.0.0.0/8
Rule : [matchclass 10.0.0.1 equals private_net]: 1
Rule : [matchclass 10.0.0.1 equals $private_net]: 1
Rule : [matchclass 10.0.0.1 equals ::private_net]: 1
Rule : [matchclass 10.0.0.1 equals $::private_net]: 1
Rule : [findclass 205.0.0.1 private_net]:
Rule : [findclass 205.0.0.1 $private_net]:
Rule : [findclass 205.0.0.1 ::private_net]:
Rule : [findclass 205.0.0.1 $::private_net]:
Rule : [matchclass 205.0.0.1 equals private_net]: 0
Rule : [matchclass 205.0.0.1 equals $private_net]: 0
Rule : [matchclass 205.0.0.1 equals ::private_net]: 0
Rule : [matchclass 205.0.0.1 equals $::private_net]: 0
Aaron - Nicolas_Menant
Employee
::class and $::class work to make reference to a class (starting v9.4.2)
But if you use matchclass or findclass then you should use ::class since it will maintain CMP. Click here - hoolio
Cirrostratus
Thanks for the confirmation, nmenant. So should using class, $class and ::class all work to leave CMP enabled?
Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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
