Forum Discussion
Ulf_Zimmermann_
Nimbostratus
Sep 11, 2009Checking for file from iRule?
I am looking at implementing a downtime pool for something like 50-60 virtual servers at a time. My current idea would involve an iRule always applied to these virtual servers which as the first action checks for a file locally on the BigIP. If it exists the rule would send requests to the downtime pool, otherwise it would just exit.
This would allow us to give the application people an account, they would do a touch via a script on the file system and when the downtime is done, they would remove it.
Is this possible with iRules?
11 Replies
- The_Bhattman
Nimbostratus
Are you talking about moving your connections to a single pool for maintenance? - Ulf_Zimmermann_
Nimbostratus
The downtime rule would allow our internal IPs still to go to the normal pool, while external IPs should get redirected to another virtual server or to the downtime pool.
The file access (like a -f in a shell script or perl), would make it easier to enable the rule, instead of having to add it to 50-60 virtual servers at start of the downtime and removing it afterwards. - Ulf_Zimmermann_
Nimbostratus
Reading up on TCL, it seems what I would be looking for is "file exists" which is a disabled command. - The_Bhattman
Nimbostratus
That would be correct that you can't access the file system directly with iRules. One way would be to write up something using iControl or possibly using an indirect method with iRules
For example you would create an external class data group called downtimepool
that contains "UP" or "DOWN"
Then you can use a common irulewhen CLIENT_ACCEPTED { if { (![IP::address [IP::client_address]/24 eq "192.168.1.0") and ($::downtimepool eq "DOWN" } { pool pool_downtime } }
Where 192.168.1.0 is your internal IP block
The only catch is that the application people would have to log into the BIGIP and go to the external file and change the language to "UP" and perform a b load.
Another alternative is to give them access to the BIGIP GUI and let them change a parameter in the irule that is common to all your VSwhen CLIENT_ACCEPTED { set downtimepool "UP" if { (![IP::address [IP::client_address]/24 eq "192.168.1.0") and ($:downtimepool eq "DOWN" } { pool pool_downtime } }
Another way is seting up a pool called dummy_pool containing a single pool member where it is doing a standard TCP port check, where the the application users would normally disable the service that the standard TCP port is being checked on so that the pool is always down under normal conditions.
Then use you can write up an irule similiar to thiswhen CLIENT_ACCEPTED { if { (![IP::address [IP::client_address]/24 eq "192.168.1.0") and (![active_members dummy_pool] < 1) } { pool pool_downtime } }
When they want external users to go to the downtime pool they simply turn up the service on the single pool member and thus the monitor will pass and mark up the pool which will trigger the irule to process.
Of course this all untested but hopefully this helps
CB - Another options would be to use a Statistics Profile and have the iRule reference the contents of a variable in it. You could then write a perl script on the BIG-IP that either talks iControl to configure the stats profile entry or uses bigpipe. When I get back into the office on Monday I'll whip up a prototype for you.
-Joe - hoolio
Cirrostratus
Another option would be to use priority groups and a health check which looks for a file on the server which is available over HTTP(S). The monitor would check that file for an UP message and mark the pool member up. If the server admin modifies the file or the web server is down, the file wouldn't be served and the monitor would mark the pool member down. You could use priority groups on the pool so that your normal production servers would handle all requests unless some or all of them were down. In that case, the lower priority pool members would be used.
This option would only be efficient for one click changes if the servers' content is pushed via a CMS.
Aaron - Ulf_Zimmermann_
Nimbostratus
Using the suggestions posted in reply to my posts, here is what I have come up with so far:when HTTP_REQUEST { if { [PROFILE::exists serverssl] == 1 } { set downtimepool "Downtime-SSL" set downtimemember "10.21.67.103" set downtimeport "16443" log local0. "Virtual server has SSL server profile" } else { set downtimepool "Downtime-NonSSL" set downtimemember "10.21.67.103" set downtimeport "16080" log local0. "Virtual server has no SSL server profile" } if { ([LB::status pool $downtimepool member $downtimemember $downtimeport] eq "up") and (![IP::addr [IP::client_addr]/16 equals 10.21.0.0]) } { pool $::downtimepool log local0. "Sending request to pool $downtimepool" } }
Now I am running into a problem with PROFILE::exists serverssl, testing it for one server has serverssl set, the above rule still enters the else {} instead. - The_Bhattman
Nimbostratus
Put in a log statement to see what is contained in the profile.when HTTP_REQUEST { log local0. "server SSL profile enabled: [PROFILE::serverssl name]" if { [PROFILE::exists serverssl] == 1 } { set downtimepool "Downtime-SSL" set downtimemember "10.21.67.103" set downtimeport "16443" log local0. "Virtual server has SSL server profile" } else { set downtimepool "Downtime-NonSSL" set downtimemember "10.21.67.103" set downtimeport "16080" log local0. "Virtual server has no SSL server profile" k } if { ([LB::status pool $downtimepool member $downtimemember $downtimeport] eq "up") and (![IP::addr [IP::client_addr]/16 equals 10.21.0.0]) } { pool $::downtimepool log local0. "Sending request to pool $downtimepool" } } - Ulf_Zimmermann_
Nimbostratus
I think my problem might be this part:
Note that the results of the PROFILE::exists "profile type" command is specific to the context of the event.
For example, with a client SSL profile associated with the virtual server, [PROFILE::exists clientssl]
will return 1 in clientside events and 0 in serverside events. Likewise, [PROFILE::exists serverssl]
will return 0 in clientside events and 1 in serverside events.
I either need to be able to say "send to this pool with no serverssl" or being able to determine if serverssl is set and choose a pool based on it. - Ulf_Zimmermann_
Nimbostratus
Ok, I think this is working as I intend it to work:when HTTP_REQUEST { set downtimepool "Downtime-NonSSL" set downtimemember "10.21.67.103" set downtimeport "16080" set downtime 0 if { ([LB::status pool $downtimepool member $downtimemember $downtimeport] eq "up") and (![IP::addr [IP::client_addr]/16 equals 10.21.0.0]) } { pool $downtimepool log local0. "Sending request to pool $downtimepool" set downtime 1 } } when SERVER_CONNECTED { if { $downtime == 1 and [PROFILE::exists serverssl] == 1 } { set disable "SSL::disable serverside" catch {eval $disable} log local0. "Disabled server side SSL" } }
Now I will let the people, who take applications up/down, set the node enable/disable via SOAP/XML and that should allow them to control the direction to another pool. I probably will expand the IP::addr match up there to a class, as we use not only 10.0.0.0/8 inside the company but one office still uses 100.0.0.0/8 (not my call). Plus there might be the need for some real IP addresses used for people sitting at home during our software releases.
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
