filter log/ filenames into sw.command
[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 use lib '.';
15 require 'config.pl';
16
17 #$Net::OpenSSH::debug = ~0;
18
19 my $ip = shift @ARGV || die "usage: $0 IP command[ command ...]\n";
20 $ip = $1 if `host $ip` =~ m/has address (\S+)/;
21 my @commands = @ARGV;
22 @commands = <DATA> unless @commands;
23
24 warn "\n## ssh $ip\n";
25 my $ssh = Net::OpenSSH->new($ip, user => $login, passwd => $passwd, default_ssh_opts => [-o => "StrictHostKeyChecking=no"]);
26 my ($pty ,$pid) = $ssh->open2pty();
27 if ( ! $pty ) {
28         warn "ERROR: can't connect to $ip, skipping";
29         exit 0;
30 }
31
32 my $buff;
33
34 sub send_pty {
35         my $string = shift;
36         sleep 0.05; # we really need to wait for slow PowerConnect 5324
37         foreach (split //, $string) {
38                 print STDERR "[$_]" if $debug;
39                 syswrite $pty, $_;
40                 #$pty->flush;
41                 sleep 0.01;
42
43                 sysread $pty, my $echo, 1;
44                 print STDERR $echo;
45                 $buff .= $echo;
46         }
47 }
48
49 mkdir 'log' unless -d 'log';
50
51 chdir 'log';
52
53 sub save_log {
54         my ($ip, $hostname, $command, $buff) = @_;
55
56         return unless $command;
57         return if $ENV{NO_LOG};
58         
59         my $file = "${ip}_${hostname}_${command}.log";
60         open my $log, '>', $file;
61         $buff =~ s/\r//gs; # strip CR, leave LF only
62         print $log $buff;
63         if ( -e '.git' ) {
64                 system 'git', 'add', $file;
65                 system 'git', 'commit', '-m', "$ip $hostname", $file;
66         }
67 }
68
69 my $command;
70 my @commands_while = ( @commands );
71
72 while() {
73         my $data;
74         my $read = sysread($pty, $data, 1);
75         print STDERR $data;
76         $buff .= $data;
77         if ( $buff =~ m/User Name:/ ) {
78                 send_pty "$login\n";
79                 $buff = '';
80         } elsif ( $buff =~ m/Password:/ ) {
81                 send_pty "$passwd\n";
82                 $buff = '';
83         } elsif ( $buff =~ m/([\w\-\(\)]+)#$/ ) {
84                 my $hostname = $1;
85                 if ( $buff ) {
86                         save_log $ip, $hostname, $command, $buff;
87                         $buff = '';
88                 }
89                 if ( $command = shift @commands_while ) {
90                         $command =~ s/[\n\r]+$//;
91                         send_pty "$command\n";
92                         $buff = '';
93                 } else  {
94                         send_pty "exit\n";
95                         close($pty);
96                         last;
97                 }
98         } elsif ( $buff =~ m/% Unrecognized command/ ) {
99                 exit 1;
100         } elsif ( $buff =~ s{More: <space>,  Quit: q.*One line: <return>\s*}{} ) {
101                 send_pty " ";
102         } elsif ( $buff =~ s{\Q--More-- or (q)uit\E}{} ) {
103                 send_pty " ";
104         } elsif ( $buff =~ s{\e\[0m\s*\r\s+\r}{} ) {
105                 # nop
106         } elsif ( $buff =~ m/^[\r\n]+[\w\-]+>$/ ) {
107                 send_pty "enable\n";
108         } elsif ( $buff =~ m{\QOverwrite file [startup-config] ?[Yes/press any key for no]....\E} ) {
109                 send_pty "y";
110                 $buff = '';
111         } elsif ( $buff =~ s{Management access will be blocked for the duration of the transfer.*Are you sure you want to start\? \(y/n\) }{}s ) {
112                 send_pty 'y';
113         } elsif ( $buff =~ s{\QThis command will reset the whole system and disconnect your current session.\E}{}s ) { # reload
114                 warn "\nRELOAD detected\n";
115                 sleep 0.5;
116                 send_pty 'y';
117         } elsif ( $buff =~ m{MikroTik RouterOS} ) {
118                 warn "\nERROR: don't know how to talk to MicroTik - ABORTING";
119                 exit 0;
120         }
121 }
122
123 __DATA__
124 show system
125 show arp
126 show vlan
127 show running-config
128 show bridge address
129 show interfaces status
130