For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Custom reuseable iApp data profiles and other Generic useful procedures

Problem this snippet solves:

This library provides the methods for generically importing other service objects, a callback mechanism utilizing per object metadata that allows for dependancies to be correctly handled within iApps, a nice regexp get_items variant for grabbing objects with regex filters, and to generically import a table from the current service with multiple views of the data.

proc import_service { service name }
proc service_callback { }
proc import_table { table_local type } 

This proc allows you to import a local table in an iApp.

import_table { table type}

Table must be an APL table object such as $::sectionname_tablename

Types
ary – returns an array in "array set" form and is referenced $name(column__row#) and contains the value for that column__row#
comma – returns an array in "array set" form and is referenced $name(column,row#) and contains the value for that column,row#
names – returns a TCL list of the column names in the stored order – this is crucial for interpreting the "row" TCL lists referenced below
row – returns an array in "array set" form and is referenced $name(row#) and contains row# in a TCL list in the order of "names" list
Col – returns an array in "array set" form and is referenced $name(columnname) and contains columnname in a TCL list in the order of the rows 
Rowcol – returns an array in "array set" form and is referenced $name(row#) and contains row# in a TCL list of lists where each sub list is {columnname value}

IMPLEMENTATION CODE
    array set hostfile_table [tmsh::run_proc f5.ntr_utils:import_table { $::hostfile__hostfile comma }]
    puts "$hostfile_table(names,1)" 


APL CODE
    section hostfile {
        table hostfile {
            string hostname 
            choice record_type { "A", "AAAA" }
            string addr validator "IpAddress"
        }
    }
proc get_items_regexp { field_name field args }

Contributed by: m.earnhart

Code :

cli script f5.ntr_utils_devcentral {
proc import_service { service name } {
    tmsh::include "f5.meta_utils"
    tmsh::cd /Common
    set fullname ${tmsh::app_name}.app/${tmsh::app_name}
    set cmd "\"tmsh::modify sys application service $fullname execute-action definition\""
    set_service_description_meta ${service} ${fullname} ${cmd}
    set objs [lindex [tmsh::get_config sys application service ${service} one-line] 0]
    namespace eval ${name} {
        proc service_var { objs pre flag } {
            set name [namespace current]
            set parent_obj $pre
            set count 0
            foreach obj $objs {
                 if { ([expr ${count} % 2]) and ($flag eq 0)} {
                    variable $pre_obj $obj

                 } elseif { ([expr ${count} % 2]) and ($flag > 0)} {
                    variable ${parent_obj}__${pre_obj} $obj
                 }
                 if {([llength $obj] > 1) && ($pre_obj ne "column-names") && ($pre_obj ne "rows") } {
                    incr flag
                    ${name}::service_var $obj $pre_obj $flag
                    incr flag -1
                 }
                 set pre_obj $obj
                 incr count
            }
        }
        proc import_tables { tables } {
            set name [namespace current]
            set table_count 0
            foreach table $tables {
                set result ""
                # Only process the even elements
                if {![expr $table_count % 2]} {
                    set row_count 0
                    foreach row [set ${name}::${table}__rows] {
                        set column_count 0
                        foreach column [set ${name}::${table}__column-names] {
                            #puts "Set ${table}(${column}__${row_count}): [lindex [lindex $row 1] $column_count]"
                            lappend result ${column}__${row_count}
                            lappend result [lindex [lindex $row 1] $column_count]
                            lappend result ${column},${row_count}
                            lappend result [lindex [lindex $row 1] $column_count]
                            incr column_count
                        }
                        incr row_count
                    }
                    variable ${table}
                    array set ${table} ${result}
                }
                incr table_count
            }
        }
        proc import_variables { vars } {
            set var_count 0
            foreach var $vars {
                if {![expr $var_count % 2]} {
                    set varname $var
                } else {
                    variable ${varname} [lindex $var 1]
                }
                incr var_count
            }
        }
    }
    ${name}::service_var [lindex $objs 4] "" 0
    ${name}::import_tables [set ${name}::tables]
    ${name}::import_variables [set ${name}::variables]
}
proc service_callback { } {
    tmsh::include "f5.meta_utils"
    set name $tmsh::app_name
    set fullname ${name}.app/${name}
    tmsh::cd /Common
    catch { foreach service [get_service_description_meta $fullname] {
        tmsh::cd /Common
        eval [lindex ${service} 1]
    }
    }
}
proc import_table { table_local type } {
    set row_count 0
    array set row_result {}
    array set col_result {}
    array set rowcol_result {}
    foreach row ${table_local} {
        set element_count 0
        set names ""
        foreach element [split $row "\n"] {
            if { ($element_count > 0) && ($element_count < [expr [llength [split $row "\n"]] - 1])} {
                if { [llength $element] > 1 } {
                    set value "[lindex $element 1]"
                    set column "[lindex $element 0]"
                    lappend ary_result "${column}__${row_count}" 
                    lappend ary_result "${value}" 
                    lappend comma_result "${column},${row_count}" 
                    lappend comma_result "${value}" 
                    lappend row_result($row_count) ${value}
                    lappend col_result($column) ${value}
                    lappend rowcol_result($row_count) "[list $column ${value}]"
                    lappend names $column
                }
            }
            incr element_count
        }
        incr row_count
    }
    switch $type {
        row 
            {
                foreach row [array names row_result] {
                    lappend result $row
                    lappend result $row_result($row)
                }
                set final_result ${result}
            }
        col
            {
                foreach col [array names col_result] {
                    lappend result $col
                    lappend result $col_result($col)
                }
                set final_result ${result}
            }
        names
            {
                set final_result ${name}s
            }
        rowcol
            {
                foreach row [array names rowcol_result] {
                    lappend result $row
                    lappend result $rowcol_result($row)
                }
                set final_result ${result}
            }
        comma
            {
                set final_result $comma_result
            }
        ary
            {
                set final_result $ary_result
            }
        default
            {
                set final_result $ary_result
            }
    }
    return ${final_result}
}
proc get_items_regexp { field_name field args } {
    set results ""
    puts "args: $args"
    append args " recursive"
    set folder [tmsh::pwd]
    if { [catch {
        set objs [tmsh::get_config $args]
        foreach obj $objs {
            set name [tmsh::get_name $obj]
            puts "name: ${name}" 
            puts "obj: $objs"
            set field_value [tmsh::get_field_value $obj $field_name]
            puts "field_value: $field_value"
            puts "field: $field"
            if { [regexp "$field" $field_value] } {
                append results "$folder/"
                append results [format "%s\n" ${name}]
            }
        }

        if { $folder != "/Common" } {
            tmsh::cd "/Common"
            append objs [tmsh::get_config $args]
            tmsh::cd $folder
            foreach obj $objs {
                set name [tmsh::get_name $obj]
                set field_value [tmsh::get_field_value $obj $field_name]
                if { [regexp "$field" $field_value] } {
                    append results "/Common/"
                    append results [format "%s\n" ${name}]
                }
            }
        }
    } err] } {
        puts "Command failed: tmsh::get_config $args\n  $err"
        return ${results}
    }

    return ${results}
}
}
Published Mar 11, 2015
Version 1.0
No CommentsBe the first to comment