Wednesday, April 9, 2008

Expect-ing some changes

We recently put a process in place to monitor the configuration of our fibre channel switches for unauthorized changes. Definitely a good idea, however it was potentially a very tedious process. The initial plan went something like this:
  • login to a switch
  • run configupload, sending the config to an ftp server
  • pore over the config, comparing it to the "gold" copy
  • repeat for the other 3 switches
My general philosophy is to automate anything I have to do repeatedly, so this was an unacceptable plan (even though I wasn't going to be doing the review -- it was the principle). The problem was that the switches are configured to only allow ssh logins, and we couldn't use our normal ssh key to login to them without providing a password (vendor box that doesn't allow that change). Enter expect.

Expect is a tool for "programmed dialogue with interactive programs." In our case that means supplying passwords to programs (ssh) that prompt for them. The new plan looks something more like this:
  • write two scripts
    • one that does a login to a switch and a configupload from that switch
    • one that iterates over the 4 switch names, runs the other script for each, and then runs diff to compare this config to the previous one, reporting on changes
  • take a vacation
I much prefer that plan.

Here are the scripts. I've pulled comments from them to shorten this post a bit, and changed the names to protect the guilty. The first of those scripts (the one that runs configupload):

#!/opt/sfw/bin/expect
spawn /usr/bin/ssh -l root [lindex $argv 0]
expect "password"
send "XXXXXXXXXX\r"
expect "root>"
send "configupload -p scp HOSTNAME,USERNAME,/data/switch_config/[lindex $argv 1]\r"
expect "root>"
send "exit\r"
expect "logout"
exit 0


and here's the second one that calls the expect script above:

#!/usr/bin/bash
DATE=`/usr/bin/date +%m%y`
for i in switch1a switch2a switch1b switch2b; do
/usr/local/bin/switch_backup.exp $i $i.$DATE
echo Switch comparision for $i >> /tmp/$$.tmp
echo >> /tmp/$$.tmp
echo >> /tmp/$$.tmp
/usr/bin/diff /data/switch_config/${i}_baseline /data/switch_config/$i.$DATE >> /tmp/$$.tmp
echo >> /tmp/$$.tmp
echo >> /tmp/$$.tmp
/usr/bin/mv /data/switch_config/$i.$DATE /data/switch_config/${i}_baseline
done
/usr/bin/cat /tmp/$$.tmp |/usr/bin/mailx -s "switch comparison on `/usr/bin/date +%m/%d/%Y`" mygroup@mycompany.com
/usr/bin/rm /tmp/$$.tmp


Now we just have to look at an email that only contains the changes (and accepted changes don't continue to show up -- this config becomes the baseline for the next compare).

2 comments:

Anonymous said...

Love your general philosophy, any chance you automate laundry, dish washing and all that for us?

John McDevitt said...

Easy:

while (clothes_are_dirty) {
select (clothes_color)
when (dark) {
set temp=cold
when (white) {
set temp=hot
end_select
set second_rinse = true
end_while

Now you just need a runtime for that script. May I suggest your husband?

counter free hit invisible