Forum Discussion
iApp variable scope
Hi all,
I'm writing my first iApp to automate deployment of a few virtual servers, nodes, pools and iRule data-groups
I have finished the presentation section and am now starting on the implementation. One issue that I'm having though is referencing variables assigned from the presentation within tmsh::create, tmsh:modify etc
I can read the variables back fine within the base iApp, for example I have the following:
puts "Adding SNAT data. $::private__privateAddr maps to $::public__publicAddr"
Which logs the following in scriptd.out:
Adding SNAT data. xxx.xxx.xxx.xxx maps to xxx.xxx.xxx.xxx
Where I run into the issue though is referencing the same variables in tmsh::modify.
For example I have the following:
proc tmsh_modify { args } {
set args [join $args]
puts "tmsh modify $args"
tmsh::modify $args
return [lindex $args [lsearch -glob $args "*_*"]]
}
puts "Adding SNAT data. $::private__privateAddr maps to $::public__publicAddr"
tmsh_modify { ltm data-group internal /Common/snat-map
records add {
$::private__privateAddr {
data $::public__publicAddr
}
}
}
This logs the following:
[root@ltm02-dev:Active:Changes Pending] config tail -f /var/tmp/scriptd.out -n0
Adding SNAT data. xxx.xxx.xxx.xxx maps to xxx.xxx.xxx.xxx
tmsh modify ltm data-group internal /Common/snat-map
records add {
$::private__privateAddr {
data $::public__publicAddr
}
}
So from this I can see the variables are being treated as normal strings. As expected this errors out on the iApp creation screen:
script did not successfully complete: ("$::private__privateAddr" invalid address
while executing
"tmsh::modify $args"
(procedure "tmsh_modify" line 4)
invoked from within
"tmsh_modify { ltm data-group internal /Common/snat-map
records add {
$::private__privateAddr {
data $::public__publicAddr
} ..." line:14)
I couldn't find any specific information on the scope of variables when used in this manner, perhaps it is just a simple issue of syntax.
I'd appreciate if someone can give me some guidance on this.
Thanks!
Scope is not the problem. Tcl treats anything inside curly braces as verbatim. Enclosed strings in quotes and escape each curly brace with a backslash.
tmsh_modify "ltm data-group internal /Common/snat-map records add { $::private__privateAddr { data $::public__publicAddr }}"
- Fred_Slater_856Historic F5 Account
Scope is not the problem. Tcl treats anything inside curly braces as verbatim. Enclosed strings in quotes and escape each curly brace with a backslash.
tmsh_modify "ltm data-group internal /Common/snat-map records add { $::private__privateAddr { data $::public__publicAddr }}"
- Fred_Slater_856Historic F5 AccountThis wiki is not displaying what I am typing. You must add a backslash before each curly brace above.
- Uber_Nathan_202NimbostratusThanks a lot Fred, all working now :)
- jojo83_271212Nimbostratus
Hi Fred! I've a similar questions:
I'm modifying an iApp in order to create an irule to assign to the vs.
the assignment is here { [iapp_conf create ltm virtual ${app}_vs \ destination [iapp_destination $::pool__addr $::pool__port] \ mask $mask \ $vs_params \ ip-protocol tcp \ mirror $mirror_action \ profiles replace-all-with { $tcp_profiles http } \ rules { iwf_test_irulebal iwf_$irulelog }] }
the irule are very simple
the first irule is with no variables
tmsh::create ltm rule iwf_$irulelog {
when HTTP_REQUEST { log local0. "No variables" } `
} the second irule need to balance on the pool created with the iapp, so i need to write it with variable statement and not with string
`iapp_conf create ltm rule iwf_test_irulebal { when HTTP_REQUEST { if { [HTTP::uri] starts_with "/portal${app}_pool" } { use pool ${app}_pool } else { TCP::close } } }
i've tried with \before the { but seems not works. also with ::global variable but not works.
In a classic BIG-IP environment without iapp the use of variable in irule works. how can i use the variable in an irule created with an iapp?
- Fred_Slater_856Historic F5 Account
I typically use string map.
set app "xyz" set irule [string map " $app" { when HTTP_REQUEST { if { [HTTP::uri] starts_with "/portal_pool" } { use pool _pool } else { TCP::close } } }] iapp::conf create ltm rule iwf_test_irulebal $irule
- jojo83_271212Nimbostratus
Hi Fred,
 
I tried your suggestion but I encountered some problem with the variable "Iwf_test_irulebal".
 
in the meantime I had solved this
 
set :: iapp_sn $ tmsh :: app_name set :: pool_irule $ {:: iapp_sn} _pool
 
set infile1 [open "/var/tmp/irule.tmp" "w" "0644"] puts $ infile1 "ltm rule /Common/$::iapp_sn.app/irule$::iapp_sn \ {" puts $ infile1 "app-service $ :: iapp_sn" puts $ infile1 "when HTTP_REQUEST \ {" puts $ infile1 "if \ {\ [HTTP :: uri ] starts_with \" / portal $ :: iapp_sn \ "} \ {" puts $ infile1 "use pool $ :: pool_irule }" puts $ infile1 "elseif \ {\ [HTTP :: uri ] starts_with \" / script $ :: iapp_sn \ "} \ {" puts $ infile1 "use pool $ :: pool_irule }" puts $ infile1 "else \ {" puts $ infile1 "TCP :: close" puts $ infile1 "}" puts $ infile1 "}" puts $ infile1 "}" close $ infile1
 
tmsh :: load sys config merge check file /var/tmp/irule.tmp
 
file delete "/var/tmp/irule.tmp"
 
set irulevs "/Common/$::iapp_sn.app/irule$::iapp_sn"
 
and it works.
 
but in the end I did as suggested by crodriguez.
 
https://devcentral.f5.com/s/feed/0D51T00006i7hIpSAI
 
thanks anyway Regards
 
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com