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