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

Filter by:
  • Solution
  • Technology
Clear all filters
Answers

Create a node based on an event

From my research I believe what I need is an iCall. But as per my other DevCentral post I'm not sure how to actually implement an iCall: HowTo: iCall Question

The task: An HTTP request has the fqdn of a node in the URI. If the node exist forward the request to the node but if the node doesn't exist create an fqdn node and then forward the request.

My thoughts: In an iRule extract node's fqdn from the HTTP request (simple enough). Then with a mixture of iRule syntax and iStats/iCall compare fqdn with the current nodes in a particular pool. If it doesn't exist use iCall to create an fqdn node, add it to the pool and send it the request. Is this possible with iCall? If yes, what would the syntax be?

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hey Ottleydamian,

As I already said in my previous post, iCall is unfortunately not the right choice for your scenario.

The problem with iCall in its current form is, that you can't syncronouly trigger an iCall script out of an iRule, while passing parameters/variables to the script execution and to get return information back once the script is executed.

iCall is basically an asyncronouly operating framework which can trigger based on time, log events and ISTATS statistic counters. iCall has some awesome usecases, but in your specific scenario it would be a rather poor choice:

  • Triggering iCall scripts out of an iRule via iRule generated log-lines does not support to pass parameters based on dynamic information found in the log line itself (e.g. which NODE to add?). The executed iCall script would need to read the entire log file to begin with and extract the NODE information out of the individual log lines that may have triggered this script. You would need to implement a custom machanism to track which log lines have already been processed by previous iCall executions and which are outstanding. Kind of nightmare...
  • Triggering iCall scripts out of an iRule via ISTATS counter values adds unfortunately some delay till ISTATS collects and updates the counters (highly asynchronous) and you get no response back when the node has been added. So the iRule would need to HOLD the ongoing HTTP request and continiously check if the iCall script has already been added the pool members. In addition, you would be forced to implement some queuing logic, to support concurrent client side requests for new node objects. This is way to complex...

As I already said, it's far more elegant to make a syncronous SIDEBAND request to the REST-API and execute a TMSH script, pass the NODE info via additional parameters, wait for the REST-API response and evaluate the return'ed information.

PoC for changing DATA-GROUPS via TMSH Scripts out of an iRule via REST-API calls. https://devcentral.f5.com/questions/write-into-internal-data-group-from-irule-50597

This may be usefull if you want to execute BASH commands (including native TMSH commands) out of an iRule via REST-API calls. https://devcentral.f5.com/questions/running-bash-commands-via-rest-api-51527

Cheers, Kai

0
Comments on this Answer
Comment made 1 month ago by ottleydamian 84

Sweet thanks!

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hi ottleydamian,

dont think iCall would be a good choice for your requirement.

ISTAT based triggers adding some (unpredictable) latency and LOG based triggers wont be able to pass the entire log-line (including the requested HOSTHEADER) to your iCall scripts.

It would be far more stable and elegant to SIDEBAND out of your iRule to F5's REST-API and create a new pool member or to use DevCentrals "Action On Log" contribution (https://devcentral.f5.com/codeshare?sid=430) to automate the pool member creation.

Beside of this, what is the purpose of having those pool members in place? You could also perform a a simple DNS lookup (after visiting DNS-Caches) within your iRule and then forward the traffic based on the DNS responses.

when HTTP_REQUEST {
    # Extract the HOSTNAME value...
    set fqdn [URI::query [HTTP::uri] hostname]
    # You may want to add some additional tests to make sure the passed HOSTNAME values are legit!!!!
    if { $fqdn ne "" } then {
        if { [set resolved_ip [table lookup "dns_cache_$fqdn"]] ne "" } then {
            # Found a cached DNS response...    
            node $resolved_ip
        } else {    
            # Need to DNS resolve the IP address
            if { [set resolved_ip [lindex [RESOLV::lookup @8.8.8.8%1 -a $fqdn] 0]] ne "" } then {
                # Found an IP address. Updating DNS cache (for 60 sec) and forwarding the request to the just resolved IP.
                table set "dns_cache_$fqdn" $resolved_ip indef 60
                node $resolved_ip
            } else {
                # HOST not found...
                HTTP::respond 200 content "HOST not found..." "Content-type" "text/html"
            }
        }
    } else {
        # Empty hostname param...
        HTTP::respond 200 content "Empty hostname value..." "Content-type" "text/html"  
    }
}

Cheers, Kai

0
Comments on this Answer
Comment made 1 month ago by Jason Rahm

odd, this just showed up, didn't see it when I responded!

0
Comment made 1 month ago by ottleydamian 84

Thanks, only as you mentioned it I realized that I'm not don't really need to monitor the node so all I have to do is pass the info along.

0
Comment made 1 month ago by Kai Wilke 6860

@Jason: I did run into identical problems in the past. It happens but luckily not that often :-)

Glad to see you came up with an identical idea for this request. Compare the differences of our iRules and think abount that DNS-Cache difference to offload the "Per-HTTP-Request" DNS lookups. Its worth the additional lines of code.

Cheers, Kai

1
Comment made 1 month ago by Jason Rahm

you were far more thorough with yours! I was just stubbing out an approach to take, but I agree wholeheartedly that caching that is a wise idea.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

if the goal is to add the node to a pool, then yes, you'll need something like iCall to do that. If you just want to forward the request to the node and not have BIG-IP "manage" that node as a pool member with health monitors, then you can just do that straight up in an iRule. Assuming you are handling the fqdn extraction from the uri, a header, or the payload, it's pretty basic:

when RULE_INIT {
  set static::ldns "x.x.x.x"
}

when HTTP_REQUEST {
  set node_fqdn "your code to get fqdn here"
  set node_ip [RESOLV::lookup @$static::ldns -a $node_fqdn]
  if {$node_ip eq ""}{
    # didn't resolv, send to default pool?
  } else {
      # multiple ip's possibly returned, this covers string and list scenario
      node [lindex $node_ip 0]
  }
}
0
Comments on this Answer
Comment made 1 month ago by Jason Rahm

let me know how you want BIG-IP to relate the node. Passively with no visibility into node behaviors and load, or actively with a configured BIG-IP object.

I'd caution that allowing object-level configuration control via web requests outside a normal process is rare and high risk, and while possible, should probably be avoided.

0
Comment made 1 month ago by ottleydamian 84

As both you and Kai Wilke have made me think about it I don't need to monitor the node so in theory I could just send the request straight to it.

So just for curiosity, if I had to create the node and add it to a pool with a monitor. I would have had to make the iRule create a log message (alert). Then have iCall read the alert and do all the other requirements?

0
Comment made 1 month ago by Kai Wilke 6860

@Ottleydamian: See my previous and latest response to satisfy your curiosity... ;-)

Cheers, Kai

0