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