iApp Implementation v11.4¶
Decision-making arrays and the iapp:: namespace package are two v11.4
enhancements described in this brief.
iApp Tcl on BIG-IP v11.4¶
A number of changes and enhancements were made to the suite of
F5-supported iApps in the v11.4 release. All v11.4 templates share
common code from the v11.4 iapp:: namespace, and obtain that code from
Tcl packages rather than cli scripts. In addition, all v11.4 templates
and ESD templates released after December 2012 use new coding
practices, such as array-based decision trees. This article describes
these changes and how they affect iApp users.
Decision-Making with Tcl Arrays¶
Much of what an iApp does is translation. It obtains a set of
presentation data, forms it into command language instructions, and
delivers the instructions to the operating system. The hallmark of a
well-written iApp, therefore, is its ability to derive a correct and
useful TMOS configuration from a minimum set of easily-understood user
inputs. Due to this common purpose, iApps typically share the need for
the decision-making aspects of the programming language more than,
say, floating-point operations. The obvious mechanism for
decision-making in Tcl, as with most languages, is the “if-then”
statement. These statements are easily understood when isolated, but
become confusing when deeply nested or embracing long, complex
expressions. An alternative in these situations is to use arrays. The
concept is two-fold. First, reduce your decision into a few equations
that have binary or otherwise very limited outcomes, storing the
results as key variables. Second, build an array of executable
statements paired with key value combinations. The following example
illustrates the basic idea.
“if-then” decision
if { $feel == “drowsy” } {
if { $taste == “sweet” } {
puts “Coffee with sugar, please”
} else {
puts “Coffee black, please”
}
} else {
puts “Just water, thanks”
}
}
array-based decision
# array keys: $feel,$taste
array set coffee {
drowsy,sweet {[puts “Coffee with sugar, please” ]}
drowsy,bitter {[puts “Coffee black, please” ]}
alert,sweet {[puts “Just water, thanks” ]}
alert,bitter {[puts “Just water, thanks” ]}
}
subst $coffee($feel,$taste)
This example shows how an array obviates the decision paths, but this
is both a strength and a weakness. The weakness is that all possible
keys must be declared, or you risk execution failure. The PME group
partially solved this problem by writing a “subst” statement wrapper
that allows a default outcome. This proc, called “substa,” is included
in the v11.4 release. The following example illustrates how its use
differs from the native Tcl “subst,” simplifying the array and
preventing potential key non-existence errors.
# array keys: $feel,$taste
array set coffee {
drowsy,sweet {[puts “Coffee with sugar, please” ]}
drowsy,bitter {[puts “Coffee black, please” ]}
* {[puts “Just water, thanks” ]}
}
iapp::substa coffee($feel,$taste)
Below is a typical use of array-based decision-making for virtual
server configuration. It uses pre-calculated binary keys to choose the
correct port, and create a second virtual for redirect if required.
# VIRTUAL SERVERS
set do_client_ssl [expr { [iapp::is ::ssl__offload yes] }]
set do_redirect [expr { [iapp::is ::pool__redirect_to_https yes] }]
# array keys: $do_client_ssl,$do_redirect
array set vs_arr {
1,1 { [iapp::conf create ltm virtual my_vs \
destination ${::pool__addr}:443 \
pool mypool \
profiles replace-all-with \{ http \}] \
[iapp::conf create ltm virtual my_redir_vs \
destination ${::pool__addr}:80 \
pool none \
profiles replace-all-with \{ http \}] }
1,0 { [iapp::conf create ltm virtual my_vs \
destination ${::pool__addr}:443 \
pool mypool \
profiles replace-all-with \{ http \}] }
* { [iapp::conf create ltm virtual my_vs \
destination ${::pool__addr}:80 \
pool mypool \
profiles replace-all-with \{ http \}] }
}
iapp::substa vs_arr($do_client_ssl,$do_redirect)
Note that Tcl does not explicitly support multidimensional arrays, but
any string may be used as a key. In the example above, the key “1,1”
is a 3-character key in a one-dimensional array, not a numeric key in
a 2-dimensional array. Inserting whitespace (“1, 1”) will break the
assignment statement. Further discussion of Tcl arrays may be found at
http://wiki.tcl.tk/1032. It is also important to understand that these
decision-making arrays may be, and often are, nested. The following
example shows an array that generates an ltm pool (itself a product of
arrays) being used in the virtual server array from the prior example.
# POOL
set new_pool [iapp::is ::pool__pool_to_use $CREATE_NEW_ANSWER]
# array keys: $new_pool,$do_server_ssl
array set pool_arr {
1,1 { pool [iapp::conf create ltm pool my_pool \
[iapp::substa pool_ramp_pga_arr($advanced,$do_slow_ramp,$do_pga)] \
[iapp::substa pool_lb_queue_arr($advanced,$tcp_queuing)] \
[iapp::substa monitor_arr($do_monitor,$new_monitor,$advanced)] \
[iapp::pool_members $::pool__members]] }
1,0 { pool [iapp::conf create ltm pool my_pool \
[iapp::substa pool_ramp_pga_arr($advanced,$do_slow_ramp,$do_pga)] \
[iapp::substa pool_lb_queue_arr($advanced,$tcp_queuing)] \
[iapp::substa monitor_arr($do_monitor,$new_monitor,$advanced)] \
[iapp::pool_members $::pool__members]] }
0,1 { pool $::pool__pool_to_use }
0,0 { pool $::pool__pool_to_use }
}
# VIRTUAL SERVERS
set do_client_ssl [expr { [iapp::is ::ssl__offload yes] }]
set do_redirect [expr { [iapp::is ::pool__redirect_to_https yes] }]
# array keys: $do_client_ssl,$do_redirect
array set vs_arr {
1,1 { [iapp::conf create ltm virtual my_vs \
destination ${::pool__addr}:443 \
pool [iapp::substa $pool_arr($new_pool,$do_server_ssl)] \
profiles replace-all-with \{ http \}] \
[iapp::conf create ltm virtual my_redir_vs \
destination ${::pool__addr}:80 \
pool none \
profiles replace-all-with \{ http \}] }
1,0 { [iapp::conf create ltm virtual my_vs \
destination ${::pool__addr}:443 \
pool [iapp::substa $pool_arr($new_pool,$do_server_ssl)] \
profiles replace-all-with \{ http \}] }
* { [iapp::conf create ltm virtual my_vs \
destination ${::pool__addr}:80 \
pool [iapp::substa $pool_arr($new_pool,$do_server_ssl)] \
profiles replace-all-with \{ http \}] }
}
iapp::substa vs_arr($do_client_ssl,$do_redirect)
The iapp_11_4_0 Tcl Package and iapp:: Namespace¶
In prior releases, common code has been stored in an F5-supported cli
script called “app_utils.” In v11.4, app_utils is still supported, but
F5-supported templates have been migrated to the “iapp_11_4_0” package
and logically protected within the “iapp::” namespace. Tcl packages
support versioning and occupy a smaller memory footprint than cli
scripts. Namespaces help to prevent conflicts between template code
and common code. There are syntactic differences between these
methods, but the end goal is achieved in both cases, i.e. multiple
templates are able to share common procedures. example use of cli
script in v11.3 tmsh::include “f5.app_utils” set provisioned
tmsh::run_proc f5.app_utils:get_provisioned
wam
example use of Tcl package in v11.4
package require iapp 1.0.0
set provisioned [iapp::get_provisioned wam -is]
In addition to the new location, the common code itself has undergone
a significant revision. Many of the v11.3 app_util functions have been
consolidated into a few generic procedures, while new procedures such
as “is” and “substa” have been included to support the v11.4
array-based programming style.
The BIG-IP API Reference documentation contains community-contributed content. F5 does not monitor or control community code contributions. We make no guarantees or warranties regarding the available code, and it may contain errors, defects, bugs, inaccuracies, or security vulnerabilities. Your access to and use of any code available in the BIG-IP API reference guides is solely at your own risk.