dns_auditer

Hello,

Here is a simple dns auditor, maps name -> ip and should work for other things scotty3 supports, BTW does any one have a patch to get the full SOA record back? The theory is simple you have 2 config files, list of dns servers to check and a csv file with 4 entries: dept tag, item to check, action, result. Ex: server_grp,www.xyz.com,address,123.123.123.123. What happens is that the check is preformed against each of the listed dns servers and checked for accuracy against the result. This is done by generating a tcl testsuite for the config files that you can execute at will. There are some ugly bits in it but it has proved useful.

anyway here is the code:

#!/opt/pkg/bin/tclsh8.4

package require cmdline
package require csv
package require fileutil

proc server_load { path file } {

    if {[catch {open $path/$file r} result]} {
        error "could not open file for reading : $result"
    }
    return [split [read $result ] \n]
}

proc items_load {path file} {
    set result [list]
    foreach line [server_load $path $file] {
        lappend result [csv::split $line ]
    }
    return $result
}


set options {
    {o.arg "out"      "Change the default out file location"}
    {d.arg "data"      "directory with data files"}
    {D.arg "servers"      "DNS server info file"}
    {C.arg "check.csv"      "Things to check file"}
}

set usage "{build|clean} \[options\] \n"

##::cmdline::getoptions argv $options $usage
## bug here with errors, probably my fault
array set params [::cmdline::getoptions argv $options $usage ]

#parray params
#puts "$argv\n"


set start "
    lappend auto_path /opt/local/lib
    package require Tnm
    package require tcltest

    namespace eval ::%s {
        namespace import ::tcltest::*
        namespace import ::Tnm::dns

   ## put dns server here format 'variable server ip'
"

set middle {
    test %s-%i.%i { %s: %s %s } -body {
        dns -server %s %s %s
    }  -result %s
}

set end "
    cleanupTests
}
"

set all.tcl {
#!/opt/pkg/bin/tclsh8.4

package require tcltest

::tcltest::configure -testdir %s/%s
eval ::tcltest::configure $argv
::tcltest::runAllTests

}

set tmp [server_load $params(d) $params(D) ]
set servers [list]
foreach line $tmp {
    if {[string length $line] >3 } {
        lappend servers $line
    }
}
set items [items_load $params(d) $params(C) ]

set i 1
array set j {}

foreach server $servers {
    #puts "server == $server\n"

    foreach row $items {
        if {[llength $row] < 2 } {
            continue
        }
        #puts "row:: $row\n"
        set owner [lindex $row 0]
        set item [lindex $row 1]
        set action [lindex $row 2]
        set result [lindex $row 3]

        if {[info exists bob($owner/$item)] != 1 } {
            set bob($owner/$item) [list]
            lappend bob($owner/$item) [format $start $item]
            #puts "$owner/$item new \n"
            set j($owner/$item) 1
         }

        lappend bob($owner/$item) [format "$middle" $item $i $j($owner/$item)\
                                   $server $action $item $server $action\
                                   $item $result  ]
        incr j($owner/$item)
    }
    incr i
    foreach name [array names j] {
    set j($name) 1
    }
}

array set group_dir {}

foreach row $items {
    if {[llength $row ] < 2 } {
        continue
    }
    set group_dir([lindex $row 0]) 1
}

catch {exec rm -rf $params(o) } xxy
#puts "$xxy"


::fileutil::writeFile $params(o)/all.tcl "[format ${all.tcl} [file dirname [file normalize [info script]]] $params(o) ]"
foreach name [array names group_dir] {
    ::fileutil::writeFile $params(o)/$name/all.tcl "[format ${all.tcl} [file dirname [file normalize [info script]]] $params(o)/$name ]"

}
foreach name [array names bob] {

    lappend bob($name) [format $end]
    ::fileutil::writeFile $params(o)/$name.test  "[join $bob($name) \n ]\n"
   # gets stdin
}

Now if you have gotten here you can see there is room for improvement, comments welcome