Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

iRule for Version check with dependent pool selection

Hello,

I have a scenario, my web developers want a dynamic pool selection which depents on a Version No., my idea was to make a curl get request with credentials (with a simple http basic auth) and I get back something like that. (result from the curl get)


{
"build" : {
"version" : "20001.0.1",
"artifact" : "calculator-web-service",
"name" : "calculator-web-service",
...

Now the user access the VIP maybe 10.10.10.10/Version.20001.0.1 and I want to compare with my curl query, is it the same version balance to pool A is it different balance to pool B. Is that possible and how could I realize that, Im not so familiar with iRules ! Maybe I could get an example ? Or a another idea how can I realize this.

THX Manuel

0
Rate this Question
Comments on this Question
Comment made 08-May-2018 by youssef 3608

Hi,

just want to clarify your need before to give your an solution.

Use case:

  • User connect to VIP: https://myapp/Version.20001.0.1
  • F5 made a curl on one poolmember hosted by poolA and poolB?
  • If poolmember have the same version that poolA you redirect user on poolA
  • If poolmember have the same version that poolB you redirect user on poolB
  • else defautl pool.

We are agree that you want curl a backend server? to retrieve Version No...

You can validate please.

Regards.

1
Comment made 08-May-2018 by eLeCtRoN 251

Hi youssef,

yes your explanation is correct but, I have a pool member with a static version this version will be never change, and is in the pool A, the poolmember with the changing version is in pool B, connect the user to https://myapp/Version.20001.0.1 should check the version from poolmeber in pool B is it the same balance to pool B but is the version different balance all to pool A and else to default pool

THX

Manuel

0
Comment made 09-May-2018 by eLeCtRoN 251

Hi Youssef,

I spoke with the developers again and I have to correct my anserwer, I thing your questions or explainations are correct.

Thats the correct scenario:

There are pool A with software version Y and pool B with software version X.

At a certain time then software version Z is deployed on the pool A and software version Y migrates on the pool B.

This process happens every few weeks.

The user always enters:

http://abc.de/X or http://abc.de/Y etc…

With a GET query I can read from a node in a pool, which software version has this node:

Example of a CURL query:

rdexec 1 curl --user user: password http://192.168.1.1/info

And the output is something like:

{
   "build": {
   "version": "20001.0.1",

        I hope it is not too messed up now ;)

Regards Manuel

1
Comment made 10-May-2018 by youssef 3608

Hello Manuel,

I'am sorry for te delate I was off :-). So you can use sideband connections:

https://devcentral.f5.com/wiki/iRules.SIDEBAND.ashx

Using this command (1.1.1.1 will be your backend. just be carefull, sideband working only in http:

connect -timeout 1000 -idle 30 -status conn_status 12.1.1.1:80

So I write your an Irule that allow you to retrieve version from backend node. I have not tested it but you have all elements that allow you to go ahead. Below Irule you need:

when HTTP_REQUEST {

# following code allow you to connect to your backend (1.1.1.1 1.1.1.1 will be your backend server in the pool)

if {[catch {connect -timeout 1000 -idle 30 -status conn_status 1.1.1.1:80} conn_id] == 0 && $conn_id ne ""}{
    log local0. "Connect returns: $conn_id and conn status: $conn_status"
} else {
    log local0. "Connection could not be established to backend node"
}

# we set var tha we will send to backend, you can use post, get put as you want (mybackend_hostname.com will be the backend hostname)

set data_validate "GET /info HTTP/1.1\r\nHost: mybackend_hostname.com\r\nConnection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36\r\nAccept-Language: fr,en;q=0.9\r\n\r\n"

# we sent date

set send_bytes [send -timeout 1000 -status send_status $conn_id $data_validate]
log local0. "AAA Sent $send_bytes with status $send_status"

# we receive data

set recv_data [recv -timeout 1000 $conn_id]
log local0. "1 - ([string length $recv_data]): $recv_data"

#retrieve version info from response
regexp {.*\"sourceGuid\":[^\"]+\"([^\"]+)\"} $recv_data -> version
log local0. "Node version $version"

}

Let me now if you need additional help in order to finalize your irule.

1
Comment made 14-May-2018 by youssef 3608

Hello Manuel,

have you been able to test my irule?

regards

0

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

I may not have fully understood but here is a simple iRule I've put together which may work, or at least give you an idea of where to go next. Unfortunately there is no why to interrogate the result of a health monitor by an iRule but you can can determine if you have active members - which is reliant on the monitor.

From what I understand, incoming requests will have the version number in the URI and from that you want to dynamically select the pool or pool member.

If you have a one to one relationship between pool names and version you can dynamically select the pool based on URI - you will however have to maintain a different pool for every new version.

when HTTP_REQUEST {

    set defaultPool "MY_DEFAULT_POOL_NAME"
    # use getfield to pick 'field1'of the URI https://host.com/field1/field2
    set dynamicPool [getfield [HTTP::uri] "/" 2]
    log local0. "Pool: $dynamicPool derived from URI"

    if {$dynamicPool ne ""} {
        # place commands using dynamicPool in catch statement
        # this will silently catch the TCL error in the event 
        # the pool doesn't exist
        if {[catch {
            if {[active_members $dynamicPool] > 0} {
                log local0. "load balancing to pool: $dynamicPool"
                pool $dynamicPool
            }
        } catchErr ]} {
            # select default pool if dynamicPool doesn't exist
            log local0. "unable to select pool based on URI, will use default  - error: $catchErr'"
            pool $defaultPool
        }
    } else {
        log local0. "Error - pool value empty, setting to default"
        pool $defaultPool
    }

}

Please note this iRule has only tested for syntax errors

0
Comments on this Answer
Comment made 09-May-2018 by eLeCtRoN 251

Thank you for that, this is the half what I need, but the main point would be how can I put the curl query to get the version info in the iRule and how can I compare the result of the query with the URL string. Thats my main problem, pleas read my last comment there is discriped what I excactly need !

THX Manuel

0
Comment made 09-May-2018 by Lee Sutcliffe 2772

I'm afraid that isn't possible using standard iRules. As I've mentioned, TCL based iRules cannot interrogate the status of a monitor. If you have pools with appropriate monitors, i.e. ones that check for the version, you won't need to compare it against the URI as the monitor will mark down any members that don't return the correct version.

You could look to use iRules LX which can make an outbound HTTP call (no need for a cURL monitor), return the version (using JSON.parse) and pass it back to standard iRules to compare against the URI.

This could however add quite a bit of latency to your application as you'll need the server to respond before traffic can be forwarded to the correct pool/member

0
Comment made 10-May-2018 by youssef 3608

Hi Guys,

it's possible (I have already done it several times), I am writing an Irule for Manuel...

Regards

0
Comment made 10-May-2018 by Lee Sutcliffe 2772

Hey youssef, I think you've misinterpreted my reply, iRules cannot directly query a configured health monitor but as you've described you can simulate a monitor with a side bind connection and parse the response, which is the same principle I described using iRules LX - to make an outbound call.

I'd definitely look to using iRules LX if possible as it's much simpler than using sideband

0
Comment made 10-May-2018 by youssef 3608

Hello.

Thank you for your feedback. I just understood what you meant ... I had not read everything :-) I am totally agree with you.

Regards

0
Comment made 10-May-2018 by eLeCtRoN 251

Hey MrPlastic,

I want not with the iRule ask a health monitor "how is your status, version" I want with the iRule check which version it is ! But what I know now is, it is not possible to make a curl inside the iRule? Hmm and iRule LX I never herad about that.

Regard

0
Comment made 11-May-2018 by youssef 3608

Hi.

Check my Irule above. It respond to your need. You can do a get or post (like curl) using sideband.

Regards

0