send enable only as first command, fix cleanup
[dell-switch] / dell-switch.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4 use autodie;
5
6 use Net::OpenSSH;
7 use Data::Dump qw(dump);
8 use Time::HiRes qw(sleep);
9
10 our $login;
11 our $passwd;
12 our $debug = $ENV{DEBUG} || 0;
13
14 require 'config.pl';
15
16 #$Net::OpenSSH::debug = ~0;
17
18 my $ip = shift @ARGV || die "usage: $0 IP command[ command ...]\n";
19 my @commands = @ARGV;
20 @commands = <DATA> unless @commands;
21
22 warn "\n## ssh $ip\n";
23 my $ssh = Net::OpenSSH->new($ip, user => $login, passwd => $passwd);
24 my ($pty ,$pid) = $ssh->open2pty();
25 if ( ! $pty ) {
26         warn "ERROR: can't connect to $ip, skipping";
27         exit 0;
28 }
29
30 my $buff;
31
32 sub send_pty {
33         my $string = shift;
34         sleep 0.1; # we really need to wait for slow PowerConnect 5324
35         foreach (split //, $string) {
36                 print STDERR "[$_]" if $debug;
37                 syswrite $pty, $_;
38                 #$pty->flush;
39                 sleep 0.05;
40
41                 sysread $pty, my $echo, 1;
42                 print STDERR $echo;
43                 $buff .= $echo;
44         }
45 }
46
47 mkdir 'log' unless -d 'log';
48
49 chdir 'log';
50
51 sub save_log {
52         my ($ip, $hostname, $command, $buff) = @_;
53
54         return unless $command;
55         
56         my $file = "${ip}_${hostname}_${command}.log";
57         open my $log, '>', $file;
58         $buff =~ s/\r//gs; # strip CR, leave LF only
59         print $log $buff;
60         if ( -e '.git' ) {
61                 system 'git', 'add', $file;
62                 system 'git', 'commit', '-m', "$ip $hostname", $file;
63         }
64 }
65
66 my $command;
67
68 while(1) {
69         my $data;
70         my $read = sysread($pty, $data, 1);
71         print STDERR $data;
72         $buff .= $data;
73         if ( $buff =~ m/User Name:/ ) {
74                 send_pty "$login\n";
75                 $buff = '';
76         } elsif ( $buff =~ m/Password:/ ) {
77                 send_pty "$passwd\n";
78                 $buff = '';
79         } elsif ( $buff =~ m/([\w\-]+)#$/ ) {
80                 my $hostname = $1;
81                 if ( $buff ) {
82                         save_log $ip, $hostname, $command, $buff;
83                         $buff = '';
84                 }
85                 if ( $command = shift @commands ) {
86                         $command =~ s/[\n\r]+$//;
87                         send_pty "$command\n";
88                         $buff = '';
89                 } else  {
90                         send_pty "exit\n";
91                         close($pty);
92                         last;
93                 }
94         } elsif ( $buff =~ m/% Unrecognized command/ ) {
95                 exit 1;
96         } elsif ( $buff =~ s{More: <space>,  Quit: q.*One line: <return>\s*}{} ) {
97                 send_pty " ";
98         } elsif ( $buff =~ s{\Q--More-- or (q)uit\E}{} ) {
99                 send_pty " ";
100         } elsif ( $buff =~ s{\e\[0m\s*\r\s+\r}{} ) {
101                 # nop
102         } elsif ( $buff =~ m/^[\r\n]+[\w\-]+>$/ ) {
103                 send_pty "enable\n";
104         }
105 }
106
107 __DATA__
108 show arp
109 show vlan
110 show running-config
111 show bridge address