What could you do with your code in 20 Lines or Less?

That's the question we like to ask from, for, and of (feel free to insert your favorite preposition here) the DevCentral community, and every time we do, we go looking to find cool new examples that show just how flexible and powerful iRules and other F5 API code can be without getting in over your head. Thus was born the 20LoL (20 Lines or Less) series many moons ago. Over the years we've highlighted hundreds of iRules examples, and a growing number of iControl samples, all of which do downright cool things in less than 21 lines of code.

Deploy an iRule with the new F5 SDK

This time last month Lori posted an article announcing a new sdk for python. You might be thinking things like “but I love bigsuds, it’s awesome!” or if you are Joe, “python sucks,” but unlike bigsuds, which interacts with the SOAP interface on BIG-IP, the f5-common-python sdk interacts with the REST interface. This simplifies end user code tremendously as you don’t need to roll your own modules. For example, to take an iRule from a local file and deploy it to a range of BIG-IPs, it takes a scant few lines of code that doesn’t come near our 20 line limit.

from f5.bigip import BigIP

with open('proc.tcl', 'r') as irule:
    mycode = irule.read()
irule.close()

for i in range(1, 30):
    host = '172.16.%d.5' % i
    b = BigIP(host, 'admin', 'admin')
    try:
        newrule = b.ltm.rules.rule.create(name='proctest', partition='Common', apiAnonymous=mycode)
        print newrule.raw
    except Exception, e:
            print e

SP Issuer Extraction from APM SAML idP

APM doesn't expose any detail about the SAML SP Issuer when authentication requests hitting APM as an IdP during an SP initiated SAMLRequest. This iRule when applied to a SAML IdP enabled virtual server will extract the assertion request, decode it and present the SAML SP Issuer ID as the session variable %{session.saml.request.issuer} within APM. This comes in real handy when performing authorization of the resource and could help avoid having APM perform a TCP connection reset when a SAML resource isn't authorized.

when CLIENT_ACCEPTED {
    ACCESS::restrict_irule_events disable
}
when HTTP_REQUEST {
	if { [HTTP::path] equals "/saml/idp/profile/redirectorpost/sso" } {
		if { [HTTP::method] equals "POST" } {
			set content_length [HTTP::header value Content-Length]
			HTTP::collect $content_length
		}
	}
}
when HTTP_REQUEST_DATA {
	set payload_data [URI::decode [HTTP::payload]]
	if { $payload_data contains "SAMLRequest" } {
		set SAMLdata [b64decode [URI::query "?$payload_data" "SAMLRequest"]]
 		set SAML_Issuer_loc 	[string first "saml:issuer" [string tolower $SAMLdata]]
		set SAML_Issuer_start 	[expr {[string first ">" $SAMLdata $SAML_Issuer_loc] + 1}]
		set SAML_Issuer_end 	[expr {[string first "<" $SAMLdata $SAML_Issuer_start] - 1}]
		set SAML_Issuer 		[string range $SAMLdata $SAML_Issuer_start $SAML_Issuer_end]
		if { !([ACCESS::session sid] equals "" ) } {
			ACCESS::session data set session.saml.request.issuer $SAML_Issuer
		}
	}
}
when ACCESS_SESSION_STARTED {
	if { [info exists SAML_Issuer] } {
		ACCESS::session data set session.saml.request.issuer $SAML_Issuer
	}
}

Changing Narrow Scope

Ken B had a couple specific requirements for his scenario: Change the server and path from initial request, but retain the query. Sometimes the scale seems so much larger than it actually is, and once you get to a solution, like this one provided by Stanislas, you can really see the elegance and simplicity of iRules.

when HTTP_REQUEST {
    if {([HTTP::path] equals "/fubarpath/AMSDocViewer.asp") && ([HTTP::host] equals "server1")} {
        HTTP::respond 302 noserver Location "http://server2/apppath/ImageEnablingLauncher.aspx?[HTTP::query]"
    }
}

And there it is, another edition of 20 Lines or Less, the power of iRules on full display. Happy coding out there, and I look forward to seeing what excellent contributions might make the next edition!