Forum Discussion
James_Thomson
Employee
Dec 10, 2004mapclass2node
Along the same lines off an an earlier post by Natty about persistence. I'm trying to just read a cookie that is handed out by the server and persist a user on it. One example is where the cookie is static and therefore, I thought of user mapclass2node.
class nodes {
"s1s1 10.11.1.10:80"
"s1s2 10.11.1.20:80"
}
I'd like to search the request and map as appropriate. I used to do this in the pool with a select command:
select mapclass2node ((http_cookie,("server")),nodes)
How does this work now? Do I need to do a when HTTP_REQUEST and then some if statement.
when HTTP_REQUEST {
if {HTTP::cookie]} {
select mapclass2node((http_cookie,("server")),nodes)
}}
15 Replies
- unRuleY_95363Historic F5 AccountIt's pretty simple, though not configured quite the same as the select statement on the pool. Here's what to do:
class node_class { "s1s1 10.11.1.10:80" "s1s2 10.11.1.20:80" } rule direct_select { when HTTP_REQUEST { node [findclass [HTTP::cookie "server"] $::node_class " "] } }
The findclass command does pretty much the same thing as the mapclass2node, returning the latter portion of the matched class entry. The node command directly selects the node. - unRuleY_95363Historic F5 AccountWe discovered an issue in 9.0.2 with the separator argument of the findclass command. The getfield command should be used in conjunction with the findclass command until 9.0.3 where the issue has been resolved.
Updated example:rule direct_select { when HTTP_REQUEST { set server [HTTP::cookie "server"] set entry [findclass $server $::node_class] if { $entry ne "" } { node [getfield $entry " " 2] } else { log "Bad server cookie: $server" reject } } } - James_Thomson
Employee
Thanks, I used this and it works great.rule select_on_cookie { when HTTP_REQUEST { if {[HTTP::cookie exists "server"]} { set result [findclass [HTTP::cookie "server"] $::nodes] if {$result ne ""} { node [getfield $result " " 2] } } } } class nodes { "s1s1 10.11.1.10:80" "s1s2 10.11.1.20:80" } - David_Zuk_10432
Nimbostratus
Hi there. I'm trying to follow your example and am having absolutley no luck. When I try to define the class in the iRule, it doesn't allow it. I created the data group that is supposed to do the same thing, but that fails as well. I am running BigIP 9.0.3 and any help would be greatly appreciated. - In the example above, this is what is stored in the system configuration file. If you are using the GUI, you will need to create a Data Group List of name "nodes" and then only include the when part of the rule.
If you can explain further what you mean by "fails" we might be able to help further. A good debugging trick is to make use of the log statement to output values you are expecting to search on. In the case of this example logging the [HTTP::cookie "server"] value might help if you aren't finding an exact match.
-Joe - David_Zuk_10432
Nimbostratus
Joe,
Yeah, I figured that out about the configuration file. I'll give the logging a try tonight. Unfortunatley I can't test during the day. As for the failing part, I'm not quite sure. I am new to BigIP and not a programmer. I can describe what happens though. Persistance works fine for client based http requests with this rule -->
when HTTP_REQUEST {
if { [HTTP::cookie exists "server"] } {
use pool Staging
}
else {
use pool Staging
}
}
Very basic, but it works for http and https. The problem comes in when another website of ours uses our Virtual Server for authentication. With the above rule, persistence doesn't work. It just uses round robin. When I tried the rules about, either it didn't make a difference, or I got the page cannot be displayed message every time.
Also, besides the LTM config manual, is there a list of all the commands and options and such that work with iRules? Thanks a million.
Dave - Now I'm a bit confused. Your code above shows sessions with the "server" cookie set, will be routed to pool "staging" and all other sessions will be routed to "Staging" as well. This rule is equivalent to setting the virtual's default pool to "Staging" without an iRule.
I also don't see any persistence in this rule, just choosing pools to sent the connection to.
I think adding some log statements would shed a lot of light onto this situation as well as a full posting of your iRule (assuming it's more than what you stated above).
As for the iRules command reference. It's funny you ask, that is a side project I'm working on right now. More details to come to DevCentral soon...
-Joe - David_Zuk_10432
Nimbostratus
Joe,
I think I figured out where I went wrong. We had the persistence in v4.5 like the first guy did using the mapclass2node line in the pool section. Since I took over mid-stream, I didn't know that part was there. I need to duplicate that in v9.0.3. In 4.5 it was
mapclass2node(http_cookie("SERVER"), staging_nodes)
with a string class:
NV 10.96.8.88:80
EP 10.96.8.111:80
and using that simple rule from above. I'm not sure if that was the proper way to do things, but it works in 4.5
In 9.0.3, I've created the "data group" the same, now I need to make my virtual server use the mapclass2node option, which is now findclass?
So should I use the example from above :when HTTP_REQUEST { set server [HTTP::cookie "server"] set entry [findclass $server $::staging_nodes] if { $entry ne "" } { node [getfield $entry " " 2] } else { log "Bad server cookie: $server" reject } }
Also, I need this to work for both port 80 and port 443. Would the "data group" need the same IP's but with 443 at the end?
And Thanks. I really appreciate the help. - unRuleY_95363Historic F5 AccountYup, sounds like you are on the right track.
As for having it work for both 80 and 443, that is going to depend on what you are trying to accomplish. If you mean you want the rule to work on both a http and https vip, then you can simply modify the rule as such:when HTTP_REQUEST { set server [HTTP::cookie "server"] set entry [findclass $server $::staging_nodes] if { $entry ne "" } { node [getfield $entry " " 2] [IP::local_addr] } else { log "Bad server cookie: $server" reject } }
and remove the port from the data group.
The node command takes either format: "node a.b.c.d:p" or "node a.b.c.d p". The latter form allows you to do things like above.
Depending on if you have different cookie designators for the https servers vs. the http servers, you could also just add them to the data group. And finally, yes you could just create two separate data groups, one for http and one for https.
Another thing you may want to consider is how the rule handles the case when the "server" cookie is not present. Currently, the rule will still try to look in the data group. You may want to add a clause like "if { [HTTP::cookie exists "server"] } { " at the top and another else log & reject statement at the bottom. - First a little on findclass and matchclass. matchclass will search a data group list for an exact string match while findclass will search for a string in the class that starts with the search string. Either should work for your case but I just wanted to make clear the subtle difference.
So, the answer to your question really depends on what you have defined in your data group list as well as in the cookie. If you have the cookie being set in the format of "xx ip_addr:port", then since you are including the port in the cookie, you will have to explicitly state all values in the data group list.
Another option would be to include only the IP Addresses in the data group list and use the getfield command to break apart the cookie value into address and port before searching.// assuming $server is of the form "xx ip4_addr:port" set server_addr [getfield $server ":" 1];
You might want to throw in some "[info exists var]" in there to make sure you don't get runtime errors on the assignment commands for undefined variables - check in the /var/log/ltm logfile for any signs of this. You'll get something like this if you try to reference an undefined variable
can't read "varaible_name": no such variable
Once that is done, you then can do a matchclass (or findclass) on the extracted addrset entry [findclass $server_addr $::staging_nodes]
Hope this helps...
-Joe
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
