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

Filter by:
  • Solution
  • Technology
Answers

iControlREST replace iRule references on all virtual servers

I'm looking for a way to replace one iRule with another across all Virtual Servers on a given F5. The rule should preserve the order of the irules ie:

vs_example.com_HTTPS

irules before:

rule_some_exception
rule_old_irule
rule_catch_all

irules after:

rules_some_exception
rule_new_irule
rule_catch_all

This would run and change all virtual servers on the F5. I can do this with a config reload, but that's a minor outage. I'll post a sample script below. I'm looking for a way using the REST interface or something similar. Suggestions?

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Since the task requires search and manipulation of the returned JSON data, you should consider writing a script rather than combining a number of curl calls. A Python example code below should do the job.

from sys import argv
from f5.bigip import ManagementRoot
import urllib3

# Disable SNIMissingWarning and InsecurePlatformWarning
urllib3.disable_warnings()

nameOldRule = argv[1]
nameNewRule = argv[2]

mgmt = ManagementRoot('ltm1311', 'admin', 'admin')  # Change me

# Get me all the virtuals
virtualCollection = mgmt.tm.ltm.virtuals.get_collection()

for v in virtualCollection:                         # All the virtuals
    vsname = v.__dict__['name']                     # Get the virtual name

    try:
        oldRules = v.__dict__['rules']              # Check if it has any rules
    except KeyError:
        continue

    try:                                            # Check if it has the nameOldRule
        index = oldRules.index(nameOldRule)
    except ValueError:
        continue

    newRules = oldRules
    newRules[index] = nameNewRule                   # Replace nameOldRule > nameNewRule
    vs = mgmt.tm.ltm.virtuals.virtual.load(name=vsname)
    vs.update(rules=newRules)                       # Update the virtual
    print('Updated {}: {} > {}'.format(vsname, oldRules, newRules))

Specify the old and new rules in full path as the 1st and 2nd arguments to the program: e.g., ./ModifyRulesInVirtuals.py /Common/Rule2a /Common/Rule2b. It first gets all the virtuals on the box (GET /mgmt/tm/ltm/virtuals). Then, for each virtual, check if it has any rules (otherwise go to next virtual), check if has the old rule, then replace that element with the new one and put it back to the virtual (PATCH /mgmt/tm/ltm/virtual/<virtual>). The rules attached to a virtual is stored in a list (array), so they are ordered: The order of rules won't change.

See also F5 Python SDK Documentation.

1
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Here's a script to do it with a reload:

#!/bin/sh
# replaceirule.sh
# replace references to one irule with references to another
# Tim Riker <Tim@Rikers.org>

if [ -z "$1" -o -z "$2" ] ; then
        echo "Usage $0 oldrule newrule"
        exit -1
fi
tmsh save /sys config
sed -e "s~^\( *\)/Common/$1$~\1/Common/$2~g" \
 < /config/bigip.conf \
 > /config/bigip.conf.new
echo "# do this if /config/bigip.conf.new looks good"
echo "mv /config/bigip.conf.new /config/bigip.conf && tmsh load /sys config"
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Take a look at the iControl cheat sheet, there's an example on how to update the iRules applied to a virtual server.

iControl Cheat Sheet

curl -sku admin:admin  https://<host>/mgmt/tm/ltm/virtual/<vs> \
  -X PATCH -H "Content-Type: application/json" \

If the order of the iRules is important I would edit the iRules ensuring the events have an appropriate priority, this dictates the execution order. This way you do not need to worry about the order

iRule Priority

0
Comments on this Answer
Comment made 1 month ago by TimRiker 21

Yes, I read the example in the cheat sheet:

curl -sku admin:admin  https://<host>/mgmt/tm/ltm/virtual/<vs> \
  -X PATCH -H "Content-Type: application/json" \
  -d '{"rules": ["/Common/test1", "/Common/test2"] }'

I'd need to query each virtual host, looking for the rule I want to replace, edit the rules and then PATCH the host. I was hoping to find some same code that did something similar. It's good to have examples of the direct interface.

Something like this should work to get the existing rules:

curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs>?options=rules

Link with more samples: https://devcentral.f5.com/questions/i-need-rest-api-for-list-datagroup-and-check-the-irule-is-applied-to-which-vs

from which we find:

To list virtual server names:

curl -sk -u admin:admin -H "Content-Type: application/json" -X GET https://localhost/mgmt/tm/ltm/virtual?\$select=name | sed -r 's/$/\n/; s/,/$\n/g; s/(\[)/\1\n/g; s/(\])/\n]/g'

0