Export Virtual Server Configuration in CSV - tmsh cli script

Problem this snippet solves:

This is a simple cli script used to collect all the virtuals name, its VIP details, Pool names, members, all Profiles, Irules, persistence associated to each, in all partitions. A sample output would be like below,

 One can customize the code to extract other fields available too. The same logic can be allowed to pull information's from profiles stats, certificates etc.

 

Update: 5th Oct 2020

 

Added Pool members capture in the code. After the Pool-Name, Pool-Members column will be found.

If a pool does not have members - field not present: "members" will shown in the respective Pool-Members column.

If a pool itself is not bound to the VS, then Pool-Name, Pool-Members will have none in the respective columns.

 

Update: 21st Jan 2021

 

Added logic to look for multiple partitions & collect configs

 

Update: 12th Feb 2021

 

Added logic to add persistence to sheet.

 

Update: 26th May 2021

 

Added logic to add state & status to sheet.

 

Update: 24th Oct 2023

Added logic to add hostname, Pool Status, Total-Connections & Current-Connections.

Note: The codeshare has multiple version, use the latest version alone. The reason to keep the other versions is for end users to understand & compare, thus helping them to modify to their own requirements. Hope it helps.

 

How to use this snippet:

Login to the LTM, create your script by running the below commands and paste the code provided in snippet

 

tmsh create cli script virtual-details

 

So when you list it, it should look something like below,

 

[admin@labltm:Active:Standalone] ~ # tmsh list cli script virtual-details
cli script virtual-details {
proc script::run {} {
  puts "Virtual Server,Destination,Pool-Name,Profiles,Rules"
  foreach { obj } [tmsh::get_config ltm virtual all-properties] {
    set profiles [tmsh::get_field_value $obj "profiles"]
    set remprof [regsub -all {\n} [regsub -all "  context" [join $profiles "\n"] "context"] " "]
    set profilelist [regsub -all "profiles " $remprof ""]
    puts "[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],[tmsh::get_field_value $obj "pool"],$profilelist,[tmsh::get_field_value $obj "rules"]"
  }
}
  total-signing-status not-all-signed
}
[admin@labltm:Active:Standalone] ~ #

 

 

And you can run the script like below,

tmsh run cli script virtual-details > /var/tmp/virtual-details.csv

 

And get the output from the saved file,

cat /var/tmp/virtual-details.csv

 

Old Codes:

cli script virtual-details {
proc script::run {} {
    puts "Virtual Server,Destination,Pool-Name,Profiles,Rules"
    foreach { obj } [tmsh::get_config ltm virtual all-properties] {
        set profiles [tmsh::get_field_value $obj "profiles"]
        set remprof [regsub -all {\n} [regsub -all  "    context" [join $profiles "\n"] "context"] " "]
        set profilelist [regsub -all "profiles " $remprof ""]
        puts "[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],[tmsh::get_field_value $obj "pool"],$profilelist,[tmsh::get_field_value $obj "rules"]"
    }
}
    total-signing-status not-all-signed
}

###===================================================
###2.0
###UPDATED CODE BELOW
### DO NOT MIX ABOVE CODE & BELOW CODE TOGETHER
###===================================================

cli script virtual-details {
proc script::run {} {
    puts "Virtual Server,Destination,Pool-Name,Pool-Members,Profiles,Rules"
    foreach { obj } [tmsh::get_config ltm virtual all-properties] {
        set poolname [tmsh::get_field_value $obj "pool"]
        set profiles [tmsh::get_field_value $obj "profiles"]
        set remprof [regsub -all {\n} [regsub -all  "    context" [join $profiles "\n"] "context"] " "]
        set profilelist [regsub -all "profiles " $remprof ""]
        if { $poolname != "none" }{
            set poolconfig [tmsh::get_config /ltm pool $poolname]
            foreach poolinfo $poolconfig {
                if { [catch { set member_name [tmsh::get_field_value $poolinfo "members" ]} err] } {
                    set pool_member $err
                    puts "[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"]"
                } else {
                    set pool_member ""
                    set member_name [tmsh::get_field_value $poolinfo "members" ]
                    foreach member $member_name {
                        append pool_member "[lindex $member 1] "
                    }
                    puts "[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"]"
                }
            }
        } else {
                    puts "[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,none,$profilelist,[tmsh::get_field_value $obj "rules"]"
                            }
    }
}
    total-signing-status not-all-signed
}


###===================================================
### Version 3.0
### UPDATED CODE BELOW FOR MULTIPLE PARTITION 
### DO NOT MIX ABOVE CODE & BELOW CODE TOGETHER
###===================================================
cli script virtual-details {
proc script::run {} {
    puts "Partition,Virtual Server,Destination,Pool-Name,Pool-Members,Profiles,Rules"
    foreach all_partitions [tmsh::get_config auth partition] {
        set partition "[lindex [split $all_partitions " "] 2]"
        tmsh::cd /$partition
        foreach { obj } [tmsh::get_config ltm virtual all-properties] {
            set poolname [tmsh::get_field_value $obj "pool"]
            set profiles [tmsh::get_field_value $obj "profiles"]
            set remprof [regsub -all {\n} [regsub -all  "    context" [join $profiles "\n"] "context"] " "]
            set profilelist [regsub -all "profiles " $remprof ""]
            if { $poolname != "none" }{
                set poolconfig [tmsh::get_config /ltm pool $poolname]
                foreach poolinfo $poolconfig {
                    if { [catch { set member_name [tmsh::get_field_value $poolinfo "members" ]} err] } {
                        set pool_member $err
                        puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"]"
                    } else {
                        set pool_member ""
                        set member_name [tmsh::get_field_value $poolinfo "members" ]
                        foreach member $member_name {
                            append pool_member "[lindex $member 1] "
                        }
                        puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"]"
                    }
                }
            } else {
                puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,none,$profilelist,[tmsh::get_field_value $obj "rules"]"
            }
        }
    }
}
    total-signing-status not-all-signed
}

###===================================================
### Version 4.0
### UPDATED CODE BELOW FOR CAPTURING PERSISTENCE
### DO NOT MIX ABOVE CODE & BELOW CODE TOGETHER
###===================================================
cli script virtual-details {
proc script::run {} {
    puts "Partition,Virtual Server,Destination,Pool-Name,Pool-Members,Profiles,Rules,Persist"
    foreach all_partitions [tmsh::get_config auth partition] {
        set partition "[lindex [split $all_partitions " "] 2]"
        tmsh::cd /$partition
        foreach { obj } [tmsh::get_config ltm virtual all-properties] {
            set poolname [tmsh::get_field_value $obj "pool"]
            set profiles [tmsh::get_field_value $obj "profiles"]
            set remprof [regsub -all {\n} [regsub -all  "    context" [join $profiles "\n"] "context"] " "]
            set profilelist [regsub -all "profiles " $remprof ""]
			set persist [lindex [lindex [tmsh::get_field_value $obj "persist"] 0] 1]
			if { $poolname != "none" }{
                set poolconfig [tmsh::get_config /ltm pool $poolname]
                foreach poolinfo $poolconfig {
                    if { [catch { set member_name [tmsh::get_field_value $poolinfo "members" ]} err] } {
                        set pool_member $err
                        puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"],$persist"
                    } else {
                        set pool_member ""
                        set member_name [tmsh::get_field_value $poolinfo "members" ]
                        foreach member $member_name {
                            append pool_member "[lindex $member 1] "
                        }
                        puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"],$persist"
                    }
                }
            } else {
                puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,none,$profilelist,[tmsh::get_field_value $obj "rules"],$persist"
            }
        }
    }
}
    total-signing-status not-all-signed
}

###===================================================
### 5.0
### UPDATED CODE BELOW
### DO NOT MIX ABOVE CODE & BELOW CODE TOGETHER
###===================================================
cli script virtual-details {
proc script::run {} {
puts "Partition,Virtual Server,Destination,Pool-Name,Pool-Members,Profiles,Rules,Persist,Status,State"
foreach all_partitions [tmsh::get_config auth partition] {
set partition "[lindex [split $all_partitions " "] 2]"
tmsh::cd /$partition
foreach { obj } [tmsh::get_config ltm virtual all-properties] {
foreach { status } [tmsh::get_status ltm virtual [tmsh::get_name $obj]] {
set vipstatus [tmsh::get_field_value $status "status.availability-state"]
set vipstate [tmsh::get_field_value $status "status.enabled-state"]
}
set poolname [tmsh::get_field_value $obj "pool"]
set profiles [tmsh::get_field_value $obj "profiles"]
set remprof [regsub -all {\n} [regsub -all  "    context" [join $profiles "\n"] "context"] " "]
set profilelist [regsub -all "profiles " $remprof ""]
set persist [lindex [lindex [tmsh::get_field_value $obj "persist"] 0] 1]
if { $poolname != "none" }{
set poolconfig [tmsh::get_config /ltm pool $poolname]
foreach poolinfo $poolconfig {
if { [catch { set member_name [tmsh::get_field_value $poolinfo "members" ]} err] } {
set pool_member $err
puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"],$persist,$vipstatus,$vipstate"
} else {
set pool_member ""
set member_name [tmsh::get_field_value $poolinfo "members" ]
foreach member $member_name {
append pool_member "[lindex $member 1] "
}
puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"],$persist,$vipstatus,$vipstate"
}
}
} else {
puts "$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,none,$profilelist,[tmsh::get_field_value $obj "rules"],$persist,$vipstatus,$vipstate"
}
}
}
}
total-signing-status not-all-signed
}

Latest Code:

 

cli script virtual-details {
proc script::run {} {
set hostconf [tmsh::get_config /sys global-settings hostname]
set hostname [tmsh::get_field_value [lindex $hostconf 0] hostname]
puts "Hostname,Partition,Virtual Server,Destination,Pool-Name,Pool-Status,Pool-Members,Profiles,Rules,Persist,Status,State,Total-Conn,Current-Conn"
foreach all_partitions [tmsh::get_config auth partition] {
set partition "[lindex [split $all_partitions " "] 2]"
tmsh::cd /$partition
foreach { obj } [tmsh::get_config ltm virtual all-properties] {
foreach { status } [tmsh::get_status ltm virtual [tmsh::get_name $obj]] {
set vipstatus [tmsh::get_field_value $status "status.availability-state"]
set vipstate [tmsh::get_field_value $status "status.enabled-state"]
set total_conn [tmsh::get_field_value $status "clientside.tot-conns"]
set curr_conn [tmsh::get_field_value $status "clientside.cur-conns"]
}
set poolname [tmsh::get_field_value $obj "pool"]
set profiles [tmsh::get_field_value $obj "profiles"]
set remprof [regsub -all {\n} [regsub -all  "    context" [join $profiles "\n"] "context"] " "]
set profilelist [regsub -all "profiles " $remprof ""]
set persist [lindex [lindex [tmsh::get_field_value $obj "persist"] 0] 1]
if { $poolname != "none" }{
foreach { p_status } [tmsh::get_status ltm pool $poolname] {
set pool_status [tmsh::get_field_value $p_status "status.availability-state"]
}
set poolconfig [tmsh::get_config /ltm pool $poolname]
foreach poolinfo $poolconfig {
if { [catch { set member_name [tmsh::get_field_value $poolinfo "members" ]} err] } {
set pool_member $err
puts "$hostname,$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_status,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"],$persist,$vipstatus,$vipstate,$total_conn,$curr_conn"
} else {
set pool_member ""
set member_name [tmsh::get_field_value $poolinfo "members" ]
foreach member $member_name {
append pool_member "[lindex $member 1] "
}
puts "$hostname,$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,$pool_status,$pool_member,$profilelist,[tmsh::get_field_value $obj "rules"],$persist,$vipstatus,$vipstate,$total_conn,$curr_conn"
}
}
} else {
puts "$hostname,$partition,[tmsh::get_name $obj],[tmsh::get_field_value $obj "destination"],$poolname,none,none,$profilelist,[tmsh::get_field_value $obj "rules"],$persist,$vipstatus,$vipstate,$total_conn,$curr_conn"
}
}
}
}
}

 

 

Tested this on version:

13.0

 

Updated Oct 24, 2023
Version 2.0